prestodb/presto · error · IllegalArgumentException
Unsupported EXPLAIN format:
Error message
Unsupported EXPLAIN format:
What it means
AstBuilder.visitExplainFormat throws this IllegalArgumentException when the grammar reduced an EXPLAIN FORMAT clause whose token does not map to a known ExplainFormat.Type (only TEXT and JSON are handled). It is a parser-side sanity check that should be unreachable for valid grammar input, so hitting it means the grammar and the enum are out of sync or the ANTLR-generated classes were regenerated inconsistently.
Source
Thrown at presto-parser/src/main/java/com/facebook/presto/sql/parser/AstBuilder.java:1335
@Override
public Node visitExplain(SqlBaseParser.ExplainContext context)
{
return new Explain(getLocation(context), context.ANALYZE() != null, context.VERBOSE() != null, (Statement) visit(context.statement()), visit(context.explainOption(), ExplainOption.class));
}
@Override
public Node visitExplainFormat(SqlBaseParser.ExplainFormatContext context)
{
switch (context.value.getType()) {
case SqlBaseLexer.GRAPHVIZ:
return new ExplainFormat(getLocation(context), ExplainFormat.Type.GRAPHVIZ);
case SqlBaseLexer.TEXT:
return new ExplainFormat(getLocation(context), ExplainFormat.Type.TEXT);
case SqlBaseLexer.JSON:
return new ExplainFormat(getLocation(context), ExplainFormat.Type.JSON);
}
throw new IllegalArgumentException("Unsupported EXPLAIN format: " + context.value.getText());
}
@Override
public Node visitExplainType(SqlBaseParser.ExplainTypeContext context)
{
switch (context.value.getType()) {
case SqlBaseLexer.LOGICAL:
return new ExplainType(getLocation(context), ExplainType.Type.LOGICAL);
case SqlBaseLexer.DISTRIBUTED:
return new ExplainType(getLocation(context), ExplainType.Type.DISTRIBUTED);
case SqlBaseLexer.VALIDATE:
return new ExplainType(getLocation(context), ExplainType.Type.VALIDATE);
case SqlBaseLexer.IO:
return new ExplainType(getLocation(context), ExplainType.Type.IO);
}
throw new IllegalArgumentException("Unsupported EXPLAIN type: " + context.value.getText());
}View on GitHub (pinned to 55bb57d202)
Solutions
- Use FORMAT TEXT or FORMAT JSON, which are the only supported values.
- Remove the FORMAT clause entirely to get the default text output.
- If you maintain a fork, add the new token's case in visitExplainFormat and a matching ExplainFormat.Type.
- Rebuild/align presto-parser so the generated SqlBaseParser/Lexer matches AstBuilder.
Example fix
// before EXPLAIN FORMAT GRAPHVIZ SELECT * FROM t; // after EXPLAIN FORMAT TEXT SELECT * FROM t;
Defensive patterns
Strategy: validation
Validate before calling
Set<String> allowed = Set.of("TEXT", "JSON");
if (format != null && !allowed.contains(format.toUpperCase(Locale.ROOT))) {
throw new IllegalArgumentException("EXPLAIN FORMAT must be TEXT or JSON: " + format);
} Type guard
boolean isSupportedExplainFormat(String s) {
return s != null && (s.equalsIgnoreCase("TEXT") || s.equalsIgnoreCase("JSON"));
} Try / catch
try {
parser.createStatement(sql);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Unsupported EXPLAIN format")) {
sql = sql.replaceFirst("(?i)FORMAT\\s+\\S+", "FORMAT TEXT");
parser.createStatement(sql);
} else throw e;
} Prevention
- Only emit FORMAT TEXT or FORMAT JSON in query tooling.
- Keep the grammar and AstBuilder in sync when adding formats.
- Pin a single version of the shaded presto-parser artifact.
When it happens
Trigger: Executing 'EXPLAIN ANALYZE? ... FORMAT <x>' where the FORMAT token is neither TEXT nor JSON (e.g. FORMAT GRAPHVIZ removed from the grammar's switch), or running a stale/incompatible presto-parser build where SqlBase.g4 accepts more format tokens than AstBuilder handles.
Common situations: Copy-pasted EXPLAIN statements from other engines (e.g. FORMAT YAML), custom forks that added a lexer token without extending visitExplainFormat, or version-mismatched shaded parser jars.
Related errors
- Unsupported EXPLAIN type:
- Unsupported join criteria
- WARNING_AS_ERROR
- Invalid day-time interval:
- Invalid year-month interval:
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/18e9c667edd0d852.
Report an issue: GitHub.