duckdb 0.7.1-dev2.0 → 0.7.1-dev284.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 (140) hide show
  1. package/binding.gyp +7 -7
  2. package/package.json +1 -1
  3. package/src/duckdb/extension/json/buffered_json_reader.cpp +50 -9
  4. package/src/duckdb/extension/json/include/buffered_json_reader.hpp +7 -2
  5. package/src/duckdb/extension/json/include/json_common.hpp +2 -2
  6. package/src/duckdb/extension/json/include/json_scan.hpp +29 -10
  7. package/src/duckdb/extension/json/json_functions/copy_json.cpp +35 -22
  8. package/src/duckdb/extension/json/json_functions/json_create.cpp +8 -8
  9. package/src/duckdb/extension/json/json_functions/json_transform.cpp +47 -8
  10. package/src/duckdb/extension/json/json_functions/read_json.cpp +104 -49
  11. package/src/duckdb/extension/json/json_functions/read_json_objects.cpp +5 -3
  12. package/src/duckdb/extension/json/json_functions.cpp +6 -0
  13. package/src/duckdb/extension/json/json_scan.cpp +144 -34
  14. package/src/duckdb/extension/parquet/parquet-extension.cpp +3 -2
  15. package/src/duckdb/src/catalog/catalog.cpp +15 -0
  16. package/src/duckdb/src/catalog/catalog_entry/index_catalog_entry.cpp +8 -7
  17. package/src/duckdb/src/common/enums/logical_operator_type.cpp +2 -0
  18. package/src/duckdb/src/common/enums/physical_operator_type.cpp +2 -0
  19. package/src/duckdb/src/common/enums/statement_type.cpp +2 -0
  20. package/src/duckdb/src/common/file_system.cpp +14 -0
  21. package/src/duckdb/src/common/hive_partitioning.cpp +1 -0
  22. package/src/duckdb/src/common/operator/cast_operators.cpp +14 -8
  23. package/src/duckdb/src/common/printer.cpp +1 -1
  24. package/src/duckdb/src/common/types/time.cpp +1 -1
  25. package/src/duckdb/src/common/types/timestamp.cpp +35 -4
  26. package/src/duckdb/src/common/types.cpp +36 -10
  27. package/src/duckdb/src/execution/column_binding_resolver.cpp +5 -2
  28. package/src/duckdb/src/execution/index/art/art.cpp +117 -67
  29. package/src/duckdb/src/execution/index/art/art_key.cpp +24 -12
  30. package/src/duckdb/src/execution/index/art/leaf.cpp +7 -8
  31. package/src/duckdb/src/execution/index/art/node.cpp +13 -27
  32. package/src/duckdb/src/execution/index/art/node16.cpp +5 -8
  33. package/src/duckdb/src/execution/index/art/node256.cpp +3 -5
  34. package/src/duckdb/src/execution/index/art/node4.cpp +4 -7
  35. package/src/duckdb/src/execution/index/art/node48.cpp +5 -8
  36. package/src/duckdb/src/execution/index/art/prefix.cpp +2 -3
  37. package/src/duckdb/src/execution/operator/join/physical_iejoin.cpp +7 -9
  38. package/src/duckdb/src/execution/operator/persistent/base_csv_reader.cpp +6 -11
  39. package/src/duckdb/src/execution/operator/persistent/buffered_csv_reader.cpp +13 -13
  40. package/src/duckdb/src/execution/operator/persistent/parallel_csv_reader.cpp +1 -1
  41. package/src/duckdb/src/execution/operator/schema/physical_detach.cpp +37 -0
  42. package/src/duckdb/src/execution/operator/schema/physical_drop.cpp +0 -5
  43. package/src/duckdb/src/execution/physical_plan/plan_simple.cpp +4 -0
  44. package/src/duckdb/src/execution/physical_plan_generator.cpp +1 -0
  45. package/src/duckdb/src/function/pragma/pragma_queries.cpp +38 -11
  46. package/src/duckdb/src/function/table/read_csv.cpp +17 -5
  47. package/src/duckdb/src/function/table/table_scan.cpp +3 -0
  48. package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
  49. package/src/duckdb/src/include/duckdb/catalog/catalog.hpp +5 -1
  50. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/duck_index_entry.hpp +1 -1
  51. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/index_catalog_entry.hpp +1 -1
  52. package/src/duckdb/src/include/duckdb/common/enums/logical_operator_type.hpp +1 -0
  53. package/src/duckdb/src/include/duckdb/common/enums/physical_operator_type.hpp +1 -0
  54. package/src/duckdb/src/include/duckdb/common/enums/statement_type.hpp +3 -2
  55. package/src/duckdb/src/include/duckdb/common/enums/wal_type.hpp +3 -0
  56. package/src/duckdb/src/include/duckdb/common/exception.hpp +10 -0
  57. package/src/duckdb/src/include/duckdb/common/file_system.hpp +1 -0
  58. package/src/duckdb/src/include/duckdb/common/hive_partitioning.hpp +9 -1
  59. package/src/duckdb/src/include/duckdb/common/radix_partitioning.hpp +4 -4
  60. package/src/duckdb/src/include/duckdb/common/types/timestamp.hpp +5 -1
  61. package/src/duckdb/src/include/duckdb/execution/index/art/art.hpp +37 -41
  62. package/src/duckdb/src/include/duckdb/execution/index/art/art_key.hpp +8 -11
  63. package/src/duckdb/src/include/duckdb/execution/operator/persistent/base_csv_reader.hpp +1 -3
  64. package/src/duckdb/src/include/duckdb/execution/operator/persistent/buffered_csv_reader.hpp +0 -2
  65. package/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_reader_options.hpp +2 -0
  66. package/src/duckdb/src/include/duckdb/execution/operator/schema/physical_detach.hpp +32 -0
  67. package/src/duckdb/src/include/duckdb/main/client_data.hpp +2 -2
  68. package/src/duckdb/src/include/duckdb/main/config.hpp +0 -3
  69. package/src/duckdb/src/include/duckdb/parser/parsed_data/create_database_info.hpp +0 -4
  70. package/src/duckdb/src/include/duckdb/parser/parsed_data/detach_info.hpp +32 -0
  71. package/src/duckdb/src/include/duckdb/parser/query_node/select_node.hpp +1 -1
  72. package/src/duckdb/src/include/duckdb/parser/sql_statement.hpp +2 -2
  73. package/src/duckdb/src/include/duckdb/parser/statement/copy_statement.hpp +1 -1
  74. package/src/duckdb/src/include/duckdb/parser/statement/detach_statement.hpp +29 -0
  75. package/src/duckdb/src/include/duckdb/parser/statement/list.hpp +1 -0
  76. package/src/duckdb/src/include/duckdb/parser/statement/select_statement.hpp +3 -3
  77. package/src/duckdb/src/include/duckdb/parser/tableref/subqueryref.hpp +1 -1
  78. package/src/duckdb/src/include/duckdb/parser/tokens.hpp +1 -0
  79. package/src/duckdb/src/include/duckdb/parser/transformer.hpp +1 -0
  80. package/src/duckdb/src/include/duckdb/planner/binder.hpp +4 -0
  81. package/src/duckdb/src/include/duckdb/planner/expression_binder/index_binder.hpp +10 -3
  82. package/src/duckdb/src/include/duckdb/planner/operator/logical_execute.hpp +1 -5
  83. package/src/duckdb/src/include/duckdb/planner/operator/logical_show.hpp +1 -2
  84. package/src/duckdb/src/include/duckdb/storage/data_table.hpp +7 -1
  85. package/src/duckdb/src/include/duckdb/storage/index.hpp +47 -38
  86. package/src/duckdb/src/include/duckdb/storage/storage_extension.hpp +7 -0
  87. package/src/duckdb/src/include/duckdb/storage/table/update_segment.hpp +2 -0
  88. package/src/duckdb/src/include/duckdb/storage/write_ahead_log.hpp +7 -0
  89. package/src/duckdb/src/main/client_context.cpp +2 -0
  90. package/src/duckdb/src/main/extension/extension_alias.cpp +2 -1
  91. package/src/duckdb/src/optimizer/statistics/operator/propagate_join.cpp +2 -6
  92. package/src/duckdb/src/parser/parsed_data/create_index_info.cpp +3 -0
  93. package/src/duckdb/src/parser/statement/copy_statement.cpp +2 -13
  94. package/src/duckdb/src/parser/statement/delete_statement.cpp +3 -0
  95. package/src/duckdb/src/parser/statement/detach_statement.cpp +15 -0
  96. package/src/duckdb/src/parser/statement/insert_statement.cpp +9 -0
  97. package/src/duckdb/src/parser/statement/update_statement.cpp +3 -0
  98. package/src/duckdb/src/parser/transform/expression/transform_case.cpp +3 -3
  99. package/src/duckdb/src/parser/transform/statement/transform_create_database.cpp +0 -1
  100. package/src/duckdb/src/parser/transform/statement/transform_detach.cpp +19 -0
  101. package/src/duckdb/src/parser/transformer.cpp +2 -0
  102. package/src/duckdb/src/planner/binder/expression/bind_aggregate_expression.cpp +3 -0
  103. package/src/duckdb/src/planner/binder/statement/bind_copy.cpp +6 -3
  104. package/src/duckdb/src/planner/binder/statement/bind_create.cpp +16 -14
  105. package/src/duckdb/src/planner/binder/statement/bind_create_table.cpp +13 -0
  106. package/src/duckdb/src/planner/binder/statement/bind_detach.cpp +19 -0
  107. package/src/duckdb/src/planner/binder/statement/bind_drop.cpp +29 -4
  108. package/src/duckdb/src/planner/binder/statement/bind_insert.cpp +22 -1
  109. package/src/duckdb/src/planner/binder/tableref/bind_joinref.cpp +2 -1
  110. package/src/duckdb/src/planner/binder.cpp +2 -0
  111. package/src/duckdb/src/planner/expression_binder/index_binder.cpp +32 -1
  112. package/src/duckdb/src/planner/expression_binder/lateral_binder.cpp +21 -5
  113. package/src/duckdb/src/planner/logical_operator.cpp +4 -0
  114. package/src/duckdb/src/planner/planner.cpp +1 -0
  115. package/src/duckdb/src/storage/compression/bitpacking.cpp +16 -7
  116. package/src/duckdb/src/storage/data_table.cpp +66 -3
  117. package/src/duckdb/src/storage/index.cpp +1 -1
  118. package/src/duckdb/src/storage/local_storage.cpp +1 -1
  119. package/src/duckdb/src/storage/storage_info.cpp +2 -1
  120. package/src/duckdb/src/storage/table/column_data.cpp +4 -2
  121. package/src/duckdb/src/storage/table/update_segment.cpp +15 -0
  122. package/src/duckdb/src/storage/table_index_list.cpp +1 -2
  123. package/src/duckdb/src/storage/wal_replay.cpp +68 -0
  124. package/src/duckdb/src/storage/write_ahead_log.cpp +21 -1
  125. package/src/duckdb/src/transaction/commit_state.cpp +5 -2
  126. package/src/duckdb/third_party/fmt/include/fmt/core.h +1 -2
  127. package/src/duckdb/third_party/libpg_query/include/nodes/nodes.hpp +1 -0
  128. package/src/duckdb/third_party/libpg_query/include/nodes/parsenodes.hpp +14 -0
  129. package/src/duckdb/third_party/libpg_query/include/parser/gram.hpp +530 -1006
  130. package/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp +17659 -17626
  131. package/src/duckdb/third_party/thrift/thrift/Thrift.h +8 -2
  132. package/src/duckdb/ub_extension_icu_third_party_icu_i18n.cpp +4 -4
  133. package/src/duckdb/ub_src_execution_operator_schema.cpp +2 -0
  134. package/src/duckdb/ub_src_parser_statement.cpp +2 -0
  135. package/src/duckdb/ub_src_parser_transform_statement.cpp +2 -0
  136. package/src/duckdb/ub_src_planner_binder_statement.cpp +2 -0
  137. package/src/statement.cpp +46 -12
  138. package/test/prepare.test.ts +39 -1
  139. package/test/typescript_decls.test.ts +1 -1
  140. package/src/duckdb/src/include/duckdb/function/create_database_extension.hpp +0 -37
