duckdb 1.1.4-dev13.0 → 1.1.4-dev14.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 (219) hide show
  1. package/binding.gyp +1 -0
  2. package/package.json +1 -1
  3. package/src/duckdb/extension/core_functions/function_list.cpp +1 -0
  4. package/src/duckdb/extension/core_functions/include/core_functions/scalar/map_functions.hpp +9 -0
  5. package/src/duckdb/extension/core_functions/scalar/date/current.cpp +1 -0
  6. package/src/duckdb/extension/core_functions/scalar/generic/can_implicitly_cast.cpp +2 -2
  7. package/src/duckdb/extension/core_functions/scalar/generic/typeof.cpp +1 -1
  8. package/src/duckdb/extension/core_functions/scalar/list/flatten.cpp +91 -61
  9. package/src/duckdb/extension/core_functions/scalar/map/map_extract.cpp +89 -8
  10. package/src/duckdb/extension/icu/icu-current.cpp +63 -0
  11. package/src/duckdb/extension/icu/icu-makedate.cpp +43 -39
  12. package/src/duckdb/extension/icu/icu-timezone.cpp +63 -63
  13. package/src/duckdb/extension/icu/icu_extension.cpp +2 -0
  14. package/src/duckdb/extension/icu/include/icu-casts.hpp +39 -0
  15. package/src/duckdb/extension/icu/include/icu-current.hpp +17 -0
  16. package/src/duckdb/extension/icu/third_party/icu/stubdata/stubdata.cpp +1 -1
  17. package/src/duckdb/extension/json/json_functions/json_structure.cpp +3 -1
  18. package/src/duckdb/extension/parquet/column_writer.cpp +26 -18
  19. package/src/duckdb/extension/parquet/include/parquet_reader.hpp +0 -6
  20. package/src/duckdb/extension/parquet/include/parquet_writer.hpp +15 -1
  21. package/src/duckdb/extension/parquet/include/resizable_buffer.hpp +1 -0
  22. package/src/duckdb/extension/parquet/parquet_extension.cpp +67 -15
  23. package/src/duckdb/extension/parquet/parquet_reader.cpp +5 -3
  24. package/src/duckdb/extension/parquet/parquet_writer.cpp +5 -6
  25. package/src/duckdb/src/catalog/catalog.cpp +21 -8
  26. package/src/duckdb/src/catalog/catalog_search_path.cpp +17 -1
  27. package/src/duckdb/src/catalog/catalog_set.cpp +1 -1
  28. package/src/duckdb/src/catalog/default/default_functions.cpp +0 -3
  29. package/src/duckdb/src/catalog/dependency_list.cpp +7 -0
  30. package/src/duckdb/src/common/adbc/adbc.cpp +1 -56
  31. package/src/duckdb/src/common/arrow/arrow_converter.cpp +3 -2
  32. package/src/duckdb/src/common/arrow/arrow_type_extension.cpp +58 -28
  33. package/src/duckdb/src/common/arrow/schema_metadata.cpp +1 -1
  34. package/src/duckdb/src/common/compressed_file_system.cpp +6 -2
  35. package/src/duckdb/src/common/enum_util.cpp +26 -22
  36. package/src/duckdb/src/common/error_data.cpp +3 -2
  37. package/src/duckdb/src/common/gzip_file_system.cpp +8 -8
  38. package/src/duckdb/src/common/local_file_system.cpp +2 -2
  39. package/src/duckdb/src/common/multi_file_reader.cpp +1 -1
  40. package/src/duckdb/src/common/random_engine.cpp +4 -1
  41. package/src/duckdb/src/common/serializer/memory_stream.cpp +23 -19
  42. package/src/duckdb/src/common/serializer/serializer.cpp +1 -1
  43. package/src/duckdb/src/common/types/bit.cpp +1 -1
  44. package/src/duckdb/src/common/types/column/column_data_allocator.cpp +0 -5
  45. package/src/duckdb/src/common/types/column/column_data_collection.cpp +4 -1
  46. package/src/duckdb/src/common/types/data_chunk.cpp +2 -1
  47. package/src/duckdb/src/common/types/row/tuple_data_segment.cpp +0 -4
  48. package/src/duckdb/src/common/types.cpp +1 -1
  49. package/src/duckdb/src/execution/index/art/art.cpp +52 -42
  50. package/src/duckdb/src/execution/index/art/leaf.cpp +4 -9
  51. package/src/duckdb/src/execution/index/art/node.cpp +13 -13
  52. package/src/duckdb/src/execution/index/art/prefix.cpp +21 -16
  53. package/src/duckdb/src/execution/index/bound_index.cpp +6 -8
  54. package/src/duckdb/src/execution/index/fixed_size_allocator.cpp +39 -34
  55. package/src/duckdb/src/execution/index/fixed_size_buffer.cpp +2 -1
  56. package/src/duckdb/src/execution/index/unbound_index.cpp +10 -0
  57. package/src/duckdb/src/execution/operator/aggregate/physical_streaming_window.cpp +62 -44
  58. package/src/duckdb/src/execution/operator/csv_scanner/scanner/column_count_scanner.cpp +26 -0
  59. package/src/duckdb/src/execution/operator/csv_scanner/scanner/string_value_scanner.cpp +69 -40
  60. package/src/duckdb/src/execution/operator/csv_scanner/sniffer/dialect_detection.cpp +3 -7
  61. package/src/duckdb/src/execution/operator/csv_scanner/sniffer/header_detection.cpp +11 -5
  62. package/src/duckdb/src/execution/operator/csv_scanner/sniffer/type_detection.cpp +4 -0
  63. package/src/duckdb/src/execution/operator/csv_scanner/state_machine/csv_state_machine_cache.cpp +8 -8
  64. package/src/duckdb/src/execution/operator/csv_scanner/util/csv_error.cpp +36 -12
  65. package/src/duckdb/src/execution/operator/csv_scanner/util/csv_reader_options.cpp +12 -9
  66. package/src/duckdb/src/execution/operator/join/physical_hash_join.cpp +0 -1
  67. package/src/duckdb/src/execution/operator/persistent/physical_copy_database.cpp +29 -1
  68. package/src/duckdb/src/execution/operator/persistent/physical_delete.cpp +58 -10
  69. package/src/duckdb/src/execution/operator/persistent/physical_insert.cpp +58 -35
  70. package/src/duckdb/src/execution/operator/schema/physical_create_art_index.cpp +2 -1
  71. package/src/duckdb/src/execution/radix_partitioned_hashtable.cpp +9 -4
  72. package/src/duckdb/src/execution/sample/reservoir_sample.cpp +7 -6
  73. package/src/duckdb/src/function/compression_config.cpp +4 -0
  74. package/src/duckdb/src/function/function_binder.cpp +1 -1
  75. package/src/duckdb/src/function/scalar/system/write_log.cpp +2 -2
  76. package/src/duckdb/src/function/table/arrow/arrow_duck_schema.cpp +15 -2
  77. package/src/duckdb/src/function/table/arrow_conversion.cpp +10 -10
  78. package/src/duckdb/src/function/table/copy_csv.cpp +8 -5
  79. package/src/duckdb/src/function/table/read_csv.cpp +21 -4
  80. package/src/duckdb/src/function/table/sniff_csv.cpp +7 -0
  81. package/src/duckdb/src/function/table/system/duckdb_extensions.cpp +4 -0
  82. package/src/duckdb/src/function/table/system/duckdb_secret_types.cpp +71 -0
  83. package/src/duckdb/src/function/table/system_functions.cpp +1 -0
  84. package/src/duckdb/src/function/table/table_scan.cpp +120 -36
  85. package/src/duckdb/src/function/table/version/pragma_version.cpp +4 -4
  86. package/src/duckdb/src/function/window/window_aggregate_function.cpp +6 -1
  87. package/src/duckdb/src/function/window/window_boundaries_state.cpp +135 -11
  88. package/src/duckdb/src/function/window/window_segment_tree.cpp +50 -22
  89. package/src/duckdb/src/function/window/window_token_tree.cpp +4 -3
  90. package/src/duckdb/src/include/duckdb/catalog/catalog.hpp +4 -0
  91. package/src/duckdb/src/include/duckdb/catalog/catalog_search_path.hpp +2 -0
  92. package/src/duckdb/src/include/duckdb/catalog/dependency_list.hpp +1 -0
  93. package/src/duckdb/src/include/duckdb/common/arrow/arrow_type_extension.hpp +4 -2
  94. package/src/duckdb/src/include/duckdb/common/enum_util.hpp +8 -8
  95. package/src/duckdb/src/include/duckdb/common/multi_file_reader.hpp +0 -2
  96. package/src/duckdb/src/include/duckdb/common/serializer/deserializer.hpp +8 -3
  97. package/src/duckdb/src/include/duckdb/common/serializer/memory_stream.hpp +6 -1
  98. package/src/duckdb/src/include/duckdb/common/serializer/serialization_data.hpp +25 -0
  99. package/src/duckdb/src/include/duckdb/common/serializer/serializer.hpp +9 -3
  100. package/src/duckdb/src/include/duckdb/common/types/selection_vector.hpp +1 -1
  101. package/src/duckdb/src/include/duckdb/execution/index/art/art.hpp +11 -14
  102. package/src/duckdb/src/include/duckdb/execution/index/art/prefix.hpp +5 -4
  103. package/src/duckdb/src/include/duckdb/execution/index/bound_index.hpp +21 -10
  104. package/src/duckdb/src/include/duckdb/execution/index/fixed_size_allocator.hpp +6 -5
  105. package/src/duckdb/src/include/duckdb/execution/index/fixed_size_buffer.hpp +37 -32
  106. package/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/base_scanner.hpp +36 -1
  107. package/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/column_count_scanner.hpp +3 -0
  108. package/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/sniffer/csv_sniffer.hpp +2 -0
  109. package/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/state_machine_options.hpp +5 -5
  110. package/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/string_value_scanner.hpp +5 -30
  111. package/src/duckdb/src/include/duckdb/execution/reservoir_sample.hpp +7 -1
  112. package/src/duckdb/src/include/duckdb/function/scalar_function.hpp +3 -3
  113. package/src/duckdb/src/include/duckdb/function/table/arrow/arrow_duck_schema.hpp +1 -0
  114. package/src/duckdb/src/include/duckdb/function/table/system_functions.hpp +4 -0
  115. package/src/duckdb/src/include/duckdb/function/window/window_boundaries_state.hpp +2 -2
  116. package/src/duckdb/src/include/duckdb/logging/logger.hpp +40 -119
  117. package/src/duckdb/src/include/duckdb/logging/logging.hpp +0 -2
  118. package/src/duckdb/src/include/duckdb/main/config.hpp +5 -0
  119. package/src/duckdb/src/include/duckdb/main/connection.hpp +0 -8
  120. package/src/duckdb/src/include/duckdb/main/connection_manager.hpp +2 -1
  121. package/src/duckdb/src/include/duckdb/main/extension.hpp +1 -0
  122. package/src/duckdb/src/include/duckdb/main/extension_entries.hpp +11 -7
  123. package/src/duckdb/src/include/duckdb/main/extension_helper.hpp +1 -0
  124. package/src/duckdb/src/include/duckdb/main/secret/secret.hpp +2 -0
  125. package/src/duckdb/src/include/duckdb/main/secret/secret_manager.hpp +3 -0
  126. package/src/duckdb/src/include/duckdb/main/settings.hpp +10 -0
  127. package/src/duckdb/src/include/duckdb/parser/constraint.hpp +9 -0
  128. package/src/duckdb/src/include/duckdb/parser/expression/window_expression.hpp +36 -9
  129. package/src/duckdb/src/include/duckdb/parser/parsed_data/create_view_info.hpp +2 -1
  130. package/src/duckdb/src/include/duckdb/parser/query_node/set_operation_node.hpp +8 -2
  131. package/src/duckdb/src/include/duckdb/planner/binder.hpp +4 -0
  132. package/src/duckdb/src/include/duckdb/planner/expression/bound_parameter_data.hpp +9 -1
  133. package/src/duckdb/src/include/duckdb/planner/filter/constant_filter.hpp +1 -0
  134. package/src/duckdb/src/include/duckdb/planner/filter/in_filter.hpp +0 -2
  135. package/src/duckdb/src/include/duckdb/planner/filter/optional_filter.hpp +4 -4
  136. package/src/duckdb/src/include/duckdb/planner/table_filter.hpp +1 -1
  137. package/src/duckdb/src/include/duckdb/storage/data_table.hpp +14 -10
  138. package/src/duckdb/src/include/duckdb/storage/index_storage_info.hpp +4 -0
  139. package/src/duckdb/src/include/duckdb/storage/single_file_block_manager.hpp +6 -1
  140. package/src/duckdb/src/include/duckdb/storage/storage_info.hpp +7 -2
  141. package/src/duckdb/src/include/duckdb/storage/storage_manager.hpp +9 -0
  142. package/src/duckdb/src/include/duckdb/storage/storage_options.hpp +2 -0
  143. package/src/duckdb/src/include/duckdb/storage/string_uncompressed.hpp +4 -3
  144. package/src/duckdb/src/include/duckdb/storage/table/column_data.hpp +2 -0
  145. package/src/duckdb/src/include/duckdb/storage/table/table_index_list.hpp +6 -4
  146. package/src/duckdb/src/include/duckdb/storage/table/table_statistics.hpp +1 -1
  147. package/src/duckdb/src/include/duckdb/storage/write_ahead_log.hpp +2 -0
  148. package/src/duckdb/src/include/duckdb/transaction/local_storage.hpp +2 -0
  149. package/src/duckdb/src/include/duckdb/transaction/meta_transaction.hpp +1 -1
  150. package/src/duckdb/src/logging/logger.cpp +8 -66
  151. package/src/duckdb/src/main/attached_database.cpp +3 -1
  152. package/src/duckdb/src/main/client_context.cpp +4 -2
  153. package/src/duckdb/src/main/config.cpp +20 -2
  154. package/src/duckdb/src/main/connection.cpp +2 -29
  155. package/src/duckdb/src/main/connection_manager.cpp +5 -3
  156. package/src/duckdb/src/main/database.cpp +2 -2
  157. package/src/duckdb/src/main/extension/extension_helper.cpp +4 -5
  158. package/src/duckdb/src/main/extension/extension_install.cpp +23 -10
  159. package/src/duckdb/src/main/extension/extension_load.cpp +6 -7
  160. package/src/duckdb/src/main/extension.cpp +27 -9
  161. package/src/duckdb/src/main/secret/secret_manager.cpp +11 -0
  162. package/src/duckdb/src/main/settings/custom_settings.cpp +44 -0
  163. package/src/duckdb/src/optimizer/column_lifetime_analyzer.cpp +6 -0
  164. package/src/duckdb/src/optimizer/filter_combiner.cpp +13 -3
  165. package/src/duckdb/src/optimizer/filter_pushdown.cpp +33 -6
  166. package/src/duckdb/src/optimizer/late_materialization.cpp +14 -3
  167. package/src/duckdb/src/optimizer/remove_unused_columns.cpp +0 -3
  168. package/src/duckdb/src/parser/parsed_data/attach_info.cpp +5 -1
  169. package/src/duckdb/src/parser/parsed_data/create_view_info.cpp +6 -3
  170. package/src/duckdb/src/parser/query_node/set_operation_node.cpp +49 -0
  171. package/src/duckdb/src/parser/transform/expression/transform_columnref.cpp +1 -0
  172. package/src/duckdb/src/parser/transform/expression/transform_function.cpp +50 -12
  173. package/src/duckdb/src/planner/binder/expression/bind_columnref_expression.cpp +7 -5
  174. package/src/duckdb/src/planner/binder/expression/bind_comparison_expression.cpp +1 -0
  175. package/src/duckdb/src/planner/binder/expression/bind_operator_expression.cpp +2 -2
  176. package/src/duckdb/src/planner/binder/expression/bind_star_expression.cpp +12 -2
  177. package/src/duckdb/src/planner/binder/statement/bind_copy_database.cpp +0 -1
  178. package/src/duckdb/src/planner/binder/statement/bind_create.cpp +55 -39
  179. package/src/duckdb/src/planner/binder/statement/bind_execute.cpp +2 -1
  180. package/src/duckdb/src/planner/binder/tableref/bind_basetableref.cpp +15 -7
  181. package/src/duckdb/src/planner/binder/tableref/bind_showref.cpp +13 -8
  182. package/src/duckdb/src/planner/binder/tableref/bind_table_function.cpp +8 -3
  183. package/src/duckdb/src/planner/expression/bound_function_expression.cpp +17 -1
  184. package/src/duckdb/src/planner/expression_binder/index_binder.cpp +1 -0
  185. package/src/duckdb/src/planner/filter/conjunction_filter.cpp +1 -0
  186. package/src/duckdb/src/planner/filter/constant_filter.cpp +21 -0
  187. package/src/duckdb/src/planner/filter/in_filter.cpp +4 -7
  188. package/src/duckdb/src/planner/logical_operator.cpp +5 -3
  189. package/src/duckdb/src/planner/planner.cpp +1 -1
  190. package/src/duckdb/src/planner/subquery/flatten_dependent_join.cpp +2 -0
  191. package/src/duckdb/src/storage/checkpoint/table_data_writer.cpp +3 -4
  192. package/src/duckdb/src/storage/checkpoint_manager.cpp +3 -5
  193. package/src/duckdb/src/storage/compression/dictionary/decompression.cpp +4 -4
  194. package/src/duckdb/src/storage/compression/fsst.cpp +2 -2
  195. package/src/duckdb/src/storage/compression/roaring/common.cpp +10 -1
  196. package/src/duckdb/src/storage/compression/string_uncompressed.cpp +11 -6
  197. package/src/duckdb/src/storage/compression/validity_uncompressed.cpp +4 -0
  198. package/src/duckdb/src/storage/compression/zstd.cpp +6 -0
  199. package/src/duckdb/src/storage/data_table.cpp +104 -109
  200. package/src/duckdb/src/storage/local_storage.cpp +8 -6
  201. package/src/duckdb/src/storage/magic_bytes.cpp +1 -1
  202. package/src/duckdb/src/storage/serialization/serialize_dependency.cpp +3 -3
  203. package/src/duckdb/src/storage/serialization/serialize_nodes.cpp +3 -3
  204. package/src/duckdb/src/storage/serialization/serialize_query_node.cpp +7 -5
  205. package/src/duckdb/src/storage/single_file_block_manager.cpp +95 -28
  206. package/src/duckdb/src/storage/storage_info.cpp +38 -0
  207. package/src/duckdb/src/storage/storage_manager.cpp +11 -0
  208. package/src/duckdb/src/storage/table/column_data.cpp +4 -0
  209. package/src/duckdb/src/storage/table/column_data_checkpointer.cpp +3 -3
  210. package/src/duckdb/src/storage/table/row_group_collection.cpp +67 -68
  211. package/src/duckdb/src/storage/table/table_statistics.cpp +4 -4
  212. package/src/duckdb/src/storage/table_index_list.cpp +41 -15
  213. package/src/duckdb/src/storage/wal_replay.cpp +3 -1
  214. package/src/duckdb/src/storage/write_ahead_log.cpp +11 -4
  215. package/src/duckdb/src/transaction/meta_transaction.cpp +1 -1
  216. package/src/duckdb/src/verification/deserialized_statement_verifier.cpp +2 -1
  217. package/src/duckdb/third_party/httplib/httplib.hpp +0 -1
  218. package/src/duckdb/third_party/re2/util/logging.h +10 -10
  219. package/src/duckdb/ub_src_function_table_system.cpp +2 -0
