duckdb 0.5.1-dev61.0 → 0.5.1-dev88.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "duckdb",
3
3
  "main": "./lib/duckdb.js",
4
- "version": "0.5.1-dev61.0",
4
+ "version": "0.5.1-dev88.0",
5
5
  "description": "DuckDB node.js API",
6
6
  "gypfile": true,
7
7
  "dependencies": {
package/src/duckdb.cpp CHANGED
@@ -620,7 +620,88 @@ public:
620
620
 
621
621
  } // namespace duckdb
622
622
 
623
+ //===----------------------------------------------------------------------===//
624
+ // DuckDB
625
+ //
626
+ // extension_functions.hpp
627
+ //
628
+ //
629
+ //===----------------------------------------------------------------------===//
630
+
631
+
632
+
633
+
623
634
 
635
+ namespace duckdb {
636
+
637
+ struct ExtensionFunction {
638
+ char function[48];
639
+ char extension[48];
640
+ };
641
+
642
+ static constexpr ExtensionFunction EXTENSION_FUNCTIONS[] = {
643
+ {"->>", "json"},
644
+ {"array_to_json", "json"},
645
+ {"create_fts_index", "fts"},
646
+ {"dbgen", "tpch"},
647
+ {"drop_fts_index", "fts"},
648
+ {"dsdgen", "tpcds"},
649
+ {"excel_text", "excel"},
650
+ {"from_json", "json"},
651
+ {"from_json_strict", "json"},
652
+ {"from_substrait", "substrait"},
653
+ {"get_substrait", "substrait"},
654
+ {"get_substrait_json", "substrait"},
655
+ {"icu_calendar_names", "icu"},
656
+ {"icu_sort_key", "icu"},
657
+ {"json", "json"},
658
+ {"json_array", "json"},
659
+ {"json_array_length", "json"},
660
+ {"json_extract", "json"},
661
+ {"json_extract_path", "json"},
662
+ {"json_extract_path_text", "json"},
663
+ {"json_extract_string", "json"},
664
+ {"json_group_array", "json"},
665
+ {"json_group_object", "json"},
666
+ {"json_group_structure", "json"},
667
+ {"json_merge_patch", "json"},
668
+ {"json_object", "json"},
669
+ {"json_quote", "json"},
670
+ {"json_structure", "json"},
671
+ {"json_transform", "json"},
672
+ {"json_transform_strict", "json"},
673
+ {"json_type", "json"},
674
+ {"json_valid", "json"},
675
+ {"make_timestamptz", "icu"},
676
+ {"parquet_metadata", "parquet"},
677
+ {"parquet_scan", "parquet"},
678
+ {"parquet_schema", "parquet"},
679
+ {"pg_timezone_names", "icu"},
680
+ {"postgres_attach", "postgres_scanner"},
681
+ {"postgres_scan", "postgres_scanner"},
682
+ {"postgres_scan_pushdown", "postgres_scanner"},
683
+ {"read_json_objects", "json"},
684
+ {"read_ndjson_objects", "json"},
685
+ {"read_parquet", "parquet"},
686
+ {"row_to_json", "json"},
687
+ {"sqlite_attach", "sqlite_scanner"},
688
+ {"sqlite_scan", "sqlite_scanner"},
689
+ {"stem", "fts"},
690
+ {"text", "excel"},
691
+ {"to_json", "json"},
692
+ {"tpcds", "tpcds"},
693
+ {"tpcds_answers", "tpcds"},
694
+ {"tpcds_queries", "tpcds"},
695
+ {"tpch", "tpch"},
696
+ {"tpch_answers", "tpch"},
697
+ {"tpch_queries", "tpch"},
698
+ {"visualize_diff_profiling_output", "visualizer"},
699
+ {"visualize_json_profiling_output", "visualizer"},
700
+ {"visualize_last_profiling_output", "visualizer"},
701
+ };
702
+ } // namespace duckdb
703
+
704
+ #include <algorithm>
624
705
  namespace duckdb {
625
706
 
626
707
  string SimilarCatalogEntry::GetQualifiedName() const {
@@ -823,6 +904,16 @@ SimilarCatalogEntry Catalog::SimilarEntryInSchemas(ClientContext &context, const
823
904
  return {most_similar.first, most_similar.second, schema_of_most_similar};
824
905
  }
825
906
 
907
+ string FindExtension(const string &function_name) {
908
+ auto size = sizeof(EXTENSION_FUNCTIONS) / sizeof(ExtensionFunction);
909
+ auto it = std::lower_bound(
910
+ EXTENSION_FUNCTIONS, EXTENSION_FUNCTIONS + size, function_name,
911
+ [](const ExtensionFunction &element, const string &value) { return element.function < value; });
912
+ if (it != EXTENSION_FUNCTIONS + size && it->function == function_name) {
913
+ return it->extension;
914
+ }
915
+ return "";
916
+ }
826
917
  CatalogException Catalog::CreateMissingEntryException(ClientContext &context, const string &entry_name,
827
918
  CatalogType type, const vector<SchemaCatalogEntry *> &schemas,
828
919
  QueryErrorContext error_context) {
@@ -836,7 +927,12 @@ CatalogException Catalog::CreateMissingEntryException(ClientContext &context, co
836
927
  }
837
928
  });
838
929
  auto unseen_entry = SimilarEntryInSchemas(context, entry_name, type, unseen_schemas);
839
-
930
+ auto extension_name = FindExtension(entry_name);
931
+ if (!extension_name.empty()) {
932
+ return CatalogException("Function with name %s is not on the catalog, but it exists in the %s extension. To "
933
+ "Install and Load the extension, run: INSTALL %s; LOAD %s;",
934
+ entry_name, extension_name, extension_name, extension_name);
935
+ }
840
936
  string did_you_mean;
841
937
  if (unseen_entry.Found() && unseen_entry.distance < entry.distance) {
842
938
  did_you_mean = "\nDid you mean \"" + unseen_entry.GetQualifiedName() + "\"?";
@@ -47605,11 +47701,36 @@ Value Value::CreateValue(dtime_t value) {
47605
47701
  return Value::TIME(value);
47606
47702
  }
47607
47703
 
47704
+ template <>
47705
+ Value Value::CreateValue(dtime_tz_t value) {
47706
+ return Value::TIMETZ(value);
47707
+ }
47708
+
47608
47709
  template <>
47609
47710
  Value Value::CreateValue(timestamp_t value) {
47610
47711
  return Value::TIMESTAMP(value);
47611
47712
  }
47612
47713
 
47714
+ template <>
47715
+ Value Value::CreateValue(timestamp_sec_t value) {
47716
+ return Value::TIMESTAMPSEC(value);
47717
+ }
47718
+
47719
+ template <>
47720
+ Value Value::CreateValue(timestamp_ms_t value) {
47721
+ return Value::TIMESTAMPMS(value);
47722
+ }
47723
+
47724
+ template <>
47725
+ Value Value::CreateValue(timestamp_ns_t value) {
47726
+ return Value::TIMESTAMPNS(value);
47727
+ }
47728
+
47729
+ template <>
47730
+ Value Value::CreateValue(timestamp_tz_t value) {
47731
+ return Value::TIMESTAMPTZ(value);
47732
+ }
47733
+
47613
47734
  template <>
47614
47735
  Value Value::CreateValue(const char *value) {
47615
47736
  return Value(string(value));
@@ -49182,19 +49303,6 @@ void Vector::Resize(idx_t cur_size, idx_t new_size) {
49182
49303
  }
49183
49304
  }
49184
49305
 
49185
- // FIXME Just like DECIMAL, it's important that type_info gets considered when determining whether or not to cast
49186
- // just comparing internal type is not always enough
49187
- static bool ValueShouldBeCast(const LogicalType &incoming, const LogicalType &target) {
49188
- if (incoming.InternalType() != target.InternalType()) {
49189
- return true;
49190
- }
49191
- if (incoming.id() == LogicalTypeId::DECIMAL && incoming.id() == target.id()) {
49192
- //! Compare the type_info
49193
- return incoming != target;
49194
- }
49195
- return false;
49196
- }
49197
-
49198
49306
  void Vector::SetValue(idx_t index, const Value &val) {
49199
49307
  if (GetVectorType() == VectorType::DICTIONARY_VECTOR) {
49200
49308
  // dictionary: apply dictionary and forward to child
@@ -49202,10 +49310,11 @@ void Vector::SetValue(idx_t index, const Value &val) {
49202
49310
  auto &child = DictionaryVector::Child(*this);
49203
49311
  return child.SetValue(sel_vector.get_index(index), val);
49204
49312
  }
49205
- if (ValueShouldBeCast(val.type(), GetType())) {
49313
+ if (val.type() != GetType()) {
49206
49314
  SetValue(index, val.CastAs(GetType()));
49207
49315
  return;
49208
49316
  }
49317
+ D_ASSERT(val.type().InternalType() == GetType().InternalType());
49209
49318
 
49210
49319
  validity.EnsureWritable();
49211
49320
  validity.Set(index, !val.IsNull());
@@ -49456,7 +49565,10 @@ Value Vector::GetValue(const Vector &v_p, idx_t index_p) {
49456
49565
  auto value = GetValueInternal(v_p, index_p);
49457
49566
  // set the alias of the type to the correct value, if there is a type alias
49458
49567
  if (v_p.GetType().HasAlias()) {
49459
- value.type().SetAlias(v_p.GetType().GetAlias());
49568
+ value.type().CopyAuxInfo(v_p.GetType());
49569
+ }
49570
+ if (v_p.GetType().id() != LogicalTypeId::AGGREGATE_STATE && value.type().id() != LogicalTypeId::AGGREGATE_STATE) {
49571
+ D_ASSERT(v_p.GetType() == value.type());
49460
49572
  }
49461
49573
  return value;
49462
49574
  }
@@ -51523,6 +51635,7 @@ public:
51523
51635
  if (!alias.empty()) {
51524
51636
  return false;
51525
51637
  }
51638
+ //! We only need to compare aliases when both types have them in this case
51526
51639
  return true;
51527
51640
  }
51528
51641
  if (alias != other_p->alias) {
@@ -51536,8 +51649,7 @@ public:
51536
51649
  if (type != other_p->type) {
51537
51650
  return false;
51538
51651
  }
51539
- auto &other = (ExtraTypeInfo &)*other_p;
51540
- return alias == other.alias && EqualsInternal(other_p);
51652
+ return alias == other_p->alias && EqualsInternal(other_p);
51541
51653
  }
51542
51654
  //! Serializes a ExtraTypeInfo to a stand-alone binary blob
51543
51655
  virtual void Serialize(FieldWriter &writer) const {};
@@ -52216,10 +52328,7 @@ LogicalType LogicalType::Deserialize(Deserializer &source) {
52216
52328
  return LogicalType(id, move(info));
52217
52329
  }
52218
52330
 
52219
- bool LogicalType::operator==(const LogicalType &rhs) const {
52220
- if (id_ != rhs.id_) {
52221
- return false;
52222
- }
52331
+ bool LogicalType::EqualTypeInfo(const LogicalType &rhs) const {
52223
52332
  if (type_info_.get() == rhs.type_info_.get()) {
52224
52333
  return true;
52225
52334
  }
@@ -52231,6 +52340,13 @@ bool LogicalType::operator==(const LogicalType &rhs) const {
52231
52340
  }
52232
52341
  }
52233
52342
 
52343
+ bool LogicalType::operator==(const LogicalType &rhs) const {
52344
+ if (id_ != rhs.id_) {
52345
+ return false;
52346
+ }
52347
+ return EqualTypeInfo(rhs);
52348
+ }
52349
+
52234
52350
  } // namespace duckdb
52235
52351
 
52236
52352
 
@@ -93315,21 +93431,21 @@ AggregateFunction GetHistogramFunction(const LogicalType &type) {
93315
93431
  case LogicalType::VARCHAR:
93316
93432
  return GetMapType<HistogramStringFunctor, string, IS_ORDERED>(type);
93317
93433
  case LogicalType::TIMESTAMP:
93318
- return GetMapType<HistogramFunctor, int64_t, IS_ORDERED>(type);
93434
+ return GetMapType<HistogramFunctor, timestamp_t, IS_ORDERED>(type);
93319
93435
  case LogicalType::TIMESTAMP_TZ:
93320
- return GetMapType<HistogramFunctor, int64_t, IS_ORDERED>(type);
93436
+ return GetMapType<HistogramFunctor, timestamp_tz_t, IS_ORDERED>(type);
93321
93437
  case LogicalType::TIMESTAMP_S:
93322
- return GetMapType<HistogramFunctor, int64_t, IS_ORDERED>(type);
93438
+ return GetMapType<HistogramFunctor, timestamp_sec_t, IS_ORDERED>(type);
93323
93439
  case LogicalType::TIMESTAMP_MS:
93324
- return GetMapType<HistogramFunctor, int64_t, IS_ORDERED>(type);
93440
+ return GetMapType<HistogramFunctor, timestamp_ms_t, IS_ORDERED>(type);
93325
93441
  case LogicalType::TIMESTAMP_NS:
93326
- return GetMapType<HistogramFunctor, int64_t, IS_ORDERED>(type);
93442
+ return GetMapType<HistogramFunctor, timestamp_ns_t, IS_ORDERED>(type);
93327
93443
  case LogicalType::TIME:
93328
- return GetMapType<HistogramFunctor, int64_t, IS_ORDERED>(type);
93444
+ return GetMapType<HistogramFunctor, dtime_t, IS_ORDERED>(type);
93329
93445
  case LogicalType::TIME_TZ:
93330
- return GetMapType<HistogramFunctor, int64_t, IS_ORDERED>(type);
93446
+ return GetMapType<HistogramFunctor, dtime_tz_t, IS_ORDERED>(type);
93331
93447
  case LogicalType::DATE:
93332
- return GetMapType<HistogramFunctor, int32_t, IS_ORDERED>(type);
93448
+ return GetMapType<HistogramFunctor, date_t, IS_ORDERED>(type);
93333
93449
  default:
93334
93450
  throw InternalException("Unimplemented histogram aggregate");
93335
93451
  }
@@ -103278,12 +103394,49 @@ static void ListAggregatesFunction(DataChunk &args, ExpressionState &state, Vect
103278
103394
  result, state_vector.state_vector, count);
103279
103395
  break;
103280
103396
  case PhysicalType::INT32:
103281
- FUNCTION_FUNCTOR::template ListExecuteFunction<FinalizeValueFunctor, int32_t>(
103282
- result, state_vector.state_vector, count);
103397
+ if (key_type.id() == LogicalTypeId::DATE) {
103398
+ FUNCTION_FUNCTOR::template ListExecuteFunction<FinalizeValueFunctor, date_t>(
103399
+ result, state_vector.state_vector, count);
103400
+ } else {
103401
+ FUNCTION_FUNCTOR::template ListExecuteFunction<FinalizeValueFunctor, int32_t>(
103402
+ result, state_vector.state_vector, count);
103403
+ }
103283
103404
  break;
103284
103405
  case PhysicalType::INT64:
103285
- FUNCTION_FUNCTOR::template ListExecuteFunction<FinalizeValueFunctor, int64_t>(
103286
- result, state_vector.state_vector, count);
103406
+ switch (key_type.id()) {
103407
+ case LogicalTypeId::TIME:
103408
+ FUNCTION_FUNCTOR::template ListExecuteFunction<FinalizeValueFunctor, dtime_t>(
103409
+ result, state_vector.state_vector, count);
103410
+ break;
103411
+ case LogicalTypeId::TIME_TZ:
103412
+ FUNCTION_FUNCTOR::template ListExecuteFunction<FinalizeValueFunctor, dtime_tz_t>(
103413
+ result, state_vector.state_vector, count);
103414
+ break;
103415
+ case LogicalTypeId::TIMESTAMP:
103416
+ FUNCTION_FUNCTOR::template ListExecuteFunction<FinalizeValueFunctor, timestamp_t>(
103417
+ result, state_vector.state_vector, count);
103418
+ break;
103419
+ case LogicalTypeId::TIMESTAMP_MS:
103420
+ FUNCTION_FUNCTOR::template ListExecuteFunction<FinalizeValueFunctor, timestamp_ms_t>(
103421
+ result, state_vector.state_vector, count);
103422
+ break;
103423
+ case LogicalTypeId::TIMESTAMP_NS:
103424
+ FUNCTION_FUNCTOR::template ListExecuteFunction<FinalizeValueFunctor, timestamp_ns_t>(
103425
+ result, state_vector.state_vector, count);
103426
+ break;
103427
+ case LogicalTypeId::TIMESTAMP_SEC:
103428
+ FUNCTION_FUNCTOR::template ListExecuteFunction<FinalizeValueFunctor, timestamp_sec_t>(
103429
+ result, state_vector.state_vector, count);
103430
+ break;
103431
+ case LogicalTypeId::TIMESTAMP_TZ:
103432
+ FUNCTION_FUNCTOR::template ListExecuteFunction<FinalizeValueFunctor, timestamp_tz_t>(
103433
+ result, state_vector.state_vector, count);
103434
+ break;
103435
+ default:
103436
+ FUNCTION_FUNCTOR::template ListExecuteFunction<FinalizeValueFunctor, int64_t>(
103437
+ result, state_vector.state_vector, count);
103438
+ break;
103439
+ }
103287
103440
  break;
103288
103441
  case PhysicalType::FLOAT:
103289
103442
  FUNCTION_FUNCTOR::template ListExecuteFunction<FinalizeValueFunctor, float>(
package/src/duckdb.hpp CHANGED
@@ -11,8 +11,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
11
11
  #pragma once
12
12
  #define DUCKDB_AMALGAMATION 1
13
13
  #define DUCKDB_AMALGAMATION_EXTENDED 1
14
- #define DUCKDB_SOURCE_ID "8a4d0609c"
15
- #define DUCKDB_VERSION "v0.5.1-dev61"
14
+ #define DUCKDB_SOURCE_ID "0d13deb75"
15
+ #define DUCKDB_VERSION "v0.5.1-dev88"
16
16
  //===----------------------------------------------------------------------===//
17
17
  // DuckDB
18
18
  //
@@ -670,7 +670,7 @@ struct date_t { // NOLINT
670
670
 
671
671
  //! Type used to represent time (microseconds)
672
672
  struct dtime_t { // NOLINT
673
- int64_t micros;
673
+ int64_t micros;
674
674
 
675
675
  dtime_t() = default;
676
676
  explicit inline dtime_t(int64_t micros_p) : micros(micros_p) {}
@@ -705,9 +705,11 @@ struct dtime_t { // NOLINT
705
705
  static inline dtime_t allballs() {return dtime_t(0); } // NOLINT
706
706
  };
707
707
 
708
+ struct dtime_tz_t : public dtime_t {};
709
+
708
710
  //! Type used to represent timestamps (seconds,microseconds,milliseconds or nanoseconds since 1970-01-01)
709
711
  struct timestamp_t { // NOLINT
710
- int64_t value;
712
+ int64_t value;
711
713
 
712
714
  timestamp_t() = default;
713
715
  explicit inline timestamp_t(int64_t value_p) : value(value_p) {}
@@ -738,6 +740,11 @@ struct timestamp_t { // NOLINT
738
740
  static inline timestamp_t epoch() {return timestamp_t(0); } // NOLINT
739
741
  };
740
742
 
743
+ struct timestamp_tz_t : public timestamp_t {};
744
+ struct timestamp_ns_t : public timestamp_t {};
745
+ struct timestamp_ms_t : public timestamp_t {};
746
+ struct timestamp_sec_t : public timestamp_t {};
747
+
741
748
  struct interval_t {
742
749
  int32_t months;
743
750
  int32_t days;
@@ -1021,6 +1028,10 @@ struct LogicalType {
1021
1028
  inline const ExtraTypeInfo *AuxInfo() const {
1022
1029
  return type_info_.get();
1023
1030
  }
1031
+ inline void CopyAuxInfo(const LogicalType& other) {
1032
+ type_info_ = other.type_info_;
1033
+ }
1034
+ bool EqualTypeInfo(const LogicalType& rhs) const;
1024
1035
 
1025
1036
  // copy assignment
1026
1037
  inline LogicalType& operator=(const LogicalType &other) {
@@ -1047,6 +1058,16 @@ struct LogicalType {
1047
1058
  //! Deserializes a blob back into an LogicalType
1048
1059
  DUCKDB_API static LogicalType Deserialize(Deserializer &source);
1049
1060
 
1061
+ DUCKDB_API static bool TypeIsTimestamp(LogicalTypeId id) {
1062
+ return (id == LogicalTypeId::TIMESTAMP ||
1063
+ id == LogicalTypeId::TIMESTAMP_MS ||
1064
+ id == LogicalTypeId::TIMESTAMP_NS ||
1065
+ id == LogicalTypeId::TIMESTAMP_SEC ||
1066
+ id == LogicalTypeId::TIMESTAMP_TZ);
1067
+ }
1068
+ DUCKDB_API static bool TypeIsTimestamp(const LogicalType& type) {
1069
+ return TypeIsTimestamp(type.id());
1070
+ }
1050
1071
  DUCKDB_API string ToString() const;
1051
1072
  DUCKDB_API bool IsIntegral() const;
1052
1073
  DUCKDB_API bool IsNumeric() const;
@@ -1263,6 +1284,87 @@ struct aggregate_state_t {
1263
1284
 
1264
1285
  } // namespace duckdb
1265
1286
 
1287
+ namespace std {
1288
+
1289
+ //! Date
1290
+ template <>
1291
+ struct hash<duckdb::date_t>
1292
+ {
1293
+ std::size_t operator()(const duckdb::date_t& k) const
1294
+ {
1295
+ using std::hash;
1296
+ return hash<int32_t>()((int32_t)k);
1297
+ }
1298
+ };
1299
+
1300
+ //! Time
1301
+ template <>
1302
+ struct hash<duckdb::dtime_t>
1303
+ {
1304
+ std::size_t operator()(const duckdb::dtime_t& k) const
1305
+ {
1306
+ using std::hash;
1307
+ return hash<int64_t>()((int64_t)k);
1308
+ }
1309
+ };
1310
+ template <>
1311
+ struct hash<duckdb::dtime_tz_t>
1312
+ {
1313
+ std::size_t operator()(const duckdb::dtime_tz_t& k) const
1314
+ {
1315
+ using std::hash;
1316
+ return hash<int64_t>()((int64_t)k);
1317
+ }
1318
+ };
1319
+
1320
+ //! Timestamp
1321
+ template <>
1322
+ struct hash<duckdb::timestamp_t>
1323
+ {
1324
+ std::size_t operator()(const duckdb::timestamp_t& k) const
1325
+ {
1326
+ using std::hash;
1327
+ return hash<int64_t>()((int64_t)k);
1328
+ }
1329
+ };
1330
+ template <>
1331
+ struct hash<duckdb::timestamp_ms_t>
1332
+ {
1333
+ std::size_t operator()(const duckdb::timestamp_ms_t& k) const
1334
+ {
1335
+ using std::hash;
1336
+ return hash<int64_t>()((int64_t)k);
1337
+ }
1338
+ };
1339
+ template <>
1340
+ struct hash<duckdb::timestamp_ns_t>
1341
+ {
1342
+ std::size_t operator()(const duckdb::timestamp_ns_t& k) const
1343
+ {
1344
+ using std::hash;
1345
+ return hash<int64_t>()((int64_t)k);
1346
+ }
1347
+ };
1348
+ template <>
1349
+ struct hash<duckdb::timestamp_sec_t>
1350
+ {
1351
+ std::size_t operator()(const duckdb::timestamp_sec_t& k) const
1352
+ {
1353
+ using std::hash;
1354
+ return hash<int64_t>()((int64_t)k);
1355
+ }
1356
+ };
1357
+ template <>
1358
+ struct hash<duckdb::timestamp_tz_t>
1359
+ {
1360
+ std::size_t operator()(const duckdb::timestamp_tz_t& k) const
1361
+ {
1362
+ using std::hash;
1363
+ return hash<int64_t>()((int64_t)k);
1364
+ }
1365
+ };
1366
+ }
1367
+
1266
1368
 
1267
1369
  namespace duckdb {
1268
1370
 
@@ -3161,8 +3263,18 @@ Value DUCKDB_API Value::CreateValue(date_t value);
3161
3263
  template <>
3162
3264
  Value DUCKDB_API Value::CreateValue(dtime_t value);
3163
3265
  template <>
3266
+ Value DUCKDB_API Value::CreateValue(dtime_tz_t value);
3267
+ template <>
3164
3268
  Value DUCKDB_API Value::CreateValue(timestamp_t value);
3165
3269
  template <>
3270
+ Value DUCKDB_API Value::CreateValue(timestamp_sec_t value);
3271
+ template <>
3272
+ Value DUCKDB_API Value::CreateValue(timestamp_ms_t value);
3273
+ template <>
3274
+ Value DUCKDB_API Value::CreateValue(timestamp_ns_t value);
3275
+ template <>
3276
+ Value DUCKDB_API Value::CreateValue(timestamp_tz_t value);
3277
+ template <>
3166
3278
  Value DUCKDB_API Value::CreateValue(const char *value);
3167
3279
  template <>
3168
3280
  Value DUCKDB_API Value::CreateValue(string value);