@@ -2,6 +2,7 @@
2
2
 
3
3
  #include "duckdb/catalog/catalog_search_path.hpp"
4
4
  #include "duckdb/catalog/catalog_entry/list.hpp"
5
+ #include "duckdb/catalog/catalog_entry/table_catalog_entry.hpp"
5
6
  #include "duckdb/catalog/catalog_set.hpp"
6
7
  #include "duckdb/catalog/default/default_schemas.hpp"
7
8
  #include "duckdb/catalog/catalog_entry/type_catalog_entry.hpp"
@@ -251,6 +252,20 @@ CatalogEntry *Catalog::CreateCollation(CatalogTransaction transaction, SchemaCat
251
252
  return schema->CreateCollation(transaction, info);
252
253
  }
253
254
 
255
+ //===--------------------------------------------------------------------===//
256
+ // Index
257
+ //===--------------------------------------------------------------------===//
258
+ CatalogEntry *Catalog::CreateIndex(CatalogTransaction transaction, CreateIndexInfo *info) {
259
+ auto &context = transaction.GetContext();
260
+ return CreateIndex(context, info);
261
+ }
262
+
263
+ CatalogEntry *Catalog::CreateIndex(ClientContext &context, CreateIndexInfo *info) {
264
+ auto schema = GetSchema(context, info->schema);
265
+ auto table = GetEntry<TableCatalogEntry>(context, schema->name, info->table->table_name);
266
+ return schema->CreateIndex(context, info, table);
267
+ }
268
+
254
269
  //===--------------------------------------------------------------------===//
