duckdb 0.7.2-dev1803.0 → 0.7.2-dev1867.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 (142) hide show
  1. package/package.json +1 -1
  2. package/src/duckdb/src/catalog/catalog.cpp +27 -27
  3. package/src/duckdb/src/catalog/catalog_entry/duck_schema_entry.cpp +6 -6
  4. package/src/duckdb/src/catalog/catalog_set.cpp +27 -25
  5. package/src/duckdb/src/catalog/default/default_functions.cpp +4 -4
  6. package/src/duckdb/src/catalog/default/default_types.cpp +4 -4
  7. package/src/duckdb/src/catalog/default/default_views.cpp +4 -4
  8. package/src/duckdb/src/catalog/dependency_list.cpp +7 -6
  9. package/src/duckdb/src/catalog/dependency_manager.cpp +44 -38
  10. package/src/duckdb/src/common/serializer/buffered_file_reader.cpp +11 -6
  11. package/src/duckdb/src/common/types/batched_data_collection.cpp +2 -1
  12. package/src/duckdb/src/common/types/column_data_allocator.cpp +1 -0
  13. package/src/duckdb/src/common/types/vector.cpp +2 -2
  14. package/src/duckdb/src/common/vector_operations/vector_copy.cpp +14 -11
  15. package/src/duckdb/src/execution/operator/aggregate/distinct_aggregate_data.cpp +1 -1
  16. package/src/duckdb/src/execution/operator/aggregate/physical_window.cpp +51 -50
  17. package/src/duckdb/src/execution/operator/persistent/physical_batch_insert.cpp +14 -13
  18. package/src/duckdb/src/execution/operator/persistent/physical_insert.cpp +20 -20
  19. package/src/duckdb/src/execution/operator/schema/physical_create_table.cpp +2 -2
  20. package/src/duckdb/src/execution/physical_plan/plan_create_index.cpp +1 -1
  21. package/src/duckdb/src/execution/physical_plan/plan_create_table.cpp +3 -3
  22. package/src/duckdb/src/execution/physical_plan/plan_delete.cpp +1 -1
  23. package/src/duckdb/src/execution/physical_plan/plan_insert.cpp +1 -1
  24. package/src/duckdb/src/execution/physical_plan/plan_update.cpp +1 -1
  25. package/src/duckdb/src/function/aggregate/sorted_aggregate_function.cpp +3 -3
  26. package/src/duckdb/src/function/cast/cast_function_set.cpp +2 -1
  27. package/src/duckdb/src/function/scalar/sequence/nextval.cpp +29 -29
  28. package/src/duckdb/src/function/scalar/string/damerau_levenshtein.cpp +106 -0
  29. package/src/duckdb/src/function/scalar/string/regexp.cpp +145 -28
  30. package/src/duckdb/src/function/scalar/string_functions.cpp +1 -0
  31. package/src/duckdb/src/function/table/checkpoint.cpp +4 -4
  32. package/src/duckdb/src/function/table/system/duckdb_columns.cpp +24 -24
  33. package/src/duckdb/src/function/table/system/duckdb_constraints.cpp +7 -6
  34. package/src/duckdb/src/function/table/system/duckdb_databases.cpp +1 -1
  35. package/src/duckdb/src/function/table/system/duckdb_dependencies.cpp +11 -11
  36. package/src/duckdb/src/function/table/system/pragma_database_size.cpp +1 -1
  37. package/src/duckdb/src/function/table/system/pragma_table_info.cpp +17 -18
  38. package/src/duckdb/src/function/table/table_scan.cpp +8 -11
  39. package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
  40. package/src/duckdb/src/include/duckdb/catalog/catalog.hpp +9 -9
  41. package/src/duckdb/src/include/duckdb/catalog/catalog_entry_map.hpp +38 -0
  42. package/src/duckdb/src/include/duckdb/catalog/catalog_transaction.hpp +4 -3
  43. package/src/duckdb/src/include/duckdb/catalog/default/default_functions.hpp +2 -2
  44. package/src/duckdb/src/include/duckdb/catalog/default/default_types.hpp +2 -2
  45. package/src/duckdb/src/include/duckdb/catalog/default/default_views.hpp +2 -2
  46. package/src/duckdb/src/include/duckdb/catalog/dependency.hpp +4 -5
  47. package/src/duckdb/src/include/duckdb/catalog/dependency_list.hpp +4 -5
  48. package/src/duckdb/src/include/duckdb/catalog/dependency_manager.hpp +10 -9
  49. package/src/duckdb/src/include/duckdb/common/allocator.hpp +2 -1
  50. package/src/duckdb/src/include/duckdb/common/field_writer.hpp +1 -1
  51. package/src/duckdb/src/include/duckdb/common/helper.hpp +9 -0
  52. package/src/duckdb/src/include/duckdb/common/optional_ptr.hpp +29 -6
  53. package/src/duckdb/src/include/duckdb/common/serializer/buffered_file_reader.hpp +6 -5
  54. package/src/duckdb/src/include/duckdb/common/serializer.hpp +1 -1
  55. package/src/duckdb/src/include/duckdb/common/types/row_data_collection.hpp +1 -0
  56. package/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_batch_insert.hpp +2 -2
  57. package/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_insert.hpp +5 -5
  58. package/src/duckdb/src/include/duckdb/execution/operator/schema/physical_create_table.hpp +2 -2
  59. package/src/duckdb/src/include/duckdb/function/cast/default_casts.hpp +3 -2
  60. package/src/duckdb/src/include/duckdb/function/scalar/string_functions.hpp +4 -0
  61. package/src/duckdb/src/include/duckdb/main/database_manager.hpp +4 -3
  62. package/src/duckdb/src/include/duckdb/main/query_result.hpp +3 -2
  63. package/src/duckdb/src/include/duckdb/optimizer/filter_combiner.hpp +7 -7
  64. package/src/duckdb/src/include/duckdb/optimizer/matcher/expression_matcher.hpp +11 -11
  65. package/src/duckdb/src/include/duckdb/optimizer/matcher/set_matcher.hpp +8 -8
  66. package/src/duckdb/src/include/duckdb/optimizer/rule/arithmetic_simplification.hpp +1 -1
  67. package/src/duckdb/src/include/duckdb/optimizer/rule/case_simplification.hpp +1 -1
  68. package/src/duckdb/src/include/duckdb/optimizer/rule/comparison_simplification.hpp +1 -1
  69. package/src/duckdb/src/include/duckdb/optimizer/rule/conjunction_simplification.hpp +2 -2
  70. package/src/duckdb/src/include/duckdb/optimizer/rule/constant_folding.hpp +1 -1
  71. package/src/duckdb/src/include/duckdb/optimizer/rule/date_part_simplification.hpp +1 -1
  72. package/src/duckdb/src/include/duckdb/optimizer/rule/distributivity.hpp +1 -1
  73. package/src/duckdb/src/include/duckdb/optimizer/rule/empty_needle_removal.hpp +1 -1
  74. package/src/duckdb/src/include/duckdb/optimizer/rule/enum_comparison.hpp +1 -1
  75. package/src/duckdb/src/include/duckdb/optimizer/rule/equal_or_null_simplification.hpp +1 -1
  76. package/src/duckdb/src/include/duckdb/optimizer/rule/in_clause_simplification.hpp +1 -1
  77. package/src/duckdb/src/include/duckdb/optimizer/rule/like_optimizations.hpp +1 -1
  78. package/src/duckdb/src/include/duckdb/optimizer/rule/move_constants.hpp +1 -1
  79. package/src/duckdb/src/include/duckdb/optimizer/rule/ordered_aggregate_optimizer.hpp +1 -1
  80. package/src/duckdb/src/include/duckdb/optimizer/rule/regex_optimizations.hpp +1 -1
  81. package/src/duckdb/src/include/duckdb/optimizer/rule.hpp +2 -2
  82. package/src/duckdb/src/include/duckdb/parser/base_expression.hpp +1 -1
  83. package/src/duckdb/src/include/duckdb/parser/expression_map.hpp +19 -6
  84. package/src/duckdb/src/include/duckdb/parser/expression_util.hpp +1 -1
  85. package/src/duckdb/src/include/duckdb/planner/expression.hpp +5 -2
  86. package/src/duckdb/src/include/duckdb/planner/expression_binder/base_select_binder.hpp +1 -1
  87. package/src/duckdb/src/include/duckdb/planner/expression_binder/order_binder.hpp +3 -3
  88. package/src/duckdb/src/include/duckdb/storage/buffer/block_handle.hpp +10 -2
  89. package/src/duckdb/src/include/duckdb/storage/buffer/buffer_pool.hpp +1 -0
  90. package/src/duckdb/src/include/duckdb/storage/buffer_manager.hpp +49 -126
  91. package/src/duckdb/src/include/duckdb/storage/meta_block_reader.hpp +5 -5
  92. package/src/duckdb/src/include/duckdb/storage/standard_buffer_manager.hpp +159 -0
  93. package/src/duckdb/src/include/duckdb/storage/table/column_segment.hpp +1 -0
  94. package/src/duckdb/src/include/duckdb/transaction/meta_transaction.hpp +6 -5
  95. package/src/duckdb/src/main/client_context.cpp +1 -1
  96. package/src/duckdb/src/main/database.cpp +2 -1
  97. package/src/duckdb/src/main/database_manager.cpp +4 -4
  98. package/src/duckdb/src/optimizer/common_aggregate_optimizer.cpp +2 -2
  99. package/src/duckdb/src/optimizer/cse_optimizer.cpp +4 -4
  100. package/src/duckdb/src/optimizer/deliminator.cpp +13 -11
  101. package/src/duckdb/src/optimizer/expression_rewriter.cpp +2 -2
  102. package/src/duckdb/src/optimizer/filter_combiner.cpp +67 -65
  103. package/src/duckdb/src/optimizer/join_order/cardinality_estimator.cpp +1 -0
  104. package/src/duckdb/src/optimizer/join_order/join_order_optimizer.cpp +26 -25
  105. package/src/duckdb/src/optimizer/matcher/expression_matcher.cpp +23 -21
  106. package/src/duckdb/src/optimizer/rule/arithmetic_simplification.cpp +3 -3
  107. package/src/duckdb/src/optimizer/rule/case_simplification.cpp +2 -2
  108. package/src/duckdb/src/optimizer/rule/comparison_simplification.cpp +6 -7
  109. package/src/duckdb/src/optimizer/rule/conjunction_simplification.cpp +9 -8
  110. package/src/duckdb/src/optimizer/rule/constant_folding.cpp +7 -7
  111. package/src/duckdb/src/optimizer/rule/date_part_simplification.cpp +3 -3
  112. package/src/duckdb/src/optimizer/rule/distributivity.cpp +5 -5
  113. package/src/duckdb/src/optimizer/rule/empty_needle_removal.cpp +6 -6
  114. package/src/duckdb/src/optimizer/rule/enum_comparison.cpp +4 -4
  115. package/src/duckdb/src/optimizer/rule/equal_or_null_simplification.cpp +23 -26
  116. package/src/duckdb/src/optimizer/rule/in_clause_simplification_rule.cpp +2 -3
  117. package/src/duckdb/src/optimizer/rule/like_optimizations.cpp +3 -3
  118. package/src/duckdb/src/optimizer/rule/move_constants.cpp +6 -6
  119. package/src/duckdb/src/optimizer/rule/ordered_aggregate_optimizer.cpp +2 -2
  120. package/src/duckdb/src/optimizer/rule/regex_optimizations.cpp +3 -3
  121. package/src/duckdb/src/parser/expression_util.cpp +6 -6
  122. package/src/duckdb/src/parser/transform/helpers/transform_groupby.cpp +3 -3
  123. package/src/duckdb/src/planner/binder/expression/bind_aggregate_expression.cpp +2 -2
  124. package/src/duckdb/src/planner/binder/query_node/bind_select_node.cpp +3 -3
  125. package/src/duckdb/src/planner/binder/query_node/bind_setop_node.cpp +5 -5
  126. package/src/duckdb/src/planner/binder/statement/bind_create_table.cpp +2 -2
  127. package/src/duckdb/src/planner/expression_binder/base_select_binder.cpp +4 -4
  128. package/src/duckdb/src/planner/expression_binder/order_binder.cpp +3 -3
  129. package/src/duckdb/src/storage/buffer/block_handle.cpp +3 -2
  130. package/src/duckdb/src/storage/buffer/block_manager.cpp +3 -1
  131. package/src/duckdb/src/storage/buffer/buffer_handle.cpp +1 -0
  132. package/src/duckdb/src/storage/buffer/buffer_pool_reservation.cpp +3 -0
  133. package/src/duckdb/src/storage/buffer_manager.cpp +35 -726
  134. package/src/duckdb/src/storage/checkpoint_manager.cpp +2 -2
  135. package/src/duckdb/src/storage/meta_block_reader.cpp +6 -5
  136. package/src/duckdb/src/storage/standard_buffer_manager.cpp +801 -0
  137. package/src/duckdb/src/storage/wal_replay.cpp +2 -2
  138. package/src/duckdb/src/transaction/meta_transaction.cpp +13 -13
  139. package/src/duckdb/src/transaction/transaction.cpp +1 -1
  140. package/src/duckdb/src/transaction/transaction_context.cpp +1 -1
  141. package/src/duckdb/ub_src_function_scalar_string.cpp +2 -0
  142. package/src/duckdb/ub_src_storage.cpp +2 -0
