duckdb 0.9.2.2 → 0.10.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ae1127b035cba551fdee1c009f9e0ee76161936aadaf192d1e78bdf6c5482c0a
4
- data.tar.gz: 9c7889dbc1dc31af86d99011b3af37fe427ac23a3ba40f6aa23f253c7453874d
3
+ metadata.gz: e5855147af5fe02372c4bf0f67e5f5c4c046305e3d77fee7d6578d63b7d31aa7
4
+ data.tar.gz: 88701d3c0213ce6fbbe45185f82cbc823d7eb5ee6ff531ab19a720bfd72f3939
5
5
  SHA512:
6
- metadata.gz: 67cbfeabe7fcbc6e2cab91ea0eb3670546ad33ef06e9f3f9cd768885b3b17849910e55bc0d6d71d609ccca90d8896a08df2a8b3a2b4477b2591a5ad60135b388
7
- data.tar.gz: 00a229aad9144ebb1d36664729211795f728fc00888323b0bdbbd1e516a274d62e4727fb469d1e913e5c8e7a4bc15226e938d85d25f9c3684797d94a73272581
6
+ metadata.gz: 955bf24278d0eff8138690a9fa2dbb465c5ab94654e7be07f8001d7eeb8863af461d94c9bbdd0af4260bac0090c13bb1b18f3dd8608b55dec1d23e057577eac9
7
+ data.tar.gz: 9c2ce6b1648cd95ee16418abb01203c18f8f1d7f0360f242866c97aadd5ee1af92c1c4ba9da29146ea54904cd1acc45873ebf3cf5c0db42a6d94c4212dbeef96
@@ -15,8 +15,8 @@ jobs:
15
15
  runs-on: macos-latest
16
16
  strategy:
17
17
  matrix:
18
- ruby: ['3.0.6', '3.1.4', '3.2.2', '3.3.0', 'head']
19
- duckdb: ['0.9.2', '0.8.1']
18
+ ruby: ['3.0.6', '3.1.4', '3.2.3', '3.3.0', 'head']
19
+ duckdb: ['0.9.2', '0.10.0']
20
20
 
21
21
  steps:
22
22
  - uses: actions/checkout@v3
@@ -15,8 +15,8 @@ jobs:
15
15
  runs-on: ubuntu-latest
16
16
  strategy:
17
17
  matrix:
18
- ruby: ['3.0.6', '3.1.4', '3.2.2', '3.3.0', 'head']
19
- duckdb: ['0.9.2', '0.8.1']
18
+ ruby: ['3.0.6', '3.1.4', '3.2.3', '3.3.0', 'head']
19
+ duckdb: ['0.9.2', '0.10.0']
20
20
 
21
21
  steps:
22
22
  - uses: actions/checkout@v3
@@ -15,8 +15,8 @@ jobs:
15
15
  runs-on: windows-latest
16
16
  strategy:
17
17
  matrix:
18
- ruby: ['3.0.6', '3.1.4', '3.2.2', 'ucrt', 'mingw', 'mswin', 'head']
19
- duckdb: ['0.9.2', '0.8.1']
18
+ ruby: ['3.0.6', '3.1.4', '3.2.2', '3.3.0', 'ucrt', 'mingw', 'mswin', 'head']
19
+ duckdb: ['0.9.2', '0.10.0']
20
20
 
21
21
  steps:
22
22
  - uses: actions/checkout@v3
data/CHANGELOG.md CHANGED
@@ -1,27 +1,45 @@
1
- # ChangeLog
1
+ # Changelog
2
2
 
3
- # 0.9.2.2
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## Unreleased
6
+
7
+ # 0.10.0.0 - 2024-02-18
8
+ - bump to duckdb 0.10.0.
9
+ - fix building error with duckdb v0.10.0.
10
+ - bundle update to bump nokogiri from 1.16.0 to 1.16.2.
11
+ - fix Decimal type conversion.
12
+
13
+ ## Breaking changes
14
+
15
+ - `DuckDB::Connection#query_progress` returns `DuckDB::QueryProgress` object only when duckdb library version is 0.10.0.
16
+ - The available methods are `DuckDB::QueryProgress#percentage`, `DuckDB::QueryProgress#rows_processed`, `DuckDB::QueryProgress#total_rows_to_process`.
17
+
18
+ # 0.9.2.3 - 2023-12-29
19
+ - fix bigdecimal warning with Ruby 3.3.0.
20
+
21
+ # 0.9.2.2 - 2023-12-26
4
22
  - bump Ruby to 3.3.0 on CI.
