clickhouse-native 0.8.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/clickhouse_native/client.cpp +112 -28
- data/ext/clickhouse_native/extconf.rb +30 -3
- data/ext/clickhouse_native/vendor/clickhouse-cpp/.github/workflows/bazel.yml +120 -0
- data/ext/clickhouse_native/vendor/clickhouse-cpp/.github/workflows/cross-repo-bug-relay.yml +17 -0
- data/ext/clickhouse_native/vendor/clickhouse-cpp/.github/workflows/linux.yml +22 -23
- data/ext/clickhouse_native/vendor/clickhouse-cpp/.github/workflows/macos.yml +22 -21
- data/ext/clickhouse_native/vendor/clickhouse-cpp/.github/workflows/windows_mingw.yml +29 -36
- data/ext/clickhouse_native/vendor/clickhouse-cpp/.github/workflows/windows_msvc.yml +29 -36
- data/ext/clickhouse_native/vendor/clickhouse-cpp/.gitignore +6 -0
- data/ext/clickhouse_native/vendor/clickhouse-cpp/AI_POLICY.md +13 -0
- data/ext/clickhouse_native/vendor/clickhouse-cpp/BUILD.bazel +167 -0
- data/ext/clickhouse_native/vendor/clickhouse-cpp/CMakeLists.txt +2 -1
- data/ext/clickhouse_native/vendor/clickhouse-cpp/MODULE.bazel +17 -0
- data/ext/clickhouse_native/vendor/clickhouse-cpp/MODULE.bazel.lock +503 -0
- data/ext/clickhouse_native/vendor/clickhouse-cpp/README.md +32 -6
- data/ext/clickhouse_native/vendor/clickhouse-cpp/ci/docker-compose/config.xml +53 -0
- data/ext/clickhouse_native/vendor/clickhouse-cpp/ci/docker-compose/users.xml +35 -0
- data/ext/clickhouse_native/vendor/clickhouse-cpp/ci/docker-compose.yml +22 -0
- data/ext/clickhouse_native/vendor/clickhouse-cpp/clickhouse/CMakeLists.txt +11 -0
- data/ext/clickhouse_native/vendor/clickhouse-cpp/clickhouse/base/sslsocket.cpp +24 -0
- data/ext/clickhouse_native/vendor/clickhouse-cpp/clickhouse/block.cpp +1 -1
- data/ext/clickhouse_native/vendor/clickhouse-cpp/clickhouse/block.h +2 -1
- data/ext/clickhouse_native/vendor/clickhouse-cpp/clickhouse/client.cpp +293 -136
- data/ext/clickhouse_native/vendor/clickhouse-cpp/clickhouse/client.h +31 -2
- data/ext/clickhouse_native/vendor/clickhouse-cpp/clickhouse/columns/array.cpp +12 -0
- data/ext/clickhouse_native/vendor/clickhouse-cpp/clickhouse/columns/array.h +17 -7
- data/ext/clickhouse_native/vendor/clickhouse-cpp/clickhouse/columns/bool.cpp +79 -0
- data/ext/clickhouse_native/vendor/clickhouse-cpp/clickhouse/columns/bool.h +62 -0
- data/ext/clickhouse_native/vendor/clickhouse-cpp/clickhouse/columns/factory.cpp +16 -0
- data/ext/clickhouse_native/vendor/clickhouse-cpp/clickhouse/columns/itemview.cpp +2 -0
- data/ext/clickhouse_native/vendor/clickhouse-cpp/clickhouse/columns/itemview.h +6 -2
- data/ext/clickhouse_native/vendor/clickhouse-cpp/clickhouse/columns/json.cpp +102 -0
- data/ext/clickhouse_native/vendor/clickhouse-cpp/clickhouse/columns/json.h +82 -0
- data/ext/clickhouse_native/vendor/clickhouse-cpp/clickhouse/columns/lowcardinality.cpp +2 -1
- data/ext/clickhouse_native/vendor/clickhouse-cpp/clickhouse/columns/string.cpp +7 -2
- data/ext/clickhouse_native/vendor/clickhouse-cpp/clickhouse/columns/tuple.cpp +48 -5
- data/ext/clickhouse_native/vendor/clickhouse-cpp/clickhouse/columns/tuple.h +14 -1
- data/ext/clickhouse_native/vendor/clickhouse-cpp/clickhouse/query.h +2 -2
- data/ext/clickhouse_native/vendor/clickhouse-cpp/clickhouse/server_exception.h +0 -3
- data/ext/clickhouse_native/vendor/clickhouse-cpp/clickhouse/types/type_parser.cpp +43 -0
- data/ext/clickhouse_native/vendor/clickhouse-cpp/clickhouse/types/type_parser.h +9 -0
- data/ext/clickhouse_native/vendor/clickhouse-cpp/clickhouse/types/types.cpp +61 -11
- data/ext/clickhouse_native/vendor/clickhouse-cpp/clickhouse/types/types.h +18 -2
- data/ext/clickhouse_native/vendor/clickhouse-cpp/clickhouse/version.h +1 -1
- data/lib/clickhouse_native/logging.rb +4 -4
- data/lib/clickhouse_native/pool.rb +8 -8
- data/lib/clickhouse_native/version.rb +1 -1
- data/lib/clickhouse_native.rb +1 -0
- metadata +15 -2
|
@@ -6,6 +6,7 @@ C++ client for [ClickHouse](https://clickhouse.com/).
|
|
|
6
6
|
## Supported data types
|
|
7
7
|
|
|
8
8
|
* Array(T)
|
|
9
|
+
* Bool \* (by default, mapped to UInt8 when receiving data)
|
|
9
10
|
* Date
|
|
10
11
|
* DateTime, DateTime64
|
|
11
12
|
* DateTime([timezone]), DateTime64(N, [timezone])
|
|
@@ -23,6 +24,15 @@ C++ client for [ClickHouse](https://clickhouse.com/).
|
|
|
23
24
|
* UUID
|
|
24
25
|
* Map
|
|
25
26
|
* Point, Ring, Polygon, MultiPolygon
|
|
27
|
+
* JSON - experimental support; requires output_format_native_write_json_as_string=1; data is passed as strings
|
|
28
|
+
|
|
29
|
+
\*: There exists a distinct `ColumnBool` and entry in the `Type` enumeration that
|
|
30
|
+
can be used.
|
|
31
|
+
By default, data received from the server will map Bool columns to UInt8. This is
|
|
32
|
+
a backwards compatibility feature.
|
|
33
|
+
If you want the library to produce ColumnBool, set the CMake variable `DCH_MAP_BOOL_TO_UINT8=OFF`.
|
|
34
|
+
The default for this variable will switch, with it being subsequently removed, in
|
|
35
|
+
a future release.
|
|
26
36
|
|
|
27
37
|
## Dependencies
|
|
28
38
|
In the most basic case one needs only:
|
|
@@ -157,16 +167,34 @@ target_link_libraries(${PROJECT_NAME} PRIVATE clickhouse-cpp-lib)
|
|
|
157
167
|
- run `rm -rf build && cmake -B build -S . && cmake --build build -j32` to remove remainders of the previous builds, run CMake and build the
|
|
158
168
|
application. The generated binary is located in location `build/application-example`.
|
|
159
169
|
|
|
170
|
+
## Experimental Bazel support
|
|
171
|
+
|
|
172
|
+
If you use Bazel, you can also use it to import the library into your project. However, please keep
|
|
173
|
+
in mind that Bazel support is currently experimental and is still being refined. This means things
|
|
174
|
+
might change as we improve and update the setup.
|
|
175
|
+
|
|
176
|
+
Most importantly, the project includes settings that were added for compatibility with older
|
|
177
|
+
versions of the library and its API, and to preserve old behavior. These settings will not be part
|
|
178
|
+
of the Bazel configuration. This means that even when only the minor version changes your build
|
|
179
|
+
still might break.
|
|
180
|
+
|
|
181
|
+
Additionally, by default, the library is built with BoringSSL and not OpenSSL because it builds
|
|
182
|
+
reliably across platforms on BCR today and matches what many Bazel workspaces, such as gRPC and
|
|
183
|
+
Envoy, already link against.
|
|
184
|
+
|
|
185
|
+
It is still possible to build the library with OpenSSL by using the `tls=openssl` option. TLS
|
|
186
|
+
support can be completely omitted with the `tls=no` option.
|
|
187
|
+
|
|
160
188
|
## Batch Insertion
|
|
161
189
|
|
|
162
190
|
In addition to the `Insert` method, which inserts all the data in a block in a
|
|
163
|
-
single call, you can use the `BeginInsert` / `
|
|
191
|
+
single call, you can use the `BeginInsert` / `SendInsertBlock` / `EndInsert`
|
|
164
192
|
pattern to insert batches of data. This can be useful for managing larger data
|
|
165
193
|
sets without inflating memory with the entire set.
|
|
166
194
|
|
|
167
195
|
To use it pass `BeginInsert` an `INSERT` statement ending in `VALUES` but with
|
|
168
196
|
no actual values. Use the resulting `Block` to append batches of data, sending
|
|
169
|
-
each to the sever with `
|
|
197
|
+
each to the sever with `SendInsertBlock`. Finally, call `EndInsert` (or let the
|
|
170
198
|
client go out of scope) to signal the server that insertion is complete.
|
|
171
199
|
Example:
|
|
172
200
|
|
|
@@ -186,7 +214,7 @@ col2.Append("naomi");
|
|
|
186
214
|
|
|
187
215
|
// Send those records.
|
|
188
216
|
block.RefreshRowCount();
|
|
189
|
-
client->
|
|
217
|
+
client->SendInsertBlock(block);
|
|
190
218
|
block.Clear();
|
|
191
219
|
|
|
192
220
|
// Add another record.
|
|
@@ -195,7 +223,7 @@ col2.Append("amos");
|
|
|
195
223
|
|
|
196
224
|
// Send it and finish.
|
|
197
225
|
block.RefreshRowCount();
|
|
198
|
-
client->EndInsert(
|
|
226
|
+
client->EndInsert();
|
|
199
227
|
```
|
|
200
228
|
|
|
201
229
|
## Thread-safety
|
|
@@ -256,5 +284,3 @@ client.Insert("default.test", block);
|
|
|
256
284
|
```sql
|
|
257
285
|
ALTER USER insert_account SETTINGS async_insert=1,wait_for_async_insert=1,async_insert_use_adaptive_busy_timeout=0,async_insert_busy_timeout_ms=5000,async_insert_max_data_size=104857600
|
|
258
286
|
```
|
|
259
|
-
|
|
260
|
-
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<?xml version="1.0"?>
|
|
2
|
+
<clickhouse>
|
|
3
|
+
|
|
4
|
+
<http_port>8123</http_port>
|
|
5
|
+
<tcp_port>9000</tcp_port>
|
|
6
|
+
|
|
7
|
+
<users_config>users.xml</users_config>
|
|
8
|
+
<default_profile>default</default_profile>
|
|
9
|
+
<default_database>default</default_database>
|
|
10
|
+
|
|
11
|
+
<mark_cache_size>5368709120</mark_cache_size>
|
|
12
|
+
|
|
13
|
+
<path>/var/lib/clickhouse/</path>
|
|
14
|
+
<tmp_path>/var/lib/clickhouse/tmp/</tmp_path>
|
|
15
|
+
<user_files_path>/var/lib/clickhouse/user_files/</user_files_path>
|
|
16
|
+
<access_control_path>/var/lib/clickhouse/access/</access_control_path>
|
|
17
|
+
<keep_alive_timeout>3</keep_alive_timeout>
|
|
18
|
+
|
|
19
|
+
<logger>
|
|
20
|
+
<level>debug</level>
|
|
21
|
+
<log>/var/log/clickhouse-server/clickhouse-server.log</log>
|
|
22
|
+
<errorlog>/var/log/clickhouse-server/clickhouse-server.err.log</errorlog>
|
|
23
|
+
<size>1000M</size>
|
|
24
|
+
<count>10</count>
|
|
25
|
+
<console>1</console>
|
|
26
|
+
</logger>
|
|
27
|
+
|
|
28
|
+
<query_log>
|
|
29
|
+
<database>system</database>
|
|
30
|
+
<table>query_log</table>
|
|
31
|
+
<partition_by>toYYYYMM(event_date)</partition_by>
|
|
32
|
+
<flush_interval_milliseconds>1000</flush_interval_milliseconds>
|
|
33
|
+
</query_log>
|
|
34
|
+
|
|
35
|
+
<format_schema_path>/var/lib/clickhouse/format_schemas/</format_schema_path>
|
|
36
|
+
<user_directories>
|
|
37
|
+
<users_xml>
|
|
38
|
+
<path>users.xml</path>
|
|
39
|
+
</users_xml>
|
|
40
|
+
</user_directories>
|
|
41
|
+
|
|
42
|
+
<opentelemetry_span_log>
|
|
43
|
+
<engine>
|
|
44
|
+
engine MergeTree
|
|
45
|
+
partition by toYYYYMM(finish_date)
|
|
46
|
+
order by (finish_date, finish_time_us, trace_id)
|
|
47
|
+
</engine>
|
|
48
|
+
<database>system</database>
|
|
49
|
+
<table>opentelemetry_span_log</table>
|
|
50
|
+
<flush_interval_milliseconds>7500</flush_interval_milliseconds>
|
|
51
|
+
</opentelemetry_span_log>
|
|
52
|
+
|
|
53
|
+
</clickhouse>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<?xml version="1.0"?>
|
|
2
|
+
<clickhouse>
|
|
3
|
+
|
|
4
|
+
<profiles>
|
|
5
|
+
<default>
|
|
6
|
+
<load_balancing>random</load_balancing>
|
|
7
|
+
<enable_time_time64_type>1</enable_time_time64_type>
|
|
8
|
+
</default>
|
|
9
|
+
</profiles>
|
|
10
|
+
|
|
11
|
+
<users>
|
|
12
|
+
<default>
|
|
13
|
+
<password></password>
|
|
14
|
+
<networks>
|
|
15
|
+
<ip>::/0</ip>
|
|
16
|
+
</networks>
|
|
17
|
+
<profile>default</profile>
|
|
18
|
+
<quota>default</quota>
|
|
19
|
+
<access_management>1</access_management>
|
|
20
|
+
</default>
|
|
21
|
+
</users>
|
|
22
|
+
|
|
23
|
+
<quotas>
|
|
24
|
+
<default>
|
|
25
|
+
<interval>
|
|
26
|
+
<duration>3600</duration>
|
|
27
|
+
<queries>0</queries>
|
|
28
|
+
<errors>0</errors>
|
|
29
|
+
<result_rows>0</result_rows>
|
|
30
|
+
<read_rows>0</read_rows>
|
|
31
|
+
<execution_time>0</execution_time>
|
|
32
|
+
</interval>
|
|
33
|
+
</default>
|
|
34
|
+
</quotas>
|
|
35
|
+
</clickhouse>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
services:
|
|
2
|
+
clickhouse:
|
|
3
|
+
image: 'docker.io/clickhouse/clickhouse-server:${CLICKHOUSE_VERSION-25.12-alpine}'
|
|
4
|
+
container_name: 'clickhouse-odbc-clickhouse-server'
|
|
5
|
+
environment:
|
|
6
|
+
CLICKHOUSE_SKIP_USER_SETUP: 1
|
|
7
|
+
ports:
|
|
8
|
+
- '8123:8123'
|
|
9
|
+
- '9000:9000'
|
|
10
|
+
ulimits:
|
|
11
|
+
nofile:
|
|
12
|
+
soft: 262144
|
|
13
|
+
hard: 262144
|
|
14
|
+
volumes:
|
|
15
|
+
- './docker-compose/config.xml:/etc/clickhouse-server/config.xml:z'
|
|
16
|
+
- './docker-compose/users.xml:/etc/clickhouse-server/users.xml:z'
|
|
17
|
+
networks:
|
|
18
|
+
- clickhouse-odbc
|
|
19
|
+
|
|
20
|
+
networks:
|
|
21
|
+
clickhouse-odbc:
|
|
22
|
+
driver: bridge
|
|
@@ -8,6 +8,7 @@ SET ( clickhouse-cpp-lib-src
|
|
|
8
8
|
base/endpoints_iterator.cpp
|
|
9
9
|
|
|
10
10
|
columns/array.cpp
|
|
11
|
+
columns/bool.cpp
|
|
11
12
|
columns/column.cpp
|
|
12
13
|
columns/date.cpp
|
|
13
14
|
columns/decimal.cpp
|
|
@@ -16,6 +17,7 @@ SET ( clickhouse-cpp-lib-src
|
|
|
16
17
|
columns/geo.cpp
|
|
17
18
|
columns/ip4.cpp
|
|
18
19
|
columns/ip6.cpp
|
|
20
|
+
columns/json.cpp
|
|
19
21
|
columns/lowcardinality.cpp
|
|
20
22
|
columns/nullable.cpp
|
|
21
23
|
columns/numeric.cpp
|
|
@@ -52,6 +54,7 @@ SET ( clickhouse-cpp-lib-src
|
|
|
52
54
|
base/wire_format.h
|
|
53
55
|
|
|
54
56
|
columns/array.h
|
|
57
|
+
columns/bool.h
|
|
55
58
|
columns/column.h
|
|
56
59
|
columns/date.h
|
|
57
60
|
columns/decimal.h
|
|
@@ -60,6 +63,7 @@ SET ( clickhouse-cpp-lib-src
|
|
|
60
63
|
columns/geo.h
|
|
61
64
|
columns/ip4.h
|
|
62
65
|
columns/ip6.h
|
|
66
|
+
columns/json.h
|
|
63
67
|
columns/itemview.h
|
|
64
68
|
columns/lowcardinality.h
|
|
65
69
|
columns/lowcardinalityadaptor.h
|
|
@@ -120,6 +124,11 @@ TARGET_LINK_LIBRARIES (clickhouse-cpp-lib
|
|
|
120
124
|
TARGET_INCLUDE_DIRECTORIES (clickhouse-cpp-lib
|
|
121
125
|
PUBLIC ${PROJECT_SOURCE_DIR}
|
|
122
126
|
)
|
|
127
|
+
IF (CH_MAP_BOOL_TO_UINT8)
|
|
128
|
+
TARGET_COMPILE_DEFINITIONS (clickhouse-cpp-lib PUBLIC CH_MAP_BOOL_TO_UINT8=1)
|
|
129
|
+
ELSE ()
|
|
130
|
+
TARGET_COMPILE_DEFINITIONS (clickhouse-cpp-lib PUBLIC CH_MAP_BOOL_TO_UINT8=0)
|
|
131
|
+
ENDIF ()
|
|
123
132
|
|
|
124
133
|
IF (NOT BUILD_SHARED_LIBS)
|
|
125
134
|
ADD_LIBRARY (clickhouse-cpp-lib-static ALIAS clickhouse-cpp-lib)
|
|
@@ -213,6 +222,7 @@ INSTALL(FILES base/endpoints_iterator.h DESTINATION include/clickhouse/base/)
|
|
|
213
222
|
|
|
214
223
|
# columns
|
|
215
224
|
INSTALL(FILES columns/array.h DESTINATION include/clickhouse/columns/)
|
|
225
|
+
INSTALL(FILES columns/bool.h DESTINATION include/clickhouse/columns/)
|
|
216
226
|
INSTALL(FILES columns/column.h DESTINATION include/clickhouse/columns/)
|
|
217
227
|
INSTALL(FILES columns/date.h DESTINATION include/clickhouse/columns/)
|
|
218
228
|
INSTALL(FILES columns/decimal.h DESTINATION include/clickhouse/columns/)
|
|
@@ -221,6 +231,7 @@ INSTALL(FILES columns/factory.h DESTINATION include/clickhouse/columns/)
|
|
|
221
231
|
INSTALL(FILES columns/geo.h DESTINATION include/clickhouse/columns/)
|
|
222
232
|
INSTALL(FILES columns/ip4.h DESTINATION include/clickhouse/columns/)
|
|
223
233
|
INSTALL(FILES columns/ip6.h DESTINATION include/clickhouse/columns/)
|
|
234
|
+
INSTALL(FILES columns/json.h DESTINATION include/clickhouse/columns/)
|
|
224
235
|
INSTALL(FILES columns/itemview.h DESTINATION include/clickhouse/columns/)
|
|
225
236
|
INSTALL(FILES columns/lowcardinality.h DESTINATION include/clickhouse/columns/)
|
|
226
237
|
INSTALL(FILES columns/nothing.h DESTINATION include/clickhouse/columns/)
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
#include "../client.h"
|
|
3
3
|
#include "../exceptions.h"
|
|
4
4
|
|
|
5
|
+
#include <iostream>
|
|
5
6
|
#include <stdexcept>
|
|
6
7
|
|
|
7
8
|
#include <openssl/ssl.h>
|
|
@@ -50,6 +51,19 @@ void throwSSLError(SSL * ssl, int error, const char * /*location*/, const char *
|
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
void configureSSL(const clickhouse::SSLParams::ConfigurationType & configuration, SSL * ssl, SSL_CTX * context = nullptr) {
|
|
54
|
+
#ifdef USE_BORINGSSL
|
|
55
|
+
// BoringSSL doesn't ship the SSL_CONF_* command API, so the
|
|
56
|
+
// configuration vector cannot be applied. Users who rely on
|
|
57
|
+
// SSL_CONF commands should build against
|
|
58
|
+
// OpenSSL (e.g. --@clickhouse_cpp//:tls=openssl with Bazel).
|
|
59
|
+
(void)ssl;
|
|
60
|
+
(void)context;
|
|
61
|
+
if (!configuration.empty()) {
|
|
62
|
+
throw clickhouse::OpenSSLError(
|
|
63
|
+
"SSLParams::configuration cannot be used when the library is built against BoringSSL "
|
|
64
|
+
"To apply these settings, build against OpenSSL by using the `tls=openssl` option in Bazel.");
|
|
65
|
+
}
|
|
66
|
+
#else
|
|
53
67
|
std::unique_ptr<SSL_CONF_CTX, decltype(&SSL_CONF_CTX_free)> conf_ctx_holder(SSL_CONF_CTX_new(), SSL_CONF_CTX_free);
|
|
54
68
|
auto conf_ctx = conf_ctx_holder.get();
|
|
55
69
|
|
|
@@ -84,6 +98,7 @@ void configureSSL(const clickhouse::SSLParams::ConfigurationType & configuration
|
|
|
84
98
|
else
|
|
85
99
|
throw clickhouse::OpenSSLError("Failed to configure OpenSSL: command '" + kv.first + "' unknown error: " + std::to_string(err));
|
|
86
100
|
}
|
|
101
|
+
#endif
|
|
87
102
|
}
|
|
88
103
|
|
|
89
104
|
#define STRINGIFY_HELPER(x) #x
|
|
@@ -285,9 +300,18 @@ SSLSocketInput::SSLSocketInput(SSL *ssl)
|
|
|
285
300
|
{}
|
|
286
301
|
|
|
287
302
|
size_t SSLSocketInput::DoRead(void* buf, size_t len) {
|
|
303
|
+
#ifdef USE_BORINGSSL
|
|
304
|
+
// BoringSSL doesn't have SSL_read_ex (OpenSSL 3.0+ API); fall back to
|
|
305
|
+
// SSL_read with the length clamped to INT_MAX.
|
|
306
|
+
const int max_read = static_cast<int>(
|
|
307
|
+
std::min<std::size_t>(len, std::numeric_limits<int>::max()));
|
|
308
|
+
return static_cast<size_t>(
|
|
309
|
+
HANDLE_SSL_ERROR(ssl_, SSL_read(ssl_, buf, max_read)));
|
|
310
|
+
#else
|
|
288
311
|
size_t actually_read;
|
|
289
312
|
HANDLE_SSL_ERROR(ssl_, SSL_read_ex(ssl_, buf, len, &actually_read));
|
|
290
313
|
return actually_read;
|
|
314
|
+
#endif
|
|
291
315
|
}
|
|
292
316
|
|
|
293
317
|
SSLSocketOutput::SSLSocketOutput(SSL *ssl)
|
|
@@ -92,7 +92,8 @@ public:
|
|
|
92
92
|
void Reserve(size_t new_cap);
|
|
93
93
|
|
|
94
94
|
/// Reference to column by index in the block.
|
|
95
|
-
ColumnRef
|
|
95
|
+
ColumnRef At(size_t idx) const;
|
|
96
|
+
ColumnRef operator [] (size_t idx) const { return At(idx); }
|
|
96
97
|
|
|
97
98
|
Iterator begin() const;
|
|
98
99
|
Iterator end() const;
|