@@ -3,6 +3,7 @@
3
3
  #include "duckdb/optimizer/optimizer.hpp"
4
4
  #include "duckdb/planner/expression_iterator.hpp"
5
5
  #include "duckdb/planner/operator/logical_comparison_join.hpp"
6
+ #include "duckdb/planner/operator/logical_aggregate.hpp"
6
7
  #include "duckdb/planner/operator/logical_filter.hpp"
7
8
  #include "duckdb/planner/operator/logical_join.hpp"
8
9
  #include "duckdb/planner/operator/logical_projection.hpp"
@@ -20,7 +21,8 @@ void FilterPushdown::CheckMarkToSemi(LogicalOperator &op, unordered_set<idx_t> &
20
21
  if (join.join_type != JoinType::MARK) {
21
22
  break;
22
23
  }
23
- // if the projected table bindings include the mark join index,
24
+ // if an operator above the mark join includes the mark join index,
25
+ // then the mark join cannot be converted to a semi join
24
26
  if (table_bindings.find(join.mark_index) != table_bindings.end()) {
25
27
  join.convert_mark_to_semi = false;
26
28
  }
@@ -38,20 +40,45 @@ void FilterPushdown::CheckMarkToSemi(LogicalOperator &op, unordered_set<idx_t> &
38
40
  for (auto &binding : proj_bindings) {
39
41
  auto col_index = binding.column_index;
40
42
  auto &expr = proj.expressions.at(col_index);
41
- vector<ColumnBinding> bindings_to_keep;
42
43
  ExpressionIterator::EnumerateExpression(expr, [&](Expression &child) {
43
44
  if (child.GetExpressionClass() == ExpressionClass::BOUND_COLUMN_REF) {
44
45
  auto &col_ref = child.Cast<BoundColumnRefExpression>();
45
- bindings_to_keep.push_back(col_ref.binding);
46
+ new_table_bindings.insert(col_ref.binding.table_index);
46
47
  }
47
48
  });
48
- for (auto &expr_binding : bindings_to_keep) {
49
- new_table_bindings.insert(expr_binding.table_index);
50
- }
51
49
  table_bindings = new_table_bindings;
52
50
  }
53
51
  break;
54
52
  }
53
+ // It's possible a mark join index makes its way into a group by as the grouping index
54
+ // when that happens we need to keep track of it to make sure we do not convert a mark join to semi.
55
+ // see filter_pushdown_into_subquery.
56
+ case LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY: {
57
+ auto &aggr = op.Cast<LogicalAggregate>();
58
+ auto aggr_bindings = aggr.GetColumnBindings();
59
+ vector<ColumnBinding> bindings_to_keep;
60
+ for (auto &expr : aggr.groups) {
61
+ ExpressionIterator::EnumerateExpression(expr, [&](Expression &child) {
62
+ if (child.GetExpressionClass() == ExpressionClass::BOUND_COLUMN_REF) {
63
+ auto &col_ref = child.Cast<BoundColumnRefExpression>();
64
+ bindings_to_keep.push_back(col_ref.binding);
65
+ }
66
+ });
67
+ }
68
+ for (auto &expr : aggr.expressions) {
69
+ ExpressionIterator::EnumerateExpression(expr, [&](Expression &child) {
70
+ if (child.GetExpressionClass() == ExpressionClass::BOUND_COLUMN_REF) {
71
+ auto &col_ref = child.Cast<BoundColumnRefExpression>();
72
+ bindings_to_keep.push_back(col_ref.binding);
73
+ }
74
+ });
75
+ }
76
+ table_bindings = unordered_set<idx_t>();
77
+ for (auto &expr_binding : bindings_to_keep) {
78
+ table_bindings.insert(expr_binding.table_index);
79
+ }
80
+ break;
81
+ }
55
82
  default:
56
83
  break;
57
84
  }
