duckdb 2.0.0.0 → 2.0.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ee2e890f808c2ff97b099f79c12f17a8fe856253b13a3ee2378bbb21306e3587
4
- data.tar.gz: a7081554ee0ff1ebb22d688f9aafab9b434c93cb080f2abcc7ffe1e9ae3f70d1
3
+ metadata.gz: dce0a7e743dbaec8c7efce887915aa63b07814dd1552fe2030d9a3b993b4e76b
4
+ data.tar.gz: aa663e1016c3562af385b24488511835c8f7bb2fbb82a23ad45982d059d12af4
5
5
  SHA512:
6
- metadata.gz: b13a967b1e810a51220080b227b8b6dd5098e56775567b049ed722ec3a9dec02f3fe97c399fbd8a88e292bc65888ce905ef5b908f182e110abf785d2ff2aa94e
7
- data.tar.gz: ff96826d03f74eedb1633bc5256addb916abd737741636918748d0fcd65c0527669100b96103beff430184a6a8b21b4387fffb2351888898c1729c4c335d01be
6
+ metadata.gz: 27b9ad500f23e294806e7d957d05f804e1102a37c2c6fbbfb009421b3c1301f04dbe09acecc015247221265fcdc6bafa8dda243bee76cec4ae641a17a9e63417
7
+ data.tar.gz: 052a875e216cd582f90ae339fb43c93d9609190715545ebe83409ed6e0907d752114d0ee8e347d121814c55baa3944b0bcf78101c67c475b621aa49f43f4ff34
data/CHANGELOG.md CHANGED
@@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  # Unreleased
6
6
 
7
+ # 2.0.0.1 - 2026-10-25
8
+ - `DuckDB::PreparedStatement#bind_decimal` (and `#bind` with a `BigDecimal`) raises `ArgumentError` when the DECIMAL width is out of range (1..38), instead of aborting the process or binding a wrong value.
9
+ - raise `RangeError` instead of aborting the process when a result contains a TIMESTAMP value before `-9223372022400000000` microseconds (near INT64_MIN).
10
+ - raise `RangeError` instead of aborting the process when an out-of-range date or timestamp is passed to `bind_date`, `bind_timestamp`, `bind_timestamp_tz`, `Appender#append_date`, `Appender#append_timestamp`, `DuckDB::Value.create_date`, `DuckDB::Value.create_timestamp*`, or returned from a UDF.
11
+
7
12
  # 2.0.0.0 - 2026-10-24
8
13
  - bump Ruby to 4.0.9 on CI (Ubuntu and macOS).
9
14
  - bump up DuckDB 2.0.0 on CI.
