duckdb 1.1.2.0 → 1.1.3.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: 7b6ad88562489a943d5ed0a4fcf56c4f84c9c3aa1a9f28d6d1fc6431c3fcea0b
4
- data.tar.gz: ac3047cf0098642db942d3547d1e8069fdb53ac0c8eb7f757a0f15c31465b895
3
+ metadata.gz: 5d9c9c9844335a39c1c154534cb50c031f872679c98eb5434a9d664805091c96
4
+ data.tar.gz: ca48e19a321441194515ad781ebcedb5010bca519e53bdfe9469af6a83add301
5
5
  SHA512:
6
- metadata.gz: 5614558f8685681f3369dfb4d8e36ead416b7ba1e4b0de48ff5edcc375a99c43bc1c3d996eca1f083d2df0352ced146f1e6d23bff99fa193035c9f996674e63d
7
- data.tar.gz: 2ace009816b0dfee961d8db1b0864e512239186ebf7b8b0ffe20a360e0a247a68afd11c4b97993e350f7b2a7f8eb29d4b4b3fcb367b31c575a6163d1d9d333c6
6
+ metadata.gz: 2fa6587abdac4d639630c0a605704ed76ff5f3373dcf56f83355dcc999913689e6628db690b8004ccdfc510ade6440b7ca088d9e9ac3a71e228a68ce2a8b359f
7
+ data.tar.gz: 1776ead93436933f732ec46c573ef7ef056c2cb86b9d601ac6574cf252c0a9774a3f78b464ddb8fe32deb61d5f626f4e6a379276898d08176a429def29f90a10
@@ -15,8 +15,8 @@ jobs:
15
15
  runs-on: macos-latest
16
16
  strategy:
17
17
  matrix:
18
- ruby: ['3.1.6', '3.2.5', '3.3.5', '3.4.0-preview2', 'head']
19
- duckdb: ['1.1.2', '1.1.1', '1.0.0']
18
+ ruby: ['3.1.6', '3.2.6', '3.3.6', '3.4.0-preview2', 'head']
19
+ duckdb: ['1.1.3', '1.1.1', '1.0.0']
20
20
 
21
21
  steps:
22
22
  - uses: actions/checkout@v4
@@ -15,8 +15,8 @@ jobs:
15
15
  runs-on: ubuntu-latest
16
16
  strategy:
17
17
  matrix:
18
- ruby: ['3.1.6', '3.2.5', '3.3.5', '3.4.0-preview2', 'head']
19
- duckdb: ['1.1.2', '1.1.1', '1.0.0']
18
+ ruby: ['3.1.6', '3.2.6', '3.3.6', '3.4.0-preview2', 'head']
19
+ duckdb: ['1.1.3', '1.1.1', '1.0.0']
20
20
 
21
21
  steps:
22
22
  - uses: actions/checkout@v4
@@ -16,7 +16,7 @@ jobs:
16
16
  strategy:
17
17
  matrix:
18
18
  ruby: ['3.1.6', '3.2.5', '3.3.5', 'ucrt', 'mingw', 'mswin', 'head']
19
- duckdb: ['1.1.2', '1.1.1', '1.0.0']
19
+ duckdb: ['1.1.3', '1.1.1', '1.0.0']
20
20
 
21
21
  steps:
22
22
  - uses: actions/checkout@v4
data/CHANGELOG.md CHANGED
@@ -3,6 +3,25 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  # Unreleased
5
5
 
6
+ # 1.1.3.0 - 2024-11-10
7
+ - add `DuckDB::PreparedStatement#bind_decimal`. (Thanks to @otegami)
8
+ - bump duckdb to 1.1.3.
9
+
10
+ # 1.1.2.1 - 2024-11-04
11
+ - `DuckDB::Connection#query` accepts multiple SQL statement.
12
+ - When multiple SQL statements are given, `DuckDB::Connection#query` returns the last statement result.
13
+ - `DuckDB::Connection#query` does not support multiple SQL statements with bind parameters. If you pass 2 or more argument,
14
+ `DuckDB::Connection#query` will regard first argument as only one SQL statement and the rest as bind parameters.
15
+ - add `DuckDB::ExtracteStatements#each` method.
16
+ - add `DuckDB::ExtracteStatementsImpl#destroy` method.
17
+ - add `DuckDB::PreparedStatement#prepare`.
18
+ - `DuckDB::Connection#prepared_statement` accepts block and calls `PreparedStatement#destroy` after block executed.
19
+ ```ruby
20
+ con.prepared_statement('SELECT * FROM table WHERE id = ?') do |stmt|
21
+ stmt.bind(1)
22
+ stmt.execute
23
+ end
24
+ ```
6
25
  # 1.1.2.0 - 2024-10-20
