duckdb 0.8.2-dev5120.0 → 0.8.2-dev5154.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.
Files changed (29) hide show
  1. package/package.json +1 -1
  2. package/src/duckdb/extension/icu/icu-dateadd.cpp +11 -19
  3. package/src/duckdb/extension/icu/icu-datepart.cpp +44 -53
  4. package/src/duckdb/extension/icu/icu-datesub.cpp +10 -15
  5. package/src/duckdb/extension/icu/icu-datetrunc.cpp +6 -8
  6. package/src/duckdb/extension/icu/icu-list-range.cpp +6 -8
  7. package/src/duckdb/extension/icu/icu-makedate.cpp +8 -10
  8. package/src/duckdb/extension/icu/icu-strptime.cpp +30 -32
  9. package/src/duckdb/extension/icu/icu-table-range.cpp +6 -9
  10. package/src/duckdb/extension/icu/icu-timebucket.cpp +5 -7
  11. package/src/duckdb/extension/icu/icu-timezone.cpp +18 -29
  12. package/src/duckdb/extension/icu/icu_extension.cpp +18 -25
  13. package/src/duckdb/extension/icu/include/icu-dateadd.hpp +1 -1
  14. package/src/duckdb/extension/icu/include/icu-datepart.hpp +1 -1
  15. package/src/duckdb/extension/icu/include/icu-datesub.hpp +1 -1
  16. package/src/duckdb/extension/icu/include/icu-datetrunc.hpp +1 -1
  17. package/src/duckdb/extension/icu/include/icu-list-range.hpp +1 -1
  18. package/src/duckdb/extension/icu/include/icu-makedate.hpp +1 -1
  19. package/src/duckdb/extension/icu/include/icu-strptime.hpp +1 -1
  20. package/src/duckdb/extension/icu/include/icu-table-range.hpp +1 -1
  21. package/src/duckdb/extension/icu/include/icu-timebucket.hpp +1 -1
  22. package/src/duckdb/extension/icu/include/icu-timezone.hpp +1 -1
  23. package/src/duckdb/extension/json/json_functions/read_json.cpp +15 -0
  24. package/src/duckdb/src/catalog/catalog.cpp +4 -0
  25. package/src/duckdb/src/execution/operator/schema/physical_attach.cpp +4 -1
  26. package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
  27. package/src/duckdb/src/include/duckdb/main/extension_entries.hpp +26 -0
  28. package/src/duckdb/src/include/duckdb/main/extension_util.hpp +14 -0
  29. package/src/duckdb/src/main/extension/extension_util.cpp +56 -0
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "duckdb",
3
3
  "main": "./lib/duckdb.js",
4
4
  "types": "./lib/duckdb.d.ts",
5
- "version": "0.8.2-dev5120.0",
5
+ "version": "0.8.2-dev5154.0",
6
6
  "description": "DuckDB node.js API",
7
7
  "gypfile": true,
