duckdb 0.7.2-dev16.0 → 0.7.2-dev314.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 (242) hide show
  1. package/binding.gyp +2 -0
  2. package/package.json +1 -1
  3. package/src/duckdb/extension/icu/icu-extension.cpp +2 -0
  4. package/src/duckdb/extension/icu/icu-table-range.cpp +194 -0
  5. package/src/duckdb/extension/icu/include/icu-table-range.hpp +17 -0
  6. package/src/duckdb/extension/parquet/column_reader.cpp +5 -6
  7. package/src/duckdb/extension/parquet/column_writer.cpp +0 -1
  8. package/src/duckdb/extension/parquet/include/column_reader.hpp +1 -2
  9. package/src/duckdb/extension/parquet/include/generated_column_reader.hpp +1 -11
  10. package/src/duckdb/extension/parquet/parquet-extension.cpp +11 -2
  11. package/src/duckdb/extension/parquet/parquet_statistics.cpp +26 -32
  12. package/src/duckdb/src/catalog/catalog_entry/duck_schema_entry.cpp +4 -0
  13. package/src/duckdb/src/catalog/catalog_entry/scalar_function_catalog_entry.cpp +7 -6
  14. package/src/duckdb/src/catalog/catalog_entry/table_function_catalog_entry.cpp +20 -1
  15. package/src/duckdb/src/common/enums/statement_type.cpp +2 -0
  16. package/src/duckdb/src/common/sort/sort_state.cpp +5 -7
  17. package/src/duckdb/src/common/types/bit.cpp +95 -58
  18. package/src/duckdb/src/common/types/value.cpp +149 -53
  19. package/src/duckdb/src/common/types/vector.cpp +13 -10
  20. package/src/duckdb/src/execution/column_binding_resolver.cpp +6 -0
  21. package/src/duckdb/src/execution/operator/aggregate/physical_perfecthash_aggregate.cpp +4 -5
  22. package/src/duckdb/src/execution/operator/aggregate/physical_window.cpp +1 -1
  23. package/src/duckdb/src/execution/operator/helper/physical_vacuum.cpp +2 -3
  24. package/src/duckdb/src/execution/operator/join/physical_blockwise_nl_join.cpp +32 -6
  25. package/src/duckdb/src/execution/operator/persistent/buffered_csv_reader.cpp +1 -1
  26. package/src/duckdb/src/execution/physical_plan/plan_aggregate.cpp +15 -15
  27. package/src/duckdb/src/execution/physical_plan/plan_comparison_join.cpp +18 -12
  28. package/src/duckdb/src/function/aggregate/algebraic/avg.cpp +0 -6
  29. package/src/duckdb/src/function/aggregate/distributive/bitagg.cpp +99 -95
  30. package/src/duckdb/src/function/aggregate/distributive/bitstring_agg.cpp +254 -0
  31. package/src/duckdb/src/function/aggregate/distributive/count.cpp +2 -4
  32. package/src/duckdb/src/function/aggregate/distributive/sum.cpp +11 -16
  33. package/src/duckdb/src/function/aggregate/distributive_functions.cpp +1 -0
  34. package/src/duckdb/src/function/aggregate/sorted_aggregate_function.cpp +16 -5
  35. package/src/duckdb/src/function/cast/bit_cast.cpp +0 -2
  36. package/src/duckdb/src/function/cast/blob_cast.cpp +0 -1
  37. package/src/duckdb/src/function/scalar/bit/bitstring.cpp +99 -0
  38. package/src/duckdb/src/function/scalar/date/date_diff.cpp +0 -1
  39. package/src/duckdb/src/function/scalar/date/date_part.cpp +17 -25
  40. package/src/duckdb/src/function/scalar/date/date_sub.cpp +0 -1
  41. package/src/duckdb/src/function/scalar/date/date_trunc.cpp +10 -14
  42. package/src/duckdb/src/function/scalar/generic/stats.cpp +2 -4
  43. package/src/duckdb/src/function/scalar/list/flatten.cpp +5 -12
  44. package/src/duckdb/src/function/scalar/list/list_concat.cpp +3 -8
  45. package/src/duckdb/src/function/scalar/list/list_extract.cpp +5 -12
  46. package/src/duckdb/src/function/scalar/list/list_value.cpp +5 -9
  47. package/src/duckdb/src/function/scalar/map/map_entries.cpp +61 -0
  48. package/src/duckdb/src/function/scalar/map/map_keys_values.cpp +97 -0
  49. package/src/duckdb/src/function/scalar/math/numeric.cpp +14 -17
  50. package/src/duckdb/src/function/scalar/nested_functions.cpp +3 -0
  51. package/src/duckdb/src/function/scalar/operators/add.cpp +0 -9
  52. package/src/duckdb/src/function/scalar/operators/arithmetic.cpp +29 -48
  53. package/src/duckdb/src/function/scalar/operators/bitwise.cpp +0 -63
  54. package/src/duckdb/src/function/scalar/operators/multiply.cpp +0 -6
  55. package/src/duckdb/src/function/scalar/operators/subtract.cpp +0 -6
  56. package/src/duckdb/src/function/scalar/string/caseconvert.cpp +2 -6
  57. package/src/duckdb/src/function/scalar/string/instr.cpp +2 -6
  58. package/src/duckdb/src/function/scalar/string/length.cpp +2 -6
  59. package/src/duckdb/src/function/scalar/string/like.cpp +2 -6
  60. package/src/duckdb/src/function/scalar/string/substring.cpp +2 -6
  61. package/src/duckdb/src/function/scalar/string_functions.cpp +1 -0
  62. package/src/duckdb/src/function/scalar/struct/struct_extract.cpp +4 -9
  63. package/src/duckdb/src/function/scalar/struct/struct_insert.cpp +10 -13
  64. package/src/duckdb/src/function/scalar/struct/struct_pack.cpp +5 -6
  65. package/src/duckdb/src/function/table/read_csv.cpp +9 -0
  66. package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
  67. package/src/duckdb/src/function/table_function.cpp +19 -0
  68. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/table_function_catalog_entry.hpp +6 -8
  69. package/src/duckdb/src/include/duckdb/common/constants.hpp +0 -19
  70. package/src/duckdb/src/include/duckdb/common/enums/statement_type.hpp +2 -1
  71. package/src/duckdb/src/include/duckdb/common/enums/tableref_type.hpp +2 -1
  72. package/src/duckdb/src/include/duckdb/common/types/bit.hpp +5 -1
  73. package/src/duckdb/src/include/duckdb/common/types/value.hpp +2 -8
  74. package/src/duckdb/src/include/duckdb/common/types.hpp +1 -2
  75. package/src/duckdb/src/include/duckdb/execution/operator/aggregate/physical_perfecthash_aggregate.hpp +1 -1
  76. package/src/duckdb/src/include/duckdb/function/aggregate/distributive_functions.hpp +5 -0
  77. package/src/duckdb/src/include/duckdb/function/aggregate_function.hpp +12 -3
  78. package/src/duckdb/src/include/duckdb/function/scalar/bit_functions.hpp +4 -0
  79. package/src/duckdb/src/include/duckdb/function/scalar/nested_functions.hpp +12 -0
  80. package/src/duckdb/src/include/duckdb/function/scalar_function.hpp +2 -2
  81. package/src/duckdb/src/include/duckdb/function/table_function.hpp +2 -0
  82. package/src/duckdb/src/include/duckdb/main/capi/capi_internal.hpp +2 -0
  83. package/src/duckdb/src/include/duckdb/main/config.hpp +3 -0
  84. package/src/duckdb/src/include/duckdb/main/database.hpp +1 -0
  85. package/src/duckdb/src/include/duckdb/optimizer/join_order/cardinality_estimator.hpp +2 -2
  86. package/src/duckdb/src/include/duckdb/parser/common_table_expression_info.hpp +2 -0
  87. package/src/duckdb/src/include/duckdb/parser/parsed_data/alter_info.hpp +2 -1
  88. package/src/duckdb/src/include/duckdb/parser/parsed_data/{alter_function_info.hpp → alter_scalar_function_info.hpp} +13 -13
  89. package/src/duckdb/src/include/duckdb/parser/parsed_data/alter_table_function_info.hpp +47 -0
  90. package/src/duckdb/src/include/duckdb/parser/parsed_data/create_table_function_info.hpp +2 -1
  91. package/src/duckdb/src/include/duckdb/parser/query_node.hpp +2 -1
  92. package/src/duckdb/src/include/duckdb/parser/statement/multi_statement.hpp +28 -0
  93. package/src/duckdb/src/include/duckdb/parser/tableref/list.hpp +1 -0
  94. package/src/duckdb/src/include/duckdb/parser/tableref/pivotref.hpp +76 -0
  95. package/src/duckdb/src/include/duckdb/parser/tokens.hpp +2 -0
  96. package/src/duckdb/src/include/duckdb/parser/transformer.hpp +28 -0
  97. package/src/duckdb/src/include/duckdb/planner/bind_context.hpp +2 -0
  98. package/src/duckdb/src/include/duckdb/planner/binder.hpp +8 -0
  99. package/src/duckdb/src/include/duckdb/storage/buffer/block_handle.hpp +2 -0
  100. package/src/duckdb/src/include/duckdb/storage/buffer_manager.hpp +76 -44
  101. package/src/duckdb/src/include/duckdb/storage/checkpoint/table_data_writer.hpp +3 -2
  102. package/src/duckdb/src/include/duckdb/storage/compression/chimp/chimp_compress.hpp +2 -2
  103. package/src/duckdb/src/include/duckdb/storage/compression/chimp/chimp_fetch.hpp +1 -1
  104. package/src/duckdb/src/include/duckdb/storage/compression/chimp/chimp_scan.hpp +1 -1
  105. package/src/duckdb/src/include/duckdb/storage/compression/patas/patas_compress.hpp +2 -2
  106. package/src/duckdb/src/include/duckdb/storage/compression/patas/patas_fetch.hpp +1 -1
  107. package/src/duckdb/src/include/duckdb/storage/compression/patas/patas_scan.hpp +1 -1
  108. package/src/duckdb/src/include/duckdb/storage/data_pointer.hpp +5 -2
  109. package/src/duckdb/src/include/duckdb/storage/data_table.hpp +1 -1
  110. package/src/duckdb/src/include/duckdb/storage/statistics/base_statistics.hpp +93 -29
  111. package/src/duckdb/src/include/duckdb/storage/statistics/column_statistics.hpp +22 -3
  112. package/src/duckdb/src/include/duckdb/storage/statistics/distinct_statistics.hpp +6 -6
  113. package/src/duckdb/src/include/duckdb/storage/statistics/list_stats.hpp +41 -0
  114. package/src/duckdb/src/include/duckdb/storage/statistics/node_statistics.hpp +26 -0
  115. package/src/duckdb/src/include/duckdb/storage/statistics/numeric_stats.hpp +157 -0
  116. package/src/duckdb/src/include/duckdb/storage/statistics/segment_statistics.hpp +2 -7
  117. package/src/duckdb/src/include/duckdb/storage/statistics/string_stats.hpp +74 -0
  118. package/src/duckdb/src/include/duckdb/storage/statistics/struct_stats.hpp +42 -0
  119. package/src/duckdb/src/include/duckdb/storage/string_uncompressed.hpp +2 -3
  120. package/src/duckdb/src/include/duckdb/storage/table/column_segment.hpp +2 -2
  121. package/src/duckdb/src/include/duckdb/storage/table/list_column_data.hpp +1 -1
  122. package/src/duckdb/src/include/duckdb/storage/table/persistent_table_data.hpp +2 -1
  123. package/src/duckdb/src/include/duckdb/storage/table/row_group.hpp +4 -3
  124. package/src/duckdb/src/include/duckdb/storage/table/row_group_collection.hpp +3 -2
  125. package/src/duckdb/src/include/duckdb/storage/table/scan_state.hpp +2 -0
  126. package/src/duckdb/src/include/duckdb/storage/table/table_statistics.hpp +5 -0
  127. package/src/duckdb/src/include/duckdb.h +49 -1
  128. package/src/duckdb/src/include/duckdb.hpp +0 -1
  129. package/src/duckdb/src/main/capi/pending-c.cpp +16 -3
  130. package/src/duckdb/src/main/capi/result-c.cpp +27 -1
  131. package/src/duckdb/src/main/capi/stream-c.cpp +25 -0
  132. package/src/duckdb/src/main/client_context.cpp +8 -1
  133. package/src/duckdb/src/main/config.cpp +66 -1
  134. package/src/duckdb/src/main/database.cpp +10 -2
  135. package/src/duckdb/src/optimizer/join_order/cardinality_estimator.cpp +98 -67
  136. package/src/duckdb/src/optimizer/join_order/join_order_optimizer.cpp +16 -3
  137. package/src/duckdb/src/optimizer/statistics/expression/propagate_aggregate.cpp +9 -3
  138. package/src/duckdb/src/optimizer/statistics/expression/propagate_and_compress.cpp +6 -7
  139. package/src/duckdb/src/optimizer/statistics/expression/propagate_cast.cpp +14 -11
  140. package/src/duckdb/src/optimizer/statistics/expression/propagate_columnref.cpp +1 -1
  141. package/src/duckdb/src/optimizer/statistics/expression/propagate_comparison.cpp +13 -15
  142. package/src/duckdb/src/optimizer/statistics/expression/propagate_conjunction.cpp +0 -1
  143. package/src/duckdb/src/optimizer/statistics/expression/propagate_constant.cpp +3 -75
  144. package/src/duckdb/src/optimizer/statistics/expression/propagate_function.cpp +7 -2
  145. package/src/duckdb/src/optimizer/statistics/expression/propagate_operator.cpp +10 -0
  146. package/src/duckdb/src/optimizer/statistics/operator/propagate_aggregate.cpp +2 -3
  147. package/src/duckdb/src/optimizer/statistics/operator/propagate_filter.cpp +28 -31
  148. package/src/duckdb/src/optimizer/statistics/operator/propagate_join.cpp +4 -5
  149. package/src/duckdb/src/optimizer/statistics/operator/propagate_set_operation.cpp +3 -3
  150. package/src/duckdb/src/optimizer/statistics_propagator.cpp +1 -1
  151. package/src/duckdb/src/parser/parsed_data/alter_info.cpp +7 -3
  152. package/src/duckdb/src/parser/parsed_data/alter_scalar_function_info.cpp +56 -0
  153. package/src/duckdb/src/parser/parsed_data/alter_table_function_info.cpp +51 -0
  154. package/src/duckdb/src/parser/parsed_data/create_scalar_function_info.cpp +3 -2
  155. package/src/duckdb/src/parser/parsed_data/create_table_function_info.cpp +6 -0
  156. package/src/duckdb/src/parser/parsed_expression_iterator.cpp +8 -0
  157. package/src/duckdb/src/parser/query_node.cpp +1 -1
  158. package/src/duckdb/src/parser/statement/multi_statement.cpp +18 -0
  159. package/src/duckdb/src/parser/tableref/pivotref.cpp +296 -0
  160. package/src/duckdb/src/parser/tableref.cpp +3 -0
  161. package/src/duckdb/src/parser/transform/helpers/transform_alias.cpp +12 -6
  162. package/src/duckdb/src/parser/transform/helpers/transform_cte.cpp +24 -0
  163. package/src/duckdb/src/parser/transform/statement/transform_create_function.cpp +4 -0
  164. package/src/duckdb/src/parser/transform/statement/transform_create_view.cpp +4 -0
  165. package/src/duckdb/src/parser/transform/statement/transform_pivot_stmt.cpp +150 -0
  166. package/src/duckdb/src/parser/transform/statement/transform_select.cpp +8 -0
  167. package/src/duckdb/src/parser/transform/statement/transform_select_node.cpp +1 -1
  168. package/src/duckdb/src/parser/transform/tableref/transform_join.cpp +4 -0
  169. package/src/duckdb/src/parser/transform/tableref/transform_pivot.cpp +105 -0
  170. package/src/duckdb/src/parser/transform/tableref/transform_tableref.cpp +2 -0
  171. package/src/duckdb/src/parser/transformer.cpp +15 -3
  172. package/src/duckdb/src/planner/bind_context.cpp +16 -0
  173. package/src/duckdb/src/planner/binder/query_node/bind_select_node.cpp +11 -3
  174. package/src/duckdb/src/planner/binder/query_node/plan_select_node.cpp +0 -1
  175. package/src/duckdb/src/planner/binder/statement/bind_create.cpp +1 -1
  176. package/src/duckdb/src/planner/binder/statement/bind_logical_plan.cpp +17 -0
  177. package/src/duckdb/src/planner/binder/tableref/bind_joinref.cpp +9 -0
  178. package/src/duckdb/src/planner/binder/tableref/bind_pivot.cpp +365 -0
  179. package/src/duckdb/src/planner/binder.cpp +7 -1
  180. package/src/duckdb/src/planner/bound_result_modifier.cpp +1 -1
  181. package/src/duckdb/src/planner/expression/bound_window_expression.cpp +1 -1
  182. package/src/duckdb/src/planner/filter/constant_filter.cpp +4 -6
  183. package/src/duckdb/src/planner/pragma_handler.cpp +10 -2
  184. package/src/duckdb/src/storage/buffer_manager.cpp +44 -46
  185. package/src/duckdb/src/storage/checkpoint/row_group_writer.cpp +1 -1
  186. package/src/duckdb/src/storage/checkpoint/table_data_reader.cpp +1 -4
  187. package/src/duckdb/src/storage/checkpoint/table_data_writer.cpp +4 -4
  188. package/src/duckdb/src/storage/compression/bitpacking.cpp +28 -24
  189. package/src/duckdb/src/storage/compression/fixed_size_uncompressed.cpp +43 -45
  190. package/src/duckdb/src/storage/compression/numeric_constant.cpp +9 -10
  191. package/src/duckdb/src/storage/compression/patas.cpp +1 -1
  192. package/src/duckdb/src/storage/compression/rle.cpp +19 -15
  193. package/src/duckdb/src/storage/compression/validity_uncompressed.cpp +5 -5
  194. package/src/duckdb/src/storage/data_table.cpp +4 -6
  195. package/src/duckdb/src/storage/statistics/base_statistics.cpp +373 -128
  196. package/src/duckdb/src/storage/statistics/column_statistics.cpp +58 -3
  197. package/src/duckdb/src/storage/statistics/distinct_statistics.cpp +4 -9
  198. package/src/duckdb/src/storage/statistics/list_stats.cpp +117 -0
  199. package/src/duckdb/src/storage/statistics/numeric_stats.cpp +529 -0
  200. package/src/duckdb/src/storage/statistics/segment_statistics.cpp +2 -11
  201. package/src/duckdb/src/storage/statistics/string_stats.cpp +273 -0
  202. package/src/duckdb/src/storage/statistics/struct_stats.cpp +131 -0
  203. package/src/duckdb/src/storage/storage_info.cpp +1 -1
  204. package/src/duckdb/src/storage/table/column_checkpoint_state.cpp +3 -4
  205. package/src/duckdb/src/storage/table/column_data.cpp +16 -11
  206. package/src/duckdb/src/storage/table/column_data_checkpointer.cpp +2 -3
  207. package/src/duckdb/src/storage/table/column_segment.cpp +6 -8
  208. package/src/duckdb/src/storage/table/list_column_data.cpp +39 -58
  209. package/src/duckdb/src/storage/table/row_group.cpp +24 -23
  210. package/src/duckdb/src/storage/table/row_group_collection.cpp +12 -12
  211. package/src/duckdb/src/storage/table/standard_column_data.cpp +6 -6
  212. package/src/duckdb/src/storage/table/struct_column_data.cpp +15 -16
  213. package/src/duckdb/src/storage/table/table_statistics.cpp +27 -7
  214. package/src/duckdb/src/storage/table/update_segment.cpp +10 -12
  215. package/src/duckdb/third_party/libpg_query/include/nodes/nodes.hpp +3 -0
  216. package/src/duckdb/third_party/libpg_query/include/nodes/parsenodes.hpp +34 -1
  217. package/src/duckdb/third_party/libpg_query/include/parser/gram.hpp +1020 -530
  218. package/src/duckdb/third_party/libpg_query/include/parser/kwlist.hpp +7 -0
  219. package/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp +23560 -22737
  220. package/src/duckdb/ub_src_function_aggregate_distributive.cpp +2 -0
  221. package/src/duckdb/ub_src_function_scalar_bit.cpp +2 -0
  222. package/src/duckdb/ub_src_function_scalar_map.cpp +4 -0
  223. package/src/duckdb/ub_src_main_capi.cpp +2 -0
  224. package/src/duckdb/ub_src_parser_parsed_data.cpp +4 -2
  225. package/src/duckdb/ub_src_parser_statement.cpp +2 -0
  226. package/src/duckdb/ub_src_parser_tableref.cpp +2 -0
  227. package/src/duckdb/ub_src_parser_transform_statement.cpp +2 -0
  228. package/src/duckdb/ub_src_parser_transform_tableref.cpp +2 -0
  229. package/src/duckdb/ub_src_planner_binder_tableref.cpp +2 -0
  230. package/src/duckdb/ub_src_storage_statistics.cpp +4 -6
  231. package/src/duckdb/src/include/duckdb/main/loadable_extension.hpp +0 -59
  232. package/src/duckdb/src/include/duckdb/storage/statistics/list_statistics.hpp +0 -36
  233. package/src/duckdb/src/include/duckdb/storage/statistics/numeric_statistics.hpp +0 -75
  234. package/src/duckdb/src/include/duckdb/storage/statistics/string_statistics.hpp +0 -49
  235. package/src/duckdb/src/include/duckdb/storage/statistics/struct_statistics.hpp +0 -36
  236. package/src/duckdb/src/include/duckdb/storage/statistics/validity_statistics.hpp +0 -45
  237. package/src/duckdb/src/parser/parsed_data/alter_function_info.cpp +0 -55
  238. package/src/duckdb/src/storage/statistics/list_statistics.cpp +0 -94
  239. package/src/duckdb/src/storage/statistics/numeric_statistics.cpp +0 -307
  240. package/src/duckdb/src/storage/statistics/string_statistics.cpp +0 -220
  241. package/src/duckdb/src/storage/statistics/struct_statistics.cpp +0 -108
  242. package/src/duckdb/src/storage/statistics/validity_statistics.cpp +0 -91