@@ -487,13 +487,7 @@ static VALUE update_process_rows(VALUE varg) {
487
487
  * a GC, and the earlier columns' objects must stay reachable. */
488
488
  VALUE args = rb_ary_new_capa((long)arg->col_count + 1);
489
489
 
490
- arg->input_vectors = ALLOC_N(duckdb_vector, arg->col_count);
491
- arg->input_types = ALLOC_N(duckdb_logical_type, arg->col_count);
492
-
493
- for (j = 0; j < arg->col_count; j++) {
494
- arg->input_vectors[j] = duckdb_data_chunk_get_vector(arg->input, j);
495
- arg->input_types[j] = duckdb_vector_get_column_type(arg->input_vectors[j]);
496
- }
490
+ rbduckdb_input_columns_load(arg->input, arg->col_count, &arg->input_vectors, &arg->input_types);
497
491
 
498
492
  for (i = 0; i < arg->row_count; i++) {
499
493
  ruby_aggregate_state *state = arg->constant_states ? states[0] : states[i];
@@ -557,17 +551,8 @@ static VALUE update_process_rows(VALUE varg) {
557
551
 
558
552
  static VALUE update_cleanup_callback(VALUE varg) {
559
553
  struct update_callback_arg *arg = (struct update_callback_arg *)varg;
560
- idx_t j;
561
554
 
562
- if (arg->input_types != NULL) {
563
- for (j = 0; j < arg->col_count; j++) {
564
- duckdb_destroy_logical_type(&arg->input_types[j]);
565
- }
566
- xfree(arg->input_types);
567
- }
568
- if (arg->input_vectors != NULL) {
569
- xfree(arg->input_vectors);
570
- }
555
+ rbduckdb_input_columns_free(arg->input_vectors, arg->input_types, arg->col_count);
571
556
 
572
557
  return Qnil;
573
558
  }
@@ -598,23 +583,39 @@ static void execute_update_callback_protected(void *user_data) {
598
583
  }
599
584
  }
600
585
 
586
+ /*
587
+ * Shared preamble for update/combine/finalize callbacks: returns the context,
588
+ * or NULL (after setting a DuckDB error if the proc is missing).
589
+ * A missing proc is reached only if _set_init was called directly (bypassing
590
+ * the Ruby wrapper); raise rather than silently misbehave or SIGSEGV.
591
+ */
592
+ static rubyDuckDBAggregateFunction *aggregate_ctx_with_proc(duckdb_function_info info,
593
+ size_t proc_offset,
594
+ const char *missing_msg) {
595
+ rubyDuckDBAggregateFunction *ctx;
596
+
597
+ ctx = (rubyDuckDBAggregateFunction *)duckdb_aggregate_function_get_extra_info(info);
598
+ if (ctx == NULL) {
599
+ return NULL;
600
+ }
601
+ if (*(VALUE *)((char *)ctx + proc_offset) == Qnil) {
602
+ duckdb_aggregate_function_set_error(info, missing_msg);
603
+ return NULL;
604
+ }
605
+ return ctx;
606
+ }
607
+
601
608
  static void update_callback(duckdb_function_info info,
602
609
  duckdb_data_chunk input,
603
610
  duckdb_aggregate_state *states) {
604
611
  rubyDuckDBAggregateFunction *ctx;
605
612
  struct update_callback_arg arg;
606
613
 
607
- ctx = (rubyDuckDBAggregateFunction *)duckdb_aggregate_function_get_extra_info(info);
614
+ ctx = aggregate_ctx_with_proc(info, offsetof(rubyDuckDBAggregateFunction, update_proc),
615
+ "update callback invoked with no update proc set");
608
616
  if (ctx == NULL) {
609
617
  return;
610
618
  }
611
- if (ctx->update_proc == Qnil) {
612
- /* Reached only if _set_init was called directly (bypassing the Ruby
613
- * wrapper) without setting an update proc. Raise rather than silently
614
- * leaving state unchanged. */
615
- duckdb_aggregate_function_set_error(info, "update callback invoked with no update proc set");
616
- return;
617
- }
618
619
 
619
620
  arg.ctx = ctx;
620
621
  arg.info = info;
@@ -694,16 +695,11 @@ static void combine_callback(duckdb_function_info info,
694
695
  rubyDuckDBAggregateFunction *ctx;
695
696
  struct combine_callback_arg arg;
696
697
 
697
- ctx = (rubyDuckDBAggregateFunction *)duckdb_aggregate_function_get_extra_info(info);
698
+ ctx = aggregate_ctx_with_proc(info, offsetof(rubyDuckDBAggregateFunction, combine_proc),
699
+ "combine callback invoked with no combine proc set");
698
700
  if (ctx == NULL) {
699
701
  return;
700
702
  }
701
- if (ctx->combine_proc == Qnil) {
702
- /* Reached only if _set_init was called directly (bypassing the Ruby
703
- * wrapper) without setting a combine proc. Raise rather than SIGSEGV. */
704
- duckdb_aggregate_function_set_error(info, "combine callback invoked with no combine proc set");
705
- return;
706
- }
707
703
 
708
704
  arg.ctx = ctx;
709
705
  arg.info = info;
@@ -805,16 +801,11 @@ static void finalize_callback(duckdb_function_info info,
805
801
  rubyDuckDBAggregateFunction *ctx;
806
802
  struct finalize_callback_arg arg;
807
803
 
808
- ctx = (rubyDuckDBAggregateFunction *)duckdb_aggregate_function_get_extra_info(info);
804
+ ctx = aggregate_ctx_with_proc(info, offsetof(rubyDuckDBAggregateFunction, finalize_proc),
805
+ "finalize callback invoked with no finalize proc set");
809
806
  if (ctx == NULL) {
810
807
  return;
811
808
  }
812
- if (ctx->finalize_proc == Qnil) {
813
- /* Reached only if _set_init was called directly (bypassing the Ruby
814
- * wrapper) without setting a finalize proc. Raise rather than SIGSEGV. */
815
- duckdb_aggregate_function_set_error(info, "finalize callback invoked with no finalize proc set");
816
- return;
817
- }
818
809
 
819
810
  arg.ctx = ctx;
820
811
  arg.info = info;
@@ -886,8 +877,7 @@ static void maybe_set_functions(rubyDuckDBAggregateFunction *p) {
886
877
  rbduckdb_function_executor_ensure_started();
887
878
  }
888
879
 
889
- /* :nodoc: */
890
- static VALUE aggregate_function__set_init(VALUE self) {
880
+ static VALUE aggregate_function_store_block_proc(VALUE self, size_t slot_offset) {
891
881
  rubyDuckDBAggregateFunction *p;
892
882
 
893
883
  if (!rb_block_given_p()) {
@@ -895,7 +885,7 @@ static VALUE aggregate_function__set_init(VALUE self) {
895
885
  }
896
886
 
897
887
  TypedData_Get_Struct(self, rubyDuckDBAggregateFunction, &aggregate_function_data_type, p);
898
- RB_OBJ_WRITE(self, &p->init_proc, rb_block_proc());
888
+ RB_OBJ_WRITE(self, (VALUE *)((char *)p + slot_offset), rb_block_proc());
899
889
 
900
890
  maybe_set_functions(p);
901
891
 
@@ -903,51 +893,23 @@ static VALUE aggregate_function__set_init(VALUE self) {
903
893
  }
904
894
 
905
895
  /* :nodoc: */
906
- static VALUE aggregate_function__set_update(VALUE self) {
907
- rubyDuckDBAggregateFunction *p;
908
-
909
- if (!rb_block_given_p()) {
910
- rb_raise(rb_eArgError, "block is required");
911
- }
912
-
913
- TypedData_Get_Struct(self, rubyDuckDBAggregateFunction, &aggregate_function_data_type, p);
914
- RB_OBJ_WRITE(self, &p->update_proc, rb_block_proc());
915
-
916
- maybe_set_functions(p);
896
+ static VALUE aggregate_function__set_init(VALUE self) {
897
+ return aggregate_function_store_block_proc(self, offsetof(rubyDuckDBAggregateFunction, init_proc));
898
+ }
917
899
 
918
- return self;
900
+ /* :nodoc: */
901
+ static VALUE aggregate_function__set_update(VALUE self) {
902
+ return aggregate_function_store_block_proc(self, offsetof(rubyDuckDBAggregateFunction, update_proc));
919
903
  }
920
904
 
921
905
  /* :nodoc: */
922
906
  static VALUE aggregate_function__set_combine(VALUE self) {
923
- rubyDuckDBAggregateFunction *p;
924
-
925
- if (!rb_block_given_p()) {
926
- rb_raise(rb_eArgError, "block is required");
927
- }
928
-
929
- TypedData_Get_Struct(self, rubyDuckDBAggregateFunction, &aggregate_function_data_type, p);
930
- RB_OBJ_WRITE(self, &p->combine_proc, rb_block_proc());
931
-
932
- maybe_set_functions(p);
933
-
934
- return self;
907
+ return aggregate_function_store_block_proc(self, offsetof(rubyDuckDBAggregateFunction, combine_proc));
935
908
  }
936
909
 
937
910
  /* :nodoc: */
938
911
  static VALUE aggregate_function__set_finalize(VALUE self) {
939
- rubyDuckDBAggregateFunction *p;
940
-
941
- if (!rb_block_given_p()) {
942
- rb_raise(rb_eArgError, "block is required");
943
- }
944
-
945
- TypedData_Get_Struct(self, rubyDuckDBAggregateFunction, &aggregate_function_data_type, p);
946
- RB_OBJ_WRITE(self, &p->finalize_proc, rb_block_proc());
947
-
948
- maybe_set_functions(p);
949
-
950
- return self;
912
+ return aggregate_function_store_block_proc(self, offsetof(rubyDuckDBAggregateFunction, finalize_proc));
951
913
  }
952
914
 
953
915
  /* :nodoc: */
@@ -78,6 +78,12 @@ static VALUE allocate(VALUE klass) {
78
78
  return TypedData_Wrap_Struct(klass, &appender_data_type, ctx);
79
79
  }
80
80
 
81
+ static duckdb_appender appender_of(VALUE self) {
82
+ rubyDuckDBAppender *ctx;
83
+ TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
84
+ return ctx->appender;
85
+ }
86
+
81
87
  static size_t memsize(const void *p) {
82
88
  return sizeof(rubyDuckDBAppender);
83
89
  }
@@ -219,13 +225,11 @@ static VALUE appender__initialize_ext(VALUE self, VALUE con, VALUE catalog, VALU
219
225
  * appender.error_message # => nil
220
226
  */
221
227
  static VALUE appender_error_message(VALUE self) {
222
- rubyDuckDBAppender *ctx;
223
228
  duckdb_error_data error_data;
224
229
  const char *msg = NULL;
225
230
  VALUE rb_msg = Qnil;
226
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
227
231
 
228
- error_data = duckdb_appender_error_data(ctx->appender);
232
+ error_data = duckdb_appender_error_data(appender_of(self));
229
233
  if (duckdb_error_data_has_error(error_data)) {
230
234
  msg = duckdb_error_data_message(error_data);
231
235
  rb_msg = rb_str_new2(msg);
@@ -236,220 +240,159 @@ static VALUE appender_error_message(VALUE self) {
236
240
 
237
241
  /* :nodoc: */
238
242
  static VALUE appender__end_row(VALUE self) {
239
- rubyDuckDBAppender *ctx;
240
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
241
-
242
- return state_to_rbool(duckdb_appender_end_row(ctx->appender));
243
+ return state_to_rbool(duckdb_appender_end_row(appender_of(self)));
243
244
  }
244
245
 
245
246
  /* :nodoc: */
246
247
  static VALUE appender__append_bool(VALUE self, VALUE val) {
247
- rubyDuckDBAppender *ctx;
248
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
249
-
250
248
  if (val != Qtrue && val != Qfalse) {
251
249
  rb_raise(rb_eArgError, "argument must be boolean");
252
250
  }
253
251
 
254
- return state_to_rbool(duckdb_append_bool(ctx->appender, (val == Qtrue)));
252
+ return state_to_rbool(duckdb_append_bool(appender_of(self), (val == Qtrue)));
255
253
  }
256
254
 
257
255
  /* :nodoc: */
258
256
  static VALUE appender__append_int8(VALUE self, VALUE val) {
259
- rubyDuckDBAppender *ctx;
260
257
  int8_t i8val = (int8_t)NUM2INT(val);
261
258
 
262
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
263
-
264
- return state_to_rbool(duckdb_append_int8(ctx->appender, i8val));
259
+ return state_to_rbool(duckdb_append_int8(appender_of(self), i8val));
265
260
  }
266
261
 
267
262
  /* :nodoc: */
268
263
  static VALUE appender__append_int16(VALUE self, VALUE val) {
269
- rubyDuckDBAppender *ctx;
270
264
  int16_t i16val = (int16_t)NUM2INT(val);
271
265
 
272
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
273
-
274
- return state_to_rbool(duckdb_append_int16(ctx->appender, i16val));
266
+ return state_to_rbool(duckdb_append_int16(appender_of(self), i16val));
275
267
  }
276
268
 
277
269
  /* :nodoc: */
278
270
  static VALUE appender__append_int32(VALUE self, VALUE val) {
279
- rubyDuckDBAppender *ctx;
280
271
  int32_t i32val = (int32_t)NUM2INT(val);
281
272
 
282
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
283
-
284
- return state_to_rbool(duckdb_append_int32(ctx->appender, i32val));
273
+ return state_to_rbool(duckdb_append_int32(appender_of(self), i32val));
285
274
  }
286
275
 
287
276
  /* :nodoc: */
288
277
  static VALUE appender__append_int64(VALUE self, VALUE val) {
289
- rubyDuckDBAppender *ctx;
290
278
  int64_t i64val = (int64_t)NUM2LL(val);
291
279
 
292
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
293
-
294
- return state_to_rbool(duckdb_append_int64(ctx->appender, i64val));
280
+ return state_to_rbool(duckdb_append_int64(appender_of(self), i64val));
295
281
  }
296
282
 
297
283
  /* :nodoc: */
298
284
  static VALUE appender__append_uint8(VALUE self, VALUE val) {
299
- rubyDuckDBAppender *ctx;
300
285
  uint8_t ui8val = (uint8_t)NUM2UINT(val);
301
286
 
302
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
303
-
304
- return state_to_rbool(duckdb_append_uint8(ctx->appender, ui8val));
287
+ return state_to_rbool(duckdb_append_uint8(appender_of(self), ui8val));
305
288
  }
306
289
 
307
290
  /* :nodoc: */
308
291
  static VALUE appender__append_uint16(VALUE self, VALUE val) {
309
- rubyDuckDBAppender *ctx;
310
292
  uint16_t ui16val = (uint16_t)NUM2UINT(val);
311
293
 
312
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
313
-
314
- return state_to_rbool(duckdb_append_uint16(ctx->appender, ui16val));
294
+ return state_to_rbool(duckdb_append_uint16(appender_of(self), ui16val));
315
295
  }
316
296
 
317
297
  /* :nodoc: */
318
298
  static VALUE appender__append_uint32(VALUE self, VALUE val) {
319
- rubyDuckDBAppender *ctx;
320
299
  uint32_t ui32val = (uint32_t)NUM2UINT(val);
321
300
 
322
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
323
-
324
- return state_to_rbool(duckdb_append_uint32(ctx->appender, ui32val));
301
+ return state_to_rbool(duckdb_append_uint32(appender_of(self), ui32val));
325
302
  }
326
303
 
327
304
  /* :nodoc: */
328
305
  static VALUE appender__append_uint64(VALUE self, VALUE val) {
329
- rubyDuckDBAppender *ctx;
330
306
  uint64_t ui64val = (uint64_t)NUM2ULL(val);
331
307
 
332
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
333
-
334
- return state_to_rbool(duckdb_append_uint64(ctx->appender, ui64val));
308
+ return state_to_rbool(duckdb_append_uint64(appender_of(self), ui64val));
335
309
  }
336
310
 
337
311
  /* :nodoc: */
338
312
  static VALUE appender__append_float(VALUE self, VALUE val) {
339
- rubyDuckDBAppender *ctx;
340
313
  float fval = (float)NUM2DBL(val);
341
314
 
342
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
343
-
344
- return state_to_rbool(duckdb_append_float(ctx->appender, fval));
315
+ return state_to_rbool(duckdb_append_float(appender_of(self), fval));
345
316
  }
346
317
 
347
318
  /* :nodoc: */
348
319
  static VALUE appender__append_double(VALUE self, VALUE val) {
349
- rubyDuckDBAppender *ctx;
350
320
  double dval = NUM2DBL(val);
351
321
 
352
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
353
-
354
- return state_to_rbool(duckdb_append_double(ctx->appender, dval));
322
+ return state_to_rbool(duckdb_append_double(appender_of(self), dval));
355
323
  }
356
324
 
357
325
  /* :nodoc: */
358
326
  static VALUE appender__append_varchar(VALUE self, VALUE val) {
359
- rubyDuckDBAppender *ctx;
360
327
  /* Length-aware, as duckdb_append_varchar would stop at an embedded NUL. */
361
328
  char *pval = StringValuePtr(val);
362
329
  long len = RSTRING_LEN(val);
363
330
 
364
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
365
-
366
- return state_to_rbool(duckdb_append_varchar_length(ctx->appender, pval, (idx_t)len));
331
+ return state_to_rbool(duckdb_append_varchar_length(appender_of(self), pval, (idx_t)len));
367
332
  }
368
333
 
369
334
  /* :nodoc: */
370
335
  static VALUE appender__append_varchar_length(VALUE self, VALUE val, VALUE len) {
371
- rubyDuckDBAppender *ctx;
372
336
 
373
337
  char *pval = StringValuePtr(val);
374
338
  idx_t length = (idx_t)NUM2ULL(len);
375
339
 
376
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
377
-
378
- return state_to_rbool(duckdb_append_varchar_length(ctx->appender, pval, length));
340
+ return state_to_rbool(duckdb_append_varchar_length(appender_of(self), pval, length));
379
341
  }
380
342
 
381
343
  /* :nodoc: */
382
344
  static VALUE appender__append_blob(VALUE self, VALUE val) {
383
- rubyDuckDBAppender *ctx;
384
345
 
385
346
  char *pval = StringValuePtr(val);
386
347
  idx_t length = (idx_t)RSTRING_LEN(val);
387
348
 
388
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
389
-
390
- return state_to_rbool(duckdb_append_blob(ctx->appender, (void *)pval, length));
349
+ return state_to_rbool(duckdb_append_blob(appender_of(self), (void *)pval, length));
391
350
  }
392
351
 
393
352
  /* :nodoc: */
394
353
  static VALUE appender__append_null(VALUE self) {
395
- rubyDuckDBAppender *ctx;
396
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
397
-
398
- return state_to_rbool(duckdb_append_null(ctx->appender));
354
+ return state_to_rbool(duckdb_append_null(appender_of(self)));
399
355
  }
400
356
 
401
357
  /* :nodoc: */
402
358
  static VALUE appender__append_default(VALUE self) {
403
- rubyDuckDBAppender *ctx;
404
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
405
-
406
- return state_to_rbool(duckdb_append_default(ctx->appender));
359
+ return state_to_rbool(duckdb_append_default(appender_of(self)));
407
360
  }
408
361
 
409
362
  /* :nodoc: */
410
363
  static VALUE appender__append_date(VALUE self, VALUE year, VALUE month, VALUE day) {
411
364
  duckdb_date dt;
412
- rubyDuckDBAppender *ctx;
413
365
 
414
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
415
366
  dt = rbduckdb_to_duckdb_date_from_value(year, month, day);
416
367
 
417
- return state_to_rbool(duckdb_append_date(ctx->appender, dt));
368
+ return state_to_rbool(duckdb_append_date(appender_of(self), dt));
418
369
  }
419
370
 
420
371
  /* :nodoc: */
421
372
  static VALUE appender__append_interval(VALUE self, VALUE months, VALUE days, VALUE micros) {
422
373
  duckdb_interval interval;
423
- rubyDuckDBAppender *ctx;
424
374
 
425
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
426
375
  rbduckdb_to_duckdb_interval_from_value(&interval, months, days, micros);
427
376
 
428
- return state_to_rbool(duckdb_append_interval(ctx->appender, interval));
377
+ return state_to_rbool(duckdb_append_interval(appender_of(self), interval));
429
378
  }
430
379
 
431
380
  /* :nodoc: */
432
381
  static VALUE appender__append_time(VALUE self, VALUE hour, VALUE min, VALUE sec, VALUE micros) {
433
382
  duckdb_time time;
434
- rubyDuckDBAppender *ctx;
435
383
 
436
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
437
384
  time = rbduckdb_to_duckdb_time_from_value(hour, min, sec, micros);
438
385
 
439
- return state_to_rbool(duckdb_append_time(ctx->appender, time));
386
+ return state_to_rbool(duckdb_append_time(appender_of(self), time));
440
387
  }
441
388
 
442
389
  /* :nodoc: */
443
390
  static VALUE appender__append_timestamp(VALUE self, VALUE year, VALUE month, VALUE day, VALUE hour, VALUE min, VALUE sec, VALUE micros) {
444
391
  duckdb_timestamp timestamp;
445
392
 
446
- rubyDuckDBAppender *ctx;
447
-
448
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
449
-
450
393
  timestamp = rbduckdb_to_duckdb_timestamp_from_value(year, month, day, hour, min, sec, micros);
451
394
 
452
- return state_to_rbool(duckdb_append_timestamp(ctx->appender, timestamp));
395
+ return state_to_rbool(duckdb_append_timestamp(appender_of(self), timestamp));
453
396
  }
454
397
 
455
398
  /* :nodoc: */
@@ -459,11 +402,7 @@ static VALUE appender__append_hugeint(VALUE self, VALUE lower, VALUE upper) {
459
402
  hugeint.lower = NUM2ULL(lower);
460
403
  hugeint.upper = NUM2LL(upper);
461
404
 
462
- rubyDuckDBAppender *ctx;
463
-
464
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
465
-
466
- return state_to_rbool(duckdb_append_hugeint(ctx->appender, hugeint));
405
+ return state_to_rbool(duckdb_append_hugeint(appender_of(self), hugeint));
467
406
  }
468
407
 
469
408
  /* :nodoc: */
@@ -473,102 +412,76 @@ static VALUE appender__append_uhugeint(VALUE self, VALUE lower, VALUE upper) {
473
412
  uhugeint.lower = NUM2ULL(lower);
474
413
  uhugeint.upper = NUM2ULL(upper);
475
414
 
476
- rubyDuckDBAppender *ctx;
477
-
478
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
479
-
480
- return state_to_rbool(duckdb_append_uhugeint(ctx->appender, uhugeint));
415
+ return state_to_rbool(duckdb_append_uhugeint(appender_of(self), uhugeint));
481
416
  }
482
417
 
483
418
  /* :nodoc: */
484
419
  static VALUE appender__append_uuid(VALUE self, VALUE val) {
485
- rubyDuckDBAppender *ctx;
486
420
  duckdb_uhugeint uhugeint;
487
421
  duckdb_value uuid_val;
488
422
  duckdb_state state;
489
423
 
490
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
491
424
  rbduckdb_uuid_str_to_uhugeint(val, &uhugeint);
492
425
  uuid_val = duckdb_create_uuid(uhugeint);
493
- state = duckdb_append_value(ctx->appender, uuid_val);
426
+ state = duckdb_append_value(appender_of(self), uuid_val);
494
427
  duckdb_destroy_value(&uuid_val);
495
428
  return state_to_rbool(state);
496
429
  }
497
430
 
498
431
  /* :nodoc: */
499
432
  static VALUE appender__append_value(VALUE self, VALUE val) {
500
- rubyDuckDBAppender *ctx;
501
433
  rubyDuckDBValue *value_ctx;
502
434
 
503
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
504
435
  value_ctx = rbduckdb_get_struct_value(val);
505
436
 
506
- return state_to_rbool(duckdb_append_value(ctx->appender, value_ctx->value));
437
+ return state_to_rbool(duckdb_append_value(appender_of(self), value_ctx->value));
507
438
  }
508
439
 
509
440
  /* :nodoc: */
510
441
  static VALUE appender__append_data_chunk(VALUE self, VALUE chunk) {
511
- rubyDuckDBAppender *ctx;
512
442
  rubyDuckDBDataChunk *chunk_ctx;
513
443
 
514
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
515
444
  chunk_ctx = rbduckdb_get_struct_data_chunk(chunk);
516
445
 
517
- return state_to_rbool(duckdb_append_data_chunk(ctx->appender, chunk_ctx->data_chunk));
446
+ return state_to_rbool(duckdb_append_data_chunk(appender_of(self), chunk_ctx->data_chunk));
518
447
  }
519
448
 
520
449
  /* :nodoc: */
521
450
  static VALUE appender__append_default_to_chunk(VALUE self, VALUE chunk, VALUE col, VALUE row) {
522
- rubyDuckDBAppender *ctx;
523
451
  rubyDuckDBDataChunk *chunk_ctx;
524
452
 
525
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
526
453
  chunk_ctx = rbduckdb_get_struct_data_chunk(chunk);
527
454
 
528
- return state_to_rbool(duckdb_append_default_to_chunk(ctx->appender, chunk_ctx->data_chunk, NUM2ULL(col), NUM2ULL(row)));
455
+ return state_to_rbool(duckdb_append_default_to_chunk(appender_of(self), chunk_ctx->data_chunk, NUM2ULL(col), NUM2ULL(row)));
529
456
  }
530
457
 
531
458
  /* :nodoc: */
532
459
  static VALUE appender__flush(VALUE self) {
533
- rubyDuckDBAppender *ctx;
534
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
535
-
536
- return state_to_rbool(duckdb_appender_flush(ctx->appender));
460
+ return state_to_rbool(duckdb_appender_flush(appender_of(self)));
537
461
  }
538
462
 
539
463
  #ifdef HAVE_DUCKDB_H_GE_V1_5_0
540
464
  /* :nodoc: */
541
465
  static VALUE appender__clear(VALUE self) {
542
- rubyDuckDBAppender *ctx;
543
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
544
-
545
- return state_to_rbool(duckdb_appender_clear(ctx->appender));
466
+ return state_to_rbool(duckdb_appender_clear(appender_of(self)));
546
467
  }
547
468
  #endif
548
469
 
549
470
  /* :nodoc: */
550
471
  static VALUE appender__add_column(VALUE self, VALUE name) {
551
472
  char *p = StringValuePtr(name);
552
- rubyDuckDBAppender *ctx;
553
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
554
473
 
555
- return state_to_rbool(duckdb_appender_add_column(ctx->appender, p));
474
+ return state_to_rbool(duckdb_appender_add_column(appender_of(self), p));
556
475
  }
557
476
 
558
477
  /* :nodoc: */
559
478
  static VALUE appender__clear_columns(VALUE self) {
560
- rubyDuckDBAppender *ctx;
561
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
562
-
563
- return state_to_rbool(duckdb_appender_clear_columns(ctx->appender));
479
+ return state_to_rbool(duckdb_appender_clear_columns(appender_of(self)));
564
480
  }
565
481
 
566
482
  /* :nodoc: */
567
483
  static VALUE appender__close(VALUE self) {
568
- rubyDuckDBAppender *ctx;
569
- TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
570
-
571
- return state_to_rbool(duckdb_appender_close(ctx->appender));
484
+ return state_to_rbool(duckdb_appender_close(appender_of(self)));
572
485
  }
573
486
 
574
487
  static VALUE state_to_rbool(duckdb_state state) {