duckdb 0.10.3.0 → 1.0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/test_on_macos.yml +2 -2
- data/.github/workflows/test_on_ubuntu.yml +2 -2
- data/.github/workflows/test_on_windows.yml +2 -2
- data/CHANGELOG.md +40 -0
- data/Dockerfile +2 -2
- data/Gemfile.lock +4 -4
- data/ext/duckdb/appender.c +17 -0
- data/ext/duckdb/duckdb.c +1 -0
- data/ext/duckdb/extconf.rb +9 -2
- data/ext/duckdb/extracted_statements.c +94 -0
- data/ext/duckdb/extracted_statements.h +12 -0
- data/ext/duckdb/pending_result.c +16 -0
- data/ext/duckdb/prepared_statement.c +14 -0
- data/ext/duckdb/prepared_statement.h +1 -0
- data/ext/duckdb/result.c +292 -47
- data/ext/duckdb/ruby-duckdb.h +8 -0
- data/lib/duckdb/appender.rb +18 -0
- data/lib/duckdb/library_version.rb +2 -0
- data/lib/duckdb/pending_result.rb +2 -0
- data/lib/duckdb/prepared_statement.rb +2 -0
- data/lib/duckdb/result.rb +11 -3
- data/lib/duckdb/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4ec35034af422ec8f64f8474e95321a72a635925227fa8b5c26b3a430a4283a6
|
4
|
+
data.tar.gz: 52fb59085c80865dd6c51a5f7cb93b0e3eb2940245b4df580040753d364bd989
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 00d69fe6df1f7acdb1fac1e8bce26b17d9d7f06802fb8a8ddb287f25831858a69576c0d3558f6e5a48d0761226aae46a9f92d541b9e2547ae7f81f8b65a67441
|
7
|
+
data.tar.gz: dd8734f7a005a0007336faf58b6b032e6a2dbcf668859483cc9c713eef50ca585df9e564257b6890c9af3c394e82de8e0bd7a42790d3e1c033ffedeb41702e2c
|
@@ -15,8 +15,8 @@ jobs:
|
|
15
15
|
runs-on: macos-latest
|
16
16
|
strategy:
|
17
17
|
matrix:
|
18
|
-
ruby: ['3.0.7', '3.1.
|
19
|
-
duckdb: ['0.
|
18
|
+
ruby: ['3.0.7', '3.1.6', '3.2.4', '3.3.3', '3.4.0-preview1', 'head']
|
19
|
+
duckdb: ['1.0.0', '0.10.3']
|
20
20
|
|
21
21
|
steps:
|
22
22
|
- uses: actions/checkout@v4
|
@@ -15,8 +15,8 @@ jobs:
|
|
15
15
|
runs-on: ubuntu-latest
|
16
16
|
strategy:
|
17
17
|
matrix:
|
18
|
-
ruby: ['3.0.7', '3.1.
|
19
|
-
duckdb: ['0.
|
18
|
+
ruby: ['3.0.7', '3.1.6', '3.2.4', '3.3.3', '3.4.0-preview1', 'head']
|
19
|
+
duckdb: ['1.0.0', '0.10.3']
|
20
20
|
|
21
21
|
steps:
|
22
22
|
- uses: actions/checkout@v4
|
@@ -15,8 +15,8 @@ jobs:
|
|
15
15
|
runs-on: windows-latest
|
16
16
|
strategy:
|
17
17
|
matrix:
|
18
|
-
ruby: ['3.0.7', '3.1.5', '3.2.4', '3.3.
|
19
|
-
duckdb: ['0.
|
18
|
+
ruby: ['3.0.7', '3.1.5', '3.2.4', '3.3.2', 'ucrt', 'mingw', 'mswin', 'head']
|
19
|
+
duckdb: ['1.0.0', '0.10.3']
|
20
20
|
|
21
21
|
steps:
|
22
22
|
- uses: actions/checkout@v4
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,46 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
|
5
5
|
## Unreleased
|
6
6
|
|
7
|
+
# 1.0.0.1 - 2024-06-16
|
8
|
+
- support fetch the value from UHUGEINT type column.
|
9
|
+
- add `DuckDB::Appender#append_uhugeint`.
|
10
|
+
- DuckDB::Result supports ARRAY column type (only when DuckDB::Result.use_chunk_each is true).
|
11
|
+
- DuckDB::Result supports LIST column type (only when DuckDB::Result.use_chunk_each is true).
|
12
|
+
Thanks to stephenprater.
|
13
|
+
|
14
|
+
# 1.0.0.0 - 2024-06-08
|
15
|
+
- bump duckdb to 1.0.0.
|
16
|
+
- add `DuckDB::ExtractedStatements` class.
|
17
|
+
- add `DuckDB::ExtractedStatements#size`.
|
18
|
+
- add `DuckDB::ExtractedStatements#prepared_statement`.
|
19
|
+
- raise error when `DuckDB::ExtractedStatements#new` is called with invalid SQL.
|
20
|
+
- The following public/private methods will be deprecated.
|
21
|
+
- `DuckDB::Result#streaming?`
|
22
|
+
- `DuckDB::Result#_null?`
|
23
|
+
- `DuckDB::Result#_to_boolean`
|
24
|
+
- `DuckDB::Result#_to_smallint`
|
25
|
+
- `DuckDB::Result#_to_utinyint`
|
26
|
+
- `DuckDB::Result#_to_integer`
|
27
|
+
- `DuckDB::Result#_to_bigint`
|
28
|
+
- `DuckDB::Result#_to_hugeint`
|
29
|
+
- `DuckDB::Result#_to_hugeint_internal`
|
30
|
+
- `DuckDB::Result#__to_hugeint_internal`
|
31
|
+
- `DuckDB::Result#_to_decimal`
|
32
|
+
- `DuckDB::Result#_to_decimal_internal`
|
33
|
+
- `DuckDB::Result#__to_decimal_internal`
|
34
|
+
- `DuckDB::Result#_to_float`
|
35
|
+
- `DuckDB::Result#_to_double`
|
36
|
+
- `DuckDB::Result#_to_string`
|
37
|
+
- `DuckDB::Result#_to_string_internal`
|
38
|
+
- `DuckDB::Result#_to_blob`
|
39
|
+
- `DuckDB::Result.use_chunk_each=`
|
40
|
+
- `DuckDB::Result#use_chunk_each?`
|
41
|
+
|
42
|
+
## Breaking changes
|
43
|
+
- DuckDB::Result.use_chunk_each is true by default.
|
44
|
+
If you want to use the old behavior, set `DuckDB::Result.use_chunk_each = false`.
|
45
|
+
But the old behavior will be removed in the future release.
|
46
|
+
|
7
47
|
# 0.10.3.0 - 2024-05-25
|
8
48
|
- bump to duckdb v0.10.3.
|
9
49
|
|
data/Dockerfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
duckdb (0.
|
4
|
+
duckdb (1.0.0.1)
|
5
5
|
bigdecimal (>= 3.1.4)
|
6
6
|
|
7
7
|
GEM
|
@@ -9,12 +9,12 @@ GEM
|
|
9
9
|
specs:
|
10
10
|
benchmark-ips (2.13.0)
|
11
11
|
bigdecimal (3.1.8)
|
12
|
-
mini_portile2 (2.8.
|
12
|
+
mini_portile2 (2.8.7)
|
13
13
|
minitest (5.23.1)
|
14
|
-
nokogiri (1.16.
|
14
|
+
nokogiri (1.16.6)
|
15
15
|
mini_portile2 (~> 2.8.2)
|
16
16
|
racc (~> 1.4)
|
17
|
-
nokogiri (1.16.
|
17
|
+
nokogiri (1.16.6-x86_64-linux)
|
18
18
|
racc (~> 1.4)
|
19
19
|
racc (1.8.0)
|
20
20
|
rake (13.2.1)
|
data/ext/duckdb/appender.c
CHANGED
@@ -28,6 +28,7 @@ static VALUE appender__append_interval(VALUE self, VALUE months, VALUE days, VAL
|
|
28
28
|
static VALUE appender__append_time(VALUE self, VALUE hour, VALUE min, VALUE sec, VALUE micros);
|
29
29
|
static VALUE appender__append_timestamp(VALUE self, VALUE year, VALUE month, VALUE day, VALUE hour, VALUE min, VALUE sec, VALUE micros);
|
30
30
|
static VALUE appender__append_hugeint(VALUE self, VALUE lower, VALUE upper);
|
31
|
+
static VALUE appender__append_uhugeint(VALUE self, VALUE lower, VALUE upper);
|
31
32
|
static VALUE appender_flush(VALUE self);
|
32
33
|
static VALUE appender_close(VALUE self);
|
33
34
|
|
@@ -349,6 +350,21 @@ static VALUE appender__append_hugeint(VALUE self, VALUE lower, VALUE upper) {
|
|
349
350
|
return self;
|
350
351
|
}
|
351
352
|
|
353
|
+
static VALUE appender__append_uhugeint(VALUE self, VALUE lower, VALUE upper) {
|
354
|
+
duckdb_uhugeint uhugeint;
|
355
|
+
|
356
|
+
uhugeint.lower = NUM2ULL(lower);
|
357
|
+
uhugeint.upper = NUM2ULL(upper);
|
358
|
+
|
359
|
+
rubyDuckDBAppender *ctx;
|
360
|
+
|
361
|
+
TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
|
362
|
+
if (duckdb_append_uhugeint(ctx->appender, uhugeint) == DuckDBError) {
|
363
|
+
rb_raise(eDuckDBError, "failed to append uhugeint");
|
364
|
+
}
|
365
|
+
return self;
|
366
|
+
}
|
367
|
+
|
352
368
|
static VALUE appender_flush(VALUE self) {
|
353
369
|
rubyDuckDBAppender *ctx;
|
354
370
|
TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);
|
@@ -395,6 +411,7 @@ void rbduckdb_init_duckdb_appender(void) {
|
|
395
411
|
rb_define_private_method(cDuckDBAppender, "_append_time", appender__append_time, 4);
|
396
412
|
rb_define_private_method(cDuckDBAppender, "_append_timestamp", appender__append_timestamp, 7);
|
397
413
|
rb_define_private_method(cDuckDBAppender, "_append_hugeint", appender__append_hugeint, 2);
|
414
|
+
rb_define_private_method(cDuckDBAppender, "_append_uhugeint", appender__append_uhugeint, 2);
|
398
415
|
rb_define_method(cDuckDBAppender, "flush", appender_flush, 0);
|
399
416
|
rb_define_method(cDuckDBAppender, "close", appender_close, 0);
|
400
417
|
}
|
data/ext/duckdb/duckdb.c
CHANGED
data/ext/duckdb/extconf.rb
CHANGED
@@ -29,6 +29,10 @@ def check_duckdb_library(library, func, version)
|
|
29
29
|
have_func(func, 'duckdb.h')
|
30
30
|
return if found
|
31
31
|
|
32
|
+
raise_not_found_library(library, version)
|
33
|
+
end
|
34
|
+
|
35
|
+
def raise_not_found_library(library, version)
|
32
36
|
library_name = duckdb_library_name(library)
|
33
37
|
msg = "#{library_name} is not found. Install #{library_name} of duckdb >= #{version}."
|
34
38
|
print_message(msg)
|
@@ -36,7 +40,7 @@ def check_duckdb_library(library, func, version)
|
|
36
40
|
end
|
37
41
|
|
38
42
|
def duckdb_library_name(library)
|
39
|
-
"lib#{library}
|
43
|
+
"lib#{library}.#{RbConfig::CONFIG['DLEXT']}"
|
40
44
|
end
|
41
45
|
|
42
46
|
def print_message(msg)
|
@@ -60,7 +64,10 @@ have_func('duckdb_bind_parameter_index', 'duckdb.h')
|
|
60
64
|
# check duckdb >= 0.10.0
|
61
65
|
have_func('duckdb_appender_column_count', 'duckdb.h')
|
62
66
|
|
63
|
-
#
|
67
|
+
# check duckdb >= 1.0.0
|
68
|
+
have_func('duckdb_fetch_chunk', 'duckdb.h')
|
69
|
+
|
70
|
+
# duckdb_parameter_name in duckdb <= 0.9.1 is not found on Windows.
|
64
71
|
have_func('duckdb_parameter_name', 'duckdb.h')
|
65
72
|
|
66
73
|
create_makefile('duckdb/duckdb_native')
|
@@ -0,0 +1,94 @@
|
|
1
|
+
#include "ruby-duckdb.h"
|
2
|
+
|
3
|
+
static VALUE cDuckDBExtractedStatements;
|
4
|
+
|
5
|
+
static void deallocate(void *ctx);
|
6
|
+
static VALUE allocate(VALUE klass);
|
7
|
+
static size_t memsize(const void *p);
|
8
|
+
|
9
|
+
static const rb_data_type_t extract_statements_data_type = {
|
10
|
+
"DuckDB/ExtractedStatements",
|
11
|
+
{NULL, deallocate, memsize,},
|
12
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
13
|
+
};
|
14
|
+
|
15
|
+
static void deallocate(void *ctx);
|
16
|
+
static VALUE allocate(VALUE klass);
|
17
|
+
static size_t memsize(const void *p);
|
18
|
+
|
19
|
+
static VALUE duckdb_extracted_statements_initialize(VALUE self, VALUE con, VALUE query);
|
20
|
+
static VALUE duckdb_extracted_statements_size(VALUE self);
|
21
|
+
static VALUE duckdb_extracted_statements_prepared_statement(VALUE self, VALUE con, VALUE index);
|
22
|
+
|
23
|
+
static void deallocate(void *ctx) {
|
24
|
+
rubyDuckDBExtractedStatements *p = (rubyDuckDBExtractedStatements *)ctx;
|
25
|
+
|
26
|
+
duckdb_destroy_extracted(&(p->extracted_statements));
|
27
|
+
xfree(p);
|
28
|
+
}
|
29
|
+
|
30
|
+
static VALUE allocate(VALUE klass) {
|
31
|
+
rubyDuckDBExtractedStatements *ctx = xcalloc((size_t)1, sizeof(rubyDuckDBExtractedStatements));
|
32
|
+
ctx->num_statements = 0;
|
33
|
+
|
34
|
+
return TypedData_Wrap_Struct(klass, &extract_statements_data_type, ctx);
|
35
|
+
}
|
36
|
+
|
37
|
+
static size_t memsize(const void *p) {
|
38
|
+
return sizeof(rubyDuckDBExtractedStatements);
|
39
|
+
}
|
40
|
+
|
41
|
+
static VALUE duckdb_extracted_statements_initialize(VALUE self, VALUE con, VALUE query) {
|
42
|
+
rubyDuckDBConnection *pcon;
|
43
|
+
rubyDuckDBExtractedStatements *ctx;
|
44
|
+
char *pquery;
|
45
|
+
const char *error;
|
46
|
+
|
47
|
+
if (rb_obj_is_kind_of(con, cDuckDBConnection) != Qtrue) {
|
48
|
+
rb_raise(rb_eTypeError, "1st argument must be DuckDB::Connection");
|
49
|
+
}
|
50
|
+
|
51
|
+
pquery = StringValuePtr(query);
|
52
|
+
pcon = get_struct_connection(con);
|
53
|
+
TypedData_Get_Struct(self, rubyDuckDBExtractedStatements, &extract_statements_data_type, ctx);
|
54
|
+
|
55
|
+
ctx->num_statements = duckdb_extract_statements(pcon->con, pquery, &(ctx->extracted_statements));
|
56
|
+
|
57
|
+
if (ctx->num_statements == 0) {
|
58
|
+
error = duckdb_extract_statements_error(ctx->extracted_statements);
|
59
|
+
rb_raise(eDuckDBError, "%s", error);
|
60
|
+
}
|
61
|
+
|
62
|
+
return self;
|
63
|
+
}
|
64
|
+
|
65
|
+
static VALUE duckdb_extracted_statements_size(VALUE self) {
|
66
|
+
rubyDuckDBExtractedStatements *ctx;
|
67
|
+
|
68
|
+
TypedData_Get_Struct(self, rubyDuckDBExtractedStatements, &extract_statements_data_type, ctx);
|
69
|
+
|
70
|
+
return ULL2NUM(ctx->num_statements);
|
71
|
+
}
|
72
|
+
|
73
|
+
|
74
|
+
static VALUE duckdb_extracted_statements_prepared_statement(VALUE self, VALUE con, VALUE index) {
|
75
|
+
rubyDuckDBConnection *pcon;
|
76
|
+
rubyDuckDBExtractedStatements *ctx;
|
77
|
+
|
78
|
+
if (rb_obj_is_kind_of(con, cDuckDBConnection) != Qtrue) {
|
79
|
+
rb_raise(rb_eTypeError, "1st argument must be DuckDB::Connection");
|
80
|
+
}
|
81
|
+
pcon = get_struct_connection(con);
|
82
|
+
TypedData_Get_Struct(self, rubyDuckDBExtractedStatements, &extract_statements_data_type, ctx);
|
83
|
+
|
84
|
+
return rbduckdb_prepared_statement_new(pcon->con, ctx->extracted_statements, NUM2ULL(index));
|
85
|
+
}
|
86
|
+
|
87
|
+
void rbduckdb_init_duckdb_extracted_statements(void) {
|
88
|
+
cDuckDBExtractedStatements = rb_define_class_under(mDuckDB, "ExtractedStatements", rb_cObject);
|
89
|
+
|
90
|
+
rb_define_alloc_func(cDuckDBExtractedStatements, allocate);
|
91
|
+
rb_define_method(cDuckDBExtractedStatements, "initialize", duckdb_extracted_statements_initialize, 2);
|
92
|
+
rb_define_method(cDuckDBExtractedStatements, "size", duckdb_extracted_statements_size, 0);
|
93
|
+
rb_define_method(cDuckDBExtractedStatements, "prepared_statement", duckdb_extracted_statements_prepared_statement, 2);
|
94
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#ifndef RUBY_DUCKDB_EXTRACTED_STATEMENTS_H
|
2
|
+
#define RUBY_DUCKDB_EXTRACTED_STATEMENTS_H
|
3
|
+
|
4
|
+
struct _rubyDuckDBExtractedStatements {
|
5
|
+
duckdb_extracted_statements extracted_statements;
|
6
|
+
idx_t num_statements;
|
7
|
+
};
|
8
|
+
|
9
|
+
typedef struct _rubyDuckDBExtractedStatements rubyDuckDBExtractedStatements;
|
10
|
+
|
11
|
+
void rbduckdb_init_duckdb_extracted_statements(void);
|
12
|
+
#endif
|
data/ext/duckdb/pending_result.c
CHANGED
@@ -39,6 +39,13 @@ static VALUE duckdb_pending_result_initialize(int argc, VALUE *argv, VALUE self)
|
|
39
39
|
VALUE streaming_p = Qfalse;
|
40
40
|
duckdb_state state;
|
41
41
|
|
42
|
+
/*
|
43
|
+
* FIXME: The 2nd argument is deprecated and will be removed in the future.
|
44
|
+
* The behavior will be same as streaming.
|
45
|
+
if (argc == 2) {
|
46
|
+
rb_warn("The 2nd argument is deprecated and will be removed in the future.");
|
47
|
+
}
|
48
|
+
*/
|
42
49
|
rb_scan_args(argc, argv, "11", &oDuckDBPreparedStatement, &streaming_p);
|
43
50
|
|
44
51
|
if (rb_obj_is_kind_of(oDuckDBPreparedStatement, cDuckDBPreparedStatement) != Qtrue) {
|
@@ -48,11 +55,20 @@ static VALUE duckdb_pending_result_initialize(int argc, VALUE *argv, VALUE self)
|
|
48
55
|
rubyDuckDBPendingResult *ctx = get_struct_pending_result(self);
|
49
56
|
rubyDuckDBPreparedStatement *stmt = get_struct_prepared_statement(oDuckDBPreparedStatement);
|
50
57
|
|
58
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
59
|
+
state = duckdb_pending_prepared(stmt->prepared_statement, &(ctx->pending_result));
|
60
|
+
#else
|
61
|
+
/*
|
62
|
+
* FIXME: streaming_p check will be removed in the future.
|
63
|
+
*
|
64
|
+
* state = duckdb_pending_prepared(stmt->prepared_statement, &(ctx->pending_result));
|
65
|
+
*/
|
51
66
|
if (!NIL_P(streaming_p) && streaming_p == Qtrue) {
|
52
67
|
state = duckdb_pending_prepared_streaming(stmt->prepared_statement, &(ctx->pending_result));
|
53
68
|
} else {
|
54
69
|
state = duckdb_pending_prepared(stmt->prepared_statement, &(ctx->pending_result));
|
55
70
|
}
|
71
|
+
#endif
|
56
72
|
|
57
73
|
if (state == DuckDBError) {
|
58
74
|
rb_raise(eDuckDBError, "%s", duckdb_pending_error(ctx->pending_result));
|
@@ -53,6 +53,20 @@ static size_t memsize(const void *p) {
|
|
53
53
|
return sizeof(rubyDuckDBPreparedStatement);
|
54
54
|
}
|
55
55
|
|
56
|
+
VALUE rbduckdb_prepared_statement_new(duckdb_connection con, duckdb_extracted_statements extracted_statements, idx_t index) {
|
57
|
+
VALUE obj;
|
58
|
+
rubyDuckDBPreparedStatement *ctx;
|
59
|
+
|
60
|
+
obj = allocate(cDuckDBPreparedStatement);
|
61
|
+
|
62
|
+
TypedData_Get_Struct(obj, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
|
63
|
+
|
64
|
+
if (duckdb_prepare_extracted_statement(con, extracted_statements, index, &(ctx->prepared_statement)) == DuckDBError) {
|
65
|
+
rb_raise(eDuckDBError, "Fail to get DuckDB::PreparedStatement object from ExtractedStatements object");
|
66
|
+
}
|
67
|
+
return obj;
|
68
|
+
}
|
69
|
+
|
56
70
|
static VALUE duckdb_prepared_statement_initialize(VALUE self, VALUE con, VALUE query) {
|
57
71
|
rubyDuckDBConnection *ctxcon;
|
58
72
|
rubyDuckDBPreparedStatement *ctx;
|
@@ -8,6 +8,7 @@ struct _rubyDuckDBPreparedStatement {
|
|
8
8
|
|
9
9
|
typedef struct _rubyDuckDBPreparedStatement rubyDuckDBPreparedStatement;
|
10
10
|
|
11
|
+
VALUE rbduckdb_prepared_statement_new(duckdb_connection con, duckdb_extracted_statements extracted_statements, idx_t index);
|
11
12
|
rubyDuckDBPreparedStatement *get_struct_prepared_statement(VALUE self);
|
12
13
|
void rbduckdb_init_duckdb_prepared_statement(void);
|
13
14
|
|
data/ext/duckdb/result.c
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
#include "ruby-duckdb.h"
|
2
2
|
|
3
|
+
struct chunk_arg {
|
4
|
+
duckdb_data_chunk chunk;
|
5
|
+
idx_t col_count;
|
6
|
+
};
|
7
|
+
|
3
8
|
static VALUE cDuckDBResult;
|
4
9
|
static ID id__to_date;
|
5
10
|
static ID id__to_time;
|
@@ -27,10 +32,11 @@ static VALUE duckdb_result_row_count(VALUE oDuckDBResult);
|
|
27
32
|
static VALUE duckdb_result_rows_changed(VALUE oDuckDBResult);
|
28
33
|
static VALUE duckdb_result_columns(VALUE oDuckDBResult);
|
29
34
|
static VALUE duckdb_result_streaming_p(VALUE oDuckDBResult);
|
35
|
+
static VALUE destroy_data_chunk(VALUE arg);
|
30
36
|
static VALUE duckdb_result_chunk_each(VALUE oDuckDBResult);
|
31
37
|
|
32
38
|
static VALUE duckdb_result__chunk_stream(VALUE oDuckDBResult);
|
33
|
-
static
|
39
|
+
static VALUE yield_rows(VALUE arg);
|
34
40
|
static VALUE duckdb_result__column_type(VALUE oDuckDBResult, VALUE col_idx);
|
35
41
|
static VALUE duckdb_result__is_null(VALUE oDuckDBResult, VALUE row_idx, VALUE col_idx);
|
36
42
|
static VALUE duckdb_result__to_boolean(VALUE oDuckDBResult, VALUE row_idx, VALUE col_idx);
|
@@ -56,9 +62,12 @@ static VALUE vector_interval(void* vector_data, idx_t row_idx);
|
|
56
62
|
static VALUE vector_blob(void* vector_data, idx_t row_idx);
|
57
63
|
static VALUE vector_varchar(void* vector_data, idx_t row_idx);
|
58
64
|
static VALUE vector_hugeint(void* vector_data, idx_t row_idx);
|
65
|
+
static VALUE vector_uhugeint(void* vector_data, idx_t row_idx);
|
59
66
|
static VALUE vector_decimal(duckdb_logical_type ty, void* vector_data, idx_t row_idx);
|
60
67
|
static VALUE vector_enum(duckdb_logical_type ty, void* vector_data, idx_t row_idx);
|
61
|
-
static VALUE
|
68
|
+
static VALUE vector_array(duckdb_logical_type ty, duckdb_vector vector, idx_t row_idx);
|
69
|
+
static VALUE vector_array_value_at(duckdb_vector array, duckdb_logical_type element_type, idx_t index);
|
70
|
+
static VALUE vector_list(duckdb_logical_type ty, duckdb_vector vector, void* vector_data, idx_t row_idx);
|
62
71
|
static VALUE vector_map(duckdb_logical_type ty, duckdb_vector vector, idx_t row_idx);
|
63
72
|
static VALUE vector_struct(duckdb_logical_type ty, duckdb_vector vector, idx_t row_idx);
|
64
73
|
static VALUE vector_uuid(void* vector_data, idx_t row_idx);
|
@@ -93,52 +102,102 @@ rubyDuckDBResult *get_struct_result(VALUE obj) {
|
|
93
102
|
}
|
94
103
|
|
95
104
|
static VALUE to_ruby_obj_boolean(duckdb_result *result, idx_t col_idx, idx_t row_idx) {
|
105
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
106
|
+
return Qnil;
|
107
|
+
#else
|
108
|
+
rb_warn("private method `_to_boolean` will be deprecated in the future. Set DuckDB::Result#use_chunk_each to true.");
|
96
109
|
bool bval = duckdb_value_boolean(result, col_idx, row_idx);
|
97
110
|
return bval ? Qtrue : Qfalse;
|
111
|
+
#endif
|
98
112
|
}
|
99
113
|
|
100
114
|
static VALUE to_ruby_obj_smallint(duckdb_result *result, idx_t col_idx, idx_t row_idx) {
|
115
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
116
|
+
return Qnil;
|
117
|
+
#else
|
118
|
+
rb_warn("private method `_to_smallint` will be deprecated in the future. Set DuckDB::Result#use_chunk_each to true.");
|
101
119
|
int16_t i16val = duckdb_value_int16(result, col_idx, row_idx);
|
102
120
|
return INT2FIX(i16val);
|
121
|
+
#endif
|
103
122
|
}
|
104
123
|
|
105
124
|
static VALUE to_ruby_obj_utinyint(duckdb_result *result, idx_t col_idx, idx_t row_idx) {
|
125
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
126
|
+
return Qnil;
|
127
|
+
#else
|
128
|
+
rb_warn("private method `_to_utinyint` will be deprecated in the future. Set DuckDB::Result#use_chunk_each to true.");
|
106
129
|
uint8_t ui8val = duckdb_value_uint8(result, col_idx, row_idx);
|
107
130
|
return UINT2NUM(ui8val);
|
131
|
+
#endif
|
108
132
|
}
|
109
133
|
|
110
134
|
static VALUE to_ruby_obj_integer(duckdb_result *result, idx_t col_idx, idx_t row_idx) {
|
135
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
136
|
+
return Qnil;
|
137
|
+
#else
|
138
|
+
rb_warn("private method `_to_integer` will be deprecated in the future. Set DuckDB::Result#use_chunk_each to true.");
|
111
139
|
int32_t i32val = duckdb_value_int32(result, col_idx, row_idx);
|
112
140
|
return INT2NUM(i32val);
|
141
|
+
#endif
|
113
142
|
}
|
114
143
|
|
115
144
|
static VALUE to_ruby_obj_bigint(duckdb_result *result, idx_t col_idx, idx_t row_idx) {
|
145
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
146
|
+
return Qnil;
|
147
|
+
#else
|
148
|
+
rb_warn("private method `_to_bigint` will be deprecated in the future. Set DuckDB::Result#use_chunk_each to true.");
|
116
149
|
int64_t i64val = duckdb_value_int64(result, col_idx, row_idx);
|
117
150
|
return LL2NUM(i64val);
|
151
|
+
#endif
|
118
152
|
}
|
119
153
|
|
120
154
|
static VALUE to_ruby_obj_hugeint(duckdb_result *result, idx_t col_idx, idx_t row_idx) {
|
155
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
156
|
+
return Qnil;
|
157
|
+
#else
|
158
|
+
rb_warn("private method `__to_hugeint_internal` will be deprecated in the future. Set DuckDB::Result#use_chunk_each to true.");
|
121
159
|
duckdb_hugeint hugeint = duckdb_value_hugeint(result, col_idx, row_idx);
|
122
160
|
return rb_ary_new3(2, ULL2NUM(hugeint.lower), LL2NUM(hugeint.upper));
|
161
|
+
#endif
|
123
162
|
}
|
124
163
|
|
125
164
|
static VALUE to_ruby_obj_decimal(duckdb_result *result, idx_t col_idx, idx_t row_idx) {
|
165
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
166
|
+
return Qnil;
|
167
|
+
#else
|
168
|
+
rb_warn("private method `__to_decimal_internal` will be deprecated in the future. Set DuckDB::Result#use_chunk_each to true.");
|
126
169
|
duckdb_decimal decimal = duckdb_value_decimal(result, col_idx, row_idx);
|
127
170
|
return rb_ary_new3(4, ULL2NUM(decimal.value.lower), LL2NUM(decimal.value.upper), UINT2NUM(decimal.width), UINT2NUM(decimal.scale));
|
171
|
+
#endif
|
128
172
|
}
|
129
173
|
|
130
174
|
static VALUE to_ruby_obj_float(duckdb_result *result, idx_t col_idx, idx_t row_idx) {
|
175
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
176
|
+
return Qnil;
|
177
|
+
#else
|
178
|
+
rb_warn("private method `_to_float` will be deprecated in the future. Set DuckDB::Result#use_chunk_each to true.");
|
131
179
|
float fval = duckdb_value_float(result, col_idx, row_idx);
|
132
180
|
return DBL2NUM(fval);
|
181
|
+
#endif
|
133
182
|
}
|
134
183
|
|
135
184
|
static VALUE to_ruby_obj_double(duckdb_result *result, idx_t col_idx, idx_t row_idx) {
|
185
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
186
|
+
return Qnil;
|
187
|
+
#else
|
188
|
+
rb_warn("private method `_to_double` will be deprecated in the future. Set DuckDB::Result#use_chunk_each to true.");
|
136
189
|
double dval = duckdb_value_double(result, col_idx, row_idx);
|
137
190
|
return DBL2NUM(dval);
|
191
|
+
#endif
|
138
192
|
}
|
139
193
|
|
140
194
|
static VALUE to_ruby_obj_blob(duckdb_result *result, idx_t col_idx, idx_t row_idx) {
|
195
|
+
|
196
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
197
|
+
return Qnil;
|
198
|
+
#else
|
141
199
|
VALUE str;
|
200
|
+
rb_warn("private method `_to_blob` will be deprecated in the future. Set DuckDB::Result#use_chunk_each to true.");
|
142
201
|
duckdb_blob bval = duckdb_value_blob(result, col_idx, row_idx);
|
143
202
|
str = rb_str_new(bval.data, bval.size);
|
144
203
|
|
@@ -147,6 +206,7 @@ static VALUE to_ruby_obj_blob(duckdb_result *result, idx_t col_idx, idx_t row_id
|
|
147
206
|
}
|
148
207
|
|
149
208
|
return str;
|
209
|
+
#endif
|
150
210
|
}
|
151
211
|
|
152
212
|
/*
|
@@ -220,9 +280,15 @@ static VALUE duckdb_result_column_count(VALUE oDuckDBResult) {
|
|
220
280
|
*
|
221
281
|
*/
|
222
282
|
static VALUE duckdb_result_row_count(VALUE oDuckDBResult) {
|
283
|
+
|
284
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
285
|
+
return Qnil;
|
286
|
+
#else
|
223
287
|
rubyDuckDBResult *ctx;
|
288
|
+
rb_warn("`row_count` will be deprecated in the future.");
|
224
289
|
TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
|
225
290
|
return LL2NUM(duckdb_row_count(&(ctx->result)));
|
291
|
+
#endif
|
226
292
|
}
|
227
293
|
|
228
294
|
/*
|
@@ -256,51 +322,77 @@ static VALUE duckdb_result_columns(VALUE oDuckDBResult) {
|
|
256
322
|
*/
|
257
323
|
static VALUE duckdb_result_streaming_p(VALUE oDuckDBResult) {
|
258
324
|
rubyDuckDBResult *ctx;
|
325
|
+
|
326
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
327
|
+
return Qtrue;
|
328
|
+
#else
|
329
|
+
/* FIXME streaming is allways true. so this method is not useful and deprecated. */
|
259
330
|
TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
|
260
331
|
return duckdb_result_is_streaming(ctx->result) ? Qtrue : Qfalse;
|
332
|
+
#endif
|
333
|
+
}
|
334
|
+
|
335
|
+
static VALUE destroy_data_chunk(VALUE arg) {
|
336
|
+
struct chunk_arg *p = (struct chunk_arg *)arg;
|
337
|
+
duckdb_destroy_data_chunk(&(p->chunk));
|
338
|
+
return Qnil;
|
261
339
|
}
|
262
340
|
|
263
341
|
static VALUE duckdb_result_chunk_each(VALUE oDuckDBResult) {
|
342
|
+
/*
|
343
|
+
#ifdef HAVE_DUCKDB_H_GE_V1_0_0
|
344
|
+
return duckdb_result__chunk_stream(oDuckDBResult);
|
345
|
+
#else
|
346
|
+
*/
|
264
347
|
rubyDuckDBResult *ctx;
|
265
|
-
|
348
|
+
struct chunk_arg arg;
|
266
349
|
idx_t chunk_count;
|
267
350
|
idx_t chunk_idx;
|
268
|
-
duckdb_data_chunk chunk;
|
269
351
|
|
352
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
353
|
+
//TODO: use duckdb_fetch_chunk instead of duckdb_result_chunk_count and duckdb_result_get_chunk.
|
354
|
+
// duckdb_result_chunk_count will be deprecated in the future.
|
355
|
+
// duckdb_result_get_chunk will be deprecated in the future.
|
356
|
+
#else
|
270
357
|
TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
|
271
358
|
|
272
|
-
col_count = duckdb_column_count(&(ctx->result));
|
359
|
+
arg.col_count = duckdb_column_count(&(ctx->result));
|
273
360
|
chunk_count = duckdb_result_chunk_count(ctx->result);
|
274
361
|
|
275
362
|
RETURN_ENUMERATOR(oDuckDBResult, 0, 0);
|
276
363
|
|
277
364
|
for (chunk_idx = 0; chunk_idx < chunk_count; chunk_idx++) {
|
278
|
-
chunk = duckdb_result_get_chunk(ctx->result, chunk_idx);
|
279
|
-
yield_rows(
|
280
|
-
duckdb_destroy_data_chunk(&chunk);
|
365
|
+
arg.chunk = duckdb_result_get_chunk(ctx->result, chunk_idx);
|
366
|
+
rb_ensure(yield_rows, (VALUE)&arg, destroy_data_chunk, (VALUE)&arg);
|
281
367
|
}
|
368
|
+
#endif
|
282
369
|
return Qnil;
|
370
|
+
/*
|
371
|
+
#endif
|
372
|
+
*/
|
283
373
|
}
|
284
374
|
|
285
375
|
static VALUE duckdb_result__chunk_stream(VALUE oDuckDBResult) {
|
286
376
|
rubyDuckDBResult *ctx;
|
287
|
-
|
288
|
-
idx_t col_count;
|
377
|
+
struct chunk_arg arg;
|
289
378
|
|
290
379
|
TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
|
291
380
|
|
292
381
|
RETURN_ENUMERATOR(oDuckDBResult, 0, 0);
|
293
382
|
|
294
|
-
col_count = duckdb_column_count(&(ctx->result));
|
383
|
+
arg.col_count = duckdb_column_count(&(ctx->result));
|
295
384
|
|
296
|
-
|
297
|
-
|
298
|
-
|
385
|
+
#ifdef HAVE_DUCKDB_H_GE_V1_0_0
|
386
|
+
while((arg.chunk = duckdb_fetch_chunk(ctx->result)) != NULL) {
|
387
|
+
#else
|
388
|
+
while((arg.chunk = duckdb_stream_fetch_chunk(ctx->result)) != NULL) {
|
389
|
+
#endif
|
390
|
+
rb_ensure(yield_rows, (VALUE)&arg, destroy_data_chunk, (VALUE)&arg);
|
299
391
|
}
|
300
392
|
return Qnil;
|
301
393
|
}
|
302
394
|
|
303
|
-
static
|
395
|
+
static VALUE yield_rows(VALUE arg) {
|
304
396
|
idx_t row_count;
|
305
397
|
idx_t row_idx;
|
306
398
|
idx_t col_idx;
|
@@ -308,16 +400,19 @@ static void yield_rows(duckdb_data_chunk chunk, idx_t col_count) {
|
|
308
400
|
VALUE row;
|
309
401
|
VALUE val;
|
310
402
|
|
311
|
-
|
403
|
+
struct chunk_arg *p = (struct chunk_arg *)arg;
|
404
|
+
|
405
|
+
row_count = duckdb_data_chunk_get_size(p->chunk);
|
312
406
|
for (row_idx = 0; row_idx < row_count; row_idx++) {
|
313
|
-
row = rb_ary_new2(col_count);
|
314
|
-
for (col_idx = 0; col_idx < col_count; col_idx++) {
|
315
|
-
vector = duckdb_data_chunk_get_vector(chunk, col_idx);
|
407
|
+
row = rb_ary_new2(p->col_count);
|
408
|
+
for (col_idx = 0; col_idx < p->col_count; col_idx++) {
|
409
|
+
vector = duckdb_data_chunk_get_vector(p->chunk, col_idx);
|
316
410
|
val = vector_value(vector, row_idx);
|
317
411
|
rb_ary_store(row, col_idx, val);
|
318
412
|
}
|
319
413
|
rb_yield(row);
|
320
414
|
}
|
415
|
+
return Qnil;
|
321
416
|
}
|
322
417
|
|
323
418
|
static VALUE duckdb_result__column_type(VALUE oDuckDBResult, VALUE col_idx) {
|
@@ -329,10 +424,15 @@ static VALUE duckdb_result__column_type(VALUE oDuckDBResult, VALUE col_idx) {
|
|
329
424
|
static VALUE duckdb_result__is_null(VALUE oDuckDBResult, VALUE row_idx, VALUE col_idx) {
|
330
425
|
rubyDuckDBResult *ctx;
|
331
426
|
bool is_null;
|
427
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
428
|
+
return Qfalse;
|
429
|
+
#else
|
430
|
+
rb_warn("private method `_null?` will be deprecated in the future. Set DuckDB::Result#use_chunk_each to true.");
|
332
431
|
TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
|
333
432
|
|
334
433
|
is_null = duckdb_value_is_null(&(ctx->result), NUM2LL(col_idx), NUM2LL(row_idx));
|
335
434
|
return is_null ? Qtrue : Qfalse;
|
435
|
+
#endif
|
336
436
|
}
|
337
437
|
|
338
438
|
static VALUE duckdb_result__to_boolean(VALUE oDuckDBResult, VALUE row_idx, VALUE col_idx) {
|
@@ -403,6 +503,10 @@ static VALUE duckdb_result__to_string(VALUE oDuckDBResult, VALUE row_idx, VALUE
|
|
403
503
|
duckdb_string p;
|
404
504
|
VALUE obj;
|
405
505
|
|
506
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
507
|
+
return Qnil;
|
508
|
+
#else
|
509
|
+
rb_warn("private method `_to_string` will be deprecated in the future. Set DuckDB::Result#use_chunk_each to true.");
|
406
510
|
TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
|
407
511
|
|
408
512
|
p = duckdb_value_string(&(ctx->result), NUM2LL(col_idx), NUM2LL(row_idx));
|
@@ -411,6 +515,7 @@ static VALUE duckdb_result__to_string(VALUE oDuckDBResult, VALUE row_idx, VALUE
|
|
411
515
|
duckdb_free(p.data);
|
412
516
|
return obj;
|
413
517
|
}
|
518
|
+
#endif
|
414
519
|
return Qnil;
|
415
520
|
}
|
416
521
|
|
@@ -418,6 +523,10 @@ static VALUE duckdb_result__to_string_internal(VALUE oDuckDBResult, VALUE row_id
|
|
418
523
|
rubyDuckDBResult *ctx;
|
419
524
|
duckdb_string p;
|
420
525
|
VALUE obj;
|
526
|
+
#ifdef DUCKDB_API_NO_DEPRECATED
|
527
|
+
// duckdb_value_string_internal will be deprecated in the future.
|
528
|
+
#else
|
529
|
+
rb_warn("private method `_to_string_internal` will be deprecated in the future. Set DuckDB::Result#use_chunk_each to true.");
|
421
530
|
TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
|
422
531
|
|
423
532
|
p = duckdb_value_string_internal(&(ctx->result), NUM2LL(col_idx), NUM2LL(row_idx));
|
@@ -425,6 +534,7 @@ static VALUE duckdb_result__to_string_internal(VALUE oDuckDBResult, VALUE row_id
|
|
425
534
|
obj = rb_utf8_str_new(p.data, p.size);
|
426
535
|
return obj;
|
427
536
|
}
|
537
|
+
#endif
|
428
538
|
return Qnil;
|
429
539
|
}
|
430
540
|
|
@@ -555,6 +665,14 @@ static VALUE vector_hugeint(void* vector_data, idx_t row_idx) {
|
|
555
665
|
);
|
556
666
|
}
|
557
667
|
|
668
|
+
static VALUE vector_uhugeint(void* vector_data, idx_t row_idx) {
|
669
|
+
duckdb_uhugeint uhugeint = ((duckdb_uhugeint *)vector_data)[row_idx];
|
670
|
+
return rb_funcall(mDuckDBConverter, id__to_hugeint_from_vector, 2,
|
671
|
+
ULL2NUM(uhugeint.lower),
|
672
|
+
ULL2NUM(uhugeint.upper)
|
673
|
+
);
|
674
|
+
}
|
675
|
+
|
558
676
|
static VALUE vector_decimal(duckdb_logical_type ty, void* vector_data, idx_t row_idx) {
|
559
677
|
VALUE width = INT2FIX(duckdb_decimal_width(ty));
|
560
678
|
VALUE scale = INT2FIX(duckdb_decimal_scale(ty));
|
@@ -614,27 +732,147 @@ static VALUE vector_enum(duckdb_logical_type ty, void* vector_data, idx_t row_id
|
|
614
732
|
return value;
|
615
733
|
}
|
616
734
|
|
617
|
-
static VALUE
|
618
|
-
|
735
|
+
static VALUE vector_array(duckdb_logical_type ty, duckdb_vector vector, idx_t row_idx) {
|
736
|
+
VALUE ary = Qnil;
|
737
|
+
VALUE value = Qnil;
|
738
|
+
|
739
|
+
duckdb_logical_type child_logical_type = duckdb_array_type_child_type(ty);
|
740
|
+
idx_t size = duckdb_array_type_array_size(ty);
|
741
|
+
idx_t bgn = row_idx * size;
|
742
|
+
idx_t end = bgn + size;
|
743
|
+
duckdb_vector child = duckdb_array_vector_get_child(vector);
|
744
|
+
|
745
|
+
ary = rb_ary_new2(size);
|
746
|
+
for (idx_t i = bgn; i < end; ++i) {
|
747
|
+
value = vector_array_value_at(child, child_logical_type, i);
|
748
|
+
rb_ary_store(ary, i - bgn, value);
|
749
|
+
}
|
750
|
+
|
751
|
+
duckdb_destroy_logical_type(&child_logical_type);
|
752
|
+
return ary;
|
753
|
+
}
|
754
|
+
|
755
|
+
static VALUE vector_array_value_at(duckdb_vector array, duckdb_logical_type element_type, idx_t index) {
|
756
|
+
uint64_t *validity;
|
757
|
+
duckdb_type type_id;
|
758
|
+
void* vector_data;
|
759
|
+
VALUE obj = Qnil;
|
760
|
+
|
761
|
+
validity = duckdb_vector_get_validity(array);
|
762
|
+
if (!duckdb_validity_row_is_valid(validity, index)) {
|
763
|
+
return Qnil;
|
764
|
+
}
|
765
|
+
|
766
|
+
type_id = duckdb_get_type_id(element_type);
|
767
|
+
vector_data = duckdb_vector_get_data(array);
|
768
|
+
|
769
|
+
switch(type_id) {
|
770
|
+
case DUCKDB_TYPE_INVALID:
|
771
|
+
obj = Qnil;
|
772
|
+
break;
|
773
|
+
case DUCKDB_TYPE_BOOLEAN:
|
774
|
+
obj = (((bool*) vector_data)[index]) ? Qtrue : Qfalse;
|
775
|
+
break;
|
776
|
+
case DUCKDB_TYPE_TINYINT:
|
777
|
+
obj = INT2FIX(((int8_t *) vector_data)[index]);
|
778
|
+
break;
|
779
|
+
case DUCKDB_TYPE_SMALLINT:
|
780
|
+
obj = INT2FIX(((int16_t *) vector_data)[index]);
|
781
|
+
break;
|
782
|
+
case DUCKDB_TYPE_INTEGER:
|
783
|
+
obj = INT2NUM(((int32_t *) vector_data)[index]);
|
784
|
+
break;
|
785
|
+
case DUCKDB_TYPE_BIGINT:
|
786
|
+
obj = LL2NUM(((int64_t *) vector_data)[index]);
|
787
|
+
break;
|
788
|
+
case DUCKDB_TYPE_UTINYINT:
|
789
|
+
obj = INT2FIX(((uint8_t *) vector_data)[index]);
|
790
|
+
break;
|
791
|
+
case DUCKDB_TYPE_USMALLINT:
|
792
|
+
obj = INT2FIX(((uint16_t *) vector_data)[index]);
|
793
|
+
break;
|
794
|
+
case DUCKDB_TYPE_UINTEGER:
|
795
|
+
obj = UINT2NUM(((uint32_t *) vector_data)[index]);
|
796
|
+
break;
|
797
|
+
case DUCKDB_TYPE_UBIGINT:
|
798
|
+
obj = ULL2NUM(((uint64_t *) vector_data)[index]);
|
799
|
+
break;
|
800
|
+
case DUCKDB_TYPE_HUGEINT:
|
801
|
+
obj = vector_hugeint(vector_data, index);
|
802
|
+
break;
|
803
|
+
case DUCKDB_TYPE_UHUGEINT:
|
804
|
+
obj = vector_uhugeint(vector_data, index);
|
805
|
+
break;
|
806
|
+
case DUCKDB_TYPE_FLOAT:
|
807
|
+
obj = DBL2NUM((((float *) vector_data)[index]));
|
808
|
+
break;
|
809
|
+
case DUCKDB_TYPE_DOUBLE:
|
810
|
+
obj = DBL2NUM((((double *) vector_data)[index]));
|
811
|
+
break;
|
812
|
+
case DUCKDB_TYPE_DATE:
|
813
|
+
obj = vector_date(vector_data, index);
|
814
|
+
break;
|
815
|
+
case DUCKDB_TYPE_TIMESTAMP:
|
816
|
+
obj = vector_timestamp(vector_data, index);
|
817
|
+
break;
|
818
|
+
case DUCKDB_TYPE_TIME:
|
819
|
+
obj = vector_time(vector_data, index);
|
820
|
+
break;
|
821
|
+
case DUCKDB_TYPE_INTERVAL:
|
822
|
+
obj = vector_interval(vector_data, index);
|
823
|
+
break;
|
824
|
+
case DUCKDB_TYPE_VARCHAR:
|
825
|
+
obj = vector_varchar(vector_data, index);
|
826
|
+
break;
|
827
|
+
case DUCKDB_TYPE_BLOB:
|
828
|
+
obj = vector_blob(vector_data, index);
|
829
|
+
break;
|
830
|
+
case DUCKDB_TYPE_DECIMAL:
|
831
|
+
obj = vector_decimal(element_type, vector_data, index);
|
832
|
+
break;
|
833
|
+
case DUCKDB_TYPE_ENUM:
|
834
|
+
obj = vector_enum(element_type, vector_data, index);
|
835
|
+
break;
|
836
|
+
case DUCKDB_TYPE_ARRAY:
|
837
|
+
obj = vector_array(element_type, array, index);
|
838
|
+
break;
|
839
|
+
case DUCKDB_TYPE_LIST:
|
840
|
+
obj = vector_list(element_type, array, vector_data, index);
|
841
|
+
break;
|
842
|
+
case DUCKDB_TYPE_MAP:
|
843
|
+
obj = vector_map(element_type, vector_data, index);
|
844
|
+
break;
|
845
|
+
case DUCKDB_TYPE_STRUCT:
|
846
|
+
obj = vector_struct(element_type, vector_data, index);
|
847
|
+
break;
|
848
|
+
case DUCKDB_TYPE_UUID:
|
849
|
+
obj = vector_uuid(vector_data, index);
|
850
|
+
break;
|
851
|
+
default:
|
852
|
+
rb_warn("Unknown type %d", type_id);
|
853
|
+
obj = Qnil;
|
854
|
+
}
|
855
|
+
|
856
|
+
return obj;
|
857
|
+
}
|
619
858
|
|
859
|
+
static VALUE vector_list(duckdb_logical_type ty, duckdb_vector vector, void * vector_data, idx_t row_idx) {
|
620
860
|
VALUE ary = Qnil;
|
621
|
-
VALUE
|
861
|
+
VALUE value = Qnil;
|
622
862
|
idx_t i;
|
623
863
|
|
624
|
-
// rb_warn("ruby-duckdb does not support List yet");
|
625
|
-
|
626
864
|
duckdb_logical_type child_logical_type = duckdb_list_type_child_type(ty);
|
627
|
-
// duckdb_type child_type = duckdb_get_type_id(child_logical_type);
|
628
865
|
|
629
|
-
duckdb_list_entry list_entry = ((duckdb_list_entry *)
|
866
|
+
duckdb_list_entry list_entry = ((duckdb_list_entry *)vector_data)[row_idx];
|
867
|
+
idx_t bgn = list_entry.offset;
|
868
|
+
idx_t end = bgn + list_entry.length;
|
630
869
|
ary = rb_ary_new2(list_entry.length);
|
631
870
|
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
rb_ary_store(ary, i - list_entry.offset, element);
|
871
|
+
duckdb_vector child = duckdb_list_vector_get_child(vector);
|
872
|
+
|
873
|
+
for (i = bgn; i < end; ++i) {
|
874
|
+
value = vector_array_value_at(child, child_logical_type, i);
|
875
|
+
rb_ary_store(ary, i - bgn, value);
|
638
876
|
}
|
639
877
|
duckdb_destroy_logical_type(&child_logical_type);
|
640
878
|
return ary;
|
@@ -741,6 +979,9 @@ static VALUE vector_value(duckdb_vector vector, idx_t row_idx) {
|
|
741
979
|
case DUCKDB_TYPE_HUGEINT:
|
742
980
|
obj = vector_hugeint(vector_data, row_idx);
|
743
981
|
break;
|
982
|
+
case DUCKDB_TYPE_UHUGEINT:
|
983
|
+
obj = vector_uhugeint(vector_data, row_idx);
|
984
|
+
break;
|
744
985
|
case DUCKDB_TYPE_FLOAT:
|
745
986
|
obj = DBL2NUM((((float *) vector_data)[row_idx]));
|
746
987
|
break;
|
@@ -771,8 +1012,11 @@ static VALUE vector_value(duckdb_vector vector, idx_t row_idx) {
|
|
771
1012
|
case DUCKDB_TYPE_ENUM:
|
772
1013
|
obj = vector_enum(ty, vector_data, row_idx);
|
773
1014
|
break;
|
1015
|
+
case DUCKDB_TYPE_ARRAY:
|
1016
|
+
obj = vector_array(ty, vector, row_idx);
|
1017
|
+
break;
|
774
1018
|
case DUCKDB_TYPE_LIST:
|
775
|
-
obj = vector_list(ty, vector_data, row_idx);
|
1019
|
+
obj = vector_list(ty, vector, vector_data, row_idx);
|
776
1020
|
break;
|
777
1021
|
case DUCKDB_TYPE_MAP:
|
778
1022
|
obj = vector_map(ty, vector_data, row_idx);
|
@@ -805,26 +1049,27 @@ void rbduckdb_init_duckdb_result(void) {
|
|
805
1049
|
rb_define_alloc_func(cDuckDBResult, allocate);
|
806
1050
|
|
807
1051
|
rb_define_method(cDuckDBResult, "column_count", duckdb_result_column_count, 0);
|
808
|
-
rb_define_method(cDuckDBResult, "row_count", duckdb_result_row_count, 0);
|
1052
|
+
rb_define_method(cDuckDBResult, "row_count", duckdb_result_row_count, 0); /* deprecated */
|
809
1053
|
rb_define_method(cDuckDBResult, "rows_changed", duckdb_result_rows_changed, 0);
|
810
1054
|
rb_define_method(cDuckDBResult, "columns", duckdb_result_columns, 0);
|
811
1055
|
rb_define_method(cDuckDBResult, "streaming?", duckdb_result_streaming_p, 0);
|
812
1056
|
rb_define_method(cDuckDBResult, "chunk_each", duckdb_result_chunk_each, 0);
|
813
1057
|
rb_define_private_method(cDuckDBResult, "_chunk_stream", duckdb_result__chunk_stream, 0);
|
814
1058
|
rb_define_private_method(cDuckDBResult, "_column_type", duckdb_result__column_type, 1);
|
815
|
-
|
816
|
-
rb_define_private_method(cDuckDBResult, "
|
817
|
-
rb_define_private_method(cDuckDBResult, "
|
818
|
-
rb_define_private_method(cDuckDBResult, "
|
819
|
-
rb_define_private_method(cDuckDBResult, "
|
820
|
-
rb_define_private_method(cDuckDBResult, "
|
821
|
-
rb_define_private_method(cDuckDBResult, "
|
822
|
-
rb_define_private_method(cDuckDBResult, "
|
823
|
-
rb_define_private_method(cDuckDBResult, "
|
824
|
-
rb_define_private_method(cDuckDBResult, "
|
825
|
-
rb_define_private_method(cDuckDBResult, "
|
826
|
-
rb_define_private_method(cDuckDBResult, "
|
827
|
-
rb_define_private_method(cDuckDBResult, "
|
1059
|
+
|
1060
|
+
rb_define_private_method(cDuckDBResult, "_null?", duckdb_result__is_null, 2); /* deprecated */
|
1061
|
+
rb_define_private_method(cDuckDBResult, "_to_boolean", duckdb_result__to_boolean, 2); /* deprecated */
|
1062
|
+
rb_define_private_method(cDuckDBResult, "_to_smallint", duckdb_result__to_smallint, 2); /* deprecated */
|
1063
|
+
rb_define_private_method(cDuckDBResult, "_to_utinyint", duckdb_result__to_utinyint, 2); /* deprecated */
|
1064
|
+
rb_define_private_method(cDuckDBResult, "_to_integer", duckdb_result__to_integer, 2); /* deprecated */
|
1065
|
+
rb_define_private_method(cDuckDBResult, "_to_bigint", duckdb_result__to_bigint, 2); /* deprecated */
|
1066
|
+
rb_define_private_method(cDuckDBResult, "__to_hugeint_internal", duckdb_result___to_hugeint_internal, 2); /* deprecated */
|
1067
|
+
rb_define_private_method(cDuckDBResult, "__to_decimal_internal", duckdb_result___to_decimal_internal, 2); /* deprecated */
|
1068
|
+
rb_define_private_method(cDuckDBResult, "_to_float", duckdb_result__to_float, 2); /* deprecated */
|
1069
|
+
rb_define_private_method(cDuckDBResult, "_to_double", duckdb_result__to_double, 2); /* deprecated */
|
1070
|
+
rb_define_private_method(cDuckDBResult, "_to_string", duckdb_result__to_string, 2); /* deprecated */
|
1071
|
+
rb_define_private_method(cDuckDBResult, "_to_string_internal", duckdb_result__to_string_internal, 2); /* deprecated */
|
1072
|
+
rb_define_private_method(cDuckDBResult, "_to_blob", duckdb_result__to_blob, 2); /* deprecated */
|
828
1073
|
rb_define_private_method(cDuckDBResult, "_enum_internal_type", duckdb_result__enum_internal_type, 1);
|
829
1074
|
rb_define_private_method(cDuckDBResult, "_enum_dictionary_size", duckdb_result__enum_dictionary_size, 1);
|
830
1075
|
rb_define_private_method(cDuckDBResult, "_enum_dictionary_value", duckdb_result__enum_dictionary_value, 2);
|
data/ext/duckdb/ruby-duckdb.h
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
#ifndef RUBY_DUCKDB_H
|
2
2
|
#define RUBY_DUCKDB_H
|
3
3
|
|
4
|
+
// #define DUCKDB_API_NO_DEPRECATED
|
5
|
+
#define DUCKDB_NO_EXTENSION_FUNCTIONS // disable extension C-functions
|
6
|
+
|
4
7
|
#include "ruby.h"
|
5
8
|
#include <duckdb.h>
|
6
9
|
|
@@ -8,12 +11,17 @@
|
|
8
11
|
#define HAVE_DUCKDB_H_GE_V0_10_0 1
|
9
12
|
#endif
|
10
13
|
|
14
|
+
#ifdef HAVE_DUCKDB_FETCH_CHUNK
|
15
|
+
#define HAVE_DUCKDB_H_GE_V1_0_0 1
|
16
|
+
#endif
|
17
|
+
|
11
18
|
#include "./error.h"
|
12
19
|
#include "./database.h"
|
13
20
|
#include "./connection.h"
|
14
21
|
#include "./result.h"
|
15
22
|
#include "./column.h"
|
16
23
|
#include "./prepared_statement.h"
|
24
|
+
#include "./extracted_statements.h"
|
17
25
|
#include "./pending_result.h"
|
18
26
|
#include "./util.h"
|
19
27
|
#include "./converter.h"
|
data/lib/duckdb/appender.rb
CHANGED
@@ -39,6 +39,24 @@ module DuckDB
|
|
39
39
|
_append_hugeint(lower, upper)
|
40
40
|
end
|
41
41
|
|
42
|
+
#
|
43
|
+
# appends unsigned huge int value.
|
44
|
+
#
|
45
|
+
# require 'duckdb'
|
46
|
+
# db = DuckDB::Database.open
|
47
|
+
# con = db.connect
|
48
|
+
# con.query('CREATE TABLE numbers (num UHUGEINT)')
|
49
|
+
# appender = con.appender('numbers')
|
50
|
+
# appender
|
51
|
+
# .begin_row
|
52
|
+
# .append_hugeint(340_282_366_920_938_463_463_374_607_431_768_211_455)
|
53
|
+
# .end_row
|
54
|
+
#
|
55
|
+
def append_uhugeint(value)
|
56
|
+
lower, upper = integer_to_hugeint(value)
|
57
|
+
_append_uhugeint(lower, upper)
|
58
|
+
end
|
59
|
+
|
42
60
|
#
|
43
61
|
# appends date value.
|
44
62
|
#
|
data/lib/duckdb/result.rb
CHANGED
@@ -53,15 +53,17 @@ module DuckDB
|
|
53
53
|
alias column_size column_count
|
54
54
|
alias row_size row_count
|
55
55
|
|
56
|
+
@use_chunk_each = true
|
57
|
+
|
56
58
|
class << self
|
57
59
|
def new
|
58
60
|
raise DuckDB::Error, 'DuckDB::Result cannot be instantiated directly.'
|
59
61
|
end
|
60
62
|
|
61
|
-
def use_chunk_each=(
|
62
|
-
|
63
|
+
def use_chunk_each=(value)
|
64
|
+
warn('`changing DuckDB::Result.use_chunk_each to false` will be deprecated.') if value == false
|
63
65
|
|
64
|
-
@use_chunk_each =
|
66
|
+
@use_chunk_each = value
|
65
67
|
end
|
66
68
|
|
67
69
|
def use_chunk_each?
|
@@ -91,6 +93,7 @@ module DuckDB
|
|
91
93
|
end
|
92
94
|
|
93
95
|
def row(row_index)
|
96
|
+
warn("#{self.class}##{__method__} will be deprecated. set `DuckDB::Result.use_chunk_each = true`.")
|
94
97
|
row = []
|
95
98
|
column_count.times do |col_index|
|
96
99
|
row << (_null?(row_index, col_index) ? nil : to_value(row_index, col_index))
|
@@ -99,6 +102,7 @@ module DuckDB
|
|
99
102
|
end
|
100
103
|
|
101
104
|
def to_value(row_index, col_index)
|
105
|
+
warn("#{self.class}##{__method__} will be deprecated. set `DuckDB::Result.use_chunk_each = true`.")
|
102
106
|
send(TO_METHODS[_column_type(col_index)], row_index, col_index)
|
103
107
|
end
|
104
108
|
|
@@ -113,19 +117,23 @@ module DuckDB
|
|
113
117
|
private
|
114
118
|
|
115
119
|
def _to_hugeint(row, col)
|
120
|
+
warn("#{self.class}##{__method__} will be deprecated.")
|
116
121
|
_to_string(row, col).to_i
|
117
122
|
end
|
118
123
|
|
119
124
|
def _to_hugeint_internal(row, col)
|
125
|
+
warn("#{self.class}##{__method__} will be deprecated.")
|
120
126
|
lower, upper = __to_hugeint_internal(row, col)
|
121
127
|
Converter._to_hugeint_from_vector(lower, upper)
|
122
128
|
end
|
123
129
|
|
124
130
|
def _to_decimal(row, col)
|
131
|
+
warn("#{self.class}##{__method__} will be deprecated.")
|
125
132
|
BigDecimal(_to_string(row, col))
|
126
133
|
end
|
127
134
|
|
128
135
|
def _to_decimal_internal(row, col)
|
136
|
+
warn("#{self.class}##{__method__} will be deprecated.")
|
129
137
|
lower, upper, width, scale = __to_decimal_internal(row, col)
|
130
138
|
Converter._to_decimal_from_hugeint(width, scale, upper, lower)
|
131
139
|
end
|
data/lib/duckdb/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: duckdb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Masaki Suketa
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-06-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bigdecimal
|
@@ -132,6 +132,8 @@ files:
|
|
132
132
|
- ext/duckdb/error.c
|
133
133
|
- ext/duckdb/error.h
|
134
134
|
- ext/duckdb/extconf.rb
|
135
|
+
- ext/duckdb/extracted_statements.c
|
136
|
+
- ext/duckdb/extracted_statements.h
|
135
137
|
- ext/duckdb/pending_result.c
|
136
138
|
- ext/duckdb/pending_result.h
|
137
139
|
- ext/duckdb/prepared_statement.c
|
@@ -179,7 +181,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
179
181
|
- !ruby/object:Gem::Version
|
180
182
|
version: '0'
|
181
183
|
requirements: []
|
182
|
-
rubygems_version: 3.5.
|
184
|
+
rubygems_version: 3.5.11
|
183
185
|
signing_key:
|
184
186
|
specification_version: 4
|
185
187
|
summary: This module is Ruby binding for DuckDB database engine.
|