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.
@@ -251,6 +251,17 @@ static VALUE connection__get_table_names(VALUE self, VALUE query, VALUE qualifie
251
251
  return rbduckdb_value_new(table_names);
252
252
  }
253
253
 
254
+ static VALUE connection_check_registered(VALUE self, duckdb_state state, VALUE obj, const char *kind) {
255
+ if (state == DuckDBError) {
256
+ rb_raise(eDuckDBError, "Failed to register %s", kind);
257
+ }
258
+
259
+ /* Keep reference alive as long as the database can call it */
260
+ connection_retain_registered(self, obj);
261
+
262
+ return self;
263
+ }
264
+
254
265
  /* :nodoc: */
255
266
  static VALUE connection__register_logical_type(VALUE self, VALUE logical_type) {
256
267
  rubyDuckDBConnection *ctxcon;
@@ -261,15 +272,7 @@ static VALUE connection__register_logical_type(VALUE self, VALUE logical_type) {
261
272
  ctxlt = rbduckdb_get_struct_logical_type(logical_type);
262
273
 
263
274
  state = duckdb_register_logical_type(ctxcon->con, ctxlt->logical_type, NULL);
264
-
265
- if (state == DuckDBError) {
266
- rb_raise(eDuckDBError, "Failed to register logical type");
267
- }
268
-
269
- /* Keep reference alive as long as the database can call it */
270
- connection_retain_registered(self, logical_type);
271
-
272
- return self;
275
+ return connection_check_registered(self, state, logical_type, "logical type");
273
276
  }
274
277
 
275
278
  /* :nodoc: */
@@ -282,15 +285,7 @@ static VALUE connection__register_scalar_function(VALUE self, VALUE scalar_funct
282
285
  ctxsf = rbduckdb_get_struct_scalar_function(scalar_function);
283
286
 
284
287
  state = duckdb_register_scalar_function(ctxcon->con, ctxsf->scalar_function);
285
-
286
- if (state == DuckDBError) {
287
- rb_raise(eDuckDBError, "Failed to register scalar function");
288
- }
289
-
290
- /* Keep reference alive as long as the database can call it */
291
- connection_retain_registered(self, scalar_function);
292
-
293
- return self;
288
+ return connection_check_registered(self, state, scalar_function, "scalar function");
294
289
  }
295
290
 
296
291
  /* :nodoc: */
@@ -303,15 +298,7 @@ static VALUE connection__register_scalar_function_set(VALUE self, VALUE scalar_f
303
298
  ctxsfs = rbduckdb_get_struct_scalar_function_set(scalar_function_set);
304
299
 
305
300
  state = duckdb_register_scalar_function_set(ctxcon->con, ctxsfs->scalar_function_set);
306
-
307
- if (state == DuckDBError) {
308
- rb_raise(eDuckDBError, "Failed to register scalar function set");
309
- }
310
-
311
- /* Keep reference alive as long as the database can call it */
312
- connection_retain_registered(self, scalar_function_set);
313
-
314
- return self;
301
+ return connection_check_registered(self, state, scalar_function_set, "scalar function set");
315
302
  }
316
303
 
317
304
  /* :nodoc: */
@@ -324,15 +311,7 @@ static VALUE connection__register_aggregate_function(VALUE self, VALUE aggregate
324
311
  ctxaf = rbduckdb_get_struct_aggregate_function(aggregate_function);
325
312
 
326
313
  state = duckdb_register_aggregate_function(ctxcon->con, ctxaf->aggregate_function);
327
-
328
- if (state == DuckDBError) {
329
- rb_raise(eDuckDBError, "Failed to register aggregate function");
330
- }
331
-
332
- /* Keep reference alive as long as the database can call it */
333
- connection_retain_registered(self, aggregate_function);
334
-
335
- return self;
314
+ return connection_check_registered(self, state, aggregate_function, "aggregate function");
336
315
  }
337
316
 
338
317
  /* :nodoc: */
@@ -345,15 +324,7 @@ static VALUE connection__register_aggregate_function_set(VALUE self, VALUE aggre
345
324
  ctxafs = rbduckdb_get_struct_aggregate_function_set(aggregate_function_set);
346
325
 
347
326
  state = duckdb_register_aggregate_function_set(ctxcon->con, ctxafs->aggregate_function_set);
348
-
349
- if (state == DuckDBError) {
350
- rb_raise(eDuckDBError, "Failed to register aggregate function set");
351
- }
352
-
353
- /* Keep reference alive as long as the database can call it */
354
- connection_retain_registered(self, aggregate_function_set);
355
-
356
- return self;
327
+ return connection_check_registered(self, state, aggregate_function_set, "aggregate function set");
357
328
  }
358
329
 
359
330
  static VALUE connection__register_table_function(VALUE self, VALUE table_function) {
@@ -365,15 +336,7 @@ static VALUE connection__register_table_function(VALUE self, VALUE table_functio
365
336
  ctxtf = rbduckdb_get_struct_table_function(table_function);
366
337
 
367
338
  state = duckdb_register_table_function(ctxcon->con, ctxtf->table_function);
368
-
369
- if (state == DuckDBError) {
370
- rb_raise(eDuckDBError, "Failed to register table function");
371
- }
372
-
373
- /* Keep reference alive as long as the database can call it */
374
- connection_retain_registered(self, table_function);
375
-
376
- return self;
339
+ return connection_check_registered(self, state, table_function, "table function");
377
340
  }
378
341
 
379
342
  void rbduckdb_init_connection(void) {
@@ -17,49 +17,8 @@ ID id__to_time_from_duckdb_timestamp_tz;
17
17
  ID id__to_infinity;
18
18
  ID id__decimal_to_unscaled;
19
19
 
20
- static VALUE infinite_date_value(duckdb_date date) {
21
- if (duckdb_is_finite_date(date) == false) {
22
- return rb_funcall(mDuckDBConverter, id__to_infinity, 1,
23
- INT2NUM(date.days)
24
- );
25
- }
26
- return Qnil;
27
- }
28
-
29
- static VALUE infinite_timestamp_value(duckdb_timestamp timestamp) {
30
- if (duckdb_is_finite_timestamp(timestamp) == false) {
31
- return rb_funcall(mDuckDBConverter, id__to_infinity, 1,
32
- LL2NUM(timestamp.micros)
33
- );
34
- }
35
- return Qnil;
36
- }
37
-
38
- static VALUE infinite_timestamp_s_value(duckdb_timestamp_s timestamp_s) {
39
- if (duckdb_is_finite_timestamp_s(timestamp_s) == false) {
40
- return rb_funcall(mDuckDBConverter, id__to_infinity, 1,
41
- LL2NUM(timestamp_s.seconds)
42
- );
43
- }
44
- return Qnil;
45
- }
46
-
47
- static VALUE infinite_timestamp_ms_value(duckdb_timestamp_ms timestamp_ms) {
48
- if (duckdb_is_finite_timestamp_ms(timestamp_ms) == false) {
49
- return rb_funcall(mDuckDBConverter, id__to_infinity, 1,
50
- LL2NUM(timestamp_ms.millis)
51
- );
52
- }
53
- return Qnil;
54
- }
55
-
56
- static VALUE infinite_timestamp_ns_value(duckdb_timestamp_ns timestamp_ns) {
57
- if (duckdb_is_finite_timestamp_ns(timestamp_ns) == false) {
58
- return rb_funcall(mDuckDBConverter, id__to_infinity, 1,
59
- LL2NUM(timestamp_ns.nanos)
60
- );
61
- }
62
- return Qnil;
20
+ static VALUE ruby_infinity(VALUE raw) {
21
+ return rb_funcall(mDuckDBConverter, id__to_infinity, 1, raw);
63
22
  }
64
23
 
65
24
  #define DUCKDB_UUID_SIGN_BIT 0x8000000000000000ULL
@@ -256,9 +215,8 @@ VALUE rbduckdb_uhugeint_to_ruby(duckdb_uhugeint h) {
256
215
  }
257
216
 
258
217
  VALUE rbduckdb_timestamp_s_to_ruby(duckdb_timestamp_s ts) {
259
- VALUE obj = infinite_timestamp_s_value(ts);
260
- if (obj != Qnil) {
261
- return obj;
218
+ if (!duckdb_is_finite_timestamp_s(ts)) {
219
+ return ruby_infinity(LL2NUM(ts.seconds));
262
220
  }
263
221
  return rb_funcall(mDuckDBConverter, id__to_time_from_duckdb_timestamp_s, 1,
264
222
  LL2NUM(ts.seconds)
@@ -266,9 +224,8 @@ VALUE rbduckdb_timestamp_s_to_ruby(duckdb_timestamp_s ts) {
266
224
  }
267
225
 
268
226
  VALUE rbduckdb_timestamp_ms_to_ruby(duckdb_timestamp_ms ts) {
269
- VALUE obj = infinite_timestamp_ms_value(ts);
270
- if (obj != Qnil) {
271
- return obj;
227
+ if (!duckdb_is_finite_timestamp_ms(ts)) {
228
+ return ruby_infinity(LL2NUM(ts.millis));
272
229
  }
273
230
  return rb_funcall(mDuckDBConverter, id__to_time_from_duckdb_timestamp_ms, 1,
274
231
  LL2NUM(ts.millis)
@@ -276,9 +233,8 @@ VALUE rbduckdb_timestamp_ms_to_ruby(duckdb_timestamp_ms ts) {
276
233
  }
277
234
 
278
235
  VALUE rbduckdb_timestamp_ns_to_ruby(duckdb_timestamp_ns ts) {
279
- VALUE obj = infinite_timestamp_ns_value(ts);
280
- if (obj != Qnil) {
281
- return obj;
236
+ if (!duckdb_is_finite_timestamp_ns(ts)) {
237
+ return ruby_infinity(LL2NUM(ts.nanos));
282
238
  }
283
239
  return rb_funcall(mDuckDBConverter, id__to_time_from_duckdb_timestamp_ns, 1,
284
240
  LL2NUM(ts.nanos)
@@ -319,35 +275,42 @@ VALUE rbduckdb_time_to_ruby(duckdb_time t) {
319
275
  }
320
276
 
321
277
  VALUE rbduckdb_date_to_ruby(duckdb_date date) {
322
- VALUE obj = infinite_date_value(date);
323
-
324
- if (obj == Qnil) {
325
- duckdb_date_struct date_st = duckdb_from_date(date);
326
- obj = rb_funcall(mDuckDBConverter, id__to_date, 3,
327
- INT2FIX(date_st.year),
328
- INT2FIX(date_st.month),
329
- INT2FIX(date_st.day)
330
- );
278
+ duckdb_date_struct date_st;
279
+
280
+ if (!duckdb_is_finite_date(date)) {
281
+ return ruby_infinity(INT2NUM(date.days));
331
282
  }
332
- return obj;
283
+ date_st = duckdb_from_date(date);
284
+ return rb_funcall(mDuckDBConverter, id__to_date, 3,
285
+ INT2FIX(date_st.year),
286
+ INT2FIX(date_st.month),
287
+ INT2FIX(date_st.day)
288
+ );
333
289
  }
334
290
 
335
291
  VALUE rbduckdb_timestamp_to_ruby(duckdb_timestamp ts) {
336
- VALUE obj = infinite_timestamp_value(ts);
337
-
338
- if (obj == Qnil) {
339
- duckdb_timestamp_struct data_st = duckdb_from_timestamp(ts);
340
- obj = rb_funcall(mDuckDBConverter, id__to_time, 7,
341
- INT2FIX(data_st.date.year),
342
- INT2FIX(data_st.date.month),
343
- INT2FIX(data_st.date.day),
344
- INT2FIX(data_st.time.hour),
345
- INT2FIX(data_st.time.min),
346
- INT2FIX(data_st.time.sec),
347
- INT2NUM(data_st.time.micros)
348
- );
292
+ duckdb_timestamp_struct data_st;
293
+
294
+ if (!duckdb_is_finite_timestamp(ts)) {
295
+ return ruby_infinity(LL2NUM(ts.micros));
349
296
  }
350
- return obj;
297
+ /*
298
+ * duckdb_from_timestamp throws a C++ exception below this value
299
+ * (days * MICROS_PER_DAY overflows int64), which would abort the process.
300
+ */
301
+ if (ts.micros < -9223372022400000000LL) {
302
+ rb_raise(rb_eRangeError, "timestamp out of range: %lld microseconds", (long long)ts.micros);
303
+ }
304
+ data_st = duckdb_from_timestamp(ts);
305
+ return rb_funcall(mDuckDBConverter, id__to_time, 7,
306
+ INT2FIX(data_st.date.year),
307
+ INT2FIX(data_st.date.month),
308
+ INT2FIX(data_st.date.day),
309
+ INT2FIX(data_st.time.hour),
310
+ INT2FIX(data_st.time.min),
311
+ INT2FIX(data_st.time.sec),
312
+ INT2NUM(data_st.time.micros)
313
+ );
351
314
  }
352
315
 
353
316
  void rbduckdb_init_converter(void) {