@@ -1,5 +1,6 @@
1
1
  #include "duckdb/optimizer/late_materialization.hpp"
2
2
  #include "duckdb/planner/operator/logical_comparison_join.hpp"
3
+ #include "duckdb/planner/operator/logical_filter.hpp"
3
4
  #include "duckdb/planner/operator/logical_get.hpp"
4
5
  #include "duckdb/planner/operator/logical_limit.hpp"
5
6
  #include "duckdb/planner/operator/logical_order.hpp"
@@ -61,6 +62,8 @@ ColumnBinding LateMaterialization::ConstructRHS(unique_ptr<LogicalOperator> &op)
61
62
  // we have reached the logical get - now we need to push the row-id column (if it is not yet projected out)
62
63
  auto &get = child.get().Cast<LogicalGet>();
63
64
  auto row_id_idx = GetOrInsertRowId(get);
65
+ idx_t column_count = get.projection_ids.empty() ? get.GetColumnIds().size() : get.projection_ids.size();
66
+ D_ASSERT(column_count == get.GetColumnBindings().size());
64
67
 
65
68
  // the row id has been projected - now project it up the stack
66
69
  ColumnBinding row_id_binding(get.table_index, row_id_idx);
@@ -74,11 +77,18 @@ ColumnBinding LateMaterialization::ConstructRHS(unique_ptr<LogicalOperator> &op)
74
77
  make_uniq<BoundColumnRefExpression>("rowid", get.GetRowIdType(), row_id_binding));
