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 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