prestodb/presto · error · ParsingException
Unexpected decimal literal: ${text}
Error message
Unexpected decimal literal: ${text} What it means
AstBuilder.visitDecimalLiteral throws ParsingException when parsingOptions.getDecimalLiteralTreatment() is REJECT and the input contains a decimal literal (e.g. 1.23). The parser is configured to refuse decimal literals rather than coerce them to DOUBLE or DECIMAL.
Source
Thrown at presto-parser/src/main/java/com/facebook/presto/sql/parser/AstBuilder.java:2541
return new GenericLiteral(getLocation(context), type, value);
}
@Override
public Node visitIntegerLiteral(SqlBaseParser.IntegerLiteralContext context)
{
return new LongLiteral(getLocation(context), context.getText());
}
@Override
public Node visitDecimalLiteral(SqlBaseParser.DecimalLiteralContext context)
{
switch (parsingOptions.getDecimalLiteralTreatment()) {
case AS_DOUBLE:
return new DoubleLiteral(getLocation(context), context.getText());
case AS_DECIMAL:
return new DecimalLiteral(getLocation(context), context.getText());
case REJECT:
throw new ParsingException("Unexpected decimal literal: " + context.getText());
}
throw new AssertionError("Unreachable");
}
@Override
public Node visitDoubleLiteral(SqlBaseParser.DoubleLiteralContext context)
{
return new DoubleLiteral(getLocation(context), context.getText());
}
@Override
public Node visitBooleanValue(SqlBaseParser.BooleanValueContext context)
{
return new BooleanLiteral(getLocation(context), context.getText());
}
@Override
public Node visitInterval(SqlBaseParser.IntervalContext context)View on GitHub (pinned to 55bb57d202)
Solutions
- Change ParsingOptions to AS_DECIMAL so decimals become DecimalLiteral.
- Or use AS_DOUBLE if legacy DoubleLiteral semantics are desired.
- Rewrite the SQL to avoid decimal literals (e.g. CAST('1.23' AS DECIMAL)).
- If the server sets REJECT, remove or reconfigure that option at the caller site.
Example fix
// before
new SqlParser().createStatement("SELECT 1.5", ParsingOptions.builder().decimalLiteralTreatment(DecimalLiteralTreatment.REJECT).build());
// after
new SqlParser().createStatement("SELECT 1.5", ParsingOptions.builder().decimalLiteralTreatment(DecimalLiteralTreatment.AS_DECIMAL).build()); Defensive patterns
Strategy: validation
Validate before calling
// reject REJECT mode when SQL contains decimal literals
if (parsingOptions.getDecimalLiteralTreatment() == DecimalLiteralTreatment.REJECT
&& Pattern.compile("\\b\\d+\\.\\d+\\b").matcher(sql).find()) {
throw new IllegalArgumentException("Decimal literal present but treatment is REJECT");
} Type guard
boolean isDecimalLiteralRejected(ParsingOptions opts, String sql) {
return opts.getDecimalLiteralTreatment() == DecimalLiteralTreatment.REJECT
&& Pattern.compile("\\d+\\.\\d+").matcher(sql).find();
} Try / catch
try {
parser.createStatement(sql, parsingOptions);
} catch (ParsingException e) {
if (e.getMessage().startsWith("Unexpected decimal literal")) {
ParsingOptions relaxed = ParsingOptions.builder(parsingOptions)
.decimalLiteralTreatment(DecimalLiteralTreatment.AS_DECIMAL).build();
parser.createStatement(sql, relaxed);
} else throw e;
} Prevention
- Use AS_DECIMAL (the modern default) unless legacy DOUBLE semantics are required.
- Never copy REJECT-mode ParsingOptions from legacy examples without intent.
- Strip or CAST decimal literals when strict parsing is mandatory.
When it happens
Trigger: Calling SqlParser with ParsingOptions decimalLiteralTreatment=REJECT and parsing any statement containing a decimal number literal.
Common situations: Server/tooling code that explicitly sets REJECT to force legacy behavior, or API users who copied ParsingOptions.builder().decimalLiteralTreatment(DecimalLiteralTreatment.REJECT) from strict-mode examples.
Related errors
- WARNING_AS_ERROR
- Unsupported EXPLAIN format:
- Unsupported EXPLAIN type:
- Unsupported join criteria
- Unsupported Type:
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/2374f6793d34a89b.
Report an issue: GitHub.