5
23
 
6
24
  ## Breaking changes
7
25
  - drop Ruby 2.7.
8
26
 
9
- # 0.9.2.1
27
+ # 0.9.2.1 - 2023-12-24
10
28
  - support Time column in `DuckDB#Result#chunk_each`.
11
29
  - add `DuckDB::Interval#eql?`.
12
30
 
13
- # 0.9.2
31
+ # 0.9.2 - 2023-11-26
14
32
  - add `DuckDB::Connection#async_query_stream`.
15
33
  - `DuckDB::PendingResult` accepts second argument. If the second argument is
16
34
  true, `PendingResult#execute_pending` returns streaming `DuckDB::Result` object.
17
35
  - add `DuckDB::PreparedStatement#pending_prepared_stream`
18
36
  - add `DuckDB::Result#streaming?`.
19
37
 
20
- # 0.9.1.2
38
+ # 0.9.1.2 - 2023-11-05
21
39
  - add `DuckDB::Connection#interrupt`, `DuckDB::Connection#query_progress`.
22
40
  - add `DuckDB::Connection#async_query`, alias method `async_execute`.
23
41
 
24
- # 0.9.1.1
42
+ # 0.9.1.1 - 2023-10-29
25
43
  - change default branch to main from master.
26
44
  - add `DuckDB::PendingResult` class.
27
45
  - add `DuckDB::PendingResult#state`.
@@ -32,15 +50,15 @@
32
50
  ## Breaking Changes
33
51
  - drop duckdb v0.7.x.
34
52
 
35
- # 0.9.1
53
+ # 0.9.1 - 2023-10-14
36
54
  - add `DuckDB::PreparedStatement#parameter_name`.
37
55
  - bump duckdb to 0.9.1.
38
56
 
39
- # 0.9.0.1
57
+ # 0.9.0.1 - 2023-10-08
40
58
  - add `DuckDB::PreparedStatement#bind_parameter_index`.
41
59
  - `DuckDB::Connection#query` accepts SQL with named bind parameters.
42
60
 
43
- # 0.9.0
61
+ # 0.9.0 - 2023-09-30
44
62
  - bump duckdb to 0.9.0.
45
63
 
46
64
  ## Breaking Changes
data/Dockerfile CHANGED
@@ -1,7 +1,7 @@
1
1
  ARG RUBY_VERSION=3.2.2
2
2
  FROM ruby:${RUBY_VERSION}
3
3
 
4
- ARG DUCKDB_VERSION=0.9.2
4
+ ARG DUCKDB_VERSION=0.10.0
5
5
 
6
6
  RUN apt update -qq && \
7
7
  apt install -y build-essential curl git wget
data/Gemfile.lock CHANGED
@@ -1,24 +1,28 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- duckdb (0.9.2.2)
4
+ duckdb (0.10.0.0)
5
+ bigdecimal (>= 3.1.4)
5
6
 
6
7
  GEM
7
8
  remote: https://rubygems.org/
8
9
  specs:
9
10
  benchmark-ips (2.13.0)
11
+ bigdecimal (3.1.6)
10
12
  mini_portile2 (2.8.5)
11
- minitest (5.20.0)
12
- nokogiri (1.15.5)
13
+ minitest (5.22.2)
14
+ nokogiri (1.16.2)
13
15
  mini_portile2 (~> 2.8.2)
14
16
  racc (~> 1.4)
17
+ nokogiri (1.16.2-x86_64-linux)
18
+ racc (~> 1.4)
15
19
  racc (1.7.3)
16
20
  rake (13.1.0)
17
- rake-compiler (1.2.5)
21
+ rake-compiler (1.2.7)
18
22
  rake
19
23
  ruby_memcheck (2.3.0)
20
24
  nokogiri
