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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4ec35034af422ec8f64f8474e95321a72a635925227fa8b5c26b3a430a4283a6
4
- data.tar.gz: 52fb59085c80865dd6c51a5f7cb93b0e3eb2940245b4df580040753d364bd989
3
+ metadata.gz: 2a632e159017449943e06edae0808189967be14845c29b479cb77a0d9e6b9da7
4
+ data.tar.gz: ec7b9c0f6d34aa943436e9525e914759dbd775d8c9a02b1eff991e2a03ade249
5
5
  SHA512:
6
- metadata.gz: 00d69fe6df1f7acdb1fac1e8bce26b17d9d7f06802fb8a8ddb287f25831858a69576c0d3558f6e5a48d0761226aae46a9f92d541b9e2547ae7f81f8b65a67441
7
- data.tar.gz: dd8734f7a005a0007336faf58b6b032e6a2dbcf668859483cc9c713eef50ca585df9e564257b6890c9af3c394e82de8e0bd7a42790d3e1c033ffedeb41702e2c
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: Build with Ruby ${{ matrix.ruby }}
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: Build with Ruby ${{ matrix.ruby }}
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
@@ -1,4 +1,4 @@
1
- ARG RUBY_VERSION=3.3.2
1
+ ARG RUBY_VERSION=3.3.3
2
2
  FROM ruby:${RUBY_VERSION}
3
3
 
4
4
  ARG DUCKDB_VERSION=1.0.0
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- duckdb (1.0.0.1)
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.23.1)
13
+ minitest (5.24.0)
14
14
  nokogiri (1.16.6)
15
15
  mini_portile2 (~> 2.8.2)
16
16
  racc (~> 1.4)
@@ -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 vector_array_value_at(duckdb_vector array, duckdb_logical_type element_type, idx_t index);
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 = vector_array_value_at(child, child_logical_type, i);
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 vector_array_value_at(duckdb_vector array, duckdb_logical_type element_type, idx_t index) {
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(array);
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(array);
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, array, vector_data, index);
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 DUCKDB_TYPE_STRUCT:
846
- obj = vector_struct(element_type, vector_data, index);
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 = vector_array_value_at(child, child_logical_type, i);
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
- // duckdb_type key_type = duckdb_get_type_id(key_logical_type);
887
- // duckdb_type value_type = duckdb_get_type_id(value_logical_type);
888
-
889
- /*
890
- * FIXME: How to get key and value?
891
- *
892
- * rb_hash_aset(hash, key, value);
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 = rb_str_new2(p);
911
- // FIXME
912
- // How to get Struct values?
913
- // value = ???
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
- switch(type_id) {
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
 
@@ -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
@@ -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.0.0.1'
6
+ VERSION = '1.0.0.2'
7
7
  end
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.1
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-15 00:00:00.000000000 Z
11
+ date: 2024-06-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bigdecimal