75
78
  // modify the row-id-binding to push to the new projection
76
79
  row_id_binding = ColumnBinding(proj.table_index, proj.expressions.size() - 1);
80
+ column_count = proj.expressions.size();
77
81
  break;
78
82
  }
79
- case LogicalOperatorType::LOGICAL_FILTER:
80
- // column bindings pass-through this operator as-is
83
+ case LogicalOperatorType::LOGICAL_FILTER: {
84
+ auto &filter = op.Cast<LogicalFilter>();
85
+ // column bindings pass-through this operator as-is UNLESS the filter has a projection map
86
+ if (filter.HasProjectionMap()) {
87
+ // if the filter has a projection map, we need to project the new column
88
+ filter.projection_map.push_back(column_count - 1);
89
+ }
81
90
  break;
91
+ }
82
92
  default:
83
93
  throw InternalException("Unsupported logical operator in LateMaterialization::ConstructRHS");
84
94
  }
@@ -212,12 +222,13 @@ bool LateMaterialization::TryLateMaterialization(unique_ptr<LogicalOperator> &op
212
222
  child = *child.get().children[0];
213
223
  break;
214
224
  }
215
- case LogicalOperatorType::LOGICAL_FILTER:
225
+ case LogicalOperatorType::LOGICAL_FILTER: {
216
226
  // visit filter expressions - we need these columns
217
227
  VisitOperatorExpressions(child.get());
218
228
  // continue into child
219
229
  child = *child.get().children[0];
220
230
  break;
231
+ }
221
232
  default:
222
233
  // unsupported operator for late materialization
223
234
  return false;
@@ -261,9 +261,6 @@ void RemoveUnusedColumns::VisitOperator(LogicalOperator &op) {
261
261
  if (entry == column_references.end()) {
262
262
  throw InternalException("RemoveUnusedColumns - could not find referenced column");
263
263
  }
264
- if (final_column_ids[col_sel_idx].HasChildren()) {
265
- throw InternalException("RemoveUnusedColumns - LogicalGet::column_ids already has children");
266
- }
267
264
  ColumnIndex new_index(final_column_ids[col_sel_idx].GetPrimaryIndex(), entry->second.child_columns);
268
265
  column_ids.emplace_back(new_index);
269
266
  }
@@ -3,6 +3,7 @@
3
3
 
4
4
  #include "duckdb/storage/storage_info.hpp"
5
5
  #include "duckdb/common/optional_idx.hpp"
6
+ #include "duckdb/main/config.hpp"
6
7
 
7
8
  namespace duckdb {
8
9
 
@@ -15,6 +16,9 @@ StorageOptions AttachInfo::GetStorageOptions() const {
15
16
  storage_options.block_alloc_size = entry.second.GetValue<uint64_t>();
16
17
  } else if (entry.first == "row_group_size") {
17
18
  storage_options.row_group_size = entry.second.GetValue<uint64_t>();
19
+ } else if (entry.first == "storage_version") {
20
+ storage_options.storage_version =
21
+ SerializationCompatibility::FromString(entry.second.ToString()).serialization_version;
18
22
  }
19
23
  }
20
24
  return storage_options;
@@ -36,7 +40,7 @@ string AttachInfo::ToString() const {
36
40
  result += " IF NOT EXISTS";
37
41
  }
38
42
  result += " DATABASE";
39
- result += StringUtil::Format(" '%s'", path);
43
+ result += KeywordHelper::WriteQuoted(path, '\'');
40
44
  if (!name.empty()) {
41
45
  result += " AS " + KeywordHelper::WriteOptionallyQuoted(name);
42
46
  }
