apache/beam · error · SqlConversionException
Unable to convert query %s
Error message
Unable to convert query %s
What it means
CalciteQueryPlanner.convertToBeamRel() catches RelConversionException and CannotPlanException from Calcite's planning/optimization pipeline and rethrows them as SqlConversionException with the SQL statement. The SQL parsed but Calcite/Beam could not convert the validated relational tree into an executable BeamRelNode — typically an unsupported relational construct or a trait-conversion/planning failure. This signals a planning problem, not a syntax error.
Source
Thrown at sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/CalciteQueryPlanner.java:238
.simplify();
// beam physical plan
relNode
.getCluster()
.setMetadataProvider(
ChainedRelMetadataProvider.of(
ImmutableList.of(
NonCumulativeCostImpl.SOURCE,
RelMdNodeStats.SOURCE,
relNode.getCluster().getMetadataProvider())));
relNode.getCluster().setMetadataQuerySupplier(BeamRelMetadataQuery::instance);
RelMetadataQuery.THREAD_PROVIDERS.set(
JaninoRelMetadataProvider.of(relNode.getCluster().getMetadataProvider()));
relNode.getCluster().invalidateMetadataQuery();
beamRelNode = (BeamRelNode) planner.transform(0, desiredTraits, relNode);
LOG.info("BEAMPlan>\n{}", BeamSqlRelUtils.explainLazily(beamRelNode));
} catch (RelConversionException | CannotPlanException e) {
throw new SqlConversionException(
String.format("Unable to convert query %s", sqlStatement), e);
} catch (SqlParseException | ValidationException e) {
throw new ParseException(String.format("Unable to parse query %s", sqlStatement), e);
} finally {
planner.close();
}
return beamRelNode;
}
private static RelNode bindParameters(RelNode rel, RexShuttle binder) {
RelNode newRel = rel.accept(binder);
java.util.List<RelNode> newInputs = new java.util.ArrayList<>();
for (RelNode input : newRel.getInputs()) {
newInputs.add(bindParameters(input, binder));
}
return newRel.copy(newRel.getTraitSet(), newInputs);
}
View on GitHub (pinned to 12126d8942)
Solutions
- Rewrite the query to avoid the unsupported construct identified in the exception cause.
- Simplify or split the query, computing the unsupported part outside SQL.
- Check Beam SQL supported-features docs for the specific operator.
- Upgrade Beam — unsupported operators are added over time.
Example fix
// before
pipeline.apply(SqlTransform.query("SELECT * FROM t ASOF JOIN u ..."));
// after
pipeline.apply(SqlTransform.query("SELECT * FROM t JOIN u ON t.k = u.k")); Defensive patterns
Strategy: try-catch
Validate before calling
// no direct pre-check API; keep queries within documented supported operators // and test complex queries against the exact Beam version in CI
Try / catch
try {
BeamRelNode beamRel = planner.convertToBeamRel(sqlStatement);
} catch (SqlConversionException e) {
LOG.error("Cannot plan query [{}]: {}", sqlStatement, e.getCause().getMessage());
throw e;
} Prevention
- Restrict queries to operators listed in Beam SQL supported features
- Test complex queries against the actual Beam version in CI
- Simplify unsupported constructs rather than layering hints
- Track Beam releases for newly supported relational operators
When it happens
Trigger: Calling convertToBeamRel(String sqlStatement) where the validated plan cannot be transformed to Beam traits (planner.transform(0, desiredTraits, relNode) throws RelConversionException) or cannot be produced (CannotPlanException).
Common situations: Queries with relational operators Beam SQL does not implement (exotic JOINs, unsupported windowing); queries referencing unsupported table expressions; hints/features Calcite cannot satisfy under Beam's convention traits.
Understand the failure class
Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.
Related errors
- Unable to parse query %s
- Index out of bounds for positional parameter: ${index}
- Unknown window function ${simpleName}
- Please explicitly specify windowing in SQL query using HOP/T
- Unknown DateTime type ${logicalId}
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/1a156dc08335a78b.
Report an issue: GitHub.