duckdb 1.5.2.0 → 1.5.2.1
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 +4 -4
- data/CHANGELOG.md +9 -0
- data/duckdb.gemspec +37 -0
- data/ext/duckdb/aggregate_function.c +61 -100
- data/ext/duckdb/aggregate_function.h +2 -2
- data/ext/duckdb/appender.c +76 -35
- data/ext/duckdb/appender.h +1 -1
- data/ext/duckdb/client_context.c +5 -5
- data/ext/duckdb/client_context.h +2 -2
- data/ext/duckdb/column.c +13 -13
- data/ext/duckdb/column.h +1 -1
- data/ext/duckdb/connection.c +40 -41
- data/ext/duckdb/connection.h +2 -2
- data/ext/duckdb/converter.h +1 -7
- data/ext/duckdb/conveter.c +6 -6
- data/ext/duckdb/data_chunk.c +22 -22
- data/ext/duckdb/data_chunk.h +2 -2
- data/ext/duckdb/database.c +10 -10
- data/ext/duckdb/database.h +1 -1
- data/ext/duckdb/duckdb.c +17 -17
- data/ext/duckdb/expression.c +8 -8
- data/ext/duckdb/expression.h +1 -1
- data/ext/duckdb/extconf.rb +4 -3
- data/ext/duckdb/extracted_statements.c +15 -15
- data/ext/duckdb/extracted_statements.h +1 -1
- data/ext/duckdb/instance_cache.c +10 -10
- data/ext/duckdb/instance_cache.h +1 -1
- data/ext/duckdb/logical_type.c +94 -133
- data/ext/duckdb/logical_type.h +2 -2
- data/ext/duckdb/memory_helper.c +28 -28
- data/ext/duckdb/pending_result.c +27 -27
- data/ext/duckdb/pending_result.h +2 -2
- data/ext/duckdb/prepared_statement.c +103 -103
- data/ext/duckdb/prepared_statement.h +2 -2
- data/ext/duckdb/result.c +33 -33
- data/ext/duckdb/result.h +2 -3
- data/ext/duckdb/ruby-duckdb.h +4 -0
- data/ext/duckdb/scalar_function.c +3 -3
- data/ext/duckdb/table_description.c +1 -1
- data/ext/duckdb/table_function.c +3 -3
- data/ext/duckdb/table_function_bind_info.c +1 -1
- data/ext/duckdb/value.c +62 -50
- data/ext/duckdb/value.h +2 -2
- data/ext/duckdb/vector.c +20 -20
- data/ext/duckdb/vector.h +2 -2
- data/lib/duckdb/aggregate_function.rb +202 -3
- data/lib/duckdb/appender.rb +74 -0
- data/lib/duckdb/connection.rb +1 -16
- data/lib/duckdb/converter.rb +5 -0
- data/lib/duckdb/logical_type.rb +1 -3
- data/lib/duckdb/prepared_statement.rb +1 -1
- data/lib/duckdb/table_function.rb +0 -1
- data/lib/duckdb/value.rb +19 -0
- data/lib/duckdb/version.rb +1 -1
- metadata +2 -2
- data/lib/duckdb/duckdb_native.so +0 -0
data/lib/duckdb/appender.rb
CHANGED
|
@@ -93,6 +93,80 @@ module DuckDB
|
|
|
93
93
|
raise_appender_error('failed to close')
|
|
94
94
|
end
|
|
95
95
|
|
|
96
|
+
# :call-seq:
|
|
97
|
+
# appender.add_column(column_name) -> self
|
|
98
|
+
#
|
|
99
|
+
# Specifies a column to append to, allowing selective column insertion.
|
|
100
|
+
# Columns not added will use their default values or be computed from
|
|
101
|
+
# generated column expressions.
|
|
102
|
+
# Raises DuckDB::Error if the column does not exist in the table.
|
|
103
|
+
#
|
|
104
|
+
# require 'duckdb'
|
|
105
|
+
# db = DuckDB::Database.open
|
|
106
|
+
# con = db.connect
|
|
107
|
+
# con.query('CREATE TABLE t (id UUID PRIMARY KEY DEFAULT uuidv4(), name VARCHAR)')
|
|
108
|
+
# appender = con.appender('t')
|
|
109
|
+
# appender.add_column('name')
|
|
110
|
+
# appender
|
|
111
|
+
# .append_varchar('Alice')
|
|
112
|
+
# .end_row
|
|
113
|
+
# .flush
|
|
114
|
+
def add_column(column)
|
|
115
|
+
return self if _add_column(column)
|
|
116
|
+
|
|
117
|
+
raise_appender_error('failed to add_column')
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# :call-seq:
|
|
121
|
+
# appender.clear_columns -> self
|
|
122
|
+
#
|
|
123
|
+
# Clears the list of columns previously set by #add_column, so that all
|
|
124
|
+
# columns of the table become active again. Any previously appended rows
|
|
125
|
+
# are flushed before the column list is reset; if the flush fails (e.g.
|
|
126
|
+
# a constraint violation), this method raises DuckDB::Error.
|
|
127
|
+
#
|
|
128
|
+
# require 'duckdb'
|
|
129
|
+
# db = DuckDB::Database.open
|
|
130
|
+
# con = db.connect
|
|
131
|
+
# con.query('CREATE TABLE t (id UUID PRIMARY KEY DEFAULT uuidv4(), name VARCHAR)')
|
|
132
|
+
# appender = con.appender('t')
|
|
133
|
+
# appender.add_column('name')
|
|
134
|
+
# appender
|
|
135
|
+
# .append_varchar('Alice')
|
|
136
|
+
# .end_row
|
|
137
|
+
# .flush
|
|
138
|
+
# appender.clear_columns
|
|
139
|
+
# # all table columns are active again
|
|
140
|
+
def clear_columns
|
|
141
|
+
return self if _clear_columns
|
|
142
|
+
|
|
143
|
+
raise_appender_error('failed to clear_columns')
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
if DuckDB::Appender.private_method_defined?(:_clear)
|
|
147
|
+
# :call-seq:
|
|
148
|
+
# appender.clear -> self
|
|
149
|
+
#
|
|
150
|
+
# Clears all unflushed data from the appender, discarding any appended rows
|
|
151
|
+
# that have not yet been flushed to the table.
|
|
152
|
+
#
|
|
153
|
+
# require 'duckdb'
|
|
154
|
+
# db = DuckDB::Database.open
|
|
155
|
+
# con = db.connect
|
|
156
|
+
# con.query('CREATE TABLE users (id INTEGER, name VARCHAR)')
|
|
157
|
+
# appender = con.appender('users')
|
|
158
|
+
# appender
|
|
159
|
+
# .append_int32(1)
|
|
160
|
+
# .append_varchar('Alice')
|
|
161
|
+
# .end_row
|
|
162
|
+
# .clear # discards the row above without flushing to the table
|
|
163
|
+
def clear
|
|
164
|
+
return self if _clear
|
|
165
|
+
|
|
166
|
+
raise_appender_error('failed to clear')
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
96
170
|
# call-seq:
|
|
97
171
|
# appender.append_bool(val) -> self
|
|
98
172
|
#
|
data/lib/duckdb/connection.rb
CHANGED
|
@@ -34,7 +34,7 @@ module DuckDB
|
|
|
34
34
|
|
|
35
35
|
def query_multi_sql(sql)
|
|
36
36
|
stmts = ExtractedStatements.new(self, sql)
|
|
37
|
-
return
|
|
37
|
+
return _query_sql(sql) if stmts.size == 1
|
|
38
38
|
|
|
39
39
|
result = nil
|
|
40
40
|
stmts.each do |stmt|
|
|
@@ -276,7 +276,6 @@ module DuckDB
|
|
|
276
276
|
def register_table_function(table_function)
|
|
277
277
|
raise ArgumentError, 'table_function must be a TableFunction' unless table_function.is_a?(TableFunction)
|
|
278
278
|
|
|
279
|
-
check_threads
|
|
280
279
|
_register_table_function(table_function)
|
|
281
280
|
end
|
|
282
281
|
|
|
@@ -291,12 +290,10 @@ module DuckDB
|
|
|
291
290
|
# @param columns [Hash{String => DuckDB::LogicalType}, nil] optional column schema override;
|
|
292
291
|
# if omitted, the adapter determines the columns (e.g. from headers or inference)
|
|
293
292
|
# @raise [ArgumentError] if no adapter is registered for the object's class
|
|
294
|
-
# @raise [DuckDB::Error] if threads setting is not 1
|
|
295
293
|
# @return [void]
|
|
296
294
|
#
|
|
297
295
|
# @example Expose a CSV as a table
|
|
298
296
|
# require 'csv'
|
|
299
|
-
# con.execute('SET threads=1')
|
|
300
297
|
# DuckDB::TableFunction.add_table_adapter(CSV, CSVTableAdapter.new)
|
|
301
298
|
# csv = CSV.new(File.read('data.csv'), headers: true)
|
|
302
299
|
# con.expose_as_table(csv, 'csv_table')
|
|
@@ -318,18 +315,6 @@ module DuckDB
|
|
|
318
315
|
|
|
319
316
|
private
|
|
320
317
|
|
|
321
|
-
def check_threads
|
|
322
|
-
result = execute("SELECT current_setting('threads')")
|
|
323
|
-
thread_count = result.first.first.to_i
|
|
324
|
-
|
|
325
|
-
return unless thread_count > 1
|
|
326
|
-
|
|
327
|
-
raise DuckDB::Error,
|
|
328
|
-
'Functions with Ruby callbacks require single-threaded execution. ' \
|
|
329
|
-
"Current threads setting: #{thread_count}. " \
|
|
330
|
-
"Execute 'SET threads=1' before registering functions."
|
|
331
|
-
end
|
|
332
|
-
|
|
333
318
|
def run_appender_block(appender, &)
|
|
334
319
|
return appender unless block_given?
|
|
335
320
|
|
data/lib/duckdb/converter.rb
CHANGED
|
@@ -18,6 +18,7 @@ module DuckDB
|
|
|
18
18
|
RANGE_UINT64 = 0..18_446_744_073_709_551_615
|
|
19
19
|
RANGE_HUGEINT = (-(1 << 127)..((1 << 127) - 1))
|
|
20
20
|
RANGE_UHUGEINT = (0..((1 << 128) - 1))
|
|
21
|
+
RANGE_DECIMAL_WIDTH = 1..38
|
|
21
22
|
|
|
22
23
|
HALF_HUGEINT_BIT = 64
|
|
23
24
|
HALF_HUGEINT = 1 << HALF_HUGEINT_BIT
|
|
@@ -122,6 +123,10 @@ module DuckDB
|
|
|
122
123
|
value >> HALF_HUGEINT_BIT
|
|
123
124
|
end
|
|
124
125
|
|
|
126
|
+
def _decimal_width(value)
|
|
127
|
+
value.to_s('F').gsub(/[^0-9]/, '').length
|
|
128
|
+
end
|
|
129
|
+
|
|
125
130
|
def _to_decimal_from_hugeint(width, scale, upper, lower = nil)
|
|
126
131
|
v = lower.nil? ? upper : _to_hugeint_from_vector(lower, upper)
|
|
127
132
|
_to_decimal_from_value(width, scale, v)
|
data/lib/duckdb/logical_type.rb
CHANGED
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
module DuckDB
|
|
4
4
|
class LogicalType # rubocop:disable Metrics/ClassLength
|
|
5
|
-
RANGE_DECIMAL_WIDTH = 1..38
|
|
6
|
-
|
|
7
5
|
alias :alias get_alias
|
|
8
6
|
alias :alias= set_alias
|
|
9
7
|
|
|
@@ -171,7 +169,7 @@ module DuckDB
|
|
|
171
169
|
# decimal_type.width #=> 18
|
|
172
170
|
# decimal_type.scale #=> 3
|
|
173
171
|
def create_decimal(width, scale)
|
|
174
|
-
raise DuckDB::Error, 'width must be between 1 and 38' unless RANGE_DECIMAL_WIDTH.cover?(width)
|
|
172
|
+
raise DuckDB::Error, 'width must be between 1 and 38' unless Converter::RANGE_DECIMAL_WIDTH.cover?(width)
|
|
175
173
|
raise DuckDB::Error, "scale must be between 0 and width(#{width})" unless (0..width).cover?(scale)
|
|
176
174
|
|
|
177
175
|
_create_decimal_type(width, scale)
|
|
@@ -281,7 +281,7 @@ module DuckDB
|
|
|
281
281
|
def bind_decimal(index, value)
|
|
282
282
|
decimal = _parse_deciaml(value)
|
|
283
283
|
lower, upper = decimal_to_hugeint(decimal)
|
|
284
|
-
width = decimal
|
|
284
|
+
width = _decimal_width(decimal)
|
|
285
285
|
_bind_decimal(index, lower, upper, width, decimal.scale)
|
|
286
286
|
end
|
|
287
287
|
|
data/lib/duckdb/value.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'bigdecimal'
|
|
4
|
+
|
|
3
5
|
module DuckDB
|
|
4
6
|
class Value
|
|
5
7
|
class << self
|
|
@@ -219,6 +221,23 @@ module DuckDB
|
|
|
219
221
|
_create_uhugeint(lower, upper)
|
|
220
222
|
end
|
|
221
223
|
|
|
224
|
+
# Creates a DuckDB::Value of DECIMAL type.
|
|
225
|
+
#
|
|
226
|
+
# value = DuckDB::Value.create_decimal(BigDecimal('12345.678'))
|
|
227
|
+
#
|
|
228
|
+
# @param value [BigDecimal] the decimal value.
|
|
229
|
+
# @return [DuckDB::Value] the created Value object.
|
|
230
|
+
# @raise [ArgumentError] if +value+ is not a BigDecimal or its width is out of range (1..38).
|
|
231
|
+
def create_decimal(value)
|
|
232
|
+
check_type!(value, BigDecimal)
|
|
233
|
+
|
|
234
|
+
width = _decimal_width(value)
|
|
235
|
+
check_range!(width, RANGE_DECIMAL_WIDTH, 'DECIMAL width')
|
|
236
|
+
|
|
237
|
+
lower, upper = decimal_to_hugeint(value)
|
|
238
|
+
_create_decimal(lower, upper, width, value.scale)
|
|
239
|
+
end
|
|
240
|
+
|
|
222
241
|
private
|
|
223
242
|
|
|
224
243
|
def check_range!(value, range, type_name)
|
data/lib/duckdb/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: duckdb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.5.2.
|
|
4
|
+
version: 1.5.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Masaki Suketa
|
|
@@ -40,6 +40,7 @@ files:
|
|
|
40
40
|
- Rakefile
|
|
41
41
|
- bin/console
|
|
42
42
|
- bin/setup
|
|
43
|
+
- duckdb.gemspec
|
|
43
44
|
- ext/duckdb/aggregate_function.c
|
|
44
45
|
- ext/duckdb/aggregate_function.h
|
|
45
46
|
- ext/duckdb/appender.c
|
|
@@ -120,7 +121,6 @@ files:
|
|
|
120
121
|
- lib/duckdb/converter/int_to_sym.rb
|
|
121
122
|
- lib/duckdb/data_chunk.rb
|
|
122
123
|
- lib/duckdb/database.rb
|
|
123
|
-
- lib/duckdb/duckdb_native.so
|
|
124
124
|
- lib/duckdb/expression.rb
|
|
125
125
|
- lib/duckdb/extracted_statements.rb
|
|
126
126
|
- lib/duckdb/function_type_validation.rb
|
data/lib/duckdb/duckdb_native.so
DELETED
|
Binary file
|