prestodb/presto · error · PinotException
PINOT_UNSUPPORTED_EXPRESSION
PINOT_UNSUPPORTED_EXPRESSION
Error message
Don't know how to handle plan node of type
What it means
The default branch of the plan visitor (visitPlan) in PinotQueryGenerator throws PINOT_UNSUPPORTED_EXPRESSION 'Don't know how to handle plan node of type <node>' for any PlanNode type it does not explicitly override. The connector only knows how to translate a fixed set of plan nodes (scan, filter, project, aggregate, top-n, etc.); anything else means it cannot generate a Pinot query for that subtree.
Source
Thrown at presto-pinot-toolkit/src/main/java/com/facebook/presto/pinot/query/PinotQueryGenerator.java:232
class PinotQueryPlanVisitor
extends PlanVisitor<PinotQueryGeneratorContext, PinotQueryGeneratorContext>
{
private final ConnectorSession session;
private final boolean forbidBrokerQueries;
private final boolean pushdownTopnBrokerQueries;
protected PinotQueryPlanVisitor(ConnectorSession session)
{
this.session = session;
this.forbidBrokerQueries = PinotSessionProperties.isForbidBrokerQueries(session);
this.pushdownTopnBrokerQueries = PinotSessionProperties.getPushdownTopnBrokerQueries(session);
}
@Override
public PinotQueryGeneratorContext visitPlan(PlanNode node, PinotQueryGeneratorContext context)
{
throw new PinotException(PINOT_UNSUPPORTED_EXPRESSION, Optional.empty(), "Don't know how to handle plan node of type " + node);
}
protected VariableReferenceExpression getVariableReference(RowExpression expression)
{
if (expression instanceof VariableReferenceExpression) {
return ((VariableReferenceExpression) expression);
}
throw new PinotException(PINOT_UNSUPPORTED_EXPRESSION, Optional.empty(), "Expected a variable reference but got " + expression);
}
@Override
public PinotQueryGeneratorContext visitMarkDistinct(MarkDistinctNode node, PinotQueryGeneratorContext context)
{
requireNonNull(context, "context is null");
return node.getSource().accept(this, context);
}
@OverrideView on GitHub (pinned to 55bb57d202)
Solutions
- Restructure the query so unsupported operations happen above the Pinot subquery: keep pushed-down parts to filters/aggregations/limits on a single table, join or window in an outer query.
- Upgrade the Pinot connector plugin to match your Presto engine version so more plan node types are handled.
- Check which node type the message names and rewrite that specific operation (e.g. replace a WINDOW with LIMIT/GROUP BY the connector supports).
- If the node should be supported, add a visitXxx override in the visitor that translates it or explicitly delegates to Presto execution.
Example fix
// before (join inside the Pinot-subplan triggers the error)
SELECT a.x, b.y FROM pinot_a a JOIN pinot_b b ON a.id = b.id WHERE a.dt = '2026-01-01';
// after (isolate Pinot scans; connector pushes simple filters/aggregations)
WITH s1 AS (SELECT id, x FROM pinot_a WHERE dt = '2026-01-01'),
s2 AS (SELECT id, y FROM pinot_b)
SELECT s1.x, s2.y FROM s1 JOIN s2 ON s1.id = s2.id; Defensive patterns
Strategy: fallback
Validate before calling
-- Inspect the plan before execution and check for node types the pinot connector cannot visit: EXPLAIN ANALYZE? or EXPLAIN <sql>; -- look for Join/Window/RowNumber/Unnest/Union nodes adjacent to the PinotTableScan; -- if present, restructure the query
Try / catch
try {
run(sql);
} catch (PinotException e) {
if (String.valueOf(e.getMessage()).startsWith("Don't know how to handle plan node")) {
// retry with the unsupported operation isolated outside the pinot subplan
run(rewriteToIsolatePinotScan(sql));
} else throw e;
} Prevention
- Keep single-table filters/aggregations/limits in the Pinot subplan; do joins and windows outside
- Run EXPLAIN on new query shapes to see the plan before production
- Keep the pinot plugin version in lockstep with the Presto engine
When it happens
Trigger: The Presto planner produces a plan node the Pinot connector lacks a visit method for — e.g. JoinNode, WindowNode, RowNumberNode, UnionNode, UnnestNode, MarkDistinctNode (partially supported) or other exotic nodes — directly in the part of the plan the connector attempts to convert.
Common situations: Queries with joins/windows/CTEs/unions over Pinot tables that the planner did not isolate from the Pinot scan; new engine features emitting newer node types the connector predates; version mismatch between Presto core and the Pinot plugin.
Related errors
- PINOT_UNSUPPORTED_EXPRESSION
- DRUID_QUERY_GENERATOR_FAILURE
- PINOT_UNSUPPORTED_EXPRESSION
- PINOT_UNSUPPORTED_EXPRESSION
- PINOT_UNSUPPORTED_EXPRESSION
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/1210b5a749d7fff5.
Report an issue: GitHub.