duckdb 0.7.1-dev90.0 → 0.7.2-dev0.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 (131) hide show
  1. package/README.md +1 -1
  2. package/binding.gyp +7 -7
  3. package/package.json +3 -3
  4. package/src/duckdb/extension/json/buffered_json_reader.cpp +50 -9
  5. package/src/duckdb/extension/json/include/buffered_json_reader.hpp +7 -2
  6. package/src/duckdb/extension/json/include/json_scan.hpp +45 -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_structure.cpp +8 -3
  10. package/src/duckdb/extension/json/json_functions/json_transform.cpp +54 -10
  11. package/src/duckdb/extension/json/json_functions/read_json.cpp +104 -49
  12. package/src/duckdb/extension/json/json_functions/read_json_objects.cpp +5 -3
  13. package/src/duckdb/extension/json/json_functions.cpp +7 -0
  14. package/src/duckdb/extension/json/json_scan.cpp +144 -38
  15. package/src/duckdb/extension/parquet/column_reader.cpp +7 -0
  16. package/src/duckdb/extension/parquet/include/column_reader.hpp +1 -0
  17. package/src/duckdb/extension/parquet/parquet-extension.cpp +2 -10
  18. package/src/duckdb/src/catalog/catalog.cpp +62 -13
  19. package/src/duckdb/src/catalog/catalog_entry/index_catalog_entry.cpp +8 -7
  20. package/src/duckdb/src/catalog/catalog_entry/schema_catalog_entry.cpp +1 -1
  21. package/src/duckdb/src/catalog/catalog_set.cpp +1 -1
  22. package/src/duckdb/src/catalog/default/default_functions.cpp +1 -0
  23. package/src/duckdb/src/catalog/default/default_views.cpp +1 -1
  24. package/src/duckdb/src/common/bind_helpers.cpp +55 -0
  25. package/src/duckdb/src/common/file_system.cpp +23 -9
  26. package/src/duckdb/src/common/hive_partitioning.cpp +1 -0
  27. package/src/duckdb/src/common/local_file_system.cpp +4 -4
  28. package/src/duckdb/src/common/string_util.cpp +8 -4
  29. package/src/duckdb/src/common/types/partitioned_column_data.cpp +1 -0
  30. package/src/duckdb/src/common/types.cpp +37 -11
  31. package/src/duckdb/src/execution/column_binding_resolver.cpp +5 -2
  32. package/src/duckdb/src/execution/index/art/art.cpp +117 -67
  33. package/src/duckdb/src/execution/index/art/art_key.cpp +24 -12
  34. package/src/duckdb/src/execution/index/art/leaf.cpp +7 -8
  35. package/src/duckdb/src/execution/index/art/node.cpp +13 -27
  36. package/src/duckdb/src/execution/index/art/node16.cpp +5 -8
  37. package/src/duckdb/src/execution/index/art/node256.cpp +3 -5
  38. package/src/duckdb/src/execution/index/art/node4.cpp +4 -7
  39. package/src/duckdb/src/execution/index/art/node48.cpp +5 -8
  40. package/src/duckdb/src/execution/index/art/prefix.cpp +2 -3
  41. package/src/duckdb/src/execution/operator/aggregate/physical_window.cpp +6 -27
  42. package/src/duckdb/src/execution/operator/helper/physical_reset.cpp +1 -9
  43. package/src/duckdb/src/execution/operator/helper/physical_set.cpp +1 -9
  44. package/src/duckdb/src/execution/operator/join/physical_iejoin.cpp +7 -9
  45. package/src/duckdb/src/execution/operator/persistent/buffered_csv_reader.cpp +9 -0
  46. package/src/duckdb/src/execution/physical_operator.cpp +6 -6
  47. package/src/duckdb/src/function/pragma/pragma_queries.cpp +38 -11
  48. package/src/duckdb/src/function/scalar/generic/current_setting.cpp +2 -2
  49. package/src/duckdb/src/function/scalar/list/array_slice.cpp +2 -3
  50. package/src/duckdb/src/function/scalar/map/map.cpp +69 -21
  51. package/src/duckdb/src/function/scalar/string/like.cpp +6 -3
  52. package/src/duckdb/src/function/table/read_csv.cpp +16 -5
  53. package/src/duckdb/src/function/table/system/duckdb_temporary_files.cpp +59 -0
  54. package/src/duckdb/src/function/table/system_functions.cpp +1 -0
  55. package/src/duckdb/src/function/table/table_scan.cpp +3 -0
  56. package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
  57. package/src/duckdb/src/include/duckdb/catalog/catalog.hpp +7 -1
  58. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/duck_index_entry.hpp +1 -1
  59. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/index_catalog_entry.hpp +1 -1
  60. package/src/duckdb/src/include/duckdb/common/bind_helpers.hpp +2 -0
  61. package/src/duckdb/src/include/duckdb/common/enums/statement_type.hpp +1 -1
  62. package/src/duckdb/src/include/duckdb/common/enums/wal_type.hpp +3 -0
  63. package/src/duckdb/src/include/duckdb/common/file_system.hpp +1 -1
  64. package/src/duckdb/src/include/duckdb/common/hive_partitioning.hpp +9 -1
  65. package/src/duckdb/src/include/duckdb/common/radix_partitioning.hpp +4 -4
  66. package/src/duckdb/src/include/duckdb/common/string_util.hpp +9 -2
  67. package/src/duckdb/src/include/duckdb/execution/index/art/art.hpp +37 -41
  68. package/src/duckdb/src/include/duckdb/execution/index/art/art_key.hpp +8 -11
  69. package/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_reader_options.hpp +2 -0
  70. package/src/duckdb/src/include/duckdb/function/scalar/string_functions.hpp +2 -1
  71. package/src/duckdb/src/include/duckdb/function/table/system_functions.hpp +4 -0
  72. package/src/duckdb/src/include/duckdb/main/client_data.hpp +2 -2
  73. package/src/duckdb/src/include/duckdb/main/config.hpp +2 -0
  74. package/src/duckdb/src/include/duckdb/main/{extension_functions.hpp → extension_entries.hpp} +27 -5
  75. package/src/duckdb/src/include/duckdb/main/extension_helper.hpp +11 -1
  76. package/src/duckdb/src/include/duckdb/main/settings.hpp +9 -0
  77. package/src/duckdb/src/include/duckdb/parallel/pipeline_executor.hpp +0 -7
  78. package/src/duckdb/src/include/duckdb/parser/query_node/select_node.hpp +1 -1
  79. package/src/duckdb/src/include/duckdb/parser/sql_statement.hpp +2 -2
  80. package/src/duckdb/src/include/duckdb/parser/statement/copy_statement.hpp +1 -1
  81. package/src/duckdb/src/include/duckdb/parser/statement/select_statement.hpp +3 -3
  82. package/src/duckdb/src/include/duckdb/parser/tableref/subqueryref.hpp +1 -1
  83. package/src/duckdb/src/include/duckdb/planner/binder.hpp +3 -0
  84. package/src/duckdb/src/include/duckdb/planner/expression_binder/index_binder.hpp +10 -3
  85. package/src/duckdb/src/include/duckdb/planner/operator/logical_execute.hpp +1 -5
  86. package/src/duckdb/src/include/duckdb/planner/operator/logical_show.hpp +1 -2
  87. package/src/duckdb/src/include/duckdb/storage/buffer_manager.hpp +8 -0
  88. package/src/duckdb/src/include/duckdb/storage/data_table.hpp +7 -1
  89. package/src/duckdb/src/include/duckdb/storage/index.hpp +47 -38
  90. package/src/duckdb/src/include/duckdb/storage/write_ahead_log.hpp +7 -0
  91. package/src/duckdb/src/main/client_context.cpp +2 -0
  92. package/src/duckdb/src/main/config.cpp +1 -0
  93. package/src/duckdb/src/main/database.cpp +14 -5
  94. package/src/duckdb/src/main/extension/extension_alias.cpp +2 -1
  95. package/src/duckdb/src/main/extension/extension_helper.cpp +15 -0
  96. package/src/duckdb/src/main/extension/extension_install.cpp +60 -16
  97. package/src/duckdb/src/main/extension/extension_load.cpp +62 -13
  98. package/src/duckdb/src/main/settings/settings.cpp +16 -0
  99. package/src/duckdb/src/optimizer/statistics/operator/propagate_join.cpp +2 -6
  100. package/src/duckdb/src/parallel/pipeline_executor.cpp +1 -55
  101. package/src/duckdb/src/parser/parsed_data/create_index_info.cpp +3 -0
  102. package/src/duckdb/src/parser/statement/copy_statement.cpp +2 -13
  103. package/src/duckdb/src/parser/statement/delete_statement.cpp +3 -0
  104. package/src/duckdb/src/parser/statement/insert_statement.cpp +9 -0
  105. package/src/duckdb/src/parser/statement/update_statement.cpp +3 -0
  106. package/src/duckdb/src/parser/transform/expression/transform_case.cpp +3 -3
  107. package/src/duckdb/src/planner/bind_context.cpp +1 -1
  108. package/src/duckdb/src/planner/binder/expression/bind_aggregate_expression.cpp +3 -0
  109. package/src/duckdb/src/planner/binder/statement/bind_copy.cpp +7 -14
  110. package/src/duckdb/src/planner/binder/statement/bind_create_table.cpp +13 -0
  111. package/src/duckdb/src/planner/binder/statement/bind_drop.cpp +2 -2
  112. package/src/duckdb/src/planner/binder/statement/bind_insert.cpp +22 -1
  113. package/src/duckdb/src/planner/expression_binder/index_binder.cpp +32 -1
  114. package/src/duckdb/src/planner/logical_operator.cpp +4 -1
  115. package/src/duckdb/src/storage/buffer_manager.cpp +105 -26
  116. package/src/duckdb/src/storage/compression/bitpacking.cpp +16 -7
  117. package/src/duckdb/src/storage/data_table.cpp +66 -3
  118. package/src/duckdb/src/storage/index.cpp +1 -1
  119. package/src/duckdb/src/storage/local_storage.cpp +1 -1
  120. package/src/duckdb/src/storage/table_index_list.cpp +1 -2
  121. package/src/duckdb/src/storage/wal_replay.cpp +68 -0
  122. package/src/duckdb/src/storage/write_ahead_log.cpp +21 -1
  123. package/src/duckdb/src/transaction/commit_state.cpp +5 -2
  124. package/src/duckdb/third_party/concurrentqueue/blockingconcurrentqueue.h +2 -2
  125. package/src/duckdb/third_party/fmt/include/fmt/core.h +1 -2
  126. package/src/duckdb/ub_extension_icu_third_party_icu_i18n.cpp +4 -4
  127. package/src/duckdb/ub_src_function_table_system.cpp +2 -0
  128. package/src/statement.cpp +46 -12
  129. package/test/arrow.test.ts +3 -3
  130. package/test/prepare.test.ts +39 -1
  131. package/test/typescript_decls.test.ts +1 -1
