duckdb 0.7.0 → 0.8.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: d4780513bea94513e38b460cf9580b9bad9b9128d913a46f58f2054451cf838d
4
- data.tar.gz: 5cbfe5da32da9562d121d634a7a45fdc153222bb4c5b8c79a2f37dbff6f57f27
3
+ metadata.gz: 8e8040d795ad975b4472fe439aa2cfb403ad5f24f9c602bca7dbdf6103c37b65
4
+ data.tar.gz: 82cd61d78fec67f62be8ad0280305b224ae605ffd2ea453855168dcaa77f4d32
5
5
  SHA512:
6
- metadata.gz: 04acc6297bac9ae7d217072d1fec3b7c603f407270143d654f738462e0f540a2e8ebdb67fa4d466ff13636dab279a0d245241201c9b3f829f4e97fbf628fb086
7
- data.tar.gz: aa200fce49d05edee27095771e4c7e394a7431b8b1881e58d053f46dafc628920e4924c899159619c2fd337c6607eeed55f5863ea0e119f13ec2236d72c33f6b
6
+ metadata.gz: b54b53aa6ec96ef9e8607bea7f96b8ef9fc7c4e2189675e575eeabdfaa2d608320c02ac86dc8ca7453cd9d314ceb943241a0a858689c85b8221374ff5dc6e00e
7
+ data.tar.gz: 86936495132694846dd8931998c9f716d405571dd34842f6f8563ad531f2e0b8fb678f4477cff9ec33a1c0d3affc615884a4dd8063909f57cb8e4a1da2a0434f
@@ -15,8 +15,8 @@ jobs:
15
15
  runs-on: macos-latest
16
16
  strategy:
17
17
  matrix:
18
- ruby: ['2.7.7', '3.0.5', '3.1.3', '3.2.1', 'head']
19
- duckdb: ['0.7.0', '0.6.1']
18
+ ruby: ['2.7.8', '3.0.6', '3.1.4', '3.2.2', 'head']
19
+ duckdb: ['0.7.1', '0.8.0']
20
20
 
21
21
  steps:
22
22
  - uses: actions/checkout@v3