@@ -111,7 +111,7 @@ public:
111
111
  orders.emplace_back(OrderType::ASCENDING, OrderByNullType::NULLS_FIRST, pexpr->Copy(), nullptr);
112
112
  } else {
113
113
  orders.emplace_back(OrderType::ASCENDING, OrderByNullType::NULLS_FIRST, pexpr->Copy(),
114
- wexpr->partitions_stats[prt_idx]->Copy());
114
+ wexpr->partitions_stats[prt_idx]->ToUnique());
115
115
  }
116
116
  partitions.emplace_back(orders.back().Copy());
117
117
  }
@@ -72,9 +72,8 @@ SinkFinalizeType PhysicalVacuum::Finalize(Pipeline &pipeline, Event &event, Clie
72
72
 
73
73
  auto table = info->table;
74
74
  for (idx_t col_idx = 0; col_idx < sink.column_distinct_stats.size(); col_idx++) {
75
- table->GetStorage().SetStatistics(info->column_id_map.at(col_idx), [&](BaseStatistics &stats) {
76
- stats.distinct_stats = std::move(sink.column_distinct_stats[col_idx]);
77
- });
75
+ table->GetStorage().SetDistinct(info->column_id_map.at(col_idx),
76
+ std::move(sink.column_distinct_stats[col_idx]));
78
77
  }
79
78
 
80
79
  return SinkFinalizeType::READY;
@@ -87,11 +87,23 @@ public:
87
87
  OuterJoinMarker left_outer;
88
88
  SelectionVector match_sel;
89
89
  ExpressionExecutor executor;
90
+ DataChunk intermediate_chunk;
90
91
  };