@@ -27,23 +27,23 @@ FilterCombiner::FilterCombiner(ClientContext &context) : context(context) {
27
27
  FilterCombiner::FilterCombiner(Optimizer &optimizer) : FilterCombiner(optimizer.context) {
28
28
  }
29
29
 
30
- Expression *FilterCombiner::GetNode(Expression *expr) {
30
+ Expression &FilterCombiner::GetNode(Expression &expr) {
31
31
  auto entry = stored_expressions.find(expr);
32
32
  if (entry != stored_expressions.end()) {
33
33
  // expression already exists: return a reference to the stored expression
34
- return entry->second.get();
34
+ return *entry->second;
35
35
  }
36
36
  // expression does not exist yet: create a copy and store it
37
- auto copy = expr->Copy();
38
- auto pointer_copy = copy.get();
39
- D_ASSERT(stored_expressions.find(pointer_copy) == stored_expressions.end());
40
- stored_expressions.insert(make_pair(pointer_copy, std::move(copy)));
41
- return pointer_copy;
37
+ auto copy = expr.Copy();
38
+ auto &copy_ref = *copy;
39
+ D_ASSERT(stored_expressions.find(copy_ref) == stored_expressions.end());
40
+ stored_expressions[copy_ref] = std::move(copy);
41
+ return copy_ref;
42
42
  }
43
43
 
44
- idx_t FilterCombiner::GetEquivalenceSet(Expression *expr) {
44
+ idx_t FilterCombiner::GetEquivalenceSet(Expression &expr) {
45
45
  D_ASSERT(stored_expressions.find(expr) != stored_expressions.end());
46
- D_ASSERT(stored_expressions.find(expr)->second.get() == expr);
46
+ D_ASSERT(stored_expressions.find(expr)->second.get() == &expr);
47
47
  auto entry = equivalence_set_map.find(expr);
48
48
  if (entry == equivalence_set_map.end()) {
49
49
  idx_t index = set_index++;
@@ -88,7 +88,7 @@ FilterResult FilterCombiner::AddConstantComparison(vector<ExpressionValueInforma
88
88
  FilterResult FilterCombiner::AddFilter(unique_ptr<Expression> expr) {
89
89
  // LookUpConjunctions(expr.get());
90
90
  // try to push the filter into the combiner
91
- auto result = AddFilter(expr.get());
91
+ auto result = AddFilter(*expr);
92
92
  if (result == FilterResult::UNSUPPORTED) {
93
93
  // unsupported filter, push into remaining filters
94
94
  remaining_filters.push_back(std::move(expr));
@@ -111,8 +111,8 @@ void FilterCombiner::GenerateFilters(const std::function<void(unique_ptr<Express
111
111
  // for each entry generate an equality expression comparing to each other
112
112
  for (idx_t i = 0; i < entries.size(); i++) {
113
113
  for (idx_t k = i + 1; k < entries.size(); k++) {
114
- auto comparison = make_uniq<BoundComparisonExpression>(ExpressionType::COMPARE_EQUAL,
115
- entries[i]->Copy(), entries[k]->Copy());
114
+ auto comparison = make_uniq<BoundComparisonExpression>(
115
+ ExpressionType::COMPARE_EQUAL, entries[i].get().Copy(), entries[k].get().Copy());
116
116
  callback(std::move(comparison));
117
117
  }
118
118
  // for each entry also create a comparison with each constant
@@ -132,8 +132,8 @@ void FilterCombiner::GenerateFilters(const std::function<void(unique_ptr<Express
132
132
  upper_inclusive = info.comparison_type == ExpressionType::COMPARE_LESSTHANOREQUALTO;
133
133
  } else {
134
134
  auto constant = make_uniq<BoundConstantExpression>(info.constant);
135
- auto comparison = make_uniq<BoundComparisonExpression>(info.comparison_type, entries[i]->Copy(),
136
- std::move(constant));
135
+ auto comparison = make_uniq<BoundComparisonExpression>(
136
+ info.comparison_type, entries[i].get().Copy(), std::move(constant));
137
137
  callback(std::move(comparison));
138
138
  }
139
139
  }
@@ -142,20 +142,20 @@ void FilterCombiner::GenerateFilters(const std::function<void(unique_ptr<Express
142
142
  auto lower_constant = make_uniq<BoundConstantExpression>(constant_list[lower_index].constant);
143
143
  auto upper_constant = make_uniq<BoundConstantExpression>(constant_list[upper_index].constant);
144
144
  auto between =
145
- make_uniq<BoundBetweenExpression>(entries[i]->Copy(), std::move(lower_constant),
145
+ make_uniq<BoundBetweenExpression>(entries[i].get().Copy(), std::move(lower_constant),
146
146
  std::move(upper_constant), lower_inclusive, upper_inclusive);
147
147
  callback(std::move(between));
148
148
  } else if (lower_index >= 0) {
149
149
  // only lower index found, create simple comparison expression
150
150
  auto constant = make_uniq<BoundConstantExpression>(constant_list[lower_index].constant);
151
151
  auto comparison = make_uniq<BoundComparisonExpression>(constant_list[lower_index].comparison_type,
152
- entries[i]->Copy(), std::move(constant));
152
+ entries[i].get().Copy(), std::move(constant));
153
153
  callback(std::move(comparison));
154
154
  } else if (upper_index >= 0) {
155
155
  // only upper index found, create simple comparison expression
156
156
  auto constant = make_uniq<BoundConstantExpression>(constant_list[upper_index].constant);
157
157
  auto comparison = make_uniq<BoundComparisonExpression>(constant_list[upper_index].comparison_type,
158
- entries[i]->Copy(), std::move(constant));
158
+ entries[i].get().Copy(), std::move(constant));
159
159
  callback(std::move(comparison));
160
160
  }
161
161
  }
@@ -407,9 +407,10 @@ TableFilterSet FilterCombiner::GenerateTableScanFilters(vector<idx_t> &column_id
407
407
  constant_value.second[0].constant.type().InternalType() == PhysicalType::BOOL)) {
408
408
  //! Here we check if these filters are column references
409
409
  filter_exp = equivalence_map.find(constant_value.first);
410
- if (filter_exp->second.size() == 1 && filter_exp->second[0]->type == ExpressionType::BOUND_COLUMN_REF) {
411
- auto filter_col_exp = static_cast<BoundColumnRefExpression *>(filter_exp->second[0]);
412
- auto column_index = column_ids[filter_col_exp->binding.column_index];
410
+ if (filter_exp->second.size() == 1 &&
411
+ filter_exp->second[0].get().type == ExpressionType::BOUND_COLUMN_REF) {
412
+ auto &filter_col_exp = filter_exp->second[0].get().Cast<BoundColumnRefExpression>();
413
+ auto column_index = column_ids[filter_col_exp.binding.column_index];
413
414
  if (column_index == COLUMN_IDENTIFIER_ROW_ID) {
414
415
  break;
415
416
  }
@@ -572,8 +573,8 @@ static bool IsLessThan(ExpressionType type) {
572
573
  return type == ExpressionType::COMPARE_LESSTHAN || type == ExpressionType::COMPARE_LESSTHANOREQUALTO;
573
574
  }
574
575
 
575
- FilterResult FilterCombiner::AddBoundComparisonFilter(Expression *expr) {
576
- auto &comparison = expr->Cast<BoundComparisonExpression>();
576
+ FilterResult FilterCombiner::AddBoundComparisonFilter(Expression &expr) {
577
+ auto &comparison = expr.Cast<BoundComparisonExpression>();
577
578
  if (comparison.type != ExpressionType::COMPARE_LESSTHAN &&
578
579
  comparison.type != ExpressionType::COMPARE_LESSTHANOREQUALTO &&
579
580
  comparison.type != ExpressionType::COMPARE_GREATERTHAN &&
@@ -587,9 +588,9 @@ FilterResult FilterCombiner::AddBoundComparisonFilter(Expression *expr) {
587
588
  bool right_is_scalar = comparison.right->IsFoldable();
588
589
  if (left_is_scalar || right_is_scalar) {
589
590
  // comparison with scalar
590
- auto node = GetNode(left_is_scalar ? comparison.right.get() : comparison.left.get());
591
+ auto &node = GetNode(left_is_scalar ? *comparison.right : *comparison.left);
591
592
  idx_t equivalence_set = GetEquivalenceSet(node);
592
- auto scalar = left_is_scalar ? comparison.left.get() : comparison.right.get();
593
+ auto &scalar = left_is_scalar ? comparison.left : comparison.right;
593
594
  Value constant_value;
594
595
  if (!ExpressionExecutor::TryEvaluateScalar(context, *scalar, constant_value)) {
595
596
  return FilterResult::UNSATISFIABLE;
@@ -607,11 +608,11 @@ FilterResult FilterCombiner::AddBoundComparisonFilter(Expression *expr) {
607
608
  // get the current bucket of constant values
608
609
  D_ASSERT(constant_values.find(equivalence_set) != constant_values.end());
609
610
  auto &info_list = constant_values.find(equivalence_set)->second;
610
- D_ASSERT(node->return_type == info.constant.type());
611
+ D_ASSERT(node.return_type == info.constant.type());
611
612
  // check the existing constant comparisons to see if we can do any pruning
612
613
  auto ret = AddConstantComparison(info_list, info);
613
614
 
614
- auto non_scalar = left_is_scalar ? comparison.right.get() : comparison.left.get();
615
+ auto &non_scalar = left_is_scalar ? *comparison.right : *comparison.left;
615
616
  auto transitive_filter = FindTransitiveFilter(non_scalar);
616
617
  if (transitive_filter != nullptr) {
617
618
  // try to add transitive filters
@@ -625,16 +626,16 @@ FilterResult FilterCombiner::AddBoundComparisonFilter(Expression *expr) {
625
626
  } else {
626
627
  // comparison between two non-scalars
627
628
  // only handle comparisons for now
628
- if (expr->type != ExpressionType::COMPARE_EQUAL) {
629
- if (IsGreaterThan(expr->type) || IsLessThan(expr->type)) {
629
+ if (expr.type != ExpressionType::COMPARE_EQUAL) {
630
+ if (IsGreaterThan(expr.type) || IsLessThan(expr.type)) {
630
631
  return AddTransitiveFilters(comparison);
631
632
  }
632
633
  return FilterResult::UNSUPPORTED;
633
634
  }
634
635
  // get the LHS and RHS nodes
635
- auto left_node = GetNode(comparison.left.get());
636
- auto right_node = GetNode(comparison.right.get());
637
- if (BaseExpression::Equals(left_node, right_node)) {
636
+ auto &left_node = GetNode(*comparison.left);
637
+ auto &right_node = GetNode(*comparison.right);
638
+ if (left_node.Equals(&right_node)) {
638
639
  return FilterResult::UNSUPPORTED;
639
640
  }
640
641
  // get the equivalence sets of the LHS and RHS
@@ -650,19 +651,19 @@ FilterResult FilterCombiner::AddBoundComparisonFilter(Expression *expr) {
650
651
 
651
652
  auto &left_bucket = equivalence_map.find(left_equivalence_set)->second;
652
653
  auto &right_bucket = equivalence_map.find(right_equivalence_set)->second;
653
- for (auto &i : right_bucket) {
654
+ for (auto &right_expr : right_bucket) {
654
655
  // rewrite the equivalence set mapping for this node
655
- equivalence_set_map[i] = left_equivalence_set;
656
+ equivalence_set_map[right_expr] = left_equivalence_set;
656
657
  // add the node to the left bucket
657
- left_bucket.push_back(i);
658
+ left_bucket.push_back(right_expr);
658
659
  }
659
660
  // now add all constant values from the right bucket to the left bucket
660
661
  D_ASSERT(constant_values.find(left_equivalence_set) != constant_values.end());
661
662
  D_ASSERT(constant_values.find(right_equivalence_set) != constant_values.end());
662
663
  auto &left_constant_bucket = constant_values.find(left_equivalence_set)->second;
663
664
  auto &right_constant_bucket = constant_values.find(right_equivalence_set)->second;
664
- for (auto &i : right_constant_bucket) {
665
- if (AddConstantComparison(left_constant_bucket, i) == FilterResult::UNSATISFIABLE) {
665
+ for (auto &right_constant : right_constant_bucket) {
666
+ if (AddConstantComparison(left_constant_bucket, right_constant) == FilterResult::UNSATISFIABLE) {
666
667
  return FilterResult::UNSATISFIABLE;
667
668
  }
668
669
  }
@@ -670,14 +671,14 @@ FilterResult FilterCombiner::AddBoundComparisonFilter(Expression *expr) {
670
671
  return FilterResult::SUCCESS;
671
672
  }
672
673
 
673
- FilterResult FilterCombiner::AddFilter(Expression *expr) {
674
- if (expr->HasParameter()) {
674
+ FilterResult FilterCombiner::AddFilter(Expression &expr) {
675
+ if (expr.HasParameter()) {
675
676
  return FilterResult::UNSUPPORTED;
676
677
  }
677
- if (expr->IsFoldable()) {
678
+ if (expr.IsFoldable()) {
678
679
  // scalar condition, evaluate it
679
680
  Value result;
680
- if (!ExpressionExecutor::TryEvaluateScalar(context, *expr, result)) {
681
+ if (!ExpressionExecutor::TryEvaluateScalar(context, expr, result)) {
681
682
  return FilterResult::UNSUPPORTED;
682
683
  }
683
684
  result = result.DefaultCastAs(LogicalType::BOOLEAN);
@@ -690,15 +691,15 @@ FilterResult FilterCombiner::AddFilter(Expression *expr) {
690
691
  return FilterResult::SUCCESS;
691
692
  }
692
693
  }
693
- D_ASSERT(!expr->IsFoldable());
694
- if (expr->GetExpressionClass() == ExpressionClass::BOUND_BETWEEN) {
695
- auto &comparison = expr->Cast<BoundBetweenExpression>();
694
+ D_ASSERT(!expr.IsFoldable());
695
+ if (expr.GetExpressionClass() == ExpressionClass::BOUND_BETWEEN) {
696
+ auto &comparison = expr.Cast<BoundBetweenExpression>();
696
697
  //! check if one of the sides is a scalar value
697
698
  bool lower_is_scalar = comparison.lower->IsFoldable();
698
699
  bool upper_is_scalar = comparison.upper->IsFoldable();
699
700
  if (lower_is_scalar || upper_is_scalar) {
700
701
  //! comparison with scalar - break apart
701
- auto node = GetNode(comparison.input.get());
702
+ auto &node = GetNode(*comparison.input);
702
703
  idx_t equivalence_set = GetEquivalenceSet(node);
703
704
  auto result = FilterResult::UNSATISFIABLE;
704
705
 
@@ -730,7 +731,7 @@ FilterResult FilterCombiner::AddFilter(Expression *expr) {
730
731
  auto left = comparison.lower->Copy();
731
732
  auto right = comparison.input->Copy();
732
733
  auto lower_comp = make_uniq<BoundComparisonExpression>(type, std::move(left), std::move(right));
733
- result = AddBoundComparisonFilter(lower_comp.get());
734
+ result = AddBoundComparisonFilter(*lower_comp);
734
735
  }
735
736
 
736
737
  // Stop if we failed
@@ -765,12 +766,12 @@ FilterResult FilterCombiner::AddFilter(Expression *expr) {
765
766
  auto left = comparison.input->Copy();
766
767
  auto right = comparison.upper->Copy();
767
768
  auto upper_comp = make_uniq<BoundComparisonExpression>(type, std::move(left), std::move(right));
768
- result = AddBoundComparisonFilter(upper_comp.get());
769
+ result = AddBoundComparisonFilter(*upper_comp);
769
770
  }
770
771
 
771
772
  return result;
772
773
  }
773
- } else if (expr->GetExpressionClass() == ExpressionClass::BOUND_COMPARISON) {
774
+ } else if (expr.GetExpressionClass() == ExpressionClass::BOUND_COMPARISON) {
774
775
  return AddBoundComparisonFilter(expr);
775
776
  }
776
777
  // only comparisons supported for now
@@ -784,20 +785,20 @@ FilterResult FilterCombiner::AddFilter(Expression *expr) {
784
785
  FilterResult FilterCombiner::AddTransitiveFilters(BoundComparisonExpression &comparison) {
785
786
  D_ASSERT(IsGreaterThan(comparison.type) || IsLessThan(comparison.type));
786
787
  // get the LHS and RHS nodes
787
- Expression *left_node = GetNode(comparison.left.get());
788
- Expression *right_node = GetNode(comparison.right.get());
788
+ auto &left_node = GetNode(*comparison.left);
789
+ reference<Expression> right_node = GetNode(*comparison.right);
789
790
  // In case with filters like CAST(i) = j and i = 5 we replace the COLUMN_REF i with the constant 5
790
- if (right_node->type == ExpressionType::OPERATOR_CAST) {
791
- auto &bound_cast_expr = right_node->Cast<BoundCastExpression>();
791
+ if (right_node.get().type == ExpressionType::OPERATOR_CAST) {
792
+ auto &bound_cast_expr = right_node.get().Cast<BoundCastExpression>();
792
793
  if (bound_cast_expr.child->type == ExpressionType::BOUND_COLUMN_REF) {
793
794
  auto &col_ref = bound_cast_expr.child->Cast<BoundColumnRefExpression>();
794
795
  for (auto &stored_exp : stored_expressions) {
795
- if (stored_exp.first->type == ExpressionType::BOUND_COLUMN_REF) {
796
+ if (stored_exp.first.get().type == ExpressionType::BOUND_COLUMN_REF) {
796
797
  auto &st_col_ref = stored_exp.second->Cast<BoundColumnRefExpression>();
797
798
  if (st_col_ref.binding == col_ref.binding &&
798
799
  bound_cast_expr.return_type == stored_exp.second->return_type) {
799
800
  bound_cast_expr.child = stored_exp.second->Copy();
800
- right_node = GetNode(bound_cast_expr.child.get());
801
+ right_node = GetNode(*bound_cast_expr.child);
801
802
  break;
802
803
  }
803
804
  }
@@ -805,7 +806,7 @@ FilterResult FilterCombiner::AddTransitiveFilters(BoundComparisonExpression &com
805
806
  }
806
807
  }
807
808
 
808
- if (BaseExpression::Equals(left_node, right_node)) {
809
+ if (left_node.Equals(&right_node.get())) {
809
810
  return FilterResult::UNSUPPORTED;
810
811
  }
811
812
  // get the equivalence sets of the LHS and RHS
@@ -874,7 +875,7 @@ FilterResult FilterCombiner::AddTransitiveFilters(BoundComparisonExpression &com
874
875
  }
875
876
  if (is_successful) {
876
877
  // now check for remaining trasitive filters from the left column
877
- auto transitive_filter = FindTransitiveFilter(comparison.left.get());
878
+ auto transitive_filter = FindTransitiveFilter(*comparison.left);
878
879
  if (transitive_filter != nullptr) {
879
880
  // try to add transitive filters
880
881
  if (AddTransitiveFilters(transitive_filter->Cast<BoundComparisonExpression>()) ==
@@ -894,17 +895,18 @@ FilterResult FilterCombiner::AddTransitiveFilters(BoundComparisonExpression &com
894
895
  * Check for a match between the right column of bound comparisons and the expression,
895
896
  * then removes the bound comparison from the remaining filters and returns it
896
897
  */
897
- unique_ptr<Expression> FilterCombiner::FindTransitiveFilter(Expression *expr) {
898
+ unique_ptr<Expression> FilterCombiner::FindTransitiveFilter(Expression &expr) {
898
899
  // We only check for bound column ref
899
- if (expr->type == ExpressionType::BOUND_COLUMN_REF) {
900
- for (idx_t i = 0; i < remaining_filters.size(); i++) {
901
- if (remaining_filters[i]->GetExpressionClass() == ExpressionClass::BOUND_COMPARISON) {
902
- auto &comparison = remaining_filters[i]->Cast<BoundComparisonExpression>();
903
- if (expr->Equals(comparison.right.get()) && comparison.type != ExpressionType::COMPARE_NOTEQUAL) {
904
- auto filter = std::move(remaining_filters[i]);
905
- remaining_filters.erase(remaining_filters.begin() + i);
906
- return filter;
907
- }
900
+ if (expr.type != ExpressionType::BOUND_COLUMN_REF) {
901
+ return nullptr;
902
+ }
903
+ for (idx_t i = 0; i < remaining_filters.size(); i++) {
904
+ if (remaining_filters[i]->GetExpressionClass() == ExpressionClass::BOUND_COMPARISON) {
905
+ auto &comparison = remaining_filters[i]->Cast<BoundComparisonExpression>();
906
+ if (expr.Equals(comparison.right.get()) && comparison.type != ExpressionType::COMPARE_NOTEQUAL) {
907
+ auto filter = std::move(remaining_filters[i]);
908
+ remaining_filters.erase(remaining_filters.begin() + i);
909
+ return filter;
908
910
  }
909
911
  }
910
912
  }
@@ -105,6 +105,7 @@ void CardinalityEstimator::AddRelationToColumnMapping(ColumnBinding key, ColumnB
105
105
 
106
106
  void CardinalityEstimator::CopyRelationMap(column_binding_map_t<ColumnBinding> &child_binding_map) {
107
107
  for (auto &binding_map : relation_column_to_original_column) {
108
+ D_ASSERT(child_binding_map.find(binding_map.first) == child_binding_map.end());
108
109
  child_binding_map[binding_map.first] = binding_map.second;
109
110
  }
110
111
  }
@@ -96,8 +96,9 @@ static unique_ptr<LogicalOperator> PushFilter(unique_ptr<LogicalOperator> node,
96
96
  bool JoinOrderOptimizer::ExtractJoinRelations(LogicalOperator &input_op, vector<LogicalOperator *> &filter_operators,
97
97
  LogicalOperator *parent) {
98
98
  LogicalOperator *op = &input_op;
99
- while (op->children.size() == 1 && (op->type != LogicalOperatorType::LOGICAL_PROJECTION &&
100
- op->type != LogicalOperatorType::LOGICAL_EXPRESSION_GET)) {
99
+ while (op->children.size() == 1 &&
100
+ (op->type != LogicalOperatorType::LOGICAL_PROJECTION &&
101
+ op->type != LogicalOperatorType::LOGICAL_EXPRESSION_GET && op->type != LogicalOperatorType::LOGICAL_GET)) {
101
102
  if (op->type == LogicalOperatorType::LOGICAL_FILTER) {
102
103
  // extract join conditions from filter
103
104
  filter_operators.push_back(op);
@@ -193,18 +194,7 @@ bool JoinOrderOptimizer::ExtractJoinRelations(LogicalOperator &input_op, vector<
193
194
  bool can_reorder_right = ExtractJoinRelations(*op->children[1], filter_operators, op);
194
195
  return can_reorder_left && can_reorder_right;
195
196
  }
196
- case LogicalOperatorType::LOGICAL_GET: {
197
- // base table scan, add to set of relations
198
- auto &get = op->Cast<LogicalGet>();
199
- auto relation = make_uniq<SingleJoinRelation>(&input_op, parent);
200
- idx_t relation_id = relations.size();
201
- //! make sure the optimizer has knowledge of the exact column bindings as well.
202
- auto table_index = get.table_index;
203
- relation_mapping[table_index] = relation_id;
204
- cardinality_estimator.AddRelationColumnMapping(&get, relation_id);
205
- relations.push_back(std::move(relation));
206
- return true;
207
- }
197
+
208
198
  case LogicalOperatorType::LOGICAL_EXPRESSION_GET: {
209
199
  // base table scan, add to set of relations
210
200
  auto &get = op->Cast<LogicalExpressionGet>();
@@ -222,24 +212,35 @@ bool JoinOrderOptimizer::ExtractJoinRelations(LogicalOperator &input_op, vector<
222
212
  relations.push_back(std::move(relation));
223
213
  return true;
224
214
  }
215
+ case LogicalOperatorType::LOGICAL_GET:
225
216
  case LogicalOperatorType::LOGICAL_PROJECTION: {
226
- auto &proj = op->Cast<LogicalProjection>();
217
+ auto table_index = op->GetTableIndex()[0];
218
+ auto relation = make_uniq<SingleJoinRelation>(&input_op, parent);
219
+ auto relation_id = relations.size();
220
+
221
+ // If the children are empty, operator can't ge a logical get.
222
+ if (op->children.empty() && op->type == LogicalOperatorType::LOGICAL_GET) {
223
+ auto &get = op->Cast<LogicalGet>();
224
+ cardinality_estimator.AddRelationColumnMapping(&get, relation_id);
225
+ relation_mapping[table_index] = relation_id;
226
+ relations.push_back(std::move(relation));
227
+ return true;
228
+ }
229
+
227
230
  // we run the join order optimizer within the subquery as well
228
231
  JoinOrderOptimizer optimizer(context);
229
232
  op->children[0] = optimizer.Optimize(std::move(op->children[0]));
230
- // projection, add to the set of relations
231
- auto relation = make_uniq<SingleJoinRelation>(&input_op, parent);
232
- auto relation_id = relations.size();
233
+
233
234
  // push one child column binding map back.
234
235
  vector<column_binding_map_t<ColumnBinding>> child_binding_maps;
235
236
  child_binding_maps.emplace_back();
236
237
  optimizer.cardinality_estimator.CopyRelationMap(child_binding_maps.at(0));
237
- // This logical projection may sit on top of a logical comparison join that has been pushed down
238
+ // This logical projection/get may sit on top of a logical comparison join that has been pushed down
238
239
  // we want to copy the binding info of both tables
239
- relation_mapping[proj.table_index] = relation_id;
240
+ relation_mapping[table_index] = relation_id;
240
241
  for (auto &binding_info : child_binding_maps.at(0)) {
241
242
  cardinality_estimator.AddRelationToColumnMapping(
242
- ColumnBinding(proj.table_index, binding_info.first.column_index), binding_info.second);
243
+ ColumnBinding(table_index, binding_info.first.column_index), binding_info.second);
243
244
  cardinality_estimator.AddColumnToRelationMap(binding_info.second.table_index,
244
245
  binding_info.second.column_index);
245
246
  }
@@ -955,16 +956,16 @@ unique_ptr<LogicalOperator> JoinOrderOptimizer::Optimize(unique_ptr<LogicalOpera
955
956
  for (auto &cond : join.conditions) {
956
957
  auto comparison =
957
958
  make_uniq<BoundComparisonExpression>(cond.comparison, std::move(cond.left), std::move(cond.right));
958
- if (filter_set.find(comparison.get()) == filter_set.end()) {
959
- filter_set.insert(comparison.get());
959
+ if (filter_set.find(*comparison) == filter_set.end()) {
960
+ filter_set.insert(*comparison);
960
961
  filters.push_back(std::move(comparison));
961
962
  }
962
963
  }
963
964
  join.conditions.clear();
964
965
  } else {
965
966
  for (auto &expression : f_op->expressions) {
966
- if (filter_set.find(expression.get()) == filter_set.end()) {
967
- filter_set.insert(expression.get());
967
+ if (filter_set.find(*expression) == filter_set.end()) {
968
+ filter_set.insert(*expression);
968
969
  filters.push_back(std::move(expression));
969
970
  }
970
971
  }
@@ -4,82 +4,84 @@
4
4
 
5
5
  namespace duckdb {
6
6
 
7
- bool ExpressionMatcher::Match(Expression *expr, vector<Expression *> &bindings) {
8
- if (type && !type->Match(expr->return_type)) {
7
+ bool ExpressionMatcher::Match(Expression &expr, vector<reference<Expression>> &bindings) {
8
+ if (type && !type->Match(expr.return_type)) {
9
9
  return false;
10
10
  }
11
- if (expr_type && !expr_type->Match(expr->type)) {
11
+ if (expr_type && !expr_type->Match(expr.type)) {
12
12
  return false;
13
13
  }
14
- if (expr_class != ExpressionClass::INVALID && expr_class != expr->GetExpressionClass()) {
14
+ if (expr_class != ExpressionClass::INVALID && expr_class != expr.GetExpressionClass()) {
15
15
  return false;
16
16
  }
17
17
  bindings.push_back(expr);
18
18
  return true;
19
19
  }
20
20
 
21
- bool ExpressionEqualityMatcher::Match(Expression *expr, vector<Expression *> &bindings) {
22
- if (!Expression::Equals(expression, expr)) {
21
+ bool ExpressionEqualityMatcher::Match(Expression &expr, vector<reference<Expression>> &bindings) {
22
+ if (!expr.Equals(&expression)) {
23
23
  return false;
24
24
  }
25
25
  bindings.push_back(expr);
26
26
  return true;
27
27
  }
28
28
 
29
- bool CaseExpressionMatcher::Match(Expression *expr_p, vector<Expression *> &bindings) {
29
+ bool CaseExpressionMatcher::Match(Expression &expr_p, vector<reference<Expression>> &bindings) {
30
30
  if (!ExpressionMatcher::Match(expr_p, bindings)) {
31
31
  return false;
32
32
  }
33
33
  return true;
34
34
  }
35
35
 
36
- bool ComparisonExpressionMatcher::Match(Expression *expr_p, vector<Expression *> &bindings) {
36
+ bool ComparisonExpressionMatcher::Match(Expression &expr_p, vector<reference<Expression>> &bindings) {
37
37
  if (!ExpressionMatcher::Match(expr_p, bindings)) {
38
38
  return false;
39
39
  }
40
- auto &expr = expr_p->Cast<BoundComparisonExpression>();
41
- vector<Expression *> expressions = {expr.left.get(), expr.right.get()};
40
+ auto &expr = expr_p.Cast<BoundComparisonExpression>();
41
+ vector<reference<Expression>> expressions;
42
+ expressions.push_back(*expr.left);
43
+ expressions.push_back(*expr.right);
42
44
  return SetMatcher::Match(matchers, expressions, bindings, policy);
43
45
  }
44
46
 
45
- bool CastExpressionMatcher::Match(Expression *expr_p, vector<Expression *> &bindings) {
47
+ bool CastExpressionMatcher::Match(Expression &expr_p, vector<reference<Expression>> &bindings) {
46
48
  if (!ExpressionMatcher::Match(expr_p, bindings)) {
47
49
  return false;
48
50
  }
49
51
  if (!matcher) {
50
52
  return true;
51
53
  }
52
- auto &expr = expr_p->Cast<BoundCastExpression>();
53
- return matcher->Match(expr.child.get(), bindings);
54
+ auto &expr = expr_p.Cast<BoundCastExpression>();
55
+ return matcher->Match(*expr.child, bindings);
54
56
  }
55
57
 
56
- bool InClauseExpressionMatcher::Match(Expression *expr_p, vector<Expression *> &bindings) {
58
+ bool InClauseExpressionMatcher::Match(Expression &expr_p, vector<reference<Expression>> &bindings) {
57
59
  if (!ExpressionMatcher::Match(expr_p, bindings)) {
58
60
  return false;
59
61
  }
60
- auto &expr = expr_p->Cast<BoundOperatorExpression>();
62
+ auto &expr = expr_p.Cast<BoundOperatorExpression>();
61
63
  if (expr.type != ExpressionType::COMPARE_IN || expr.type == ExpressionType::COMPARE_NOT_IN) {
62
64
  return false;
63
65
  }
64
66
  return SetMatcher::Match(matchers, expr.children, bindings, policy);
65
67
  }
66
68
 
67
- bool ConjunctionExpressionMatcher::Match(Expression *expr_p, vector<Expression *> &bindings) {
69
+ bool ConjunctionExpressionMatcher::Match(Expression &expr_p, vector<reference<Expression>> &bindings) {
68
70
  if (!ExpressionMatcher::Match(expr_p, bindings)) {
69
71
  return false;
70
72
  }
71
- auto &expr = expr_p->Cast<BoundConjunctionExpression>();
73
+ auto &expr = expr_p.Cast<BoundConjunctionExpression>();
72
74
  if (!SetMatcher::Match(matchers, expr.children, bindings, policy)) {
73
75
  return false;
74
76
  }
75
77
  return true;
76
78
  }
77
79
 
78
- bool FunctionExpressionMatcher::Match(Expression *expr_p, vector<Expression *> &bindings) {
80
+ bool FunctionExpressionMatcher::Match(Expression &expr_p, vector<reference<Expression>> &bindings) {
79
81
  if (!ExpressionMatcher::Match(expr_p, bindings)) {
80
82
  return false;
81
83
  }
82
- auto &expr = expr_p->Cast<BoundFunctionExpression>();
84
+ auto &expr = expr_p.Cast<BoundFunctionExpression>();
83
85
  if (!FunctionMatcher::Match(function, expr.function.name)) {
84
86
  return false;
85
87
  }
@@ -89,9 +91,9 @@ bool FunctionExpressionMatcher::Match(Expression *expr_p, vector<Expression *> &
89
91
  return true;
90
92
  }
91
93
 
92
- bool FoldableConstantMatcher::Match(Expression *expr, vector<Expression *> &bindings) {
94
+ bool FoldableConstantMatcher::Match(Expression &expr, vector<reference<Expression>> &bindings) {
93
95
  // we match on ANY expression that is a scalar expression
94
- if (!expr->IsFoldable()) {
96
+ if (!expr.IsFoldable()) {
95
97
  return false;
96
98
  }
97
99
  bindings.push_back(expr);
@@ -22,10 +22,10 @@ ArithmeticSimplificationRule::ArithmeticSimplificationRule(ExpressionRewriter &r
22
22
  root = std::move(op);
23
23
  }
24
24
 
25
- unique_ptr<Expression> ArithmeticSimplificationRule::Apply(LogicalOperator &op, vector<Expression *> &bindings,
25
+ unique_ptr<Expression> ArithmeticSimplificationRule::Apply(LogicalOperator &op, vector<reference<Expression>> &bindings,
26
26
  bool &changes_made, bool is_root) {
27
- auto &root = bindings[0]->Cast<BoundFunctionExpression>();
28
- auto &constant = bindings[1]->Cast<BoundConstantExpression>();
27
+ auto &root = bindings[0].get().Cast<BoundFunctionExpression>();
28
+ auto &constant = bindings[1].get().Cast<BoundConstantExpression>();
29
29
  int constant_child = root.children[0].get() == &constant ? 0 : 1;
30
30
  D_ASSERT(root.children.size() == 2);
31
31
  (void)root;
@@ -11,9 +11,9 @@ CaseSimplificationRule::CaseSimplificationRule(ExpressionRewriter &rewriter) : R
11
11
  root = std::move(op);
12
12
  }
13
13
 
14
- unique_ptr<Expression> CaseSimplificationRule::Apply(LogicalOperator &op, vector<Expression *> &bindings,
14
+ unique_ptr<Expression> CaseSimplificationRule::Apply(LogicalOperator &op, vector<reference<Expression>> &bindings,
15
15
  bool &changes_made, bool is_root) {
16
- auto &root = bindings[0]->Cast<BoundCaseExpression>();
16
+ auto &root = bindings[0].get().Cast<BoundCaseExpression>();
17
17
  for (idx_t i = 0; i < root.case_checks.size(); i++) {
18
18
  auto &case_check = root.case_checks[i];
19
19
  if (case_check.when_expr->IsFoldable()) {
@@ -14,18 +14,17 @@ ComparisonSimplificationRule::ComparisonSimplificationRule(ExpressionRewriter &r
14
14
  root = std::move(op);
15
15
  }
16
16
 
17
- unique_ptr<Expression> ComparisonSimplificationRule::Apply(LogicalOperator &op, vector<Expression *> &bindings,
17
+ unique_ptr<Expression> ComparisonSimplificationRule::Apply(LogicalOperator &op, vector<reference<Expression>> &bindings,
18
18
  bool &changes_made, bool is_root) {
19
- D_ASSERT(bindings[0]->expression_class == ExpressionClass::BOUND_COMPARISON);
20
- auto &expr = bindings[0]->Cast<BoundComparisonExpression>();
21
- auto constant_expr = bindings[1];
22
- bool column_ref_left = expr.left.get() != constant_expr;
19
+ auto &expr = bindings[0].get().Cast<BoundComparisonExpression>();
20
+ auto &constant_expr = bindings[1].get();
21
+ bool column_ref_left = expr.left.get() != &constant_expr;
23
22
  auto column_ref_expr = !column_ref_left ? expr.right.get() : expr.left.get();
24
23
  // the constant_expr is a scalar expression that we have to fold
25
24
  // use an ExpressionExecutor to execute the expression
26
- D_ASSERT(constant_expr->IsFoldable());
25
+ D_ASSERT(constant_expr.IsFoldable());
27
26
  Value constant_value;
28
- if (!ExpressionExecutor::TryEvaluateScalar(GetContext(), *constant_expr, constant_value)) {
27
+ if (!ExpressionExecutor::TryEvaluateScalar(GetContext(), constant_expr, constant_value)) {
29
28
  return nullptr;
30
29
  }
31
30
  if (constant_value.IsNull() && !(expr.type == ExpressionType::COMPARE_NOT_DISTINCT_FROM ||
@@ -15,9 +15,9 @@ ConjunctionSimplificationRule::ConjunctionSimplificationRule(ExpressionRewriter
15
15
  }
16
16
 
17
17
  unique_ptr<Expression> ConjunctionSimplificationRule::RemoveExpression(BoundConjunctionExpression &conj,
18
- Expression *expr) {
18
+ const Expression &expr) {
19
19
  for (idx_t i = 0; i < conj.children.size(); i++) {
20
- if (conj.children[i].get() == expr) {
20
+ if (conj.children[i].get() == &expr) {
21
21
  // erase the expression
22
22
  conj.children.erase(conj.children.begin() + i);
23
23
  break;
@@ -30,15 +30,16 @@ unique_ptr<Expression> ConjunctionSimplificationRule::RemoveExpression(BoundConj
30
30
  return nullptr;
31
31
  }
32
32
 
33
- unique_ptr<Expression> ConjunctionSimplificationRule::Apply(LogicalOperator &op, vector<Expression *> &bindings,
34
- bool &changes_made, bool is_root) {
35
- auto &conjunction = bindings[0]->Cast<BoundConjunctionExpression>();
36
- auto constant_expr = bindings[1];
33
+ unique_ptr<Expression> ConjunctionSimplificationRule::Apply(LogicalOperator &op,
34
+ vector<reference<Expression>> &bindings, bool &changes_made,
35
+ bool is_root) {
36
+ auto &conjunction = bindings[0].get().Cast<BoundConjunctionExpression>();
37
+ auto &constant_expr = bindings[1].get();
37
38
  // the constant_expr is a scalar expression that we have to fold
38
39
  // use an ExpressionExecutor to execute the expression
39
- D_ASSERT(constant_expr->IsFoldable());
40
+ D_ASSERT(constant_expr.IsFoldable());
40
41
  Value constant_value;
41
- if (!ExpressionExecutor::TryEvaluateScalar(GetContext(), *constant_expr, constant_value)) {
42
+ if (!ExpressionExecutor::TryEvaluateScalar(GetContext(), constant_expr, constant_value)) {
42
43
  return nullptr;
43
44
  }
44
45
  constant_value = constant_value.DefaultCastAs(LogicalType::BOOLEAN);