@@ -52,11 +52,14 @@ jobs:
52
52
  cp duckdb-v$DUCKDB_VERSION/src/include/*.h /usr/local/include
53
53
  cp duckdb-v$DUCKDB_VERSION/build/release/src/*.dylib /usr/local/lib
54
54
 
55
- - name: Build and test with Rake with Ruby ${{ matrix.ruby }}
55
+ - name: Build with Ruby ${{ matrix.ruby }}
56
56
  run: |
57
- ruby -v
58
57
  bundle install --jobs 4 --retry 3
59
- bundle exec rake
58
+ rake build
59
+
60
+ - name: run test with Ruby ${{ matrix.ruby }}
61
+ run: |
62
+ rake test
60
63
 
61
64
  post-test:
62
65
  name: All tests passed on macos
@@ -15,8 +15,8 @@ jobs:
15
15
  runs-on: ubuntu-latest
16
16
  strategy:
17
17
  matrix:
18
- ruby: ['2.7.7', '3.0.5', '3.1.3', '3.2.1', 'head']
19
- duckdb: ['0.7.0', '0.6.1']
18
+ ruby: ['2.7.8', '3.0.6', '3.1.4', '3.2.2', 'head']
19
+ duckdb: ['0.7.1', '0.8.0']
20
20
 
21
21
  steps:
22
22
  - uses: actions/checkout@v3
@@ -45,13 +45,19 @@ jobs:
45
45
  cp -rip duckdb-tmp-v$DUCKDB_VERSION/build/release/src/*.so duckdb-v$DUCKDB_VERSION/build/release/src
46
46
  cp -rip duckdb-tmp-v$DUCKDB_VERSION/src/include duckdb-v$DUCKDB_VERSION/src/
47
47
 
48
- - name: Build and test with Rake with Ruby ${{ matrix.ruby }}
48
+ - name: Build with Ruby ${{ matrix.ruby }}
49
49
  env:
50
50
  DUCKDB_VERSION: ${{ matrix.duckdb }}
51
51
  run: |
52
52
  gem install bundler
53
53
  bundle install --jobs 4 --retry 3
54
- bundle exec rake -- --with-duckdb-include=${GITHUB_WORKSPACE}/duckdb-v${DUCKDB_VERSION}/src/include --with-duckdb-lib=${GITHUB_WORKSPACE}/duckdb-v${DUCKDB_VERSION}/build/release/src/
54
+ bundle exec rake build -- --with-duckdb-include=${GITHUB_WORKSPACE}/duckdb-v${DUCKDB_VERSION}/src/include --with-duckdb-lib=${GITHUB_WORKSPACE}/duckdb-v${DUCKDB_VERSION}/build/release/src/
55
+
56
+ - name: test with Ruby ${{ matrix.ruby }}
57
+ env:
58
+ DUCKDB_VERSION: ${{ matrix.duckdb }}
59
+ run: |
60
+ rake test
55
61
 
56
62
  post-test:
57
63
  name: All tests passed on Ubuntu
@@ -15,8 +15,8 @@ jobs:
15
15
  runs-on: windows-latest
16
16
  strategy:
17
17
  matrix:
18
- ruby: ['2.7.7', '3.0.5', '3.1.3', '3.2.1', 'ucrt', 'mingw', 'mswin', 'head']
19
- duckdb: ['0.7.0', '0.6.1']
18
+ ruby: ['2.7.8', '3.0.6', '3.1.4', '3.2.2', 'ucrt', 'mingw', 'mswin', 'head']
19
+ duckdb: ['0.7.1', '0.8.0']
20
20
 
21
21
  steps:
22
22
  - uses: actions/checkout@v3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # ChangeLog
2
2
 
3
+ # 0.8.0
4
+ - bump duckdb to 0.8.0
5
+ - add DuckDB::Result#_to_decimal_internal
6
+ - add DuckDB::Result#_to_hugeint_internal
7
+
8
+ ## Breaking Change
9
+ - DuckDB::Result returns BigDecimal object instead of String object if the column type is DECIMAL.
10
+
11
+ # 0.7.1
12
+ - bump duckdb to 0.7.1
13
+ - fix docker build error on M1 Mac
14
+
3
15
  # 0.7.0
4
16
  - bump duckdb to 0.7.0
5
17
  - fix have_func argument order
data/CONTRIBUTION.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # Contribution Guide
2
2
 
3
+ ## Environment setup
4
+
5
+ ### With docker
6
+
7
+ 1. Fork the repository and `git clone` to your local machine.
8
+ 2. Build and access to docker container
9
+
10
+ ```
11
+ docker-compose build ubuntu
12
+ docker-compose run --rm ubuntu bash
13
+ ```
14
+
15
+ In case you want custom ruby or duckdb versions, use `--build-arg` options
16
+ ```
17
+ docker-compose build ubuntu --build-arg RUBY_VERSION=3.1.3 --build-arg DUCKDB_VERSION=0.6.0
18
+ ```
19
+
20
+ ### Without docker
21
+
22
+ 1. Install [Ruby](https://www.ruby-lang.org/) into your local machine.
23
+ 2. Install [duckdb](https://duckdb.org/) into your local machine.
24
+ 3. Fork the repository and `git clone` to your local machine.
25
+ 4. Run `bundle install`
26
+ 5. Run `rake build`
27
+ or you might run with C duckdb header and library directories:
28
+ `rake build -- --with-duckdb-include=/duckdb_header_directory --with-duckdb-lib=/duckdb_library_directory`
29
+
30
+
3
31
  ## Issue
4
32
 
5
33
  If you spot a problem, [search if an issue already exists](https://github.com/suketa/ruby-duckdb/issues).
@@ -8,17 +36,10 @@ If a related issue doesn't exist, you can open a [new issue](https://github.com/
8
36
 
9
37
  ## Fix Issues or Add New Features.
10
38
 
11
- 1. install [Ruby](https://www.ruby-lang.org/) into your local machine.
12
- 2. install [duckdb](https://duckdb.org/) into your local machine.
13
- 3. fork the repository and `git clone` to your local machine.
14
- 4. run `bundle install`
15
- 5. run `rake build`
16
- or you might run with C duckdb header and library directories:
17
- `rake build -- --with-duckdb-include=/duckdb_header_directory --with-duckdb-lib=/duckdb_library_directory`
18
- 6. run `rake test`
19
- 7. create new branch to change the code.
20
- 8. change the code.
21
- 9. write test.
22
- 10. run `rake test` and confirm all tests pass.
23
- 11. git push.
24
- 12. create PR.
39
+ 1. Run `rake test`
40
+ 2. Create new branch to change the code.
41
+ 3. Change the code.
42
+ 4. Write test.
43
+ 5. Run `rake test` and confirm all tests pass.
44
+ 6. Git push.
45
+ 7. Create PR.
data/Dockerfile ADDED
@@ -0,0 +1,21 @@
1
+ ARG RUBY_VERSION=3.2.1
2
+ FROM ruby:${RUBY_VERSION}
3
+
4
+ ARG DUCKDB_VERSION=0.7.1
5
+
6
+ RUN apt update -qq && \
7
+ apt install -y build-essential curl git wget
8
+
9
+ COPY getduckdb.sh .
10
+ RUN ./getduckdb.sh
11
+
12
+ RUN unzip duckdb.zip -d libduckdb
13
+ RUN mv libduckdb/duckdb.* /usr/local/include
14
+ RUN mv libduckdb/libduckdb.so /usr/local/lib
15
+ RUN ldconfig /usr/local/lib
16
+
17
+ COPY . /root/ruby-duckdb
18
+ WORKDIR /root/ruby-duckdb
19
+ RUN git config --global --add safe.directory /root/ruby-duckdb
20
+ RUN bundle install
21
+ RUN rake build
data/Gemfile CHANGED
@@ -2,3 +2,8 @@ source "https://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in duckdb.gemspec
4
4
  gemspec
5
+
6
+ if /(linux|darwin)/ =~ RUBY_PLATFORM
7
+ gem 'benchmark-ips'
8
+ gem 'stackprof'
9
+ end
data/Gemfile.lock CHANGED
@@ -1,26 +1,30 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- duckdb (0.7.0)
4
+ duckdb (0.8.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- minitest (5.17.0)
9
+ benchmark-ips (2.12.0)
10
+ minitest (5.18.0)
10
11
  rake (13.0.6)
11
12
  rake-compiler (1.2.1)
12
13
  rake
14
+ stackprof (0.2.24)
13
15
 
14
16
  PLATFORMS
15
17
  ruby
16
18
  x86_64-linux
17
19
 
18
20
  DEPENDENCIES
21
+ benchmark-ips
19
22
  bundler (~> 2.3)
20
23
  duckdb!
21
24
  minitest (~> 5.0)
22
25
  rake (~> 13.0)
23
26
  rake-compiler
27
+ stackprof
24
28
 
25
29
  BUNDLED WITH
26
- 2.3.22
30
+ 2.4.9
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ require 'duckdb'
5
+ require 'benchmark/ips'
6
+
7
+ db = DuckDB::Database.open
8
+ con = db.connect
9
+ con.query('CREATE TABLE decimals (decimal_value DECIMAL(38, 3))')
10
+ con.query('INSERT INTO decimals VALUES (1234567890123.456)')
11
+ result = con.query('SELECT decimal_value FROM decimals')
12
+
13
+ Benchmark.ips do |x|
14
+ x.report('_to_decimal') { result.send(:_to_decimal, 0, 0) }
15
+ x.report('_to_decimal_internal') { result.send(:_to_decimal_internal, 0, 0) }
16
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ require 'duckdb'
5
+ require 'benchmark/ips'
6
+
7
+ db = DuckDB::Database.open
8
+ con = db.connect
9
+ con.query('CREATE TABLE hugeints (hugeint_value HUGEINT)')
10
+ con.query('INSERT INTO hugeints VALUES (123456789012345678901234567890123456789)')
11
+ result = con.query('SELECT hugeint_value FROM hugeints')
12
+
13
+ Benchmark.ips do |x|
14
+ x.report('_to_hugeint') { result.send(:_to_hugeint, 0, 0) }
15
+ x.report('_to_hugeint_internal') { result.send(:_to_hugeint_internal, 0, 0) }
16
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ require 'duckdb'
5
+ require 'stackprof'
6
+
7
+ db = DuckDB::Database.open
8
+ con = db.connect
9
+ con.query('CREATE TABLE hugeints (hugeint_value HUGEINT)')
10
+ con.query('INSERT INTO hugeints VALUES (123456789012345678901234567890123456789)')
11
+ result = con.query('SELECT hugeint_value FROM hugeints')
12
+
13
+ def profile(name, &block)
14
+ profile = StackProf.run(mode: :wall, interval: 1_000) do
15
+ 2_000_000.times(&block)
16
+ end
17
+
18
+ result = StackProf::Report.new(profile)
19
+ puts
20
+ puts "=== #{name} ==="
21
+ result.print_text
22
+ puts
23
+ end
24
+
25
+ profile(:_to_hugeint) { result.send(:_to_hugeint, 0, 0) }
26
+ profile(:_to_hugeint_internal) { result.send(:_to_hugeint_internal, 0, 0) }
@@ -0,0 +1,12 @@
1
+ version: '3'
2
+ services:
3
+ ubuntu:
4
+ build:
5
+ context: .
6
+ dockerfile: ./Dockerfile
7
+ args:
8
+ - RUBY_VERSION
9
+ - DUCKDB_VERSION
10
+ working_dir: /root/ruby-duckdb
11
+ volumes:
12
+ - .:/root/ruby-duckdb
@@ -22,13 +22,10 @@ dir_config('duckdb')
22
22
 
23
23
  check_duckdb_library('duckdb_pending_prepared', '0.5.0')
24
24
 
25
- # check duckdb >= 0.3.3
26
- # ducdb >= 0.3.3 if duckdb_append_data_chunk() is defined.
27
- have_func('duckdb_append_data_chunk', 'duckdb.h')
28
-
29
25
  # check duckdb >= 0.6.0
30
26
  have_func('duckdb_value_string', 'duckdb.h')
31
27
 
32
- have_func('duckdb_free', 'duckdb.h')
28
+ # check duckdb >= 0.7.0
29
+ have_func('duckdb_extract_statements', 'duckdb.h')
33
30
 
34
31
  create_makefile('duckdb/duckdb_native')
@@ -68,7 +68,7 @@ static VALUE duckdb_prepared_statement_initialize(VALUE self, VALUE con, VALUE q
68
68
  static VALUE duckdb_prepared_statement_nparams(VALUE self) {
69
69
  rubyDuckDBPreparedStatement *ctx;
70
70
  TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
71
- return rb_int2big(duckdb_nparams(ctx->prepared_statement));
71
+ return ULL2NUM(duckdb_nparams(ctx->prepared_statement));
72
72
  }
73
73
 
74
74
 
@@ -86,7 +86,7 @@ static VALUE duckdb_prepared_statement_execute(VALUE self) {
86
86
  }
87
87
 
88
88
  static idx_t check_index(VALUE vidx) {
89
- idx_t idx = FIX2INT(vidx);
89
+ idx_t idx = NUM2ULL(vidx);
90
90
  if (idx <= 0) {
91
91
  rb_raise(rb_eArgError, "index of parameter must be greater than 0");
92
92
  }
data/ext/duckdb/result.c CHANGED
@@ -87,7 +87,7 @@ static VALUE to_ruby_obj_integer(duckdb_result *result, idx_t col_idx, idx_t row
87
87
 
88
88
  static VALUE to_ruby_obj_bigint(duckdb_result *result, idx_t col_idx, idx_t row_idx) {
89
89
  int64_t i64val = duckdb_value_int64(result, col_idx, row_idx);
90
- return rb_int2big(i64val);
90
+ return LL2NUM(i64val);
91
91
  }
92
92
 
93
93
  static VALUE to_ruby_obj_hugeint(duckdb_result *result, idx_t col_idx, idx_t row_idx) {
@@ -4,14 +4,14 @@
4
4
  #include "ruby.h"
5
5
  #include <duckdb.h>
6
6
 
7
- #ifdef HAVE_DUCKDB_APPEND_DATA_CHUNK
8
- #define HAVE_DUCKDB_H_GE_V033 1
9
- #endif
10
-
11
7
  #ifdef HAVE_DUCKDB_VALUE_STRING
12
8
  #define HAVE_DUCKDB_H_GE_V060 1
13
9
  #endif
14
10
 
11
+ #ifdef HAVE_DUCKDB_EXTRACT_STATEMENTS
12
+ #define HAVE_DUCKDB_H_GE_V070 1
13
+ #endif
14
+
15
15
  #include "./error.h"
16
16
  #include "./database.h"
17
17
  #include "./connection.h"
data/getduckdb.sh ADDED
@@ -0,0 +1,10 @@
1
+ #!/bin/sh
2
+
3
+ MACHINE=`uname -m`
4
+
5
+ case "$MACHINE" in
6
+ "x86_64" ) ARC=amd64 ;;
7
+ "aarch64" ) ARC=aarch64 ;;
8
+ esac
9
+
10
+ wget -O duckdb.zip "https://github.com/duckdb/duckdb/releases/download/v$DUCKDB_VERSION/libduckdb-linux-$ARC.zip"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'date'
2
4
  require 'time'
3
5
  require_relative './converter'
data/lib/duckdb/column.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DuckDB
2
4
  class Column
3
5
  #
data/lib/duckdb/config.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DuckDB
2
4
  if defined?(DuckDB::Config)
3
5
  # The DuckDB::Config encapsulates DuckDB Configuration.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DuckDB
2
4
  # The DuckDB::Connection encapsulates connection with DuckDB database.
3
5
  #
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DuckDB
2
4
  module Converter
3
5
  HALF_HUGEINT = 1 << 64
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DuckDB
2
4
  # The Database class encapsulates a DuckDB database.
3
5
  #
@@ -1,4 +1,5 @@
1
1
  require 'date'
2
+ require 'bigdecimal'
2
3
  require_relative './converter'
3
4
 
4
5
  module DuckDB
@@ -192,6 +193,8 @@ module DuckDB
192
193
  bind_varchar(i, value.strftime('%Y-%m-%d %H:%M:%S.%N'))
193
194
  when Date
194
195
  bind_varchar(i, value.strftime('%Y-%m-%d'))
196
+ when BigDecimal
197
+ bind_varchar(i, value.to_s('F'))
195
198
  else
196
199
  raise(DuckDB::Error, "not supported type `#{value}` (#{value.class})")
197
200
  end
data/lib/duckdb/result.rb CHANGED
@@ -1,3 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bigdecimal'
4
+
1
5
  module DuckDB
2
6
  # The Result class encapsulates a execute result of DuckDB database.
3
7
  #
@@ -28,8 +32,9 @@ module DuckDB
28
32
  5 => :_to_bigint,
29
33
  10 => :_to_float,
30
34
  11 => :_to_double,
31
- 16 => :_to_hugeint,
35
+ 16 => :_to_hugeint_internal,
32
36
  18 => :_to_blob,
37
+ 19 => :_to_decimal_internal
33
38
  }
34
39
 
35
40
  ToRuby.default = :_to_string
@@ -70,5 +75,21 @@ module DuckDB
70
75
  def _to_hugeint(row, col)
71
76
  _to_string(row, col).to_i
72
77
  end
78
+
79
+ def _to_hugeint_internal(row, col)
80
+ lower, upper = __to_hugeint_internal(row, col)
81
+ upper * Converter::HALF_HUGEINT + lower
82
+ end
83
+
84
+ def _to_decimal(row, col)
85
+ BigDecimal(_to_string(row, col))
86
+ end
87
+
88
+ def _to_decimal_internal(row, col)
89
+ lower, upper, _width, scale = __to_decimal_internal(row, col)
90
+ v = (upper * Converter::HALF_HUGEINT + lower).to_s
91
+ v[-scale, 0] = '.'
92
+ BigDecimal(v)
93
+ end
73
94
  end
74
95
  end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DuckDB
2
4
  # The version string of ruby-duckdb.
3
5
  # Currently, ruby-duckdb is NOT semantic versioning.
4
- VERSION = '0.7.0'.freeze
6
+ VERSION = '0.8.0'.freeze
5
7
  end
data/lib/duckdb.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'duckdb/duckdb_native'
2
4
  require 'duckdb/library_version'
3
5
  require 'duckdb/version'
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.7.0
4
+ version: 0.8.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-02-18 00:00:00.000000000 Z
11
+ date: 2023-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -81,13 +81,18 @@ files:
81
81
  - ".gitignore"
82
82
  - CHANGELOG.md
83
83
  - CONTRIBUTION.md
84
+ - Dockerfile
84
85
  - Gemfile
85
86
  - Gemfile.lock
86
87
  - LICENSE
87
88
  - README.md
88
89
  - Rakefile
90
+ - benchmark/to_bigdecimal_ips.rb
91
+ - benchmark/to_hugeint_ips.rb
92
+ - benchmark/to_hugeint_profile.rb
89
93
  - bin/console
90
94
  - bin/setup
95
+ - docker-compose.yml
91
96
  - duckdb.gemspec
92
97
  - ext/duckdb/appender.c
93
98
  - ext/duckdb/appender.h
@@ -112,6 +117,7 @@ files:
112
117
  - ext/duckdb/ruby-duckdb.h
113
118
  - ext/duckdb/util.c
114
119
  - ext/duckdb/util.h
120
+ - getduckdb.sh
115
121
  - lib/duckdb.rb
116
122
  - lib/duckdb/appender.rb
117
123
  - lib/duckdb/column.rb
@@ -145,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
145
151
  - !ruby/object:Gem::Version
146
152
  version: '0'
147
153
  requirements: []
148
- rubygems_version: 3.4.6
154
+ rubygems_version: 3.4.10
149
155
  signing_key:
150
156
  specification_version: 4
151
157
  summary: This module is Ruby binding for DuckDB database engine.