duckdb 0.9.2.3 → 0.10.1.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: a636f9cec690ea0c67c8407996c74337e2dfd4a78b3d949e25dcdf4b080e9ad8
4
- data.tar.gz: 7f958a1daa56685544f23d8ac096bae993120b5d9d9562fb55daa915f91516cc
3
+ metadata.gz: b2100acff5462ba1ae39b45795b53969911ff7e567007875098cebc536b6b3a1
4
+ data.tar.gz: c99f55d6e6b9d535f75ed6759daaddb0ef39dc49ee1861cc1a1b7c18a914ea6d
5
5
  SHA512:
6
- metadata.gz: 3b4cf27c17979e07133df3fa97b97a47a9cb64f10fdce7bb369cfe3b623b30065d428cc7f36ca16156ea37c433cb94faf12ed311433e8bd4b3fc82954dda9cc0
7
- data.tar.gz: 52362d2a207c0c156a8b32971fd0de8b531b7f9e6f3ad3eb7fc148dff905b6570637eebf30a6b785ca729f147c864b829bd60f4d6ba80f0064f7565b2d0a7eb9
6
+ metadata.gz: 112837a9b6df91ff4db6ebd489c1ad04fbacac7eea0d778d3c82ecc21ef1c0772cbca42123a99f39a170585fbbaf0cba5f904809cac2dd71a8e7fe2b474fe71b
7
+ data.tar.gz: b6b2b47cff49a552e51d53988f03f73dd2163ec06877114a019bbaf155c2519417465e3fe208a15cdaf4953df6749661786f2ca627fb42488fbae7f466b77e97
@@ -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', '0.10.1']
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', '0.10.1']
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', '0.10.1']
20
20
 
21
21
  steps:
22
22
  - uses: actions/checkout@v3
data/CHANGELOG.md CHANGED
@@ -1,30 +1,49 @@
1
- # ChangeLog
1
+ # Changelog
2
2
 
3
- # 0.9.2.3
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## Unreleased
6
+
7
+ # 0.10.1.0 - 2024-03-22
8
+ - drop duckdb v0.8.x.
9
+ - fix column type failures with duckdb v0.10.1.
10
+
11
+ # 0.10.0.0 - 2024-02-18
12
+ - bump to duckdb v0.10.0.
13
+ - fix building error with duckdb v0.10.0.
14
+ - bundle update to bump nokogiri from 1.16.0 to 1.16.2.
15
+ - fix Decimal type conversion.
16
+
17
+ ## Breaking changes
18
+
19
+ - `DuckDB::Connection#query_progress` returns `DuckDB::QueryProgress` object only when duckdb library version is 0.10.0 or later.
20
+ - The available methods are `DuckDB::QueryProgress#percentage`, `DuckDB::QueryProgress#rows_processed`, `DuckDB::QueryProgress#total_rows_to_process`.
21
+
22
+ # 0.9.2.3 - 2023-12-29
4
23
  - fix bigdecimal warning with Ruby 3.3.0.
5
24
 
6
- # 0.9.2.2
25
+ # 0.9.2.2 - 2023-12-26
7
26
  - bump Ruby to 3.3.0 on CI.
8
27
 
9
28
  ## Breaking changes
10
29
  - drop Ruby 2.7.
11
30
 
12
- # 0.9.2.1
31
+ # 0.9.2.1 - 2023-12-24
13
32
  - support Time column in `DuckDB#Result#chunk_each`.
14
33
  - add `DuckDB::Interval#eql?`.
15
34
 
16
- # 0.9.2
35
+ # 0.9.2 - 2023-11-26
17
36
  - add `DuckDB::Connection#async_query_stream`.
18
37
  - `DuckDB::PendingResult` accepts second argument. If the second argument is
19
38
  true, `PendingResult#execute_pending` returns streaming `DuckDB::Result` object.
20
39
  - add `DuckDB::PreparedStatement#pending_prepared_stream`
21
40
  - add `DuckDB::Result#streaming?`.
22
41
 
23
- # 0.9.1.2
42
+ # 0.9.1.2 - 2023-11-05
24
43
  - add `DuckDB::Connection#interrupt`, `DuckDB::Connection#query_progress`.
25
44
  - add `DuckDB::Connection#async_query`, alias method `async_execute`.
26
45
 
