duckdb 1.0.0.1 → 1.0.0.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 +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
|