duckdb 0.9.2.3 → 0.10.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a636f9cec690ea0c67c8407996c74337e2dfd4a78b3d949e25dcdf4b080e9ad8
4
- data.tar.gz: 7f958a1daa56685544f23d8ac096bae993120b5d9d9562fb55daa915f91516cc
3
+ metadata.gz: e5855147af5fe02372c4bf0f67e5f5c4c046305e3d77fee7d6578d63b7d31aa7
4
+ data.tar.gz: 88701d3c0213ce6fbbe45185f82cbc823d7eb5ee6ff531ab19a720bfd72f3939
5
5
  SHA512:
6
- metadata.gz: 3b4cf27c17979e07133df3fa97b97a47a9cb64f10fdce7bb369cfe3b623b30065d428cc7f36ca16156ea37c433cb94faf12ed311433e8bd4b3fc82954dda9cc0
7
- data.tar.gz: 52362d2a207c0c156a8b32971fd0de8b531b7f9e6f3ad3eb7fc148dff905b6570637eebf30a6b785ca729f147c864b829bd60f4d6ba80f0064f7565b2d0a7eb9
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,30 +1,45 @@
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.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
4
19
  - fix bigdecimal warning with Ruby 3.3.0.
5
20
 
6
- # 0.9.2.2
21
+ # 0.9.2.2 - 2023-12-26
7
22
  - bump Ruby to 3.3.0 on CI.
8
23
 
9
24
  ## Breaking changes
10
25
  - drop Ruby 2.7.
11
26
 
12
- # 0.9.2.1
27
+ # 0.9.2.1 - 2023-12-24
13
28
  - support Time column in `DuckDB#Result#chunk_each`.
14
29
  - add `DuckDB::Interval#eql?`.
15
30
 
16
- # 0.9.2
31
+ # 0.9.2 - 2023-11-26
17
32
  - add `DuckDB::Connection#async_query_stream`.
18
33
  - `DuckDB::PendingResult` accepts second argument. If the second argument is
19
34
  true, `PendingResult#execute_pending` returns streaming `DuckDB::Result` object.
20
35
  - add `DuckDB::PreparedStatement#pending_prepared_stream`
21
36
  - add `DuckDB::Result#streaming?`.
22
37
 
23
- # 0.9.1.2
38
+ # 0.9.1.2 - 2023-11-05
24
39
  - add `DuckDB::Connection#interrupt`, `DuckDB::Connection#query_progress`.
25
40
  - add `DuckDB::Connection#async_query`, alias method `async_execute`.
26
41
 
27
- # 0.9.1.1
42
+ # 0.9.1.1 - 2023-10-29
28
43
  - change default branch to main from master.
29
44
  - add `DuckDB::PendingResult` class.
30
45
  - add `DuckDB::PendingResult#state`.
@@ -35,15 +50,15 @@
35
50
  ## Breaking Changes
36
51
  - drop duckdb v0.7.x.
37
52
 
38
- # 0.9.1
53
+ # 0.9.1 - 2023-10-14
39
54
  - add `DuckDB::PreparedStatement#parameter_name`.
40
55
  - bump duckdb to 0.9.1.
41
56
 
42
- # 0.9.0.1
57
+ # 0.9.0.1 - 2023-10-08
43
58
  - add `DuckDB::PreparedStatement#bind_parameter_index`.
44
59
  - `DuckDB::Connection#query` accepts SQL with named bind parameters.
45
60
 
46
- # 0.9.0
61
+ # 0.9.0 - 2023-09-30
47
62
  - bump duckdb to 0.9.0.
48
63
 
49
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,28 +1,28 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- duckdb (0.9.2.3)
4
+ duckdb (0.10.0.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.6)
12
12
  mini_portile2 (2.8.5)
13
- minitest (5.20.0)
14
- nokogiri (1.16.0)
13
+ minitest (5.22.2)
14
+ nokogiri (1.16.2)
15
15
  mini_portile2 (~> 2.8.2)
16
16
  racc (~> 1.4)
17
- nokogiri (1.16.0-x86_64-linux)
17
+ nokogiri (1.16.2-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,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
@@ -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.3'
6
+ VERSION = '0.10.0.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.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-29 00:00:00.000000000 Z
11
+ date: 2024-02-17 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