duckdb 1.0.0.1 → 1.1.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 +4 -4
- data/.github/workflows/test_on_macos.yml +15 -3
- data/.github/workflows/test_on_ubuntu.yml +15 -3
- data/.github/workflows/test_on_windows.yml +2 -2
- data/CHANGELOG.md +64 -1
- data/Dockerfile +2 -2
- data/Gemfile.lock +6 -6
- data/README.md +0 -3
- data/benchmark/async_query.rb +0 -2
- data/benchmark/to_intern_ips.rb +0 -1
- data/duckdb.gemspec +1 -1
- data/ext/duckdb/duckdb.c +4 -0
- data/ext/duckdb/extconf.rb +6 -7
- data/ext/duckdb/pending_result.c +7 -0
- data/ext/duckdb/prepared_statement.c +35 -9
- data/ext/duckdb/result.c +246 -411
- data/ext/duckdb/ruby-duckdb.h +6 -0
- data/lib/duckdb/column.rb +2 -38
- data/lib/duckdb/config.rb +47 -49
- data/lib/duckdb/connection.rb +0 -1
- data/lib/duckdb/converter/int_to_sym.rb +127 -0
- data/lib/duckdb/converter.rb +68 -0
- data/lib/duckdb/database.rb +2 -4
- data/lib/duckdb/infinity.rb +8 -0
- data/lib/duckdb/pending_result.rb +16 -5
- data/lib/duckdb/prepared_statement.rb +29 -2
- data/lib/duckdb/result.rb +39 -78
- data/lib/duckdb/version.rb +1 -1
- data/lib/duckdb.rb +1 -0
- data/sample/async_query.rb +0 -1
- data/sample/async_query_stream.rb +0 -1
- metadata +6 -7
- data/benchmark/to_bigdecimal_ips.rb +0 -16
- data/benchmark/to_hugeint_ips.rb +0 -16
- data/benchmark/to_hugeint_profile.rb +0 -26
data/ext/duckdb/ruby-duckdb.h
CHANGED
@@ -15,6 +15,10 @@
|
|
15
15
|
#define HAVE_DUCKDB_H_GE_V1_0_0 1
|
16
16
|
#endif
|
17
17
|
|
18
|
+
#ifdef HAVE_DUCKDB_RESULT_ERROR_TYPE
|
19
|
+
#define HAVE_DUCKDB_H_GE_V1_1_0 1
|
20
|
+
#endif
|
21
|
+
|
18
22
|
#include "./error.h"
|
19
23
|
#include "./database.h"
|
20
24
|
#include "./connection.h"
|
@@ -38,5 +42,7 @@ extern VALUE cDuckDBConfig;
|
|
38
42
|
extern VALUE eDuckDBError;
|
39
43
|
extern VALUE mDuckDBConverter;
|
40
44
|
extern VALUE cDuckDBPreparedStatement;
|
45
|
+
extern VALUE PositiveInfinity;
|
46
|
+
extern VALUE NegativeInfinity;
|
41
47
|
|
42
48
|
#endif
|
data/lib/duckdb/column.rb
CHANGED
@@ -17,44 +17,8 @@ module DuckDB
|
|
17
17
|
# columns.first.type #=> :integer
|
18
18
|
#
|
19
19
|
def type
|
20
|
-
|
21
|
-
|
22
|
-
boolean
|
23
|
-
tinyint
|
24
|
-
smallint
|
25
|
-
integer
|
26
|
-
bigint
|
27
|
-
utinyint
|
28
|
-
usmallint
|
29
|
-
uinteger
|
30
|
-
ubigint
|
31
|
-
float
|
32
|
-
double
|
33
|
-
timestamp
|
34
|
-
date
|
35
|
-
time
|
36
|
-
interval
|
37
|
-
hugeint
|
38
|
-
varchar
|
39
|
-
blob
|
40
|
-
decimal
|
41
|
-
timestamp_s
|
42
|
-
timestamp_ms
|
43
|
-
timestamp_ns
|
44
|
-
enum
|
45
|
-
list
|
46
|
-
struct
|
47
|
-
map
|
48
|
-
uuid
|
49
|
-
json
|
50
|
-
]
|
51
|
-
if Gem::Version.new(DuckDB::LIBRARY_VERSION) == Gem::Version.new('0.10.0')
|
52
|
-
types[17, 0] = :uhugeint
|
53
|
-
end
|
54
|
-
index = _type
|
55
|
-
return :unknown if index >= types.size
|
56
|
-
|
57
|
-
types[index]
|
20
|
+
type_id = _type
|
21
|
+
DuckDB::Converter::IntToSym.type_to_sym(type_id)
|
58
22
|
end
|
59
23
|
end
|
60
24
|
end
|
data/lib/duckdb/config.rb
CHANGED
@@ -1,64 +1,62 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module DuckDB
|
4
|
-
|
5
|
-
|
4
|
+
# The DuckDB::Config encapsulates DuckDB Configuration.
|
5
|
+
#
|
6
|
+
# require 'duckdb'
|
7
|
+
# config = DuckDB::Config.new
|
8
|
+
# config['default_order'] = 'DESC'
|
9
|
+
# db = DuckDB::Database.open(nil, config)
|
10
|
+
# con = db.connect
|
11
|
+
# con.query('CREATE TABLE numbers (number INTEGER)')
|
12
|
+
# con.query('INSERT INTO numbers VALUES (2), (1), (4), (3)')
|
13
|
+
#
|
14
|
+
# # number is ordered by descending.
|
15
|
+
# r = con.query('SELECT number FROM numbers ORDER BY number)
|
16
|
+
# r.first.first # => 4
|
17
|
+
class Config
|
18
|
+
class << self
|
19
|
+
#
|
20
|
+
# returns available configuration name and the description.
|
21
|
+
# The return value is array object. The first element is the configuration
|
22
|
+
# name. The second is the description.
|
23
|
+
#
|
24
|
+
# key, desc = DuckDB::Config.key_description(0)
|
25
|
+
# key # => "access_mode"
|
26
|
+
# desc # => "Access mode of the database ([AUTOMATIC], READ_ONLY or READ_WRITE)"
|
27
|
+
#
|
28
|
+
alias key_description get_config_flag
|
29
|
+
|
30
|
+
#
|
31
|
+
# returns the Hash object of all available configuration names and
|
32
|
+
# the descriptions.
|
33
|
+
#
|
34
|
+
# configs = DuckDB::Config.key_descriptions
|
35
|
+
# configs['default_order'] # => "The order type used when none is specified ([ASC] or DESC)"
|
36
|
+
#
|
37
|
+
def key_descriptions
|
38
|
+
@key_descriptions ||= (0...size).each_with_object({}) do |i, hash|
|
39
|
+
key, description = key_description(i)
|
40
|
+
hash[key] = description
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# set configuration value
|
6
47
|
#
|
7
|
-
# require 'duckdb'
|
8
48
|
# config = DuckDB::Config.new
|
49
|
+
# # config.set_config('default_order', 'DESC')
|
9
50
|
# config['default_order'] = 'DESC'
|
51
|
+
#
|
10
52
|
# db = DuckDB::Database.open(nil, config)
|
11
53
|
# con = db.connect
|
12
54
|
# con.query('CREATE TABLE numbers (number INTEGER)')
|
13
55
|
# con.query('INSERT INTO numbers VALUES (2), (1), (4), (3)')
|
14
56
|
#
|
15
|
-
# #
|
57
|
+
# # numbers are ordered by descending.
|
16
58
|
# r = con.query('SELECT number FROM numbers ORDER BY number)
|
17
59
|
# r.first.first # => 4
|
18
|
-
|
19
|
-
class << self
|
20
|
-
#
|
21
|
-
# returns available configuration name and the description.
|
22
|
-
# The return value is array object. The first element is the configuration
|
23
|
-
# name. The second is the description.
|
24
|
-
#
|
25
|
-
# key, desc = DuckDB::Config.key_description(0)
|
26
|
-
# key # => "access_mode"
|
27
|
-
# desc # => "Access mode of the database ([AUTOMATIC], READ_ONLY or READ_WRITE)"
|
28
|
-
#
|
29
|
-
alias key_description get_config_flag
|
30
|
-
|
31
|
-
#
|
32
|
-
# returns the Hash object of all available configuration names and
|
33
|
-
# the descriptions.
|
34
|
-
#
|
35
|
-
# configs = DuckDB::Config.key_descriptions
|
36
|
-
# configs['default_order'] # => "The order type used when none is specified ([ASC] or DESC)"
|
37
|
-
#
|
38
|
-
def key_descriptions
|
39
|
-
@key_descriptions ||= (0...size).each_with_object({}) do |i, hash|
|
40
|
-
key, description = key_description(i)
|
41
|
-
hash[key] = description
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
#
|
47
|
-
# set configuration value
|
48
|
-
#
|
49
|
-
# config = DuckDB::Config.new
|
50
|
-
# # config.set_config('default_order', 'DESC')
|
51
|
-
# config['default_order'] = 'DESC'
|
52
|
-
#
|
53
|
-
# db = DuckDB::Database.open(nil, config)
|
54
|
-
# con = db.connect
|
55
|
-
# con.query('CREATE TABLE numbers (number INTEGER)')
|
56
|
-
# con.query('INSERT INTO numbers VALUES (2), (1), (4), (3)')
|
57
|
-
#
|
58
|
-
# # numbers are ordered by descending.
|
59
|
-
# r = con.query('SELECT number FROM numbers ORDER BY number)
|
60
|
-
# r.first.first # => 4
|
61
|
-
alias []= set_config
|
62
|
-
end
|
60
|
+
alias []= set_config
|
63
61
|
end
|
64
62
|
end
|
data/lib/duckdb/connection.rb
CHANGED
@@ -0,0 +1,127 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DuckDB
|
4
|
+
module Converter
|
5
|
+
module IntToSym
|
6
|
+
STATEMENT_TYPES = %i[
|
7
|
+
invalid
|
8
|
+
select
|
9
|
+
insert
|
10
|
+
update
|
11
|
+
explain
|
12
|
+
delete
|
13
|
+
prepare
|
14
|
+
create
|
15
|
+
execute
|
16
|
+
alter
|
17
|
+
transaction
|
18
|
+
copy
|
19
|
+
analyze
|
20
|
+
variable_set
|
21
|
+
create_func
|
22
|
+
drop
|
23
|
+
export
|
24
|
+
pragma
|
25
|
+
vacuum
|
26
|
+
call
|
27
|
+
set
|
28
|
+
load
|
29
|
+
relation
|
30
|
+
extension
|
31
|
+
logical_plan
|
32
|
+
attach
|
33
|
+
detach
|
34
|
+
multi
|
35
|
+
].freeze
|
36
|
+
|
37
|
+
HASH_TYPES = if Gem::Version.new(DuckDB::LIBRARY_VERSION) == Gem::Version.new('0.10.0')
|
38
|
+
{
|
39
|
+
0 => :invalid,
|
40
|
+
1 => :boolean,
|
41
|
+
2 => :tinyint,
|
42
|
+
3 => :smallint,
|
43
|
+
4 => :integer,
|
44
|
+
5 => :bigint,
|
45
|
+
6 => :utinyint,
|
46
|
+
7 => :usmallint,
|
47
|
+
8 => :uinteger,
|
48
|
+
9 => :ubigint,
|
49
|
+
10 => :float,
|
50
|
+
11 => :double,
|
51
|
+
12 => :timestamp,
|
52
|
+
13 => :date,
|
53
|
+
14 => :time,
|
54
|
+
15 => :interval,
|
55
|
+
16 => :hugeint,
|
56
|
+
17 => :uhugeint,
|
57
|
+
18 => :varchar,
|
58
|
+
19 => :blob,
|
59
|
+
20 => :decimal,
|
60
|
+
21 => :timestamp_s,
|
61
|
+
22 => :timestamp_ms,
|
62
|
+
23 => :timestamp_ns,
|
63
|
+
24 => :enum,
|
64
|
+
25 => :list,
|
65
|
+
26 => :struct,
|
66
|
+
27 => :map,
|
67
|
+
28 => :uuid,
|
68
|
+
29 => :union,
|
69
|
+
30 => :bit,
|
70
|
+
31 => :time_tz,
|
71
|
+
32 => :timestamp_tz
|
72
|
+
}.freeze
|
73
|
+
else
|
74
|
+
{
|
75
|
+
0 => :invalid,
|
76
|
+
1 => :boolean,
|
77
|
+
2 => :tinyint,
|
78
|
+
3 => :smallint,
|
79
|
+
4 => :integer,
|
80
|
+
5 => :bigint,
|
81
|
+
6 => :utinyint,
|
82
|
+
7 => :usmallint,
|
83
|
+
8 => :uinteger,
|
84
|
+
9 => :ubigint,
|
85
|
+
10 => :float,
|
86
|
+
11 => :double,
|
87
|
+
12 => :timestamp,
|
88
|
+
13 => :date,
|
89
|
+
14 => :time,
|
90
|
+
15 => :interval,
|
91
|
+
16 => :hugeint,
|
92
|
+
32 => :uhugeint,
|
93
|
+
17 => :varchar,
|
94
|
+
18 => :blob,
|
95
|
+
19 => :decimal,
|
96
|
+
20 => :timestamp_s,
|
97
|
+
21 => :timestamp_ms,
|
98
|
+
22 => :timestamp_ns,
|
99
|
+
23 => :enum,
|
100
|
+
24 => :list,
|
101
|
+
25 => :struct,
|
102
|
+
26 => :map,
|
103
|
+
33 => :array,
|
104
|
+
27 => :uuid,
|
105
|
+
28 => :union,
|
106
|
+
29 => :bit,
|
107
|
+
30 => :time_tz,
|
108
|
+
31 => :timestamp_tz
|
109
|
+
}.freeze
|
110
|
+
end
|
111
|
+
|
112
|
+
module_function
|
113
|
+
|
114
|
+
def statement_type_to_sym(val)
|
115
|
+
raise DuckDB::Error, "Unknown statement type: #{val}" if val >= STATEMENT_TYPES.size
|
116
|
+
|
117
|
+
STATEMENT_TYPES[val]
|
118
|
+
end
|
119
|
+
|
120
|
+
def type_to_sym(val)
|
121
|
+
raise DuckDB::Error, "Unknown type: #{val}" unless HASH_TYPES.key?(val)
|
122
|
+
|
123
|
+
HASH_TYPES[val]
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
data/lib/duckdb/converter.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'date'
|
4
4
|
require_relative 'interval'
|
5
|
+
require_relative 'converter/int_to_sym'
|
5
6
|
|
6
7
|
module DuckDB
|
7
8
|
QueryProgress = Struct.new(:percentage, :rows_processed, :total_rows_to_process)
|
@@ -10,9 +11,19 @@ module DuckDB
|
|
10
11
|
HALF_HUGEINT_BIT = 64
|
11
12
|
HALF_HUGEINT = 1 << HALF_HUGEINT_BIT
|
12
13
|
FLIP_HUGEINT = 1 << 63
|
14
|
+
EPOCH = Time.local(1970, 1, 1)
|
15
|
+
EPOCH_UTC = Time.new(1970, 1, 1, 0, 0, 0, 0)
|
13
16
|
|
14
17
|
module_function
|
15
18
|
|
19
|
+
def _to_infinity(value)
|
20
|
+
if value.positive?
|
21
|
+
DuckDB::Infinity::POSITIVE
|
22
|
+
else
|
23
|
+
DuckDB::Infinity::NEGATIVE
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
16
27
|
def _to_date(year, month, day)
|
17
28
|
Date.new(year, month, day)
|
18
29
|
end
|
@@ -33,6 +44,63 @@ module DuckDB
|
|
33
44
|
)
|
34
45
|
end
|
35
46
|
|
47
|
+
def _to_time_from_duckdb_timestamp_s(time)
|
48
|
+
EPOCH + time
|
49
|
+
end
|
50
|
+
|
51
|
+
def _to_time_from_duckdb_timestamp_ms(time)
|
52
|
+
tm = EPOCH + (time / 1000)
|
53
|
+
Time.local(tm.year, tm.month, tm.day, tm.hour, tm.min, tm.sec, time % 1000 * 1000)
|
54
|
+
end
|
55
|
+
|
56
|
+
def _to_time_from_duckdb_timestamp_ns(time)
|
57
|
+
tm = EPOCH + (time / 1_000_000_000)
|
58
|
+
Time.local(tm.year, tm.month, tm.day, tm.hour, tm.min, tm.sec, time % 1_000_000_000 / 1000)
|
59
|
+
end
|
60
|
+
|
61
|
+
def _to_time_from_duckdb_time_tz(hour, min, sec, micro, timezone)
|
62
|
+
sign = '+'
|
63
|
+
if timezone.negative?
|
64
|
+
timezone = -timezone
|
65
|
+
sign = '-'
|
66
|
+
end
|
67
|
+
|
68
|
+
tzhour = timezone / 3600
|
69
|
+
tzmin = (timezone % 3600) / 60
|
70
|
+
|
71
|
+
Time.parse(
|
72
|
+
format(
|
73
|
+
'%<hour>02d:%<min>02d:%<sec>02d.%<micro>06d%<sign>s%<tzhour>02d:%<tzmin>02d',
|
74
|
+
hour: hour,
|
75
|
+
min: min,
|
76
|
+
sec: sec,
|
77
|
+
micro: micro,
|
78
|
+
sign: sign,
|
79
|
+
tzhour: tzhour,
|
80
|
+
tzmin: tzmin
|
81
|
+
)
|
82
|
+
)
|
83
|
+
end
|
84
|
+
|
85
|
+
def _to_time_from_duckdb_timestamp_tz(bits)
|
86
|
+
micro = bits % 1_000_000
|
87
|
+
sec = (bits / 1_000_000)
|
88
|
+
time = EPOCH_UTC + sec
|
89
|
+
|
90
|
+
Time.parse(
|
91
|
+
format(
|
92
|
+
'%<year>04d-%<mon>02d-%<day>02d %<hour>02d:%<min>02d:%<sec>02d.%<micro>06d +0000',
|
93
|
+
year: time.year,
|
94
|
+
mon: time.month,
|
95
|
+
day: time.day,
|
96
|
+
hour: time.hour,
|
97
|
+
min: time.min,
|
98
|
+
sec: time.sec,
|
99
|
+
micro: micro
|
100
|
+
)
|
101
|
+
)
|
102
|
+
end
|
103
|
+
|
36
104
|
def _to_hugeint_from_vector(lower, upper)
|
37
105
|
(upper << HALF_HUGEINT_BIT) + lower
|
38
106
|
end
|
data/lib/duckdb/database.rb
CHANGED
@@ -23,7 +23,7 @@ module DuckDB
|
|
23
23
|
#
|
24
24
|
class Database
|
25
25
|
private_class_method :_open
|
26
|
-
private_class_method :_open_ext
|
26
|
+
private_class_method :_open_ext
|
27
27
|
|
28
28
|
class << self
|
29
29
|
##
|
@@ -55,10 +55,8 @@ module DuckDB
|
|
55
55
|
private
|
56
56
|
|
57
57
|
def _db_open(dbpath, config)
|
58
|
-
if
|
58
|
+
if config
|
59
59
|
_open_ext(dbpath, config)
|
60
|
-
elsif config
|
61
|
-
_open(dbpath, config)
|
62
60
|
else
|
63
61
|
_open(dbpath)
|
64
62
|
end
|
@@ -8,8 +8,6 @@ module DuckDB
|
|
8
8
|
#
|
9
9
|
# require 'duckdb'
|
10
10
|
#
|
11
|
-
# DuckDB::Result.use_chunk_each = true
|
12
|
-
#
|
13
11
|
# db = DuckDB::Database.open
|
14
12
|
# con = db.connect
|
15
13
|
# stmt = con.prepared_statement(VERY_SLOW_QUERY)
|
@@ -24,8 +22,7 @@ module DuckDB
|
|
24
22
|
STATES = %i[ready not_ready error no_tasks].freeze
|
25
23
|
|
26
24
|
# returns the state of the pending result.
|
27
|
-
#
|
28
|
-
# (:no_tasks is available only with duckdb 0.9.0 or later.)
|
25
|
+
# the result can be :ready, :not_ready, :error, :no_tasks.
|
29
26
|
#
|
30
27
|
# :ready means the result is ready to be fetched, and
|
31
28
|
# you can call `execute_pending` to get the result.
|
@@ -33,9 +30,23 @@ module DuckDB
|
|
33
30
|
# :not_ready means the result is not ready yet, so
|
34
31
|
# you need to call `execute_task`.
|
35
32
|
#
|
36
|
-
# @return [
|
33
|
+
# @return [symbol] :ready, :not_ready, :error, :no_tasks
|
37
34
|
def state
|
38
35
|
STATES[_state]
|
39
36
|
end
|
37
|
+
|
38
|
+
# returns the state of the pending result.
|
39
|
+
# the result can be :ready, :not_ready, :error, :no_tasks.
|
40
|
+
#
|
41
|
+
# :ready means the result is ready to be fetched, and
|
42
|
+
# you can call `execute_pending` to get the result.
|
43
|
+
#
|
44
|
+
# :not_ready or :no_tasks might mean the pending result
|
45
|
+
# is not executed yet, so you need to call `execute_task`.
|
46
|
+
#
|
47
|
+
# @return [symbol] :ready, :not_ready, :error, :no_tasks
|
48
|
+
def execute_check_state
|
49
|
+
STATES[_execute_check_state]
|
50
|
+
end
|
40
51
|
end
|
41
52
|
end
|
@@ -27,11 +27,38 @@ module DuckDB
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def pending_prepared_stream
|
30
|
-
raise DuckDB::Error, 'DuckDB::Result.use_chunk_each must be true.' unless DuckDB::Result.use_chunk_each?
|
31
|
-
|
32
30
|
PendingResult.new(self, true)
|
33
31
|
end
|
34
32
|
|
33
|
+
# returns statement type. The return value is one of the following symbols:
|
34
|
+
# :invalid, :select, :insert, :update, :explain, :delete, :prepare, :create,
|
35
|
+
# :execute, :alter, :transaction, :copy, :analyze, :variable_set, :create_func,
|
36
|
+
# :drop, :export, :pragma, :vacuum, :call, :set, :load, :relation, :extension,
|
37
|
+
# :logical_plan, :attach, :detach, :multi
|
38
|
+
#
|
39
|
+
# require 'duckdb'
|
40
|
+
# db = DuckDB::Database.open('duckdb_database')
|
41
|
+
# con = db.connect
|
42
|
+
# stmt = con.prepared_statement('SELECT * FROM users')
|
43
|
+
# stmt.statement_type # => :select
|
44
|
+
def statement_type
|
45
|
+
i = _statement_type
|
46
|
+
Converter::IntToSym.statement_type_to_sym(i)
|
47
|
+
end
|
48
|
+
|
49
|
+
# returns parameter type. The argument must be index of parameter.
|
50
|
+
#
|
51
|
+
# require 'duckdb'
|
52
|
+
# db = DuckDB::Database.open
|
53
|
+
# con = db.connect
|
54
|
+
# con.execute('CREATE TABLE users (id INTEGER, name VARCHAR(255))')
|
55
|
+
# stmt = con.prepared_statement('SELECT * FROM users WHERE id = ?')
|
56
|
+
# stmt.param_type(1) # => :integer
|
57
|
+
def param_type(index)
|
58
|
+
i = _param_type(index)
|
59
|
+
Converter::IntToSym.type_to_sym(i)
|
60
|
+
end
|
61
|
+
|
35
62
|
# binds all parameters with SQL prepared statement.
|
36
63
|
#
|
37
64
|
# require 'duckdb'
|
data/lib/duckdb/result.rb
CHANGED
@@ -24,86 +24,71 @@ module DuckDB
|
|
24
24
|
# end
|
25
25
|
class Result
|
26
26
|
include Enumerable
|
27
|
-
|
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
|
27
|
+
RETURN_TYPES = %i[invalid changed_rows nothing query_result].freeze
|
52
28
|
|
53
29
|
alias column_size column_count
|
54
30
|
alias row_size row_count
|
55
31
|
|
56
|
-
@use_chunk_each = true
|
57
|
-
|
58
32
|
class << self
|
59
33
|
def new
|
60
34
|
raise DuckDB::Error, 'DuckDB::Result cannot be instantiated directly.'
|
61
35
|
end
|
62
36
|
|
63
37
|
def use_chunk_each=(value)
|
64
|
-
|
38
|
+
raise('`changing DuckDB::Result.use_chunk_each to false` was deprecated.') unless value
|
39
|
+
|
40
|
+
warn('`DuckDB::Result.use_chunk_each=` will be deprecated.')
|
65
41
|
|
66
|
-
|
42
|
+
true
|
67
43
|
end
|
68
44
|
|
69
45
|
def use_chunk_each?
|
70
|
-
|
46
|
+
warn('`DuckDB::Result.use_chunk_each?` will be deprecated.')
|
47
|
+
true
|
71
48
|
end
|
72
49
|
end
|
73
50
|
|
74
51
|
def each
|
75
|
-
if
|
76
|
-
|
77
|
-
return _chunk_stream unless block_given?
|
52
|
+
if streaming?
|
53
|
+
return _chunk_stream unless block_given?
|
78
54
|
|
79
|
-
|
80
|
-
else
|
81
|
-
return chunk_each unless block_given?
|
82
|
-
|
83
|
-
chunk_each { |row| yield row }
|
84
|
-
end
|
55
|
+
_chunk_stream { |row| yield row }
|
85
56
|
else
|
86
|
-
|
87
|
-
return to_enum { row_size } unless block_given?
|
57
|
+
return chunk_each unless block_given?
|
88
58
|
|
89
|
-
|
90
|
-
yield row(row_index)
|
91
|
-
end
|
59
|
+
chunk_each { |row| yield row }
|
92
60
|
end
|
93
61
|
end
|
94
62
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
63
|
+
# returns return type. The return value is one of the following symbols:
|
64
|
+
# :invalid, :changed_rows, :nothing, :query_result
|
65
|
+
#
|
66
|
+
# require 'duckdb'
|
67
|
+
# db = DuckDB::Database.open('duckdb_database')
|
68
|
+
# con = db.connect
|
69
|
+
# result = con.execute('CREATE TABLE users (id INTEGER, name VARCHAR(30))')
|
70
|
+
# result.return_type # => :nothing
|
71
|
+
def return_type
|
72
|
+
i = _return_type
|
73
|
+
raise DuckDB::Error, "Unknown return type: #{i}" if i >= RETURN_TYPES.size
|
74
|
+
|
75
|
+
RETURN_TYPES[i]
|
102
76
|
end
|
103
77
|
|
104
|
-
|
105
|
-
|
106
|
-
|
78
|
+
# returns statement type. The return value is one of the following symbols:
|
79
|
+
# :invalid, :select, :insert, :update, :explain, :delete, :prepare, :create,
|
80
|
+
# :execute, :alter, :transaction, :copy, :analyze, :variable_set, :create_func,
|
81
|
+
# :drop, :export, :pragma, :vacuum, :call, :set, :load, :relation, :extension,
|
82
|
+
# :logical_plan, :attach, :detach, :multi
|
83
|
+
#
|
84
|
+
# require 'duckdb'
|
85
|
+
# db = DuckDB::Database.open('duckdb_database')
|
86
|
+
# con = db.connect
|
87
|
+
# result = con.execute('CREATE TABLE users (id INTEGER, name VARCHAR(30))')
|
88
|
+
# result.statement_type # => :create
|
89
|
+
def statement_type
|
90
|
+
i = _statement_type
|
91
|
+
Converter::IntToSym.statement_type_to_sym(i)
|
107
92
|
end
|
108
93
|
|
109
94
|
def enum_dictionary_values(col_index)
|
@@ -113,29 +98,5 @@ module DuckDB
|
|
113
98
|
end
|
114
99
|
values
|
115
100
|
end
|
116
|
-
|
117
|
-
private
|
118
|
-
|
119
|
-
def _to_hugeint(row, col)
|
120
|
-
warn("#{self.class}##{__method__} will be deprecated.")
|
121
|
-
_to_string(row, col).to_i
|
122
|
-
end
|
123
|
-
|
124
|
-
def _to_hugeint_internal(row, col)
|
125
|
-
warn("#{self.class}##{__method__} will be deprecated.")
|
126
|
-
lower, upper = __to_hugeint_internal(row, col)
|
127
|
-
Converter._to_hugeint_from_vector(lower, upper)
|
128
|
-
end
|
129
|
-
|
130
|
-
def _to_decimal(row, col)
|
131
|
-
warn("#{self.class}##{__method__} will be deprecated.")
|
132
|
-
BigDecimal(_to_string(row, col))
|
133
|
-
end
|
134
|
-
|
135
|
-
def _to_decimal_internal(row, col)
|
136
|
-
warn("#{self.class}##{__method__} will be deprecated.")
|
137
|
-
lower, upper, width, scale = __to_decimal_internal(row, col)
|
138
|
-
Converter._to_decimal_from_hugeint(width, scale, upper, lower)
|
139
|
-
end
|
140
101
|
end
|
141
102
|
end
|
data/lib/duckdb/version.rb
CHANGED