duckdb 1.5.3.0 → 1.5.4.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/CHANGELOG.md +11 -0
- data/README.md +52 -0
- data/ext/duckdb/aggregate_function.c +0 -1
- data/ext/duckdb/appender.c +17 -0
- data/ext/duckdb/arrow_array_stream.c +226 -0
- data/ext/duckdb/arrow_array_stream.h +61 -0
- data/ext/duckdb/arrow_import.c +165 -0
- data/ext/duckdb/arrow_import.h +6 -0
- data/ext/duckdb/blob.c +1 -1
- data/ext/duckdb/blob.h +1 -2
- data/ext/duckdb/config.c +1 -1
- data/ext/duckdb/config.h +1 -1
- data/ext/duckdb/connection.c +3 -3
- data/ext/duckdb/converter.h +1 -0
- data/ext/duckdb/conveter.c +39 -9
- data/ext/duckdb/data_chunk.c +10 -0
- data/ext/duckdb/data_chunk.h +1 -0
- data/ext/duckdb/duckdb.c +13 -11
- data/ext/duckdb/error.c +1 -1
- data/ext/duckdb/error.h +1 -3
- data/ext/duckdb/function_executor.c +308 -2
- data/ext/duckdb/function_executor.h +44 -0
- data/ext/duckdb/prepared_statement.c +21 -0
- data/ext/duckdb/result.c +49 -3
- data/ext/duckdb/result.h +11 -0
- data/ext/duckdb/ruby-duckdb.h +3 -0
- data/ext/duckdb/scalar_function.c +97 -29
- data/ext/duckdb/scalar_function.h +2 -4
- data/ext/duckdb/scalar_function_bind_info.c +13 -13
- data/ext/duckdb/scalar_function_bind_info.h +1 -1
- data/ext/duckdb/scalar_function_set.c +9 -9
- data/ext/duckdb/scalar_function_set.h +2 -2
- data/ext/duckdb/table_description.c +19 -19
- data/ext/duckdb/table_description.h +1 -1
- data/ext/duckdb/table_function.c +94 -28
- data/ext/duckdb/table_function.h +2 -2
- data/ext/duckdb/table_function_bind_info.c +20 -20
- data/ext/duckdb/table_function_bind_info.h +2 -2
- data/ext/duckdb/table_function_function_info.c +5 -5
- data/ext/duckdb/table_function_function_info.h +2 -2
- data/ext/duckdb/table_function_init_info.c +70 -5
- data/ext/duckdb/table_function_init_info.h +2 -2
- data/lib/duckdb/appender.rb +23 -0
- data/lib/duckdb/arrow_array_stream.rb +33 -0
- data/lib/duckdb/connection.rb +54 -0
- data/lib/duckdb/prepared_statement.rb +17 -0
- data/lib/duckdb/version.rb +1 -1
- data/lib/duckdb.rb +1 -0
- metadata +6 -1
data/ext/duckdb/result.c
CHANGED
|
@@ -16,6 +16,7 @@ static VALUE result_columns(VALUE oDuckDBResult);
|
|
|
16
16
|
static VALUE destroy_data_chunk(VALUE arg);
|
|
17
17
|
|
|
18
18
|
static VALUE result__chunk_stream(VALUE oDuckDBResult);
|
|
19
|
+
static VALUE result_arrow_c_stream(VALUE oDuckDBResult);
|
|
19
20
|
static VALUE yield_rows(VALUE arg);
|
|
20
21
|
static VALUE result__return_type(VALUE oDuckDBResult);
|
|
21
22
|
static VALUE result__statement_type(VALUE oDuckDBResult);
|
|
@@ -56,15 +57,30 @@ static const rb_data_type_t result_data_type = {
|
|
|
56
57
|
static void deallocate(void *ctx) {
|
|
57
58
|
rubyDuckDBResult *p = (rubyDuckDBResult *)ctx;
|
|
58
59
|
|
|
59
|
-
|
|
60
|
-
xfree(p);
|
|
60
|
+
rbduckdb_result_unref(p);
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
static VALUE allocate(VALUE klass) {
|
|
64
|
-
rubyDuckDBResult *ctx =
|
|
64
|
+
rubyDuckDBResult *ctx = calloc((size_t)1, sizeof(rubyDuckDBResult));
|
|
65
|
+
|
|
66
|
+
if (ctx == NULL) {
|
|
67
|
+
rb_raise(rb_eNoMemError, "failed to allocate DuckDB::Result");
|
|
68
|
+
}
|
|
69
|
+
ctx->refcount = 1;
|
|
65
70
|
return TypedData_Wrap_Struct(klass, &result_data_type, ctx);
|
|
66
71
|
}
|
|
67
72
|
|
|
73
|
+
void rbduckdb_result_ref(rubyDuckDBResult *ctx) {
|
|
74
|
+
RUBY_ATOMIC_FETCH_ADD(ctx->refcount, 1);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
void rbduckdb_result_unref(rubyDuckDBResult *ctx) {
|
|
78
|
+
if (RUBY_ATOMIC_FETCH_SUB(ctx->refcount, 1) == 1) {
|
|
79
|
+
duckdb_destroy_result(&(ctx->result));
|
|
80
|
+
free(ctx);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
68
84
|
static size_t memsize(const void *p) {
|
|
69
85
|
return sizeof(rubyDuckDBResult);
|
|
70
86
|
}
|
|
@@ -647,6 +663,35 @@ static VALUE vector_uuid(void* vector_data, idx_t row_idx) {
|
|
|
647
663
|
return rbduckdb_uuid_to_ruby(((duckdb_hugeint *)vector_data)[row_idx]);
|
|
648
664
|
}
|
|
649
665
|
|
|
666
|
+
/*
|
|
667
|
+
* call-seq:
|
|
668
|
+
* result.arrow_c_stream -> DuckDB::ArrowArrayStream
|
|
669
|
+
*
|
|
670
|
+
* [EXPERIMENTAL] Exports the result as an Arrow C stream
|
|
671
|
+
* (Arrow C Data Interface). The returned stream object satisfies the
|
|
672
|
+
* Ruby Arrow C stream protocol, so it can be consumed directly by
|
|
673
|
+
* ruby-polars, red-arrow and other Arrow consumers:
|
|
674
|
+
*
|
|
675
|
+
* result = con.query('SELECT * FROM users')
|
|
676
|
+
* df = Polars::DataFrame.new(result)
|
|
677
|
+
*
|
|
678
|
+
* The stream consumes the result's chunks; a result can be exported
|
|
679
|
+
* only once. This API is built on DuckDB's unstable Arrow C API and
|
|
680
|
+
* may change in any minor release.
|
|
681
|
+
*/
|
|
682
|
+
static VALUE result_arrow_c_stream(VALUE oDuckDBResult) {
|
|
683
|
+
rubyDuckDBResult *ctx;
|
|
684
|
+
VALUE stream;
|
|
685
|
+
|
|
686
|
+
TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
|
|
687
|
+
if (ctx->arrow_exported) {
|
|
688
|
+
rb_raise(eDuckDBError, "result is already exported as an Arrow stream");
|
|
689
|
+
}
|
|
690
|
+
stream = rbduckdb_create_arrow_array_stream(oDuckDBResult);
|
|
691
|
+
ctx->arrow_exported = true;
|
|
692
|
+
return stream;
|
|
693
|
+
}
|
|
694
|
+
|
|
650
695
|
static VALUE vector_value(duckdb_vector vector, idx_t row_idx) {
|
|
651
696
|
duckdb_logical_type ty;
|
|
652
697
|
VALUE obj = Qnil;
|
|
@@ -671,6 +716,7 @@ void rbduckdb_init_result(void) {
|
|
|
671
716
|
rb_define_method(cDuckDBResult, "rows_changed", result_rows_changed, 0);
|
|
672
717
|
rb_define_method(cDuckDBResult, "columns", result_columns, 0);
|
|
673
718
|
rb_define_private_method(cDuckDBResult, "_chunk_stream", result__chunk_stream, 0);
|
|
719
|
+
rb_define_method(cDuckDBResult, "arrow_c_stream", result_arrow_c_stream, 0);
|
|
674
720
|
rb_define_private_method(cDuckDBResult, "_return_type", result__return_type, 0);
|
|
675
721
|
rb_define_private_method(cDuckDBResult, "_statement_type", result__statement_type, 0);
|
|
676
722
|
|
data/ext/duckdb/result.h
CHANGED
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
#ifndef RUBY_DUCKDB_RESULT_H
|
|
2
2
|
#define RUBY_DUCKDB_RESULT_H
|
|
3
3
|
|
|
4
|
+
/*
|
|
5
|
+
* Allocated with plain calloc/free and reference-counted: the Ruby Result
|
|
6
|
+
* object holds one reference, and each exported Arrow stream holds another,
|
|
7
|
+
* so the duckdb_result stays valid for consumers that outlive the Ruby
|
|
8
|
+
* objects. rbduckdb_result_unref() must not call any Ruby API: it runs from
|
|
9
|
+
* GC sweep (deallocate) and from Arrow stream release callbacks.
|
|
10
|
+
*/
|
|
4
11
|
struct _rubyDuckDBResult {
|
|
5
12
|
duckdb_result result;
|
|
13
|
+
bool arrow_exported;
|
|
14
|
+
rb_atomic_t refcount;
|
|
6
15
|
};
|
|
7
16
|
|
|
8
17
|
typedef struct _rubyDuckDBResult rubyDuckDBResult;
|
|
9
18
|
|
|
10
19
|
rubyDuckDBResult *rbduckdb_get_struct_result(VALUE obj);
|
|
20
|
+
void rbduckdb_result_ref(rubyDuckDBResult *ctx);
|
|
21
|
+
void rbduckdb_result_unref(rubyDuckDBResult *ctx);
|
|
11
22
|
void rbduckdb_init_result(void);
|
|
12
23
|
VALUE rbduckdb_create_result(void);
|
|
13
24
|
VALUE rbduckdb_vector_value_at(duckdb_vector vector, duckdb_logical_type element_type, idx_t index);
|
data/ext/duckdb/ruby-duckdb.h
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
#include "ruby.h"
|
|
8
8
|
#include "ruby/thread.h"
|
|
9
|
+
#include "ruby/atomic.h"
|
|
9
10
|
#include <duckdb.h>
|
|
10
11
|
|
|
11
12
|
#ifdef HAVE_DUCKDB_UNSAFE_VECTOR_ASSIGN_STRING_ELEMENT_LEN
|
|
@@ -50,6 +51,8 @@
|
|
|
50
51
|
#include "./memory_helper.h"
|
|
51
52
|
#include "./table_function.h"
|
|
52
53
|
#include "./table_description.h"
|
|
54
|
+
#include "./arrow_array_stream.h"
|
|
55
|
+
#include "./arrow_import.h"
|
|
53
56
|
|
|
54
57
|
extern VALUE mDuckDB;
|
|
55
58
|
extern VALUE cDuckDBDatabase;
|
|
@@ -7,16 +7,24 @@ static void deallocate(void *);
|
|
|
7
7
|
static VALUE allocate(VALUE klass);
|
|
8
8
|
static size_t memsize(const void *p);
|
|
9
9
|
static void compact(void *);
|
|
10
|
-
static VALUE
|
|
11
|
-
static VALUE
|
|
12
|
-
static VALUE
|
|
13
|
-
static VALUE
|
|
14
|
-
static VALUE
|
|
15
|
-
static VALUE
|
|
16
|
-
static VALUE
|
|
17
|
-
static VALUE
|
|
10
|
+
static VALUE scalar_function_initialize(VALUE self);
|
|
11
|
+
static VALUE scalar_function_set_name(VALUE self, VALUE name);
|
|
12
|
+
static VALUE scalar_function__set_return_type(VALUE self, VALUE logical_type);
|
|
13
|
+
static VALUE scalar_function__set_varargs(VALUE self, VALUE logical_type);
|
|
14
|
+
static VALUE scalar_function__add_parameter(VALUE self, VALUE logical_type);
|
|
15
|
+
static VALUE scalar_function__set_special_handling(VALUE self);
|
|
16
|
+
static VALUE scalar_function_set_function(VALUE self);
|
|
17
|
+
static VALUE scalar_function__set_bind(VALUE self);
|
|
18
18
|
static void scalar_function_callback(duckdb_function_info info, duckdb_data_chunk input, duckdb_vector output);
|
|
19
19
|
static void scalar_function_bind_callback(duckdb_bind_info info);
|
|
20
|
+
#ifdef HAVE_DUCKDB_H_GE_V1_5_0
|
|
21
|
+
/*
|
|
22
|
+
* Thread detection functions (available since Ruby 2.3).
|
|
23
|
+
* Used to skip the proxy on Ruby threads.
|
|
24
|
+
*/
|
|
25
|
+
extern int ruby_native_thread_p(void);
|
|
26
|
+
static void scalar_function_init_callback(duckdb_init_info info);
|
|
27
|
+
#endif
|
|
20
28
|
|
|
21
29
|
|
|
22
30
|
struct callback_arg {
|
|
@@ -115,7 +123,7 @@ static size_t memsize(const void *p) {
|
|
|
115
123
|
return sizeof(rubyDuckDBScalarFunction);
|
|
116
124
|
}
|
|
117
125
|
|
|
118
|
-
static VALUE
|
|
126
|
+
static VALUE scalar_function_initialize(VALUE self) {
|
|
119
127
|
rubyDuckDBScalarFunction *p;
|
|
120
128
|
TypedData_Get_Struct(self, rubyDuckDBScalarFunction, &scalar_function_data_type, p);
|
|
121
129
|
p->scalar_function = duckdb_create_scalar_function();
|
|
@@ -124,7 +132,7 @@ static VALUE duckdb_scalar_function_initialize(VALUE self) {
|
|
|
124
132
|
return self;
|
|
125
133
|
}
|
|
126
134
|
|
|
127
|
-
static VALUE
|
|
135
|
+
static VALUE scalar_function_set_name(VALUE self, VALUE name) {
|
|
128
136
|
rubyDuckDBScalarFunction *p;
|
|
129
137
|
TypedData_Get_Struct(self, rubyDuckDBScalarFunction, &scalar_function_data_type, p);
|
|
130
138
|
|
|
@@ -134,7 +142,7 @@ static VALUE rbduckdb_scalar_function_set_name(VALUE self, VALUE name) {
|
|
|
134
142
|
return self;
|
|
135
143
|
}
|
|
136
144
|
|
|
137
|
-
static VALUE
|
|
145
|
+
static VALUE scalar_function__set_return_type(VALUE self, VALUE logical_type) {
|
|
138
146
|
rubyDuckDBScalarFunction *p;
|
|
139
147
|
rubyDuckDBLogicalType *lt;
|
|
140
148
|
|
|
@@ -146,7 +154,7 @@ static VALUE rbduckdb_scalar_function__set_return_type(VALUE self, VALUE logical
|
|
|
146
154
|
return self;
|
|
147
155
|
}
|
|
148
156
|
|
|
149
|
-
static VALUE
|
|
157
|
+
static VALUE scalar_function__set_varargs(VALUE self, VALUE logical_type) {
|
|
150
158
|
rubyDuckDBScalarFunction *p;
|
|
151
159
|
rubyDuckDBLogicalType *lt;
|
|
152
160
|
|
|
@@ -158,7 +166,7 @@ static VALUE rbduckdb_scalar_function__set_varargs(VALUE self, VALUE logical_typ
|
|
|
158
166
|
return self;
|
|
159
167
|
}
|
|
160
168
|
|
|
161
|
-
static VALUE
|
|
169
|
+
static VALUE scalar_function__set_special_handling(VALUE self) {
|
|
162
170
|
rubyDuckDBScalarFunction *p;
|
|
163
171
|
|
|
164
172
|
TypedData_Get_Struct(self, rubyDuckDBScalarFunction, &scalar_function_data_type, p);
|
|
@@ -167,7 +175,7 @@ static VALUE rbduckdb_scalar_function__set_special_handling(VALUE self) {
|
|
|
167
175
|
return self;
|
|
168
176
|
}
|
|
169
177
|
|
|
170
|
-
static VALUE
|
|
178
|
+
static VALUE scalar_function__add_parameter(VALUE self, VALUE logical_type) {
|
|
171
179
|
rubyDuckDBScalarFunction *p;
|
|
172
180
|
rubyDuckDBLogicalType *lt;
|
|
173
181
|
|
|
@@ -191,6 +199,7 @@ static void scalar_function_callback(duckdb_function_info info, duckdb_data_chun
|
|
|
191
199
|
rubyDuckDBScalarFunction *ctx;
|
|
192
200
|
idx_t i;
|
|
193
201
|
struct callback_arg arg;
|
|
202
|
+
struct worker_proxy *proxy = NULL;
|
|
194
203
|
|
|
195
204
|
ctx = (rubyDuckDBScalarFunction *)duckdb_scalar_function_get_extra_info(info);
|
|
196
205
|
|
|
@@ -218,7 +227,11 @@ static void scalar_function_callback(duckdb_function_info info, duckdb_data_chun
|
|
|
218
227
|
arg.row_count = duckdb_data_chunk_get_size(input);
|
|
219
228
|
arg.col_count = duckdb_data_chunk_get_column_count(input);
|
|
220
229
|
|
|
221
|
-
|
|
230
|
+
#ifdef HAVE_DUCKDB_H_GE_V1_5_0
|
|
231
|
+
/* On DuckDB >= 1.5.0 each worker thread carries its own proxy (see init). */
|
|
232
|
+
proxy = (struct worker_proxy *)duckdb_scalar_function_get_state(info);
|
|
233
|
+
#endif
|
|
234
|
+
rbduckdb_function_executor_dispatch_via_proxy(execute_callback_protected, &arg, proxy);
|
|
222
235
|
}
|
|
223
236
|
|
|
224
237
|
static VALUE process_no_param_rows(VALUE varg) {
|
|
@@ -259,7 +272,7 @@ static VALUE process_rows(VALUE varg) {
|
|
|
259
272
|
}
|
|
260
273
|
|
|
261
274
|
/* Call the Ruby block with the arguments */
|
|
262
|
-
result = rb_funcallv(arg->ctx->function_proc, rb_intern("call"), arg->col_count, arg->args);
|
|
275
|
+
result = rb_funcallv(arg->ctx->function_proc, rb_intern("call"), (int)arg->col_count, arg->args);
|
|
263
276
|
|
|
264
277
|
/* Write result to output using helper function */
|
|
265
278
|
rbduckdb_vector_set_value_at(arg->output, arg->output_type, i, result);
|
|
@@ -294,14 +307,66 @@ static VALUE cleanup_callback(VALUE varg) {
|
|
|
294
307
|
return Qnil;
|
|
295
308
|
}
|
|
296
309
|
|
|
297
|
-
|
|
310
|
+
#ifdef HAVE_DUCKDB_H_GE_V1_5_0
|
|
311
|
+
/*
|
|
312
|
+
* Per-worker init for the execute path (DuckDB >= 1.5.0).
|
|
313
|
+
*
|
|
314
|
+
* DuckDB calls this once on each worker thread that will run the execute
|
|
315
|
+
* callback. We create a per-worker proxy (allocating its Ruby thread under the
|
|
316
|
+
* GVL via the global executor, since this runs on a non-Ruby thread) and store
|
|
317
|
+
* it as per-worker state. The execute callback then dispatches through it
|
|
318
|
+
* instead of the shared global executor, so workers run callbacks concurrently.
|
|
319
|
+
* DuckDB invokes rbduckdb_worker_proxy_destroy when the state is freed.
|
|
320
|
+
*/
|
|
321
|
+
struct create_proxy_callback_arg {
|
|
322
|
+
struct worker_proxy *proxy;
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
static VALUE create_proxy_callback(VALUE varg) {
|
|
326
|
+
struct create_proxy_callback_arg *arg = (struct create_proxy_callback_arg *)varg;
|
|
327
|
+
arg->proxy = rbduckdb_worker_proxy_create();
|
|
328
|
+
return Qnil;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/*
|
|
332
|
+
* rbduckdb_worker_proxy_create may raise (NoMemError, Thread.new failure),
|
|
333
|
+
* and the executor runs callbacks unprotected — a raise would longjmp past
|
|
334
|
+
* its done-signaling and block the waiting DuckDB worker forever. Swallow
|
|
335
|
+
* the exception instead: the proxy stays NULL, init sets no state, and the
|
|
336
|
+
* execute callback falls back to the global executor.
|
|
337
|
+
*/
|
|
338
|
+
static void create_proxy_callback_protected(void *user_data) {
|
|
339
|
+
int exception_state;
|
|
340
|
+
|
|
341
|
+
rb_protect(create_proxy_callback, (VALUE)user_data, &exception_state);
|
|
342
|
+
if (exception_state) {
|
|
343
|
+
rb_set_errinfo(Qnil);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
static void scalar_function_init_callback(duckdb_init_info info) {
|
|
348
|
+
struct create_proxy_callback_arg arg;
|
|
349
|
+
|
|
350
|
+
/* A Ruby calling thread runs the callback inline (Case 1/2); no proxy needed. */
|
|
351
|
+
if (ruby_native_thread_p()) return;
|
|
352
|
+
|
|
353
|
+
arg.proxy = NULL;
|
|
354
|
+
rbduckdb_function_executor_dispatch(create_proxy_callback_protected, &arg);
|
|
355
|
+
|
|
356
|
+
if (arg.proxy != NULL) {
|
|
357
|
+
duckdb_scalar_function_init_set_state(info, arg.proxy, rbduckdb_worker_proxy_destroy);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
#endif
|
|
361
|
+
|
|
362
|
+
rubyDuckDBScalarFunction *rbduckdb_get_struct_scalar_function(VALUE obj) {
|
|
298
363
|
rubyDuckDBScalarFunction *ctx;
|
|
299
364
|
TypedData_Get_Struct(obj, rubyDuckDBScalarFunction, &scalar_function_data_type, ctx);
|
|
300
365
|
return ctx;
|
|
301
366
|
}
|
|
302
367
|
|
|
303
368
|
/* :nodoc: */
|
|
304
|
-
static VALUE
|
|
369
|
+
static VALUE scalar_function_set_function(VALUE self) {
|
|
305
370
|
rubyDuckDBScalarFunction *p;
|
|
306
371
|
|
|
307
372
|
if (!rb_block_given_p()) {
|
|
@@ -314,6 +379,10 @@ static VALUE rbduckdb_scalar_function_set_function(VALUE self) {
|
|
|
314
379
|
|
|
315
380
|
duckdb_scalar_function_set_extra_info(p->scalar_function, p, NULL);
|
|
316
381
|
duckdb_scalar_function_set_function(p->scalar_function, scalar_function_callback);
|
|
382
|
+
#ifdef HAVE_DUCKDB_H_GE_V1_5_0
|
|
383
|
+
/* Per-worker proxy threads for the execute path (DuckDB >= 1.5.0). */
|
|
384
|
+
duckdb_scalar_function_set_init(p->scalar_function, scalar_function_init_callback);
|
|
385
|
+
#endif
|
|
317
386
|
|
|
318
387
|
/*
|
|
319
388
|
* Mark as volatile to prevent constant folding during query optimization.
|
|
@@ -328,7 +397,7 @@ static VALUE rbduckdb_scalar_function_set_function(VALUE self) {
|
|
|
328
397
|
}
|
|
329
398
|
|
|
330
399
|
/* :nodoc: */
|
|
331
|
-
static VALUE
|
|
400
|
+
static VALUE scalar_function__set_bind(VALUE self) {
|
|
332
401
|
rubyDuckDBScalarFunction *p;
|
|
333
402
|
|
|
334
403
|
TypedData_Get_Struct(self, rubyDuckDBScalarFunction, &scalar_function_data_type, p);
|
|
@@ -406,19 +475,18 @@ static void scalar_function_bind_callback(duckdb_bind_info info) {
|
|
|
406
475
|
}
|
|
407
476
|
|
|
408
477
|
|
|
409
|
-
void
|
|
478
|
+
void rbduckdb_init_scalar_function(void) {
|
|
410
479
|
#if 0
|
|
411
480
|
VALUE mDuckDB = rb_define_module("DuckDB");
|
|
412
481
|
#endif
|
|
413
482
|
cDuckDBScalarFunction = rb_define_class_under(mDuckDB, "ScalarFunction", rb_cObject);
|
|
414
483
|
rb_define_alloc_func(cDuckDBScalarFunction, allocate);
|
|
415
|
-
rb_define_method(cDuckDBScalarFunction, "initialize",
|
|
416
|
-
rb_define_method(cDuckDBScalarFunction, "set_name",
|
|
417
|
-
|
|
418
|
-
rb_define_private_method(cDuckDBScalarFunction, "
|
|
419
|
-
rb_define_private_method(cDuckDBScalarFunction, "
|
|
420
|
-
rb_define_private_method(cDuckDBScalarFunction, "
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
rb_define_private_method(cDuckDBScalarFunction, "_set_bind", rbduckdb_scalar_function__set_bind, 0);
|
|
484
|
+
rb_define_method(cDuckDBScalarFunction, "initialize", scalar_function_initialize, 0);
|
|
485
|
+
rb_define_method(cDuckDBScalarFunction, "set_name", scalar_function_set_name, 1);
|
|
486
|
+
rb_define_private_method(cDuckDBScalarFunction, "_set_return_type", scalar_function__set_return_type, 1);
|
|
487
|
+
rb_define_private_method(cDuckDBScalarFunction, "_set_varargs", scalar_function__set_varargs, 1);
|
|
488
|
+
rb_define_private_method(cDuckDBScalarFunction, "_set_special_handling", scalar_function__set_special_handling, 0);
|
|
489
|
+
rb_define_private_method(cDuckDBScalarFunction, "_add_parameter", scalar_function__add_parameter, 1);
|
|
490
|
+
rb_define_method(cDuckDBScalarFunction, "set_function", scalar_function_set_function, 0);
|
|
491
|
+
rb_define_private_method(cDuckDBScalarFunction, "_set_bind", scalar_function__set_bind, 0);
|
|
424
492
|
}
|
|
@@ -9,9 +9,7 @@ struct _rubyDuckDBScalarFunction {
|
|
|
9
9
|
|
|
10
10
|
typedef struct _rubyDuckDBScalarFunction rubyDuckDBScalarFunction;
|
|
11
11
|
|
|
12
|
-
void
|
|
13
|
-
rubyDuckDBScalarFunction *
|
|
12
|
+
void rbduckdb_init_scalar_function(void);
|
|
13
|
+
rubyDuckDBScalarFunction *rbduckdb_get_struct_scalar_function(VALUE obj);
|
|
14
14
|
|
|
15
15
|
#endif
|
|
16
|
-
|
|
17
|
-
|
|
@@ -5,10 +5,10 @@ VALUE cDuckDBScalarFunctionBindInfo;
|
|
|
5
5
|
static void deallocate(void *ctx);
|
|
6
6
|
static VALUE allocate(VALUE klass);
|
|
7
7
|
static size_t memsize(const void *p);
|
|
8
|
-
static VALUE
|
|
9
|
-
static VALUE
|
|
10
|
-
static VALUE
|
|
11
|
-
static VALUE
|
|
8
|
+
static VALUE scalar_function_bind_info_argument_count(VALUE self);
|
|
9
|
+
static VALUE scalar_function_bind_info_set_error(VALUE self, VALUE error);
|
|
10
|
+
static VALUE scalar_function_bind_info__get_argument(VALUE self, VALUE index);
|
|
11
|
+
static VALUE scalar_function_bind_info_client_context(VALUE self);
|
|
12
12
|
|
|
13
13
|
static const rb_data_type_t scalar_function_bind_info_data_type = {
|
|
14
14
|
"DuckDB/ScalarFunction/BindInfo",
|
|
@@ -46,7 +46,7 @@ VALUE rbduckdb_scalar_function_bind_info_new(duckdb_bind_info bind_info) {
|
|
|
46
46
|
*
|
|
47
47
|
* bind_info.argument_count # => 2
|
|
48
48
|
*/
|
|
49
|
-
static VALUE
|
|
49
|
+
static VALUE scalar_function_bind_info_argument_count(VALUE self) {
|
|
50
50
|
rubyDuckDBScalarFunctionBindInfo *ctx;
|
|
51
51
|
TypedData_Get_Struct(self, rubyDuckDBScalarFunctionBindInfo, &scalar_function_bind_info_data_type, ctx);
|
|
52
52
|
return ULL2NUM(duckdb_scalar_function_bind_get_argument_count(ctx->bind_info));
|
|
@@ -61,7 +61,7 @@ static VALUE rbduckdb_scalar_function_bind_info_argument_count(VALUE self) {
|
|
|
61
61
|
*
|
|
62
62
|
* bind_info.set_error('invalid argument')
|
|
63
63
|
*/
|
|
64
|
-
static VALUE
|
|
64
|
+
static VALUE scalar_function_bind_info_set_error(VALUE self, VALUE error) {
|
|
65
65
|
rubyDuckDBScalarFunctionBindInfo *ctx;
|
|
66
66
|
TypedData_Get_Struct(self, rubyDuckDBScalarFunctionBindInfo, &scalar_function_bind_info_data_type, ctx);
|
|
67
67
|
duckdb_scalar_function_bind_set_error(ctx->bind_info, StringValueCStr(error));
|
|
@@ -75,7 +75,7 @@ static VALUE rbduckdb_scalar_function_bind_info_set_error(VALUE self, VALUE erro
|
|
|
75
75
|
* Returns the expression at the given argument index.
|
|
76
76
|
* Called internally by +get_argument+ after index validation.
|
|
77
77
|
*/
|
|
78
|
-
static VALUE
|
|
78
|
+
static VALUE scalar_function_bind_info__get_argument(VALUE self, VALUE index) {
|
|
79
79
|
rubyDuckDBScalarFunctionBindInfo *ctx;
|
|
80
80
|
TypedData_Get_Struct(self, rubyDuckDBScalarFunctionBindInfo, &scalar_function_bind_info_data_type, ctx);
|
|
81
81
|
duckdb_expression expr = duckdb_scalar_function_bind_get_argument(ctx->bind_info, (idx_t)NUM2ULL(index));
|
|
@@ -88,7 +88,7 @@ static VALUE rbduckdb_scalar_function_bind_info_get_argument(VALUE self, VALUE i
|
|
|
88
88
|
*
|
|
89
89
|
* Returns the client context associated with the bind phase of the scalar function.
|
|
90
90
|
*/
|
|
91
|
-
static VALUE
|
|
91
|
+
static VALUE scalar_function_bind_info_client_context(VALUE self) {
|
|
92
92
|
rubyDuckDBScalarFunctionBindInfo *ctx;
|
|
93
93
|
duckdb_client_context client_context;
|
|
94
94
|
TypedData_Get_Struct(self, rubyDuckDBScalarFunctionBindInfo, &scalar_function_bind_info_data_type, ctx);
|
|
@@ -96,14 +96,14 @@ static VALUE rbduckdb_scalar_function_bind_info_client_context(VALUE self) {
|
|
|
96
96
|
return rbduckdb_client_context_new(client_context);
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
void
|
|
99
|
+
void rbduckdb_init_scalar_function_bind_info(void) {
|
|
100
100
|
#if 0
|
|
101
101
|
VALUE mDuckDB = rb_define_module("DuckDB");
|
|
102
102
|
#endif
|
|
103
103
|
cDuckDBScalarFunctionBindInfo = rb_define_class_under(cDuckDBScalarFunction, "BindInfo", rb_cObject);
|
|
104
104
|
rb_define_alloc_func(cDuckDBScalarFunctionBindInfo, allocate);
|
|
105
|
-
rb_define_method(cDuckDBScalarFunctionBindInfo, "argument_count",
|
|
106
|
-
rb_define_method(cDuckDBScalarFunctionBindInfo, "set_error",
|
|
107
|
-
rb_define_private_method(cDuckDBScalarFunctionBindInfo, "_get_argument",
|
|
108
|
-
rb_define_method(cDuckDBScalarFunctionBindInfo, "client_context",
|
|
105
|
+
rb_define_method(cDuckDBScalarFunctionBindInfo, "argument_count", scalar_function_bind_info_argument_count, 0);
|
|
106
|
+
rb_define_method(cDuckDBScalarFunctionBindInfo, "set_error", scalar_function_bind_info_set_error, 1);
|
|
107
|
+
rb_define_private_method(cDuckDBScalarFunctionBindInfo, "_get_argument", scalar_function_bind_info__get_argument, 1);
|
|
108
|
+
rb_define_method(cDuckDBScalarFunctionBindInfo, "client_context", scalar_function_bind_info_client_context, 0);
|
|
109
109
|
}
|
|
@@ -7,7 +7,7 @@ struct _rubyDuckDBScalarFunctionBindInfo {
|
|
|
7
7
|
|
|
8
8
|
typedef struct _rubyDuckDBScalarFunctionBindInfo rubyDuckDBScalarFunctionBindInfo;
|
|
9
9
|
|
|
10
|
-
void
|
|
10
|
+
void rbduckdb_init_scalar_function_bind_info(void);
|
|
11
11
|
VALUE rbduckdb_scalar_function_bind_info_new(duckdb_bind_info bind_info);
|
|
12
12
|
|
|
13
13
|
#endif
|
|
@@ -7,8 +7,8 @@ static void deallocate(void *);
|
|
|
7
7
|
static VALUE allocate(VALUE klass);
|
|
8
8
|
static size_t memsize(const void *p);
|
|
9
9
|
static void compact(void *);
|
|
10
|
-
static VALUE
|
|
11
|
-
static VALUE
|
|
10
|
+
static VALUE scalar_function_set__initialize(VALUE self, VALUE name);
|
|
11
|
+
static VALUE scalar_function_set__add(VALUE self, VALUE scalar_function);
|
|
12
12
|
|
|
13
13
|
static const rb_data_type_t scalar_function_set_data_type = {
|
|
14
14
|
"DuckDB/ScalarFunctionSet",
|
|
@@ -44,14 +44,14 @@ static size_t memsize(const void *p) {
|
|
|
44
44
|
return sizeof(rubyDuckDBScalarFunctionSet);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
rubyDuckDBScalarFunctionSet *
|
|
47
|
+
rubyDuckDBScalarFunctionSet *rbduckdb_get_struct_scalar_function_set(VALUE obj) {
|
|
48
48
|
rubyDuckDBScalarFunctionSet *ctx;
|
|
49
49
|
TypedData_Get_Struct(obj, rubyDuckDBScalarFunctionSet, &scalar_function_set_data_type, ctx);
|
|
50
50
|
return ctx;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
/* :nodoc: */
|
|
54
|
-
static VALUE
|
|
54
|
+
static VALUE scalar_function_set__initialize(VALUE self, VALUE name) {
|
|
55
55
|
rubyDuckDBScalarFunctionSet *p;
|
|
56
56
|
|
|
57
57
|
TypedData_Get_Struct(self, rubyDuckDBScalarFunctionSet, &scalar_function_set_data_type, p);
|
|
@@ -60,12 +60,12 @@ static VALUE rbduckdb_scalar_function_set__initialize(VALUE self, VALUE name) {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
/* :nodoc: */
|
|
63
|
-
static VALUE
|
|
63
|
+
static VALUE scalar_function_set__add(VALUE self, VALUE scalar_function) {
|
|
64
64
|
rubyDuckDBScalarFunctionSet *p;
|
|
65
65
|
rubyDuckDBScalarFunction *sf;
|
|
66
66
|
|
|
67
67
|
TypedData_Get_Struct(self, rubyDuckDBScalarFunctionSet, &scalar_function_set_data_type, p);
|
|
68
|
-
sf =
|
|
68
|
+
sf = rbduckdb_get_struct_scalar_function(scalar_function);
|
|
69
69
|
|
|
70
70
|
if (duckdb_add_scalar_function_to_set(p->scalar_function_set, sf->scalar_function) == DuckDBError) {
|
|
71
71
|
rb_raise(eDuckDBError, "failed to add scalar function to set (duplicate overload?)");
|
|
@@ -75,12 +75,12 @@ static VALUE rbduckdb_scalar_function_set__add(VALUE self, VALUE scalar_function
|
|
|
75
75
|
return self;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
void
|
|
78
|
+
void rbduckdb_init_scalar_function_set(void) {
|
|
79
79
|
#if 0
|
|
80
80
|
VALUE mDuckDB = rb_define_module("DuckDB");
|
|
81
81
|
#endif
|
|
82
82
|
cDuckDBScalarFunctionSet = rb_define_class_under(mDuckDB, "ScalarFunctionSet", rb_cObject);
|
|
83
83
|
rb_define_alloc_func(cDuckDBScalarFunctionSet, allocate);
|
|
84
|
-
rb_define_private_method(cDuckDBScalarFunctionSet, "_initialize",
|
|
85
|
-
rb_define_private_method(cDuckDBScalarFunctionSet, "_add",
|
|
84
|
+
rb_define_private_method(cDuckDBScalarFunctionSet, "_initialize", scalar_function_set__initialize, 1);
|
|
85
|
+
rb_define_private_method(cDuckDBScalarFunctionSet, "_add", scalar_function_set__add, 1);
|
|
86
86
|
}
|
|
@@ -8,7 +8,7 @@ struct _rubyDuckDBScalarFunctionSet {
|
|
|
8
8
|
|
|
9
9
|
typedef struct _rubyDuckDBScalarFunctionSet rubyDuckDBScalarFunctionSet;
|
|
10
10
|
|
|
11
|
-
void
|
|
12
|
-
rubyDuckDBScalarFunctionSet *
|
|
11
|
+
void rbduckdb_init_scalar_function_set(void);
|
|
12
|
+
rubyDuckDBScalarFunctionSet *rbduckdb_get_struct_scalar_function_set(VALUE obj);
|
|
13
13
|
|
|
14
14
|
#endif
|
|
@@ -8,13 +8,13 @@ static void deallocate(void *ctx);
|
|
|
8
8
|
static VALUE allocate(VALUE klass);
|
|
9
9
|
static size_t memsize(const void *p);
|
|
10
10
|
static rubyDuckDBTableDescription *get_struct_table_description(VALUE obj);
|
|
11
|
-
static VALUE
|
|
12
|
-
static VALUE
|
|
11
|
+
static VALUE table_description_error_message(VALUE self);
|
|
12
|
+
static VALUE table_description__initialize(VALUE self, VALUE conn, VALUE catalog, VALUE schema, VALUE table);
|
|
13
13
|
|
|
14
|
-
static VALUE
|
|
15
|
-
static VALUE
|
|
16
|
-
static VALUE
|
|
17
|
-
static VALUE
|
|
14
|
+
static VALUE table_description__column_count(VALUE self);
|
|
15
|
+
static VALUE table_description__column_name(VALUE self, VALUE idx);
|
|
16
|
+
static VALUE table_description__column_logical_type(VALUE self, VALUE idx);
|
|
17
|
+
static VALUE table_description__column_has_default(VALUE self, VALUE idx);
|
|
18
18
|
|
|
19
19
|
static const rb_data_type_t table_description_data_type = {
|
|
20
20
|
"DuckDB/TableDescription",
|
|
@@ -46,14 +46,14 @@ static rubyDuckDBTableDescription *get_struct_table_description(VALUE obj) {
|
|
|
46
46
|
return ctx;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
static VALUE
|
|
49
|
+
static VALUE table_description_error_message(VALUE self) {
|
|
50
50
|
rubyDuckDBTableDescription *ctx = get_struct_table_description(self);
|
|
51
51
|
const char *p = duckdb_table_description_error(ctx->table_description);
|
|
52
52
|
return p ? rb_str_new2(p) : Qnil;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
/* nodoc */
|
|
56
|
-
static VALUE
|
|
56
|
+
static VALUE table_description__initialize(VALUE self, VALUE con, VALUE catalog, VALUE schema, VALUE table) {
|
|
57
57
|
char *pcatalog = NULL;
|
|
58
58
|
char *pschema = NULL;
|
|
59
59
|
char *ptable = NULL;
|
|
@@ -89,14 +89,14 @@ static VALUE duckdb_table_description__initialize(VALUE self, VALUE con, VALUE c
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
/* nodoc */
|
|
92
|
-
static VALUE
|
|
92
|
+
static VALUE table_description__column_count(VALUE self) {
|
|
93
93
|
rubyDuckDBTableDescription *ctx;
|
|
94
94
|
ctx = get_struct_table_description(self);
|
|
95
95
|
return ULL2NUM(duckdb_table_description_get_column_count(ctx->table_description));
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
/* nodoc */
|
|
99
|
-
static VALUE
|
|
99
|
+
static VALUE table_description__column_name(VALUE self, VALUE idx) {
|
|
100
100
|
VALUE name = Qnil;
|
|
101
101
|
rubyDuckDBTableDescription *ctx;
|
|
102
102
|
ctx = get_struct_table_description(self);
|
|
@@ -109,7 +109,7 @@ static VALUE duckdb_table_description__column_name(VALUE self, VALUE idx) {
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
/* nodoc */
|
|
112
|
-
static VALUE
|
|
112
|
+
static VALUE table_description__column_logical_type(VALUE self, VALUE idx) {
|
|
113
113
|
rubyDuckDBTableDescription *ctx;
|
|
114
114
|
duckdb_logical_type lt;
|
|
115
115
|
ctx = get_struct_table_description(self);
|
|
@@ -117,7 +117,7 @@ static VALUE duckdb_table_description__column_logical_type(VALUE self, VALUE idx
|
|
|
117
117
|
return rbduckdb_create_logical_type(lt);
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
static VALUE
|
|
120
|
+
static VALUE table_description__column_has_default(VALUE self, VALUE idx) {
|
|
121
121
|
rubyDuckDBTableDescription *ctx;
|
|
122
122
|
bool has_default;
|
|
123
123
|
ctx = get_struct_table_description(self);
|
|
@@ -128,17 +128,17 @@ static VALUE duckdb_table_description__column_has_default(VALUE self, VALUE idx)
|
|
|
128
128
|
return has_default ? Qtrue : Qfalse;
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
void
|
|
131
|
+
void rbduckdb_init_table_description(void) {
|
|
132
132
|
#if 0
|
|
133
133
|
VALUE mDuckDB = rb_define_module("DuckDB");
|
|
134
134
|
#endif
|
|
135
135
|
cDuckDBTableDescription = rb_define_class_under(mDuckDB, "TableDescription", rb_cObject);
|
|
136
136
|
rb_define_alloc_func(cDuckDBTableDescription, allocate);
|
|
137
|
-
rb_define_method(cDuckDBTableDescription, "error_message",
|
|
138
|
-
rb_define_private_method(cDuckDBTableDescription, "_initialize",
|
|
139
|
-
rb_define_private_method(cDuckDBTableDescription, "_column_count",
|
|
140
|
-
rb_define_private_method(cDuckDBTableDescription, "_column_name",
|
|
141
|
-
rb_define_private_method(cDuckDBTableDescription, "_column_logical_type",
|
|
142
|
-
rb_define_private_method(cDuckDBTableDescription, "_column_has_default",
|
|
137
|
+
rb_define_method(cDuckDBTableDescription, "error_message", table_description_error_message, 0);
|
|
138
|
+
rb_define_private_method(cDuckDBTableDescription, "_initialize", table_description__initialize, 4);
|
|
139
|
+
rb_define_private_method(cDuckDBTableDescription, "_column_count", table_description__column_count, 0);
|
|
140
|
+
rb_define_private_method(cDuckDBTableDescription, "_column_name", table_description__column_name, 1);
|
|
141
|
+
rb_define_private_method(cDuckDBTableDescription, "_column_logical_type", table_description__column_logical_type, 1);
|
|
142
|
+
rb_define_private_method(cDuckDBTableDescription, "_column_has_default", table_description__column_has_default, 1);
|
|
143
143
|
}
|
|
144
144
|
#endif
|