27
- # 0.9.1.1
46
+ # 0.9.1.1 - 2023-10-29
28
47
  - change default branch to main from master.
29
48
  - add `DuckDB::PendingResult` class.
30
49
  - add `DuckDB::PendingResult#state`.
@@ -35,15 +54,15 @@
35
54
  ## Breaking Changes
36
55
  - drop duckdb v0.7.x.
37
56
 
38
- # 0.9.1
57
+ # 0.9.1 - 2023-10-14
39
58
  - add `DuckDB::PreparedStatement#parameter_name`.
40
59
  - bump duckdb to 0.9.1.
41
60
 
42
- # 0.9.0.1
61
+ # 0.9.0.1 - 2023-10-08
43
62
  - add `DuckDB::PreparedStatement#bind_parameter_index`.
44
63
  - `DuckDB::Connection#query` accepts SQL with named bind parameters.
45
64
 
46
- # 0.9.0
65
+ # 0.9.0 - 2023-09-30
47
66
  - bump duckdb to 0.9.0.
48
67
 
49
68
  ## 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,28 +1,28 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- duckdb (0.9.2.3)
4
+ duckdb (0.10.1.0)
5
5
  bigdecimal (>= 3.1.4)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
10
  benchmark-ips (2.13.0)
11
- bigdecimal (3.1.5)
11
+ bigdecimal (3.1.7)
12
12
  mini_portile2 (2.8.5)
13
- minitest (5.20.0)
14
- nokogiri (1.16.0)
13
+ minitest (5.22.3)
14
+ nokogiri (1.16.3)
15
15
  mini_portile2 (~> 2.8.2)
16
16
  racc (~> 1.4)
17
- nokogiri (1.16.0-x86_64-linux)
17
+ nokogiri (1.16.3-x86_64-linux)
18
18
  racc (~> 1.4)
19
19
  racc (1.7.3)
20
20
  rake (13.1.0)
21
- rake-compiler (1.2.5)
21
+ rake-compiler (1.2.7)
22
22
  rake
23
23
  ruby_memcheck (2.3.0)
24
24
  nokogiri
25
- stackprof (0.2.25)
25
+ stackprof (0.2.26)
26
26
 
27
27
  PLATFORMS
28
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,22 @@ Using `brew install` is recommended.
40
42
  brew install duckdb
41
43
  ```
42
44
 
43
- ## How to Install
45
+ ## Pre-requisite setup (Windows):
46
+
47
+ Using [Ruby + Devkit](https://rubyinstaller.org/downloads/) is recommended.
48
+
49
+ 1. Download libduckdb-windows-amd64.zip from [DuckDB](https://github.com/duckdb/duckdb/releases) and extranct it.
50
+ 2. Copy `duckdb.dll` into `C:\Windows\System32`
51
+
52
+ ## How to install
44
53
 
45
54
  ```sh
46
55
  gem install duckdb
47
56
  ```
48
- > this will work fine with the above pre-requisite setup.
49
57
 
50
- or you must specify the location of the C header and library files:
58
+ After you've run the above pre-requisite setup, this should work fine.
59
+
60
+ If it doesn't, you may have to specify the location of the C header and library files:
51
61
 
52
62
  ```sh
53
63
  gem install duckdb -- --with-duckdb-include=/duckdb_header_directory --with-duckdb-lib=/duckdb_library_directory
@@ -69,7 +79,7 @@ con.query("INSERT into users VALUES(3, 'Cathy')")
69
79
 
70
80
  result = con.query('SELECT * from users')
71
81
  result.each do |row|
72
- p row
82
+ puts row
73
83
  end
74
84
  ```
75
85
 
@@ -88,13 +98,13 @@ DuckDB::Database.open do |db|
88
98
 
89
99
  result = con.query('SELECT * from users')
90
100
  result.each do |row|
91
- p row
101
+ puts row
92
102
  end
93
103
  end
94
104
  end
95
105
  ```
96
106
 
97
- ### using bind variables
107
+ ### Using bind variables
98
108
 
99
109
  You can use bind variables.
100
110
 