91
92
 
92
93
  unique_ptr<OperatorState> PhysicalBlockwiseNLJoin::GetOperatorState(ExecutionContext &context) const {
93
94
  auto &gstate = (BlockwiseNLJoinGlobalState &)*sink_state;
94
- return make_unique<BlockwiseNLJoinState>(context, gstate.right_chunks, *this);
95
+ auto result = make_unique<BlockwiseNLJoinState>(context, gstate.right_chunks, *this);
96
+ if (join_type == JoinType::SEMI || join_type == JoinType::ANTI) {
97
+ vector<LogicalType> intermediate_types;
98
+ for (auto &type : children[0]->types) {
99
+ intermediate_types.emplace_back(type);
100
+ }
101
+ for (auto &type : children[1]->types) {
102
+ intermediate_types.emplace_back(type);
103
+ }
104
+ result->intermediate_chunk.Initialize(Allocator::DefaultAllocator(), intermediate_types);
105
+ }
106
+ return std::move(result);
95
107
  }
96
108
 
97
109
  OperatorResultType PhysicalBlockwiseNLJoin::ExecuteInternal(ExecutionContext &context, DataChunk &input,
@@ -111,24 +123,30 @@ OperatorResultType PhysicalBlockwiseNLJoin::ExecuteInternal(ExecutionContext &co
111
123
  }
112
124
  }