7
26
  - bump duckdb to 1.1.2.
8
27
  - add `DuckDB::PreparedStatement#destroy`.
data/Dockerfile CHANGED
@@ -1,7 +1,7 @@
1
- ARG RUBY_VERSION=3.3.5
1
+ ARG RUBY_VERSION=3.3.6
2
2
  FROM ruby:${RUBY_VERSION}
3
3
 
4
- ARG DUCKDB_VERSION=1.1.2
4
+ ARG DUCKDB_VERSION=1.1.3
5
5
 
6
6
  RUN apt update -qq && \
7
7
  apt install -y build-essential curl git wget
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- duckdb (1.1.2.0)
4
+ duckdb (1.1.3.0)
5
5
  bigdecimal (>= 3.1.4)
6
6
 
7
7
  GEM
@@ -17,6 +17,7 @@ static VALUE allocate(VALUE klass);
17
17
  static size_t memsize(const void *p);
18
18
 
19
19
  static VALUE duckdb_extracted_statements_initialize(VALUE self, VALUE con, VALUE query);
20
+ static VALUE duckdb_extracted_statements_destroy(VALUE self);
20
21
  static VALUE duckdb_extracted_statements_size(VALUE self);
21
22
  static VALUE duckdb_extracted_statements_prepared_statement(VALUE self, VALUE con, VALUE index);
22
23
 
@@ -56,12 +57,22 @@ static VALUE duckdb_extracted_statements_initialize(VALUE self, VALUE con, VALUE
56
57
 
57
58
  if (ctx->num_statements == 0) {
58
59
  error = duckdb_extract_statements_error(ctx->extracted_statements);
59
- rb_raise(eDuckDBError, "%s", error);
60
+ rb_raise(eDuckDBError, "%s", error ? error : "Failed to extract statements(Database connection closed?).");
60
61
  }
61
62
 
62
63
  return self;
63
64
  }
64
65
 