8
8
  "dependencies": {
@@ -1,5 +1,6 @@
1
1
  #include "include/icu-dateadd.hpp"
2
2
 
3
+ #include "duckdb/main/extension_util.hpp"
3
4
  #include "duckdb/common/operator/add.hpp"
4
5
  #include "duckdb/common/operator/multiply.hpp"
5
6
  #include "duckdb/common/types/time.hpp"
@@ -237,17 +238,14 @@ struct ICUDateAdd : public ICUDateFunc {
237
238
  return GetBinaryDateFunction<TA, TB, timestamp_t, OP>(left_type, right_type, LogicalType::TIMESTAMP_TZ);
238
239
  }
239
240
 
240
- static void AddDateAddOperators(const string &name, ClientContext &context) {
241
+ static void AddDateAddOperators(const string &name, DatabaseInstance &db) {
241
242
  // temporal + interval
242
243
  ScalarFunctionSet set(name);
243
244
  set.AddFunction(GetDateAddFunction<timestamp_t, interval_t, ICUCalendarAdd>(LogicalType::TIMESTAMP_TZ,
244
245
  LogicalType::INTERVAL));
245
246
  set.AddFunction(GetDateAddFunction<interval_t, timestamp_t, ICUCalendarAdd>(LogicalType::INTERVAL,
246
247
  LogicalType::TIMESTAMP_TZ));
247
-
248
- CreateScalarFunctionInfo func_info(set);
249
- auto &catalog = Catalog::GetSystemCatalog(context);
250
- catalog.AddFunction(context, func_info);
248
+ ExtensionUtil::AddFunctionOverload(db, set);
251
249
  }
252
250
 
253
251
  template <typename TA, typename OP>
@@ -260,7 +258,7 @@ struct ICUDateAdd : public ICUDateFunc {
260
258
  return GetBinaryDateFunction<TA, TB, interval_t, OP>(left_type, right_type, LogicalType::INTERVAL);
261
259
  }
262
260
 
263
- static void AddDateSubOperators(const string &name, ClientContext &context) {
261
+ static void AddDateSubOperators(const string &name, DatabaseInstance &db) {
264
262
  // temporal - interval
265
263
  ScalarFunctionSet set(name);
266
264
  set.AddFunction(GetDateAddFunction<timestamp_t, interval_t, ICUCalendarSub>(LogicalType::TIMESTAMP_TZ,
@@ -269,22 +267,16 @@ struct ICUDateAdd : public ICUDateFunc {
269
267
  // temporal - temporal
270
268
  set.AddFunction(GetBinaryAgeFunction<timestamp_t, timestamp_t, ICUCalendarSub>(LogicalType::TIMESTAMP_TZ,
271
269
  LogicalType::TIMESTAMP_TZ));
272
-
273
- CreateScalarFunctionInfo func_info(set);
274
- auto &catalog = Catalog::GetSystemCatalog(context);
275
- catalog.AddFunction(context, func_info);
270
+ ExtensionUtil::AddFunctionOverload(db, set);
276
271
  }
277
272
 
278
- static void AddDateAgeFunctions(const string &name, ClientContext &context) {
273
+ static void AddDateAgeFunctions(const string &name, DatabaseInstance &db) {
279
274
  // age(temporal, temporal)
280
275
  ScalarFunctionSet set(name);
281
276
  set.AddFunction(GetBinaryAgeFunction<timestamp_t, timestamp_t, ICUCalendarAge>(LogicalType::TIMESTAMP_TZ,
282
277
  LogicalType::TIMESTAMP_TZ));
283
278
  set.AddFunction(GetUnaryAgeFunction<timestamp_t, ICUCalendarAge>(LogicalType::TIMESTAMP_TZ));
284
-
285
- CreateScalarFunctionInfo func_info(set);
286
- auto &catalog = Catalog::GetSystemCatalog(context);
287
- catalog.AddFunction(context, func_info);
279
+ ExtensionUtil::AddFunctionOverload(db, set);
288
280
  }
289
281
  };
290
282
 
@@ -300,10 +292,10 @@ interval_t ICUDateFunc::Sub(icu::Calendar *calendar, timestamp_t end_date, times
300
292
  return ICUCalendarSub::Operation<timestamp_t, timestamp_t, interval_t>(end_date, start_date, calendar);
301
293
  }
302
294
 
303
- void RegisterICUDateAddFunctions(ClientContext &context) {
304
- ICUDateAdd::AddDateAddOperators("+", context);
305
- ICUDateAdd::AddDateSubOperators("-", context);
306
- ICUDateAdd::AddDateAgeFunctions("age", context);
295
+ void RegisterICUDateAddFunctions(DatabaseInstance &db) {
296
+ ICUDateAdd::AddDateAddOperators("+", db);
297
+ ICUDateAdd::AddDateSubOperators("-", db);
298
+ ICUDateAdd::AddDateAgeFunctions("age", db);
307
299
  }
308
300
 
309
301
  } // namespace duckdb
@@ -1,6 +1,7 @@
1
1
  #include "include/icu-datepart.hpp"
2
2
  #include "include/icu-datefunc.hpp"
3
3
 
4
+ #include "duckdb/main/extension_util.hpp"
4
5
  #include "duckdb/common/enums/date_part_specifier.hpp"
5
6
  #include "duckdb/common/types/date.hpp"
6
7
  #include "duckdb/common/types/timestamp.hpp"
@@ -562,13 +563,11 @@ struct ICUDatePart : public ICUDateFunc {
562
563
  }
563
564
 
564
565
  template <typename RESULT_TYPE = int64_t>
565
- static void AddUnaryPartCodeFunctions(const string &name, ClientContext &context,
566
+ static void AddUnaryPartCodeFunctions(const string &name, DatabaseInstance &db,
566
567
  const LogicalType &result_type = LogicalType::BIGINT) {
567
- auto &catalog = Catalog::GetSystemCatalog(context);
568
568
  ScalarFunctionSet set(name);
569
569
  set.AddFunction(GetUnaryPartCodeFunction<timestamp_t, RESULT_TYPE>(LogicalType::TIMESTAMP_TZ, result_type));
570
- CreateScalarFunctionInfo func_info(set);
571
- catalog.AddFunction(context, func_info);
570
+ ExtensionUtil::AddFunctionOverload(db, set);
572
571
  }
573
572
 
574
573
  template <typename INPUT_TYPE, typename RESULT_TYPE>
@@ -587,13 +586,11 @@ struct ICUDatePart : public ICUDateFunc {
587
586
  return result;
588
587
  }
589
588
 
590
- static void AddDatePartFunctions(const string &name, ClientContext &context) {
591
- auto &catalog = Catalog::GetSystemCatalog(context);
589
+ static void AddDatePartFunctions(const string &name, DatabaseInstance &db) {
592
590
  ScalarFunctionSet set(name);
593
591
  set.AddFunction(GetBinaryPartCodeFunction<timestamp_t, int64_t>(LogicalType::TIMESTAMP_TZ));
594
592
  set.AddFunction(GetStructFunction<timestamp_t>(LogicalType::TIMESTAMP_TZ));
595
- CreateScalarFunctionInfo func_info(set);
596
- catalog.AddFunction(context, func_info);
593
+ ExtensionUtil::AddFunctionOverload(db, set);
597
594
  }
598
595
 
599
596
  static duckdb::unique_ptr<FunctionData> BindLastDate(ClientContext &context, ScalarFunction &bound_function,
@@ -607,12 +604,10 @@ struct ICUDatePart : public ICUDateFunc {
607
604
  return ScalarFunction({temporal_type}, LogicalType::DATE, UnaryTimestampFunction<INPUT_TYPE, date_t>,
608
605
  BindLastDate);
609
606
  }
610
- static void AddLastDayFunctions(const string &name, ClientContext &context) {
611
- auto &catalog = Catalog::GetSystemCatalog(context);
607
+ static void AddLastDayFunctions(const string &name, DatabaseInstance &db) {
612
608
  ScalarFunctionSet set(name);
613
609
  set.AddFunction(GetLastDayFunction<timestamp_t>(LogicalType::TIMESTAMP_TZ));
614
- CreateScalarFunctionInfo func_info(set);
615
- catalog.AddFunction(context, func_info);
610
+ ExtensionUtil::AddFunctionOverload(db, set);
616
611
  }
617
612
 
618
613
  static unique_ptr<FunctionData> BindMonthName(ClientContext &context, ScalarFunction &bound_function,
@@ -626,12 +621,10 @@ struct ICUDatePart : public ICUDateFunc {
626
621
  return ScalarFunction({temporal_type}, LogicalType::VARCHAR, UnaryTimestampFunction<INPUT_TYPE, string_t>,
627
622
  BindMonthName);
628
623
  }
629
- static void AddMonthNameFunctions(const string &name, ClientContext &context) {
630
- auto &catalog = Catalog::GetSystemCatalog(context);
624
+ static void AddMonthNameFunctions(const string &name, DatabaseInstance &db) {
631
625
  ScalarFunctionSet set(name);
632
626
  set.AddFunction(GetMonthNameFunction<timestamp_t>(LogicalType::TIMESTAMP_TZ));
633
- CreateScalarFunctionInfo func_info(set);
634
- catalog.AddFunction(context, func_info);
627
+ ExtensionUtil::AddFunctionOverload(db, set);
635
628
  }
636
629
 
637
630
  static unique_ptr<FunctionData> BindDayName(ClientContext &context, ScalarFunction &bound_function,
@@ -645,63 +638,61 @@ struct ICUDatePart : public ICUDateFunc {
645
638
  return ScalarFunction({temporal_type}, LogicalType::VARCHAR, UnaryTimestampFunction<INPUT_TYPE, string_t>,
646
639
  BindDayName);
647
640
  }
648
- static void AddDayNameFunctions(const string &name, ClientContext &context) {
649
- auto &catalog = Catalog::GetSystemCatalog(context);
641
+ static void AddDayNameFunctions(const string &name, DatabaseInstance &db) {
650
642
  ScalarFunctionSet set(name);
651
643
  set.AddFunction(GetDayNameFunction<timestamp_t>(LogicalType::TIMESTAMP_TZ));
652
- CreateScalarFunctionInfo func_info(set);
653
- catalog.AddFunction(context, func_info);
644
+ ExtensionUtil::AddFunctionOverload(db, set);
654
645
  }
655
646
  };
656
647
 
657
- void RegisterICUDatePartFunctions(ClientContext &context) {
648
+ void RegisterICUDatePartFunctions(DatabaseInstance &db) {
658
649
  // register the individual operators
659
650
 
660
651
  // BIGINTs
661
- ICUDatePart::AddUnaryPartCodeFunctions("era", context);
662
- ICUDatePart::AddUnaryPartCodeFunctions("year", context);
663
- ICUDatePart::AddUnaryPartCodeFunctions("month", context);
664
- ICUDatePart::AddUnaryPartCodeFunctions("day", context);
665
- ICUDatePart::AddUnaryPartCodeFunctions("decade", context);
666
- ICUDatePart::AddUnaryPartCodeFunctions("century", context);
667
- ICUDatePart::AddUnaryPartCodeFunctions("millennium", context);
668
- ICUDatePart::AddUnaryPartCodeFunctions("microsecond", context);
669
- ICUDatePart::AddUnaryPartCodeFunctions("millisecond", context);
670
- ICUDatePart::AddUnaryPartCodeFunctions("second", context);
671
- ICUDatePart::AddUnaryPartCodeFunctions("minute", context);
672
- ICUDatePart::AddUnaryPartCodeFunctions("hour", context);
673
- ICUDatePart::AddUnaryPartCodeFunctions("dayofweek", context);
674
- ICUDatePart::AddUnaryPartCodeFunctions("isodow", context);
675
- ICUDatePart::AddUnaryPartCodeFunctions("week", context); // Note that WeekOperator is ISO-8601, not US
676
- ICUDatePart::AddUnaryPartCodeFunctions("dayofyear", context);
677
- ICUDatePart::AddUnaryPartCodeFunctions("quarter", context);
678
- ICUDatePart::AddUnaryPartCodeFunctions("isoyear", context);
679
- ICUDatePart::AddUnaryPartCodeFunctions("timezone", context);
680
- ICUDatePart::AddUnaryPartCodeFunctions("timezone_hour", context);
681
- ICUDatePart::AddUnaryPartCodeFunctions("timezone_minute", context);
652
+ ICUDatePart::AddUnaryPartCodeFunctions("era", db);
653
+ ICUDatePart::AddUnaryPartCodeFunctions("year", db);
654
+ ICUDatePart::AddUnaryPartCodeFunctions("month", db);
655
+ ICUDatePart::AddUnaryPartCodeFunctions("day", db);
656
+ ICUDatePart::AddUnaryPartCodeFunctions("decade", db);
657
+ ICUDatePart::AddUnaryPartCodeFunctions("century", db);
658
+ ICUDatePart::AddUnaryPartCodeFunctions("millennium", db);
659
+ ICUDatePart::AddUnaryPartCodeFunctions("microsecond", db);
660
+ ICUDatePart::AddUnaryPartCodeFunctions("millisecond", db);
661
+ ICUDatePart::AddUnaryPartCodeFunctions("second", db);
662
+ ICUDatePart::AddUnaryPartCodeFunctions("minute", db);
663
+ ICUDatePart::AddUnaryPartCodeFunctions("hour", db);
664
+ ICUDatePart::AddUnaryPartCodeFunctions("dayofweek", db);
665
+ ICUDatePart::AddUnaryPartCodeFunctions("isodow", db);
666
+ ICUDatePart::AddUnaryPartCodeFunctions("week", db); // Note that WeekOperator is ISO-8601, not US
667
+ ICUDatePart::AddUnaryPartCodeFunctions("dayofyear", db);
668
+ ICUDatePart::AddUnaryPartCodeFunctions("quarter", db);
669
+ ICUDatePart::AddUnaryPartCodeFunctions("isoyear", db);
670
+ ICUDatePart::AddUnaryPartCodeFunctions("timezone", db);
671
+ ICUDatePart::AddUnaryPartCodeFunctions("timezone_hour", db);
672
+ ICUDatePart::AddUnaryPartCodeFunctions("timezone_minute", db);
682
673
 
683
674
  // DOUBLEs
684
- ICUDatePart::AddUnaryPartCodeFunctions<double>("epoch", context, LogicalType::DOUBLE);
685
- ICUDatePart::AddUnaryPartCodeFunctions<double>("julian", context, LogicalType::DOUBLE);
675
+ ICUDatePart::AddUnaryPartCodeFunctions<double>("epoch", db, LogicalType::DOUBLE);
676
+ ICUDatePart::AddUnaryPartCodeFunctions<double>("julian", db, LogicalType::DOUBLE);
686
677
 
687
678
  // register combinations
688
- ICUDatePart::AddUnaryPartCodeFunctions("yearweek", context); // Note this is ISO year and week
679
+ ICUDatePart::AddUnaryPartCodeFunctions("yearweek", db); // Note this is ISO year and week
689
680
 
690
681
  // register various aliases
691
- ICUDatePart::AddUnaryPartCodeFunctions("dayofmonth", context);
692
- ICUDatePart::AddUnaryPartCodeFunctions("weekday", context);
693
- ICUDatePart::AddUnaryPartCodeFunctions("weekofyear", context);
682
+ ICUDatePart::AddUnaryPartCodeFunctions("dayofmonth", db);
683
+ ICUDatePart::AddUnaryPartCodeFunctions("weekday", db);
684
+ ICUDatePart::AddUnaryPartCodeFunctions("weekofyear", db);
694
685
 
695
686
  // register the last_day function
696
- ICUDatePart::AddLastDayFunctions("last_day", context);
687
+ ICUDatePart::AddLastDayFunctions("last_day", db);
697
688
 
698
689
  // register the dayname/monthname functions
699
- ICUDatePart::AddMonthNameFunctions("monthname", context);
700
- ICUDatePart::AddDayNameFunctions("dayname", context);
690
+ ICUDatePart::AddMonthNameFunctions("monthname", db);
691
+ ICUDatePart::AddDayNameFunctions("dayname", db);
701
692
 
702
693
  // finally the actual date_part function
703
- ICUDatePart::AddDatePartFunctions("date_part", context);
704
- ICUDatePart::AddDatePartFunctions("datepart", context);
694
+ ICUDatePart::AddDatePartFunctions("date_part", db);
695
+ ICUDatePart::AddDatePartFunctions("datepart", db);
705
696
  }
706
697
 
707
698
  } // namespace duckdb
@@ -1,6 +1,7 @@
1
1
  #include "include/icu-datesub.hpp"
2
2
  #include "include/icu-datefunc.hpp"
3
3
 
4
+ #include "duckdb/main/extension_util.hpp"
4
5
  #include "duckdb/common/enums/date_part_specifier.hpp"
5
6
  #include "duckdb/common/types/timestamp.hpp"
6
7
  #include "duckdb/parser/parsed_data/create_scalar_function_info.hpp"
@@ -138,13 +139,10 @@ struct ICUCalendarSub : public ICUDateFunc {
138
139
  return ScalarFunction({LogicalType::VARCHAR, type, type}, LogicalType::BIGINT, ICUDateSubFunction<TA>, Bind);
139
140
  }
140
141
 
141
- static void AddFunctions(const string &name, ClientContext &context) {
142
+ static void AddFunctions(const string &name, DatabaseInstance &db) {
142
143
  ScalarFunctionSet set(name);
143
144
  set.AddFunction(GetFunction<timestamp_t>(LogicalType::TIMESTAMP_TZ));
144
-
145
- CreateScalarFunctionInfo func_info(set);
146
- auto &catalog = Catalog::GetSystemCatalog(context);
147
- catalog.AddFunction(context, func_info);
145
+ ExtensionUtil::AddFunctionOverload(db, set);
148
146
  }
149
147
  };
150
148
 
@@ -266,22 +264,19 @@ struct ICUCalendarDiff : public ICUDateFunc {
266
264
  return ScalarFunction({LogicalType::VARCHAR, type, type}, LogicalType::BIGINT, ICUDateDiffFunction<TA>, Bind);
267
265
  }
268
266
 
269
- static void AddFunctions(const string &name, ClientContext &context) {
267
+ static void AddFunctions(const string &name, DatabaseInstance &db) {
270
268
  ScalarFunctionSet set(name);
271
269
  set.AddFunction(GetFunction<timestamp_t>(LogicalType::TIMESTAMP_TZ));
272
-
273
- CreateScalarFunctionInfo func_info(set);
274
- auto &catalog = Catalog::GetSystemCatalog(context);
275
- catalog.AddFunction(context, func_info);
270
+ ExtensionUtil::AddFunctionOverload(db, set);
276
271
  }
277
272
  };
278
273
 
279
- void RegisterICUDateSubFunctions(ClientContext &context) {
280
- ICUCalendarSub::AddFunctions("date_sub", context);
281
- ICUCalendarSub::AddFunctions("datesub", context);
274
+ void RegisterICUDateSubFunctions(DatabaseInstance &db) {
275
+ ICUCalendarSub::AddFunctions("date_sub", db);
276
+ ICUCalendarSub::AddFunctions("datesub", db);
282
277
 
283
- ICUCalendarDiff::AddFunctions("date_diff", context);
284
- ICUCalendarDiff::AddFunctions("datediff", context);
278
+ ICUCalendarDiff::AddFunctions("date_diff", db);
279
+ ICUCalendarDiff::AddFunctions("datediff", db);
285
280
  }
286
281
 
287
282
  } // namespace duckdb
@@ -7,6 +7,7 @@
7
7
  #include "duckdb/main/client_context.hpp"
8
8
  #include "duckdb/parser/parsed_data/create_scalar_function_info.hpp"
9
9
  #include "duckdb/planner/expression/bound_function_expression.hpp"
10
+ #include "duckdb/main/extension_util.hpp"
10
11
 
11
12
  namespace duckdb {
12
13
 
@@ -140,13 +141,10 @@ struct ICUDateTrunc : public ICUDateFunc {
140
141
  return ScalarFunction({LogicalType::VARCHAR, type}, LogicalType::TIMESTAMP_TZ, ICUDateTruncFunction<TA>, Bind);
141
142
  }
142
143
 
143
- static void AddBinaryTimestampFunction(const string &name, ClientContext &context) {
144
+ static void AddBinaryTimestampFunction(const string &name, DatabaseInstance &db) {
144
145
  ScalarFunctionSet set(name);
145
146
  set.AddFunction(GetDateTruncFunction<timestamp_t>(LogicalType::TIMESTAMP_TZ));
146
-
147
- CreateScalarFunctionInfo func_info(set);
148
- auto &catalog = Catalog::GetSystemCatalog(context);
149
- catalog.AddFunction(context, func_info);
147
+ ExtensionUtil::AddFunctionOverload(db, set);
150
148
  }
151
149
  };
152
150
 
@@ -193,9 +191,9 @@ ICUDateFunc::part_trunc_t ICUDateFunc::TruncationFactory(DatePartSpecifier type)
193
191
  }
194
192
  }
195
193
 
196
- void RegisterICUDateTruncFunctions(ClientContext &context) {
197
- ICUDateTrunc::AddBinaryTimestampFunction("date_trunc", context);
198
- ICUDateTrunc::AddBinaryTimestampFunction("datetrunc", context);
194
+ void RegisterICUDateTruncFunctions(DatabaseInstance &db) {
195
+ ICUDateTrunc::AddBinaryTimestampFunction("date_trunc", db);
196
+ ICUDateTrunc::AddBinaryTimestampFunction("datetrunc", db);
199
197
  }
200
198
 
201
199
  } // namespace duckdb
@@ -7,6 +7,7 @@
7
7
  #include "duckdb/main/client_context.hpp"
8
8
  #include "duckdb/parser/parsed_data/create_scalar_function_info.hpp"
9
9
  #include "include/icu-datefunc.hpp"
10
+ #include "duckdb/main/extension_util.hpp"
10
11
 
11
12
  namespace duckdb {
12
13
 
@@ -180,28 +181,25 @@ struct ICUListRange : public ICUDateFunc {
180
181
  result.Verify(args.size());
181
182
  }
182
183
 
183
- static void AddICUListRangeFunction(ClientContext &context) {
184
- auto &catalog = Catalog::GetSystemCatalog(context);
184
+ static void AddICUListRangeFunction(DatabaseInstance &db) {
185
185
 
186
186
  ScalarFunctionSet range("range");
187
187
  range.AddFunction(ScalarFunction({LogicalType::TIMESTAMP_TZ, LogicalType::TIMESTAMP_TZ, LogicalType::INTERVAL},
188
188
  LogicalType::LIST(LogicalType::TIMESTAMP_TZ), ICUListRangeFunction<false>,
189
189
  Bind));
190
- CreateScalarFunctionInfo range_func_info(range);
191
- catalog.AddFunction(context, range_func_info);
190
+ ExtensionUtil::AddFunctionOverload(db, range);
192
191
 
193
192
  // generate_series: similar to range, but inclusive instead of exclusive bounds on the RHS
194
193
  ScalarFunctionSet generate_series("generate_series");
195
194
  generate_series.AddFunction(
196
195
  ScalarFunction({LogicalType::TIMESTAMP_TZ, LogicalType::TIMESTAMP_TZ, LogicalType::INTERVAL},
197
196
  LogicalType::LIST(LogicalType::TIMESTAMP_TZ), ICUListRangeFunction<true>, Bind));
198
- CreateScalarFunctionInfo generate_series_func_info(generate_series);
199
- catalog.AddFunction(context, generate_series_func_info);
197
+ ExtensionUtil::AddFunctionOverload(db, generate_series);
200
198
  }
201
199
  };
202
200
 
203
- void RegisterICUListRangeFunctions(ClientContext &context) {
204
- ICUListRange::AddICUListRangeFunction(context);
201
+ void RegisterICUListRangeFunctions(DatabaseInstance &db) {
202
+ ICUListRange::AddICUListRangeFunction(db);
205
203
  }
206
204
 
207
205
  } // namespace duckdb
@@ -7,6 +7,7 @@
7
7
  #include "duckdb/common/vector_operations/senary_executor.hpp"
8
8
  #include "duckdb/common/vector_operations/septenary_executor.hpp"
9
9
  #include "duckdb/function/cast/cast_function_set.hpp"
10
+ #include "duckdb/main/extension_util.hpp"
10
11
  #include "duckdb/parser/parsed_data/create_scalar_function_info.hpp"
11
12
  #include "include/icu-datefunc.hpp"
12
13
  #include "include/icu-datetrunc.hpp"
@@ -57,8 +58,8 @@ struct ICUMakeDate : public ICUDateFunc {
57
58
  return BoundCastInfo(CastToDate, std::move(cast_data));
58
59
  }
59
60
 
60
- static void AddCasts(ClientContext &context) {
61
- auto &config = DBConfig::GetConfig(context);
61
+ static void AddCasts(DatabaseInstance &db) {
62
+ auto &config = DBConfig::GetConfig(db);
62
63
  auto &casts = config.GetCastFunctions();
63
64
 
64
65
  casts.RegisterCastFunction(LogicalType::TIMESTAMP_TZ, LogicalType::DATE, BindCastToDate);
@@ -146,21 +147,18 @@ struct ICUMakeTimestampTZFunc : public ICUDateFunc {
146
147
  LogicalType::TIMESTAMP_TZ, Execute<TA>, Bind);
147
148
  }
148
149
 
149
- static void AddFunction(const string &name, ClientContext &context) {
150
+ static void AddFunction(const string &name, DatabaseInstance &db) {
150
151
  ScalarFunctionSet set(name);
151
152
  set.AddFunction(GetSenaryFunction<int64_t>(LogicalType::BIGINT));
152
153
  set.AddFunction(GetSeptenaryFunction<int64_t>(LogicalType::BIGINT));
153
154
  set.AddFunction(ScalarFunction({LogicalType::BIGINT}, LogicalType::TIMESTAMP_TZ, FromMicros<int64_t>));
154
-
155
- CreateScalarFunctionInfo func_info(set);
156
- auto &catalog = Catalog::GetSystemCatalog(context);
157
- catalog.AddFunction(context, func_info);
155
+ ExtensionUtil::RegisterFunction(db, set);
158
156
  }
159
157
  };
160
158
 
161
- void RegisterICUMakeDateFunctions(ClientContext &context) {
162
- ICUMakeTimestampTZFunc::AddFunction("make_timestamptz", context);
163
- ICUMakeDate::AddCasts(context);
159
+ void RegisterICUMakeDateFunctions(DatabaseInstance &db) {
160
+ ICUMakeTimestampTZFunc::AddFunction("make_timestamptz", db);
161
+ ICUMakeDate::AddCasts(db);
164
162
  }
165
163
 
166
164
  } // namespace duckdb
@@ -15,6 +15,7 @@
15
15
  #include "duckdb/planner/expression/bound_function_expression.hpp"
16
16
  #include "duckdb/function/function_binder.hpp"
17
17
  #include "duckdb/function/cast/default_casts.hpp"
18
+ #include "duckdb/main/extension_util.hpp"
18
19
 
19
20
  namespace duckdb {
20
21
 
@@ -211,32 +212,32 @@ struct ICUStrptime : public ICUDateFunc {
211
212
  return bind_strptime(context, bound_function, arguments);
212
213
  }
213
214
 
214
- static void TailPatch(const string &name, ClientContext &context, const vector<LogicalType> &types) {
215
+ static void TailPatch(const string &name, DatabaseInstance &db, const vector<LogicalType> &types) {
215
216
  // Find the old function
216
- auto &catalog = Catalog::GetSystemCatalog(context);
217
- auto &entry = catalog.GetEntry(context, CatalogType::SCALAR_FUNCTION_ENTRY, DEFAULT_SCHEMA, name);
218
- D_ASSERT(entry.type == CatalogType::SCALAR_FUNCTION_ENTRY);
219
- auto &func = entry.Cast<ScalarFunctionCatalogEntry>();
220
- string error;
221
-
222
- FunctionBinder function_binder(context);
223
- const idx_t best_function = function_binder.BindFunction(func.name, func.functions, types, error);
224
- if (best_function == DConstants::INVALID_INDEX) {
225
- return;
217
+ auto &scalar_function = ExtensionUtil::GetFunction(db, name);
218
+ auto &functions = scalar_function.functions.functions;
219
+ optional_idx best_index;
220
+ for (idx_t i = 0; i < functions.size(); i++) {
221
+ auto &function = functions[i];
222
+ if (types == function.arguments) {
223
+ best_index = i;
224
+ break;
225
+ }
226
226
  }
227
-
228
- // Tail patch the old binder
229
- auto &bound_function = func.functions.GetFunctionReferenceByOffset(best_function);
227
+ if (!best_index.IsValid()) {
228
+ throw InternalException("ICU - Function for TailPatch not found");
229
+ }
230
+ auto &bound_function = functions[best_index.GetIndex()];
230
231
  bind_strptime = bound_function.bind;
231
232
  bound_function.bind = StrpTimeBindFunction;
232
233
  }
233
234
 
234
- static void AddBinaryTimestampFunction(const string &name, ClientContext &context) {
235
+ static void AddBinaryTimestampFunction(const string &name, DatabaseInstance &db) {
235
236
  vector<LogicalType> types {LogicalType::VARCHAR, LogicalType::VARCHAR};
236
- TailPatch(name, context, types);
237
+ TailPatch(name, db, types);
237
238
 
238
239
  types[1] = LogicalType::LIST(LogicalType::VARCHAR);
239
- TailPatch(name, context, types);
240
+ TailPatch(name, db, types);
240
241
  }
241
242
 
242
243
  static bool CastFromVarchar(Vector &source, Vector &result, idx_t count, CastParameters &parameters) {
@@ -284,8 +285,8 @@ struct ICUStrptime : public ICUDateFunc {
284
285
  return BoundCastInfo(CastFromVarchar, std::move(cast_data));
285
286
  }
286
287
 
287
- static void AddCasts(ClientContext &context) {
288
- auto &config = DBConfig::GetConfig(context);
288
+ static void AddCasts(DatabaseInstance &db) {
289
+ auto &config = DBConfig::GetConfig(db);
289
290
  auto &casts = config.GetCastFunctions();
290
291
 
291
292
  casts.RegisterCastFunction(LogicalType::VARCHAR, LogicalType::TIMESTAMP_TZ, BindCastFromVarchar);
@@ -383,14 +384,11 @@ struct ICUStrftime : public ICUDateFunc {
383
384
  }
384
385
  }
385
386
 
386
- static void AddBinaryTimestampFunction(const string &name, ClientContext &context) {
387
+ static void AddBinaryTimestampFunction(const string &name, DatabaseInstance &db) {
387
388
  ScalarFunctionSet set(name);
388
389
  set.AddFunction(ScalarFunction({LogicalType::TIMESTAMP_TZ, LogicalType::VARCHAR}, LogicalType::VARCHAR,
389
390
  ICUStrftimeFunction, Bind));
390
-
391
- CreateScalarFunctionInfo func_info(set);
392
- auto &catalog = Catalog::GetSystemCatalog(context);
393
- catalog.AddFunction(context, func_info);
391
+ ExtensionUtil::AddFunctionOverload(db, set);
394
392
  }
395
393
 
396
394
  static string_t CastOperation(icu::Calendar *calendar, timestamp_t input, Vector &result) {
@@ -469,23 +467,23 @@ struct ICUStrftime : public ICUDateFunc {
469
467
  return BoundCastInfo(CastToVarchar, std::move(cast_data));
470
468
  }
471
469
 
472
- static void AddCasts(ClientContext &context) {
473
- auto &config = DBConfig::GetConfig(context);
470
+ static void AddCasts(DatabaseInstance &db) {
471
+ auto &config = DBConfig::GetConfig(db);
474
472
  auto &casts = config.GetCastFunctions();
475
473
 
476
474
  casts.RegisterCastFunction(LogicalType::TIMESTAMP_TZ, LogicalType::VARCHAR, BindCastToVarchar);
477
475
  }
478
476
  };
479
477
 
480
- void RegisterICUStrptimeFunctions(ClientContext &context) {
481
- ICUStrptime::AddBinaryTimestampFunction("strptime", context);
482
- ICUStrptime::AddBinaryTimestampFunction("try_strptime", context);
478
+ void RegisterICUStrptimeFunctions(DatabaseInstance &db) {
479
+ ICUStrptime::AddBinaryTimestampFunction("strptime", db);
480
+ ICUStrptime::AddBinaryTimestampFunction("try_strptime", db);
483
481
 
484
- ICUStrftime::AddBinaryTimestampFunction("strftime", context);
482
+ ICUStrftime::AddBinaryTimestampFunction("strftime", db);
485
483
 
486
484
  // Add string casts
487
- ICUStrptime::AddCasts(context);
488
- ICUStrftime::AddCasts(context);
485
+ ICUStrptime::AddCasts(db);
486
+ ICUStrftime::AddCasts(db);
489
487
  }
490
488
 
491
489
  } // namespace duckdb
@@ -1,6 +1,7 @@
1
1
  #include "duckdb/common/exception.hpp"
2
2
  #include "duckdb/common/types/interval.hpp"
3
3
  #include "duckdb/common/types/timestamp.hpp"
4
+ #include "duckdb/main/extension_util.hpp"
4
5
  #include "duckdb/function/function_set.hpp"
5
6
  #include "duckdb/function/table_function.hpp"
6
7
  #include "duckdb/parser/parsed_data/create_table_function_info.hpp"
@@ -168,27 +169,23 @@ struct ICUTableRange {
168
169
  output.SetCardinality(size);
169
170
  }
170
171
 
171
- static void AddICUTableRangeFunction(ClientContext &context) {
172
- auto &catalog = Catalog::GetSystemCatalog(context);
173
-
172
+ static void AddICUTableRangeFunction(DatabaseInstance &db) {
174
173
  TableFunctionSet range("range");
175
174
  range.AddFunction(TableFunction({LogicalType::TIMESTAMP_TZ, LogicalType::TIMESTAMP_TZ, LogicalType::INTERVAL},
176
175
  ICUTableRangeFunction, Bind<false>, Init));
177
- CreateTableFunctionInfo range_func_info(range);
178
- catalog.AddFunction(context, range_func_info);
176
+ ExtensionUtil::AddFunctionOverload(db, range);
179
177
 
180
178
  // generate_series: similar to range, but inclusive instead of exclusive bounds on the RHS
181
179
  TableFunctionSet generate_series("generate_series");
182
180
  generate_series.AddFunction(
183
181
  TableFunction({LogicalType::TIMESTAMP_TZ, LogicalType::TIMESTAMP_TZ, LogicalType::INTERVAL},
184
182
  ICUTableRangeFunction, Bind<true>, Init));
185
- CreateTableFunctionInfo generate_series_func_info(generate_series);
186
- catalog.AddFunction(context, generate_series_func_info);
183
+ ExtensionUtil::AddFunctionOverload(db, generate_series);
187
184
  }
188
185
  };
189
186
 
190
- void RegisterICUTableRangeFunctions(ClientContext &context) {
191
- ICUTableRange::AddICUTableRangeFunction(context);
187
+ void RegisterICUTableRangeFunctions(DatabaseInstance &db) {
188
+ ICUTableRange::AddICUTableRangeFunction(db);
192
189
  }
193
190
 
194
191
  } // namespace duckdb
@@ -6,6 +6,7 @@
6
6
  #include "duckdb/common/types/time.hpp"
7
7
  #include "duckdb/common/types/timestamp.hpp"
8
8
  #include "duckdb/common/types/value.hpp"
9
+ #include "duckdb/main/extension_util.hpp"
9
10
  #include "duckdb/common/vector_operations/binary_executor.hpp"
10
11
  #include "duckdb/common/vector_operations/ternary_executor.hpp"
11
12
  #include "duckdb/main/client_context.hpp"
@@ -613,7 +614,7 @@ struct ICUTimeBucket : public ICUDateFunc {
613
614
  }
614
615
  }
615
616
 
616
- static void AddTimeBucketFunction(ClientContext &context) {
617
+ static void AddTimeBucketFunction(DatabaseInstance &db) {
617
618
  ScalarFunctionSet set("time_bucket");
618
619
  set.AddFunction(ScalarFunction({LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ}, LogicalType::TIMESTAMP_TZ,
619
620
  ICUTimeBucketFunction, Bind));
@@ -623,15 +624,12 @@ struct ICUTimeBucket : public ICUDateFunc {
623
624
  LogicalType::TIMESTAMP_TZ, ICUTimeBucketOriginFunction, Bind));
624
625
  set.AddFunction(ScalarFunction({LogicalType::INTERVAL, LogicalType::TIMESTAMP_TZ, LogicalType::VARCHAR},
625
626
  LogicalType::TIMESTAMP_TZ, ICUTimeBucketTimeZoneFunction, Bind));
626
-
627
- CreateScalarFunctionInfo func_info(set);
628
- auto &catalog = Catalog::GetSystemCatalog(context);
629
- catalog.AddFunction(context, func_info);
627
+ ExtensionUtil::AddFunctionOverload(db, set);
630
628
  }
631
629
  };
632
630
 
633
- void RegisterICUTimeBucketFunctions(ClientContext &context) {
634
- ICUTimeBucket::AddTimeBucketFunction(context);
631
+ void RegisterICUTimeBucketFunctions(DatabaseInstance &db) {
632
+ ICUTimeBucket::AddTimeBucketFunction(db);
635
633
  }
636
634
 
637
635
  } // namespace duckdb
@@ -2,6 +2,7 @@
2
2
  #include "duckdb/common/types/time.hpp"
3
3
  #include "duckdb/common/types/timestamp.hpp"
4
4
  #include "duckdb/function/cast/cast_function_set.hpp"
5
+ #include "duckdb/main/extension_util.hpp"
5
6
  #include "duckdb/parser/parsed_data/create_scalar_function_info.hpp"
6
7
  #include "duckdb/parser/parsed_data/create_table_function_info.hpp"
7
8
  #include "include/icu-datefunc.hpp"
@@ -143,8 +144,8 @@ struct ICUFromNaiveTimestamp : public ICUDateFunc {
143
144
  return BoundCastInfo(CastFromNaive, std::move(cast_data));
144
145
  }
145
146
 
146
- static void AddCasts(ClientContext &context) {
147
- auto &config = DBConfig::GetConfig(context);
147
+ static void AddCasts(DatabaseInstance &db) {
148
+ auto &config = DBConfig::GetConfig(db);
148
149
  auto &casts = config.GetCastFunctions();
149
150
 
150
151
  casts.RegisterCastFunction(LogicalType::TIMESTAMP, LogicalType::TIMESTAMP_TZ, BindCastFromNaive);
@@ -206,8 +207,8 @@ struct ICUToNaiveTimestamp : public ICUDateFunc {
206
207
  return BoundCastInfo(CastToNaive, std::move(cast_data));
207
208
  }
208
209
 
209
- static void AddCasts(ClientContext &context) {
210
- auto &config = DBConfig::GetConfig(context);
210
+ static void AddCasts(DatabaseInstance &db) {
211
+ auto &config = DBConfig::GetConfig(db);
211
212
  auto &casts = config.GetCastFunctions();
212
213
 
213
214
  casts.RegisterCastFunction(LogicalType::TIMESTAMP_TZ, LogicalType::TIMESTAMP, BindCastToNaive);
@@ -262,18 +263,14 @@ struct ICULocalTimestampFunc : public ICUDateFunc {
262
263
  rdata[0] = GetLocalTimestamp(state);
263
264
  }
264
265
 
265
- static void AddFunction(const string &name, ClientContext &context) {
266
+ static void AddFunction(const string &name, DatabaseInstance &db) {
266
267
  ScalarFunctionSet set(name);
267
268
  set.AddFunction(ScalarFunction({}, LogicalType::TIMESTAMP, Execute, BindNow));
268
-
269
- CreateScalarFunctionInfo func_info(set);
270
- auto &catalog = Catalog::GetSystemCatalog(context);
271
- catalog.AddFunction(context, func_info);
269
+ ExtensionUtil::RegisterFunction(db, set);
272
270
  }
273
271
  };
274
272
 
275
273
  struct ICULocalTimeFunc : public ICUDateFunc {
276
-
277
274
  static void Execute(DataChunk &input, ExpressionState &state, Vector &result) {
278
275
  D_ASSERT(input.ColumnCount() == 0);
279
276
  result.SetVectorType(VectorType::CONSTANT_VECTOR);
@@ -282,13 +279,10 @@ struct ICULocalTimeFunc : public ICUDateFunc {
282
279
  rdata[0] = Timestamp::GetTime(local);
283
280
  }
284
281
 
285
- static void AddFunction(const string &name, ClientContext &context) {
282
+ static void AddFunction(const string &name, DatabaseInstance &db) {
286
283
  ScalarFunctionSet set(name);
287
284
  set.AddFunction(ScalarFunction({}, LogicalType::TIME, Execute, ICULocalTimestampFunc::BindNow));
288
-
289
- CreateScalarFunctionInfo func_info(set);
290
- auto &catalog = Catalog::GetSystemCatalog(context);
291
- catalog.AddFunction(context, func_info);
285
+ ExtensionUtil::RegisterFunction(db, set);
292
286
  }
293
287
  };
294
288
 
@@ -326,16 +320,13 @@ struct ICUTimeZoneFunc : public ICUDateFunc {
326
320
  }
327
321
  }
328
322
 
329
- static void AddFunction(const string &name, ClientContext &context) {
323
+ static void AddFunction(const string &name, DatabaseInstance &db) {
330
324
  ScalarFunctionSet set(name);
331
325
  set.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::TIMESTAMP}, LogicalType::TIMESTAMP_TZ,
332
326
  Execute<ICUFromNaiveTimestamp>, Bind));
333
327
  set.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::TIMESTAMP_TZ}, LogicalType::TIMESTAMP,
334
328
  Execute<ICUToNaiveTimestamp>, Bind));
335
-
336
- CreateScalarFunctionInfo func_info(set);
337
- auto &catalog = Catalog::GetSystemCatalog(context);
338
- catalog.AddFunction(context, func_info);
329
+ ExtensionUtil::AddFunctionOverload(db, set);
339
330
  }
340
331
  };
341
332
 
@@ -343,21 +334,19 @@ timestamp_t ICUDateFunc::FromNaive(icu::Calendar *calendar, timestamp_t naive) {
343
334
  return ICUFromNaiveTimestamp::Operation(calendar, naive);
344
335
  }
345
336
 
346
- void RegisterICUTimeZoneFunctions(ClientContext &context) {
337
+ void RegisterICUTimeZoneFunctions(DatabaseInstance &db) {
347
338
  // Table functions
348
- auto &catalog = Catalog::GetSystemCatalog(context);
349
339
  TableFunction tz_names("pg_timezone_names", {}, ICUTimeZoneFunction, ICUTimeZoneBind, ICUTimeZoneInit);
350
- CreateTableFunctionInfo tz_names_info(std::move(tz_names));
351
- catalog.CreateTableFunction(context, tz_names_info);
340
+ ExtensionUtil::RegisterFunction(db, tz_names);
352
341
 
353
342
  // Scalar functions
354
- ICUTimeZoneFunc::AddFunction("timezone", context);
355
- ICULocalTimestampFunc::AddFunction("current_localtimestamp", context);
356
- ICULocalTimeFunc::AddFunction("current_localtime", context);
343
+ ICUTimeZoneFunc::AddFunction("timezone", db);
344
+ ICULocalTimestampFunc::AddFunction("current_localtimestamp", db);
345
+ ICULocalTimeFunc::AddFunction("current_localtime", db);
357
346
 
358
347
  // Casts
359
- ICUFromNaiveTimestamp::AddCasts(context);
360
- ICUToNaiveTimestamp::AddCasts(context);
348
+ ICUFromNaiveTimestamp::AddCasts(db);
349
+ ICUToNaiveTimestamp::AddCasts(db);
361
350
  }
362
351
 
363
352
  } // namespace duckdb
@@ -8,6 +8,7 @@
8
8
  #include "duckdb/main/config.hpp"
9
9
  #include "duckdb/main/connection.hpp"
10
10
  #include "duckdb/main/database.hpp"
11
+ #include "duckdb/main/extension_util.hpp"
11
12
  #include "duckdb/parser/parsed_data/create_collation_info.hpp"
12
13
  #include "duckdb/parser/parsed_data/create_scalar_function_info.hpp"
13
14
  #include "duckdb/parser/parsed_data/create_table_function_info.hpp"
@@ -220,11 +221,9 @@ static void SetICUCalendar(ClientContext &context, SetScope scope, Value &parame
220
221
  }
221
222
  }
222
223
 
223
- void IcuExtension::Load(DuckDB &db) {
224
- Connection con(db);
225
- con.BeginTransaction();
226
-
227
- auto &catalog = Catalog::GetSystemCatalog(*con.context);
224
+ void IcuExtension::Load(DuckDB &ddb) {
225
+ auto &db = *ddb.instance;
226
+ auto &catalog = Catalog::GetSystemCatalog(db);
228
227
 
229
228
  // iterate over all the collations
230
229
  int32_t count;
@@ -241,17 +240,14 @@ void IcuExtension::Load(DuckDB &db) {
241
240
  collation = StringUtil::Lower(collation);
242
241
 
243
242
  CreateCollationInfo info(collation, GetICUFunction(collation), false, true);
244
- info.on_conflict = OnCreateConflict::IGNORE_ON_CONFLICT;
245
- catalog.CreateCollation(*con.context, info);
243
+ ExtensionUtil::RegisterCollation(db, info);
246
244
  }
247
245
  ScalarFunction sort_key("icu_sort_key", {LogicalType::VARCHAR, LogicalType::VARCHAR}, LogicalType::VARCHAR,
248
246
  ICUCollateFunction, ICUSortKeyBind);
249
-
250
- CreateScalarFunctionInfo sort_key_info(std::move(sort_key));
251
- catalog.CreateFunction(*con.context, sort_key_info);
247
+ ExtensionUtil::RegisterFunction(db, sort_key);
252
248
 
253
249
  // Time Zones
254
- auto &config = DBConfig::GetConfig(*db.instance);
250
+ auto &config = DBConfig::GetConfig(db);
255
251
  duckdb::unique_ptr<icu::TimeZone> tz(icu::TimeZone::createDefault());
256
252
  icu::UnicodeString tz_id;
257
253
  std::string tz_string;
@@ -259,16 +255,16 @@ void IcuExtension::Load(DuckDB &db) {
259
255
  config.AddExtensionOption("TimeZone", "The current time zone", LogicalType::VARCHAR, Value(tz_string),
260
256
  SetICUTimeZone);
261
257
 
262
- RegisterICUDateAddFunctions(*con.context);
263
- RegisterICUDatePartFunctions(*con.context);
264
- RegisterICUDateSubFunctions(*con.context);
265
- RegisterICUDateTruncFunctions(*con.context);
266
- RegisterICUMakeDateFunctions(*con.context);
267
- RegisterICUTableRangeFunctions(*con.context);
268
- RegisterICUListRangeFunctions(*con.context);
269
- RegisterICUStrptimeFunctions(*con.context);
270
- RegisterICUTimeBucketFunctions(*con.context);
271
- RegisterICUTimeZoneFunctions(*con.context);
258
+ RegisterICUDateAddFunctions(db);
259
+ RegisterICUDatePartFunctions(db);
260
+ RegisterICUDateSubFunctions(db);
261
+ RegisterICUDateTruncFunctions(db);
262
+ RegisterICUMakeDateFunctions(db);
263
+ RegisterICUTableRangeFunctions(db);
264
+ RegisterICUListRangeFunctions(db);
265
+ RegisterICUStrptimeFunctions(db);
266
+ RegisterICUTimeBucketFunctions(db);
267
+ RegisterICUTimeZoneFunctions(db);
272
268
 
273
269
  // Calendars
274
270
  UErrorCode status = U_ZERO_ERROR;
@@ -277,10 +273,7 @@ void IcuExtension::Load(DuckDB &db) {
277
273
  SetICUCalendar);
278
274
 
279
275
  TableFunction cal_names("icu_calendar_names", {}, ICUCalendarFunction, ICUCalendarBind, ICUCalendarInit);
280
- CreateTableFunctionInfo cal_names_info(std::move(cal_names));
281
- catalog.CreateTableFunction(*con.context, cal_names_info);
282
-
283
- con.Commit();
276
+ ExtensionUtil::RegisterFunction(db, cal_names);
284
277
  }
285
278
 
286
279
  std::string IcuExtension::Name() {
@@ -12,6 +12,6 @@
12
12
 
13
13
  namespace duckdb {
14
14
 
15
- void RegisterICUDateAddFunctions(ClientContext &context);
15
+ void RegisterICUDateAddFunctions(DatabaseInstance &db);
16
16
 
17
17
  } // namespace duckdb
@@ -12,6 +12,6 @@
12
12
 
13
13
  namespace duckdb {
14
14
 
15
- void RegisterICUDatePartFunctions(ClientContext &context);
15
+ void RegisterICUDatePartFunctions(DatabaseInstance &db);
16
16
 
17
17
  } // namespace duckdb
@@ -12,6 +12,6 @@
12
12
 
13
13
  namespace duckdb {
14
14
 
15
- void RegisterICUDateSubFunctions(ClientContext &context);
15
+ void RegisterICUDateSubFunctions(DatabaseInstance &db);
16
16
 
17
17
  } // namespace duckdb
@@ -12,6 +12,6 @@
12
12
 
13
13
  namespace duckdb {
14
14
 
15
- void RegisterICUDateTruncFunctions(ClientContext &context);
15
+ void RegisterICUDateTruncFunctions(DatabaseInstance &db);
16
16
 
17
17
  } // namespace duckdb
@@ -12,6 +12,6 @@
12
12
 
13
13
  namespace duckdb {
14
14
 
15
- void RegisterICUListRangeFunctions(ClientContext &context);
15
+ void RegisterICUListRangeFunctions(DatabaseInstance &db);
16
16
 
17
17
  } // namespace duckdb
@@ -12,6 +12,6 @@
12
12
 
13
13
  namespace duckdb {
14
14
 
15
- void RegisterICUMakeDateFunctions(ClientContext &context);
15
+ void RegisterICUMakeDateFunctions(DatabaseInstance &db);
16
16
 
17
17
  } // namespace duckdb
@@ -12,6 +12,6 @@
12
12
 
13
13
  namespace duckdb {
14
14
 
15
- void RegisterICUStrptimeFunctions(ClientContext &context);
15
+ void RegisterICUStrptimeFunctions(DatabaseInstance &db);
16
16
 
17
17
  } // namespace duckdb
@@ -12,6 +12,6 @@
12
12
 
13
13
  namespace duckdb {
14
14
 
15
- void RegisterICUTableRangeFunctions(ClientContext &context);
15
+ void RegisterICUTableRangeFunctions(DatabaseInstance &db);
16
16
 
17
17
  } // namespace duckdb
@@ -12,6 +12,6 @@
12
12
 
13
13
  namespace duckdb {
14
14
 
15
- void RegisterICUTimeBucketFunctions(ClientContext &context);
15
+ void RegisterICUTimeBucketFunctions(DatabaseInstance &db);
16
16
 
17
17
  } // namespace duckdb
@@ -12,6 +12,6 @@
12
12
 
13
13
  namespace duckdb {
14
14
 
15
- void RegisterICUTimeZoneFunctions(ClientContext &context);
15
+ void RegisterICUTimeZoneFunctions(DatabaseInstance &db);
16
16
 
17
17
  } // namespace duckdb
@@ -229,6 +229,21 @@ unique_ptr<FunctionData> ReadJSONBind(ClientContext &context, TableFunctionBindI
229
229
  transform_options.error_unknown_key = bind_data->auto_detect && !bind_data->ignore_errors;
230
230
  transform_options.delay_error = true;
231
231
 
232
+ if (bind_data->auto_detect) {
233
+ // JSON may contain columns such as "id" and "Id", which are duplicates for us due to case-insensitivity
234
+ // We rename them so we can parse the file anyway. Note that we can't change bind_data->names,
235
+ // because the JSON reader gets columns by exact name, not position
236
+ case_insensitive_map_t<idx_t> name_count_map;
237
+ for (auto &name : names) {
238
+ auto it = name_count_map.find(name);
239
+ if (it == name_count_map.end()) {
240
+ name_count_map[name] = 1;
241
+ } else {
242
+ name = StringUtil::Format("%s_%llu", name, it->second++);
243
+ }
244
+ }
245
+ }
246
+
232
247
  return std::move(bind_data);
233
248
  }
234
249
 
@@ -479,6 +479,8 @@ bool Catalog::AutoLoadExtensionByCatalogEntry(ClientContext &context, CatalogTyp
479
479
  extension_name = ExtensionHelper::FindExtensionInEntries(entry_name, EXTENSION_COPY_FUNCTIONS);
480
480
  } else if (type == CatalogType::TYPE_ENTRY) {
481
481
  extension_name = ExtensionHelper::FindExtensionInEntries(entry_name, EXTENSION_TYPES);
482
+ } else if (type == CatalogType::COLLATION_ENTRY) {
483
+ extension_name = ExtensionHelper::FindExtensionInEntries(entry_name, EXTENSION_COLLATIONS);
482
484
  }
483
485
 
484
486
  if (!extension_name.empty() && ExtensionHelper::CanAutoloadExtension(extension_name)) {
@@ -536,6 +538,8 @@ CatalogException Catalog::CreateMissingEntryException(ClientContext &context, co
536
538
  extension_name = ExtensionHelper::FindExtensionInEntries(entry_name, EXTENSION_TYPES);
537
539
  } else if (type == CatalogType::COPY_FUNCTION_ENTRY) {
538
540
  extension_name = ExtensionHelper::FindExtensionInEntries(entry_name, EXTENSION_COPY_FUNCTIONS);
541
+ } else if (type == CatalogType::COLLATION_ENTRY) {
542
+ extension_name = ExtensionHelper::FindExtensionInEntries(entry_name, EXTENSION_COLLATIONS);
539
543
  }
540
544
 
541
545
  // if we found an extension that can handle this catalog entry, create an error hinting the user
@@ -56,7 +56,10 @@ SourceResultType PhysicalAttach::GetData(ExecutionContext &context, DataChunk &c
56
56
 
57
57
  // if we are loading a database type from an extension - check if that extension is loaded
58
58
  if (!type.empty()) {
59
- if (!db.ExtensionIsLoaded(type)) {
59
+ if (!Catalog::TryAutoLoad(context.client, type)) {
60
+ // FIXME: Here it might be preferrable to use an AutoLoadOrThrow kind of function
61
+ // so that either there will be success or a message to throw, and load will be
62
+ // attempted only once respecting the autoloading options
60
63
  ExtensionHelper::LoadExternalExtension(context.client, type);
61
64
  }
62
65
  }
@@ -1,8 +1,8 @@
1
1
  #ifndef DUCKDB_VERSION
2
- #define DUCKDB_VERSION "0.8.2-dev5120"
2
+ #define DUCKDB_VERSION "0.8.2-dev5154"
3
3
  #endif
4
4
  #ifndef DUCKDB_SOURCE_ID
5
- #define DUCKDB_SOURCE_ID "fc2e4b26a6"
5
+ #define DUCKDB_SOURCE_ID "78bea4f92a"
6
6
  #endif
7
7
  #include "duckdb/function/table/system_functions.hpp"
8
8
  #include "duckdb/main/database.hpp"
@@ -218,6 +218,32 @@ static constexpr ExtensionEntry EXTENSION_COPY_FUNCTIONS[] = {{"parquet", "parqu
218
218
  static constexpr ExtensionEntry EXTENSION_TYPES[] = {
219
219
  {"json", "json"}, {"inet", "inet"}, {"geometry", "spatial"}}; // END_OF_EXTENSION_TYPES
220
220
 
221
+ // Note: these are currently hardcoded in scripts/generate_extensions_function.py
222
+ // TODO: automate by passing though to script via duckdb
223
+ static constexpr ExtensionEntry EXTENSION_COLLATIONS[] = {
224
+ {"af", "icu"}, {"am", "icu"}, {"ar", "icu"}, {"ar_sa", "icu"}, {"as", "icu"}, {"az", "icu"},
225
+ {"be", "icu"}, {"bg", "icu"}, {"bn", "icu"}, {"bo", "icu"}, {"br", "icu"}, {"bs", "icu"},
226
+ {"ca", "icu"}, {"ceb", "icu"}, {"chr", "icu"}, {"cs", "icu"}, {"cy", "icu"}, {"da", "icu"},
227
+ {"de", "icu"}, {"de_at", "icu"}, {"dsb", "icu"}, {"dz", "icu"}, {"ee", "icu"}, {"el", "icu"},
228
+ {"en", "icu"}, {"en_us", "icu"}, {"eo", "icu"}, {"es", "icu"}, {"et", "icu"}, {"fa", "icu"},
229
+ {"fa_af", "icu"}, {"ff", "icu"}, {"fi", "icu"}, {"fil", "icu"}, {"fo", "icu"}, {"fr", "icu"},
230
+ {"fr_ca", "icu"}, {"fy", "icu"}, {"ga", "icu"}, {"gl", "icu"}, {"gu", "icu"}, {"ha", "icu"},
231
+ {"haw", "icu"}, {"he", "icu"}, {"he_il", "icu"}, {"hi", "icu"}, {"hr", "icu"}, {"hsb", "icu"},
232
+ {"hu", "icu"}, {"hy", "icu"}, {"id", "icu"}, {"id_id", "icu"}, {"ig", "icu"}, {"is", "icu"},
233
+ {"it", "icu"}, {"ja", "icu"}, {"ka", "icu"}, {"kk", "icu"}, {"kl", "icu"}, {"km", "icu"},
234
+ {"kn", "icu"}, {"ko", "icu"}, {"kok", "icu"}, {"ku", "icu"}, {"ky", "icu"}, {"lb", "icu"},
235
+ {"lkt", "icu"}, {"ln", "icu"}, {"lo", "icu"}, {"lt", "icu"}, {"lv", "icu"}, {"mk", "icu"},
236
+ {"ml", "icu"}, {"mn", "icu"}, {"mr", "icu"}, {"ms", "icu"}, {"mt", "icu"}, {"my", "icu"},
237
+ {"nb", "icu"}, {"nb_no", "icu"}, {"ne", "icu"}, {"nl", "icu"}, {"nn", "icu"}, {"om", "icu"},
238
+ {"or", "icu"}, {"pa", "icu"}, {"pa_in", "icu"}, {"pl", "icu"}, {"ps", "icu"}, {"pt", "icu"},
239
+ {"ro", "icu"}, {"ru", "icu"}, {"sa", "icu"}, {"se", "icu"}, {"si", "icu"}, {"sk", "icu"},
240
+ {"sl", "icu"}, {"smn", "icu"}, {"sq", "icu"}, {"sr", "icu"}, {"sr_ba", "icu"}, {"sr_me", "icu"},
241
+ {"sr_rs", "icu"}, {"sv", "icu"}, {"sw", "icu"}, {"ta", "icu"}, {"te", "icu"}, {"th", "icu"},
242
+ {"tk", "icu"}, {"to", "icu"}, {"tr", "icu"}, {"ug", "icu"}, {"uk", "icu"}, {"ur", "icu"},
243
+ {"uz", "icu"}, {"vi", "icu"}, {"wae", "icu"}, {"wo", "icu"}, {"xh", "icu"}, {"yi", "icu"},
244
+ {"yo", "icu"}, {"yue", "icu"}, {"yue_cn", "icu"}, {"zh", "icu"}, {"zh_cn", "icu"}, {"zh_hk", "icu"},
245
+ {"zh_mo", "icu"}, {"zh_sg", "icu"}, {"zh_tw", "icu"}, {"zu", "icu"}}; // END_OF_EXTENSION_COLLATIONS
246
+
221
247
  // Note: these are currently hardcoded in scripts/generate_extensions_function.py
222
248
  // TODO: automate by passing though to script via duckdb
223
249
  static constexpr ExtensionEntry EXTENSION_FILE_PREFIXES[] = {
@@ -14,6 +14,7 @@
14
14
 
15
15
  namespace duckdb {
16
16
  struct CreateMacroInfo;
17
+ struct CreateCollationInfo;
17
18
  class DatabaseInstance;
18
19
 
19
20
  //! The ExtensionUtil class contains methods that are useful for extensions
@@ -40,6 +41,19 @@ public:
40
41
  //! Register a new macro function - throw an exception if the function already exists
41
42
  DUCKDB_API static void RegisterFunction(DatabaseInstance &db, CreateMacroInfo &info);
42
43
 
44
+ //! Register a new collation
45
+ DUCKDB_API static void RegisterCollation(DatabaseInstance &db, CreateCollationInfo &info);
46
+
47
+ //! Returns a reference to the function in the catalog - throws an exception if it does not exist
48
+ DUCKDB_API static ScalarFunctionCatalogEntry &GetFunction(DatabaseInstance &db, const string &name);
49
+ DUCKDB_API static TableFunctionCatalogEntry &GetTableFunction(DatabaseInstance &db, const string &name);
50
+
51
+ //! Add a function overload
52
+ DUCKDB_API static void AddFunctionOverload(DatabaseInstance &db, ScalarFunction function);
53
+ DUCKDB_API static void AddFunctionOverload(DatabaseInstance &db, ScalarFunctionSet function);
54
+
55
+ DUCKDB_API static void AddFunctionOverload(DatabaseInstance &db, TableFunctionSet function);
56
+
43
57
  //! Registers a new type
44
58
  DUCKDB_API static void RegisterType(DatabaseInstance &db, string type_name, LogicalType type);
45
59
 
@@ -7,6 +7,9 @@
7
7
  #include "duckdb/parser/parsed_data/create_scalar_function_info.hpp"
8
8
  #include "duckdb/parser/parsed_data/create_table_function_info.hpp"
9
9
  #include "duckdb/parser/parsed_data/create_macro_info.hpp"
10
+ #include "duckdb/catalog/catalog_entry/scalar_function_catalog_entry.hpp"
11
+ #include "duckdb/catalog/catalog_entry/table_function_catalog_entry.hpp"
12
+ #include "duckdb/parser/parsed_data/create_collation_info.hpp"
10
13
  #include "duckdb/catalog/catalog.hpp"
11
14
  #include "duckdb/main/config.hpp"
12
15
 
@@ -86,6 +89,59 @@ void ExtensionUtil::RegisterFunction(DatabaseInstance &db, CreateMacroInfo &info
86
89
  system_catalog.CreateFunction(data, info);
87
90
  }
88
91
 
92
+ void ExtensionUtil::RegisterCollation(DatabaseInstance &db, CreateCollationInfo &info) {
93
+ auto &system_catalog = Catalog::GetSystemCatalog(db);
94
+ auto data = CatalogTransaction::GetSystemTransaction(db);
95
+ info.on_conflict = OnCreateConflict::IGNORE_ON_CONFLICT;
96
+ system_catalog.CreateCollation(data, info);
97
+ }
98
+
99
+ void ExtensionUtil::AddFunctionOverload(DatabaseInstance &db, ScalarFunction function) {
100
+ auto &scalar_function = ExtensionUtil::GetFunction(db, function.name);
101
+ scalar_function.functions.AddFunction(std::move(function));
102
+ }
103
+
104
+ void ExtensionUtil::AddFunctionOverload(DatabaseInstance &db, ScalarFunctionSet functions) { // NOLINT
105
+ D_ASSERT(!functions.name.empty());
106
+ auto &scalar_function = ExtensionUtil::GetFunction(db, functions.name);
107
+ for (auto &function : functions.functions) {
108
+ function.name = functions.name;
109
+ scalar_function.functions.AddFunction(std::move(function));
110
+ }
111
+ }
112
+
113
+ void ExtensionUtil::AddFunctionOverload(DatabaseInstance &db, TableFunctionSet functions) { // NOLINT
114
+ auto &table_function = ExtensionUtil::GetTableFunction(db, functions.name);
115
+ for (auto &function : functions.functions) {
116
+ function.name = functions.name;
117
+ table_function.functions.AddFunction(std::move(function));
118
+ }
119
+ }
120
+
121
+ ScalarFunctionCatalogEntry &ExtensionUtil::GetFunction(DatabaseInstance &db, const string &name) {
122
+ D_ASSERT(!name.empty());
123
+ auto &system_catalog = Catalog::GetSystemCatalog(db);
124
+ auto data = CatalogTransaction::GetSystemTransaction(db);
125
+ auto &schema = system_catalog.GetSchema(data, DEFAULT_SCHEMA);
126
+ auto catalog_entry = schema.GetEntry(data, CatalogType::SCALAR_FUNCTION_ENTRY, name);
127
+ if (!catalog_entry) {
128
+ throw InvalidInputException("Function with name \"%s\" not found in ExtensionUtil::GetFunction", name);
129
+ }
130
+ return catalog_entry->Cast<ScalarFunctionCatalogEntry>();
131
+ }
132
+
133
+ TableFunctionCatalogEntry &ExtensionUtil::GetTableFunction(DatabaseInstance &db, const string &name) {
134
+ D_ASSERT(!name.empty());
135
+ auto &system_catalog = Catalog::GetSystemCatalog(db);
136
+ auto data = CatalogTransaction::GetSystemTransaction(db);
137
+ auto &schema = system_catalog.GetSchema(data, DEFAULT_SCHEMA);
138
+ auto catalog_entry = schema.GetEntry(data, CatalogType::TABLE_FUNCTION_ENTRY, name);
139
+ if (!catalog_entry) {
140
+ throw InvalidInputException("Function with name \"%s\" not found in ExtensionUtil::GetTableFunction", name);
141
+ }
142
+ return catalog_entry->Cast<TableFunctionCatalogEntry>();
143
+ }
144
+
89
145
  void ExtensionUtil::RegisterType(DatabaseInstance &db, string type_name, LogicalType type) {
90
146
  D_ASSERT(!type_name.empty());
91
147
  CreateTypeInfo info(std::move(type_name), std::move(type));