113
125
 
126
+ DataChunk *intermediate_chunk = &chunk;
127
+ if (join_type == JoinType::SEMI || join_type == JoinType::ANTI) {
128
+ intermediate_chunk = &state.intermediate_chunk;
129
+ intermediate_chunk->Reset();
130
+ }
131
+
114
132
  // now perform the actual join
115
133
  // we perform a cross product, then execute the expression directly on the cross product' result
116
134
  idx_t result_count = 0;
117
135
  do {
118
- auto result = state.cross_product.Execute(input, chunk);
136
+ auto result = state.cross_product.Execute(input, *intermediate_chunk);
119
137
  if (result == OperatorResultType::NEED_MORE_INPUT) {
120
138
  // exhausted input, have to pull new LHS chunk
121
139
  if (state.left_outer.Enabled()) {
122
140
  // left join: before we move to the next chunk, see if we need to output any vectors that didn't
123
141
  // have a match found
124
- state.left_outer.ConstructLeftJoinResult(input, chunk);
142
+ state.left_outer.ConstructLeftJoinResult(input, *intermediate_chunk);
125
143
  state.left_outer.Reset();
126
144
  }
127
145
  return OperatorResultType::NEED_MORE_INPUT;
128
146
  }
129
147
 
130
148
  // now perform the computation
131
- result_count = state.executor.SelectExpression(chunk, state.match_sel);
149
+ result_count = state.executor.SelectExpression(*intermediate_chunk, state.match_sel);
132
150
  if (result_count > 0) {
133
151
  // found a match!
134
152
  // check if the cross product is scanning the LHS or the RHS in its entirety
@@ -143,12 +161,20 @@ OperatorResultType PhysicalBlockwiseNLJoin::ExecuteInternal(ExecutionContext &co
143
161
  // set the match flags in the RHS
144
162
  gstate.right_outer.SetMatches(state.match_sel, result_count, state.cross_product.ScanPosition());
145
163
  }
146
- chunk.Slice(state.match_sel, result_count);
164
+ intermediate_chunk->Slice(state.match_sel, result_count);
147
165
  } else {
148
166
  // no result: reset the chunk
149
- chunk.Reset();
167
+ intermediate_chunk->Reset();
150
168
  }
151
169
  } while (result_count == 0);
