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.
- checksums.yaml +4 -4
- data/.github/workflows/make_documents.yml +34 -0
- data/.github/workflows/test_on_macos.yml +2 -3
- data/.github/workflows/test_on_ubuntu.yml +2 -2
- data/.github/workflows/test_on_windows.yml +2 -2
- data/.gitignore +1 -0
- data/.rdoc_options +22 -0
- data/CHANGELOG.md +63 -0
- data/Dockerfile +2 -2
- data/Gemfile.lock +14 -12
- data/README.md +2 -1
- data/duckdb.gemspec +1 -0
- data/ext/duckdb/appender.c +140 -173
- data/ext/duckdb/blob.c +3 -0
- data/ext/duckdb/column.c +33 -3
- data/ext/duckdb/config.c +3 -0
- data/ext/duckdb/connection.c +6 -0
- data/ext/duckdb/database.c +6 -0
- data/ext/duckdb/duckdb.c +1 -0
- data/ext/duckdb/error.c +3 -0
- data/ext/duckdb/extconf.rb +5 -8
- data/ext/duckdb/extracted_statements.c +3 -0
- data/ext/duckdb/logical_type.c +323 -0
- data/ext/duckdb/logical_type.h +13 -0
- data/ext/duckdb/pending_result.c +5 -0
- data/ext/duckdb/prepared_statement.c +64 -6
- data/ext/duckdb/result.c +17 -45
- data/ext/duckdb/ruby-duckdb.h +6 -8
- data/lib/duckdb/appender.rb +458 -56
- data/lib/duckdb/column.rb +0 -2
- data/lib/duckdb/interval.rb +12 -10
- data/lib/duckdb/logical_type.rb +110 -0
- data/lib/duckdb/pending_result.rb +1 -1
- data/lib/duckdb/prepared_statement.rb +18 -1
- data/lib/duckdb/result.rb +16 -16
- data/lib/duckdb/version.rb +1 -1
- data/lib/duckdb.rb +1 -0
- metadata +9 -6
data/ext/duckdb/database.c
CHANGED
@@ -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
data/ext/duckdb/extconf.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'mkmf'
|
4
4
|
|
5
|
-
DUCKDB_REQUIRED_VERSION = '1.
|
5
|
+
DUCKDB_REQUIRED_VERSION = '1.1.0'
|
6
6
|
|
7
7
|
def check_duckdb_header(header, version)
|
8
8
|
found = find_header(
|
@@ -56,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', '
|
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
|
data/ext/duckdb/pending_result.c
CHANGED
@@ -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
|
-
|
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
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
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
|
-
|
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
|
}
|