duckdb 1.5.5.1 → 1.5.6.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 +3 -0
- data/ext/duckdb/aggregate_function.c +9 -9
- data/ext/duckdb/aggregate_function_set.c +3 -4
- data/ext/duckdb/appender.c +11 -1
- data/ext/duckdb/arrow_array_stream.c +6 -2
- data/ext/duckdb/arrow_import.c +1 -1
- data/ext/duckdb/client_context.c +1 -1
- data/ext/duckdb/column.c +1 -1
- data/ext/duckdb/column.h +0 -1
- data/ext/duckdb/config.c +1 -1
- data/ext/duckdb/connection.c +17 -6
- data/ext/duckdb/data_chunk.c +1 -1
- data/ext/duckdb/database.c +24 -13
- data/ext/duckdb/expression.c +1 -1
- data/ext/duckdb/extracted_statements.c +1 -1
- data/ext/duckdb/instance_cache.c +14 -6
- data/ext/duckdb/logical_type.c +1 -1
- data/ext/duckdb/pending_result.c +6 -1
- data/ext/duckdb/prepared_statement.c +6 -1
- data/ext/duckdb/result.c +6 -1
- data/ext/duckdb/result.h +1 -1
- data/ext/duckdb/scalar_function.c +5 -5
- data/ext/duckdb/scalar_function_bind_info.c +1 -1
- data/ext/duckdb/scalar_function_set.c +3 -4
- data/ext/duckdb/table_description.c +1 -1
- data/ext/duckdb/table_function.c +7 -7
- data/ext/duckdb/table_function_bind_info.c +1 -1
- data/ext/duckdb/table_function_function_info.c +1 -1
- data/ext/duckdb/table_function_init_info.c +1 -1
- data/ext/duckdb/value.c +2 -2
- data/ext/duckdb/vector.c +1 -1
- data/lib/duckdb/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cd491bbe1e80d7e2f20455e768b0331c91cbd015e570ccc023497c74217f86a0
|
|
4
|
+
data.tar.gz: b3c9d5bd5b38a7f72fa7d8c00be7bd20d61505c234efc702cd365b040dcce0dd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: acc1eb730e31250b6d8cc281923dd332b2141a4fb2ced34821126928b0c94757a6b1c5f49e29c39c01e899b196e4fe857ea529d62bd8fd88015c2dad806fbb8f
|
|
7
|
+
data.tar.gz: a18fc12e5e6252c32129d8ab005f75b29834711fc5790e009a8dc45fabcb9c9c9e88f1c16213a16bf346da906087ec9f57dea7e6162e51554d622a20575cdf55
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
# Unreleased
|
|
6
6
|
|
|
7
|
+
# 1.5.6.0 - 2026-10-11
|
|
8
|
+
- bump up DuckDB 1.5.6 on CI.
|
|
9
|
+
|
|
7
10
|
# 1.5.5.1 - 2026-08-29
|
|
8
11
|
- fix `DuckDB::Database#close` deadlocking when DuckDB tears down a pipeline that still owes a UDF callback, as a failed aggregate window query does on DuckDB 1.4.x. `duckdb_close` joins DuckDB's worker threads, and a worker running a callback waits for the executor thread, which waits for the GVL the closing thread was holding. The GVL is now released for the duration of `duckdb_close`.
|
|
9
12
|
- fix a segfault when an aggregate UDF was used as a window function over a constant frame, such as `OVER ()` or `OVER (PARTITION BY x)` (issue #1446). DuckDB's `CAPIAggregateUpdate` does not flatten the state vector the way its combine and finalize counterparts do, so it hands the update callback a single state while reporting the partition's full row count; reading one state per row then ran off the end of the allocation. Such a chunk is now recognised and every row aggregated into the one state DuckDB supplied.
|
|
@@ -9,7 +9,7 @@ VALUE cDuckDBAggregateFunction;
|
|
|
9
9
|
* VALUE returned from the user's init_proc and later passed to
|
|
10
10
|
* finalize_proc.
|
|
11
11
|
*
|
|
12
|
-
* Protected from GC via
|
|
12
|
+
* Protected from GC via rb_global_variable on init.
|
|
13
13
|
*/
|
|
14
14
|
static VALUE g_aggregate_state_registry;
|
|
15
15
|
|
|
@@ -37,7 +37,7 @@ static unsigned long long g_next_state_id = 0;
|
|
|
37
37
|
* reach state_id is the crash; membership here is the only test that does not.
|
|
38
38
|
* See issue #1446.
|
|
39
39
|
*
|
|
40
|
-
* Protected from GC via
|
|
40
|
+
* Protected from GC via rb_global_variable on init.
|
|
41
41
|
*/
|
|
42
42
|
static VALUE g_aggregate_state_addresses;
|
|
43
43
|
|
|
@@ -69,7 +69,7 @@ static VALUE aggregate_function__set_special_handling(VALUE self);
|
|
|
69
69
|
static const rb_data_type_t aggregate_function_data_type = {
|
|
70
70
|
"DuckDB/AggregateFunction",
|
|
71
71
|
{mark, deallocate, memsize, compact},
|
|
72
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
|
72
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
|
73
73
|
};
|
|
74
74
|
|
|
75
75
|
static void mark(void *ctx) {
|
|
@@ -895,7 +895,7 @@ static VALUE aggregate_function__set_init(VALUE self) {
|
|
|
895
895
|
}
|
|
896
896
|
|
|
897
897
|
TypedData_Get_Struct(self, rubyDuckDBAggregateFunction, &aggregate_function_data_type, p);
|
|
898
|
-
p->init_proc
|
|
898
|
+
RB_OBJ_WRITE(self, &p->init_proc, rb_block_proc());
|
|
899
899
|
|
|
900
900
|
maybe_set_functions(p);
|
|
901
901
|
|
|
@@ -911,7 +911,7 @@ static VALUE aggregate_function__set_update(VALUE self) {
|
|
|
911
911
|
}
|
|
912
912
|
|
|
913
913
|
TypedData_Get_Struct(self, rubyDuckDBAggregateFunction, &aggregate_function_data_type, p);
|
|
914
|
-
p->update_proc
|
|
914
|
+
RB_OBJ_WRITE(self, &p->update_proc, rb_block_proc());
|
|
915
915
|
|
|
916
916
|
maybe_set_functions(p);
|
|
917
917
|
|
|
@@ -927,7 +927,7 @@ static VALUE aggregate_function__set_combine(VALUE self) {
|
|
|
927
927
|
}
|
|
928
928
|
|
|
929
929
|
TypedData_Get_Struct(self, rubyDuckDBAggregateFunction, &aggregate_function_data_type, p);
|
|
930
|
-
p->combine_proc
|
|
930
|
+
RB_OBJ_WRITE(self, &p->combine_proc, rb_block_proc());
|
|
931
931
|
|
|
932
932
|
maybe_set_functions(p);
|
|
933
933
|
|
|
@@ -943,7 +943,7 @@ static VALUE aggregate_function__set_finalize(VALUE self) {
|
|
|
943
943
|
}
|
|
944
944
|
|
|
945
945
|
TypedData_Get_Struct(self, rubyDuckDBAggregateFunction, &aggregate_function_data_type, p);
|
|
946
|
-
p->finalize_proc
|
|
946
|
+
RB_OBJ_WRITE(self, &p->finalize_proc, rb_block_proc());
|
|
947
947
|
|
|
948
948
|
maybe_set_functions(p);
|
|
949
949
|
|
|
@@ -983,8 +983,8 @@ void rbduckdb_init_aggregate_function(void) {
|
|
|
983
983
|
rb_define_singleton_method(cDuckDBAggregateFunction, "_state_registry_size",
|
|
984
984
|
aggregate_function_s__state_registry_size, 0);
|
|
985
985
|
|
|
986
|
+
rb_global_variable(&g_aggregate_state_registry);
|
|
986
987
|
g_aggregate_state_registry = rb_hash_new();
|
|
987
|
-
|
|
988
|
+
rb_global_variable(&g_aggregate_state_addresses);
|
|
988
989
|
g_aggregate_state_addresses = rb_hash_new();
|
|
989
|
-
rb_gc_register_mark_object(g_aggregate_state_addresses);
|
|
990
990
|
}
|
|
@@ -13,12 +13,12 @@ static VALUE aggregate_function_set__add(VALUE self, VALUE aggregate_function);
|
|
|
13
13
|
static const rb_data_type_t aggregate_function_set_data_type = {
|
|
14
14
|
"DuckDB/AggregateFunctionSet",
|
|
15
15
|
{mark, deallocate, memsize, compact},
|
|
16
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
|
16
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
static void mark(void *ctx) {
|
|
20
20
|
rubyDuckDBAggregateFunctionSet *p = (rubyDuckDBAggregateFunctionSet *)ctx;
|
|
21
|
-
|
|
21
|
+
rb_gc_mark_movable(p->functions);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
static void deallocate(void *ctx) {
|
|
@@ -35,8 +35,7 @@ static void compact(void *ctx) {
|
|
|
35
35
|
static VALUE allocate(VALUE klass) {
|
|
36
36
|
rubyDuckDBAggregateFunctionSet *ctx = xcalloc((size_t)1, sizeof(rubyDuckDBAggregateFunctionSet));
|
|
37
37
|
VALUE obj = TypedData_Wrap_Struct(klass, &aggregate_function_set_data_type, ctx);
|
|
38
|
-
ctx->functions
|
|
39
|
-
RB_GC_GUARD(ctx->functions);
|
|
38
|
+
RB_OBJ_WRITE(obj, &ctx->functions, rb_ary_new());
|
|
40
39
|
return obj;
|
|
41
40
|
}
|
|
42
41
|
|
data/ext/duckdb/appender.c
CHANGED
|
@@ -50,10 +50,20 @@ static VALUE appender__clear_columns(VALUE self);
|
|
|
50
50
|
static VALUE appender__close(VALUE self);
|
|
51
51
|
static VALUE state_to_rbool(duckdb_state state);
|
|
52
52
|
|
|
53
|
+
/*
|
|
54
|
+
* Keeps RUBY_TYPED_FREE_IMMEDIATELY although duckdb_appender_destroy flushes
|
|
55
|
+
* buffered rows (blocking I/O): when an unclosed appender is collected in the
|
|
56
|
+
* same GC as its connection, freeing it during sweep runs before the deferred
|
|
57
|
+
* Connection/Database free, so its rows still reach the table. Deferring it too
|
|
58
|
+
* would let the connection close first and lose rows. (The appender holds no
|
|
59
|
+
* reference to its connection, so if the connection is collected in an earlier
|
|
60
|
+
* GC the flush is lost anyway.) Freeing in sweep cannot shut the database down:
|
|
61
|
+
* DuckDB's BaseAppender holds only a weak_ptr<ClientContext>.
|
|
62
|
+
*/
|
|
53
63
|
static const rb_data_type_t appender_data_type = {
|
|
54
64
|
"DuckDB/Appender",
|
|
55
65
|
{NULL, deallocate, memsize,},
|
|
56
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
|
66
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
|
57
67
|
};
|
|
58
68
|
|
|
59
69
|
static void deallocate(void * ctx) {
|
|
@@ -13,7 +13,7 @@ typedef struct {
|
|
|
13
13
|
* the Ruby DuckDB::ArrowArrayStream object is gone, so this context is
|
|
14
14
|
* freed only by the stream release callback, and it holds a reference on
|
|
15
15
|
* the result struct (rbduckdb_result_ref) until then. The release callback
|
|
16
|
-
* must not call any Ruby API: it can run during GC
|
|
16
|
+
* must not call any Ruby API: it can run during GC finalization (via deallocate
|
|
17
17
|
* of an unconsumed stream) or from a non-Ruby thread.
|
|
18
18
|
*/
|
|
19
19
|
typedef struct {
|
|
@@ -34,10 +34,14 @@ static int stream_get_next(struct ArrowArrayStream *stream, struct ArrowArray *o
|
|
|
34
34
|
static const char *stream_get_last_error(struct ArrowArrayStream *stream);
|
|
35
35
|
static void stream_release(struct ArrowArrayStream *stream);
|
|
36
36
|
|
|
37
|
+
/*
|
|
38
|
+
* No RUBY_TYPED_FREE_IMMEDIATELY: deallocate can block, and must not run
|
|
39
|
+
* during GC sweep: releasing the stream may destroy a streaming result (see result.c).
|
|
40
|
+
*/
|
|
37
41
|
static const rb_data_type_t arrow_array_stream_data_type = {
|
|
38
42
|
"DuckDB/ArrowArrayStream",
|
|
39
43
|
{NULL, deallocate, memsize,},
|
|
40
|
-
0, 0,
|
|
44
|
+
0, 0, RUBY_TYPED_WB_PROTECTED
|
|
41
45
|
};
|
|
42
46
|
|
|
43
47
|
static void deallocate(void *ctx) {
|
data/ext/duckdb/arrow_import.c
CHANGED
|
@@ -26,7 +26,7 @@ static VALUE connection__arrow_release(VALUE self, VALUE address);
|
|
|
26
26
|
static const rb_data_type_t arrow_converted_schema_data_type = {
|
|
27
27
|
"DuckDB/ArrowConvertedSchema",
|
|
28
28
|
{NULL, deallocate, memsize,},
|
|
29
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
|
29
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
static void deallocate(void *ctx) {
|
data/ext/duckdb/client_context.c
CHANGED
|
@@ -10,7 +10,7 @@ static VALUE client_context_connection_id(VALUE self);
|
|
|
10
10
|
static const rb_data_type_t client_context_data_type = {
|
|
11
11
|
"DuckDB/ClientContext",
|
|
12
12
|
{NULL, deallocate, memsize,},
|
|
13
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
|
13
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
static void deallocate(void *ctx) {
|
data/ext/duckdb/column.c
CHANGED
|
@@ -12,7 +12,7 @@ static VALUE column_name(VALUE oDuckDBColumn);
|
|
|
12
12
|
static const rb_data_type_t column_data_type = {
|
|
13
13
|
"DuckDB/Column",
|
|
14
14
|
{NULL, deallocate, memsize,},
|
|
15
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
|
15
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
static void deallocate(void *ctx) {
|
data/ext/duckdb/column.h
CHANGED
data/ext/duckdb/config.c
CHANGED
|
@@ -13,7 +13,7 @@ static VALUE config_set_config(VALUE self, VALUE key, VALUE value);
|
|
|
13
13
|
static const rb_data_type_t config_data_type = {
|
|
14
14
|
"DuckDB/Config",
|
|
15
15
|
{NULL, deallocate, memsize,},
|
|
16
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
|
16
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
static void deallocate(void * ctx) {
|
data/ext/duckdb/connection.c
CHANGED
|
@@ -4,6 +4,7 @@ VALUE cDuckDBConnection;
|
|
|
4
4
|
|
|
5
5
|
static void deallocate(void *ctx);
|
|
6
6
|
static void mark(void *ctx);
|
|
7
|
+
static void compact(void *ctx);
|
|
7
8
|
static VALUE allocate(VALUE klass);
|
|
8
9
|
static size_t memsize(const void *p);
|
|
9
10
|
static VALUE connection_disconnect(VALUE self);
|
|
@@ -19,10 +20,15 @@ static VALUE connection__register_aggregate_function_set(VALUE self, VALUE aggre
|
|
|
19
20
|
static VALUE connection__register_table_function(VALUE self, VALUE table_function);
|
|
20
21
|
static VALUE connection__get_table_names(VALUE self, VALUE query, VALUE qualified);
|
|
21
22
|
|
|
23
|
+
/*
|
|
24
|
+
* No RUBY_TYPED_FREE_IMMEDIATELY: deallocate can block, and must not run
|
|
25
|
+
* during GC sweep: duckdb_disconnect rolls back an open transaction and may drop the
|
|
26
|
+
* last reference to the database (checkpoint on shutdown).
|
|
27
|
+
*/
|
|
22
28
|
static const rb_data_type_t connection_data_type = {
|
|
23
29
|
"DuckDB/Connection",
|
|
24
|
-
{mark, deallocate, memsize,},
|
|
25
|
-
0, 0,
|
|
30
|
+
{mark, deallocate, memsize, compact},
|
|
31
|
+
0, 0, RUBY_TYPED_WB_PROTECTED
|
|
26
32
|
};
|
|
27
33
|
|
|
28
34
|
static void deallocate(void *ctx) {
|
|
@@ -34,7 +40,12 @@ static void deallocate(void *ctx) {
|
|
|
34
40
|
|
|
35
41
|
static void mark(void *ctx) {
|
|
36
42
|
rubyDuckDBConnection *p = (rubyDuckDBConnection *)ctx;
|
|
37
|
-
|
|
43
|
+
rb_gc_mark_movable(p->database);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
static void compact(void *ctx) {
|
|
47
|
+
rubyDuckDBConnection *p = (rubyDuckDBConnection *)ctx;
|
|
48
|
+
p->database = rb_gc_location(p->database);
|
|
38
49
|
}
|
|
39
50
|
|
|
40
51
|
static VALUE allocate(VALUE klass) {
|
|
@@ -77,7 +88,7 @@ VALUE rbduckdb_create_connection(VALUE oDuckDBDatabase) {
|
|
|
77
88
|
if (duckdb_connect(ctxdb->db, &(ctxcon->con)) == DuckDBError) {
|
|
78
89
|
rb_raise(eDuckDBError, "connection error");
|
|
79
90
|
}
|
|
80
|
-
ctxcon->database
|
|
91
|
+
RB_OBJ_WRITE(obj, &ctxcon->database, oDuckDBDatabase);
|
|
81
92
|
|
|
82
93
|
return obj;
|
|
83
94
|
}
|
|
@@ -93,7 +104,7 @@ static VALUE connection_disconnect(VALUE self) {
|
|
|
93
104
|
* reachable from other connections. They are released with the database.
|
|
94
105
|
* This connection no longer needs the database, so stop retaining it.
|
|
95
106
|
*/
|
|
96
|
-
ctx->database
|
|
107
|
+
RB_OBJ_WRITE(self, &ctx->database, Qnil);
|
|
97
108
|
|
|
98
109
|
return self;
|
|
99
110
|
}
|
|
@@ -162,7 +173,7 @@ static VALUE connection__connect(VALUE self, VALUE oDuckDBDatabase) {
|
|
|
162
173
|
if (duckdb_connect(ctxdb->db, &(ctx->con)) == DuckDBError) {
|
|
163
174
|
rb_raise(eDuckDBError, "connection error");
|
|
164
175
|
}
|
|
165
|
-
ctx->database
|
|
176
|
+
RB_OBJ_WRITE(self, &ctx->database, oDuckDBDatabase);
|
|
166
177
|
|
|
167
178
|
return self;
|
|
168
179
|
}
|
data/ext/duckdb/data_chunk.c
CHANGED
|
@@ -16,7 +16,7 @@ static VALUE data_chunk__reset(VALUE self);
|
|
|
16
16
|
static const rb_data_type_t data_chunk_data_type = {
|
|
17
17
|
"DuckDB/DataChunk",
|
|
18
18
|
{NULL, deallocate, memsize,},
|
|
19
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
|
19
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
static void deallocate(void *ctx) {
|
data/ext/duckdb/database.c
CHANGED
|
@@ -5,6 +5,7 @@ VALUE cDuckDBDatabase;
|
|
|
5
5
|
static void close_database(rubyDuckDB *p);
|
|
6
6
|
static void deallocate(void * ctx);
|
|
7
7
|
static void mark(void *ctx);
|
|
8
|
+
static void compact(void *ctx);
|
|
8
9
|
static VALUE allocate(VALUE klass);
|
|
9
10
|
static size_t memsize(const void *p);
|
|
10
11
|
static duckdb_config create_config_with_ruby_api(void);
|
|
@@ -12,10 +13,14 @@ static VALUE database__initialize(VALUE self, VALUE file, VALUE config);
|
|
|
12
13
|
static VALUE database__connect(VALUE self);
|
|
13
14
|
static VALUE database_close(VALUE self);
|
|
14
15
|
|
|
16
|
+
/*
|
|
17
|
+
* No RUBY_TYPED_FREE_IMMEDIATELY: deallocate can block, and must not run
|
|
18
|
+
* during GC sweep: duckdb_close may checkpoint to disk and joins worker threads.
|
|
19
|
+
*/
|
|
15
20
|
static const rb_data_type_t database_data_type = {
|
|
16
21
|
"DuckDB/Database",
|
|
17
|
-
{mark, deallocate, memsize,},
|
|
18
|
-
0, 0,
|
|
22
|
+
{mark, deallocate, memsize, compact},
|
|
23
|
+
0, 0, RUBY_TYPED_WB_PROTECTED
|
|
19
24
|
};
|
|
20
25
|
|
|
21
26
|
static void close_database(rubyDuckDB *p) {
|
|
@@ -31,7 +36,7 @@ static void close_database(rubyDuckDB *p) {
|
|
|
31
36
|
* for us, and we wait for the worker.
|
|
32
37
|
*
|
|
33
38
|
* The GC free function calls close_database directly and cannot do this;
|
|
34
|
-
*
|
|
39
|
+
* a free function must not release the GVL. A database reaching close via
|
|
35
40
|
* the GC with callbacks still pending would deadlock the same way.
|
|
36
41
|
*/
|
|
37
42
|
static void *close_database_without_gvl(void *ctx) {
|
|
@@ -49,9 +54,17 @@ static void deallocate(void * ctx) {
|
|
|
49
54
|
static void mark(void *ctx) {
|
|
50
55
|
rubyDuckDB *p = (rubyDuckDB *)ctx;
|
|
51
56
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
57
|
+
rb_gc_mark_movable(p->registered_functions);
|
|
58
|
+
rb_gc_mark_movable(p->cached_path);
|
|
59
|
+
rb_gc_mark_movable(p->cache_wrappers);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
static void compact(void *ctx) {
|
|
63
|
+
rubyDuckDB *p = (rubyDuckDB *)ctx;
|
|
64
|
+
|
|
65
|
+
p->registered_functions = rb_gc_location(p->registered_functions);
|
|
66
|
+
p->cached_path = rb_gc_location(p->cached_path);
|
|
67
|
+
p->cache_wrappers = rb_gc_location(p->cache_wrappers);
|
|
55
68
|
}
|
|
56
69
|
|
|
57
70
|
static size_t memsize(const void *p) {
|
|
@@ -61,11 +74,9 @@ static size_t memsize(const void *p) {
|
|
|
61
74
|
static VALUE allocate(VALUE klass) {
|
|
62
75
|
rubyDuckDB *ctx = xcalloc((size_t)1, sizeof(rubyDuckDB));
|
|
63
76
|
VALUE obj = TypedData_Wrap_Struct(klass, &database_data_type, ctx);
|
|
64
|
-
VALUE registered_functions = rb_ary_new();
|
|
65
|
-
ctx->registered_functions = registered_functions;
|
|
66
77
|
ctx->cached_path = Qnil;
|
|
67
78
|
ctx->cache_wrappers = Qnil;
|
|
68
|
-
|
|
79
|
+
RB_OBJ_WRITE(obj, &ctx->registered_functions, rb_ary_new());
|
|
69
80
|
return obj;
|
|
70
81
|
}
|
|
71
82
|
|
|
@@ -89,8 +100,8 @@ void rbduckdb_database_set_cache_entry(VALUE database, VALUE path, VALUE wrapper
|
|
|
89
100
|
rubyDuckDB *ctx;
|
|
90
101
|
|
|
91
102
|
TypedData_Get_Struct(database, rubyDuckDB, &database_data_type, ctx);
|
|
92
|
-
ctx->cached_path
|
|
93
|
-
ctx->cache_wrappers
|
|
103
|
+
RB_OBJ_WRITE(database, &ctx->cached_path, rb_str_new_frozen(path));
|
|
104
|
+
RB_OBJ_WRITE(database, &ctx->cache_wrappers, wrappers);
|
|
94
105
|
}
|
|
95
106
|
|
|
96
107
|
rubyDuckDB *rbduckdb_get_struct_database(VALUE obj) {
|
|
@@ -181,8 +192,8 @@ static VALUE database_close(VALUE self) {
|
|
|
181
192
|
*/
|
|
182
193
|
if (!NIL_P(ctx->cache_wrappers)) {
|
|
183
194
|
rb_funcall(ctx->cache_wrappers, rb_intern("delete"), 1, self);
|
|
184
|
-
ctx->cache_wrappers
|
|
185
|
-
ctx->cached_path
|
|
195
|
+
RB_OBJ_WRITE(self, &ctx->cache_wrappers, Qnil);
|
|
196
|
+
RB_OBJ_WRITE(self, &ctx->cached_path, Qnil);
|
|
186
197
|
}
|
|
187
198
|
rb_thread_call_without_gvl(close_database_without_gvl, ctx, NULL, NULL);
|
|
188
199
|
return self;
|
data/ext/duckdb/expression.c
CHANGED
|
@@ -11,7 +11,7 @@ static VALUE expression__fold(VALUE self, VALUE client_context);
|
|
|
11
11
|
static const rb_data_type_t expression_data_type = {
|
|
12
12
|
"DuckDB/Expression",
|
|
13
13
|
{NULL, deallocate, memsize,},
|
|
14
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
|
14
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
static void deallocate(void *ctx) {
|
|
@@ -9,7 +9,7 @@ static size_t memsize(const void *p);
|
|
|
9
9
|
static const rb_data_type_t extract_statements_data_type = {
|
|
10
10
|
"DuckDB/ExtractedStatements",
|
|
11
11
|
{NULL, deallocate, memsize,},
|
|
12
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
|
12
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
static void deallocate(void *ctx);
|
data/ext/duckdb/instance_cache.c
CHANGED
|
@@ -4,6 +4,7 @@ VALUE cDuckDBInstanceCache;
|
|
|
4
4
|
|
|
5
5
|
static void deallocate(void * ctx);
|
|
6
6
|
static void mark(void *ctx);
|
|
7
|
+
static void compact(void *ctx);
|
|
7
8
|
static VALUE allocate(VALUE klass);
|
|
8
9
|
static VALUE memoizable_path(VALUE vpath);
|
|
9
10
|
static VALUE find_cached_wrapper(rubyDuckDBInstanceCache *ctx, VALUE vpath);
|
|
@@ -14,8 +15,8 @@ static VALUE instance_cache_destroy(VALUE self);
|
|
|
14
15
|
|
|
15
16
|
static const rb_data_type_t instance_cache_data_type = {
|
|
16
17
|
"DuckDB/InstanceCache",
|
|
17
|
-
{mark, deallocate, memsize,},
|
|
18
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
|
18
|
+
{mark, deallocate, memsize, compact},
|
|
19
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
|
19
20
|
};
|
|
20
21
|
|
|
21
22
|
static void deallocate(void * ctx) {
|
|
@@ -30,7 +31,13 @@ static void deallocate(void * ctx) {
|
|
|
30
31
|
static void mark(void *ctx) {
|
|
31
32
|
rubyDuckDBInstanceCache *p = (rubyDuckDBInstanceCache *)ctx;
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
rb_gc_mark_movable(p->wrappers);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
static void compact(void *ctx) {
|
|
38
|
+
rubyDuckDBInstanceCache *p = (rubyDuckDBInstanceCache *)ctx;
|
|
39
|
+
|
|
40
|
+
p->wrappers = rb_gc_location(p->wrappers);
|
|
34
41
|
}
|
|
35
42
|
|
|
36
43
|
static size_t memsize(const void *p) {
|
|
@@ -87,9 +94,10 @@ static VALUE instance_cache_initialize(VALUE self) {
|
|
|
87
94
|
rb_raise(eDuckDBError, "Failed to create instance cache");
|
|
88
95
|
}
|
|
89
96
|
|
|
90
|
-
ctx->wrappers
|
|
91
|
-
|
|
92
|
-
|
|
97
|
+
RB_OBJ_WRITE(self, &ctx->wrappers,
|
|
98
|
+
rb_funcall(rb_const_get(rb_const_get(rb_cObject, rb_intern("ObjectSpace")),
|
|
99
|
+
rb_intern("WeakMap")),
|
|
100
|
+
rb_intern("new"), 0));
|
|
93
101
|
|
|
94
102
|
return self;
|
|
95
103
|
}
|
data/ext/duckdb/logical_type.c
CHANGED
|
@@ -35,7 +35,7 @@ static VALUE logical_type_initialize(VALUE self, VALUE type_id_arg);
|
|
|
35
35
|
static const rb_data_type_t logical_type_data_type = {
|
|
36
36
|
"DuckDB/LogicalType",
|
|
37
37
|
{NULL, deallocate, memsize,},
|
|
38
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
|
38
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
static void deallocate(void *ctx) {
|
data/ext/duckdb/pending_result.c
CHANGED
|
@@ -12,10 +12,15 @@ static VALUE pending_result_execution_finished_p(VALUE self);
|
|
|
12
12
|
static VALUE pending_result__state(VALUE self);
|
|
13
13
|
static VALUE pending_result__execute_check_state(VALUE self);
|
|
14
14
|
|
|
15
|
+
/*
|
|
16
|
+
* No RUBY_TYPED_FREE_IMMEDIATELY: deallocate can block, and must not run
|
|
17
|
+
* during GC sweep: the pending result holds a ClientContext reference; dropping the last
|
|
18
|
+
* one rolls back an open transaction and may shut the database down.
|
|
19
|
+
*/
|
|
15
20
|
static const rb_data_type_t pending_result_data_type = {
|
|
16
21
|
"DuckDB/PendingResult",
|
|
17
22
|
{NULL, deallocate, memsize,},
|
|
18
|
-
0, 0,
|
|
23
|
+
0, 0, RUBY_TYPED_WB_PROTECTED
|
|
19
24
|
};
|
|
20
25
|
|
|
21
26
|
static void deallocate(void *ctx) {
|
|
@@ -47,10 +47,15 @@ static VALUE prepared_statement__bind_uuid(VALUE self, VALUE vidx, VALUE val);
|
|
|
47
47
|
static VALUE prepared_statement__bind_decimal(VALUE self, VALUE vidx, VALUE lower, VALUE upper, VALUE width, VALUE scale);
|
|
48
48
|
static VALUE prepared_statement__bind_value(VALUE self, VALUE vidx, VALUE val);
|
|
49
49
|
|
|
50
|
+
/*
|
|
51
|
+
* No RUBY_TYPED_FREE_IMMEDIATELY: deallocate can block, and must not run
|
|
52
|
+
* during GC sweep: the statement holds a ClientContext reference; dropping the last one
|
|
53
|
+
* rolls back an open transaction and may shut the database down.
|
|
54
|
+
*/
|
|
50
55
|
static const rb_data_type_t prepared_statement_data_type = {
|
|
51
56
|
"DuckDB/PreparedStatement",
|
|
52
57
|
{NULL, deallocate, memsize,},
|
|
53
|
-
0, 0,
|
|
58
|
+
0, 0, RUBY_TYPED_WB_PROTECTED
|
|
54
59
|
};
|
|
55
60
|
|
|
56
61
|
static void destroy_prepared_statement(rubyDuckDBPreparedStatement *p) {
|
data/ext/duckdb/result.c
CHANGED
|
@@ -48,10 +48,15 @@ static VALUE vector_timestamp_tz(void* vector_data, idx_t row_idx);
|
|
|
48
48
|
static VALUE vector_uuid(void* vector_data, idx_t row_idx);
|
|
49
49
|
static VALUE vector_value(duckdb_vector vector, idx_t row_idx);
|
|
50
50
|
|
|
51
|
+
/*
|
|
52
|
+
* No RUBY_TYPED_FREE_IMMEDIATELY: deallocate can block, and must not run
|
|
53
|
+
* during GC sweep: a streaming result holds a ClientContext reference; dropping the last
|
|
54
|
+
* one rolls back an open transaction and may shut the database down.
|
|
55
|
+
*/
|
|
51
56
|
static const rb_data_type_t result_data_type = {
|
|
52
57
|
"DuckDB/Result",
|
|
53
58
|
{NULL, deallocate, memsize,},
|
|
54
|
-
0, 0,
|
|
59
|
+
0, 0, RUBY_TYPED_WB_PROTECTED
|
|
55
60
|
};
|
|
56
61
|
|
|
57
62
|
static void deallocate(void *ctx) {
|
data/ext/duckdb/result.h
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* object holds one reference, and each exported Arrow stream holds another,
|
|
7
7
|
* so the duckdb_result stays valid for consumers that outlive the Ruby
|
|
8
8
|
* objects. rbduckdb_result_unref() must not call any Ruby API: it runs from
|
|
9
|
-
* GC
|
|
9
|
+
* GC finalization (deallocate) and from Arrow stream release callbacks.
|
|
10
10
|
*/
|
|
11
11
|
struct _rubyDuckDBResult {
|
|
12
12
|
duckdb_result result;
|
|
@@ -79,13 +79,13 @@ static void execute_callback_protected(void *user_data) {
|
|
|
79
79
|
static const rb_data_type_t scalar_function_data_type = {
|
|
80
80
|
"DuckDB/ScalarFunction",
|
|
81
81
|
{mark, deallocate, memsize, compact},
|
|
82
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
|
82
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
|
83
83
|
};
|
|
84
84
|
|
|
85
85
|
static void mark(void *ctx) {
|
|
86
86
|
rubyDuckDBScalarFunction *p = (rubyDuckDBScalarFunction *)ctx;
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
rb_gc_mark_movable(p->function_proc);
|
|
88
|
+
rb_gc_mark_movable(p->bind_proc);
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
static void deallocate(void * ctx) {
|
|
@@ -371,7 +371,7 @@ static VALUE scalar_function_set_function(VALUE self) {
|
|
|
371
371
|
|
|
372
372
|
TypedData_Get_Struct(self, rubyDuckDBScalarFunction, &scalar_function_data_type, p);
|
|
373
373
|
|
|
374
|
-
p->function_proc
|
|
374
|
+
RB_OBJ_WRITE(self, &p->function_proc, rb_block_proc());
|
|
375
375
|
|
|
376
376
|
duckdb_scalar_function_set_extra_info(p->scalar_function, p, NULL);
|
|
377
377
|
duckdb_scalar_function_set_function(p->scalar_function, scalar_function_callback);
|
|
@@ -398,7 +398,7 @@ static VALUE scalar_function__set_bind(VALUE self) {
|
|
|
398
398
|
|
|
399
399
|
TypedData_Get_Struct(self, rubyDuckDBScalarFunction, &scalar_function_data_type, p);
|
|
400
400
|
|
|
401
|
-
p->bind_proc
|
|
401
|
+
RB_OBJ_WRITE(self, &p->bind_proc, rb_block_proc());
|
|
402
402
|
|
|
403
403
|
duckdb_scalar_function_set_extra_info(p->scalar_function, p, NULL);
|
|
404
404
|
duckdb_scalar_function_set_bind(p->scalar_function, scalar_function_bind_callback);
|
|
@@ -13,7 +13,7 @@ static VALUE scalar_function_bind_info_client_context(VALUE self);
|
|
|
13
13
|
static const rb_data_type_t scalar_function_bind_info_data_type = {
|
|
14
14
|
"DuckDB/ScalarFunction/BindInfo",
|
|
15
15
|
{NULL, deallocate, memsize,},
|
|
16
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
|
16
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
static void deallocate(void *ctx) {
|
|
@@ -13,12 +13,12 @@ static VALUE scalar_function_set__add(VALUE self, VALUE scalar_function);
|
|
|
13
13
|
static const rb_data_type_t scalar_function_set_data_type = {
|
|
14
14
|
"DuckDB/ScalarFunctionSet",
|
|
15
15
|
{mark, deallocate, memsize, compact},
|
|
16
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
|
16
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
static void mark(void *ctx) {
|
|
20
20
|
rubyDuckDBScalarFunctionSet *p = (rubyDuckDBScalarFunctionSet *)ctx;
|
|
21
|
-
|
|
21
|
+
rb_gc_mark_movable(p->functions);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
static void deallocate(void *ctx) {
|
|
@@ -35,8 +35,7 @@ static void compact(void *ctx) {
|
|
|
35
35
|
static VALUE allocate(VALUE klass) {
|
|
36
36
|
rubyDuckDBScalarFunctionSet *ctx = xcalloc((size_t)1, sizeof(rubyDuckDBScalarFunctionSet));
|
|
37
37
|
VALUE obj = TypedData_Wrap_Struct(klass, &scalar_function_set_data_type, ctx);
|
|
38
|
-
ctx->functions
|
|
39
|
-
RB_GC_GUARD(ctx->functions);
|
|
38
|
+
RB_OBJ_WRITE(obj, &ctx->functions, rb_ary_new());
|
|
40
39
|
return obj;
|
|
41
40
|
}
|
|
42
41
|
|
|
@@ -19,7 +19,7 @@ static VALUE table_description__column_has_default(VALUE self, VALUE idx);
|
|
|
19
19
|
static const rb_data_type_t table_description_data_type = {
|
|
20
20
|
"DuckDB/TableDescription",
|
|
21
21
|
{NULL, deallocate, memsize,},
|
|
22
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
|
22
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
static void deallocate(void *ctx) {
|
data/ext/duckdb/table_function.c
CHANGED
|
@@ -30,14 +30,14 @@ static void table_function_local_init_callback(duckdb_init_info info);
|
|
|
30
30
|
static const rb_data_type_t table_function_data_type = {
|
|
31
31
|
"DuckDB/TableFunction",
|
|
32
32
|
{mark, deallocate, memsize, compact},
|
|
33
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
|
33
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
|
34
34
|
};
|
|
35
35
|
|
|
36
36
|
static void mark(void *ctx) {
|
|
37
37
|
rubyDuckDBTableFunction *p = (rubyDuckDBTableFunction *)ctx;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
rb_gc_mark_movable(p->bind_proc);
|
|
39
|
+
rb_gc_mark_movable(p->init_proc);
|
|
40
|
+
rb_gc_mark_movable(p->execute_proc);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
static void deallocate(void *ctx) {
|
|
@@ -210,7 +210,7 @@ static VALUE table_function_bind(VALUE self) {
|
|
|
210
210
|
rb_raise(eDuckDBError, "Table function is destroyed");
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
-
ctx->bind_proc
|
|
213
|
+
RB_OBJ_WRITE(self, &ctx->bind_proc, rb_block_proc());
|
|
214
214
|
|
|
215
215
|
duckdb_table_function_set_bind(ctx->table_function, table_function_bind_callback);
|
|
216
216
|
|
|
@@ -286,7 +286,7 @@ static VALUE table_function_init(VALUE self) {
|
|
|
286
286
|
rb_raise(eDuckDBError, "Table function is destroyed");
|
|
287
287
|
}
|
|
288
288
|
|
|
289
|
-
ctx->init_proc
|
|
289
|
+
RB_OBJ_WRITE(self, &ctx->init_proc, rb_block_proc());
|
|
290
290
|
duckdb_table_function_set_init(ctx->table_function, table_function_init_callback);
|
|
291
291
|
|
|
292
292
|
rbduckdb_function_executor_ensure_started();
|
|
@@ -359,7 +359,7 @@ static VALUE table_function_execute(VALUE self) {
|
|
|
359
359
|
|
|
360
360
|
TypedData_Get_Struct(self, rubyDuckDBTableFunction, &table_function_data_type, ctx);
|
|
361
361
|
|
|
362
|
-
ctx->execute_proc
|
|
362
|
+
RB_OBJ_WRITE(self, &ctx->execute_proc, rb_block_proc());
|
|
363
363
|
duckdb_table_function_set_function(ctx->table_function, table_function_execute_callback);
|
|
364
364
|
#ifdef HAVE_DUCKDB_H_GE_V1_5_0
|
|
365
365
|
/* Per-worker proxy threads for the execute path (DuckDB >= 1.5.0). */
|
|
@@ -16,7 +16,7 @@ static VALUE table_function_bind_info_set_error(VALUE self, VALUE error);
|
|
|
16
16
|
static const rb_data_type_t bind_info_data_type = {
|
|
17
17
|
"DuckDB/TableFunctionBindInfo",
|
|
18
18
|
{NULL, deallocate, memsize,},
|
|
19
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
|
19
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
static void deallocate(void *ctx) {
|
|
@@ -11,7 +11,7 @@ static VALUE table_function_function_info_set_error(VALUE self, VALUE error);
|
|
|
11
11
|
static const rb_data_type_t function_info_data_type = {
|
|
12
12
|
"DuckDB/TableFunctionFunctionInfo",
|
|
13
13
|
{NULL, deallocate, memsize,},
|
|
14
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
|
14
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
static void deallocate(void *ctx) {
|
|
@@ -14,7 +14,7 @@ static VALUE table_function_init_info_bind_data(VALUE self);
|
|
|
14
14
|
static const rb_data_type_t init_info_data_type = {
|
|
15
15
|
"DuckDB/TableFunctionInitInfo",
|
|
16
16
|
{NULL, deallocate, memsize,},
|
|
17
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
|
17
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
static void deallocate(void *ctx) {
|
data/ext/duckdb/value.c
CHANGED
|
@@ -53,7 +53,7 @@ static VALUE value_to_ruby(VALUE self);
|
|
|
53
53
|
static const rb_data_type_t value_data_type = {
|
|
54
54
|
"DuckDB/Value",
|
|
55
55
|
{NULL, deallocate, memsize,},
|
|
56
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
|
56
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
|
57
57
|
};
|
|
58
58
|
|
|
59
59
|
static void deallocate(void * ctx) {
|
|
@@ -332,7 +332,7 @@ static idx_t marshal_values(VALUE ary, duckdb_value **out, volatile VALUE *guard
|
|
|
332
332
|
idx_t i;
|
|
333
333
|
|
|
334
334
|
for (i = 0; i < n; i++) {
|
|
335
|
-
buf[i] = rbduckdb_get_struct_value(
|
|
335
|
+
buf[i] = rbduckdb_get_struct_value(rb_ary_entry(ary, (long)i))->value;
|
|
336
336
|
}
|
|
337
337
|
*out = buf;
|
|
338
338
|
return n;
|
data/ext/duckdb/vector.c
CHANGED
|
@@ -15,7 +15,7 @@ static VALUE vector_set_validity(VALUE self, VALUE index, VALUE valid);
|
|
|
15
15
|
static const rb_data_type_t vector_data_type = {
|
|
16
16
|
"DuckDB/Vector",
|
|
17
17
|
{NULL, deallocate, memsize,},
|
|
18
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
|
18
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
static void deallocate(void *ctx) {
|
data/lib/duckdb/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: duckdb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.5.
|
|
4
|
+
version: 1.5.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Masaki Suketa
|
|
@@ -176,7 +176,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
176
176
|
- !ruby/object:Gem::Version
|
|
177
177
|
version: '0'
|
|
178
178
|
requirements: []
|
|
179
|
-
rubygems_version: 4.0.
|
|
179
|
+
rubygems_version: 4.0.20
|
|
180
180
|
specification_version: 4
|
|
181
181
|
summary: Ruby bindings for the DuckDB database engine.
|
|
182
182
|
test_files: []
|