@@ -4,6 +4,7 @@
4
4
  #include "duckdb/common/exception.hpp"
5
5
  #include "duckdb/common/types/value.hpp"
6
6
  #include "duckdb/common/case_insensitive_map.hpp"
7
+ #include <numeric>
7
8
 
8
9
  namespace duckdb {
9
10
 
@@ -64,4 +65,58 @@ vector<bool> ParseColumnList(const Value &value, vector<string> &names, const st
64
65
  return ParseColumnList(children, names, loption);
65
66
  }
66
67
 
68
+ vector<idx_t> ParseColumnsOrdered(const vector<Value> &set, vector<string> &names, const string &loption) {
69
+ vector<idx_t> result;
70
+
71
+ if (set.empty()) {
72
+ throw BinderException("\"%s\" expects a column list or * as parameter", loption);
73
+ }
74
+
75
+ // Maps option to bool indicating if its found and the index in the original set
76
+ case_insensitive_map_t<std::pair<bool, idx_t>> option_map;
77
+ for (idx_t i = 0; i < set.size(); i++) {
78
+ option_map[set[i].ToString()] = {false, i};
79
+ }
80
+ result.resize(option_map.size());
81
+
82
+ for (idx_t i = 0; i < names.size(); i++) {
83
+ auto entry = option_map.find(names[i]);
84
+ if (entry != option_map.end()) {
85
+ result[entry->second.second] = i;
86
+ entry->second.first = true;
87
+ }
88
+ }
89
+ for (auto &entry : option_map) {
90
+ if (!entry.second.first) {
91
+ throw BinderException("\"%s\" expected to find %s, but it was not found in the table", loption,
92
+ entry.first.c_str());
93
+ }
94
+ }
95
+ return result;
96
+ }
97
+
98
+ vector<idx_t> ParseColumnsOrdered(const Value &value, vector<string> &names, const string &loption) {
99
+ vector<idx_t> result;
100
+
101
+ // Only accept a list of arguments
102
+ if (value.type().id() != LogicalTypeId::LIST) {
103
+ // Support a single argument if it's '*'
104
+ if (value.type().id() == LogicalTypeId::VARCHAR && value.GetValue<string>() == "*") {
105
+ result.resize(names.size(), 0);
106
+ std::iota(std::begin(result), std::end(result), 0);
107
+ return result;
108
+ }
109
+ throw BinderException("\"%s\" expects a column list or * as parameter", loption);
110
+ }
111
+ auto &children = ListValue::GetChildren(value);
112
+ // accept '*' as single argument
113
+ if (children.size() == 1 && children[0].type().id() == LogicalTypeId::VARCHAR &&
114
+ children[0].GetValue<string>() == "*") {
115
+ result.resize(names.size(), 0);
116
+ std::iota(std::begin(result), std::end(result), 0);
117
+ return result;
118
+ }
119
+ return ParseColumnsOrdered(children, names, loption);
120
+ }
121
+
67
122
  } // namespace duckdb
