duckdb 0.8.1 → 0.8.1.2

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: dab5e8d5f3beafce29f2d545b736b34b3502f2f31120d1d7d0714fdb83512457
4
- data.tar.gz: a73a7438ec5762af143b8590923b0fd3c54ec99926aa48b485346e943fe66916
3
+ metadata.gz: def2e5adaab85bedca1363e7c527640eeb7f2cc2938c4bac219b026d8d79e895
4
+ data.tar.gz: 2f058e71abd48266432f7486bed43a67fa8ef5e8955ccc150c27a64e023fb7d5
5
5
  SHA512:
6
- metadata.gz: de0988a48ae0e9652d8411ce52265835e6d63c30f53c181cc25066d7fbae26ff9a54290e014c66aa44f6a3f87b9e5da7fa3acee6f0051c1b886cb6ea5e68d4bb
7
- data.tar.gz: 0edd9bfe15f0e47da50e860732acecc897a9cbba716218da5de80188be7bf43df5f1300d3419e501532a7d26cc42a1c79d76835cb3a1a956e7b06d7842b40c20
6
+ metadata.gz: 388302d5e187b6f8f85877c0cfd2613e78047ba78484067e99e8fe1a6cee16ca61a59918ae4d9090b4b9029e8594f0c4f63e2d9855f3f3a931979b51430ecd8f
7
+ data.tar.gz: 27418556352f19324ebc8e90cae28972f05965cd2394dccd92836ccf1dd044604f2e1045ebdb7f05b28afeec493de07fa1d060dde3c3367a60fbcf4fee30038f
data/CHANGELOG.md CHANGED
@@ -1,7 +1,22 @@
1
1
  # ChangeLog
2
2
 
3
+ # 0.8.1.2
4
+ - Fix BigDecimal conversion when the value is 0.
5
+ Thanks to shreeve.
6
+
7
+ # 0.8.1.1
8
+ - DuckDB::Result#chunk_each supports:
9
+ - UTINYINT
10
+ - USMALLINT
11
+ - UINTEGER
12
+ - UBIGINT
13
+ - fix memory leak of:
14
+ - `DuckDB::Result#_enum_dictionary_value`
15
+ - `DuckDB::Result#_enum_dictionary_size`
16
+ - `DuckDB::Result#_enum_internal_type`
17
+
3
18
  # 0.8.1
4
- - bump duckdb to 0.8.1
19
+ - bump duckdb to 0.8.1.
5
20
  - add `DuckDB::Result#chunk_each`, `DuckDB::Result.use_chunk_each=`, `DuckDB::Result#use_chunk_each?`
6
21
  The current behavior of `DuckDB::Result#each` is same as older version.
7
22
  But `DuckDB::Result#each` behavior will be changed like as `DuckDB::Result#chunk_each` in near future release.
data/Gemfile CHANGED
@@ -7,3 +7,7 @@ if /(linux|darwin)/ =~ RUBY_PLATFORM
7
7
  gem 'benchmark-ips'
8
8
  gem 'stackprof'
9
9
  end
