Skip to content

Commit 28b9150

Browse files
committed
Fix expression filter pushdown
Closes #464
1 parent 4b96717 commit 28b9150

File tree

1 file changed

+28
-1
lines changed

1 file changed

+28
-1
lines changed

src/iceberg_predicate.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "iceberg_predicate.hpp"
2+
#include "duckdb/planner/expression/bound_operator_expression.hpp"
23
#include "duckdb/planner/filter/constant_filter.hpp"
34
#include "duckdb/planner/filter/conjunction_filter.hpp"
45
#include "duckdb/planner/filter/null_filter.hpp"
@@ -80,15 +81,41 @@ bool MatchBoundsTemplated(const TableFilter &filter, const IcebergPredicateStats
8081
return MatchBoundsIsNotNullFilter<TRANSFORM>(stats, transform);
8182
}
8283
case TableFilterType::EXPRESSION_FILTER: {
84+
//! Expressions can be arbitrarily complex, and we currently only support IS NULL/IS NOT NULL checks against the
85+
//! column itself, i.e. where the expression is a BOUND_OPERATOR with type OPERATOR_IS_NULL/_IS_NOT_NULL with a
86+
//! single child expression of type BOUND_REF.
87+
//!
88+
//! See duckdb/duckdb-iceberg#464
8389
auto &expression_filter = filter.Cast<ExpressionFilter>();
8490
auto &expr = *expression_filter.expr;
91+
92+
if (expr.type != ExpressionType::OPERATOR_IS_NULL && expr.type != ExpressionType::OPERATOR_IS_NOT_NULL) {
93+
return true;
94+
}
95+
96+
if (expr.expression_class != ExpressionClass::BOUND_OPERATOR) {
97+
return true;
98+
}
99+
100+
auto &bound_operator_expr = expr.Cast<BoundOperatorExpression>();
101+
if (bound_operator_expr.children.size() != 1) {
102+
return true;
103+
}
104+
105+
auto &child_expr = bound_operator_expr.children[0];
106+
if (child_expr->type != ExpressionType::BOUND_REF) {
107+
return true;
108+
}
109+
85110
if (expr.type == ExpressionType::OPERATOR_IS_NULL) {
86111
return MatchBoundsIsNullFilter<TRANSFORM>(stats, transform);
87112
}
113+
88114
if (expr.type == ExpressionType::OPERATOR_IS_NOT_NULL) {
89115
return MatchBoundsIsNotNullFilter<TRANSFORM>(stats, transform);
90116
}
91-
//! Any other expression can not be filtered
117+
118+
//! Should be unreachable
92119
return true;
93120
}
94121
default:

0 commit comments

Comments
 (0)