@@ -10,6 +10,7 @@
10
10
  #include "duckdb/main/client_context.hpp"
11
11
  #include "duckdb/main/client_data.hpp"
12
12
  #include "duckdb/main/database.hpp"
13
+ #include "duckdb/main/extension_helper.hpp"
13
14
 
14
15
  #include <cstdint>
15
16
  #include <cstdio>
@@ -335,18 +336,31 @@ bool FileSystem::CanHandleFile(const string &fpath) {
335
336
  throw NotImplementedException("%s: CanHandleFile is not implemented!", GetName());
336
337
  }
337
338
 
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);
339
+ vector<string> FileSystem::GlobFiles(const string &pattern, ClientContext &context) {
340
+ auto result = Glob(pattern, context);
341
+ if (result.empty()) {
342
+ string required_extension;
343
+ const string prefixes[] = {"http://", "https://", "s3://"};
344
+ for (auto &prefix : prefixes) {
345
+ if (StringUtil::StartsWith(pattern, prefix)) {
346
+ required_extension = "httpfs";
347
+ break;
346
348
  }
347
349
  }
350
+ if (!required_extension.empty() && !context.db->ExtensionIsLoaded(required_extension)) {
351
+ // an extension is required to read this file but it is not loaded - try to load it
352
+ ExtensionHelper::LoadExternalExtension(context, required_extension);
353
+ // success! glob again
354
+ // check the extension is loaded just in case to prevent an infinite loop here
355
+ if (!context.db->ExtensionIsLoaded(required_extension)) {
356
+ throw InternalException("Extension load \"%s\" did not throw but somehow the extension was not loaded",
357
+ required_extension);
358
+ }
359
+ return GlobFiles(pattern, context);
360
+ }
361
+ throw IOException("No files found that match the pattern \"%s\"", pattern);
348
362
  }
349
- return IOException("No files found that match the pattern \"%s\"", file_path);
363
+ return result;
350
364
  }