10
+
11
+ if /linux/ =~ RUBY_PLATFORM
12
+ gem 'ruby_memcheck'
13
+ end
data/Gemfile.lock CHANGED
@@ -1,16 +1,25 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- duckdb (0.8.1)
4
+ duckdb (0.8.1.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
9
  benchmark-ips (2.12.0)
10
+ mini_portile2 (2.8.2)
10
11
  minitest (5.18.1)
12
+ nokogiri (1.15.3)
13
+ mini_portile2 (~> 2.8.2)
14
+ racc (~> 1.4)
15
+ nokogiri (1.15.3-x86_64-linux)
16
+ racc (~> 1.4)
17
+ racc (1.7.1)
11
18
  rake (13.0.6)
12
19
  rake-compiler (1.2.3)
13
20
  rake
21
+ ruby_memcheck (1.3.2)
22
+ nokogiri
14
23
  stackprof (0.2.25)
15
24
 
16
25
  PLATFORMS
@@ -24,7 +33,8 @@ DEPENDENCIES
24
33
  minitest (~> 5.0)
25
34
  rake (~> 13.0)
26
35
  rake-compiler
36
+ ruby_memcheck
27
37
  stackprof
28
38
 
29
39
  BUNDLED WITH
30
- 2.4.10
40
+ 2.4.17
data/Rakefile CHANGED
@@ -1,19 +1,41 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+ ruby_memcheck_avaiable = begin
4
+ require 'ruby_memcheck'
5
+ true
6
+ rescue LoadError
7
+ false
8
+ end
3
9
 
4
- Rake::TestTask.new(:test) do |t|
5
- t.libs << "test"
6
- t.libs << "lib"
7
- t.test_files = FileList["test/**/*_test.rb"]
10
+
11
+ if ruby_memcheck_avaiable
12
+ RubyMemcheck.config(
13
+ binary_name: 'duckdb/duckdb_native',
14
+ valgrind_options: ['--max-threads=1000']
15
+ )
16
+ end
17
+
18
+ test_config = lambda do |t|
19
+ t.libs << 'test'
20
+ t.libs << 'lib'
21
+ t.test_files = FileList['test/**/*_test.rb']
22
+ end
23
+
24
+ Rake::TestTask.new(test: :compile, &test_config)
25
+
26
+ if ruby_memcheck_avaiable
27
+ namespace :test do
28
+ RubyMemcheck::TestTask.new(valgrind: :compile, &test_config)
29
+ end
8
30
  end
9
31
 
10
- require "rake/extensiontask"
32
+ require 'rake/extensiontask'
11
33
 
12
- task :build => :compile
34
+ task build: :compile
13
35
 
14
- Rake::ExtensionTask.new("duckdb_native") do |ext|
36
+ Rake::ExtensionTask.new('duckdb_native') do |ext|
15
37
  ext.ext_dir = 'ext/duckdb'
16
- ext.lib_dir = "lib/duckdb"
38
+ ext.lib_dir = 'lib/duckdb'
17
39
  end
18
40
 
19
- task :default => [:clobber, :compile, :test]
41
+ task default: %i[clobber compile test]
@@ -0,0 +1,26 @@
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_val HUGEINT)')
10
+ con.query('INSERT INTO hugeints VALUES (1234567890123456789012345678901234)')
11
+ result = con.query('SELECT hugeint_val FROM hugeints')
12
+
13
+ Benchmark.ips do |x|
14
+ x.report('hugeint_convert') { result.each.to_a[0][0] }
15
+ end
16
+
17
+ __END__
18
+
19
+ ## before
20
+ ```
21
+ ✦ ❯ ruby benchmark/get_converter_module_ips.rb
22
+ Warming up --------------------------------------
23
+ hugeint_convert 45.376k i/100ms
24
+ Calculating -------------------------------------
25
+ hugeint_convert 552.127k (± 0.7%) i/s - 2.768M in 5.013483s
26
+ ```
@@ -0,0 +1,6 @@
1
+ #ifndef RUBY_DUCKDB_CONVERTER_H
2
+ #define RUBY_DUCKDB_CONVERTER_H
3
+
4
+ void init_duckdb_converter(void);
5
+
6
+ #endif
@@ -0,0 +1,7 @@
1
+ #include "ruby-duckdb.h"
2
+
3
+ VALUE mDuckDBConverter;
4
+
5
+ void init_duckdb_converter(void) {
6
+ mDuckDBConverter = rb_define_module_under(mDuckDB, "Converter");
7
+ }
data/ext/duckdb/duckdb.c CHANGED
@@ -23,4 +23,5 @@ Init_duckdb_native(void) {
23
23
  init_duckdb_blob();
24
24
  init_duckdb_appender();
25
25
  init_duckdb_config();
26
+ init_duckdb_converter();
26
27
  }
data/ext/duckdb/result.c CHANGED
@@ -362,6 +362,7 @@ static VALUE duckdb_result__enum_internal_type(VALUE oDuckDBResult, VALUE col_id
362
362
  if (logical_type) {
363
363
  type = LL2NUM(duckdb_enum_internal_type(logical_type));
364
364
  }
365
+ duckdb_destroy_logical_type(&logical_type);
365
366
  return type;
366
367
  }
367
368
 
@@ -375,6 +376,7 @@ static VALUE duckdb_result__enum_dictionary_size(VALUE oDuckDBResult, VALUE col_
375
376
  if (logical_type) {
376
377
  size = UINT2NUM(duckdb_enum_dictionary_size(logical_type));
377
378
  }
379
+ duckdb_destroy_logical_type(&logical_type);
378
380
  return size;
379
381
  }
380
382
 
@@ -393,6 +395,7 @@ static VALUE duckdb_result__enum_dictionary_value(VALUE oDuckDBResult, VALUE col
393
395
  duckdb_free(p);
394
396
  }
395
397
  }
398
+ duckdb_destroy_logical_type(&logical_type);
396
399
  return value;
397
400
  }
398
401
 