@@ -82,7 +82,8 @@ unique_ptr<CreateViewInfo> CreateViewInfo::FromSelect(ClientContext &context, un
82
82
  return info;
83
83
  }
84
84
 
85
- unique_ptr<CreateViewInfo> CreateViewInfo::FromCreateView(ClientContext &context, const string &sql) {
85
+ unique_ptr<CreateViewInfo> CreateViewInfo::FromCreateView(ClientContext &context, SchemaCatalogEntry &schema,
86
+ const string &sql) {
86
87
  D_ASSERT(!sql.empty());
87
88
 
88
89
  // parse the SQL statement
@@ -101,9 +102,11 @@ unique_ptr<CreateViewInfo> CreateViewInfo::FromCreateView(ClientContext &context
101
102
  }
102
103
 
103
104
  auto result = unique_ptr_cast<CreateInfo, CreateViewInfo>(std::move(create_statement.info));
105
+ result->catalog = schema.ParentCatalog().GetName();
106
+ result->schema = schema.name;
104
107
 
105
- auto binder = Binder::CreateBinder(context);
106
- binder->BindCreateViewInfo(*result);
108
+ auto view_binder = Binder::CreateBinder(context);
109
+ view_binder->BindCreateViewInfo(*result);
107
110
 
108
111
  return result;
109
112
  }
@@ -5,6 +5,9 @@
5
5
 
6
6
  namespace duckdb {
7
7
 
8
+ SetOperationNode::SetOperationNode() : QueryNode(QueryNodeType::SET_OPERATION_NODE) {
9
+ }
10
+
8
11
  string SetOperationNode::ToString() const {
9
12
  string result;
10
13
  result = cte_map.ToString();
@@ -63,4 +66,50 @@ unique_ptr<QueryNode> SetOperationNode::Copy() const {
63
66
  return std::move(result);
64
67
  }
65
68
 
69
+ SetOperationNode::SetOperationNode(SetOperationType setop_type, unique_ptr<QueryNode> left, unique_ptr<QueryNode> right,
70
+ vector<unique_ptr<QueryNode>> children, bool setop_all)
71
+ : QueryNode(QueryNodeType::SET_OPERATION_NODE), setop_type(setop_type), setop_all(setop_all) {
72
+ if (left && right) {
73
+ // simple case - left/right are supplied
74
+ this->left = std::move(left);
75
+ this->right = std::move(right);
76
+ return;
77
+ }
78
+ if (children.size() == 2) {
79
+ this->left = std::move(children[0]);
80
+ this->right = std::move(children[1]);
81
+ }
82
+ // we have multiple children - we need to construct a tree of set operation nodes
83
+ if (children.size() <= 1) {
84
+ throw SerializationException("Set Operation requires at least 2 children");
85
+ }
86
+ if (setop_type != SetOperationType::UNION) {
87
+ throw SerializationException("Multiple children in set-operations are only supported for UNION");
88
+ }
89
+ // construct a balanced tree from the union
90
+ while (children.size() > 2) {
91
+ vector<unique_ptr<QueryNode>> new_children;
92
+ for (idx_t i = 0; i < children.size(); i += 2) {
93
+ if (i + 1 == children.size()) {
94
+ new_children.push_back(std::move(children[i]));
95
+ } else {
96
+ vector<unique_ptr<QueryNode>> empty_children;
97
+ auto setop_node =
98
+ make_uniq<SetOperationNode>(setop_type, std::move(children[i]), std::move(children[i + 1]),
99
+ std::move(empty_children), setop_all);
100
+ new_children.push_back(std::move(setop_node));
101
+ }
102
+ }
103
+ children = std::move(new_children);
104
+ }
105
+ // two children left - fill in the left/right of this node
106
+ this->left = std::move(children[0]);
107
+ this->right = std::move(children[1]);
108
+ }
109
+
110
+ vector<unique_ptr<QueryNode>> SetOperationNode::SerializeChildNodes() const {
111
+ // we always serialize children as left/right currently
112
+ return vector<unique_ptr<QueryNode>>();
113
+ }
114
+
66
115
  } // namespace duckdb
@@ -96,6 +96,7 @@ unique_ptr<ParsedExpression> Transformer::TransformStarExpression(duckdb_libpgqu
96
96
  result->relation_name = child_star.relation_name;
97
97
  result->exclude_list = std::move(child_star.exclude_list);
98
98
  result->replace_list = std::move(child_star.replace_list);
99
+ result->rename_list = std::move(child_star.rename_list);
99
100
  result->expr.reset();
100
101
  } else if (result->expr->GetExpressionType() == ExpressionType::LAMBDA) {
101
102
  vector<unique_ptr<ParsedExpression>> children;
@@ -1,8 +1,6 @@
1
1
  #include "duckdb/common/enum_util.hpp"
2
2
  #include "duckdb/common/string_util.hpp"
3
- #include "duckdb/common/to_string.hpp"
4
3
  #include "duckdb/parser/expression/case_expression.hpp"
5
- #include "duckdb/parser/expression/cast_expression.hpp"
6
4
  #include "duckdb/parser/expression/constant_expression.hpp"
7
5
  #include "duckdb/parser/expression/function_expression.hpp"
8
6
 
@@ -35,6 +33,39 @@ void Transformer::TransformWindowDef(duckdb_libpgquery::PGWindowDef &window_spec
35
33
  }
36
34
  }
37
35
 
36
+ static inline WindowBoundary TransformFrameOption(const int frameOptions, const WindowBoundary rows,
37
+ const WindowBoundary range, const WindowBoundary groups) {
38
+
39
+ if (frameOptions & FRAMEOPTION_RANGE) {
40
+ return range;
41
+ } else if (frameOptions & FRAMEOPTION_GROUPS) {
42
+ return groups;
43
+ } else {
44
+ return rows;
45
+ }
46
+ }
47
+
48
+ static bool IsExcludableWindowFunction(ExpressionType type) {
49
+ switch (type) {
50
+ case ExpressionType::WINDOW_FIRST_VALUE:
51
+ case ExpressionType::WINDOW_LAST_VALUE:
52
+ case ExpressionType::WINDOW_NTH_VALUE:
53
+ case ExpressionType::WINDOW_AGGREGATE:
54
+ return true;
55
+ case ExpressionType::WINDOW_RANK_DENSE:
56
+ case ExpressionType::WINDOW_RANK:
57
+ case ExpressionType::WINDOW_PERCENT_RANK:
58
+ case ExpressionType::WINDOW_ROW_NUMBER:
59
+ case ExpressionType::WINDOW_NTILE:
60
+ case ExpressionType::WINDOW_CUME_DIST:
61
+ case ExpressionType::WINDOW_LEAD:
62
+ case ExpressionType::WINDOW_LAG:
63
+ return false;
64
+ default:
65
+ throw InternalException("Unknown excludable window type %s", ExpressionTypeToString(type).c_str());
66
+ }
67
+ }
68
+
38
69
  void Transformer::TransformWindowFrame(duckdb_libpgquery::PGWindowDef &window_spec, WindowExpression &expr) {
39
70
  // finally: specifics of bounds
40
71
  expr.start_expr = TransformExpression(window_spec.startOffset);
@@ -46,28 +77,30 @@ void Transformer::TransformWindowFrame(duckdb_libpgquery::PGWindowDef &window_sp
46
77
  "Window frames starting with unbounded following or ending in unbounded preceding make no sense");
47
78
  }
48
79
 
49
- if (window_spec.frameOptions & FRAMEOPTION_GROUPS) {
50
- throw ParserException("GROUPS mode for window functions is not implemented yet");
51
- }
52
- const bool rangeMode = (window_spec.frameOptions & FRAMEOPTION_RANGE) != 0;
53
80
  if (window_spec.frameOptions & FRAMEOPTION_START_UNBOUNDED_PRECEDING) {
54
81
  expr.start = WindowBoundary::UNBOUNDED_PRECEDING;
55
82
  } else if (window_spec.frameOptions & FRAMEOPTION_START_OFFSET_PRECEDING) {
56
- expr.start = rangeMode ? WindowBoundary::EXPR_PRECEDING_RANGE : WindowBoundary::EXPR_PRECEDING_ROWS;
83
+ expr.start = TransformFrameOption(window_spec.frameOptions, WindowBoundary::EXPR_PRECEDING_ROWS,
84
+ WindowBoundary::EXPR_PRECEDING_RANGE, WindowBoundary::EXPR_PRECEDING_GROUPS);
57
85
  } else if (window_spec.frameOptions & FRAMEOPTION_START_OFFSET_FOLLOWING) {
58
- expr.start = rangeMode ? WindowBoundary::EXPR_FOLLOWING_RANGE : WindowBoundary::EXPR_FOLLOWING_ROWS;
86
+ expr.start = TransformFrameOption(window_spec.frameOptions, WindowBoundary::EXPR_FOLLOWING_ROWS,
87
+ WindowBoundary::EXPR_FOLLOWING_RANGE, WindowBoundary::EXPR_FOLLOWING_GROUPS);
59
88
  } else if (window_spec.frameOptions & FRAMEOPTION_START_CURRENT_ROW) {
60
- expr.start = rangeMode ? WindowBoundary::CURRENT_ROW_RANGE : WindowBoundary::CURRENT_ROW_ROWS;
89
+ expr.start = TransformFrameOption(window_spec.frameOptions, WindowBoundary::CURRENT_ROW_ROWS,
90
+ WindowBoundary::CURRENT_ROW_RANGE, WindowBoundary::CURRENT_ROW_GROUPS);
61
91
  }
62
92
 
63
93
  if (window_spec.frameOptions & FRAMEOPTION_END_UNBOUNDED_FOLLOWING) {
64
94
  expr.end = WindowBoundary::UNBOUNDED_FOLLOWING;
65
95
  } else if (window_spec.frameOptions & FRAMEOPTION_END_OFFSET_PRECEDING) {
66
- expr.end = rangeMode ? WindowBoundary::EXPR_PRECEDING_RANGE : WindowBoundary::EXPR_PRECEDING_ROWS;
96
+ expr.end = TransformFrameOption(window_spec.frameOptions, WindowBoundary::EXPR_PRECEDING_ROWS,
97
+ WindowBoundary::EXPR_PRECEDING_RANGE, WindowBoundary::EXPR_PRECEDING_GROUPS);
67
98
  } else if (window_spec.frameOptions & FRAMEOPTION_END_OFFSET_FOLLOWING) {
68
- expr.end = rangeMode ? WindowBoundary::EXPR_FOLLOWING_RANGE : WindowBoundary::EXPR_FOLLOWING_ROWS;
99
+ expr.end = TransformFrameOption(window_spec.frameOptions, WindowBoundary::EXPR_FOLLOWING_ROWS,
100
+ WindowBoundary::EXPR_FOLLOWING_RANGE, WindowBoundary::EXPR_FOLLOWING_GROUPS);
69
101
  } else if (window_spec.frameOptions & FRAMEOPTION_END_CURRENT_ROW) {
70
- expr.end = rangeMode ? WindowBoundary::CURRENT_ROW_RANGE : WindowBoundary::CURRENT_ROW_ROWS;
102
+ expr.end = TransformFrameOption(window_spec.frameOptions, WindowBoundary::CURRENT_ROW_ROWS,
103
+ WindowBoundary::CURRENT_ROW_RANGE, WindowBoundary::CURRENT_ROW_GROUPS);
71
104
  }
72
105
 
73
106
  D_ASSERT(expr.start != WindowBoundary::INVALID && expr.end != WindowBoundary::INVALID);
@@ -87,6 +120,11 @@ void Transformer::TransformWindowFrame(duckdb_libpgquery::PGWindowDef &window_sp
87
120
  } else {
88
121
  expr.exclude_clause = WindowExcludeMode::NO_OTHER;
89
122
  }
123
+
124
+ if (expr.exclude_clause != WindowExcludeMode::NO_OTHER && !expr.arg_orders.empty() &&
125
+ !IsExcludableWindowFunction(expr.type)) {
126
+ throw ParserException("EXCLUDE is not supported for the window function \"%s\"", expr.function_name.c_str());
127
+ }
90
128
  }
91
129
 
92
130
  bool Transformer::ExpressionIsEmptyStar(ParsedExpression &expr) {
@@ -436,11 +436,13 @@ BindResult ExpressionBinder::BindExpression(ColumnRefExpression &col_ref_p, idx_
436
436
  if (found_alias) {
437
437
  return alias_result;
438
438
  }
439
-
440
- // column was not found - check if it is a SQL value function
441
- auto value_function = GetSQLValueFunction(col_ref_p.GetColumnName());
442
- if (value_function) {
443
- return BindExpression(value_function, depth);
439
+ found_alias = QualifyColumnAlias(col_ref_p);
440
+ if (!found_alias) {
441
+ // column was not found - check if it is a SQL value function
442
+ auto value_function = GetSQLValueFunction(col_ref_p.GetColumnName());
443
+ if (value_function) {
444
+ return BindExpression(value_function, depth);
445
+ }
444
446
  }
445
447
  }
446
448
  error.AddQueryLocation(col_ref_p);
@@ -28,6 +28,7 @@ void ExpressionBinder::TestCollation(ClientContext &context, const string &colla
28
28
 
29
29
  static bool SwitchVarcharComparison(const LogicalType &type) {
30
30
  switch (type.id()) {
31
+ case LogicalTypeId::BOOLEAN:
31
32
  case LogicalTypeId::TINYINT:
32
33
  case LogicalTypeId::SMALLINT:
33
34
  case LogicalTypeId::INTEGER:
@@ -109,7 +109,7 @@ BindResult ExpressionBinder::BindExpression(OperatorExpression &op, idx_t depth)
109
109
  auto &b_exp = BoundExpression::GetExpression(*op.children[0]);
110
110
  const auto &b_exp_type = b_exp->return_type;
111
111
  if (b_exp_type.id() == LogicalTypeId::MAP) {
112
- function_name = "map_extract";
112
+ function_name = "map_extract_value";
113
113
  } else if (b_exp_type.IsJSONType() && op.children.size() == 2) {
114
114
  function_name = "json_extract";
115
115
  // Make sure we only extract array elements, not fields, by adding the $[] syntax
@@ -149,7 +149,7 @@ BindResult ExpressionBinder::BindExpression(OperatorExpression &op, idx_t depth)
149
149
  if (extract_expr_type.id() == LogicalTypeId::UNION) {
150
150
  function_name = "union_extract";
151
151
  } else if (extract_expr_type.id() == LogicalTypeId::MAP) {
152
- function_name = "map_extract";
152
+ function_name = "map_extract_value";
153
153
  } else if (extract_expr_type.IsJSONType()) {
154
154
  function_name = "json_extract";
155
155
  // Make sure we only extract fields, not array elements, by adding $. syntax
@@ -145,7 +145,7 @@ void TryTransformStarLike(unique_ptr<ParsedExpression> &root) {
145
145
  return;
146
146
  }
147
147
  auto &function = root->Cast<FunctionExpression>();
148
- if (function.children.size() != 2) {
148
+ if (function.children.size() < 2 || function.children.size() > 3) {
149
149
  return;
150
150
  }
151
151
  auto &left = function.children[0];
@@ -158,7 +158,17 @@ void TryTransformStarLike(unique_ptr<ParsedExpression> &root) {
158
158
  // COLUMNS(*) has different semantics
159
159
  return;
160
160
  }
161
- unordered_set<string> supported_ops {"~~", "!~~", "~~~", "!~~~", "~~*", "!~~*", "regexp_full_match"};
161
+ unordered_set<string> supported_ops {"~~",
162
+ "!~~",
163
+ "~~~",
164
+ "!~~~",
165
+ "~~*",
166
+ "!~~*",
167
+ "regexp_full_match",
168
+ "not_like_escape",
169
+ "ilike_escape",
170
+ "not_ilike_escape",
171
+ "like_escape"};
162
172
  if (supported_ops.count(function.function_name) == 0) {
163
173
  // unsupported op for * expression
164
174
  throw BinderException(*root, "Function \"%s\" cannot be applied to a star expression", function.function_name);
@@ -43,7 +43,6 @@ unique_ptr<LogicalOperator> Binder::BindCopyDatabaseSchema(Catalog &from_databas
43
43
  info->entries.push_back(std::move(create_info));
44
44
  }
45
45
 
46
- // FIXME: copy indexes
47
46
  return make_uniq<LogicalCopyDatabase>(std::move(info));
48
47
  }
49
48
 
@@ -41,6 +41,7 @@
41
41
  #include "duckdb/planner/tableref/bound_basetableref.hpp"
42
42
  #include "duckdb/storage/storage_extension.hpp"
43
43
  #include "duckdb/common/extension_type_info.hpp"
44
+ #include "duckdb/common/type_visitor.hpp"
44
45
 
45
46
  namespace duckdb {
46
47
 
@@ -97,7 +98,7 @@ SchemaCatalogEntry &Binder::BindSchema(CreateInfo &info) {
97
98
  info.catalog = default_entry.catalog;
98
99
  info.schema = default_entry.schema;
99
100
  } else if (IsInvalidSchema(info.schema)) {
100
- info.schema = search_path->GetDefaultSchema(info.catalog);
101
+ info.schema = search_path->GetDefaultSchema(context, info.catalog);
101
102
  } else if (IsInvalidCatalog(info.catalog)) {
102
103
  info.catalog = search_path->GetDefaultCatalog(info.schema);
103
104
  }
@@ -157,6 +158,9 @@ void Binder::BindCreateViewInfo(CreateViewInfo &base) {
157
158
  }
158
159
  view_binder->can_contain_nulls = true;
159
160
 
161
+ auto view_search_path = GetSearchPath(catalog, base.schema);
162
+ view_binder->entry_retriever.SetSearchPath(std::move(view_search_path));
163
+
160
164
  auto copy = base.query->Copy();
161
165
  auto query_node = view_binder->Bind(*base.query);
162
166
  base.query = unique_ptr_cast<SQLStatement, SelectStatement>(std::move(copy));
@@ -253,54 +257,56 @@ static bool IsValidUserType(optional_ptr<CatalogEntry> entry) {
253
257
  return entry->Cast<TypeCatalogEntry>().user_type.id() != LogicalTypeId::INVALID;
254
258
  }
255
259
 
256
- void Binder::BindLogicalType(LogicalType &type, optional_ptr<Catalog> catalog, const string &schema) {
260
+ LogicalType Binder::BindLogicalTypeInternal(const LogicalType &type, optional_ptr<Catalog> catalog,
261
+ const string &schema) {
257
262
  if (type.id() != LogicalTypeId::USER) {
258
- // Recursive types, make sure to bind any nested user types recursively
259
- auto alias = type.GetAlias();
260
- auto ext_info = type.HasExtensionInfo() ? make_uniq<ExtensionTypeInfo>(*type.GetExtensionInfo()) : nullptr;
261
-
263
+ // Nested type, make sure to bind any nested user types recursively
264
+ LogicalType result;
262
265
  switch (type.id()) {
263
266
  case LogicalTypeId::LIST: {
264
- auto child_type = ListType::GetChildType(type);
265
- BindLogicalType(child_type, catalog, schema);
266
- type = LogicalType::LIST(child_type);
267
- } break;
267
+ auto child_type = BindLogicalTypeInternal(ListType::GetChildType(type), catalog, schema);
268
+ result = LogicalType::LIST(child_type);
269
+ break;
270
+ }
268
271
  case LogicalTypeId::MAP: {
269
- auto key_type = MapType::KeyType(type);
270
- BindLogicalType(key_type, catalog, schema);
271
- auto value_type = MapType::ValueType(type);
272
- BindLogicalType(value_type, catalog, schema);
273
- type = LogicalType::MAP(key_type, value_type);
274
- } break;
272
+ auto key_type = BindLogicalTypeInternal(MapType::KeyType(type), catalog, schema);
273
+ auto value_type = BindLogicalTypeInternal(MapType::ValueType(type), catalog, schema);
274
+ result = LogicalType::MAP(std::move(key_type), std::move(value_type));
275
+ break;
276
+ }
275
277
  case LogicalTypeId::ARRAY: {
276
- auto child_type = ArrayType::GetChildType(type);
278
+ auto child_type = BindLogicalTypeInternal(ArrayType::GetChildType(type), catalog, schema);
277
279
  auto array_size = ArrayType::GetSize(type);
278
- BindLogicalType(child_type, catalog, schema);
279
- type = LogicalType::ARRAY(child_type, array_size);
280
- } break;
280
+ result = LogicalType::ARRAY(child_type, array_size);
281
+ break;
282
+ }
281
283
  case LogicalTypeId::STRUCT: {
282
284
  auto child_types = StructType::GetChildTypes(type);
283
- for (auto &child_type : child_types) {
284
- BindLogicalType(child_type.second, catalog, schema);
285
+ child_list_t<LogicalType> new_child_types;
286
+ for (auto &entry : child_types) {
287
+ new_child_types.emplace_back(entry.first, BindLogicalTypeInternal(entry.second, catalog, schema));
285
288
  }
286
- type = LogicalType::STRUCT(child_types);
287
- } break;
289
+ result = LogicalType::STRUCT(std::move(new_child_types));
290
+ break;
291
+ }
288
292
  case LogicalTypeId::UNION: {
289
- auto member_types = UnionType::CopyMemberTypes(type);
290
- for (auto &member_type : member_types) {
291
- BindLogicalType(member_type.second, catalog, schema);
293
+ child_list_t<LogicalType> member_types;
294
+ for (idx_t i = 0; i < UnionType::GetMemberCount(type); i++) {
295
+ auto child_type = BindLogicalTypeInternal(UnionType::GetMemberType(type, i), catalog, schema);
296
+ member_types.emplace_back(UnionType::GetMemberName(type, i), std::move(child_type));
292
297
  }
293
- type = LogicalType::UNION(member_types);
294
- } break;
295
- default:
298
+ result = LogicalType::UNION(std::move(member_types));
296
299
  break;
297
300
  }
301
+ default:
302
+ return type;
303
+ }
298
304
 
299
305
  // Set the alias and extension info back
300
- type.SetAlias(alias);
301
- type.SetExtensionInfo(std::move(ext_info));
302
-
303
- return;
306
+ result.SetAlias(type.GetAlias());
307
+ auto ext_info = type.HasExtensionInfo() ? make_uniq<ExtensionTypeInfo>(*type.GetExtensionInfo()) : nullptr;
308
+ result.SetExtensionInfo(std::move(ext_info));
309
+ return result;
304
310
  }
305
311
 
306
312
  // User type, bind the user type
@@ -310,6 +316,7 @@ void Binder::BindLogicalType(LogicalType &type, optional_ptr<Catalog> catalog, c
310
316
 
311
317
  bind_logical_type_function_t user_bind_modifiers_func = nullptr;
312
318
 
319
+ LogicalType result;
313
320
  if (catalog) {
314
321
  // The search order is:
315
322
  // 1) In the explicitly set schema (my_schema.my_type)
@@ -335,7 +342,7 @@ void Binder::BindLogicalType(LogicalType &type, optional_ptr<Catalog> catalog, c
335
342
  OnEntryNotFound::THROW_EXCEPTION);
336
343
  }
337
344
  auto &type_entry = entry->Cast<TypeCatalogEntry>();
338
- type = type_entry.user_type;
345
+ result = type_entry.user_type;
339
346
  user_bind_modifiers_func = type_entry.bind_function;
340
347
  } else {
341
348
  string type_catalog = UserType::GetCatalog(type);
@@ -344,24 +351,33 @@ void Binder::BindLogicalType(LogicalType &type, optional_ptr<Catalog> catalog, c
344
351
  BindSchemaOrCatalog(context, type_catalog, type_schema);
345
352
  auto entry = entry_retriever.GetEntry(CatalogType::TYPE_ENTRY, type_catalog, type_schema, user_type_name);
346
353
  auto &type_entry = entry->Cast<TypeCatalogEntry>();
347
- type = type_entry.user_type;
354
+ result = type_entry.user_type;
348
355
  user_bind_modifiers_func = type_entry.bind_function;
349
356
  }
350
357
 
351
358
  // Now we bind the inner user type
352
- BindLogicalType(type, catalog, schema);
359
+ BindLogicalType(result, catalog, schema);
353
360
 
354
361
  // Apply the type modifiers (if any)
355
362
  if (user_bind_modifiers_func) {
356
363
  // If an explicit bind_modifiers function was provided, use that to construct the type
357
364
 
358
- BindLogicalTypeInput input {context, type, user_type_mods};
359
- type = user_bind_modifiers_func(input);
365
+ BindLogicalTypeInput input {context, result, user_type_mods};
366
+ result = user_bind_modifiers_func(input);
360
367
  } else {
361
368
  if (!user_type_mods.empty()) {
362
369
  throw BinderException("Type '%s' does not take any type modifiers", user_type_name);
363
370
  }
364
371
  }
372
+ return result;
373
+ }
374
+
375
+ void Binder::BindLogicalType(LogicalType &type, optional_ptr<Catalog> catalog, const string &schema) {
376
+ // check if we need to bind this type at all
377
+ if (!TypeVisitor::Contains(type, LogicalTypeId::USER)) {
378
+ return;
379
+ }
380
+ type = BindLogicalTypeInternal(type, catalog, schema);
365
381
  }
366
382
 
367
383
  unique_ptr<LogicalOperator> DuckCatalog::BindCreateIndex(Binder &binder, CreateStatement &stmt,
@@ -54,7 +54,8 @@ BoundStatement Binder::Bind(ExecuteStatement &stmt) {
54
54
  parameter_data = BoundParameterData(std::move(constant.value), std::move(return_type));
55
55
  } else {
56
56
  auto value = ExpressionExecutor::EvaluateScalar(context, *bound_expr, true);
57
- parameter_data = BoundParameterData(std::move(value));
57
+ auto value_type = value.type();
58
+ parameter_data = BoundParameterData(std::move(value), std::move(value_type));
58
59
  }
59
60
  bind_values[pair.first] = std::move(parameter_data);
60
61
  }
@@ -79,6 +79,19 @@ unique_ptr<BoundTableRef> Binder::BindWithReplacementScan(ClientContext &context
79
79
  return nullptr;
80
80
  }
81
81
 
82
+ vector<CatalogSearchEntry> Binder::GetSearchPath(Catalog &catalog, const string &schema_name) {
83
+ vector<CatalogSearchEntry> view_search_path;
84
+ auto &catalog_name = catalog.GetName();
85
+ if (!schema_name.empty()) {
86
+ view_search_path.emplace_back(catalog_name, schema_name);
87
+ }
88
+ auto default_schema = catalog.GetDefaultSchema();
89
+ if (schema_name.empty() && schema_name != default_schema) {
90
+ view_search_path.emplace_back(catalog.GetName(), default_schema);
91
+ }
92
+ return view_search_path;
93
+ }
94
+
82
95
  unique_ptr<BoundTableRef> Binder::Bind(BaseTableRef &ref) {
83
96
  QueryErrorContext error_context(ref.query_location);
84
97
  // CTEs and views are also referred to using BaseTableRefs, hence need to distinguish here
@@ -278,13 +291,8 @@ unique_ptr<BoundTableRef> Binder::Bind(BaseTableRef &ref) {
278
291
  subquery.column_name_alias = BindContext::AliasColumnNames(ref.table_name, view_names, ref.column_name_alias);
279
292
 
280
293
  // when binding a view, we always look into the catalog/schema where the view is stored first
281
- vector<CatalogSearchEntry> view_search_path;
282
- auto &catalog_name = view_catalog_entry.ParentCatalog().GetName();
283
- auto &schema_name = view_catalog_entry.ParentSchema().name;
284
- view_search_path.emplace_back(catalog_name, schema_name);
285
- if (schema_name != DEFAULT_SCHEMA) {
286
- view_search_path.emplace_back(view_catalog_entry.ParentCatalog().GetName(), DEFAULT_SCHEMA);
287
- }
294
+ auto view_search_path =
295
+ GetSearchPath(view_catalog_entry.ParentCatalog(), view_catalog_entry.ParentSchema().name);
288
296
  view_binder->entry_retriever.SetSearchPath(std::move(view_search_path));
289
297
  // bind the child subquery
290
298
  view_binder->AddBoundView(view_catalog_entry);