66
+ static VALUE duckdb_extracted_statements_destroy(VALUE self) {
67
+ rubyDuckDBExtractedStatements *ctx;
68
+
69
+ TypedData_Get_Struct(self, rubyDuckDBExtractedStatements, &extract_statements_data_type, ctx);
70
+
71
+ duckdb_destroy_extracted(&(ctx->extracted_statements));
72
+
73
+ return Qnil;
74
+ }
75
+
65
76
  static VALUE duckdb_extracted_statements_size(VALUE self) {
66
77
  rubyDuckDBExtractedStatements *ctx;
67
78
 
@@ -70,7 +81,6 @@ static VALUE duckdb_extracted_statements_size(VALUE self) {
70
81
  return ULL2NUM(ctx->num_statements);
71
82
  }
72
83
 
73
-
74
84
  static VALUE duckdb_extracted_statements_prepared_statement(VALUE self, VALUE con, VALUE index) {
75
85
  rubyDuckDBConnection *pcon;
76
86
  rubyDuckDBExtractedStatements *ctx;
@@ -85,10 +95,11 @@ static VALUE duckdb_extracted_statements_prepared_statement(VALUE self, VALUE co
85
95
  }
86
96
 
87
97
  void rbduckdb_init_duckdb_extracted_statements(void) {
88
- cDuckDBExtractedStatements = rb_define_class_under(mDuckDB, "ExtractedStatements", rb_cObject);
98
+ cDuckDBExtractedStatements = rb_define_class_under(mDuckDB, "ExtractedStatementsImpl", rb_cObject);
89
99
 
90
100
  rb_define_alloc_func(cDuckDBExtractedStatements, allocate);
91
101
  rb_define_method(cDuckDBExtractedStatements, "initialize", duckdb_extracted_statements_initialize, 2);
102
+ rb_define_method(cDuckDBExtractedStatements, "destroy", duckdb_extracted_statements_destroy, 0);
92
103
  rb_define_method(cDuckDBExtractedStatements, "size", duckdb_extracted_statements_size, 0);
93
104
  rb_define_method(cDuckDBExtractedStatements, "prepared_statement", duckdb_extracted_statements_prepared_statement, 2);
94
105
  }
@@ -32,6 +32,7 @@ static VALUE duckdb_prepared_statement__bind_time(VALUE self, VALUE vidx, VALUE
32
32
  static VALUE duckdb_prepared_statement__bind_timestamp(VALUE self, VALUE vidx, VALUE year, VALUE month, VALUE day, VALUE hour, VALUE min, VALUE sec, VALUE micros);
33
33
  static VALUE duckdb_prepared_statement__bind_interval(VALUE self, VALUE vidx, VALUE months, VALUE days, VALUE micros);
34
34
  static VALUE duckdb_prepared_statement__bind_hugeint(VALUE self, VALUE vidx, VALUE lower, VALUE upper);
35
+ static VALUE duckdb_prepared_statement__bind_decimal(VALUE self, VALUE vidx, VALUE lower, VALUE upper, VALUE width, VALUE scale);
35
36
 
36
37
  static const rb_data_type_t prepared_statement_data_type = {
37
38
  "DuckDB/PreparedStatement",
@@ -71,7 +72,7 @@ VALUE rbduckdb_prepared_statement_new(duckdb_connection con, duckdb_extracted_st
71
72
  TypedData_Get_Struct(obj, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
72
73
 
73
74
  if (duckdb_prepare_extracted_statement(con, extracted_statements, index, &(ctx->prepared_statement)) == DuckDBError) {
74
- rb_raise(eDuckDBError, "Fail to get DuckDB::PreparedStatement object from ExtractedStatements object");
75
+ rb_raise(eDuckDBError, "Failed to create DuckDB::PreparedStatement object.");
75
76
  }
76
77
  return obj;
77
78
  }
@@ -104,11 +105,16 @@ static VALUE duckdb_prepared_statement_execute(VALUE self) {
104
105
  rubyDuckDBPreparedStatement *ctx;
105
106
  rubyDuckDBResult *ctxr;
106
107
  VALUE result = rbduckdb_create_result();
108
+ const char *p = NULL;
107
109
 
108
110
  TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
109
111
  ctxr = get_struct_result(result);
110
112
  if (duckdb_execute_prepared(ctx->prepared_statement, &(ctxr->result)) == DuckDBError) {
111
- rb_raise(eDuckDBError, "%s", duckdb_result_error(&(ctxr->result)));
113
+ p = duckdb_result_error(&(ctxr->result));
114
+ if (p == NULL) {
115
+ p = duckdb_prepare_error(ctx->prepared_statement);
116
+ }
117
+ rb_raise(eDuckDBError, "%s", p ? p : "Failed to execute prepared statement.");
112
118
  }
113
119
  return result;
114
120
  }
@@ -399,6 +405,26 @@ static VALUE duckdb_prepared_statement__bind_hugeint(VALUE self, VALUE vidx, VAL
399
405
  return self;
400
406
  }
401
407
 
408
+ static VALUE duckdb_prepared_statement__bind_decimal(VALUE self, VALUE vidx, VALUE lower, VALUE upper, VALUE width, VALUE scale) {
409
+ duckdb_hugeint hugeint;
410
+ duckdb_decimal decimal;
411
+ rubyDuckDBPreparedStatement *ctx;
412
+ idx_t idx = check_index(vidx);
413
+
414
+ TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
415
+ hugeint.lower = NUM2ULL(lower);
416
+ hugeint.upper = NUM2LL(upper);
417
+ decimal.value = hugeint;
418
+ decimal.width = (uint8_t)NUM2UINT(width);
419
+ decimal.scale = (uint8_t)NUM2UINT(scale);
420
+
421
+ if (duckdb_bind_decimal(ctx->prepared_statement, idx, decimal) == DuckDBError) {
422
+ rb_raise(eDuckDBError, "fail to bind %llu parameter", (unsigned long long)idx);
423
+ }
424
+
425
+ return self;
426
+ }
427
+
402
428
  rubyDuckDBPreparedStatement *get_struct_prepared_statement(VALUE self) {
403
429
  rubyDuckDBPreparedStatement *ctx;
404
430
  TypedData_Get_Struct(self, rubyDuckDBPreparedStatement, &prepared_statement_data_type, ctx);
@@ -434,4 +460,5 @@ void rbduckdb_init_duckdb_prepared_statement(void) {
434
460
  rb_define_private_method(cDuckDBPreparedStatement, "_bind_timestamp", duckdb_prepared_statement__bind_timestamp, 8);
435
461
  rb_define_private_method(cDuckDBPreparedStatement, "_bind_interval", duckdb_prepared_statement__bind_interval, 4);
436
462
  rb_define_private_method(cDuckDBPreparedStatement, "_bind_hugeint", duckdb_prepared_statement__bind_hugeint, 3);
463
+ rb_define_private_method(cDuckDBPreparedStatement, "_bind_decimal", duckdb_prepared_statement__bind_decimal, 5);
437
464
  }
@@ -74,16 +74,7 @@ module DuckDB
74
74
  # appender.flush
75
75
  #
76
76
  def append_date(value)
77
- date = case value
78
- when Date, Time
79
- value
80
- else
81
- begin
82
- Date.parse(value)
83
- rescue
84
- raise(ArgumentError, "Cannot parse argument `#{value}` to Date.")
85
- end
86
- end
77
+ date = to_date(value)
87
78
 
88
79
  _append_date(date.year, date.month, date.day)
89
80
  end
@@ -126,18 +117,7 @@ module DuckDB
126
117
  # appender.flush
127
118
  #
128
119
  def append_timestamp(value)
129
- time = case value
130
- when Time
131
- value
132
- when Date
133
- value.to_time
134
- else
135
- begin
136
- Time.parse(value)
137
- rescue
138
- raise(ArgumentError, "Cannot parse argument `#{value}` to Time or Date.")
139
- end
140
- end
120
+ time = to_time(value)
141
121
 
142
122
  _append_timestamp(time.year, time.month, time.day, time.hour, time.min, time.sec, time.nsec / 1000)
143
123
  end
@@ -233,5 +213,33 @@ module DuckDB
233
213
  def blob?(value)
234
214
  value.instance_of?(DuckDB::Blob) || value.encoding == Encoding::BINARY
235
215
  end
216
+
217
+ def to_date(value)
218
+ case value
219
+ when Date, Time
220
+ value
221
+ else
222
+ begin
223
+ Date.parse(value)
224
+ rescue StandardError
225
+ raise(ArgumentError, "Cannot parse argument `#{value}` to Date.")
226
+ end
227
+ end
228
+ end
229
+
230
+ def to_time(value)
231
+ case value
232
+ when Time
233
+ value
234
+ when Date
235
+ value.to_time
236
+ else
237
+ begin
238
+ Time.parse(value)
239
+ rescue StandardError
240
+ raise(ArgumentError, "Cannot parse argument `#{value}` to Time or Date.")
241
+ end
242
+ end
243
+ end
236
244
  end
237
245
  end
@@ -26,13 +26,23 @@ module DuckDB
26
26
  # dave = con.query(sql, name: 'Dave', email: 'dave@example.com')
27
27
  #
28
28
  def query(sql, *args, **kwargs)
29
- return query_sql(sql) if args.empty? && kwargs.empty?
29
+ return query_multi_sql(sql) if args.empty? && kwargs.empty?
30
30
 
31
- stmt = PreparedStatement.new(self, sql)
32
- stmt.bind_args(*args, **kwargs)
33
- stmt.execute
31
+ prepare(sql) do |stmt|
32
+ stmt.bind_args(*args, **kwargs)
33
+ stmt.execute
34
+ end
35
+ end
36
+
37
+ def query_multi_sql(sql)
38
+ stmts = ExtractedStatements.new(self, sql)
39
+ result = nil
40
+ stmts.each do |stmt|
41
+ result = stmt.execute
42
+ end
43
+ result
34
44
  ensure
35
- stmt&.destroy
45
+ stmts&.destroy
36
46
  end
37
47
 
38
48
  #
@@ -52,11 +62,10 @@ module DuckDB
52
62
  # result.each.first
53
63
  #
54
64
  def async_query(sql, *args, **kwargs)
55
- stmt = PreparedStatement.new(self, sql)
56
- stmt.bind_args(*args, **kwargs)
57
- stmt.pending_prepared
58
- ensure
59
- stmt&.destroy
65
+ prepare(sql) do |stmt|
66
+ stmt.bind_args(*args, **kwargs)
67
+ stmt.pending_prepared
68
+ end
60
69
  end
61
70
 
62
71
  #
@@ -77,11 +86,10 @@ module DuckDB
77
86
  # result.each.first
78
87
  #
79
88
  def async_query_stream(sql, *args, **kwargs)
80
- stmt = PreparedStatement.new(self, sql)
81
- stmt.bind_args(*args, **kwargs)
82
- stmt.pending_prepared_stream
83
- ensure
84
- stmt&.destroy
89
+ prepare(sql) do |stmt|
90
+ stmt.bind_args(*args, **kwargs)
91
+ stmt.pending_prepared_stream
92
+ end
85
93
  end
86
94
 
87
95
  #
@@ -102,6 +110,8 @@ module DuckDB
102
110
  #
103
111
  # returns PreparedStatement object.
104
112
  # The first argument is SQL string.
113
+ # If block is given, the block is executed with PreparedStatement object
114
+ # and the object is cleaned up immediately.
105
115
  #
106
116
  # require 'duckdb'
107
117
  # db = DuckDB::Database.open('duckdb_file')
@@ -111,8 +121,17 @@ module DuckDB
111
121
  # stmt = con.prepared_statement(sql)
112
122
  # stmt.bind_args(name: 'Dave', email: 'dave@example.com')
113
123
  # result = stmt.execute
114
- def prepared_statement(str)
115
- PreparedStatement.new(self, str)
124
+ #
125
+ # # or
126
+ # result = con.prepared_statement(sql) do |stmt|
127
+ # stmt.bind_args(name: 'Dave', email: 'dave@example.com')
128
+ # stmt.execute
129
+ # end
130
+ #
131
+ def prepared_statement(str, &)
132
+ return PreparedStatement.new(self, str) unless block_given?
133
+
134
+ PreparedStatement.prepare(self, str, &)
116
135
  end
117
136
 
118
137
  #
@@ -155,6 +155,19 @@ module DuckDB
155
155
  end
156
156
  end
157
157
 
158
+ def _parse_deciaml(value)
159
+ case value
160
+ when BigDecimal
161
+ value
162
+ else
163
+ begin
164
+ BigDecimal(value.to_s)
165
+ rescue StandardError => e
166
+ raise(ArgumentError, "Cannot parse `#{value.inspect}` to BigDecimal object. #{e.message}")
167
+ end
168
+ end
169
+ end
170
+
158
171
  def _to_query_progress(percentage, rows_processed, total_rows_to_process)
159
172
  DuckDB::QueryProgress.new(percentage, rows_processed, total_rows_to_process).freeze
160
173
  end
@@ -171,5 +184,12 @@ module DuckDB
171
184
  raise(ArgumentError, "The argument `#{value.inspect}` must be Integer.")
172
185
  end
173
186
  end
187
+
188
+ def decimal_to_hugeint(value)
189
+ integer_value = (value * (10 ** value.scale)).to_i
190
+ integer_to_hugeint(integer_value)
191
+ rescue FloatDomainError => e
192
+ raise(ArgumentError, "The argument `#{value.inspect}` must be converted to Integer. #{e.message}")
193
+ end
174
194
  end
175
195
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DuckDB
4
+ class ExtractedStatements < ExtractedStatementsImpl
5
+ include Enumerable
6
+
7
+ def initialize(con, sql)
8
+ @con = con
9
+ super(con, sql)
10
+ end
11
+
12
+ def each
13
+ return to_enum(__method__) { size } unless block_given?
14
+
15
+ size.times do |i|
16
+ yield prepared_statement(@con, i)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -22,6 +22,31 @@ module DuckDB
22
22
  RANGE_INT32 = -2_147_483_648..2_147_483_647
23
23
  RANGE_INT64 = -9_223_372_036_854_775_808..9_223_372_036_854_775_807
24
24
 
25
+ class << self
26
+ # return DuckDB::PreparedStatement object.
27
+ # The first argument is DuckDB::Connection object.
28
+ # The second argument is SQL string.
29
+ # If block is given, the block is executed and the statement is destroyed.
30
+ #
31
+ # require 'duckdb'
32
+ # db = DuckDB::Database.open('duckdb_database')
33
+ # con = db.connection
34
+ # DuckDB::PreparedStatement.prepare(con, 'SELECT * FROM users WHERE id = ?') do |stmt|
35
+ # stmt.bind(1, 1)
36
+ # stmt.execute
37
+ # end
38
+ def prepare(con, sql)
39
+ stmt = new(con, sql)
40
+ return stmt unless block_given?
41
+
42
+ begin
43
+ yield stmt
44
+ ensure
45
+ stmt.destroy
46
+ end
47
+ end
48
+ end
49
+
25
50
  def pending_prepared
26
51
  PendingResult.new(self)
27
52
  end
@@ -191,6 +216,25 @@ module DuckDB
191
216
  _bind_interval(index, value.interval_months, value.interval_days, value.interval_micros)
192
217
  end
193
218
 
219
+ # binds i-th parameter with SQL prepared statement.
220
+ # The first argument is index of parameter.
221
+ # The index of first parameter is 1 not 0.
222
+ # The second argument value is to expected BigDecimal value or any value
223
+ # that can be parsed into a BigDecimal.
224
+ #
225
+ # require 'duckdb'
226
+ # db = DuckDB::Database.open('duckdb_database')
227
+ # con = db.connect
228
+ # sql ='SELECT value FROM decimals WHERE decimal = ?'
229
+ # stmt = PreparedStatement.new(con, sql)
230
+ # stmt.bind_decimal(1, BigDecimal('987654.321'))
231
+ def bind_decimal(index, value)
232
+ decimal = _parse_deciaml(value)
233
+ lower, upper = decimal_to_hugeint(decimal)
234
+ width = decimal.to_s('F').gsub(/[^0-9]/, '').length
235
+ _bind_decimal(index, lower, upper, width, decimal.scale)
236
+ end
237
+
194
238
  # binds i-th parameter with SQL prepared statement.
195
239
  # The first argument is index of parameter.
196
240
  # The index of first parameter is 1 not 0.
@@ -239,7 +283,7 @@ module DuckDB
239
283
  when Date
240
284
  bind_varchar(index, value.strftime('%Y-%m-%d'))
241
285
  when BigDecimal
242
- bind_varchar(index, value.to_s('F'))
286
+ bind_decimal(index, value)
243
287
  else
244
288
  raise(DuckDB::Error, "not supported type `#{value}` (#{value.class})")
245
289
  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 = '1.1.2.0'
6
+ VERSION = '1.1.3.0'
7
7
  end
data/lib/duckdb.rb CHANGED
@@ -6,6 +6,7 @@ require 'duckdb/version'
6
6
  require 'duckdb/converter'
7
7
  require 'duckdb/database'
8
8
  require 'duckdb/connection'
9
+ require 'duckdb/extracted_statements'
9
10
  require 'duckdb/result'
10
11
  require 'duckdb/prepared_statement'
11
12
  require 'duckdb/pending_result'
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: 1.1.2.0
4
+ version: 1.1.3.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: 2024-10-20 00:00:00.000000000 Z
11
+ date: 2024-11-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bigdecimal
@@ -149,6 +149,7 @@ files:
149
149
  - lib/duckdb/converter.rb
150
150
  - lib/duckdb/converter/int_to_sym.rb
151
151
  - lib/duckdb/database.rb
152
+ - lib/duckdb/extracted_statements.rb
152
153
  - lib/duckdb/infinity.rb
153
154
  - lib/duckdb/interval.rb
154
155
  - lib/duckdb/library_version.rb