21
- stackprof (0.2.25)
25
+ stackprof (0.2.26)
22
26
 
23
27
  PLATFORMS
24
28
  ruby
data/README.md CHANGED
@@ -7,32 +7,34 @@
7
7
 
8
8
  ## Description
9
9
 
10
- ruby-duckdb is Ruby binding for [DuckDB](http://www.duckdb.org) database engine
10
+ This gem `duckdb` is Ruby client for the [DuckDB](https://www.duckdb.org) database engine.
11
11
 
12
12
  ## Requirement
13
13
 
14
- You must have [DuckDB](http://www.duckdb.org) engine installed in order to build/use this module.
14
+ You must have [DuckDB](https://www.duckdb.org) engine installed in order to use this gem.
15
15
 
16
16
  ## Pre-requisite setup (Linux):
17
- 1. Head over to the [DuckDB](https://duckdb.org/) webpage
17
+ 1. Head over to the [DuckDB](https://duckdb.org/) webpage.
18
18
 
19
- 2. Download the latest C++ package release for DuckDB
19
+ 2. Download the latest C++ package release for DuckDB.
20
20
 
21
21
  3. Move the files to their respective location:
22
- - Extract the `duckdb.h` and `duckdb.hpp` file to `/usr/local/include`
23
- - Extract the `libduckdb.so` file to `/usr/local/lib`
22
+ - Extract the `duckdb.h` and `duckdb.hpp` file to `/usr/local/include`.
23
+ - Extract the `libduckdb.so` file to `/usr/local/lib`.
24
24
 
25
25
  ```sh
26
26
  unzip libduckdb-linux-amd64.zip -d libduckdb
27
27
  sudo mv libduckdb/duckdb.* /usr/local/include/
28
28
  sudo mv libduckdb/libduckdb.so /usr/local/lib
29
29
  ```
30
+
30
31
  4. To create the necessary link, run `ldconfig` as root:
31
32
 
32
33
  ```sh
33
34
  sudo ldconfig /usr/local/lib # adding a --verbose flag is optional - but this will let you know if the libduckdb.so library has been linked
34
35
  ```
35
- ## Pre-requisite setup (MacOS):
36
+
37
+ ## Pre-requisite setup (macOS):
36
38
 
37
39
  Using `brew install` is recommended.
38
40
 
@@ -40,14 +42,15 @@ Using `brew install` is recommended.
40
42
  brew install duckdb
41
43
  ```
42
44
 
43
- ## How to Install
45
+ ## How to install
44
46
 
45
47
  ```sh
46
48
  gem install duckdb
47
49
  ```
48
- > this will work fine with the above pre-requisite setup.
49
50
 
50
- or you must specify the location of the C header and library files:
51
+ After you've run the above pre-requisite setup, this should work fine.
52
+
53
+ If it doesn't, you may habe to specify the location of the C header and library files:
51
54
 
52
55
  ```sh
53
56
  gem install duckdb -- --with-duckdb-include=/duckdb_header_directory --with-duckdb-lib=/duckdb_library_directory
@@ -69,7 +72,7 @@ con.query("INSERT into users VALUES(3, 'Cathy')")
69
72
 
70
73
  result = con.query('SELECT * from users')
71
74
  result.each do |row|
72
- p row
75
+ puts row
73
76
  end
74
77
  ```
75
78
 
@@ -88,13 +91,13 @@ DuckDB::Database.open do |db|
88
91
 
89
92
  result = con.query('SELECT * from users')
90
93
  result.each do |row|
91
- p row
94
+ puts row
92
95
  end
93
96
  end
94
97
  end
95
98
  ```
96
99
 
97
- ### using bind variables
100
+ ### Using bind variables
98
101
 
99
102
  You can use bind variables.
100
103
 
@@ -104,12 +107,12 @@ con.query('SELECT * FROM users WHERE name = ? AND email = ?', 'Alice', 'alice@ex
104
107
  con.query('SELECT * FROM users WHERE name = $name AND email = $email', name: 'Alice', email: 'alice@example.com')
105
108
  ```
106
109
 
107
- ### using async query
110
+ ### Using async query
108
111
 
109
112
  You can use async query.
110
113
 
111
114
  ```ruby
112
- DuckDB::Result.use_chunk_each = true # must be true.
115
+ DuckDB::Result.use_chunk_each = true
113
116
  ...
114
117
 
115
118
  pending_result = con.async_query_stream('SLOW QUERY')
@@ -121,9 +124,9 @@ result.each.first
121
124
 
122
125
  Here is [the benchmark](./benchmark/async_query.rb).
123
126
 
124
- ### using BLOB column
127
+ ### Using BLOB column
125
128
 
126
- Use `DuckDB::Blob.new` or use sting#force_encoding(Encoding::BINARY)
129
+ Use `DuckDB::Blob.new` or use string#force_encoding(Encoding::BINARY)
127
130
 
128
131
  ```ruby
129
132
  require 'duckdb'
@@ -134,12 +137,12 @@ DuckDB::Database.open do |db|
134
137
  stmt = DuckDB::PreparedStatement.new(con, 'INSERT INTO blob_table VALUES ($1)')
135
138
 
136
139
  stmt.bind(1, DuckDB::Blob.new("\0\1\2\3\4\5"))
137
- # or
140
+ # or
138
141
  # stmt.bind(1, "\0\1\2\3\4\5".force_encoding(Encoding::BINARY))
139
142
  stmt.execute
140
143
 
141
144
  result = con.query('SELECT binary_data FROM blob_table')
142
- p result.first.first
145
+ puts result.first.first
143
146
  end
144
147
  end
145
148
  ```
@@ -212,14 +215,17 @@ Config class provides Ruby interface of [DuckDB configuration](https://duckdb.or
212
215
 
213
216
  ```ruby
214
217
  require 'duckdb'
218
+
215
219
  config = DuckDB::Config.new
216
220
  config['default_order'] = 'DESC'
221
+
217
222
  db = DuckDB::Database.open(nil, config)
223
+
218
224
  con = db.connect
219
225
  con.query('CREATE TABLE numbers (number INTEGER)')
220
226
  con.query('INSERT INTO numbers VALUES (2), (1), (4), (3)')
221
227
 
222
- # number is ordered by descending.
223
- r = con.query('SELECT number FROM numbers ORDER BY number')
224
- r.first.first # => 4
228
+ # number is ordered by descending
229
+ res = con.query('SELECT number FROM numbers ORDER BY number')
230
+ res.first.first # => 4
225
231
  ```
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ require 'duckdb'
5
+ require 'benchmark/ips'
6
+
7
+ DuckDB::Result.use_chunk_each = true
8
+ db = DuckDB::Database.open
9
+ con = db.connect
10
+ con.query(<<~SQL
11
+ CREATE TABLE t (
12
+ date_value DATE,
13
+ time_value TIME,
14
+ timestamp_value TIMESTAMP,
15
+ interval_value INTERVAL,
16
+ hugeint_value HUGEINT,
17
+ uuid_value UUID,
18
+ decimal_value DECIMAL(4, 2)
19
+ )
20
+ SQL
21
+ )
22
+ con.query(<<~SQL
23
+ INSERT INTO t VALUES
24
+ (
25
+ '2019-01-01',
26
+ '12:00:00',
27
+ '2019-01-01 12:00:00',
28
+ '1 day',
29
+ 12345678901234567890,
30
+ 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11',
31
+ 0.12
32
+ ),
33
+ (
34
+ '2019-01-01',
35
+ '12:00:00',
36
+ '2019-01-01 12:00:00',
37
+ '1 day',
38
+ 12345678901234567890,
39
+ 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11',
40
+ 0.12
41
+ ),
42
+ (
43
+ '2019-01-01',
44
+ '12:00:00',
45
+ '2019-01-01 12:00:00',
46
+ '1 day',
47
+ 12345678901234567890,
48
+ 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11',
49
+ 2.12
50
+ )
51
+ SQL
52
+ )
53
+ result = con.query('SELECT * FROM t')
54
+
55
+ Benchmark.ips do |x|
56
+ x.report('_to_date') { result.each.to_a }
57
+ end
58
+
59
+ __END__
60
+ ```
61
+ ## before
62
+ ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-linux]
63
+ Warming up --------------------------------------
64
+ _to_date 30.790k i/100ms
65
+ Calculating -------------------------------------
66
+ _to_date 365.254k (± 0.2%) i/s - 1.847M in 5.057875s
67
+
68
+ ## after
69
+ ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-linux]
70
+ Warming up --------------------------------------
71
+ _to_date 36.047k i/100ms
72
+ Calculating -------------------------------------
73
+ _to_date 383.760k (± 3.3%) i/s - 1.947M in 5.077849s
data/duckdb.gemspec CHANGED
@@ -27,6 +27,7 @@ Gem::Specification.new do |spec|
27
27
  spec.require_paths = ['lib']
28
28
  spec.extensions = ['ext/duckdb/extconf.rb']
29
29
  spec.required_ruby_version = '>= 3.0.0'
30
+ spec.add_dependency 'bigdecimal', '>= 3.1.4'
30
31
 
31
32
  spec.add_development_dependency 'bundler', '~> 2.3'
32
33
  spec.add_development_dependency 'minitest', '~> 5.0'
@@ -111,12 +111,20 @@ static VALUE duckdb_connection_interrupt(VALUE self) {
111
111
  */
112
112
  static VALUE duckdb_connection_query_progress(VALUE self) {
113
113
  rubyDuckDBConnection *ctx;
114
+ #ifdef HAVE_DUCKDB_H_GE_V0_10_0
115
+ duckdb_query_progress_type progress;
116
+ #else
114
117
  double progress;
118
+ #endif
115
119
 
116
120
  TypedData_Get_Struct(self, rubyDuckDBConnection, &connection_data_type, ctx);
117
121
  progress = duckdb_query_progress(ctx->con);
118
122
 
123
+ #ifdef HAVE_DUCKDB_H_GE_V0_10_0
124
+ return rb_funcall(mDuckDBConverter, rb_intern("_to_query_progress"), 3, DBL2NUM(progress.percentage), ULL2NUM(progress.rows_processed), ULL2NUM(progress.total_rows_to_process));
125
+ #else
119
126
  return DBL2NUM(progress);
127
+ #endif
120
128
  }
121
129
  #endif
122
130
 
@@ -58,6 +58,9 @@ check_duckdb_library('duckdb', 'duckdb_string_is_inlined', DUCKDB_REQUIRED_VERSI
58
58
  # check duckdb >= 0.9.0
59
59
  have_func('duckdb_bind_parameter_index', 'duckdb.h')
60
60
 
61
+ # check duckdb >= 0.10.0
62
+ have_func('duckdb_appender_column_count', 'duckdb.h')
63
+
61
64
  # duckdb_parameter_name is not found on Windows.
62
65
  have_func('duckdb_parameter_name', 'duckdb.h')
63
66
 
data/ext/duckdb/result.c CHANGED
@@ -1,6 +1,13 @@
1
1
  #include "ruby-duckdb.h"
2
2
 
3
3
  static VALUE cDuckDBResult;
4
+ static ID id__to_date;
5
+ static ID id__to_time;
6
+ static ID id__to_time_from_duckdb_time;
7
+ static ID id__to_interval_from_vector;
8
+ static ID id__to_hugeint_from_vector;
9
+ static ID id__to_decimal_from_hugeint;
10
+ static ID id__to_uuid_from_vector;
4
11
 
5
12
  static void deallocate(void *ctx);
6
13
  static VALUE allocate(VALUE klass);
@@ -482,7 +489,7 @@ VALUE rbduckdb_create_result(void) {
482
489
  static VALUE vector_date(void *vector_data, idx_t row_idx) {
483
490
  duckdb_date_struct date = duckdb_from_date(((duckdb_date *) vector_data)[row_idx]);
484
491
 
485
- return rb_funcall(mDuckDBConverter, rb_intern("_to_date"), 3,
492
+ return rb_funcall(mDuckDBConverter, id__to_date, 3,
486
493
  INT2FIX(date.year),
487
494
  INT2FIX(date.month),
488
495
  INT2FIX(date.day)
@@ -491,7 +498,7 @@ static VALUE vector_date(void *vector_data, idx_t row_idx) {
491
498
 
492
499
  static VALUE vector_timestamp(void* vector_data, idx_t row_idx) {
493
500
  duckdb_timestamp_struct data = duckdb_from_timestamp(((duckdb_timestamp *)vector_data)[row_idx]);
494
- return rb_funcall(mDuckDBConverter, rb_intern("_to_time"), 7,
501
+ return rb_funcall(mDuckDBConverter, id__to_time, 7,
495
502
  INT2FIX(data.date.year),
496
503
  INT2FIX(data.date.month),
497
504
  INT2FIX(data.date.day),
@@ -504,7 +511,7 @@ static VALUE vector_timestamp(void* vector_data, idx_t row_idx) {
504
511
 
505
512
  static VALUE vector_time(void* vector_data, idx_t row_idx) {
506
513
  duckdb_time_struct data = duckdb_from_time(((duckdb_time *)vector_data)[row_idx]);
507
- return rb_funcall(mDuckDBConverter, rb_intern("_to_time_from_duckdb_time"), 4,
514
+ return rb_funcall(mDuckDBConverter, id__to_time_from_duckdb_time, 4,
508
515
  INT2FIX(data.hour),
509
516
  INT2FIX(data.min),
510
517
  INT2FIX(data.sec),
@@ -515,7 +522,7 @@ static VALUE vector_time(void* vector_data, idx_t row_idx) {
515
522
 
516
523
  static VALUE vector_interval(void* vector_data, idx_t row_idx) {
517
524
  duckdb_interval data = ((duckdb_interval *)vector_data)[row_idx];
518
- return rb_funcall(mDuckDBConverter, rb_intern("_to_interval_from_vector"), 3,
525
+ return rb_funcall(mDuckDBConverter, id__to_interval_from_vector, 3,
519
526
  INT2NUM(data.months),
520
527
  INT2NUM(data.days),
521
528
  LL2NUM(data.micros)
@@ -542,34 +549,47 @@ static VALUE vector_varchar(void* vector_data, idx_t row_idx) {
542
549
 
543
550
  static VALUE vector_hugeint(void* vector_data, idx_t row_idx) {
544
551
  duckdb_hugeint hugeint = ((duckdb_hugeint *)vector_data)[row_idx];
545
- return rb_funcall(mDuckDBConverter, rb_intern("_to_hugeint_from_vector"), 2,
552
+ return rb_funcall(mDuckDBConverter, id__to_hugeint_from_vector, 2,
546
553
  ULL2NUM(hugeint.lower),
547
554
  LL2NUM(hugeint.upper)
548
555
  );
549
556
  }
550
557
 
551
558
  static VALUE vector_decimal(duckdb_logical_type ty, void* vector_data, idx_t row_idx) {
552
- uint8_t width = duckdb_decimal_width(ty);
553
- uint8_t scale = duckdb_decimal_scale(ty);
559
+ VALUE width = INT2FIX(duckdb_decimal_width(ty));
560
+ VALUE scale = INT2FIX(duckdb_decimal_scale(ty));
554
561
  duckdb_type type = duckdb_decimal_internal_type(ty);
555
562
  duckdb_hugeint value;
563
+ VALUE upper = Qnil;
564
+ VALUE lower = Qnil;
556
565
 
557
566
  value.upper = 0;
558
567
  value.lower = 0;
559
568
 
560
- switch(duckdb_decimal_internal_type(ty)) {
569
+ switch(type) {
561
570
  case DUCKDB_TYPE_HUGEINT:
562
571
  value = ((duckdb_hugeint *) vector_data)[row_idx];
572
+ upper = LL2NUM(value.upper);
573
+ lower = ULL2NUM(value.lower);
574
+ break;
575
+ case DUCKDB_TYPE_SMALLINT:
576
+ upper = INT2FIX(((int16_t *) vector_data)[row_idx]);
577
+ break;
578
+ case DUCKDB_TYPE_INTEGER:
579
+ upper = INT2NUM(((int32_t *) vector_data)[row_idx]);
580
+ break;
581
+ case DUCKDB_TYPE_BIGINT:
582
+ upper = LL2NUM(((int64_t *) vector_data)[row_idx]);
563
583
  break;
564
584
  default:
565
585
  rb_warn("Unknown decimal internal type %d", type);
566
586
  }
567
587
 
568
- return rb_funcall(mDuckDBConverter, rb_intern("_to_decimal_from_vector"), 4,
569
- INT2FIX(width),
570
- INT2FIX(scale),
571
- ULL2NUM(value.lower),
572
- LL2NUM(value.upper)
588
+ return rb_funcall(mDuckDBConverter, id__to_decimal_from_hugeint, 4,
589
+ width,
590
+ scale,
591
+ upper,
592
+ lower
573
593
  );
574
594
  }
575
595
 
@@ -665,7 +685,7 @@ static VALUE vector_struct(duckdb_logical_type ty, duckdb_vector vector, idx_t r
665
685
 
666
686
  static VALUE vector_uuid(void* vector_data, idx_t row_idx) {
667
687
  duckdb_hugeint hugeint = ((duckdb_hugeint *)vector_data)[row_idx];
668
- return rb_funcall(mDuckDBConverter, rb_intern("_to_uuid_from_vector"), 2,
688
+ return rb_funcall(mDuckDBConverter, id__to_uuid_from_vector, 2,
669
689
  ULL2NUM(hugeint.lower),
670
690
  LL2NUM(hugeint.upper)
671
691
  );
@@ -774,6 +794,14 @@ static VALUE vector_value(duckdb_vector vector, idx_t row_idx) {
774
794
 
775
795
  void rbduckdb_init_duckdb_result(void) {
776
796
  cDuckDBResult = rb_define_class_under(mDuckDB, "Result", rb_cObject);
797
+ id__to_date = rb_intern("_to_date");
798
+ id__to_time = rb_intern("_to_time");
799
+ id__to_time_from_duckdb_time = rb_intern("_to_time_from_duckdb_time");
800
+ id__to_interval_from_vector = rb_intern("_to_interval_from_vector");
801
+ id__to_hugeint_from_vector = rb_intern("_to_hugeint_from_vector");
802
+ id__to_decimal_from_hugeint = rb_intern("_to_decimal_from_hugeint");
803
+ id__to_uuid_from_vector = rb_intern("_to_uuid_from_vector");
804
+
777
805
  rb_define_alloc_func(cDuckDBResult, allocate);
778
806
 
779
807
  rb_define_method(cDuckDBResult, "column_count", duckdb_result_column_count, 0);
@@ -8,6 +8,10 @@
8
8
  #define HAVE_DUCKDB_H_GE_V090 1
9
9
  #endif
10
10
 
11
+ #ifdef HAVE_DUCKDB_APPENDER_COLUMN_COUNT
12
+ #define HAVE_DUCKDB_H_GE_V0_10_0 1
13
+ #endif
14
+
11
15
  #include "./error.h"
12
16
  #include "./database.h"
13
17
  #include "./connection.h"
data/lib/duckdb/column.rb CHANGED
@@ -48,6 +48,9 @@ module DuckDB
48
48
  uuid
49
49
  json
50
50
  ]
51
+ if Gem::Version.new(DuckDB::LIBRARY_VERSION) >= Gem::Version.new('0.10.0')
52
+ types[17, 0] = :uhugeint
53
+ end
51
54
  index = _type
52
55
  return :unknown if index >= types.size
53
56
 
@@ -4,6 +4,8 @@ require 'date'
4
4
  require_relative 'interval'
5
5
 
6
6
  module DuckDB
7
+ QueryProgress = Struct.new(:percentage, :rows_processed, :total_rows_to_process)
8
+
7
9
  module Converter
8
10
  HALF_HUGEINT_BIT = 64
9
11
  HALF_HUGEINT = 1 << HALF_HUGEINT_BIT
@@ -35,10 +37,15 @@ module DuckDB
35
37
  (upper << HALF_HUGEINT_BIT) + lower
36
38
  end
37
39
 
38
- def _to_decimal_from_vector(_width, scale, lower, upper)
39
- v = _to_hugeint_from_vector(lower, upper).to_s
40
+ def _to_decimal_from_hugeint(width, scale, upper, lower = nil)
41
+ v = lower.nil? ? upper : _to_hugeint_from_vector(lower, upper)
42
+ _to_decimal_from_value(width, scale, v)
43
+ end
44
+
45
+ def _to_decimal_from_value(_width, scale, value)
46
+ v = value.to_s
40
47
  v = v.rjust(scale + 1, '0') if v.length < scale
41
- v[-scale, 0] = '.'
48
+ v[-scale, 0] = '.' if scale.positive?
42
49
  BigDecimal(v)
43
50
  end
44
51
 
@@ -80,6 +87,10 @@ module DuckDB
80
87
  end
81
88
  end
82
89
 
90
+ def _to_query_progress(percentage, rows_processed, total_rows_to_process)
91
+ DuckDB::QueryProgress.new(percentage, rows_processed, total_rows_to_process).freeze
92
+ end
93
+
83
94
  private
84
95
 
85
96
  def integer_to_hugeint(value)
data/lib/duckdb/result.rb CHANGED
@@ -24,18 +24,31 @@ module DuckDB
24
24
  # end
25
25
  class Result
26
26
  include Enumerable
27
-
28
- TO_METHODS = Hash.new(:_to_string).merge(
29
- 1 => :_to_boolean,
30
- 3 => :_to_smallint,
31
- 4 => :_to_integer,
32
- 5 => :_to_bigint,
33
- 10 => :_to_float,
34
- 11 => :_to_double,
35
- 16 => :_to_hugeint_internal,
36
- 18 => :_to_blob,
37
- 19 => :_to_decimal_internal
38
- ).freeze
27
+ TO_METHODS = if Gem::Version.new(DuckDB::LIBRARY_VERSION) >= Gem::Version.new('0.10.0')
28
+ Hash.new(:_to_string).merge(
29
+ 1 => :_to_boolean,
30
+ 3 => :_to_smallint,
31
+ 4 => :_to_integer,
32
+ 5 => :_to_bigint,
33
+ 10 => :_to_float,
34
+ 11 => :_to_double,
35
+ 16 => :_to_hugeint_internal,
36
+ 19 => :_to_blob,
37
+ 20 => :_to_decimal_internal
38
+ ).freeze
39
+ else
40
+ Hash.new(:_to_string).merge(
41
+ 1 => :_to_boolean,
42
+ 3 => :_to_smallint,
43
+ 4 => :_to_integer,
44
+ 5 => :_to_bigint,
45
+ 10 => :_to_float,
46
+ 11 => :_to_double,
47
+ 16 => :_to_hugeint_internal,
48
+ 18 => :_to_blob,
49
+ 19 => :_to_decimal_internal
50
+ ).freeze
51
+ end
39
52
 
40
53
  alias column_size column_count
41
54
  alias row_size row_count
@@ -114,7 +127,7 @@ module DuckDB
114
127
 
115
128
  def _to_decimal_internal(row, col)
116
129
  lower, upper, width, scale = __to_decimal_internal(row, col)
117
- Converter._to_decimal_from_vector(width, scale, lower, upper)
130
+ Converter._to_decimal_from_hugeint(width, scale, upper, lower)
118
131
  end
119
132
  end
120
133
  end
@@ -3,5 +3,5 @@
3
3
  module DuckDB
4
4
  # The version string of ruby-duckdb.
5
5
  # Currently, ruby-duckdb is NOT semantic versioning.
6
- VERSION = '0.9.2.2'
6
+ VERSION = '0.10.0.0'
7
7
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: duckdb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2.2
4
+ version: 0.10.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masaki Suketa
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-26 00:00:00.000000000 Z
11
+ date: 2024-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bigdecimal
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 3.1.4
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 3.1.4
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -95,6 +109,7 @@ files:
95
109
  - benchmark/to_bigdecimal_ips.rb
96
110
  - benchmark/to_hugeint_ips.rb
97
111
  - benchmark/to_hugeint_profile.rb
112
+ - benchmark/to_intern_ips.rb
98
113
  - bin/console
99
114
  - bin/setup
100
115
  - docker-compose.yml