351
365
 
352
366
  void FileSystem::Seek(FileHandle &handle, idx_t location) {
@@ -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;
@@ -833,8 +833,8 @@ static bool HasGlob(const string &str) {
833
833
  return false;
834
834
  }
835
835
 
836
- static void GlobFiles(FileSystem &fs, const string &path, const string &glob, bool match_directory,
837
- vector<string> &result, bool join_path) {
836
+ static void GlobFilesInternal(FileSystem &fs, const string &path, const string &glob, bool match_directory,
837
+ vector<string> &result, bool join_path) {
838
838
  fs.ListFiles(path, [&](const string &fname, bool is_directory) {
839
839
  if (is_directory != match_directory) {
840
840
  return;
@@ -951,12 +951,12 @@ vector<string> LocalFileSystem::Glob(const string &path, FileOpener *opener) {
951
951
  } else {
952
952
  if (previous_directories.empty()) {
953
953
  // no previous directories: list in the current path
954
- GlobFiles(*this, ".", splits[i], !is_last_chunk, result, false);
954
+ GlobFilesInternal(*this, ".", splits[i], !is_last_chunk, result, false);
955
955
  } else {
956
956
  // previous directories
957
957
  // we iterate over each of the previous directories, and apply the glob of the current directory
958
958
  for (auto &prev_directory : previous_directories) {
959
- GlobFiles(*this, prev_directory, splits[i], !is_last_chunk, result, true);
959
+ GlobFilesInternal(*this, prev_directory, splits[i], !is_last_chunk, result, true);
960
960
  }
961
961
  }
962
962
  }
@@ -249,7 +249,7 @@ private:
249
249
  };
250
250
 
251
251
  // adapted from https://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#C++
252
- idx_t StringUtil::LevenshteinDistance(const string &s1_p, const string &s2_p) {
252
+ idx_t StringUtil::LevenshteinDistance(const string &s1_p, const string &s2_p, idx_t not_equal_penalty) {
253
253
  auto s1 = StringUtil::Lower(s1_p);
254
254
  auto s2 = StringUtil::Lower(s2_p);
255
255
  idx_t len1 = s1.size();
@@ -273,7 +273,7 @@ idx_t StringUtil::LevenshteinDistance(const string &s1_p, const string &s2_p) {
273
273
  // d[i][j] = std::min({ d[i - 1][j] + 1,
274
274
  // d[i][j - 1] + 1,
275
275
  // d[i - 1][j - 1] + (s1[i - 1] == s2[j - 1] ? 0 : 1) });
276
- int equal = s1[i - 1] == s2[j - 1] ? 0 : 1;
276
+ int equal = s1[i - 1] == s2[j - 1] ? 0 : not_equal_penalty;
277
277
  idx_t adjacent_score1 = array.Score(i - 1, j) + 1;
278
278
  idx_t adjacent_score2 = array.Score(i, j - 1) + 1;
279
279
  idx_t adjacent_score3 = array.Score(i - 1, j - 1) + equal;
@@ -285,15 +285,19 @@ idx_t StringUtil::LevenshteinDistance(const string &s1_p, const string &s2_p) {
285
285
  return array.Score(len1, len2);
286
286
  }
287
287
 
288
+ idx_t StringUtil::SimilarityScore(const string &s1, const string &s2) {
289
+ return LevenshteinDistance(s1, s2, 3);
290
+ }
291
+
288
292
  vector<string> StringUtil::TopNLevenshtein(const vector<string> &strings, const string &target, idx_t n,
289
293
  idx_t threshold) {
290
294
  vector<pair<string, idx_t>> scores;
291
295
  scores.reserve(strings.size());
292
296
  for (auto &str : strings) {
293
297
  if (target.size() < str.size()) {
294
- scores.emplace_back(str, LevenshteinDistance(str.substr(0, target.size()), target));
298
+ scores.emplace_back(str, SimilarityScore(str.substr(0, target.size()), target));
295
299
  } else {
296
- scores.emplace_back(str, LevenshteinDistance(str, target));
300
+ scores.emplace_back(str, SimilarityScore(str, target));
297
301
  }
298
302
  }
299
303
  return TopNStrings(scores, n, threshold);
@@ -137,6 +137,7 @@ void PartitionedColumnData::FlushAppendState(PartitionedColumnDataAppendState &s
137
137
  auto &partition_buffer = *state.partition_buffers[i];
138
138
  if (partition_buffer.size() > 0) {
139
139
  partitions[i]->Append(partition_buffer);
140
+ partition_buffer.Reset();
140
141
  }
141
142
  }
142
143
  }
@@ -424,7 +424,7 @@ string LogicalType::ToString() const {
424
424
  auto &child_types = StructType::GetChildTypes(*this);
425
425
  string ret = "STRUCT(";
426
426
  for (size_t i = 0; i < child_types.size(); i++) {
427
- ret += child_types[i].first + " " + child_types[i].second.ToString();
427
+ ret += KeywordHelper::WriteOptionallyQuoted(child_types[i].first) + " " + child_types[i].second.ToString();
428
428
  if (i < child_types.size() - 1) {
429
429
  ret += ", ";
430
430
  }
@@ -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);