@@ -403,9 +406,8 @@ VALUE create_result(void) {
403
406
  #ifdef HAVE_DUCKDB_H_GE_V080
404
407
  static VALUE vector_date(void *vector_data, idx_t row_idx) {
405
408
  duckdb_date_struct date = duckdb_from_date(((duckdb_date *) vector_data)[row_idx]);
406
- VALUE mConverter = rb_const_get(mDuckDB, rb_intern("Converter"));
407
409
 
408
- return rb_funcall(mConverter, rb_intern("_to_date"), 3,
410
+ return rb_funcall(mDuckDBConverter, rb_intern("_to_date"), 3,
409
411
  INT2FIX(date.year),
410
412
  INT2FIX(date.month),
411
413
  INT2FIX(date.day)
@@ -414,8 +416,7 @@ static VALUE vector_date(void *vector_data, idx_t row_idx) {
414
416
 
415
417
  static VALUE vector_timestamp(void* vector_data, idx_t row_idx) {
416
418
  duckdb_timestamp_struct data = duckdb_from_timestamp(((duckdb_timestamp *)vector_data)[row_idx]);
417
- VALUE mConverter = rb_const_get(mDuckDB, rb_intern("Converter"));
418
- return rb_funcall(mConverter, rb_intern("_to_time"), 7,
419
+ return rb_funcall(mDuckDBConverter, rb_intern("_to_time"), 7,
419
420
  INT2FIX(data.date.year),
420
421
  INT2FIX(data.date.month),
421
422
  INT2FIX(data.date.day),
@@ -428,8 +429,7 @@ static VALUE vector_timestamp(void* vector_data, idx_t row_idx) {
428
429
 
429
430
  static VALUE vector_interval(void* vector_data, idx_t row_idx) {
430
431
  duckdb_interval data = ((duckdb_interval *)vector_data)[row_idx];
431
- VALUE mConverter = rb_const_get(mDuckDB, rb_intern("Converter"));
432
- return rb_funcall(mConverter, rb_intern("_to_interval_from_vector"), 3,
432
+ return rb_funcall(mDuckDBConverter, rb_intern("_to_interval_from_vector"), 3,
433
433
  INT2NUM(data.months),
434
434
  INT2NUM(data.days),
435
435
  LL2NUM(data.micros)
@@ -456,8 +456,7 @@ static VALUE vector_varchar(void* vector_data, idx_t row_idx) {
456
456
 
457
457
  static VALUE vector_hugeint(void* vector_data, idx_t row_idx) {
458
458
  duckdb_hugeint hugeint = ((duckdb_hugeint *)vector_data)[row_idx];
459
- VALUE mConverter = rb_const_get(mDuckDB, rb_intern("Converter"));
460
- return rb_funcall(mConverter, rb_intern("_to_hugeint_from_vector"), 2,
459
+ return rb_funcall(mDuckDBConverter, rb_intern("_to_hugeint_from_vector"), 2,
461
460
  ULL2NUM(hugeint.lower),
462
461
  LL2NUM(hugeint.upper)
463
462
  );
@@ -466,7 +465,6 @@ static VALUE vector_hugeint(void* vector_data, idx_t row_idx) {
466
465
  static VALUE vector_decimal(duckdb_logical_type ty, void* vector_data, idx_t row_idx) {
467
466
  uint8_t width = duckdb_decimal_width(ty);
468
467
  uint8_t scale = duckdb_decimal_scale(ty);
469
- VALUE mConverter = rb_const_get(mDuckDB, rb_intern("Converter"));
470
468
  duckdb_type type = duckdb_decimal_internal_type(ty);
471
469
  duckdb_hugeint value;
472
470
 
@@ -481,7 +479,7 @@ static VALUE vector_decimal(duckdb_logical_type ty, void* vector_data, idx_t row
481
479
  rb_warn("Unknown decimal internal type %d", type);
482
480
  }
483
481
 
484
- return rb_funcall(mConverter, rb_intern("_to_decimal_from_vector"), 4,
482
+ return rb_funcall(mDuckDBConverter, rb_intern("_to_decimal_from_vector"), 4,
485
483
  INT2FIX(width),
486
484
  INT2FIX(scale),
487
485
  ULL2NUM(value.lower),
@@ -581,8 +579,7 @@ static VALUE vector_struct(duckdb_logical_type ty, duckdb_vector vector, idx_t r
581
579
 
582
580
  static VALUE vector_uuid(void* vector_data, idx_t row_idx) {
583
581
  duckdb_hugeint hugeint = ((duckdb_hugeint *)vector_data)[row_idx];
584
- VALUE mConverter = rb_const_get(mDuckDB, rb_intern("Converter"));
585
- return rb_funcall(mConverter, rb_intern("_to_uuid_from_vector"), 2,
582
+ return rb_funcall(mDuckDBConverter, rb_intern("_to_uuid_from_vector"), 2,
586
583
  ULL2NUM(hugeint.lower),
587
584
  LL2NUM(hugeint.upper)
588
585
  );
@@ -623,6 +620,18 @@ static VALUE vector_value(duckdb_vector vector, idx_t row_idx) {
623
620
  case DUCKDB_TYPE_BIGINT:
624
621
  obj = LL2NUM(((int64_t *) vector_data)[row_idx]);
625
622
  break;
623
+ case DUCKDB_TYPE_UTINYINT:
624
+ obj = INT2FIX(((uint8_t *) vector_data)[row_idx]);
625
+ break;
626
+ case DUCKDB_TYPE_USMALLINT:
627
+ obj = INT2FIX(((uint16_t *) vector_data)[row_idx]);
628
+ break;
629
+ case DUCKDB_TYPE_UINTEGER:
630
+ obj = UINT2NUM(((uint32_t *) vector_data)[row_idx]);
631
+ break;
632
+ case DUCKDB_TYPE_UBIGINT:
633
+ obj = ULL2NUM(((uint64_t *) vector_data)[row_idx]);
634
+ break;
626
635
  case DUCKDB_TYPE_HUGEINT:
627
636
  obj = vector_hugeint(vector_data, row_idx);
628
637
  break;
@@ -19,6 +19,7 @@
19
19
  #include "./column.h"
20
20
  #include "./prepared_statement.h"
21
21
  #include "./util.h"
22
+ #include "./converter.h"
22
23
 
23
24
  #include "./blob.h"
24
25
  #include "./appender.h"
@@ -30,5 +31,6 @@ extern VALUE cDuckDBConnection;
30
31
  extern VALUE cDuckDBBlob;
31
32
  extern VALUE cDuckDBConfig;
32
33
  extern VALUE eDuckDBError;
34
+ extern VALUE mDuckDBConverter;
33
35
 
34
36
  #endif
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'date'
4
4
  require 'time'
5
- require_relative './converter'
5
+ require_relative 'converter'
6
6
 
7
7
  module DuckDB
8
8
  # The DuckDB::Appender encapsulates DuckDB Appender.
@@ -194,17 +194,9 @@ module DuckDB
194
194
  when TrueClass, FalseClass
195
195
  append_bool(value)
196
196
  when Time
197
- if respond_to?(:append_timestamp)
198
- append_timestamp(value)
199
- else
200
- append_varchar(value.strftime('%Y-%m-%d %H:%M:%S.%N'))
201
- end
197
+ append_timestamp(value)
202
198
  when Date
203
- if respond_to?(:append_date)
204
- append_date(value)
205
- else
206
- append_varchar(value.strftime('%Y-%m-%d'))
207
- end
199
+ append_date(value)
208
200
  else
209
201
  raise(DuckDB::Error, "not supported type #{value} (#{value.class})")
210
202
  end
@@ -23,7 +23,7 @@ module DuckDB
23
23
 
24
24
  def _to_decimal_from_vector(_width, scale, lower, upper)
25
25
  v = _to_hugeint_from_vector(lower, upper).to_s
26
- v[-scale, 0] = '.'
26
+ v[-scale, 0] = '.' unless v == '0'
27
27
  BigDecimal(v)
28
28
  end
29
29
 
data/lib/duckdb/result.rb CHANGED
@@ -104,7 +104,7 @@ module DuckDB
104
104
  def _to_decimal_internal(row, col)
105
105
  lower, upper, _width, scale = __to_decimal_internal(row, col)
106
106
  v = (upper * Converter::HALF_HUGEINT + lower).to_s
107
- v[-scale, 0] = '.'
107
+ v[-scale, 0] = '.' unless v == '0'
108
108
  BigDecimal(v)
109
109
  end
110
110
  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.8.1'
6
+ VERSION = '0.8.1.2'
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.8.1
4
+ version: 0.8.1.2
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-06-24 00:00:00.000000000 Z
11
+ date: 2023-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -87,6 +87,7 @@ files:
87
87
  - LICENSE
88
88
  - README.md
89
89
  - Rakefile
90
+ - benchmark/get_converter_module_ips.rb
90
91
  - benchmark/to_bigdecimal_ips.rb
91
92
  - benchmark/to_hugeint_ips.rb
92
93
  - benchmark/to_hugeint_profile.rb
@@ -104,6 +105,8 @@ files:
104
105
  - ext/duckdb/config.h
105
106
  - ext/duckdb/connection.c
106
107
  - ext/duckdb/connection.h
108
+ - ext/duckdb/converter.h
109
+ - ext/duckdb/conveter.c
107
110
  - ext/duckdb/database.c
108
111
  - ext/duckdb/database.h
109
112
  - ext/duckdb/duckdb.c
@@ -151,7 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
151
154
  - !ruby/object:Gem::Version
152
155
  version: '0'
153
156
  requirements: []
154
- rubygems_version: 3.4.10
157
+ rubygems_version: 3.4.17
155
158
  signing_key:
156
159
  specification_version: 4
157
160
  summary: This module is Ruby binding for DuckDB database engine.