1#include "duckdb/planner/operator/logical_filter.hpp"
2
3#include "duckdb/planner/expression/bound_conjunction_expression.hpp"
4
5using namespace duckdb;
6using namespace std;
7
8LogicalFilter::LogicalFilter(unique_ptr<Expression> expression) : LogicalOperator(LogicalOperatorType::FILTER) {
9 expressions.push_back(move(expression));
10 SplitPredicates(expressions);
11}
12
13LogicalFilter::LogicalFilter() : LogicalOperator(LogicalOperatorType::FILTER) {
14}
15
16void LogicalFilter::ResolveTypes() {
17 types = MapTypes(children[0]->types, projection_map);
18}
19
20vector<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
27bool 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