1 | #include "duckdb/planner/operator/logical_filter.hpp" |
---|---|
2 | |
3 | #include "duckdb/planner/expression/bound_conjunction_expression.hpp" |
4 | |
5 | using namespace duckdb; |
6 | using namespace std; |
7 | |
8 | LogicalFilter::LogicalFilter(unique_ptr<Expression> expression) : LogicalOperator(LogicalOperatorType::FILTER) { |
9 | expressions.push_back(move(expression)); |
10 | SplitPredicates(expressions); |
11 | } |
12 | |
13 | LogicalFilter::LogicalFilter() : LogicalOperator(LogicalOperatorType::FILTER) { |
14 | } |
15 | |
16 | void LogicalFilter::ResolveTypes() { |
17 | types = MapTypes(children[0]->types, projection_map); |
18 | } |
19 | |
20 | vector<ColumnBinding> LogicalFilter::GetColumnBindings() { |
21 | return MapBindings(children[0]->GetColumnBindings(), projection_map); |
22 | } |
23 | |
24 | // Split the predicates separated by AND statements |
25 | // These are the predicates that are safe to push down because all of them MUST |
26 | // be true |
27 | bool LogicalFilter::SplitPredicates(vector<unique_ptr<Expression>> &expressions) { |
28 | bool found_conjunction = false; |
29 | for (idx_t i = 0; i < expressions.size(); i++) { |
30 | if (expressions[i]->type == ExpressionType::CONJUNCTION_AND) { |
31 | auto &conjunction = (BoundConjunctionExpression &)*expressions[i]; |
32 | found_conjunction = true; |
33 | // AND expression, append the other children |
34 | for (idx_t k = 1; k < conjunction.children.size(); k++) { |
35 | expressions.push_back(move(conjunction.children[k])); |
36 | } |
37 | // replace this expression with the first child of the conjunction |
38 | expressions[i] = move(conjunction.children[0]); |
39 | // we move back by one so the right child is checked again |
40 | // in case it is an AND expression as well |
41 | i--; |
42 | } |
43 | } |
44 | return found_conjunction; |
45 | } |
46 |