duckdb 0.7.2-dev1803.0 → 0.7.2-dev1898.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.
- package/package.json +1 -1
- package/src/duckdb/src/catalog/catalog.cpp +27 -27
- package/src/duckdb/src/catalog/catalog_entry/duck_schema_entry.cpp +6 -6
- package/src/duckdb/src/catalog/catalog_set.cpp +27 -25
- package/src/duckdb/src/catalog/default/default_functions.cpp +6 -6
- package/src/duckdb/src/catalog/default/default_types.cpp +4 -4
- package/src/duckdb/src/catalog/default/default_views.cpp +4 -4
- package/src/duckdb/src/catalog/dependency_list.cpp +7 -6
- package/src/duckdb/src/catalog/dependency_manager.cpp +44 -38
- package/src/duckdb/src/common/serializer/buffered_file_reader.cpp +11 -6
- package/src/duckdb/src/common/sort/sorted_block.cpp +9 -4
- package/src/duckdb/src/common/types/batched_data_collection.cpp +2 -1
- package/src/duckdb/src/common/types/column_data_allocator.cpp +1 -0
- package/src/duckdb/src/common/types/vector.cpp +2 -2
- package/src/duckdb/src/common/vector_operations/vector_copy.cpp +14 -11
- package/src/duckdb/src/execution/operator/aggregate/distinct_aggregate_data.cpp +1 -1
- package/src/duckdb/src/execution/operator/aggregate/physical_window.cpp +51 -50
- package/src/duckdb/src/execution/operator/join/physical_iejoin.cpp +4 -0
- package/src/duckdb/src/execution/operator/persistent/physical_batch_insert.cpp +14 -13
- package/src/duckdb/src/execution/operator/persistent/physical_insert.cpp +20 -20
- package/src/duckdb/src/execution/operator/schema/physical_create_table.cpp +2 -2
- package/src/duckdb/src/execution/physical_plan/plan_create_index.cpp +1 -1
- package/src/duckdb/src/execution/physical_plan/plan_create_table.cpp +3 -3
- package/src/duckdb/src/execution/physical_plan/plan_delete.cpp +1 -1
- package/src/duckdb/src/execution/physical_plan/plan_insert.cpp +1 -1
- package/src/duckdb/src/execution/physical_plan/plan_update.cpp +1 -1
- package/src/duckdb/src/function/aggregate/sorted_aggregate_function.cpp +172 -63
- package/src/duckdb/src/function/cast/cast_function_set.cpp +2 -1
- package/src/duckdb/src/function/scalar/operators/arithmetic.cpp +15 -9
- package/src/duckdb/src/function/scalar/sequence/nextval.cpp +29 -29
- package/src/duckdb/src/function/scalar/string/damerau_levenshtein.cpp +106 -0
- package/src/duckdb/src/function/scalar/string/regexp.cpp +145 -28
- package/src/duckdb/src/function/scalar/string_functions.cpp +1 -0
- package/src/duckdb/src/function/table/checkpoint.cpp +4 -4
- package/src/duckdb/src/function/table/system/duckdb_columns.cpp +24 -24
- package/src/duckdb/src/function/table/system/duckdb_constraints.cpp +7 -6
- package/src/duckdb/src/function/table/system/duckdb_databases.cpp +1 -1
- package/src/duckdb/src/function/table/system/duckdb_dependencies.cpp +11 -11
- package/src/duckdb/src/function/table/system/pragma_database_size.cpp +1 -1
- package/src/duckdb/src/function/table/system/pragma_table_info.cpp +17 -18
- package/src/duckdb/src/function/table/table_scan.cpp +8 -11
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/include/duckdb/catalog/catalog.hpp +9 -9
- package/src/duckdb/src/include/duckdb/catalog/catalog_entry_map.hpp +38 -0
- package/src/duckdb/src/include/duckdb/catalog/catalog_transaction.hpp +4 -3
- package/src/duckdb/src/include/duckdb/catalog/default/default_functions.hpp +2 -2
- package/src/duckdb/src/include/duckdb/catalog/default/default_types.hpp +2 -2
- package/src/duckdb/src/include/duckdb/catalog/default/default_views.hpp +2 -2
- package/src/duckdb/src/include/duckdb/catalog/dependency.hpp +4 -5
- package/src/duckdb/src/include/duckdb/catalog/dependency_list.hpp +4 -5
- package/src/duckdb/src/include/duckdb/catalog/dependency_manager.hpp +10 -9
- package/src/duckdb/src/include/duckdb/common/allocator.hpp +2 -1
- package/src/duckdb/src/include/duckdb/common/field_writer.hpp +1 -1
- package/src/duckdb/src/include/duckdb/common/helper.hpp +9 -0
- package/src/duckdb/src/include/duckdb/common/optional_ptr.hpp +29 -6
- package/src/duckdb/src/include/duckdb/common/serializer/buffered_file_reader.hpp +6 -5
- package/src/duckdb/src/include/duckdb/common/serializer.hpp +1 -1
- package/src/duckdb/src/include/duckdb/common/types/row_data_collection.hpp +1 -0
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_batch_insert.hpp +2 -2
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_insert.hpp +5 -5
- package/src/duckdb/src/include/duckdb/execution/operator/schema/physical_create_table.hpp +2 -2
- package/src/duckdb/src/include/duckdb/function/cast/default_casts.hpp +3 -2
- package/src/duckdb/src/include/duckdb/function/scalar/string_functions.hpp +4 -0
- package/src/duckdb/src/include/duckdb/main/client_config.hpp +5 -0
- package/src/duckdb/src/include/duckdb/main/database_manager.hpp +4 -3
- package/src/duckdb/src/include/duckdb/main/query_result.hpp +3 -2
- package/src/duckdb/src/include/duckdb/main/settings.hpp +19 -0
- package/src/duckdb/src/include/duckdb/optimizer/filter_combiner.hpp +7 -7
- package/src/duckdb/src/include/duckdb/optimizer/matcher/expression_matcher.hpp +11 -11
- package/src/duckdb/src/include/duckdb/optimizer/matcher/set_matcher.hpp +8 -8
- package/src/duckdb/src/include/duckdb/optimizer/rule/arithmetic_simplification.hpp +1 -1
- package/src/duckdb/src/include/duckdb/optimizer/rule/case_simplification.hpp +1 -1
- package/src/duckdb/src/include/duckdb/optimizer/rule/comparison_simplification.hpp +1 -1
- package/src/duckdb/src/include/duckdb/optimizer/rule/conjunction_simplification.hpp +2 -2
- package/src/duckdb/src/include/duckdb/optimizer/rule/constant_folding.hpp +1 -1
- package/src/duckdb/src/include/duckdb/optimizer/rule/date_part_simplification.hpp +1 -1
- package/src/duckdb/src/include/duckdb/optimizer/rule/distributivity.hpp +1 -1
- package/src/duckdb/src/include/duckdb/optimizer/rule/empty_needle_removal.hpp +1 -1
- package/src/duckdb/src/include/duckdb/optimizer/rule/enum_comparison.hpp +1 -1
- package/src/duckdb/src/include/duckdb/optimizer/rule/equal_or_null_simplification.hpp +1 -1
- package/src/duckdb/src/include/duckdb/optimizer/rule/in_clause_simplification.hpp +1 -1
- package/src/duckdb/src/include/duckdb/optimizer/rule/like_optimizations.hpp +1 -1
- package/src/duckdb/src/include/duckdb/optimizer/rule/move_constants.hpp +1 -1
- package/src/duckdb/src/include/duckdb/optimizer/rule/ordered_aggregate_optimizer.hpp +1 -1
- package/src/duckdb/src/include/duckdb/optimizer/rule/regex_optimizations.hpp +1 -1
- package/src/duckdb/src/include/duckdb/optimizer/rule.hpp +2 -2
- package/src/duckdb/src/include/duckdb/parser/base_expression.hpp +1 -1
- package/src/duckdb/src/include/duckdb/parser/expression_map.hpp +19 -6
- package/src/duckdb/src/include/duckdb/parser/expression_util.hpp +1 -1
- package/src/duckdb/src/include/duckdb/parser/parser.hpp +1 -7
- package/src/duckdb/src/include/duckdb/parser/parser_options.hpp +23 -0
- package/src/duckdb/src/include/duckdb/parser/transformer.hpp +5 -3
- package/src/duckdb/src/include/duckdb/planner/expression.hpp +5 -2
- package/src/duckdb/src/include/duckdb/planner/expression_binder/base_select_binder.hpp +1 -1
- package/src/duckdb/src/include/duckdb/planner/expression_binder/order_binder.hpp +3 -3
- package/src/duckdb/src/include/duckdb/storage/buffer/block_handle.hpp +10 -2
- package/src/duckdb/src/include/duckdb/storage/buffer/buffer_pool.hpp +1 -0
- package/src/duckdb/src/include/duckdb/storage/buffer_manager.hpp +49 -126
- package/src/duckdb/src/include/duckdb/storage/meta_block_reader.hpp +5 -5
- package/src/duckdb/src/include/duckdb/storage/standard_buffer_manager.hpp +159 -0
- package/src/duckdb/src/include/duckdb/storage/table/column_segment.hpp +1 -0
- package/src/duckdb/src/include/duckdb/transaction/meta_transaction.hpp +6 -5
- package/src/duckdb/src/main/client_context.cpp +5 -3
- package/src/duckdb/src/main/config.cpp +2 -0
- package/src/duckdb/src/main/database.cpp +2 -1
- package/src/duckdb/src/main/database_manager.cpp +4 -4
- package/src/duckdb/src/main/settings/settings.cpp +36 -0
- package/src/duckdb/src/optimizer/common_aggregate_optimizer.cpp +2 -2
- package/src/duckdb/src/optimizer/cse_optimizer.cpp +4 -4
- package/src/duckdb/src/optimizer/deliminator.cpp +13 -11
- package/src/duckdb/src/optimizer/expression_rewriter.cpp +2 -2
- package/src/duckdb/src/optimizer/filter_combiner.cpp +67 -65
- package/src/duckdb/src/optimizer/join_order/cardinality_estimator.cpp +1 -0
- package/src/duckdb/src/optimizer/join_order/join_order_optimizer.cpp +26 -25
- package/src/duckdb/src/optimizer/matcher/expression_matcher.cpp +23 -21
- package/src/duckdb/src/optimizer/rule/arithmetic_simplification.cpp +7 -6
- package/src/duckdb/src/optimizer/rule/case_simplification.cpp +2 -2
- package/src/duckdb/src/optimizer/rule/comparison_simplification.cpp +6 -7
- package/src/duckdb/src/optimizer/rule/conjunction_simplification.cpp +9 -8
- package/src/duckdb/src/optimizer/rule/constant_folding.cpp +7 -7
- package/src/duckdb/src/optimizer/rule/date_part_simplification.cpp +3 -3
- package/src/duckdb/src/optimizer/rule/distributivity.cpp +5 -5
- package/src/duckdb/src/optimizer/rule/empty_needle_removal.cpp +6 -6
- package/src/duckdb/src/optimizer/rule/enum_comparison.cpp +4 -4
- package/src/duckdb/src/optimizer/rule/equal_or_null_simplification.cpp +23 -26
- package/src/duckdb/src/optimizer/rule/in_clause_simplification_rule.cpp +2 -3
- package/src/duckdb/src/optimizer/rule/like_optimizations.cpp +3 -3
- package/src/duckdb/src/optimizer/rule/move_constants.cpp +6 -6
- package/src/duckdb/src/optimizer/rule/ordered_aggregate_optimizer.cpp +2 -2
- package/src/duckdb/src/optimizer/rule/regex_optimizations.cpp +3 -3
- package/src/duckdb/src/parser/expression_util.cpp +6 -6
- package/src/duckdb/src/parser/parser.cpp +1 -1
- package/src/duckdb/src/parser/transform/expression/transform_operator.cpp +7 -3
- package/src/duckdb/src/parser/transform/helpers/transform_groupby.cpp +3 -3
- package/src/duckdb/src/parser/transformer.cpp +6 -5
- package/src/duckdb/src/planner/binder/expression/bind_aggregate_expression.cpp +2 -2
- package/src/duckdb/src/planner/binder/query_node/bind_select_node.cpp +3 -3
- package/src/duckdb/src/planner/binder/query_node/bind_setop_node.cpp +5 -5
- package/src/duckdb/src/planner/binder/statement/bind_create_table.cpp +2 -2
- package/src/duckdb/src/planner/expression_binder/base_select_binder.cpp +4 -4
- package/src/duckdb/src/planner/expression_binder/order_binder.cpp +3 -3
- package/src/duckdb/src/storage/buffer/block_handle.cpp +3 -2
- package/src/duckdb/src/storage/buffer/block_manager.cpp +3 -1
- package/src/duckdb/src/storage/buffer/buffer_handle.cpp +1 -0
- package/src/duckdb/src/storage/buffer/buffer_pool_reservation.cpp +3 -0
- package/src/duckdb/src/storage/buffer_manager.cpp +35 -726
- package/src/duckdb/src/storage/checkpoint_manager.cpp +2 -2
- package/src/duckdb/src/storage/meta_block_reader.cpp +6 -5
- package/src/duckdb/src/storage/standard_buffer_manager.cpp +801 -0
- package/src/duckdb/src/storage/wal_replay.cpp +2 -2
- package/src/duckdb/src/transaction/meta_transaction.cpp +13 -13
- package/src/duckdb/src/transaction/transaction.cpp +1 -1
- package/src/duckdb/src/transaction/transaction_context.cpp +1 -1
- package/src/duckdb/third_party/libpg_query/include/parser/gram.hpp +949 -947
- package/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp +16431 -16385
- package/src/duckdb/third_party/libpg_query/src_backend_parser_scan.cpp +503 -493
- package/src/duckdb/ub_src_function_scalar_string.cpp +2 -0
- package/src/duckdb/ub_src_storage.cpp +2 -0
@@ -60,10 +60,10 @@ void CommonSubExpressionOptimizer::CountExpressions(Expression &expr, CSEReplace
|
|
60
60
|
}
|
61
61
|
if (expr.expression_class != ExpressionClass::BOUND_AGGREGATE && !expr.HasSideEffects()) {
|
62
62
|
// we can't move aggregates to a projection, so we only consider the children of the aggregate
|
63
|
-
auto node = state.expression_count.find(
|
63
|
+
auto node = state.expression_count.find(expr);
|
64
64
|
if (node == state.expression_count.end()) {
|
65
65
|
// first time we encounter this expression, insert this node with [count = 1]
|
66
|
-
state.expression_count[
|
66
|
+
state.expression_count[expr] = CSENode();
|
67
67
|
} else {
|
68
68
|
// we encountered this expression before, increment the occurrence count
|
69
69
|
node->second.count++;
|
@@ -95,8 +95,8 @@ void CommonSubExpressionOptimizer::PerformCSEReplacement(unique_ptr<Expression>
|
|
95
95
|
// check if this child is eligible for CSE elimination
|
96
96
|
bool can_cse = expr.expression_class != ExpressionClass::BOUND_CONJUNCTION &&
|
97
97
|
expr.expression_class != ExpressionClass::BOUND_CASE;
|
98
|
-
if (can_cse && state.expression_count.find(
|
99
|
-
auto &node = state.expression_count[
|
98
|
+
if (can_cse && state.expression_count.find(expr) != state.expression_count.end()) {
|
99
|
+
auto &node = state.expression_count[expr];
|
100
100
|
if (node.count > 1) {
|
101
101
|
// this expression occurs more than once! push it into the projection
|
102
102
|
// check if it has already been pushed into the projection
|
@@ -106,8 +106,10 @@ void DeliminatorPlanUpdater::VisitOperator(LogicalOperator &op) {
|
|
106
106
|
}
|
107
107
|
|
108
108
|
void DeliminatorPlanUpdater::VisitExpression(unique_ptr<Expression> *expression) {
|
109
|
-
|
110
|
-
|
109
|
+
auto &expr = **expression;
|
110
|
+
auto entry = expr_map.find(expr);
|
111
|
+
if (entry != expr_map.end()) {
|
112
|
+
*expression = entry->second->Copy();
|
111
113
|
} else {
|
112
114
|
VisitExpressionChildren(**expression);
|
113
115
|
}
|
@@ -207,17 +209,17 @@ bool Deliminator::RemoveCandidate(unique_ptr<LogicalOperator> *plan, unique_ptr<
|
|
207
209
|
}
|
208
210
|
// check if joining with the DelimGet is redundant, and collect relevant column information
|
209
211
|
bool all_equality_conditions = true;
|
210
|
-
vector<Expression
|
212
|
+
vector<reference<Expression>> nulls_are_not_equal_exprs;
|
211
213
|
for (auto &cond : join.conditions) {
|
212
214
|
all_equality_conditions = all_equality_conditions && IsEqualityJoinCondition(cond);
|
213
|
-
auto delim_side = delim_idx == 0 ? cond.left
|
214
|
-
auto other_side = delim_idx == 0 ? cond.right
|
215
|
-
if (delim_side
|
215
|
+
auto &delim_side = delim_idx == 0 ? *cond.left : *cond.right;
|
216
|
+
auto &other_side = delim_idx == 0 ? *cond.right : *cond.left;
|
217
|
+
if (delim_side.type != ExpressionType::BOUND_COLUMN_REF) {
|
216
218
|
// non-colref e.g. expression -(4, 1) in 4-i=j where i is from DelimGet
|
217
219
|
// FIXME: might be possible to also eliminate these
|
218
220
|
return false;
|
219
221
|
}
|
220
|
-
updater.expr_map[delim_side] = other_side;
|
222
|
+
updater.expr_map[delim_side] = &other_side;
|
221
223
|
if (cond.comparison != ExpressionType::COMPARE_NOT_DISTINCT_FROM) {
|
222
224
|
nulls_are_not_equal_exprs.push_back(other_side);
|
223
225
|
}
|
@@ -229,7 +231,7 @@ bool Deliminator::RemoveCandidate(unique_ptr<LogicalOperator> *plan, unique_ptr<
|
|
229
231
|
updater.projection_map[cb] = true;
|
230
232
|
updater.reverse_proj_or_agg_map[cb] = proj_or_agg.expressions[cb.column_index].get();
|
231
233
|
for (auto &expr : nulls_are_not_equal_exprs) {
|
232
|
-
if (proj_or_agg.expressions[cb.column_index]->Equals(expr)) {
|
234
|
+
if (proj_or_agg.expressions[cb.column_index]->Equals(&expr.get())) {
|
233
235
|
updater.projection_map[cb] = false;
|
234
236
|
break;
|
235
237
|
}
|
@@ -252,8 +254,8 @@ bool Deliminator::RemoveCandidate(unique_ptr<LogicalOperator> *plan, unique_ptr<
|
|
252
254
|
updater.projection_map[cb] = true;
|
253
255
|
updater.reverse_proj_or_agg_map[cb] = all_agg_exprs[cb.column_index];
|
254
256
|
for (auto &expr : nulls_are_not_equal_exprs) {
|
255
|
-
if ((cb.table_index == agg.group_index && agg.groups[cb.column_index]->Equals(expr)) ||
|
256
|
-
(cb.table_index == agg.aggregate_index && agg.expressions[cb.column_index]->Equals(expr))) {
|
257
|
+
if ((cb.table_index == agg.group_index && agg.groups[cb.column_index]->Equals(&expr.get())) ||
|
258
|
+
(cb.table_index == agg.aggregate_index && agg.expressions[cb.column_index]->Equals(&expr.get()))) {
|
257
259
|
updater.projection_map[cb] = false;
|
258
260
|
break;
|
259
261
|
}
|
@@ -276,7 +278,7 @@ bool Deliminator::RemoveCandidate(unique_ptr<LogicalOperator> *plan, unique_ptr<
|
|
276
278
|
for (auto &expr : nulls_are_not_equal_exprs) {
|
277
279
|
auto is_not_null_expr =
|
278
280
|
make_uniq<BoundOperatorExpression>(ExpressionType::OPERATOR_IS_NOT_NULL, LogicalType::BOOLEAN);
|
279
|
-
is_not_null_expr->children.push_back(expr
|
281
|
+
is_not_null_expr->children.push_back(expr.get().Copy());
|
280
282
|
filter_op->expressions.push_back(std::move(is_not_null_expr));
|
281
283
|
}
|
282
284
|
}
|
@@ -12,8 +12,8 @@ namespace duckdb {
|
|
12
12
|
unique_ptr<Expression> ExpressionRewriter::ApplyRules(LogicalOperator &op, const vector<Rule *> &rules,
|
13
13
|
unique_ptr<Expression> expr, bool &changes_made, bool is_root) {
|
14
14
|
for (auto &rule : rules) {
|
15
|
-
vector<Expression
|
16
|
-
if (rule->root->Match(expr
|
15
|
+
vector<reference<Expression>> bindings;
|
16
|
+
if (rule->root->Match(*expr, bindings)) {
|
17
17
|
// the rule matches! try to apply it
|
18
18
|
bool rule_made_change = false;
|
19
19
|
auto result = rule->Apply(op, bindings, rule_made_change, is_root);
|
@@ -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
|
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
|
34
|
+
return *entry->second;
|
35
35
|
}
|
36
36
|
// expression does not exist yet: create a copy and store it
|
37
|
-
auto copy = expr
|
38
|
-
auto
|
39
|
-
D_ASSERT(stored_expressions.find(
|
40
|
-
stored_expressions
|
41
|
-
return
|
37
|
+
auto copy = expr.Copy();
|
38
|
+
auto ©_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
|
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
|
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>(
|
115
|
-
|
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>(
|
136
|
-
|
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]
|
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]
|
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]
|
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 &&
|
411
|
-
|
412
|
-
auto
|
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
|
576
|
-
auto &comparison = expr
|
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
|
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
|
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
|
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
|
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
|
629
|
-
if (IsGreaterThan(expr
|
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
|
636
|
-
auto right_node = GetNode(comparison.right
|
637
|
-
if (
|
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 &
|
654
|
+
for (auto &right_expr : right_bucket) {
|
654
655
|
// rewrite the equivalence set mapping for this node
|
655
|
-
equivalence_set_map[
|
656
|
+
equivalence_set_map[right_expr] = left_equivalence_set;
|
656
657
|
// add the node to the left bucket
|
657
|
-
left_bucket.push_back(
|
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 &
|
665
|
-
if (AddConstantComparison(left_constant_bucket,
|
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
|
674
|
-
if (expr
|
674
|
+
FilterResult FilterCombiner::AddFilter(Expression &expr) {
|
675
|
+
if (expr.HasParameter()) {
|
675
676
|
return FilterResult::UNSUPPORTED;
|
676
677
|
}
|
677
|
-
if (expr
|
678
|
+
if (expr.IsFoldable()) {
|
678
679
|
// scalar condition, evaluate it
|
679
680
|
Value result;
|
680
|
-
if (!ExpressionExecutor::TryEvaluateScalar(context,
|
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
|
694
|
-
if (expr
|
695
|
-
auto &comparison = expr
|
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
|
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
|
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
|
769
|
+
result = AddBoundComparisonFilter(*upper_comp);
|
769
770
|
}
|
770
771
|
|
771
772
|
return result;
|
772
773
|
}
|
773
|
-
} else if (expr
|
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
|
-
|
788
|
-
Expression
|
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
|
791
|
-
auto &bound_cast_expr = right_node
|
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
|
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
|
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 (
|
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
|
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
|
898
|
+
unique_ptr<Expression> FilterCombiner::FindTransitiveFilter(Expression &expr) {
|
898
899
|
// We only check for bound column ref
|
899
|
-
if (expr
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
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 &&
|
100
|
-
|
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
|
-
|
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
|
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
|
-
|
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[
|
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(
|
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
|
959
|
-
filter_set.insert(comparison
|
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
|
967
|
-
filter_set.insert(expression
|
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
|
8
|
-
if (type && !type->Match(expr
|
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
|
11
|
+
if (expr_type && !expr_type->Match(expr.type)) {
|
12
12
|
return false;
|
13
13
|
}
|
14
|
-
if (expr_class != ExpressionClass::INVALID && expr_class != expr
|
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
|
22
|
-
if (!
|
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
|
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
|
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
|
41
|
-
vector<Expression
|
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
|
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
|
53
|
-
return matcher->Match(expr.child
|
54
|
+
auto &expr = expr_p.Cast<BoundCastExpression>();
|
55
|
+
return matcher->Match(*expr.child, bindings);
|
54
56
|
}
|
55
57
|
|
56
|
-
bool InClauseExpressionMatcher::Match(Expression
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
96
|
+
if (!expr.IsFoldable()) {
|
95
97
|
return false;
|
96
98
|
}
|
97
99
|
bindings.push_back(expr);
|