prestodb/presto · warning · PrestoException
CLICKHOUSE_PUSHDOWN_UNSUPPORTED_EXPRESSION
CLICKHOUSE_PUSHDOWN_UNSUPPORTED_EXPRESSION
Error message
is not supported in ClickHouse filter
What it means
ClickHouseFilterExpressionConverter.handleLogicalBinary() only supports logical binary operators in LOGICAL_BINARY_OPS_FILTER (AND/OR). When the converter visits a logical binary CallExpression with an operator outside that set, it throws CLICKHOUSE_PUSHDOWN_UNSUPPORTED_EXPRESSION telling the optimizer this filter cannot be translated to ClickHouse SQL.
Source
Thrown at presto-clickhouse/src/main/java/com/facebook/presto/plugin/clickhouse/optimization/ClickHouseFilterExpressionConverter.java:90
SpecialFormExpression specialForm,
boolean isWhitelist,
Function<VariableReferenceExpression, Selection> context)
{
return derived(format("(%s %s (%s))",
specialForm.getArguments().get(0).accept(this, context).getDefinition(),
isWhitelist ? "IN" : "NOT IN",
specialForm.getArguments().subList(1, specialForm.getArguments().size()).stream()
.map(argument -> argument.accept(this, context).getDefinition())
.collect(Collectors.joining(", "))));
}
private ClickHouseColumnExpression handleLogicalBinary(
String operator,
CallExpression call,
Function<VariableReferenceExpression, Selection> context)
{
if (!LOGICAL_BINARY_OPS_FILTER.contains(operator)) {
throw new PrestoException(CLICKHOUSE_PUSHDOWN_UNSUPPORTED_EXPRESSION, operator + " is not supported in ClickHouse filter");
}
List<RowExpression> arguments = call.getArguments();
if (arguments.size() == 2) {
return derived(format(
"(%s %s %s)",
arguments.get(0).accept(this, context).getDefinition(),
operator,
arguments.get(1).accept(this, context).getDefinition()));
}
throw new PrestoException(CLICKHOUSE_PUSHDOWN_UNSUPPORTED_EXPRESSION, "Unknown logical binary: " + call);
}
private ClickHouseColumnExpression handleBetween(
CallExpression between,
Function<VariableReferenceExpression, Selection> context)
{
if (between.getArguments().size() == 3) {
RowExpression value = between.getArguments().get(0);View on GitHub (pinned to 55bb57d202)
Solutions
- Rewrite the filter using AND/OR (e.g. XOR(a,b) → (a OR b) AND NOT (a AND b))
- Restructure the query so the unsupported logical expression is computed after the pushed-down filter (e.g. in an outer query)
- Disable filter pushdown for this catalog/query so the predicate is evaluated locally
- Upgrade the connector for a wider supported-operator set
Example fix
// before SELECT * FROM ch.db.t WHERE a XOR b; // after SELECT * FROM ch.db.t WHERE (a OR b) AND NOT (a AND b);
Defensive patterns
Strategy: fallback
Validate before calling
// Pre-check filter operators before pushdown
Set<String> supportedLogicalOps = Set.of("AND", "OR");
if (isLogicalBinary(call) && !supportedLogicalOps.contains(operatorOf(call).toUpperCase())) {
log.info("Operator " + operatorOf(call) + " not pushable to ClickHouse; will evaluate locally");
}
Type guard
boolean isClickHousePushableLogicalOp(String operator) {
return Set.of("AND", "OR").contains(operator.toUpperCase(Locale.ENGLISH));
} Try / catch
try {
return expressionConverter.convert(filter);
} catch (PrestoException e) {
if (e.getErrorCode().getCode() == CLICKHOUSE_PUSHDOWN_UNSUPPORTED_EXPRESSION.toErrorCode().getCode()) {
return Optional.empty(); // leave the filter unpushed; evaluate locally
}
throw e;
} Prevention
- Rewrite XOR and exotic boolean functions using AND/OR/NOT
- Structure queries so unsupported expressions sit above the pushed-down filter
- Keep filter pushdown enabled but rely on graceful local evaluation
- Check LOGICAL_BINARY_OPS_FILTER when writing custom logical expressions
When it happens
Trigger: A WHERE clause containing a logical binary expression not in the supported set (e.g. XOR, or an unexpected logical function) that the optimizer attempts to push down to ClickHouse.
Common situations: Queries using XOR or exotic logical functions in filters; planner rewriting expressions into logical calls the converter does not recognize; complex boolean filters produced by view expansion.
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/0770b1cb29b05164.
Report an issue: GitHub.