@@ -104,12 +114,12 @@ con.query('SELECT * FROM users WHERE name = ? AND email = ?', 'Alice', 'alice@ex
104
114
  con.query('SELECT * FROM users WHERE name = $name AND email = $email', name: 'Alice', email: 'alice@example.com')
105
115
  ```
106
116
 
107
- ### using async query
117
+ ### Using async query
108
118
 
109
119
  You can use async query.
110
120
 
111
121
  ```ruby
112
- DuckDB::Result.use_chunk_each = true # must be true.
122
+ DuckDB::Result.use_chunk_each = true
113
123
  ...
114
124
 
115
125
  pending_result = con.async_query_stream('SLOW QUERY')
@@ -121,9 +131,9 @@ result.each.first
121
131
 
122
132
  Here is [the benchmark](./benchmark/async_query.rb).
123
133
 
124
- ### using BLOB column
134
+ ### Using BLOB column
125
135
 
126
- Use `DuckDB::Blob.new` or use sting#force_encoding(Encoding::BINARY)
136
+ Use `DuckDB::Blob.new` or use string#force_encoding(Encoding::BINARY)
127
137
 
128
138
  ```ruby
129
139
  require 'duckdb'
@@ -134,12 +144,12 @@ DuckDB::Database.open do |db|
134
144
  stmt = DuckDB::PreparedStatement.new(con, 'INSERT INTO blob_table VALUES ($1)')
135
145
 
136
146
  stmt.bind(1, DuckDB::Blob.new("\0\1\2\3\4\5"))
137
- # or
147
+ # or
138
148
  # stmt.bind(1, "\0\1\2\3\4\5".force_encoding(Encoding::BINARY))
139
149
  stmt.execute
140
150
 
141
151
  result = con.query('SELECT binary_data FROM blob_table')
142
- p result.first.first
152
+ puts result.first.first
143
153
  end
144
154
  end
145
155
  ```
@@ -212,14 +222,17 @@ Config class provides Ruby interface of [DuckDB configuration](https://duckdb.or
212
222
 
213
223
  ```ruby
214
224
  require 'duckdb'
225
+
215
226
  config = DuckDB::Config.new
216
227
  config['default_order'] = 'DESC'
228
+
217
229
  db = DuckDB::Database.open(nil, config)
230
+
218
231
  con = db.connect
219
232
  con.query('CREATE TABLE numbers (number INTEGER)')
220
233
  con.query('INSERT INTO numbers VALUES (2), (1), (4), (3)')
221
234
 
222
- # number is ordered by descending.
223
- r = con.query('SELECT number FROM numbers ORDER BY number')
224
- r.first.first # => 4
235
+ # number is ordered by descending
236
+ res = con.query('SELECT number FROM numbers ORDER BY number')
237
+ res.first.first # => 4
225
238
  ```
@@ -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
@@ -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
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'mkmf'
4
4
 
5
- DUCKDB_REQUIRED_VERSION = '0.8.0'
5
+ DUCKDB_REQUIRED_VERSION = '0.9.0'
6
6
 
7
7
  def check_duckdb_header(header, version)
8
8
  found = find_header(
@@ -52,11 +52,11 @@ dir_config('duckdb')
52
52
 
53
53
  check_duckdb_header('duckdb.h', DUCKDB_REQUIRED_VERSION)
54
54
 
55
- # check duckdb >= 0.8.0
56
- check_duckdb_library('duckdb', 'duckdb_string_is_inlined', DUCKDB_REQUIRED_VERSION)
57
-
58
55
  # check duckdb >= 0.9.0
59
- have_func('duckdb_bind_parameter_index', 'duckdb.h')
56
+ check_duckdb_library('duckdb', 'duckdb_bind_parameter_index', DUCKDB_REQUIRED_VERSION)
57
+
58
+ # check duckdb >= 0.10.0
59
+ have_func('duckdb_appender_column_count', 'duckdb.h')
60
60
 
61
61
  # duckdb_parameter_name is not found on Windows.
62
62
  have_func('duckdb_parameter_name', 'duckdb.h')
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.3'
6
+ VERSION = '0.10.1.0'
7
7
  end
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.9.2.3
4
+ version: 0.10.1.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-29 00:00:00.000000000 Z
11
+ date: 2024-03-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bigdecimal
@@ -109,6 +109,7 @@ files:
109
109
  - benchmark/to_bigdecimal_ips.rb
110
110
  - benchmark/to_hugeint_ips.rb
111
111
  - benchmark/to_hugeint_profile.rb
112
+ - benchmark/to_intern_ips.rb
112
113
  - bin/console
113
114
  - bin/setup
114
115
  - docker-compose.yml