duckdb 1.0.0.1 → 1.0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/test_on_macos.yml +13 -1
- data/.github/workflows/test_on_ubuntu.yml +13 -1
- data/CHANGELOG.md +12 -0
- data/Dockerfile +1 -1
- data/Gemfile.lock +2 -2
- data/ext/duckdb/extconf.rb +2 -0
- data/ext/duckdb/result.c +188 -134
- data/lib/duckdb/converter.rb +59 -0
- data/lib/duckdb/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2a632e159017449943e06edae0808189967be14845c29b479cb77a0d9e6b9da7
|
4
|
+
data.tar.gz: ec7b9c0f6d34aa943436e9525e914759dbd775d8c9a02b1eff991e2a03ade249
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e50c031a4d9f38a87eb77996c90f90a36c4c5f840694bad4a7ce79dcf3d2e439b30fee8e41a21522285ff7db5293e6fa059186c958f7fbed99089455b4ea04db
|
7
|
+
data.tar.gz: 65b7187a73f43b89a8ec8997edcce562af456e3b89f697b4e25c23ae114ed712916643d39c81ef323a1b47b6ac4783e384c53477d177a9d73271859e31c0f970
|
@@ -45,11 +45,23 @@ jobs:
|
|
45
45
|
cp -rip duckdb-tmp-v$DUCKDB_VERSION/build/release/src/*.dylib 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:
|
48
|
+
- name: bundle install with Ruby ${{ matrix.ruby }}
|
49
49
|
env:
|
50
50
|
DUCKDB_VERSION: ${{ matrix.duckdb }}
|
51
51
|
run: |
|
52
52
|
bundle install --jobs 4 --retry 3
|
53
|
+
|
54
|
+
- name: Build test with DUCKDB_API_NO_DEPRECATED and Ruby ${{ matrix.ruby }}
|
55
|
+
env:
|
56
|
+
DUCKDB_VERSION: ${{ matrix.duckdb }}
|
57
|
+
run: |
|
58
|
+
env DUCKDB_API_NO_DEPRECATED=1 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/
|
59
|
+
bundle exec rake clean
|
60
|
+
|
61
|
+
- name: Build with Ruby ${{ matrix.ruby }}
|
62
|
+
env:
|
63
|
+
DUCKDB_VERSION: ${{ matrix.duckdb }}
|
64
|
+
run: |
|
53
65
|
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/
|
54
66
|
|
55
67
|
- name: test with Ruby ${{ matrix.ruby }}
|
@@ -45,11 +45,23 @@ 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:
|
48
|
+
- name: bundle install with Ruby ${{ matrix.ruby }}
|
49
49
|
env:
|
50
50
|
DUCKDB_VERSION: ${{ matrix.duckdb }}
|
51
51
|
run: |
|
52
52
|
bundle install --jobs 4 --retry 3
|
53
|
+
|
54
|
+
- name: Build test with DUCKDB_API_NO_DEPRECATED and Ruby ${{ matrix.ruby }}
|
55
|
+
env:
|
56
|
+
DUCKDB_VERSION: ${{ matrix.duckdb }}
|
57
|
+
run: |
|
58
|
+
env DUCKDB_API_NO_DEPRECATED=1 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/
|
59
|
+
bundle exec rake clean
|
60
|
+
|
61
|
+
- name: Build with Ruby ${{ matrix.ruby }}
|
62
|
+
env:
|
63
|
+
DUCKDB_VERSION: ${{ matrix.duckdb }}
|
64
|
+
run: |
|
53
65
|
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/
|
54
66
|
|
55
67
|
- name: test with Ruby ${{ matrix.ruby }}
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
|
5
5
|
## Unreleased
|
6
6
|
|
7
|
+
# 1.0.0.2 - 2024-06-23
|
8
|
+
- DuckDB::Result supports TIMESTAMPTZ column type (only when DuckDB::Result.use_chunk_each is true).
|
9
|
+
- Supporting TIMESTAMPTZ is experimental.
|
10
|
+
- DuckDB::Result supports TIMETZ column type (only when DuckDB::Result.use_chunk_each is true).
|
11
|
+
- DuckDB::Result supports TIMESTAMP_NS column type (only when DuckDB::Result.use_chunk_each is true).
|
12
|
+
- DuckDB::Result supports TIMESTAMP_MS column type (only when DuckDB::Result.use_chunk_each is true).
|
13
|
+
- DuckDB::Result supports TIMESTAMP_S column type (only when DuckDB::Result.use_chunk_each is true).
|
14
|
+
- DuckDB::Result supports STRUCT column type (only when DuckDB::Result.use_chunk_each is true).
|
15
|
+
- DuckDB::Result supports MAP column type (only when DuckDB::Result.use_chunk_each is true).
|
16
|
+
- DuckDB::Result supports UNION column type (only when DuckDB::Result.use_chunk_each is true).
|
17
|
+
- DuckDB::Result supports BIT column type (only when DuckDB::Result.use_chunk_each is true).
|
18
|
+
|
7
19
|
# 1.0.0.1 - 2024-06-16
|
8
20
|
- support fetch the value from UHUGEINT type column.
|
9
21
|
- add `DuckDB::Appender#append_uhugeint`.
|
data/Dockerfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
duckdb (1.0.0.
|
4
|
+
duckdb (1.0.0.2)
|
5
5
|
bigdecimal (>= 3.1.4)
|
6
6
|
|
7
7
|
GEM
|
@@ -10,7 +10,7 @@ GEM
|
|
10
10
|
benchmark-ips (2.13.0)
|
11
11
|
bigdecimal (3.1.8)
|
12
12
|
mini_portile2 (2.8.7)
|
13
|
-
minitest (5.
|
13
|
+
minitest (5.24.0)
|
14
14
|
nokogiri (1.16.6)
|
15
15
|
mini_portile2 (~> 2.8.2)
|
16
16
|
racc (~> 1.4)
|
data/ext/duckdb/extconf.rb
CHANGED
@@ -70,4 +70,6 @@ have_func('duckdb_fetch_chunk', 'duckdb.h')
|
|
70
70
|
# duckdb_parameter_name in duckdb <= 0.9.1 is not found on Windows.
|
71
71
|
have_func('duckdb_parameter_name', 'duckdb.h')
|
72
72
|
|
73
|
+
$CFLAGS << ' -DDUCKDB_API_NO_DEPRECATED' if ENV['DUCKDB_API_NO_DEPRECATED']
|
74
|
+
|
73
75
|
create_makefile('duckdb/duckdb_native')
|
data/ext/duckdb/result.c
CHANGED
@@ -13,6 +13,11 @@ static ID id__to_interval_from_vector;
|
|
13
13
|
static ID id__to_hugeint_from_vector;
|
14
14
|
static ID id__to_decimal_from_hugeint;
|
15
15
|
static ID id__to_uuid_from_vector;
|
16
|
+
static ID id__to_time_from_duckdb_timestamp_s;
|
17
|
+
static ID id__to_time_from_duckdb_timestamp_ms;
|
18
|
+
static ID id__to_time_from_duckdb_timestamp_ns;
|
19
|
+
static ID id__to_time_from_duckdb_time_tz;
|
20
|
+
static ID id__to_time_from_duckdb_timestamp_tz;
|
16
21
|
|
17
22
|
static void deallocate(void *ctx);
|
18
23
|
static VALUE allocate(VALUE klass);
|
@@ -64,12 +69,19 @@ static VALUE vector_varchar(void* vector_data, idx_t row_idx);
|
|
64
69
|
static VALUE vector_hugeint(void* vector_data, idx_t row_idx);
|
65
70
|
static VALUE vector_uhugeint(void* vector_data, idx_t row_idx);
|
66
71
|
static VALUE vector_decimal(duckdb_logical_type ty, void* vector_data, idx_t row_idx);
|
72
|
+
static VALUE vector_timestamp_s(void* vector_data, idx_t row_idx);
|
73
|
+
static VALUE vector_timestamp_ms(void* vector_data, idx_t row_idx);
|
74
|
+
static VALUE vector_timestamp_ns(void* vector_data, idx_t row_idx);
|
67
75
|
static VALUE vector_enum(duckdb_logical_type ty, void* vector_data, idx_t row_idx);
|
68
76
|
static VALUE vector_array(duckdb_logical_type ty, duckdb_vector vector, idx_t row_idx);
|
69
|
-
static VALUE
|
77
|
+
static VALUE vector_value_at(duckdb_vector vector, duckdb_logical_type element_type, idx_t index);
|
70
78
|
static VALUE vector_list(duckdb_logical_type ty, duckdb_vector vector, void* vector_data, idx_t row_idx);
|
71
|
-
static VALUE vector_map(duckdb_logical_type ty, duckdb_vector vector, idx_t row_idx);
|
79
|
+
static VALUE vector_map(duckdb_logical_type ty, duckdb_vector vector, void* vector_data, idx_t row_idx);
|
72
80
|
static VALUE vector_struct(duckdb_logical_type ty, duckdb_vector vector, idx_t row_idx);
|
81
|
+
static VALUE vector_union(duckdb_logical_type ty, duckdb_vector vector, void* vector_data, idx_t row_idx);
|
82
|
+
static VALUE vector_bit(void* vector_data, idx_t row_idx);
|
83
|
+
static VALUE vector_time_tz(void* vector_data, idx_t row_idx);
|
84
|
+
static VALUE vector_timestamp_tz(void* vector_data, idx_t row_idx);
|
73
85
|
static VALUE vector_uuid(void* vector_data, idx_t row_idx);
|
74
86
|
static VALUE vector_value(duckdb_vector vector, idx_t row_idx);
|
75
87
|
|
@@ -711,6 +723,27 @@ static VALUE vector_decimal(duckdb_logical_type ty, void* vector_data, idx_t row
|
|
711
723
|
);
|
712
724
|
}
|
713
725
|
|
726
|
+
static VALUE vector_timestamp_s(void* vector_data, idx_t row_idx) {
|
727
|
+
duckdb_timestamp data = ((duckdb_timestamp *)vector_data)[row_idx];
|
728
|
+
return rb_funcall(mDuckDBConverter, id__to_time_from_duckdb_timestamp_s, 1,
|
729
|
+
LL2NUM(data.micros)
|
730
|
+
);
|
731
|
+
}
|
732
|
+
|
733
|
+
static VALUE vector_timestamp_ms(void* vector_data, idx_t row_idx) {
|
734
|
+
duckdb_timestamp data = ((duckdb_timestamp *)vector_data)[row_idx];
|
735
|
+
return rb_funcall(mDuckDBConverter, id__to_time_from_duckdb_timestamp_ms, 1,
|
736
|
+
LL2NUM(data.micros)
|
737
|
+
);
|
738
|
+
}
|
739
|
+
|
740
|
+
static VALUE vector_timestamp_ns(void* vector_data, idx_t row_idx) {
|
741
|
+
duckdb_timestamp data = ((duckdb_timestamp *)vector_data)[row_idx];
|
742
|
+
return rb_funcall(mDuckDBConverter, id__to_time_from_duckdb_timestamp_ns, 1,
|
743
|
+
LL2NUM(data.micros)
|
744
|
+
);
|
745
|
+
}
|
746
|
+
|
714
747
|
static VALUE vector_enum(duckdb_logical_type ty, void* vector_data, idx_t row_idx) {
|
715
748
|
duckdb_type type = duckdb_enum_internal_type(ty);
|
716
749
|
uint8_t index;
|
@@ -744,7 +777,7 @@ static VALUE vector_array(duckdb_logical_type ty, duckdb_vector vector, idx_t ro
|
|
744
777
|
|
745
778
|
ary = rb_ary_new2(size);
|
746
779
|
for (idx_t i = bgn; i < end; ++i) {
|
747
|
-
value =
|
780
|
+
value = vector_value_at(child, child_logical_type, i);
|
748
781
|
rb_ary_store(ary, i - bgn, value);
|
749
782
|
}
|
750
783
|
|
@@ -752,19 +785,19 @@ static VALUE vector_array(duckdb_logical_type ty, duckdb_vector vector, idx_t ro
|
|
752
785
|
return ary;
|
753
786
|
}
|
754
787
|
|
755
|
-
static VALUE
|
788
|
+
static VALUE vector_value_at(duckdb_vector vector, duckdb_logical_type element_type, idx_t index) {
|
756
789
|
uint64_t *validity;
|
757
790
|
duckdb_type type_id;
|
758
791
|
void* vector_data;
|
759
792
|
VALUE obj = Qnil;
|
760
793
|
|
761
|
-
validity = duckdb_vector_get_validity(
|
794
|
+
validity = duckdb_vector_get_validity(vector);
|
762
795
|
if (!duckdb_validity_row_is_valid(validity, index)) {
|
763
796
|
return Qnil;
|
764
797
|
}
|
765
798
|
|
766
799
|
type_id = duckdb_get_type_id(element_type);
|
767
|
-
vector_data = duckdb_vector_get_data(
|
800
|
+
vector_data = duckdb_vector_get_data(vector);
|
768
801
|
|
769
802
|
switch(type_id) {
|
770
803
|
case DUCKDB_TYPE_INVALID:
|
@@ -797,30 +830,30 @@ static VALUE vector_array_value_at(duckdb_vector array, duckdb_logical_type elem
|
|
797
830
|
case DUCKDB_TYPE_UBIGINT:
|
798
831
|
obj = ULL2NUM(((uint64_t *) vector_data)[index]);
|
799
832
|
break;
|
800
|
-
case DUCKDB_TYPE_HUGEINT:
|
801
|
-
obj = vector_hugeint(vector_data, index);
|
802
|
-
break;
|
803
|
-
case DUCKDB_TYPE_UHUGEINT:
|
804
|
-
obj = vector_uhugeint(vector_data, index);
|
805
|
-
break;
|
806
833
|
case DUCKDB_TYPE_FLOAT:
|
807
834
|
obj = DBL2NUM((((float *) vector_data)[index]));
|
808
835
|
break;
|
809
836
|
case DUCKDB_TYPE_DOUBLE:
|
810
837
|
obj = DBL2NUM((((double *) vector_data)[index]));
|
811
838
|
break;
|
812
|
-
case DUCKDB_TYPE_DATE:
|
813
|
-
obj = vector_date(vector_data, index);
|
814
|
-
break;
|
815
839
|
case DUCKDB_TYPE_TIMESTAMP:
|
816
840
|
obj = vector_timestamp(vector_data, index);
|
817
841
|
break;
|
842
|
+
case DUCKDB_TYPE_DATE:
|
843
|
+
obj = vector_date(vector_data, index);
|
844
|
+
break;
|
818
845
|
case DUCKDB_TYPE_TIME:
|
819
846
|
obj = vector_time(vector_data, index);
|
820
847
|
break;
|
821
848
|
case DUCKDB_TYPE_INTERVAL:
|
822
849
|
obj = vector_interval(vector_data, index);
|
823
850
|
break;
|
851
|
+
case DUCKDB_TYPE_HUGEINT:
|
852
|
+
obj = vector_hugeint(vector_data, index);
|
853
|
+
break;
|
854
|
+
case DUCKDB_TYPE_UHUGEINT:
|
855
|
+
obj = vector_uhugeint(vector_data, index);
|
856
|
+
break;
|
824
857
|
case DUCKDB_TYPE_VARCHAR:
|
825
858
|
obj = vector_varchar(vector_data, index);
|
826
859
|
break;
|
@@ -830,24 +863,45 @@ static VALUE vector_array_value_at(duckdb_vector array, duckdb_logical_type elem
|
|
830
863
|
case DUCKDB_TYPE_DECIMAL:
|
831
864
|
obj = vector_decimal(element_type, vector_data, index);
|
832
865
|
break;
|
866
|
+
case DUCKDB_TYPE_TIMESTAMP_S:
|
867
|
+
obj = vector_timestamp_s(vector_data, index);
|
868
|
+
break;
|
869
|
+
case DUCKDB_TYPE_TIMESTAMP_MS:
|
870
|
+
obj = vector_timestamp_ms(vector_data, index);
|
871
|
+
break;
|
872
|
+
case DUCKDB_TYPE_TIMESTAMP_NS:
|
873
|
+
obj = vector_timestamp_ns(vector_data, index);
|
874
|
+
break;
|
833
875
|
case DUCKDB_TYPE_ENUM:
|
834
876
|
obj = vector_enum(element_type, vector_data, index);
|
835
877
|
break;
|
836
|
-
case DUCKDB_TYPE_ARRAY:
|
837
|
-
obj = vector_array(element_type, array, index);
|
838
|
-
break;
|
839
878
|
case DUCKDB_TYPE_LIST:
|
840
|
-
obj = vector_list(element_type,
|
879
|
+
obj = vector_list(element_type, vector, vector_data, index);
|
880
|
+
break;
|
881
|
+
case DUCKDB_TYPE_STRUCT:
|
882
|
+
obj = vector_struct(element_type, vector, index);
|
841
883
|
break;
|
842
884
|
case DUCKDB_TYPE_MAP:
|
843
|
-
obj = vector_map(element_type, vector_data, index);
|
885
|
+
obj = vector_map(element_type, vector, vector_data, index);
|
844
886
|
break;
|
845
|
-
case
|
846
|
-
obj =
|
887
|
+
case DUCKDB_TYPE_ARRAY:
|
888
|
+
obj = vector_array(element_type, vector, index);
|
847
889
|
break;
|
848
890
|
case DUCKDB_TYPE_UUID:
|
849
891
|
obj = vector_uuid(vector_data, index);
|
850
892
|
break;
|
893
|
+
case DUCKDB_TYPE_UNION:
|
894
|
+
obj = vector_union(element_type, vector, vector_data, index);
|
895
|
+
break;
|
896
|
+
case DUCKDB_TYPE_BIT:
|
897
|
+
obj = vector_bit(vector_data, index);
|
898
|
+
break;
|
899
|
+
case DUCKDB_TYPE_TIME_TZ:
|
900
|
+
obj = vector_time_tz(vector_data, index);
|
901
|
+
break;
|
902
|
+
case DUCKDB_TYPE_TIMESTAMP_TZ:
|
903
|
+
obj = vector_timestamp_tz(vector_data, index);
|
904
|
+
break;
|
851
905
|
default:
|
852
906
|
rb_warn("Unknown type %d", type_id);
|
853
907
|
obj = Qnil;
|
@@ -871,26 +925,36 @@ static VALUE vector_list(duckdb_logical_type ty, duckdb_vector vector, void * ve
|
|
871
925
|
duckdb_vector child = duckdb_list_vector_get_child(vector);
|
872
926
|
|
873
927
|
for (i = bgn; i < end; ++i) {
|
874
|
-
value =
|
928
|
+
value = vector_value_at(child, child_logical_type, i);
|
875
929
|
rb_ary_store(ary, i - bgn, value);
|
876
930
|
}
|
877
931
|
duckdb_destroy_logical_type(&child_logical_type);
|
878
932
|
return ary;
|
879
933
|
}
|
880
934
|
|
881
|
-
static VALUE vector_map(duckdb_logical_type ty, duckdb_vector vector, idx_t row_idx) {
|
935
|
+
static VALUE vector_map(duckdb_logical_type ty, duckdb_vector vector, void* vector_data, idx_t row_idx) {
|
882
936
|
VALUE hash = rb_hash_new();
|
937
|
+
VALUE key = Qnil;
|
938
|
+
VALUE value = Qnil;
|
883
939
|
|
884
940
|
duckdb_logical_type key_logical_type = duckdb_map_type_key_type(ty);
|
885
941
|
duckdb_logical_type value_logical_type = duckdb_map_type_value_type(ty);
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
942
|
+
|
943
|
+
duckdb_list_entry list_entry = ((duckdb_list_entry *)vector_data)[row_idx];
|
944
|
+
|
945
|
+
idx_t bgn = list_entry.offset;
|
946
|
+
idx_t end = bgn + list_entry.length;
|
947
|
+
|
948
|
+
duckdb_vector child = duckdb_list_vector_get_child(vector);
|
949
|
+
duckdb_vector key_vector = duckdb_struct_vector_get_child(child, 0);
|
950
|
+
duckdb_vector value_vector = duckdb_struct_vector_get_child(child, 1);
|
951
|
+
|
952
|
+
for (idx_t i = bgn; i < end; ++i) {
|
953
|
+
key = vector_value_at(key_vector, key_logical_type, i);
|
954
|
+
value = vector_value_at(value_vector, value_logical_type, i);
|
955
|
+
rb_hash_aset(hash, key, value);
|
956
|
+
}
|
957
|
+
|
894
958
|
duckdb_destroy_logical_type(&key_logical_type);
|
895
959
|
duckdb_destroy_logical_type(&value_logical_type);
|
896
960
|
return hash;
|
@@ -900,6 +964,8 @@ static VALUE vector_struct(duckdb_logical_type ty, duckdb_vector vector, idx_t r
|
|
900
964
|
VALUE hash = rb_hash_new();
|
901
965
|
VALUE value = Qnil;
|
902
966
|
VALUE key = Qnil;
|
967
|
+
duckdb_vector child;
|
968
|
+
duckdb_logical_type child_type;
|
903
969
|
char *p;
|
904
970
|
|
905
971
|
idx_t child_count = duckdb_struct_type_child_count(ty);
|
@@ -907,13 +973,12 @@ static VALUE vector_struct(duckdb_logical_type ty, duckdb_vector vector, idx_t r
|
|
907
973
|
for (idx_t i = 0; i < child_count; ++i) {
|
908
974
|
p = duckdb_struct_type_child_name(ty, i);
|
909
975
|
if (p) {
|
910
|
-
key =
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
// duckdb_vector child_vector = duckdb_struct_vector_get_child(vector, i);
|
915
|
-
// VALUE value = vector_value(child_vector, i);
|
976
|
+
key = ID2SYM(rb_intern_const(p));
|
977
|
+
child = duckdb_struct_vector_get_child(vector, i);
|
978
|
+
child_type = duckdb_struct_type_child_type(ty, i);
|
979
|
+
value = vector_value_at(child, child_type, row_idx);
|
916
980
|
rb_hash_aset(hash, key, value);
|
981
|
+
duckdb_destroy_logical_type(&child_type);
|
917
982
|
duckdb_free(p);
|
918
983
|
}
|
919
984
|
}
|
@@ -921,6 +986,85 @@ static VALUE vector_struct(duckdb_logical_type ty, duckdb_vector vector, idx_t r
|
|
921
986
|
return hash;
|
922
987
|
}
|
923
988
|
|
989
|
+
static VALUE vector_union(duckdb_logical_type ty, duckdb_vector vector, void* vector_data, idx_t row_idx){
|
990
|
+
VALUE value = Qnil;
|
991
|
+
duckdb_vector type_vector = duckdb_struct_vector_get_child(vector, 0);
|
992
|
+
void *data = duckdb_vector_get_data(type_vector);
|
993
|
+
uint8_t index = ((int8_t *)data)[row_idx];
|
994
|
+
|
995
|
+
duckdb_logical_type child_type = duckdb_union_type_member_type(ty, index);
|
996
|
+
|
997
|
+
duckdb_vector vector_value = duckdb_struct_vector_get_child(vector, index + 1);
|
998
|
+
value = vector_value_at(vector_value, child_type, row_idx);
|
999
|
+
duckdb_destroy_logical_type(&child_type);
|
1000
|
+
return value;
|
1001
|
+
}
|
1002
|
+
|
1003
|
+
static VALUE str_concat_byte(VALUE str, unsigned char byte, int offset) {
|
1004
|
+
char x[8];
|
1005
|
+
char *p = x;
|
1006
|
+
for (int j = 7; j >=0; j--) {
|
1007
|
+
if (byte % 2 == 1) {
|
1008
|
+
x[j] = '1';
|
1009
|
+
} else {
|
1010
|
+
x[j] = '0';
|
1011
|
+
}
|
1012
|
+
byte = (byte >> 1);
|
1013
|
+
}
|
1014
|
+
if (offset > 0 && offset < 8) {
|
1015
|
+
p = x + offset;
|
1016
|
+
}
|
1017
|
+
return rb_str_cat(str, p, 8 - offset);
|
1018
|
+
}
|
1019
|
+
|
1020
|
+
static VALUE bytes_to_string(char *bytes, uint32_t length, int offset) {
|
1021
|
+
VALUE str = rb_str_new_literal("");
|
1022
|
+
str = str_concat_byte(str, bytes[0], offset);
|
1023
|
+
for (uint32_t i = 1; i < length; i++) {
|
1024
|
+
str = str_concat_byte(str, bytes[i], 0);
|
1025
|
+
}
|
1026
|
+
return str;
|
1027
|
+
}
|
1028
|
+
|
1029
|
+
static VALUE vector_bit(void* vector_data, idx_t row_idx) {
|
1030
|
+
duckdb_string_t s = (((duckdb_string_t *)vector_data)[row_idx]);
|
1031
|
+
char *p;
|
1032
|
+
int offset;
|
1033
|
+
uint32_t length;
|
1034
|
+
VALUE str = Qnil;
|
1035
|
+
|
1036
|
+
if(duckdb_string_is_inlined(s)) {
|
1037
|
+
length = s.value.inlined.length - 1;
|
1038
|
+
p = &s.value.inlined.inlined[1];
|
1039
|
+
offset = s.value.inlined.inlined[0];
|
1040
|
+
str = bytes_to_string(p, length, offset);
|
1041
|
+
} else {
|
1042
|
+
length = s.value.pointer.length - 1;
|
1043
|
+
p = &s.value.pointer.ptr[1];
|
1044
|
+
offset = s.value.pointer.ptr[0];
|
1045
|
+
str = bytes_to_string(p, length, offset);
|
1046
|
+
}
|
1047
|
+
return str;
|
1048
|
+
}
|
1049
|
+
|
1050
|
+
static VALUE vector_time_tz(void* vector_data, idx_t row_idx) {
|
1051
|
+
duckdb_time_tz_struct data = duckdb_from_time_tz(((duckdb_time_tz *)vector_data)[row_idx]);
|
1052
|
+
return rb_funcall(mDuckDBConverter, id__to_time_from_duckdb_time_tz, 5,
|
1053
|
+
INT2FIX(data.time.hour),
|
1054
|
+
INT2FIX(data.time.min),
|
1055
|
+
INT2FIX(data.time.sec),
|
1056
|
+
INT2NUM(data.time.micros),
|
1057
|
+
INT2NUM(data.offset)
|
1058
|
+
);
|
1059
|
+
}
|
1060
|
+
|
1061
|
+
static VALUE vector_timestamp_tz(void* vector_data, idx_t row_idx) {
|
1062
|
+
duckdb_time_tz data = ((duckdb_time_tz *)vector_data)[row_idx];
|
1063
|
+
return rb_funcall(mDuckDBConverter, id__to_time_from_duckdb_timestamp_tz, 1,
|
1064
|
+
ULL2NUM(data.bits)
|
1065
|
+
);
|
1066
|
+
}
|
1067
|
+
|
924
1068
|
static VALUE vector_uuid(void* vector_data, idx_t row_idx) {
|
925
1069
|
duckdb_hugeint hugeint = ((duckdb_hugeint *)vector_data)[row_idx];
|
926
1070
|
return rb_funcall(mDuckDBConverter, id__to_uuid_from_vector, 2,
|
@@ -930,107 +1074,12 @@ static VALUE vector_uuid(void* vector_data, idx_t row_idx) {
|
|
930
1074
|
}
|
931
1075
|
|
932
1076
|
static VALUE vector_value(duckdb_vector vector, idx_t row_idx) {
|
933
|
-
uint64_t *validity;
|
934
1077
|
duckdb_logical_type ty;
|
935
|
-
duckdb_type type_id;
|
936
|
-
void* vector_data;
|
937
1078
|
VALUE obj = Qnil;
|
938
1079
|
|
939
|
-
validity = duckdb_vector_get_validity(vector);
|
940
|
-
if (!duckdb_validity_row_is_valid(validity, row_idx)) {
|
941
|
-
return Qnil;
|
942
|
-
}
|
943
|
-
|
944
1080
|
ty = duckdb_vector_get_column_type(vector);
|
945
|
-
type_id = duckdb_get_type_id(ty);
|
946
|
-
vector_data = duckdb_vector_get_data(vector);
|
947
1081
|
|
948
|
-
|
949
|
-
case DUCKDB_TYPE_INVALID:
|
950
|
-
obj = Qnil;
|
951
|
-
break;
|
952
|
-
case DUCKDB_TYPE_BOOLEAN:
|
953
|
-
obj = (((bool*) vector_data)[row_idx]) ? Qtrue : Qfalse;
|
954
|
-
break;
|
955
|
-
case DUCKDB_TYPE_TINYINT:
|
956
|
-
obj = INT2FIX(((int8_t *) vector_data)[row_idx]);
|
957
|
-
break;
|
958
|
-
case DUCKDB_TYPE_SMALLINT:
|
959
|
-
obj = INT2FIX(((int16_t *) vector_data)[row_idx]);
|
960
|
-
break;
|
961
|
-
case DUCKDB_TYPE_INTEGER:
|
962
|
-
obj = INT2NUM(((int32_t *) vector_data)[row_idx]);
|
963
|
-
break;
|
964
|
-
case DUCKDB_TYPE_BIGINT:
|
965
|
-
obj = LL2NUM(((int64_t *) vector_data)[row_idx]);
|
966
|
-
break;
|
967
|
-
case DUCKDB_TYPE_UTINYINT:
|
968
|
-
obj = INT2FIX(((uint8_t *) vector_data)[row_idx]);
|
969
|
-
break;
|
970
|
-
case DUCKDB_TYPE_USMALLINT:
|
971
|
-
obj = INT2FIX(((uint16_t *) vector_data)[row_idx]);
|
972
|
-
break;
|
973
|
-
case DUCKDB_TYPE_UINTEGER:
|
974
|
-
obj = UINT2NUM(((uint32_t *) vector_data)[row_idx]);
|
975
|
-
break;
|
976
|
-
case DUCKDB_TYPE_UBIGINT:
|
977
|
-
obj = ULL2NUM(((uint64_t *) vector_data)[row_idx]);
|
978
|
-
break;
|
979
|
-
case DUCKDB_TYPE_HUGEINT:
|
980
|
-
obj = vector_hugeint(vector_data, row_idx);
|
981
|
-
break;
|
982
|
-
case DUCKDB_TYPE_UHUGEINT:
|
983
|
-
obj = vector_uhugeint(vector_data, row_idx);
|
984
|
-
break;
|
985
|
-
case DUCKDB_TYPE_FLOAT:
|
986
|
-
obj = DBL2NUM((((float *) vector_data)[row_idx]));
|
987
|
-
break;
|
988
|
-
case DUCKDB_TYPE_DOUBLE:
|
989
|
-
obj = DBL2NUM((((double *) vector_data)[row_idx]));
|
990
|
-
break;
|
991
|
-
case DUCKDB_TYPE_DATE:
|
992
|
-
obj = vector_date(vector_data, row_idx);
|
993
|
-
break;
|
994
|
-
case DUCKDB_TYPE_TIMESTAMP:
|
995
|
-
obj = vector_timestamp(vector_data, row_idx);
|
996
|
-
break;
|
997
|
-
case DUCKDB_TYPE_TIME:
|
998
|
-
obj = vector_time(vector_data, row_idx);
|
999
|
-
break;
|
1000
|
-
case DUCKDB_TYPE_INTERVAL:
|
1001
|
-
obj = vector_interval(vector_data, row_idx);
|
1002
|
-
break;
|
1003
|
-
case DUCKDB_TYPE_VARCHAR:
|
1004
|
-
obj = vector_varchar(vector_data, row_idx);
|
1005
|
-
break;
|
1006
|
-
case DUCKDB_TYPE_BLOB:
|
1007
|
-
obj = vector_blob(vector_data, row_idx);
|
1008
|
-
break;
|
1009
|
-
case DUCKDB_TYPE_DECIMAL:
|
1010
|
-
obj = vector_decimal(ty, vector_data, row_idx);
|
1011
|
-
break;
|
1012
|
-
case DUCKDB_TYPE_ENUM:
|
1013
|
-
obj = vector_enum(ty, vector_data, row_idx);
|
1014
|
-
break;
|
1015
|
-
case DUCKDB_TYPE_ARRAY:
|
1016
|
-
obj = vector_array(ty, vector, row_idx);
|
1017
|
-
break;
|
1018
|
-
case DUCKDB_TYPE_LIST:
|
1019
|
-
obj = vector_list(ty, vector, vector_data, row_idx);
|
1020
|
-
break;
|
1021
|
-
case DUCKDB_TYPE_MAP:
|
1022
|
-
obj = vector_map(ty, vector_data, row_idx);
|
1023
|
-
break;
|
1024
|
-
case DUCKDB_TYPE_STRUCT:
|
1025
|
-
obj = vector_struct(ty, vector_data, row_idx);
|
1026
|
-
break;
|
1027
|
-
case DUCKDB_TYPE_UUID:
|
1028
|
-
obj = vector_uuid(vector_data, row_idx);
|
1029
|
-
break;
|
1030
|
-
default:
|
1031
|
-
rb_warn("Unknown type %d", type_id);
|
1032
|
-
obj = Qnil;
|
1033
|
-
}
|
1082
|
+
obj = vector_value_at(vector, ty, row_idx);
|
1034
1083
|
|
1035
1084
|
duckdb_destroy_logical_type(&ty);
|
1036
1085
|
return obj;
|
@@ -1045,6 +1094,11 @@ void rbduckdb_init_duckdb_result(void) {
|
|
1045
1094
|
id__to_hugeint_from_vector = rb_intern("_to_hugeint_from_vector");
|
1046
1095
|
id__to_decimal_from_hugeint = rb_intern("_to_decimal_from_hugeint");
|
1047
1096
|
id__to_uuid_from_vector = rb_intern("_to_uuid_from_vector");
|
1097
|
+
id__to_time_from_duckdb_timestamp_s = rb_intern("_to_time_from_duckdb_timestamp_s");
|
1098
|
+
id__to_time_from_duckdb_timestamp_ms = rb_intern("_to_time_from_duckdb_timestamp_ms");
|
1099
|
+
id__to_time_from_duckdb_timestamp_ns = rb_intern("_to_time_from_duckdb_timestamp_ns");
|
1100
|
+
id__to_time_from_duckdb_time_tz = rb_intern("_to_time_from_duckdb_time_tz");
|
1101
|
+
id__to_time_from_duckdb_timestamp_tz = rb_intern("_to_time_from_duckdb_timestamp_tz");
|
1048
1102
|
|
1049
1103
|
rb_define_alloc_func(cDuckDBResult, allocate);
|
1050
1104
|
|
data/lib/duckdb/converter.rb
CHANGED
@@ -10,6 +10,8 @@ module DuckDB
|
|
10
10
|
HALF_HUGEINT_BIT = 64
|
11
11
|
HALF_HUGEINT = 1 << HALF_HUGEINT_BIT
|
12
12
|
FLIP_HUGEINT = 1 << 63
|
13
|
+
EPOCH = Time.local(1970, 1, 1)
|
14
|
+
EPOCH_UTC = Time.new(1970, 1, 1, 0, 0, 0, 0)
|
13
15
|
|
14
16
|
module_function
|
15
17
|
|
@@ -33,6 +35,63 @@ module DuckDB
|
|
33
35
|
)
|
34
36
|
end
|
35
37
|
|
38
|
+
def _to_time_from_duckdb_timestamp_s(time)
|
39
|
+
EPOCH + time
|
40
|
+
end
|
41
|
+
|
42
|
+
def _to_time_from_duckdb_timestamp_ms(time)
|
43
|
+
tm = EPOCH + (time / 1000)
|
44
|
+
Time.local(tm.year, tm.month, tm.day, tm.hour, tm.min, tm.sec, time % 1000 * 1000)
|
45
|
+
end
|
46
|
+
|
47
|
+
def _to_time_from_duckdb_timestamp_ns(time)
|
48
|
+
tm = EPOCH + (time / 1_000_000_000)
|
49
|
+
Time.local(tm.year, tm.month, tm.day, tm.hour, tm.min, tm.sec, time % 1_000_000_000 / 1000)
|
50
|
+
end
|
51
|
+
|
52
|
+
def _to_time_from_duckdb_time_tz(hour, min, sec, micro, timezone)
|
53
|
+
sign = '+'
|
54
|
+
if timezone.negative?
|
55
|
+
timezone = -timezone
|
56
|
+
sign = '-'
|
57
|
+
end
|
58
|
+
|
59
|
+
tzhour = timezone / 3600
|
60
|
+
tzmin = (timezone % 3600) / 60
|
61
|
+
|
62
|
+
Time.parse(
|
63
|
+
format(
|
64
|
+
'%<hour>02d:%<min>02d:%<sec>02d.%<micro>06d%<sign>s%<tzhour>02d:%<tzmin>02d',
|
65
|
+
hour: hour,
|
66
|
+
min: min,
|
67
|
+
sec: sec,
|
68
|
+
micro: micro,
|
69
|
+
sign: sign,
|
70
|
+
tzhour: tzhour,
|
71
|
+
tzmin: tzmin
|
72
|
+
)
|
73
|
+
)
|
74
|
+
end
|
75
|
+
|
76
|
+
def _to_time_from_duckdb_timestamp_tz(bits)
|
77
|
+
micro = bits % 1_000_000
|
78
|
+
sec = (bits / 1_000_000)
|
79
|
+
time = EPOCH_UTC + sec
|
80
|
+
|
81
|
+
Time.parse(
|
82
|
+
format(
|
83
|
+
'%<year>04d-%<mon>02d-%<day>02d %<hour>02d:%<min>02d:%<sec>02d.%<micro>06d +0000',
|
84
|
+
year: time.year,
|
85
|
+
mon: time.month,
|
86
|
+
day: time.day,
|
87
|
+
hour: time.hour,
|
88
|
+
min: time.min,
|
89
|
+
sec: time.sec,
|
90
|
+
micro: micro
|
91
|
+
)
|
92
|
+
)
|
93
|
+
end
|
94
|
+
|
36
95
|
def _to_hugeint_from_vector(lower, upper)
|
37
96
|
(upper << HALF_HUGEINT_BIT) + lower
|
38
97
|
end
|
data/lib/duckdb/version.rb
CHANGED
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.0.0.
|
4
|
+
version: 1.0.0.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: 2024-06-
|
11
|
+
date: 2024-06-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bigdecimal
|