duckdb 1.2.0.0 → 1.2.1.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/.github/workflows/test_on_macos.yml +2 -2
- data/.github/workflows/test_on_ubuntu.yml +2 -2
- data/.github/workflows/test_on_windows.yml +1 -1
- data/CHANGELOG.md +18 -0
- data/Dockerfile +1 -1
- data/Gemfile.lock +8 -8
- data/ext/duckdb/appender.c +58 -104
- data/ext/duckdb/extconf.rb +5 -5
- data/ext/duckdb/logical_type.c +136 -0
- data/ext/duckdb/prepared_statement.c +24 -3
- data/ext/duckdb/result.c +1 -1
- data/ext/duckdb/ruby-duckdb.h +4 -8
- data/lib/duckdb/appender.rb +263 -24
- data/lib/duckdb/logical_type.rb +88 -0
- data/lib/duckdb/prepared_statement.rb +18 -1
- data/lib/duckdb/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8003b16f724b8a5c4863dbc507476601992e002767aa3cf7cfd7d87583265bc
|
4
|
+
data.tar.gz: a82ef0f5617349c568dd2be3cb8ad1deb5bdee8796483e376eaabc266232f280
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8220ad5939d4c60819636488a783118ba8040429348ad157515ea1801fe9462ad20e2fff12440ce3e1ffae642f3d6fca0a02b43b4ed8958a105cfd079f85de47
|
7
|
+
data.tar.gz: f221a85106b80b654750faeb855c51ff760d82082cb86d7c77834c20194ab71b21feff55d883f1d2d13b1dac699bb50ff6fc5473a04db0e50f4dbbfcb1cd5d22
|
@@ -15,8 +15,8 @@ jobs:
|
|
15
15
|
runs-on: macos-latest
|
16
16
|
strategy:
|
17
17
|
matrix:
|
18
|
-
ruby: ['3.1.6', '3.2.
|
19
|
-
duckdb: ['1.2.
|
18
|
+
ruby: ['3.1.6', '3.2.7', '3.3.7', '3.4.2', 'head']
|
19
|
+
duckdb: ['1.2.1', '1.1.3', '1.1.1']
|
20
20
|
|
21
21
|
steps:
|
22
22
|
- uses: actions/checkout@v4
|
@@ -15,8 +15,8 @@ jobs:
|
|
15
15
|
runs-on: ubuntu-latest
|
16
16
|
strategy:
|
17
17
|
matrix:
|
18
|
-
ruby: ['3.1.6', '3.2.
|
19
|
-
duckdb: ['1.2.
|
18
|
+
ruby: ['3.1.6', '3.2.7', '3.3.7', '3.4.2', 'head']
|
19
|
+
duckdb: ['1.2.1', '1.1.3', '1.1.1']
|
20
20
|
|
21
21
|
steps:
|
22
22
|
- uses: actions/checkout@v4
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,24 @@
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
# Unreleased
|
5
5
|
|
6
|
+
# 1.2.1.0 - 2025-03-30
|
7
|
+
- bump duckdb v1.2.1 on CI.
|
8
|
+
- drop duckdb v1.0.0.
|
9
|
+
- add `DuckDB::LogicalType` class.
|
10
|
+
- `DuckDB::LogicalType` class is under construction. `DuckDB::LogicalType#member_count`,
|
11
|
+
`DuckDB::LogicalType#member_name_at`, `DuckDB::LogicalType#member_type_at`,
|
12
|
+
`DuckDB::LogicalType#each_member_name`, `DuckDB::LogicalType#each_member_type`,
|
13
|
+
`DuckDB::LogicalType#child_count`, `DuckDB::LogicalType#child_name_at`,
|
14
|
+
`DuckDB::LogicalType#child_type_at`, `DuckDB::LogicalType#each_child_name`, and
|
15
|
+
`DuckDB::LogicalType#each_child_type` are available.
|
16
|
+
- fix error message when `DuckDB::Appender#append_uint16`, `DuckDB::Appender#append_uint32`,
|
17
|
+
`DuckDB::Appender#append_uint64`, `DuckDB::Appender#append_float`, `DuckDB::Appender#append_double`,
|
18
|
+
`DuckDB::Appender#append_varchar`, `DuckDB::Appender#append_varchar_length`,
|
19
|
+
`DuckDB::Appender#append_blob`, `DuckDB::Appender#append_null`, `DuckDB::Appender#append_default`,
|
20
|
+
`DuckDB::Appender#append_date`, `DuckDB::Appender#append_interval`, `DuckDB::Appender#append_time`,
|
21
|
+
`DuckDB::Appender#append_timestamp`, `DuckDB::Appender#append_hugeint` failed.
|
22
|
+
- add `DuckDB::PreparedStatement#bind_uhugeint`.
|
23
|
+
|
6
24
|
# 1.2.0.0 - 2025-02-24
|
7
25
|
- bump duckdb to 1.2.0.
|
8
26
|
- add `DuckDB::LogicalType` class(Thanks to @otegami).
|
data/Dockerfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
duckdb (1.2.
|
4
|
+
duckdb (1.2.1.0)
|
5
5
|
bigdecimal (>= 3.1.4)
|
6
6
|
|
7
7
|
GEM
|
@@ -10,19 +10,19 @@ GEM
|
|
10
10
|
benchmark-ips (2.14.0)
|
11
11
|
bigdecimal (3.1.9)
|
12
12
|
mini_portile2 (2.8.8)
|
13
|
-
minitest (5.25.
|
14
|
-
nokogiri (1.18.
|
13
|
+
minitest (5.25.5)
|
14
|
+
nokogiri (1.18.6)
|
15
15
|
mini_portile2 (~> 2.8.2)
|
16
16
|
racc (~> 1.4)
|
17
|
-
nokogiri (1.18.
|
17
|
+
nokogiri (1.18.6-aarch64-linux-gnu)
|
18
18
|
racc (~> 1.4)
|
19
|
-
nokogiri (1.18.
|
19
|
+
nokogiri (1.18.6-arm-linux-gnu)
|
20
20
|
racc (~> 1.4)
|
21
|
-
nokogiri (1.18.
|
21
|
+
nokogiri (1.18.6-arm64-darwin)
|
22
22
|
racc (~> 1.4)
|
23
|
-
nokogiri (1.18.
|
23
|
+
nokogiri (1.18.6-x86_64-darwin)
|
24
24
|
racc (~> 1.4)
|
25
|
-
nokogiri (1.18.
|
25
|
+
nokogiri (1.18.6-x86_64-linux-gnu)
|
26
26
|
racc (~> 1.4)
|
27
27
|
racc (1.8.1)
|
28
28
|
rake (13.2.1)
|
data/ext/duckdb/appender.c
CHANGED
@@ -13,20 +13,16 @@ static VALUE appender__append_int16(VALUE self, VALUE val);
|
|
13
13
|
static VALUE appender__append_int32(VALUE self, VALUE val);
|
14
14
|
static VALUE appender__append_int64(VALUE self, VALUE val);
|
15
15
|
static VALUE appender__append_uint8(VALUE self, VALUE val);
|
16
|
-
static VALUE
|
17
|
-
static VALUE
|
18
|
-
static VALUE
|
19
|
-
static VALUE
|
20
|
-
static VALUE
|
21
|
-
static VALUE
|
22
|
-
static VALUE
|
23
|
-
static VALUE
|
24
|
-
static VALUE
|
25
|
-
|
26
|
-
#ifdef HAVE_DUCKDB_H_GE_V1_1_0
|
27
|
-
static VALUE appender_append_default(VALUE self);
|
28
|
-
#endif
|
29
|
-
|
16
|
+
static VALUE appender__append_uint16(VALUE self, VALUE val);
|
17
|
+
static VALUE appender__append_uint32(VALUE self, VALUE val);
|
18
|
+
static VALUE appender__append_uint64(VALUE self, VALUE val);
|
19
|
+
static VALUE appender__append_float(VALUE self, VALUE val);
|
20
|
+
static VALUE appender__append_double(VALUE self, VALUE val);
|
21
|
+
static VALUE appender__append_varchar(VALUE self, VALUE val);
|
22
|
+
static VALUE appender__append_varchar_length(VALUE self, VALUE val, VALUE len);
|
23
|
+
static VALUE appender__append_blob(VALUE self, VALUE val);
|
24
|
+
static VALUE appender__append_null(VALUE self);
|
25
|
+
static VALUE appender__append_default(VALUE self);
|
30
26
|
static VALUE appender__end_row(VALUE self);
|
31
27
|
static VALUE appender__append_date(VALUE self, VALUE yearval, VALUE monthval, VALUE dayval);
|
32
28
|
static VALUE appender__append_interval(VALUE self, VALUE months, VALUE days, VALUE micros);
|
@@ -177,79 +173,68 @@ static VALUE appender__append_uint8(VALUE self, VALUE val) {
|
|
177
173
|
return duckdb_state_to_bool_value(duckdb_append_uint8(ctx->appender, ui8val));
|
178
174
|
}
|
179
175
|
|
180
|
-
|
176
|
+
/* :nodoc: */
|
177
|
+
static VALUE appender__append_uint16(VALUE self, VALUE val) {
|
181
178
|
rubyDuckDBAppender *ctx;
|
182
179
|
uint16_t ui16val = (uint16_t)NUM2UINT(val);
|
183
180
|
|
184
181
|
TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
|
185
182
|
|
186
|
-
|
187
|
-
rb_raise(eDuckDBError, "failed to append uint16");
|
188
|
-
}
|
189
|
-
return self;
|
183
|
+
return duckdb_state_to_bool_value(duckdb_append_uint16(ctx->appender, ui16val));
|
190
184
|
}
|
191
185
|
|
192
|
-
|
186
|
+
/* :nodoc: */
|
187
|
+
static VALUE appender__append_uint32(VALUE self, VALUE val) {
|
193
188
|
rubyDuckDBAppender *ctx;
|
194
189
|
uint32_t ui32val = (uint32_t)NUM2UINT(val);
|
195
190
|
|
196
191
|
TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
|
197
192
|
|
198
|
-
|
199
|
-
rb_raise(eDuckDBError, "failed to append uint32");
|
200
|
-
}
|
201
|
-
return self;
|
193
|
+
return duckdb_state_to_bool_value(duckdb_append_uint32(ctx->appender, ui32val));
|
202
194
|
}
|
203
195
|
|
204
|
-
|
196
|
+
/* :nodoc: */
|
197
|
+
static VALUE appender__append_uint64(VALUE self, VALUE val) {
|
205
198
|
rubyDuckDBAppender *ctx;
|
206
199
|
uint64_t ui64val = (uint64_t)NUM2ULL(val);
|
207
200
|
|
208
201
|
TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
|
209
202
|
|
210
|
-
|
211
|
-
rb_raise(eDuckDBError, "failed to append uint64");
|
212
|
-
}
|
213
|
-
return self;
|
203
|
+
return duckdb_state_to_bool_value(duckdb_append_uint64(ctx->appender, ui64val));
|
214
204
|
}
|
215
205
|
|
216
|
-
|
206
|
+
/* :nodoc: */
|
207
|
+
static VALUE appender__append_float(VALUE self, VALUE val) {
|
217
208
|
rubyDuckDBAppender *ctx;
|
218
209
|
float fval = (float)NUM2DBL(val);
|
219
210
|
|
220
211
|
TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
|
221
212
|
|
222
|
-
|
223
|
-
rb_raise(eDuckDBError, "failed to append float");
|
224
|
-
}
|
225
|
-
return self;
|
213
|
+
return duckdb_state_to_bool_value(duckdb_append_float(ctx->appender, fval));
|
226
214
|
}
|
227
215
|
|
228
|
-
|
216
|
+
/* :nodoc: */
|
217
|
+
static VALUE appender__append_double(VALUE self, VALUE val) {
|
229
218
|
rubyDuckDBAppender *ctx;
|
230
219
|
double dval = NUM2DBL(val);
|
231
220
|
|
232
221
|
TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
|
233
222
|
|
234
|
-
|
235
|
-
rb_raise(eDuckDBError, "failed to append double");
|
236
|
-
}
|
237
|
-
return self;
|
223
|
+
return duckdb_state_to_bool_value(duckdb_append_double(ctx->appender, dval));
|
238
224
|
}
|
239
225
|
|
240
|
-
|
226
|
+
/* :nodoc: */
|
227
|
+
static VALUE appender__append_varchar(VALUE self, VALUE val) {
|
241
228
|
rubyDuckDBAppender *ctx;
|
242
229
|
char *pval = StringValuePtr(val);
|
243
230
|
|
244
231
|
TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
|
245
232
|
|
246
|
-
|
247
|
-
rb_raise(eDuckDBError, "failed to append varchar");
|
248
|
-
}
|
249
|
-
return self;
|
233
|
+
return duckdb_state_to_bool_value(duckdb_append_varchar(ctx->appender, pval));
|
250
234
|
}
|
251
235
|
|
252
|
-
|
236
|
+
/* :nodoc: */
|
237
|
+
static VALUE appender__append_varchar_length(VALUE self, VALUE val, VALUE len) {
|
253
238
|
rubyDuckDBAppender *ctx;
|
254
239
|
|
255
240
|
char *pval = StringValuePtr(val);
|
@@ -257,13 +242,11 @@ static VALUE appender_append_varchar_length(VALUE self, VALUE val, VALUE len) {
|
|
257
242
|
|
258
243
|
TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
|
259
244
|
|
260
|
-
|
261
|
-
rb_raise(eDuckDBError, "failed to append varchar with length");
|
262
|
-
}
|
263
|
-
return self;
|
245
|
+
return duckdb_state_to_bool_value(duckdb_append_varchar_length(ctx->appender, pval, length));
|
264
246
|
}
|
265
247
|
|
266
|
-
|
248
|
+
/* :nodoc: */
|
249
|
+
static VALUE appender__append_blob(VALUE self, VALUE val) {
|
267
250
|
rubyDuckDBAppender *ctx;
|
268
251
|
|
269
252
|
char *pval = StringValuePtr(val);
|
@@ -271,33 +254,24 @@ static VALUE appender_append_blob(VALUE self, VALUE val) {
|
|
271
254
|
|
272
255
|
TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
|
273
256
|
|
274
|
-
|
275
|
-
rb_raise(eDuckDBError, "failed to append blob");
|
276
|
-
}
|
277
|
-
return self;
|
257
|
+
return duckdb_state_to_bool_value(duckdb_append_blob(ctx->appender, (void *)pval, length));
|
278
258
|
}
|
279
259
|
|
280
|
-
|
260
|
+
/* :nodoc: */
|
261
|
+
static VALUE appender__append_null(VALUE self) {
|
281
262
|
rubyDuckDBAppender *ctx;
|
282
263
|
TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
|
283
264
|
|
284
|
-
|
285
|
-
rb_raise(eDuckDBError, "failed to append null");
|
286
|
-
}
|
287
|
-
return self;
|
265
|
+
return duckdb_state_to_bool_value(duckdb_append_null(ctx->appender));
|
288
266
|
}
|
289
267
|
|
290
|
-
|
291
|
-
static VALUE
|
268
|
+
/* :nodoc: */
|
269
|
+
static VALUE appender__append_default(VALUE self) {
|
292
270
|
rubyDuckDBAppender *ctx;
|
293
271
|
TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
|
294
272
|
|
295
|
-
|
296
|
-
rb_raise(eDuckDBError, "failed to append default");
|
297
|
-
}
|
298
|
-
return self;
|
273
|
+
return duckdb_state_to_bool_value(duckdb_append_default(ctx->appender));
|
299
274
|
}
|
300
|
-
#endif
|
301
275
|
|
302
276
|
/* :nodoc: */
|
303
277
|
static VALUE appender__append_date(VALUE self, VALUE year, VALUE month, VALUE day) {
|
@@ -307,10 +281,7 @@ static VALUE appender__append_date(VALUE self, VALUE year, VALUE month, VALUE da
|
|
307
281
|
TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
|
308
282
|
dt = rbduckdb_to_duckdb_date_from_value(year, month, day);
|
309
283
|
|
310
|
-
|
311
|
-
rb_raise(eDuckDBError, "failed to append date");
|
312
|
-
}
|
313
|
-
return self;
|
284
|
+
return duckdb_state_to_bool_value(duckdb_append_date(ctx->appender, dt));
|
314
285
|
}
|
315
286
|
|
316
287
|
/* :nodoc: */
|
@@ -321,10 +292,7 @@ static VALUE appender__append_interval(VALUE self, VALUE months, VALUE days, VAL
|
|
321
292
|
TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
|
322
293
|
rbduckdb_to_duckdb_interval_from_value(&interval, months, days, micros);
|
323
294
|
|
324
|
-
|
325
|
-
rb_raise(eDuckDBError, "failed to append interval");
|
326
|
-
}
|
327
|
-
return self;
|
295
|
+
return duckdb_state_to_bool_value(duckdb_append_interval(ctx->appender, interval));
|
328
296
|
}
|
329
297
|
|
330
298
|
/* :nodoc: */
|
@@ -335,10 +303,7 @@ static VALUE appender__append_time(VALUE self, VALUE hour, VALUE min, VALUE sec,
|
|
335
303
|
TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
|
336
304
|
time = rbduckdb_to_duckdb_time_from_value(hour, min, sec, micros);
|
337
305
|
|
338
|
-
|
339
|
-
rb_raise(eDuckDBError, "failed to append time");
|
340
|
-
}
|
341
|
-
return self;
|
306
|
+
return duckdb_state_to_bool_value(duckdb_append_time(ctx->appender, time));
|
342
307
|
}
|
343
308
|
|
344
309
|
/* :nodoc: */
|
@@ -351,10 +316,7 @@ static VALUE appender__append_timestamp(VALUE self, VALUE year, VALUE month, VAL
|
|
351
316
|
|
352
317
|
timestamp = rbduckdb_to_duckdb_timestamp_from_value(year, month, day, hour, min, sec, micros);
|
353
318
|
|
354
|
-
|
355
|
-
rb_raise(eDuckDBError, "failed to append timestamp");
|
356
|
-
}
|
357
|
-
return self;
|
319
|
+
return duckdb_state_to_bool_value(duckdb_append_timestamp(ctx->appender, timestamp));
|
358
320
|
}
|
359
321
|
|
360
322
|
/* :nodoc: */
|
@@ -367,10 +329,8 @@ static VALUE appender__append_hugeint(VALUE self, VALUE lower, VALUE upper) {
|
|
367
329
|
rubyDuckDBAppender *ctx;
|
368
330
|
|
369
331
|
TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
|
370
|
-
|
371
|
-
|
372
|
-
}
|
373
|
-
return self;
|
332
|
+
|
333
|
+
return duckdb_state_to_bool_value(duckdb_append_hugeint(ctx->appender, hugeint));
|
374
334
|
}
|
375
335
|
|
376
336
|
/* :nodoc: */
|
@@ -383,10 +343,8 @@ static VALUE appender__append_uhugeint(VALUE self, VALUE lower, VALUE upper) {
|
|
383
343
|
rubyDuckDBAppender *ctx;
|
384
344
|
|
385
345
|
TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
|
386
|
-
|
387
|
-
|
388
|
-
}
|
389
|
-
return self;
|
346
|
+
|
347
|
+
return duckdb_state_to_bool_value(duckdb_append_uhugeint(ctx->appender, uhugeint));
|
390
348
|
}
|
391
349
|
|
392
350
|
/* :nodoc: */
|
@@ -420,20 +378,6 @@ void rbduckdb_init_duckdb_appender(void) {
|
|
420
378
|
rb_define_alloc_func(cDuckDBAppender, allocate);
|
421
379
|
rb_define_method(cDuckDBAppender, "initialize", appender_initialize, 3);
|
422
380
|
rb_define_method(cDuckDBAppender, "error_message", appender_error_message, 0);
|
423
|
-
rb_define_method(cDuckDBAppender, "append_uint16", appender_append_uint16, 1);
|
424
|
-
rb_define_method(cDuckDBAppender, "append_uint32", appender_append_uint32, 1);
|
425
|
-
rb_define_method(cDuckDBAppender, "append_uint64", appender_append_uint64, 1);
|
426
|
-
rb_define_method(cDuckDBAppender, "append_float", appender_append_float, 1);
|
427
|
-
rb_define_method(cDuckDBAppender, "append_double", appender_append_double, 1);
|
428
|
-
rb_define_method(cDuckDBAppender, "append_varchar", appender_append_varchar, 1);
|
429
|
-
rb_define_method(cDuckDBAppender, "append_varchar_length", appender_append_varchar_length, 2);
|
430
|
-
rb_define_method(cDuckDBAppender, "append_blob", appender_append_blob, 1);
|
431
|
-
rb_define_method(cDuckDBAppender, "append_null", appender_append_null, 0);
|
432
|
-
|
433
|
-
#ifdef HAVE_DUCKDB_H_GE_V1_1_0
|
434
|
-
rb_define_method(cDuckDBAppender, "append_default", appender_append_default, 0);
|
435
|
-
#endif
|
436
|
-
|
437
381
|
rb_define_private_method(cDuckDBAppender, "_end_row", appender__end_row, 0);
|
438
382
|
rb_define_private_method(cDuckDBAppender, "_flush", appender__flush, 0);
|
439
383
|
rb_define_private_method(cDuckDBAppender, "_close", appender__close, 0);
|
@@ -443,6 +387,16 @@ void rbduckdb_init_duckdb_appender(void) {
|
|
443
387
|
rb_define_private_method(cDuckDBAppender, "_append_int32", appender__append_int32, 1);
|
444
388
|
rb_define_private_method(cDuckDBAppender, "_append_int64", appender__append_int64, 1);
|
445
389
|
rb_define_private_method(cDuckDBAppender, "_append_uint8", appender__append_uint8, 1);
|
390
|
+
rb_define_private_method(cDuckDBAppender, "_append_uint16", appender__append_uint16, 1);
|
391
|
+
rb_define_private_method(cDuckDBAppender, "_append_uint32", appender__append_uint32, 1);
|
392
|
+
rb_define_private_method(cDuckDBAppender, "_append_uint64", appender__append_uint64, 1);
|
393
|
+
rb_define_private_method(cDuckDBAppender, "_append_float", appender__append_float, 1);
|
394
|
+
rb_define_private_method(cDuckDBAppender, "_append_double", appender__append_double, 1);
|
395
|
+
rb_define_private_method(cDuckDBAppender, "_append_varchar", appender__append_varchar, 1);
|
396
|
+
rb_define_private_method(cDuckDBAppender, "_append_varchar_length", appender__append_varchar_length, 2);
|
397
|
+
rb_define_private_method(cDuckDBAppender, "_append_blob", appender__append_blob, 1);
|
398
|
+
rb_define_private_method(cDuckDBAppender, "_append_null", appender__append_null, 0);
|
399
|
+
rb_define_private_method(cDuckDBAppender, "_append_default", appender__append_default, 0);
|
446
400
|
rb_define_private_method(cDuckDBAppender, "_append_date", appender__append_date, 3);
|
447
401
|
rb_define_private_method(cDuckDBAppender, "_append_interval", appender__append_interval, 3);
|
448
402
|
rb_define_private_method(cDuckDBAppender, "_append_time", appender__append_time, 4);
|
data/ext/duckdb/extconf.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'mkmf'
|
4
4
|
|
5
|
-
DUCKDB_REQUIRED_VERSION = '1.
|
5
|
+
DUCKDB_REQUIRED_VERSION = '1.1.0'
|
6
6
|
|
7
7
|
def check_duckdb_header(header, version)
|
8
8
|
found = find_header(
|
@@ -56,14 +56,14 @@ end
|
|
56
56
|
dir_config('duckdb')
|
57
57
|
|
58
58
|
check_duckdb_header('duckdb.h', DUCKDB_REQUIRED_VERSION)
|
59
|
-
check_duckdb_library('duckdb', '
|
60
|
-
|
61
|
-
# check duckdb >= 1.0.0
|
62
|
-
have_func('duckdb_fetch_chunk', 'duckdb.h')
|
59
|
+
check_duckdb_library('duckdb', 'duckdb_result_error_type', DUCKDB_REQUIRED_VERSION)
|
63
60
|
|
64
61
|
# check duckdb >= 1.1.0
|
65
62
|
have_func('duckdb_result_error_type', 'duckdb.h')
|
66
63
|
|
64
|
+
# check duckdb >= 1.2.0
|
65
|
+
have_func('duckdb_create_instance_cache', 'duckdb.h')
|
66
|
+
|
67
67
|
# Building with enabled DUCKDB_API_NO_DEPRECATED is failed with DuckDB v1.1.0 only.
|
68
68
|
# DuckDB v1.1.1 is fixed this issue https://github.com/duckdb/duckdb/issues/13872.
|
69
69
|
have_const('DUCKDB_TYPE_SQLNULL', 'duckdb.h')
|
data/ext/duckdb/logical_type.c
CHANGED
@@ -8,10 +8,16 @@ static size_t memsize(const void *p);
|
|
8
8
|
static VALUE duckdb_logical_type__type(VALUE self);
|
9
9
|
static VALUE duckdb_logical_type_width(VALUE self);
|
10
10
|
static VALUE duckdb_logical_type_scale(VALUE self);
|
11
|
+
static VALUE duckdb_logical_type_child_count(VALUE self);
|
12
|
+
static VALUE duckdb_logical_type_child_name_at(VALUE self, VALUE cidx);
|
11
13
|
static VALUE duckdb_logical_type_child_type(VALUE self);
|
14
|
+
static VALUE duckdb_logical_type_child_type_at(VALUE self, VALUE cidx);
|
12
15
|
static VALUE duckdb_logical_type_size(VALUE self);
|
13
16
|
static VALUE duckdb_logical_type_key_type(VALUE self);
|
14
17
|
static VALUE duckdb_logical_type_value_type(VALUE self);
|
18
|
+
static VALUE duckdb_logical_type_member_count(VALUE self);
|
19
|
+
static VALUE duckdb_logical_type_member_name_at(VALUE self, VALUE midx);
|
20
|
+
static VALUE duckdb_logical_type_member_type_at(VALUE self, VALUE midx);
|
15
21
|
|
16
22
|
static const rb_data_type_t logical_type_data_type = {
|
17
23
|
"DuckDB/LogicalType",
|
@@ -77,6 +83,43 @@ static VALUE duckdb_logical_type_scale(VALUE self) {
|
|
77
83
|
return INT2FIX(duckdb_decimal_scale(ctx->logical_type));
|
78
84
|
}
|
79
85
|
|
86
|
+
/*
|
87
|
+
* call-seq:
|
88
|
+
* struct_col.logical_type.child_count -> Integer
|
89
|
+
*
|
90
|
+
* Returns the number of children of a struct type, otherwise 0.
|
91
|
+
*
|
92
|
+
*/
|
93
|
+
static VALUE duckdb_logical_type_child_count(VALUE self) {
|
94
|
+
rubyDuckDBLogicalType *ctx;
|
95
|
+
TypedData_Get_Struct(self, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
|
96
|
+
return INT2FIX(duckdb_struct_type_child_count(ctx->logical_type));
|
97
|
+
}
|
98
|
+
|
99
|
+
/*
|
100
|
+
* call-seq:
|
101
|
+
* struct_col.logical_type.child_name(index) -> String
|
102
|
+
*
|
103
|
+
* Returns the name of the struct child at the specified index.
|
104
|
+
*
|
105
|
+
*/
|
106
|
+
static VALUE duckdb_logical_type_child_name_at(VALUE self, VALUE cidx) {
|
107
|
+
rubyDuckDBLogicalType *ctx;
|
108
|
+
VALUE cname;
|
109
|
+
const char *child_name;
|
110
|
+
idx_t idx = NUM2ULL(cidx);
|
111
|
+
|
112
|
+
TypedData_Get_Struct(self, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
|
113
|
+
|
114
|
+
child_name = duckdb_struct_type_child_name(ctx->logical_type, idx);
|
115
|
+
if (child_name == NULL) {
|
116
|
+
rb_raise(eDuckDBError, "fail to get name of %llu child", (unsigned long long)idx);
|
117
|
+
}
|
118
|
+
cname = rb_str_new_cstr(child_name);
|
119
|
+
duckdb_free((void *)child_name);
|
120
|
+
return cname;
|
121
|
+
}
|
122
|
+
|
80
123
|
/*
|
81
124
|
* call-seq:
|
82
125
|
* list_col.logical_type.child_type -> DuckDB::LogicalType
|
@@ -109,6 +152,31 @@ static VALUE duckdb_logical_type_child_type(VALUE self) {
|
|
109
152
|
return logical_type;
|
110
153
|
}
|
111
154
|
|
155
|
+
/*
|
156
|
+
* call-seq:
|
157
|
+
* struct_col.logical_type.child_type_at(index) -> DuckDB::LogicalType
|
158
|
+
*
|
159
|
+
* Returns the child logical type for struct types at the specified index as a
|
160
|
+
* DuckDB::LogicalType object.
|
161
|
+
*
|
162
|
+
*/
|
163
|
+
static VALUE duckdb_logical_type_child_type_at(VALUE self, VALUE cidx) {
|
164
|
+
rubyDuckDBLogicalType *ctx;
|
165
|
+
duckdb_logical_type struct_child_type;
|
166
|
+
idx_t idx = NUM2ULL(cidx);
|
167
|
+
|
168
|
+
TypedData_Get_Struct(self, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
|
169
|
+
|
170
|
+
struct_child_type = duckdb_struct_type_child_type(ctx->logical_type, idx);
|
171
|
+
if (struct_child_type == NULL) {
|
172
|
+
rb_raise(eDuckDBError,
|
173
|
+
"Failed to get the struct child type at index %llu",
|
174
|
+
(unsigned long long)idx);
|
175
|
+
}
|
176
|
+
|
177
|
+
return rbduckdb_create_logical_type(struct_child_type);
|
178
|
+
}
|
179
|
+
|
112
180
|
/*
|
113
181
|
* call-seq:
|
114
182
|
* list_col.logical_type.size -> Integer
|
@@ -158,6 +226,68 @@ static VALUE duckdb_logical_type_value_type(VALUE self) {
|
|
158
226
|
return logical_type;
|
159
227
|
}
|
160
228
|
|
229
|
+
/*
|
230
|
+
* call-seq:
|
231
|
+
* member_col.logical_type.member_count -> Integer
|
232
|
+
*
|
233
|
+
* Returns the member count of union type, otherwise 0.
|
234
|
+
*
|
235
|
+
*/
|
236
|
+
static VALUE duckdb_logical_type_member_count(VALUE self) {
|
237
|
+
rubyDuckDBLogicalType *ctx;
|
238
|
+
TypedData_Get_Struct(self, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
|
239
|
+
return INT2FIX(duckdb_union_type_member_count(ctx->logical_type));
|
240
|
+
}
|
241
|
+
|
242
|
+
/*
|
243
|
+
* call-seq:
|
244
|
+
* union_col.logical_type.member_name_at(index) -> String
|
245
|
+
*
|
246
|
+
* Returns the name of the union member at the specified index.
|
247
|
+
*
|
248
|
+
*/
|
249
|
+
static VALUE duckdb_logical_type_member_name_at(VALUE self, VALUE midx) {
|
250
|
+
rubyDuckDBLogicalType *ctx;
|
251
|
+
VALUE mname;
|
252
|
+
const char *member_name;
|
253
|
+
idx_t idx = NUM2ULL(midx);
|
254
|
+
|
255
|
+
TypedData_Get_Struct(self, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
|
256
|
+
|
257
|
+
member_name = duckdb_union_type_member_name(ctx->logical_type, idx);
|
258
|
+
if (member_name == NULL) {
|
259
|
+
rb_raise(eDuckDBError, "fail to get name of %llu member", (unsigned long long)idx);
|
260
|
+
}
|
261
|
+
mname = rb_str_new_cstr(member_name);
|
262
|
+
duckdb_free((void *)member_name);
|
263
|
+
return mname;
|
264
|
+
}
|
265
|
+
|
266
|
+
/*
|
267
|
+
* call-seq:
|
268
|
+
* union_col.logical_type.member_type_at(index) -> DuckDB::LogicalType
|
269
|
+
*
|
270
|
+
* Returns the logical type of the union member at the specified index as a
|
271
|
+
* DuckDB::LogicalType object.
|
272
|
+
*
|
273
|
+
*/
|
274
|
+
static VALUE duckdb_logical_type_member_type_at(VALUE self, VALUE midx) {
|
275
|
+
rubyDuckDBLogicalType *ctx;
|
276
|
+
duckdb_logical_type union_member_type;
|
277
|
+
idx_t idx = NUM2ULL(midx);
|
278
|
+
|
279
|
+
TypedData_Get_Struct(self, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
|
280
|
+
|
281
|
+
union_member_type = duckdb_union_type_member_type(ctx->logical_type, idx);
|
282
|
+
if (union_member_type == NULL) {
|
283
|
+
rb_raise(eDuckDBError,
|
284
|
+
"Failed to get the union member type at index %llu",
|
285
|
+
(unsigned long long)idx);
|
286
|
+
}
|
287
|
+
|
288
|
+
return rbduckdb_create_logical_type(union_member_type);
|
289
|
+
}
|
290
|
+
|
161
291
|
VALUE rbduckdb_create_logical_type(duckdb_logical_type logical_type) {
|
162
292
|
VALUE obj;
|
163
293
|
rubyDuckDBLogicalType *ctx;
|
@@ -180,8 +310,14 @@ void rbduckdb_init_duckdb_logical_type(void) {
|
|
180
310
|
rb_define_private_method(cDuckDBLogicalType, "_type", duckdb_logical_type__type, 0);
|
181
311
|
rb_define_method(cDuckDBLogicalType, "width", duckdb_logical_type_width, 0);
|
182
312
|
rb_define_method(cDuckDBLogicalType, "scale", duckdb_logical_type_scale, 0);
|
313
|
+
rb_define_method(cDuckDBLogicalType, "child_count", duckdb_logical_type_child_count, 0);
|
314
|
+
rb_define_method(cDuckDBLogicalType, "child_name_at", duckdb_logical_type_child_name_at, 1);
|
183
315
|
rb_define_method(cDuckDBLogicalType, "child_type", duckdb_logical_type_child_type, 0);
|
316
|
+
rb_define_method(cDuckDBLogicalType, "child_type_at", duckdb_logical_type_child_type_at, 1);
|
184
317
|
rb_define_method(cDuckDBLogicalType, "size", duckdb_logical_type_size, 0);
|
185
318
|
rb_define_method(cDuckDBLogicalType, "key_type", duckdb_logical_type_key_type, 0);
|
186
319
|
rb_define_method(cDuckDBLogicalType, "value_type", duckdb_logical_type_value_type, 0);
|
320
|
+
rb_define_method(cDuckDBLogicalType, "member_count", duckdb_logical_type_member_count, 0);
|
321
|
+
rb_define_method(cDuckDBLogicalType, "member_name_at", duckdb_logical_type_member_name_at, 1);
|
322
|
+
rb_define_method(cDuckDBLogicalType, "member_type_at", duckdb_logical_type_member_type_at, 1);
|
187
323
|
}
|
@@ -32,6 +32,7 @@ static VALUE duckdb_prepared_statement__bind_time(VALUE self, VALUE vidx, VALUE
|
|
32
32
|
static VALUE duckdb_prepared_statement__bind_timestamp(VALUE self, VALUE vidx, VALUE year, VALUE month, VALUE day, VALUE hour, VALUE min, VALUE sec, VALUE micros);
|
33
33
|
static VALUE duckdb_prepared_statement__bind_interval(VALUE self, VALUE vidx, VALUE months, VALUE days, VALUE micros);
|
34
34
|
static VALUE duckdb_prepared_statement__bind_hugeint(VALUE self, VALUE vidx, VALUE lower, VALUE upper);
|
35
|
+
static VALUE duckdb_prepared_statement__bind_uhugeint(VALUE self, VALUE vidx, VALUE lower, VALUE upper);
|
35
36
|
static VALUE duckdb_prepared_statement__bind_decimal(VALUE self, VALUE vidx, VALUE lower, VALUE upper, VALUE width, VALUE scale);
|
36
37
|
|
37
38
|
static const rb_data_type_t prepared_statement_data_type = {
|
@@ -121,6 +122,7 @@ static VALUE duckdb_prepared_statement_execute(VALUE self) {
|
|
121
122
|
rubyDuckDBResult *ctxr;
|
122
123
|
const char *error;
|
123
124
|
VALUE result = rbduckdb_create_result();
|
125
|
+
VALUE msg;
|
124
126
|
|
125
127
|
TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
|
126
128
|
ctxr = get_struct_result(result);
|
@@ -135,12 +137,13 @@ static VALUE duckdb_prepared_statement_execute(VALUE self) {
|
|
135
137
|
duckdb_state state = args.retval;
|
136
138
|
|
137
139
|
if (state == DuckDBError) {
|
138
|
-
error =
|
140
|
+
error = duckdb_prepare_error(args.prepared_statement);
|
139
141
|
if (error == NULL) {
|
140
|
-
error =
|
142
|
+
error = duckdb_result_error(args.out_result);
|
141
143
|
}
|
144
|
+
msg = rb_str_new2(error ? error : "Failed to execute prepared statement.");
|
142
145
|
|
143
|
-
rb_raise(eDuckDBError, "%s",
|
146
|
+
rb_raise(eDuckDBError, "%s", StringValuePtr(msg));
|
144
147
|
}
|
145
148
|
|
146
149
|
return result;
|
@@ -439,6 +442,23 @@ static VALUE duckdb_prepared_statement__bind_hugeint(VALUE self, VALUE vidx, VAL
|
|
439
442
|
return self;
|
440
443
|
}
|
441
444
|
|
445
|
+
/* :nodoc: */
|
446
|
+
static VALUE duckdb_prepared_statement__bind_uhugeint(VALUE self, VALUE vidx, VALUE lower, VALUE upper) {
|
447
|
+
duckdb_uhugeint uhugeint;
|
448
|
+
rubyDuckDBPreparedStatement *ctx;
|
449
|
+
idx_t idx = check_index(vidx);
|
450
|
+
|
451
|
+
TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
|
452
|
+
uhugeint.lower = NUM2ULL(lower);
|
453
|
+
uhugeint.upper = NUM2ULL(upper);
|
454
|
+
|
455
|
+
if (duckdb_bind_uhugeint(ctx->prepared_statement, idx, uhugeint) == DuckDBError) {
|
456
|
+
rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx);
|
457
|
+
}
|
458
|
+
|
459
|
+
return self;
|
460
|
+
}
|
461
|
+
|
442
462
|
/* :nodoc: */
|
443
463
|
static VALUE duckdb_prepared_statement__bind_decimal(VALUE self, VALUE vidx, VALUE lower, VALUE upper, VALUE width, VALUE scale) {
|
444
464
|
duckdb_hugeint hugeint;
|
@@ -498,5 +518,6 @@ void rbduckdb_init_duckdb_prepared_statement(void) {
|
|
498
518
|
rb_define_private_method(cDuckDBPreparedStatement, "_bind_timestamp", duckdb_prepared_statement__bind_timestamp, 8);
|
499
519
|
rb_define_private_method(cDuckDBPreparedStatement, "_bind_interval", duckdb_prepared_statement__bind_interval, 4);
|
500
520
|
rb_define_private_method(cDuckDBPreparedStatement, "_bind_hugeint", duckdb_prepared_statement__bind_hugeint, 3);
|
521
|
+
rb_define_private_method(cDuckDBPreparedStatement, "_bind_uhugeint", duckdb_prepared_statement__bind_uhugeint, 3);
|
501
522
|
rb_define_private_method(cDuckDBPreparedStatement, "_bind_decimal", duckdb_prepared_statement__bind_decimal, 5);
|
502
523
|
}
|
data/ext/duckdb/result.c
CHANGED
@@ -279,7 +279,7 @@ static VALUE duckdb_result__return_type(VALUE oDuckDBResult) {
|
|
279
279
|
/*
|
280
280
|
* remove this #if ... #else statement when dropping duckdb 1.1.0.
|
281
281
|
*/
|
282
|
-
#if !defined(HAVE_DUCKDB_H_GE_V1_1_1) && defined(
|
282
|
+
#if !defined(HAVE_DUCKDB_H_GE_V1_1_1) && defined(DUCKDB_API_NO_DEPRECATED)
|
283
283
|
rb_raise(eDuckDBError, "duckdb_result_return_type C-API is not available with duckdb v1.1.0 with enabled DUCKDB_API_NO_DEPRECATED.");
|
284
284
|
#else
|
285
285
|
return INT2FIX(duckdb_result_return_type(ctx->result));
|
data/ext/duckdb/ruby-duckdb.h
CHANGED
@@ -8,18 +8,14 @@
|
|
8
8
|
#include "ruby/thread.h"
|
9
9
|
#include <duckdb.h>
|
10
10
|
|
11
|
-
#ifdef HAVE_DUCKDB_FETCH_CHUNK
|
12
|
-
#define HAVE_DUCKDB_H_GE_V1_0_0 1
|
13
|
-
#endif
|
14
|
-
|
15
|
-
#ifdef HAVE_DUCKDB_RESULT_ERROR_TYPE
|
16
|
-
#define HAVE_DUCKDB_H_GE_V1_1_0 1
|
17
|
-
#endif
|
18
|
-
|
19
11
|
#ifdef HAVE_CONST_DUCKDB_TYPE_SQLNULL
|
20
12
|
#define HAVE_DUCKDB_H_GE_V1_1_1 1
|
21
13
|
#endif
|
22
14
|
|
15
|
+
#ifdef HAVE_DUCKDB_CREATE_INSTANCE_CACHE
|
16
|
+
#define HAVE_DUCKDB_H_GE_V1_2_0 1
|
17
|
+
#endif
|
18
|
+
|
23
19
|
#include "./error.h"
|
24
20
|
#include "./database.h"
|
25
21
|
#include "./connection.h"
|
data/lib/duckdb/appender.rb
CHANGED
@@ -203,27 +203,235 @@ module DuckDB
|
|
203
203
|
end
|
204
204
|
|
205
205
|
# call-seq:
|
206
|
-
#
|
206
|
+
# appender.append_uint8(val) -> self
|
207
207
|
#
|
208
208
|
# Appends an uint8 value to the current row in the appender.
|
209
209
|
#
|
210
|
-
#
|
211
|
-
#
|
212
|
-
#
|
213
|
-
#
|
214
|
-
#
|
215
|
-
#
|
216
|
-
#
|
217
|
-
#
|
218
|
-
#
|
219
|
-
#
|
210
|
+
# require 'duckdb'
|
211
|
+
# db = DuckDB::Database.open
|
212
|
+
# con = db.connect
|
213
|
+
# con.query('CREATE TABLE users (id INTEGER, age UTINYINT)')
|
214
|
+
# appender = con.appender('users')
|
215
|
+
# appender
|
216
|
+
# .append_int32(1)
|
217
|
+
# .append_uint8(20)
|
218
|
+
# .end_row
|
219
|
+
# .flush
|
220
220
|
def append_uint8(value)
|
221
221
|
return self if _append_uint8(value)
|
222
222
|
|
223
223
|
raise_appender_error('failed to append_uint8')
|
224
224
|
end
|
225
225
|
|
226
|
-
#
|
226
|
+
# call-seq:
|
227
|
+
# appender.append_uint16(val) -> self
|
228
|
+
#
|
229
|
+
# Appends an uint16 value to the current row in the appender.
|
230
|
+
#
|
231
|
+
# require 'duckdb'
|
232
|
+
# db = DuckDB::Database.open
|
233
|
+
# con = db.connect
|
234
|
+
# con.query('CREATE TABLE users (id INTEGER, age USMALLINT)')
|
235
|
+
# appender = con.appender('users')
|
236
|
+
# appender
|
237
|
+
# .append_int32(1)
|
238
|
+
# .append_uint16(20)
|
239
|
+
# .end_row
|
240
|
+
# .flush
|
241
|
+
def append_uint16(value)
|
242
|
+
return self if _append_uint16(value)
|
243
|
+
|
244
|
+
raise_appender_error('failed to append_uint16')
|
245
|
+
end
|
246
|
+
|
247
|
+
# call-seq:
|
248
|
+
# appender.append_uint32(val) -> self
|
249
|
+
#
|
250
|
+
# Appends an uint32 value to the current row in the appender.
|
251
|
+
#
|
252
|
+
# require 'duckdb'
|
253
|
+
# db = DuckDB::Database.open
|
254
|
+
# con = db.connect
|
255
|
+
# con.query('CREATE TABLE users (id INTEGER, age UINTEGER)')
|
256
|
+
# appender = con.appender('users')
|
257
|
+
# appender
|
258
|
+
# .append_int32(1)
|
259
|
+
# .append_uint32(20)
|
260
|
+
# .end_row
|
261
|
+
# .flush
|
262
|
+
def append_uint32(value)
|
263
|
+
return self if _append_uint32(value)
|
264
|
+
|
265
|
+
raise_appender_error('failed to append_uint32')
|
266
|
+
end
|
267
|
+
|
268
|
+
# call-seq:
|
269
|
+
# appender.append_uint64(val) -> self
|
270
|
+
#
|
271
|
+
# Appends an uint64 value to the current row in the appender.
|
272
|
+
#
|
273
|
+
# require 'duckdb'
|
274
|
+
# db = DuckDB::Database.open
|
275
|
+
# con = db.connect
|
276
|
+
# con.query('CREATE TABLE users (id INTEGER, age UBIGINT)')
|
277
|
+
# appender = con.appender('users')
|
278
|
+
# Appender
|
279
|
+
# .append_int32(1)
|
280
|
+
# .append_uint64(20)
|
281
|
+
# .end_row
|
282
|
+
# .flush
|
283
|
+
def append_uint64(value)
|
284
|
+
return self if _append_uint64(value)
|
285
|
+
|
286
|
+
raise_appender_error('failed to append_uint64')
|
287
|
+
end
|
288
|
+
|
289
|
+
# call-seq:
|
290
|
+
# appender.append_float(val) -> self
|
291
|
+
#
|
292
|
+
# Appends a float value to the current row in the appender.
|
293
|
+
#
|
294
|
+
# require 'duckdb'
|
295
|
+
# db = DuckDB::Database.open
|
296
|
+
# con = db.connect
|
297
|
+
# con.query('CREATE TABLE numbers (num FLOAT)')
|
298
|
+
# appender = con.appender('numbers')
|
299
|
+
# appender
|
300
|
+
# .append_float(1.23)
|
301
|
+
# .end_row
|
302
|
+
# .flush
|
303
|
+
def append_float(value)
|
304
|
+
return self if _append_float(value)
|
305
|
+
|
306
|
+
raise_appender_error('failed to append_float')
|
307
|
+
end
|
308
|
+
|
309
|
+
# call-seq:
|
310
|
+
# appender.append_double(val) -> self
|
311
|
+
#
|
312
|
+
# Appends a double value to the current row in the appender.
|
313
|
+
#
|
314
|
+
# require 'duckdb'
|
315
|
+
# db = DuckDB::Database.open
|
316
|
+
# con = db.connect
|
317
|
+
# con.query('CREATE TABLE numbers (num DOUBLE)')
|
318
|
+
# appender = con.appender('numbers')
|
319
|
+
# appender
|
320
|
+
# .append_double(1.23)
|
321
|
+
# .end_row
|
322
|
+
# .flush
|
323
|
+
def append_double(value)
|
324
|
+
return self if _append_double(value)
|
325
|
+
|
326
|
+
raise_appender_error('failed to append_double')
|
327
|
+
end
|
328
|
+
|
329
|
+
# call-seq:
|
330
|
+
# appender.append_varchar(val) -> self
|
331
|
+
#
|
332
|
+
# Appends a varchar value to the current row in the appender.
|
333
|
+
#
|
334
|
+
# require 'duckdb'
|
335
|
+
# db = DuckDB::Database.open
|
336
|
+
# con = db.connect
|
337
|
+
# con.query('CREATE TABLE names (name VARCHAR)')
|
338
|
+
# appender = con.appender('names')
|
339
|
+
# appender
|
340
|
+
# .append_varchar('Alice')
|
341
|
+
# .end_row
|
342
|
+
# .flush
|
343
|
+
def append_varchar(value)
|
344
|
+
return self if _append_varchar(value)
|
345
|
+
|
346
|
+
raise_appender_error('failed to append_varchar')
|
347
|
+
end
|
348
|
+
|
349
|
+
# call-seq:
|
350
|
+
# appender.append_varchar_length(val, len) -> self
|
351
|
+
#
|
352
|
+
# Appends a varchar value to the current row in the appender.
|
353
|
+
#
|
354
|
+
# require 'duckdb'
|
355
|
+
# db = DuckDB::Database.open
|
356
|
+
# con = db.connect
|
357
|
+
# con.query('CREATE TABLE names (name VARCHAR)')
|
358
|
+
# appender = con.appender('names')
|
359
|
+
# appender
|
360
|
+
# .append_varchar_length('Alice', 5)
|
361
|
+
# .end_row
|
362
|
+
# .flush
|
363
|
+
def append_varchar_length(value, length)
|
364
|
+
return self if _append_varchar_length(value, length)
|
365
|
+
|
366
|
+
raise_appender_error('failed to append_varchar_length')
|
367
|
+
end
|
368
|
+
|
369
|
+
# call-seq:
|
370
|
+
# appender.append_blob(val) -> self
|
371
|
+
#
|
372
|
+
# Appends a varchar value to the current row in the appender.
|
373
|
+
#
|
374
|
+
# require 'duckdb'
|
375
|
+
# db = DuckDB::Database.open
|
376
|
+
# con = db.connect
|
377
|
+
# con.query('CREATE TABLE values (value BLOB)')
|
378
|
+
# appender = con.appender('values')
|
379
|
+
# appender
|
380
|
+
# .append('\0\1\2\3\4\5'.encode(Encoding::BINARY))
|
381
|
+
# .end_row
|
382
|
+
# .flush
|
383
|
+
def append_blob(value)
|
384
|
+
return self if _append_blob(value)
|
385
|
+
|
386
|
+
raise_appender_error('failed to append_blob')
|
387
|
+
end
|
388
|
+
|
389
|
+
# call-seq:
|
390
|
+
# appender.append_null -> self
|
391
|
+
#
|
392
|
+
# Appends a NULL value to the current row in the appender.
|
393
|
+
#
|
394
|
+
# require 'duckdb'
|
395
|
+
# db = DuckDB::Database.open
|
396
|
+
# con = db.connect
|
397
|
+
# con.query('CREATE TABLE values (value INTEGER)')
|
398
|
+
# appender = con.appender('values')
|
399
|
+
# appender
|
400
|
+
# .append_null
|
401
|
+
# .end_row
|
402
|
+
# .flush
|
403
|
+
def append_null
|
404
|
+
return self if _append_null
|
405
|
+
|
406
|
+
raise_appender_error('failed to append_null')
|
407
|
+
end
|
408
|
+
|
409
|
+
# call-seq:
|
410
|
+
# appender.append_default -> self
|
411
|
+
#
|
412
|
+
# Appends a default value to the current row in the appender.
|
413
|
+
# If the column does not have a default value, this method
|
414
|
+
# appends a NULL value.
|
415
|
+
#
|
416
|
+
# require 'duckdb'
|
417
|
+
# db = DuckDB::Database.open
|
418
|
+
# con = db.connect
|
419
|
+
# con.query('CREATE TABLE values (value INTEGER DEFAULT 1)')
|
420
|
+
# appender = con.appender('values')
|
421
|
+
# appender
|
422
|
+
# .append_default
|
423
|
+
# .end_row
|
424
|
+
# .flush
|
425
|
+
def append_default
|
426
|
+
return self if _append_default
|
427
|
+
|
428
|
+
raise_appender_error('failed to append_default')
|
429
|
+
end
|
430
|
+
|
431
|
+
# call-seq:
|
432
|
+
# appender.append_hugeint(val) -> self
|
433
|
+
#
|
434
|
+
# Appends a huge int value to the current row in the appender.
|
227
435
|
#
|
228
436
|
# require 'duckdb'
|
229
437
|
# db = DuckDB::Database.open
|
@@ -233,12 +441,19 @@ module DuckDB
|
|
233
441
|
# appender
|
234
442
|
# .append_hugeint(-170_141_183_460_469_231_731_687_303_715_884_105_727)
|
235
443
|
# .end_row
|
444
|
+
# .flush
|
236
445
|
def append_hugeint(value)
|
237
446
|
lower, upper = integer_to_hugeint(value)
|
238
|
-
|
447
|
+
|
448
|
+
return self if _append_hugeint(lower, upper)
|
449
|
+
|
450
|
+
raise_appender_error('failed to append_hugeint')
|
239
451
|
end
|
240
452
|
|
241
|
-
#
|
453
|
+
# call-seq:
|
454
|
+
# appender.append_uhugeint(val) -> self
|
455
|
+
#
|
456
|
+
# Appends an unsigned huge int value to the current row in the appender.
|
242
457
|
#
|
243
458
|
# require 'duckdb'
|
244
459
|
# db = DuckDB::Database.open
|
@@ -248,12 +463,19 @@ module DuckDB
|
|
248
463
|
# appender
|
249
464
|
# .append_hugeint(340_282_366_920_938_463_463_374_607_431_768_211_455)
|
250
465
|
# .end_row
|
466
|
+
# .flush
|
251
467
|
def append_uhugeint(value)
|
252
468
|
lower, upper = integer_to_hugeint(value)
|
253
|
-
|
469
|
+
|
470
|
+
return self if _append_uhugeint(lower, upper)
|
471
|
+
|
472
|
+
raise_appender_error('failed to append_uhugeint')
|
254
473
|
end
|
255
474
|
|
256
|
-
#
|
475
|
+
# call-seq:
|
476
|
+
# appender.append_date(val) -> self
|
477
|
+
#
|
478
|
+
# Appends a date value to the current row in the appender.
|
257
479
|
#
|
258
480
|
# require 'duckdb'
|
259
481
|
# db = DuckDB::Database.open
|
@@ -269,10 +491,15 @@ module DuckDB
|
|
269
491
|
def append_date(value)
|
270
492
|
date = _parse_date(value)
|
271
493
|
|
272
|
-
_append_date(date.year, date.month, date.day)
|
494
|
+
return self if _append_date(date.year, date.month, date.day)
|
495
|
+
|
496
|
+
raise_appender_error('failed to append_date')
|
273
497
|
end
|
274
498
|
|
275
|
-
#
|
499
|
+
# call-seq:
|
500
|
+
# appender.append_time(val) -> self
|
501
|
+
#
|
502
|
+
# Appends a time value to the current row in the appender.
|
276
503
|
#
|
277
504
|
# require 'duckdb'
|
278
505
|
# db = DuckDB::Database.open
|
@@ -287,10 +514,15 @@ module DuckDB
|
|
287
514
|
def append_time(value)
|
288
515
|
time = _parse_time(value)
|
289
516
|
|
290
|
-
_append_time(time.hour, time.min, time.sec, time.usec)
|
517
|
+
return self if _append_time(time.hour, time.min, time.sec, time.usec)
|
518
|
+
|
519
|
+
raise_appender_error('failed to append_time')
|
291
520
|
end
|
292
521
|
|
293
|
-
#
|
522
|
+
# call-seq:
|
523
|
+
# appender.append_timestamp(val) -> self
|
524
|
+
#
|
525
|
+
# Appends a timestamp value to the current row in the appender.
|
294
526
|
#
|
295
527
|
# require 'duckdb'
|
296
528
|
# db = DuckDB::Database.open
|
@@ -306,12 +538,16 @@ module DuckDB
|
|
306
538
|
def append_timestamp(value)
|
307
539
|
time = to_time(value)
|
308
540
|
|
309
|
-
_append_timestamp(time.year, time.month, time.day, time.hour, time.min, time.sec, time.nsec / 1000)
|
541
|
+
return self if _append_timestamp(time.year, time.month, time.day, time.hour, time.min, time.sec, time.nsec / 1000)
|
542
|
+
|
543
|
+
raise_appender_error('failed to append_timestamp')
|
310
544
|
end
|
311
545
|
|
312
|
-
#
|
546
|
+
# call-seq:
|
547
|
+
# appender.append_interval(val) -> self
|
548
|
+
#
|
549
|
+
# Appends an interval value to the current row in the appender.
|
313
550
|
# The argument must be ISO8601 duration format.
|
314
|
-
# WARNING: This method is expremental.
|
315
551
|
#
|
316
552
|
# require 'duckdb'
|
317
553
|
# db = DuckDB::Database.open
|
@@ -324,7 +560,10 @@ module DuckDB
|
|
324
560
|
# .flush
|
325
561
|
def append_interval(value)
|
326
562
|
value = Interval.to_interval(value)
|
327
|
-
|
563
|
+
|
564
|
+
return self if _append_interval(value.interval_months, value.interval_days, value.interval_micros)
|
565
|
+
|
566
|
+
raise_appender_error('failed to append_interval')
|
328
567
|
end
|
329
568
|
|
330
569
|
# appends value.
|
data/lib/duckdb/logical_type.rb
CHANGED
@@ -18,5 +18,93 @@ module DuckDB
|
|
18
18
|
type_id = _type
|
19
19
|
DuckDB::Converter::IntToSym.type_to_sym(type_id)
|
20
20
|
end
|
21
|
+
|
22
|
+
# Iterates over each union member name.
|
23
|
+
#
|
24
|
+
# When a block is provided, this method yields each union member name in
|
25
|
+
# order. It also returns the total number of members yielded.
|
26
|
+
#
|
27
|
+
# union_logical_type.each_member_name do |name|
|
28
|
+
# puts "Union member: #{name}"
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# If no block is given, an Enumerator is returned, which can be used to
|
32
|
+
# retrieve all member names.
|
33
|
+
#
|
34
|
+
# names = union_logical_type.each_member_name.to_a
|
35
|
+
# # => ["member1", "member2"]
|
36
|
+
def each_member_name
|
37
|
+
return to_enum(__method__) {member_count} unless block_given?
|
38
|
+
|
39
|
+
member_count.times do |i|
|
40
|
+
yield member_name_at(i)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Iterates over each union member type.
|
45
|
+
#
|
46
|
+
# When a block is provided, this method yields each union member logical
|
47
|
+
# type in order. It also returns the total number of members yielded.
|
48
|
+
#
|
49
|
+
# union_logical_type.each_member_type do |logical_type|
|
50
|
+
# puts "Union member: #{logical_type.type}"
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
# If no block is given, an Enumerator is returned, which can be used to
|
54
|
+
# retrieve all member logical types.
|
55
|
+
#
|
56
|
+
# names = union_logical_type.each_member_type.map(&:type)
|
57
|
+
# # => [:varchar, :integer]
|
58
|
+
def each_member_type
|
59
|
+
return to_enum(__method__) {member_count} unless block_given?
|
60
|
+
|
61
|
+
member_count.times do |i|
|
62
|
+
yield member_type_at(i)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Iterates over each struct child name.
|
67
|
+
#
|
68
|
+
# When a block is provided, this method yields each struct child name in
|
69
|
+
# order. It also returns the total number of children yielded.
|
70
|
+
#
|
71
|
+
# struct_logical_type.each_child_name do |name|
|
72
|
+
# puts "Struct child: #{name}"
|
73
|
+
# end
|
74
|
+
#
|
75
|
+
# If no block is given, an Enumerator is returned, which can be used to
|
76
|
+
# retrieve all child names.
|
77
|
+
#
|
78
|
+
# names = struct_logical_type.each_child_name.to_a
|
79
|
+
# # => ["child1", "child2"]
|
80
|
+
def each_child_name
|
81
|
+
return to_enum(__method__) {child_count} unless block_given?
|
82
|
+
|
83
|
+
child_count.times do |i|
|
84
|
+
yield child_name_at(i)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Iterates over each struct child type.
|
89
|
+
#
|
90
|
+
# When a block is provided, this method yields each struct child type in
|
91
|
+
# order. It also returns the total number of children yielded.
|
92
|
+
#
|
93
|
+
# struct_logical_type.each_child_type do |logical_type|
|
94
|
+
# puts "Struct child type: #{logical_type.type}"
|
95
|
+
# end
|
96
|
+
#
|
97
|
+
# If no block is given, an Enumerator is returned, which can be used to
|
98
|
+
# retrieve all child logical types.
|
99
|
+
#
|
100
|
+
# types = struct_logical_type.each_child_type.map(&:type)
|
101
|
+
# # => [:integer, :varchar]
|
102
|
+
def each_child_type
|
103
|
+
return to_enum(__method__) {child_count} unless block_given?
|
104
|
+
|
105
|
+
child_count.times do |i|
|
106
|
+
yield child_type_at(i)
|
107
|
+
end
|
108
|
+
end
|
21
109
|
end
|
22
110
|
end
|
@@ -135,7 +135,7 @@ module DuckDB
|
|
135
135
|
# require 'duckdb'
|
136
136
|
# db = DuckDB::Database.open('duckdb_database')
|
137
137
|
# con = db.connect
|
138
|
-
# sql ='SELECT name FROM users WHERE
|
138
|
+
# sql ='SELECT name FROM users WHERE hugeint_col = ?'
|
139
139
|
# stmt = PreparedStatement.new(con, sql)
|
140
140
|
# stmt.bind_hugeint_internal(1, 1_234_567_890_123_456_789_012_345)
|
141
141
|
def bind_hugeint_internal(index, value)
|
@@ -143,6 +143,23 @@ module DuckDB
|
|
143
143
|
_bind_hugeint(index, lower, upper)
|
144
144
|
end
|
145
145
|
|
146
|
+
# binds i-th parameter with SQL prepared statement.
|
147
|
+
# The first argument is index of parameter.
|
148
|
+
# The index of first parameter is 1 not 0.
|
149
|
+
# The second argument value must be Integer value.
|
150
|
+
# This method uses duckdb_bind_uhugeint internally.
|
151
|
+
#
|
152
|
+
# require 'duckdb'
|
153
|
+
# db = DuckDB::Database.open('duckdb_database')
|
154
|
+
# con = db.connect
|
155
|
+
# sql ='SELECT name FROM users WHERE uhugeint_col = ?'
|
156
|
+
# stmt = PreparedStatement.new(con, sql)
|
157
|
+
# stmt.bind_uhugeint(1, (2**128) - 1)
|
158
|
+
def bind_uhugeint(index, value)
|
159
|
+
lower, upper = integer_to_hugeint(value)
|
160
|
+
_bind_uhugeint(index, lower, upper)
|
161
|
+
end
|
162
|
+
|
146
163
|
# binds i-th parameter with SQL prepared statement.
|
147
164
|
# The first argument is index of parameter.
|
148
165
|
# The index of first parameter is 1 not 0.
|
data/lib/duckdb/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: duckdb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Masaki Suketa
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
10
|
+
date: 2025-03-29 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: bigdecimal
|