| 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 |