255
270
  // Lookup Structures
256
271
  //===--------------------------------------------------------------------===//
@@ -19,10 +19,11 @@ string IndexCatalogEntry::ToSQL() {
19
19
  return sql;
20
20
  }
21
21
 
22
- void IndexCatalogEntry::Serialize(duckdb::MetaBlockWriter &serializer) {
23
- // Here we serialize the index metadata in the following order:
24
- // schema name, table name, index name, sql, index type, index constraint type, expression list.
25
- // column_ids, unbound_expression
22
+ void IndexCatalogEntry::Serialize(Serializer &serializer) {
23
+ // here we serialize the index metadata in the following order:
24
+ // schema name, table name, index name, sql, index type, index constraint type, expression list, parsed expressions,
25
+ // column IDs
26
+
26
27
  FieldWriter writer(serializer);
27
28
  writer.WriteString(GetSchemaName());
28
29
  writer.WriteString(GetTableName());
@@ -37,9 +38,9 @@ void IndexCatalogEntry::Serialize(duckdb::MetaBlockWriter &serializer) {
37
38
  }
38
39
 
39
40
  unique_ptr<CreateIndexInfo> IndexCatalogEntry::Deserialize(Deserializer &source, ClientContext &context) {
40
- // Here we deserialize the index metadata in the following order:
41
- // root block, root offset, schema name, table name, index name, sql, index type, index constraint type, expression
42
- // list.
41
+ // here we deserialize the index metadata in the following order:
42
+ // schema name, table schema name, table name, index name, sql, index type, index constraint type, expression list,
43
+ // parsed expression list, column IDs
43
44
 
44
45
  auto create_index_info = make_unique<CreateIndexInfo>();
45
46
 
@@ -100,6 +100,8 @@ string LogicalOperatorToString(LogicalOperatorType type) {
100
100
  return "CREATE_SCHEMA";
101
101
  case LogicalOperatorType::LOGICAL_ATTACH:
102
102
  return "ATTACH";
103
+ case LogicalOperatorType::LOGICAL_DETACH:
104
+ return "ATTACH";
103
105
  case LogicalOperatorType::LOGICAL_DROP:
104
106
  return "DROP";
105
107
  case LogicalOperatorType::LOGICAL_PRAGMA:
@@ -133,6 +133,8 @@ string PhysicalOperatorToString(PhysicalOperatorType type) {
133
133
  return "CREATE_TYPE";
134
134
  case PhysicalOperatorType::ATTACH:
135
135
  return "ATTACH";
136
+ case PhysicalOperatorType::DETACH:
137
+ return "DETACH";
136
138
  case PhysicalOperatorType::RESULT_COLLECTOR:
137
139
  return "RESULT_COLLECTOR";
138
140
  case PhysicalOperatorType::EXTENSION:
@@ -57,6 +57,8 @@ string StatementTypeToString(StatementType type) {
57
57
  return "LOGICAL_PLAN";
58
58
  case StatementType::ATTACH_STATEMENT:
59
59
  return "ATTACH";
60
+ case StatementType::DETACH_STATEMENT:
61
+ return "DETACH";
60
62
  case StatementType::INVALID_STATEMENT:
61
63
  break;
62
64
  }
@@ -335,6 +335,20 @@ bool FileSystem::CanHandleFile(const string &fpath) {
335
335
  throw NotImplementedException("%s: CanHandleFile is not implemented!", GetName());
336
336
  }
337
337
 
338
+ IOException FileSystem::MissingFileException(const string &file_path, ClientContext &context) {
339
+ const string prefixes[] = {"http://", "https://", "s3://"};
340
+ for (auto &prefix : prefixes) {
341
+ if (StringUtil::StartsWith(file_path, prefix)) {
342
+ if (!context.db->LoadedExtensions().count("httpfs")) {
343
+ return MissingExtensionException("No files found that match the pattern \"%s\", because the httpfs "
344
+ "extension is not loaded. Try loading the extension: LOAD HTTPFS",
345
+ file_path);
346
+ }
347
+ }
348
+ }
349
+ return IOException("No files found that match the pattern \"%s\"", file_path);
350
+ }
351
+
338
352
  void FileSystem::Seek(FileHandle &handle, idx_t location) {
339
353
  throw NotImplementedException("%s: Seek is not implemented!", GetName());
340
354
  }
@@ -150,6 +150,7 @@ HivePartitionedColumnData::HivePartitionedColumnData(const HivePartitionedColumn
150
150
  void HivePartitionedColumnData::ComputePartitionIndices(PartitionedColumnDataAppendState &state, DataChunk &input) {
151
151
  Vector hashes(LogicalType::HASH, input.size());
152
152
  input.Hash(group_by_columns, hashes);
153
+ hashes.Flatten(input.size());
153
154
 
154
155
  for (idx_t i = 0; i < input.size(); i++) {
155
156
  HivePartitionKey key;
@@ -946,13 +946,13 @@ static bool IntegerCastLoop(const char *buf, idx_t len, T &result, bool strict)
946
946
  ExponentData exponent {0, false};
947
947
  int negative = buf[pos] == '-';
948
948
  if (negative) {
949
- if (!IntegerCastLoop<ExponentData, true, false, IntegerCastOperation>(buf + pos, len - pos,
950
- exponent, strict)) {
949
+ if (!IntegerCastLoop<ExponentData, true, false, IntegerCastOperation, decimal_separator>(
950
+ buf + pos, len - pos, exponent, strict)) {
951
951
  return false;
952
952
  }
953
953
  } else {
954
- if (!IntegerCastLoop<ExponentData, false, false, IntegerCastOperation>(buf + pos, len - pos,
955
- exponent, strict)) {
954
+ if (!IntegerCastLoop<ExponentData, false, false, IntegerCastOperation, decimal_separator>(
955
+ buf + pos, len - pos, exponent, strict)) {
956
956
  return false;
957
957
  }
958
958
  }
@@ -1554,16 +1554,22 @@ dtime_t Cast::Operation(string_t input) {
1554
1554
  //===--------------------------------------------------------------------===//
1555
1555
  template <>
1556
1556
  bool TryCastErrorMessage::Operation(string_t input, timestamp_t &result, string *error_message, bool strict) {
1557
- if (!TryCast::Operation<string_t, timestamp_t>(input, result, strict)) {
1557
+ auto cast_result = Timestamp::TryConvertTimestamp(input.GetDataUnsafe(), input.GetSize(), result);
1558
+ if (cast_result == TimestampCastResult::SUCCESS) {
1559
+ return true;
1560
+ }
1561
+ if (cast_result == TimestampCastResult::ERROR_INCORRECT_FORMAT) {
1558
1562
  HandleCastError::AssignError(Timestamp::ConversionError(input), error_message);
1559
- return false;
1563
+ } else {
1564
+ HandleCastError::AssignError(Timestamp::UnsupportedTimezoneError(input), error_message);
1560
1565
  }
1561
- return true;
1566
+ return false;
1562
1567
  }
1563
1568
 
1564
1569
  template <>
1565
1570
  bool TryCast::Operation(string_t input, timestamp_t &result, bool strict) {
1566
- return Timestamp::TryConvertTimestamp(input.GetDataUnsafe(), input.GetSize(), result);
1571
+ return Timestamp::TryConvertTimestamp(input.GetDataUnsafe(), input.GetSize(), result) ==
1572
+ TimestampCastResult::SUCCESS;
1567
1573
  }
1568
1574
 
1569
1575
  template <>
@@ -65,7 +65,7 @@ idx_t Printer::TerminalWidth() {
65
65
  int columns, rows;
66
66
 
67
67
  GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
68
- rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
68
+ rows = csbi.srWindow.Right - csbi.srWindow.Left + 1;
69
69
  return rows;
70
70
  #else
71
71
  struct winsize w;
@@ -115,7 +115,7 @@ bool Time::TryConvertTime(const char *buf, idx_t len, idx_t &pos, dtime_t &resul
115
115
  if (!strict) {
116
116
  // last chance, check if we can parse as timestamp
117
117
  timestamp_t timestamp;
118
- if (Timestamp::TryConvertTimestamp(buf, len, timestamp)) {
118
+ if (Timestamp::TryConvertTimestamp(buf, len, timestamp) == TimestampCastResult::SUCCESS) {
119
119
  if (!Timestamp::IsFinite(timestamp)) {
120
120
  return false;
121
121
  }
@@ -88,11 +88,27 @@ bool Timestamp::TryConvertTimestampTZ(const char *str, idx_t len, timestamp_t &r
88
88
  return true;
89
89
  }
90
90
 
91
- bool Timestamp::TryConvertTimestamp(const char *str, idx_t len, timestamp_t &result) {
91
+ TimestampCastResult Timestamp::TryConvertTimestamp(const char *str, idx_t len, timestamp_t &result) {
92
92
  string_t tz(nullptr, 0);
93
93
  bool has_offset = false;
94
94
  // We don't understand TZ without an extension, so fail if one was provided.
95
- return TryConvertTimestampTZ(str, len, result, has_offset, tz) && !tz.GetSize();
95
+ auto success = TryConvertTimestampTZ(str, len, result, has_offset, tz);
96
+ if (!success) {
97
+ return TimestampCastResult::ERROR_INCORRECT_FORMAT;
98
+ }
99
+ if (tz.GetSize() == 0) {
100
+ // no timezone provided - success!
101
+ return TimestampCastResult::SUCCESS;
102
+ }
103
+ if (tz.GetSize() == 3) {
104
+ // we can ONLY handle UTC without ICU being loaded
105
+ auto tz_ptr = tz.GetDataUnsafe();
106
+ if ((tz_ptr[0] == 'u' || tz_ptr[0] == 'U') && (tz_ptr[1] == 't' || tz_ptr[1] == 'T') &&
107
+ (tz_ptr[2] == 'c' || tz_ptr[2] == 'C')) {
108
+ return TimestampCastResult::SUCCESS;
109
+ }
110
+ }
111
+ return TimestampCastResult::ERROR_NON_UTC_TIMEZONE;
96
112
  }
97
113
 
98
114
  string Timestamp::ConversionError(const string &str) {
@@ -101,16 +117,31 @@ string Timestamp::ConversionError(const string &str) {
101
117
  str);
102
118
  }
103
119
 
120
+ string Timestamp::UnsupportedTimezoneError(const string &str) {
121
+ return StringUtil::Format("timestamp field value \"%s\" has a timestamp that is not UTC.\nUse the TIMESTAMPTZ type "
122
+ "with the ICU extension loaded to handle non-UTC timestamps.",
123
+ str);
124
+ }
125
+
104
126
  string Timestamp::ConversionError(string_t str) {
105
127
  return Timestamp::ConversionError(str.GetString());
106
128
  }
107
129
 
130
+ string Timestamp::UnsupportedTimezoneError(string_t str) {
131
+ return Timestamp::UnsupportedTimezoneError(str.GetString());
132
+ }
133
+
108
134
  timestamp_t Timestamp::FromCString(const char *str, idx_t len) {
109
135
  timestamp_t result;
110
- if (!Timestamp::TryConvertTimestamp(str, len, result)) {
136
+ auto cast_result = Timestamp::TryConvertTimestamp(str, len, result);
137
+ if (cast_result == TimestampCastResult::SUCCESS) {
138
+ return result;
139
+ }
140
+ if (cast_result == TimestampCastResult::ERROR_NON_UTC_TIMEZONE) {
141
+ throw ConversionException(Timestamp::UnsupportedTimezoneError(string(str, len)));
142
+ } else {
111
143
  throw ConversionException(Timestamp::ConversionError(string(str, len)));
112
144
  }
113
- return result;
114
145
  }
115
146
 
116
147
  bool Timestamp::TryParseUTCOffset(const char *str, idx_t &pos, idx_t len, int &hour_offset, int &minute_offset) {
@@ -504,11 +504,32 @@ LogicalType TransformStringToLogicalType(const string &str) {
504
504
  return Parser::ParseColumnList("dummy " + str).GetColumn(LogicalIndex(0)).Type();
505
505
  }
506
506
 
507
+ LogicalType GetUserTypeRecursive(const LogicalType &type, ClientContext &context) {
508
+ if (type.id() == LogicalTypeId::USER && type.HasAlias()) {
509
+ return Catalog::GetSystemCatalog(context).GetType(context, SYSTEM_CATALOG, DEFAULT_SCHEMA, type.GetAlias());
510
+ }
511
+ // Look for LogicalTypeId::USER in nested types
512
+ if (type.id() == LogicalTypeId::STRUCT) {
513
+ child_list_t<LogicalType> children;
514
+ children.reserve(StructType::GetChildCount(type));
515
+ for (auto &child : StructType::GetChildTypes(type)) {
516
+ children.emplace_back(child.first, GetUserTypeRecursive(child.second, context));
517
+ }
518
+ return LogicalType::STRUCT(std::move(children));
519
+ }
520
+ if (type.id() == LogicalTypeId::LIST) {
521
+ return LogicalType::LIST(GetUserTypeRecursive(ListType::GetChildType(type), context));
522
+ }
523
+ if (type.id() == LogicalTypeId::MAP) {
524
+ return LogicalType::MAP(GetUserTypeRecursive(MapType::KeyType(type), context),
525
+ GetUserTypeRecursive(MapType::ValueType(type), context));
526
+ }
527
+ // Not LogicalTypeId::USER or a nested type
528
+ return type;
529
+ }
530
+
507
531
  LogicalType TransformStringToLogicalType(const string &str, ClientContext &context) {
508
- auto type = TransformStringToLogicalType(str);
509
- return type.id() == LogicalTypeId::USER
510
- ? Catalog::GetSystemCatalog(context).GetType(context, SYSTEM_CATALOG, DEFAULT_SCHEMA, str)
511
- : type;
532
+ return GetUserTypeRecursive(TransformStringToLogicalType(str), context);
512
533
  }
513
534
 
514
535
  bool LogicalType::IsIntegral() const {
@@ -888,18 +909,23 @@ void LogicalType::SetAlias(string alias) {
888
909
  }
889
910
 
890
911
  string LogicalType::GetAlias() const {
891
- if (!type_info_) {
892
- return string();
893
- } else {
912
+ if (id() == LogicalTypeId::USER) {
913
+ return UserType::GetTypeName(*this);
914
+ }
915
+ if (type_info_) {
894
916
  return type_info_->alias;
895
917
  }
918
+ return string();
896
919
  }
897
920
 
898
921
  bool LogicalType::HasAlias() const {
899
- if (!type_info_) {
900
- return false;
922
+ if (id() == LogicalTypeId::USER) {
923
+ return !UserType::GetTypeName(*this).empty();
924
+ }
925
+ if (type_info_ && !type_info_->alias.empty()) {
926
+ return true;
901
927
  }
902
- return !type_info_->alias.empty();
928
+ return false;
903
929
  }
904
930
 
905
931
  void LogicalType::SetCatalog(LogicalType &type, TypeCatalogEntry *catalog_entry) {
@@ -65,9 +65,12 @@ void ColumnBindingResolver::VisitOperator(LogicalOperator &op) {
65
65
  // ON CONFLICT DO UPDATE clause
66
66
  auto &insert_op = (LogicalInsert &)op;
67
67
  if (insert_op.action_type != OnConflictAction::THROW) {
68
+ // Get the bindings from the children
68
69
  VisitOperatorChildren(op);
69
- auto dummy_bindings = LogicalOperator::GenerateColumnBindings(
70
- insert_op.excluded_table_index, insert_op.table->GetColumns().PhysicalColumnCount());
70
+ auto column_count = insert_op.table->GetColumns().PhysicalColumnCount();
71
+ auto dummy_bindings = LogicalOperator::GenerateColumnBindings(insert_op.excluded_table_index, column_count);
72
+ // Now insert our dummy bindings at the start of the bindings,
73
+ // so the first 'column_count' indices of the chunk are reserved for our 'excluded' columns
71
74
  bindings.insert(bindings.begin(), dummy_bindings.begin(), dummy_bindings.end());
72
75
  if (insert_op.on_conflict_condition) {
73
76
  VisitExpression(&insert_op.on_conflict_condition);