170
+
171
+ if (join_type == JoinType::SEMI || join_type == JoinType::ANTI) {
172
+ for (idx_t col_idx = 0; col_idx < chunk.ColumnCount(); col_idx++) {
173
+ chunk.data[col_idx].Reference(intermediate_chunk->data[col_idx]);
174
+ }
175
+ chunk.SetCardinality(*intermediate_chunk);
176
+ }
177
+
152
178
  return OperatorResultType::HAVE_MORE_OUTPUT;
153
179
  }
154
180
 
@@ -555,7 +555,7 @@ void BufferedCSVReader::DetectCandidateTypes(const vector<LogicalType> &type_can
555
555
  // try formatting for date types if the user did not specify one and it starts with numeric values.
556
556
  string separator;
557
557
  if (has_format_candidates.count(sql_type.id()) && !original_options.has_format[sql_type.id()] &&
558
- StartsWithNumericDate(separator, StringValue::Get(dummy_val))) {
558
+ !dummy_val.IsNull() && StartsWithNumericDate(separator, StringValue::Get(dummy_val))) {
559
559
  // generate date format candidates the first time through
560
560
  auto &type_format_candidates = format_candidates[sql_type.id()];
561
561
  const auto had_format_candidates = has_format_candidates[sql_type.id()];
@@ -9,7 +9,7 @@
9
9
  #include "duckdb/parser/expression/comparison_expression.hpp"
10
10
  #include "duckdb/planner/expression/bound_aggregate_expression.hpp"
11
11
  #include "duckdb/planner/operator/logical_aggregate.hpp"
12
- #include "duckdb/storage/statistics/numeric_statistics.hpp"
12
+
13
13
  namespace duckdb {
14
14
 
15
15
  static uint32_t RequiredBitsForValue(uint32_t n) {
@@ -50,23 +50,20 @@ static bool CanUsePerfectHashAggregate(ClientContext &context, LogicalAggregate
50
50
  // for small types we can just set the stats to [type_min, type_max]
51
51
  switch (group_type.InternalType()) {
52
52
  case PhysicalType::INT8:
53
- stats = make_unique<NumericStatistics>(group_type, Value::MinimumValue(group_type),
54
- Value::MaximumValue(group_type), StatisticsType::LOCAL_STATS);
55
- break;
56
53
  case PhysicalType::INT16:
57
- stats = make_unique<NumericStatistics>(group_type, Value::MinimumValue(group_type),
58
- Value::MaximumValue(group_type), StatisticsType::LOCAL_STATS);
59
54
  break;
60
55
  default:
61
56
  // type is too large and there are no stats: skip perfect hashing
62
57
  return false;
63
58
  }
64
- // we had no stats before, so we have no clue if there are null values or not
65
- stats->validity_stats = make_unique<ValidityStatistics>(true);
59
+ // construct stats with the min and max value of the type
60
+ stats = NumericStats::CreateUnknown(group_type).ToUnique();
61
+ NumericStats::SetMin(*stats, Value::MinimumValue(group_type));
62
+ NumericStats::SetMax(*stats, Value::MaximumValue(group_type));
66
63
  }
67
- auto &nstats = (NumericStatistics &)*stats;
64
+ auto &nstats = *stats;
68
65
 
69
- if (nstats.min.IsNull() || nstats.max.IsNull()) {
66
+ if (!NumericStats::HasMinMax(nstats)) {
70
67
  return false;
71
68
  }
72
69
  // we have a min and a max value for the stats: use that to figure out how many bits we have
@@ -75,17 +72,20 @@ static bool CanUsePerfectHashAggregate(ClientContext &context, LogicalAggregate
75
72
  int64_t range;
76
73
  switch (group_type.InternalType()) {
77
74
  case PhysicalType::INT8:
78
- range = int64_t(nstats.max.GetValueUnsafe<int8_t>()) - int64_t(nstats.min.GetValueUnsafe<int8_t>());
75
+ range = int64_t(NumericStats::GetMaxUnsafe<int8_t>(nstats)) -
76
+ int64_t(NumericStats::GetMinUnsafe<int8_t>(nstats));
79
77
  break;
80
78
  case PhysicalType::INT16:
81
- range = int64_t(nstats.max.GetValueUnsafe<int16_t>()) - int64_t(nstats.min.GetValueUnsafe<int16_t>());
79
+ range = int64_t(NumericStats::GetMaxUnsafe<int16_t>(nstats)) -
80
+ int64_t(NumericStats::GetMinUnsafe<int16_t>(nstats));
82
81
  break;
83
82
  case PhysicalType::INT32:
84
- range = int64_t(nstats.max.GetValueUnsafe<int32_t>()) - int64_t(nstats.min.GetValueUnsafe<int32_t>());
83
+ range = int64_t(NumericStats::GetMaxUnsafe<int32_t>(nstats)) -
84
+ int64_t(NumericStats::GetMinUnsafe<int32_t>(nstats));
85
85
  break;
86
86
  case PhysicalType::INT64:
87
- if (!TrySubtractOperator::Operation(nstats.max.GetValueUnsafe<int64_t>(),
88
- nstats.min.GetValueUnsafe<int64_t>(), range)) {
87
+ if (!TrySubtractOperator::Operation(NumericStats::GetMaxUnsafe<int64_t>(nstats),
88
+ NumericStats::GetMinUnsafe<int64_t>(nstats), range)) {
89
89
  return false;
90
90
  }
91
91
  break;
@@ -10,7 +10,7 @@
10
10
  #include "duckdb/function/table/table_scan.hpp"
11
11
  #include "duckdb/main/client_context.hpp"
12
12
  #include "duckdb/planner/operator/logical_comparison_join.hpp"
13
- #include "duckdb/storage/statistics/numeric_statistics.hpp"
13
+
14
14
  #include "duckdb/transaction/duck_transaction.hpp"
15
15
  #include "duckdb/common/operator/subtract.hpp"
16
16
  #include "duckdb/execution/operator/join/physical_blockwise_nl_join.hpp"
@@ -92,19 +92,21 @@ void CheckForPerfectJoinOpt(LogicalComparisonJoin &op, PerfectHashJoinStats &joi
92
92
  }
93
93
  // with integral internal types
94
94
  for (auto &&join_stat : op.join_stats) {
95
- if (!TypeIsInteger(join_stat->type.InternalType()) || join_stat->type.InternalType() == PhysicalType::INT128) {
95
+ if (!TypeIsInteger(join_stat->GetType().InternalType()) ||
96
+ join_stat->GetType().InternalType() == PhysicalType::INT128) {
96
97
  // perfect join not possible for non-integral types or hugeint
97
98
  return;
98
99
  }
99
100
  }
100
101
 
101
102
  // and when the build range is smaller than the threshold
102
- auto stats_build = reinterpret_cast<NumericStatistics *>(op.join_stats[0].get()); // lhs stats
103
- if (stats_build->min.IsNull() || stats_build->max.IsNull()) {
103
+ auto &stats_build = *op.join_stats[0].get(); // lhs stats
104
+ if (!NumericStats::HasMinMax(stats_build)) {
104
105
  return;
105
106
  }
106
107
  int64_t min_value, max_value;
107
- if (!ExtractNumericValue(stats_build->min, min_value) || !ExtractNumericValue(stats_build->max, max_value)) {
108
+ if (!ExtractNumericValue(NumericStats::Min(stats_build), min_value) ||
109
+ !ExtractNumericValue(NumericStats::Max(stats_build), max_value)) {
108
110
  return;
109
111
  }
110
112
  int64_t build_range;
@@ -113,20 +115,24 @@ void CheckForPerfectJoinOpt(LogicalComparisonJoin &op, PerfectHashJoinStats &joi
113
115
  }
114
116
 
115
117
  // Fill join_stats for invisible join
116
- auto stats_probe = reinterpret_cast<NumericStatistics *>(op.join_stats[1].get()); // rhs stats
118
+ auto &stats_probe = *op.join_stats[1].get(); // rhs stats
119
+ if (!NumericStats::HasMinMax(stats_probe)) {
120
+ return;
121
+ }
117
122
 
118
123
  // The max size our build must have to run the perfect HJ
119
124
  const idx_t MAX_BUILD_SIZE = 1000000;
120
- join_state.probe_min = stats_probe->min;
121
- join_state.probe_max = stats_probe->max;
122
- join_state.build_min = stats_build->min;
123
- join_state.build_max = stats_build->max;
125
+ join_state.probe_min = NumericStats::Min(stats_probe);
126
+ join_state.probe_max = NumericStats::Max(stats_probe);
127
+ join_state.build_min = NumericStats::Min(stats_build);
128
+ join_state.build_max = NumericStats::Max(stats_build);
124
129
  join_state.estimated_cardinality = op.estimated_cardinality;
125
130
  join_state.build_range = build_range;
126
- if (join_state.build_range > MAX_BUILD_SIZE || stats_probe->max.IsNull() || stats_probe->min.IsNull()) {
131
+ if (join_state.build_range > MAX_BUILD_SIZE) {
127
132
  return;
128
133
  }
129
- if (stats_build->min <= stats_probe->min && stats_probe->max <= stats_build->max) {
134
+ if (NumericStats::Min(stats_build) <= NumericStats::Min(stats_probe) &&
135
+ NumericStats::Max(stats_probe) <= NumericStats::Max(stats_build)) {
130
136
  join_state.is_probe_in_domain = true;
131
137
  }
132
138
  join_state.is_build_small = true;
@@ -127,9 +127,6 @@ struct NumericAverageOperation : public BaseSumOperation<AverageSetOperation, Re
127
127
  if (state->count == 0) {
128
128
  mask.SetInvalid(idx);
129
129
  } else {
130
- if (!Value::DoubleIsFinite(state->value)) {
131
- throw OutOfRangeException("AVG is out of range!");
132
- }
133
130
  target[idx] = (state->value / state->count);
134
131
  }
135
132
  }
@@ -141,9 +138,6 @@ struct KahanAverageOperation : public BaseSumOperation<AverageSetOperation, Kaha
141
138
  if (state->count == 0) {
142
139
  mask.SetInvalid(idx);
143
140
  } else {
144
- if (!Value::DoubleIsFinite(state->value)) {
145
- throw OutOfRangeException("AVG is out of range!");
146
- }
147
141
  target[idx] = (state->value / state->count) + (state->err / state->count);
148
142
  }
149
143
  }
@@ -3,6 +3,8 @@
3
3
  #include "duckdb/common/types/null_value.hpp"
4
4
  #include "duckdb/common/vector_operations/vector_operations.hpp"
5
5
  #include "duckdb/common/vector_operations/aggregate_executor.hpp"
6
+ #include "duckdb/common/types/bit.hpp"
7
+ #include "duckdb/common/types/cast_helpers.hpp"
6
8
 
7
9
  namespace duckdb {
8
10
 
@@ -38,37 +40,32 @@ static AggregateFunction GetBitfieldUnaryAggregate(LogicalType type) {
38
40
  }
39
41
  }
40
42
 
41
- struct BitAndOperation {
43
+ struct BitwiseOperation {
42
44
  template <class STATE>
43
45
  static void Initialize(STATE *state) {
44
- // If there are no matching rows, BIT_AND() returns a null value.
46
+ // If there are no matching rows, returns a null value.
45
47
  state->is_set = false;
46
48
  }
47
49
 
48
50
  template <class INPUT_TYPE, class STATE, class OP>
49
51
  static void Operation(STATE *state, AggregateInputData &, INPUT_TYPE *input, ValidityMask &mask, idx_t idx) {
50
52
  if (!state->is_set) {
53
+ OP::template Assign(state, input[idx]);
51
54
  state->is_set = true;
52
- state->value = input[idx];
53
55
  } else {
54
- state->value &= input[idx];
56
+ OP::template Execute(state, input[idx]);
55
57
  }
56
58
  }
57
59
 
58
60
  template <class INPUT_TYPE, class STATE, class OP>
59
61
  static void ConstantOperation(STATE *state, AggregateInputData &aggr_input_data, INPUT_TYPE *input,
60
62
  ValidityMask &mask, idx_t count) {
61
- // count is not relevant
62
- Operation<INPUT_TYPE, STATE, OP>(state, aggr_input_data, input, mask, 0);
63
+ OP::template Operation<INPUT_TYPE, STATE, OP>(state, aggr_input_data, input, mask, 0);
63
64
  }
64
65
 
65
- template <class T, class STATE>
66
- static void Finalize(Vector &result, AggregateInputData &, STATE *state, T *target, ValidityMask &mask, idx_t idx) {
67
- if (!state->is_set) {
68
- mask.SetInvalid(idx);
69
- } else {
70
- target[idx] = state->value;
71
- }
66
+ template <class INPUT_TYPE, class STATE>
67
+ static void Assign(STATE *state, INPUT_TYPE input) {
68
+ state->value = input;
72
69
  }
73
70
 
74
71
  template <class STATE, class OP>
@@ -79,9 +76,19 @@ struct BitAndOperation {
79
76
  }
80
77
  if (!target->is_set) {
81
78
  // target is NULL, use source value directly.
82
- *target = source;
79
+ OP::template Assign(target, source.value);
80
+ target->is_set = true;
81
+ } else {
82
+ OP::template Execute(target, source.value);
83
+ }
84
+ }
85
+
86
+ template <class T, class STATE>
87
+ static void Finalize(Vector &result, AggregateInputData &, STATE *state, T *target, ValidityMask &mask, idx_t idx) {
88
+ if (!state->is_set) {
89
+ mask.SetInvalid(idx);
83
90
  } else {
84
- target->value &= source.value;
91
+ target[idx] = state->value;
85
92
  }
86
93
  }
87
94
 
@@ -90,36 +97,55 @@ struct BitAndOperation {
90
97
  }
91
98
  };
92
99
 
93
- void BitAndFun::RegisterFunction(BuiltinFunctions &set) {
94
- AggregateFunctionSet bit_and("bit_and");
95
- for (auto &type : LogicalType::Integral()) {
96
- bit_and.AddFunction(GetBitfieldUnaryAggregate<BitAndOperation>(type));
100
+ struct BitAndOperation : public BitwiseOperation {
101
+ template <class INPUT_TYPE, class STATE>
102
+ static void Execute(STATE *state, INPUT_TYPE input) {
103
+ state->value &= input;
97
104
  }
98
- set.AddFunction(bit_and);
99
- }
105
+ };
100
106
 
101
- struct BitOrOperation {
102
- template <class STATE>
103
- static void Initialize(STATE *state) {
104
- // If there are no matching rows, BIT_OR() returns a null value.
105
- state->is_set = false;
107
+ struct BitOrOperation : public BitwiseOperation {
108
+ template <class INPUT_TYPE, class STATE>
109
+ static void Execute(STATE *state, INPUT_TYPE input) {
110
+ state->value |= input;
106
111
  }
112
+ };
107
113
 
108
- template <class INPUT_TYPE, class STATE, class OP>
109
- static void Operation(STATE *state, AggregateInputData &, INPUT_TYPE *input, ValidityMask &mask, idx_t idx) {
110
- if (!state->is_set) {
111
- state->is_set = true;
112
- state->value = input[idx];
113
- } else {
114
- state->value |= input[idx];
115
- }
114
+ struct BitXorOperation : public BitwiseOperation {
115
+ template <class INPUT_TYPE, class STATE>
116
+ static void Execute(STATE *state, INPUT_TYPE input) {
117
+ state->value ^= input;
116
118
  }
117
119
 
118
120
  template <class INPUT_TYPE, class STATE, class OP>
119
121
  static void ConstantOperation(STATE *state, AggregateInputData &aggr_input_data, INPUT_TYPE *input,
120
122
  ValidityMask &mask, idx_t count) {
121
- // count is irrelevant
122
- Operation<INPUT_TYPE, STATE, OP>(state, aggr_input_data, input, mask, 0);
123
+ for (idx_t i = 0; i < count; i++) {
124
+ Operation<INPUT_TYPE, STATE, OP>(state, aggr_input_data, input, mask, 0);
125
+ }
126
+ }
127
+ };
128
+
129
+ struct BitStringBitwiseOperation : public BitwiseOperation {
130
+ template <class STATE>
131
+ static void Destroy(STATE *state) {
132
+ if (state->is_set && !state->value.IsInlined()) {
133
+ delete[] state->value.GetDataUnsafe();
134
+ }
135
+ }
136
+
137
+ template <class INPUT_TYPE, class STATE>
138
+ static void Assign(STATE *state, INPUT_TYPE input) {
139
+ D_ASSERT(state->is_set == false);
140
+ if (input.IsInlined()) {
141
+ state->value = input;
142
+ } else { // non-inlined string, need to allocate space for it
143
+ auto len = input.GetSize();
144
+ auto ptr = new char[len];
145
+ memcpy(ptr, input.GetDataUnsafe(), len);
146
+
147
+ state->value = string_t(ptr, len);
148
+ }
123
149
  }
124
150
 
125
151
  template <class T, class STATE>
@@ -127,52 +153,31 @@ struct BitOrOperation {
127
153
  if (!state->is_set) {
128
154
  mask.SetInvalid(idx);
129
155
  } else {
130
- target[idx] = state->value;
156
+ target[idx] = StringVector::AddStringOrBlob(result, state->value);
131
157
  }
132
158
  }
159
+ };
133
160
 
134
- template <class STATE, class OP>
135
- static void Combine(const STATE &source, STATE *target, AggregateInputData &) {
136
- if (!source.is_set) {
137
- // source is NULL, nothing to do.
138
- return;
139
- }
140
- if (!target->is_set) {
141
- // target is NULL, use source value directly.
142
- *target = source;
143
- } else {
144
- target->value |= source.value;
145
- }
146
- }
161
+ struct BitStringAndOperation : public BitStringBitwiseOperation {
147
162
 
148
- static bool IgnoreNull() {
149
- return true;
163
+ template <class INPUT_TYPE, class STATE>
164
+ static void Execute(STATE *state, INPUT_TYPE input) {
165
+ Bit::BitwiseAnd(input, state->value, state->value);
150
166
  }
151
167
  };
152
168
 
153
- void BitOrFun::RegisterFunction(BuiltinFunctions &set) {
154
- AggregateFunctionSet bit_or("bit_or");
155
- for (auto &type : LogicalType::Integral()) {
156
- bit_or.AddFunction(GetBitfieldUnaryAggregate<BitOrOperation>(type));
157
- }
158
- set.AddFunction(bit_or);
159
- }
169
+ struct BitStringOrOperation : public BitStringBitwiseOperation {
160
170
 
161
- struct BitXorOperation {
162
- template <class STATE>
163
- static void Initialize(STATE *state) {
164
- // If there are no matching rows, BIT_XOR() returns a null value.
165
- state->is_set = false;
171
+ template <class INPUT_TYPE, class STATE>
172
+ static void Execute(STATE *state, INPUT_TYPE input) {
173
+ Bit::BitwiseOr(input, state->value, state->value);
166
174
  }
175
+ };
167
176
 
168
- template <class INPUT_TYPE, class STATE, class OP>
169
- static void Operation(STATE *state, AggregateInputData &, INPUT_TYPE *input, ValidityMask &mask, idx_t idx) {
170
- if (!state->is_set) {
171
- state->is_set = true;
172
- state->value = input[idx];
173
- } else {
174
- state->value ^= input[idx];
175
- }
177
+ struct BitStringXorOperation : public BitStringBitwiseOperation {
178
+ template <class INPUT_TYPE, class STATE>
179
+ static void Execute(STATE *state, INPUT_TYPE input) {
180
+ Bit::BitwiseXor(input, state->value, state->value);
176
181
  }
177
182
 
178
183
  template <class INPUT_TYPE, class STATE, class OP>
@@ -182,40 +187,39 @@ struct BitXorOperation {
182
187
  Operation<INPUT_TYPE, STATE, OP>(state, aggr_input_data, input, mask, 0);
183
188
  }
184
189
  }
190
+ };
185
191
 
186
- template <class T, class STATE>
187
- static void Finalize(Vector &result, AggregateInputData &, STATE *state, T *target, ValidityMask &mask, idx_t idx) {
188
- if (!state->is_set) {
189
- mask.SetInvalid(idx);
190
- } else {
191
- target[idx] = state->value;
192
- }
192
+ void BitAndFun::RegisterFunction(BuiltinFunctions &set) {
193
+ AggregateFunctionSet bit_and("bit_and");
194
+ for (auto &type : LogicalType::Integral()) {
195
+ bit_and.AddFunction(GetBitfieldUnaryAggregate<BitAndOperation>(type));
193
196
  }
194
197
 
195
- template <class STATE, class OP>
196
- static void Combine(const STATE &source, STATE *target, AggregateInputData &) {
197
- if (!source.is_set) {
198
- // source is NULL, nothing to do.
199
- return;
200
- }
201
- if (!target->is_set) {
202
- // target is NULL, use source value directly.
203
- *target = source;
204
- } else {
205
- target->value ^= source.value;
206
- }
207
- }
198
+ bit_and.AddFunction(
199
+ AggregateFunction::UnaryAggregateDestructor<BitState<string_t>, string_t, string_t, BitStringAndOperation>(
200
+ LogicalType::BIT, LogicalType::BIT));
201
+ set.AddFunction(bit_and);
202
+ }
208
203
 
209
- static bool IgnoreNull() {
210
- return true;
204
+ void BitOrFun::RegisterFunction(BuiltinFunctions &set) {
205
+ AggregateFunctionSet bit_or("bit_or");
206
+ for (auto &type : LogicalType::Integral()) {
207
+ bit_or.AddFunction(GetBitfieldUnaryAggregate<BitOrOperation>(type));
211
208
  }
212
- };
209
+ bit_or.AddFunction(
210
+ AggregateFunction::UnaryAggregateDestructor<BitState<string_t>, string_t, string_t, BitStringOrOperation>(
211
+ LogicalType::BIT, LogicalType::BIT));
212
+ set.AddFunction(bit_or);
213
+ }
213
214
 
214
215
  void BitXorFun::RegisterFunction(BuiltinFunctions &set) {
215
216
  AggregateFunctionSet bit_xor("bit_xor");
216
217
  for (auto &type : LogicalType::Integral()) {
217
218
  bit_xor.AddFunction(GetBitfieldUnaryAggregate<BitXorOperation>(type));
218
219
  }
220
+ bit_xor.AddFunction(
221
+ AggregateFunction::UnaryAggregateDestructor<BitState<string_t>, string_t, string_t, BitStringXorOperation>(
222
+ LogicalType::BIT, LogicalType::BIT));
219
223
  set.AddFunction(bit_xor);
220
224
  }
221
225