apache/beam · error · ParseException
Unable to parse query %s
Error message
Unable to parse query %s
What it means
Beam SQL's CalciteQueryPlanner.parse() wraps Apache Calcite's SqlParseException from the planner.parse() call into a ParseException with the original SQL statement in the message. It means the SQL string is syntactically invalid (or uses syntax this Calcite dialect/parser config does not accept), not that the query failed schema validation. The planner is closed in a finally block, so the parse failure does not leak resources.
Source
Thrown at sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/CalciteQueryPlanner.java:181
// Session-scoped custom operators (e.g. registered scalar Python UDFs that must
// declare a non-fixed VARIADIC operand checker). Chained first and held by
// reference, so operators added to the connection's table after the planner is
// built
// still resolve. Placing it ahead of the catalogReader avoids the duplicate
// fixed-parameter overload that schema auto-wrapping would otherwise create.
connection.getExtraOperatorTable(), opTab0, catalogReader))
.sqlToRelConverterConfig(sqlToRelConfig)
.build();
}
/** Parse input SQL query, and return a {@link SqlNode} as grammar tree. */
@Override
public SqlNode parse(String sqlStatement) throws ParseException {
SqlNode parsed;
try {
parsed = planner.parse(sqlStatement);
} catch (SqlParseException e) {
throw new ParseException(String.format("Unable to parse query %s", sqlStatement), e);
} finally {
planner.close();
}
return parsed;
}
/**
* It parses and validate the input query, then convert into a {@link BeamRelNode} tree. Note that
* query parameters are not yet supported.
*/
@Override
public BeamRelNode convertToBeamRel(String sqlStatement, QueryParameters queryParameters)
throws ParseException, SqlConversionException {
Preconditions.checkArgument(
queryParameters.getKind() == Kind.NONE || queryParameters.getKind() == Kind.POSITIONAL,
"Beam SQL Calcite dialect only supports positional query parameters.");
BeamRelNode beamRelNode;
try {View on GitHub (pinned to 12126d8942)
Solutions
- Fix the SQL syntax reported by the wrapped SqlParseException's cause (line/column info is in the cause).
- Check Beam SQL documentation for supported syntax and rewrite unsupported constructs.
- If the query is built dynamically, print the final sqlStatement from the message and run it through a SQL linter.
- Upgrade the Beam version if the syntax is standard SQL recently added to Beam SQL.
Example fix
// before
pipeline.apply(SqlTransform.query("SELCT * FROM t"));
// after
pipeline.apply(SqlTransform.query("SELECT * FROM t")); Defensive patterns
Strategy: try-catch
Validate before calling
// basic sanity check before submitting
if (sql == null || sql.trim().isEmpty()) {
throw new IllegalArgumentException("Empty SQL statement");
}
// cheap lint: balanced parens outside string literals
int opens = 0; boolean inStr = false;
for (char c : sql.toCharArray()) {
if (c == '\'') inStr = !inStr;
else if (!inStr && c == '(') opens++;
else if (!inStr && c == ')') opens--;
}
if (opens != 0) throw new IllegalArgumentException("Unbalanced parentheses in SQL"); Type guard
boolean isLikelyValidSql(String sql) {
return sql != null && !sql.trim().isEmpty();
} Try / catch
try {
SqlNode parsed = planner.parse(sqlStatement);
} catch (ParseException e) {
LOG.error("SQL syntax error for query [{}] cause: {}", sqlStatement, e.getCause().getMessage());
throw e;
} Prevention
- Always log the wrapped cause's line/column when a parse fails
- Keep SQL templates in checked-in files and lint them in CI
- Use only syntax documented as supported by Beam SQL
- Validate dynamically composed SQL with a unit test before runtime
When it happens
Trigger: Calling parse(sqlStatement) (or convertToBeamRel) with SQL that Calcite's parser cannot tokenize or parse: typos, unbalanced parentheses/quotes, unsupported syntax outside Beam SQL's dialect, or a non-SQL string passed as a statement.
Common situations: Dynamically built SQL with missing fragments; pasting dialect-specific SQL (T-SQL/PL-SQL) that Calcite's default dialect rejects; BOM or hidden characters in the query string; Beam version not yet supporting a newly used SQL feature.
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.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Unable to parse Row
- illegal table properties: ${json}
- Unable to parse statement
- Unable to convert query %s
- Index out of bounds for positional parameter: ${index}
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/fb328cb3cdeefe2d.
Report an issue: GitHub.