duckdb 1.1.3.1 → 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.
@@ -43,6 +43,7 @@ rubyDuckDB *rbduckdb_get_struct_database(VALUE obj) {
43
43
  return ctx;
44
44
  }
45
45
 
46
+ /* :nodoc: */
46
47
  static VALUE duckdb_database_s_open(int argc, VALUE *argv, VALUE cDuckDBDatabase) {
47
48
  rubyDuckDB *ctx;
48
49
  VALUE obj;
@@ -64,6 +65,7 @@ static VALUE duckdb_database_s_open(int argc, VALUE *argv, VALUE cDuckDBDatabase
64
65
  return obj;
65
66
  }
66
67
 
68
+ /* :nodoc: */
67
69
  static VALUE duckdb_database_s_open_ext(int argc, VALUE *argv, VALUE cDuckDBDatabase) {
68
70
  rubyDuckDB *ctx;
69
71
  VALUE obj;
@@ -98,6 +100,7 @@ static VALUE duckdb_database_s_open_ext(int argc, VALUE *argv, VALUE cDuckDBData
98
100
  return obj;
99
101
  }
100
102
 
103
+ /* :nodoc: */
101
104
  static VALUE duckdb_database_connect(VALUE self) {
102
105
  return rbduckdb_create_connection(self);
103
106
  }
@@ -116,6 +119,9 @@ static VALUE duckdb_database_close(VALUE self) {
116
119
  }
117
120
 
118
121
  void rbduckdb_init_duckdb_database(void) {
122
+ #if 0
123
+ VALUE mDuckDB = rb_define_module("DuckDB");
124
+ #endif
119
125
  cDuckDBDatabase = rb_define_class_under(mDuckDB, "Database", rb_cObject);
120
126
  rb_define_alloc_func(cDuckDBDatabase, allocate);
121
127
  rb_define_singleton_method(cDuckDBDatabase, "_open", duckdb_database_s_open, -1);
data/ext/duckdb/duckdb.c CHANGED
@@ -31,6 +31,7 @@ Init_duckdb_native(void) {
31
31
  rbduckdb_init_duckdb_connection();
32
32
  rbduckdb_init_duckdb_result();
33
33
  rbduckdb_init_duckdb_column();
34
+ rbduckdb_init_duckdb_logical_type();
34
35
  rbduckdb_init_duckdb_prepared_statement();
35
36
  rbduckdb_init_duckdb_pending_result();
36
37
  rbduckdb_init_duckdb_blob();
data/ext/duckdb/error.c CHANGED
@@ -3,5 +3,8 @@
3
3
  VALUE eDuckDBError;
4
4
 
5
5
  void rbduckdb_init_duckdb_error(void) {
6
+ #if 0
7
+ VALUE mDuckDB = rb_define_module("DuckDB");
8
+ #endif
6
9
  eDuckDBError = rb_define_class_under(mDuckDB, "Error", rb_eStandardError);
7
10
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'mkmf'
4
4
 
5
- DUCKDB_REQUIRED_VERSION = '1.0.0'
5
+ DUCKDB_REQUIRED_VERSION = '1.1.0'
6
6
 
7
7
  def check_duckdb_header(header, version)
8
8
  found = find_header(
@@ -56,17 +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', 'duckdb_appender_column_count', DUCKDB_REQUIRED_VERSION)
60
-
61
- # check duckdb >= 1.0.0
62
- have_func('duckdb_fetch_chunk', 'duckdb.h')
63
-
64
- # check duckdb >= 1.0.0
65
- have_func('duckdb_fetch_chunk', 'duckdb.h')
59
+ check_duckdb_library('duckdb', 'duckdb_result_error_type', DUCKDB_REQUIRED_VERSION)
66
60
 
67
61
  # check duckdb >= 1.1.0
68
62
  have_func('duckdb_result_error_type', 'duckdb.h')
69
63
 
64
+ # check duckdb >= 1.2.0
65
+ have_func('duckdb_create_instance_cache', 'duckdb.h')
66
+
70
67
  # Building with enabled DUCKDB_API_NO_DEPRECATED is failed with DuckDB v1.1.0 only.
71
68
  # DuckDB v1.1.1 is fixed this issue https://github.com/duckdb/duckdb/issues/13872.
72
69
  have_const('DUCKDB_TYPE_SQLNULL', 'duckdb.h')
@@ -95,6 +95,9 @@ static VALUE duckdb_extracted_statements_prepared_statement(VALUE self, VALUE co
95
95
  }
96
96
 
97
97
  void rbduckdb_init_duckdb_extracted_statements(void) {
98
+ #if 0
99
+ VALUE mDuckDB = rb_define_module("DuckDB");
100
+ #endif
98
101
  cDuckDBExtractedStatements = rb_define_class_under(mDuckDB, "ExtractedStatementsImpl", rb_cObject);
99
102
 
100
103
  rb_define_alloc_func(cDuckDBExtractedStatements, allocate);
@@ -0,0 +1,323 @@
1
+ #include "ruby-duckdb.h"
2
+
3
+ static VALUE cDuckDBLogicalType;
4
+
5
+ static void deallocate(void *ctx);
6
+ static VALUE allocate(VALUE klass);
7
+ static size_t memsize(const void *p);
8
+ static VALUE duckdb_logical_type__type(VALUE self);
9
+ static VALUE duckdb_logical_type_width(VALUE self);
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);
13
+ static VALUE duckdb_logical_type_child_type(VALUE self);
14
+ static VALUE duckdb_logical_type_child_type_at(VALUE self, VALUE cidx);
15
+ static VALUE duckdb_logical_type_size(VALUE self);
16
+ static VALUE duckdb_logical_type_key_type(VALUE self);
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);
21
+
22
+ static const rb_data_type_t logical_type_data_type = {
23
+ "DuckDB/LogicalType",
24
+ {NULL, deallocate, memsize,},
25
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
26
+ };
27
+
28
+ static void deallocate(void *ctx) {
29
+ rubyDuckDBLogicalType *p = (rubyDuckDBLogicalType *)ctx;
30
+
31
+ if (p->logical_type) {
32
+ duckdb_destroy_logical_type(&(p->logical_type));
33
+ }
34
+
35
+ xfree(p);
36
+ }
37
+
38
+ static VALUE allocate(VALUE klass) {
39
+ rubyDuckDBLogicalType *ctx = xcalloc((size_t)1, sizeof(rubyDuckDBLogicalType));
40
+ return TypedData_Wrap_Struct(klass, &logical_type_data_type, ctx);
41
+ }
42
+
43
+ static size_t memsize(const void *p) {
44
+ return sizeof(rubyDuckDBLogicalType);
45
+ }
46
+
47
+ /*
48
+ * call-seq:
49
+ * decimal_col.logical_type.type -> Symbol
50
+ *
51
+ * Returns the logical type's type symbol.
52
+ *
53
+ */
54
+ static VALUE duckdb_logical_type__type(VALUE self) {
55
+ rubyDuckDBLogicalType *ctx;
56
+ TypedData_Get_Struct(self, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
57
+ return INT2FIX(duckdb_get_type_id(ctx->logical_type));
58
+ }
59
+
60
+ /*
61
+ * call-seq:
62
+ * decimal_col.logical_type.width -> Integer
63
+ *
64
+ * Returns the width of the decimal column.
65
+ *
66
+ */
67
+ static VALUE duckdb_logical_type_width(VALUE self) {
68
+ rubyDuckDBLogicalType *ctx;
69
+ TypedData_Get_Struct(self, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
70
+ return INT2FIX(duckdb_decimal_width(ctx->logical_type));
71
+ }
72
+
73
+ /*
74
+ * call-seq:
75
+ * decimal_col.logical_type.scale -> Integer
76
+ *
77
+ * Returns the scale of the decimal column.
78
+ *
79
+ */
80
+ static VALUE duckdb_logical_type_scale(VALUE self) {
81
+ rubyDuckDBLogicalType *ctx;
82
+ TypedData_Get_Struct(self, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
83
+ return INT2FIX(duckdb_decimal_scale(ctx->logical_type));
84
+ }
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
+
123
+ /*
124
+ * call-seq:
125
+ * list_col.logical_type.child_type -> DuckDB::LogicalType
126
+ *
127
+ * Returns the child logical type for list and map types, otherwise nil.
128
+ *
129
+ */
130
+ static VALUE duckdb_logical_type_child_type(VALUE self) {
131
+ rubyDuckDBLogicalType *ctx;
132
+ duckdb_type type_id;
133
+ duckdb_logical_type child_logical_type;
134
+ VALUE logical_type = Qnil;
135
+
136
+ TypedData_Get_Struct(self, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
137
+ type_id = duckdb_get_type_id(ctx->logical_type);
138
+
139
+ switch(type_id) {
140
+ case DUCKDB_TYPE_LIST:
141
+ case DUCKDB_TYPE_MAP:
142
+ child_logical_type = duckdb_list_type_child_type(ctx->logical_type);
143
+ logical_type = rbduckdb_create_logical_type(child_logical_type);
144
+ break;
145
+ case DUCKDB_TYPE_ARRAY:
146
+ child_logical_type = duckdb_array_type_child_type(ctx->logical_type);
147
+ logical_type = rbduckdb_create_logical_type(child_logical_type);
148
+ break;
149
+ default:
150
+ logical_type = Qnil;
151
+ }
152
+ return logical_type;
153
+ }
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
+
180
+ /*
181
+ * call-seq:
182
+ * list_col.logical_type.size -> Integer
183
+ *
184
+ * Returns the size of the array column, otherwise 0.
185
+ *
186
+ */
187
+ static VALUE duckdb_logical_type_size(VALUE self) {
188
+ rubyDuckDBLogicalType *ctx;
189
+ TypedData_Get_Struct(self, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
190
+ return INT2FIX(duckdb_array_type_array_size(ctx->logical_type));
191
+ }
192
+
193
+ /*
194
+ * call-seq:
195
+ * map_col.logical_type.key_type -> DuckDB::LogicalType
196
+ *
197
+ * Returns the key logical type for map type, otherwise nil.
198
+ *
199
+ */
200
+ static VALUE duckdb_logical_type_key_type(VALUE self) {
201
+ rubyDuckDBLogicalType *ctx;
202
+ duckdb_logical_type key_logical_type;
203
+ VALUE logical_type = Qnil;
204
+
205
+ TypedData_Get_Struct(self, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
206
+ key_logical_type = duckdb_map_type_key_type(ctx->logical_type);
207
+ logical_type = rbduckdb_create_logical_type(key_logical_type);
208
+ return logical_type;
209
+ }
210
+
211
+ /*
212
+ * call-seq:
213
+ * map_col.logical_type.value_type -> DuckDB::LogicalType
214
+ *
215
+ * Returns the value logical type for map type, otherwise nil.
216
+ *
217
+ */
218
+ static VALUE duckdb_logical_type_value_type(VALUE self) {
219
+ rubyDuckDBLogicalType *ctx;
220
+ duckdb_logical_type value_logical_type;
221
+ VALUE logical_type = Qnil;
222
+
223
+ TypedData_Get_Struct(self, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
224
+ value_logical_type = duckdb_map_type_value_type(ctx->logical_type);
225
+ logical_type = rbduckdb_create_logical_type(value_logical_type);
226
+ return logical_type;
227
+ }
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
+
291
+ VALUE rbduckdb_create_logical_type(duckdb_logical_type logical_type) {
292
+ VALUE obj;
293
+ rubyDuckDBLogicalType *ctx;
294
+
295
+ obj = allocate(cDuckDBLogicalType);
296
+ TypedData_Get_Struct(obj, rubyDuckDBLogicalType, &logical_type_data_type, ctx);
297
+
298
+ ctx->logical_type = logical_type;
299
+
300
+ return obj;
301
+ }
302
+
303
+ void rbduckdb_init_duckdb_logical_type(void) {
304
+ #if 0
305
+ VALUE mDuckDB = rb_define_module("DuckDB");
306
+ #endif
307
+ cDuckDBLogicalType = rb_define_class_under(mDuckDB, "LogicalType", rb_cObject);
308
+ rb_define_alloc_func(cDuckDBLogicalType, allocate);
309
+
310
+ rb_define_private_method(cDuckDBLogicalType, "_type", duckdb_logical_type__type, 0);
311
+ rb_define_method(cDuckDBLogicalType, "width", duckdb_logical_type_width, 0);
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);
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);
317
+ rb_define_method(cDuckDBLogicalType, "size", duckdb_logical_type_size, 0);
318
+ rb_define_method(cDuckDBLogicalType, "key_type", duckdb_logical_type_key_type, 0);
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);
323
+ }
@@ -0,0 +1,13 @@
1
+ #ifndef RUBY_DUCKDB_LOGICAL_TYPE_H
2
+ #define RUBY_DUCKDB_LOGICAL_TYPE_H
3
+
4
+ struct _rubyDuckDBLogicalType {
5
+ duckdb_logical_type logical_type;
6
+ };
7
+
8
+ typedef struct _rubyDuckDBLogicalType rubyDuckDBLogicalType;
9
+
10
+ void rbduckdb_init_duckdb_logical_type(void);
11
+ VALUE rbduckdb_create_logical_type(duckdb_logical_type logical_type);
12
+
13
+ #endif
@@ -124,11 +124,13 @@ static VALUE duckdb_pending_result_execute_pending(VALUE self) {
124
124
  return result;
125
125
  }
126
126
 
127
+ /* :nodoc: */
127
128
  static VALUE duckdb_pending_result__state(VALUE self) {
128
129
  rubyDuckDBPendingResult *ctx = get_struct_pending_result(self);
129
130
  return INT2FIX(ctx->state);
130
131
  }
131
132
 
133
+ /* :nodoc: */
132
134
  static VALUE duckdb_pending_result__execute_check_state(VALUE self) {
133
135
  rubyDuckDBPendingResult *ctx = get_struct_pending_result(self);
134
136
  return INT2FIX(duckdb_pending_execute_check_state(ctx->pending_result));
@@ -141,6 +143,9 @@ rubyDuckDBPendingResult *get_struct_pending_result(VALUE obj) {
141
143
  }
142
144
 
143
145
  void rbduckdb_init_duckdb_pending_result(void) {
146
+ #if 0
147
+ VALUE mDuckDB = rb_define_module("DuckDB");
148
+ #endif
144
149
  cDuckDBPendingResult = rb_define_class_under(mDuckDB, "PendingResult", rb_cObject);
145
150
  rb_define_alloc_func(cDuckDBPendingResult, allocate);
146
151
 
@@ -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 = {
@@ -102,21 +103,49 @@ static VALUE duckdb_prepared_statement_nparams(VALUE self) {
102
103
  return ULL2NUM(duckdb_nparams(ctx->prepared_statement));
103
104
  }
104
105
 
106
+ /* :nodoc: */
107
+ typedef struct {
108
+ duckdb_prepared_statement prepared_statement;
109
+ duckdb_result *out_result;
110
+ duckdb_state retval;
111
+ } duckdb_prepared_statement_execute_nogvl_args;
112
+
113
+ /* :nodoc: */
114
+ static void duckdb_prepared_statement_execute_nogvl(void *ptr) {
115
+ duckdb_prepared_statement_execute_nogvl_args *args = (duckdb_prepared_statement_execute_nogvl_args *)ptr;
116
+
117
+ args->retval = duckdb_execute_prepared(args->prepared_statement, args->out_result);
118
+ }
119
+
105
120
  static VALUE duckdb_prepared_statement_execute(VALUE self) {
106
121
  rubyDuckDBPreparedStatement *ctx;
107
122
  rubyDuckDBResult *ctxr;
123
+ const char *error;
108
124
  VALUE result = rbduckdb_create_result();
109
- const char *p = NULL;
125
+ VALUE msg;
110
126
 
111
127
  TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
112
128
  ctxr = get_struct_result(result);
113
- if (duckdb_execute_prepared(ctx->prepared_statement, &(ctxr->result)) == DuckDBError) {
114
- p = duckdb_result_error(&(ctxr->result));
115
- if (p == NULL) {
116
- p = duckdb_prepare_error(ctx->prepared_statement);
129
+
130
+ duckdb_prepared_statement_execute_nogvl_args args = {
131
+ .prepared_statement = ctx->prepared_statement,
132
+ .out_result = &(ctxr->result),
133
+ .retval = DuckDBError,
134
+ };
135
+
136
+ rb_thread_call_without_gvl((void *)duckdb_prepared_statement_execute_nogvl, &args, RUBY_UBF_IO, 0);
137
+ duckdb_state state = args.retval;
138
+
139
+ if (state == DuckDBError) {
140
+ error = duckdb_prepare_error(args.prepared_statement);
141
+ if (error == NULL) {
142
+ error = duckdb_result_error(args.out_result);
117
143
  }
118
- rb_raise(eDuckDBError, "%s", p ? p : "Failed to execute prepared statement.");
144
+ msg = rb_str_new2(error ? error : "Failed to execute prepared statement.");
145
+
146
+ rb_raise(eDuckDBError, "%s", StringValuePtr(msg));
119
147
  }
148
+
120
149
  return result;
121
150
  }
122
151
 
@@ -316,18 +345,21 @@ static VALUE duckdb_prepared_statement_bind_null(VALUE self, VALUE vidx) {
316
345
  return self;
317
346
  }
318
347
 
348
+ /* :nodoc: */
319
349
  static VALUE duckdb_prepared_statement__statement_type(VALUE self) {
320
350
  rubyDuckDBPreparedStatement *ctx;
321
351
  TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
322
352
  return INT2FIX(duckdb_prepared_statement_type(ctx->prepared_statement));
323
353
  }
324
354
 
355
+ /* :nodoc: */
325
356
  static VALUE duckdb_prepared_statement__param_type(VALUE self, VALUE vidx) {
326
357
  rubyDuckDBPreparedStatement *ctx;
327
358
  TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
328
359
  return INT2FIX(duckdb_param_type(ctx->prepared_statement, NUM2ULL(vidx)));
329
360
  }
330
361
 
362
+ /* :nodoc: */
331
363
  static VALUE duckdb_prepared_statement__bind_date(VALUE self, VALUE vidx, VALUE year, VALUE month, VALUE day) {
332
364
  rubyDuckDBPreparedStatement *ctx;
333
365
  duckdb_date dt;
@@ -344,6 +376,7 @@ static VALUE duckdb_prepared_statement__bind_date(VALUE self, VALUE vidx, VALUE
344
376
  return self;
345
377
  }
346
378
 
379
+ /* :nodoc: */
347
380
  static VALUE duckdb_prepared_statement__bind_time(VALUE self, VALUE vidx, VALUE hour, VALUE min, VALUE sec, VALUE micros){
348
381
  rubyDuckDBPreparedStatement *ctx;
349
382
  duckdb_time time;
@@ -361,6 +394,7 @@ static VALUE duckdb_prepared_statement__bind_time(VALUE self, VALUE vidx, VALUE
361
394
  return self;
362
395
  }
363
396
 
397
+ /* :nodoc: */
364
398
  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) {
365
399
  duckdb_timestamp timestamp;
366
400
  rubyDuckDBPreparedStatement *ctx;
@@ -375,6 +409,7 @@ static VALUE duckdb_prepared_statement__bind_timestamp(VALUE self, VALUE vidx, V
375
409
  return self;
376
410
  }
377
411
 
412
+ /* :nodoc: */
378
413
  static VALUE duckdb_prepared_statement__bind_interval(VALUE self, VALUE vidx, VALUE months, VALUE days, VALUE micros) {
379
414
  duckdb_interval interval;
380
415
  rubyDuckDBPreparedStatement *ctx;
@@ -390,6 +425,7 @@ static VALUE duckdb_prepared_statement__bind_interval(VALUE self, VALUE vidx, VA
390
425
  return self;
391
426
  }
392
427
 
428
+ /* :nodoc: */
393
429
  static VALUE duckdb_prepared_statement__bind_hugeint(VALUE self, VALUE vidx, VALUE lower, VALUE upper) {
394
430
  duckdb_hugeint hugeint;
395
431
  rubyDuckDBPreparedStatement *ctx;
@@ -406,6 +442,24 @@ static VALUE duckdb_prepared_statement__bind_hugeint(VALUE self, VALUE vidx, VAL
406
442
  return self;
407
443
  }
408
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
+
462
+ /* :nodoc: */
409
463
  static VALUE duckdb_prepared_statement__bind_decimal(VALUE self, VALUE vidx, VALUE lower, VALUE upper, VALUE width, VALUE scale) {
410
464
  duckdb_hugeint hugeint;
411
465
  duckdb_decimal decimal;
@@ -433,6 +487,9 @@ rubyDuckDBPreparedStatement *get_struct_prepared_statement(VALUE self) {
433
487
  }
434
488
 
435
489
  void rbduckdb_init_duckdb_prepared_statement(void) {
490
+ #if 0
491
+ VALUE mDuckDB = rb_define_module("DuckDB");
492
+ #endif
436
493
  cDuckDBPreparedStatement = rb_define_class_under(mDuckDB, "PreparedStatement", rb_cObject);
437
494
 
438
495
  rb_define_alloc_func(cDuckDBPreparedStatement, allocate);
@@ -461,5 +518,6 @@ void rbduckdb_init_duckdb_prepared_statement(void) {
461
518
  rb_define_private_method(cDuckDBPreparedStatement, "_bind_timestamp", duckdb_prepared_statement__bind_timestamp, 8);
462
519
  rb_define_private_method(cDuckDBPreparedStatement, "_bind_interval", duckdb_prepared_statement__bind_interval, 4);
463
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);
464
522
  rb_define_private_method(cDuckDBPreparedStatement, "_bind_decimal", duckdb_prepared_statement__bind_decimal, 5);
465
523
  }