prestodb/presto · error · PrestoException
INVALID_LIMIT_CLAUSE
INVALID_LIMIT_CLAUSE
Error message
Invalid limit: %s
What it means
When planning a FETCH FIRST/LIMIT clause, QueryPlanner accepts either the literal 'ALL' or a parseable long. If the limit string is neither 'all' (case-insensitive) nor a valid long, Long.parseLong throws NumberFormatException, which is rethrown as PrestoException with INVALID_LIMIT_CLAUSE.
Source
Thrown at presto-main-base/src/main/java/com/facebook/presto/sql/planner/QueryPlanner.java:2003
private PlanBuilder limit(PlanBuilder subPlan, QuerySpecification node)
{
return limit(subPlan, node.getLimit());
}
private PlanBuilder limit(PlanBuilder subPlan, Optional<String> limit)
{
if (!limit.isPresent()) {
return subPlan;
}
if (!limit.get().equalsIgnoreCase("all")) {
try {
long limitValue = Long.parseLong(limit.get());
subPlan = subPlan.withNewRoot(new LimitNode(subPlan.getRoot().getSourceLocation(), idAllocator.getNextId(), subPlan.getRoot(), limitValue, FINAL));
}
catch (NumberFormatException e) {
throw new PrestoException(INVALID_LIMIT_CLAUSE, format("Invalid limit: %s", limit.get()));
}
}
return subPlan;
}
// Special treatment of CallExpression
private List<RowExpression> callArgumentsToRowExpression(FunctionHandle functionHandle, List<Expression> arguments)
{
return arguments.stream()
.map(expression -> toRowExpression(
expression,
metadata,
session,
analyzeCallExpressionTypes(functionHandle, arguments, metadata, sqlParser, session, TypeProvider.viewOf(variableAllocator.getVariables())),
sqlPlannerContext.getTranslatorContext()))
.collect(toImmutableList());
}View on GitHub (pinned to 55bb57d202)
Solutions
- Fix the SQL to use a plain integer literal, e.g. LIMIT 10 or FETCH FIRST 10 ROWS ONLY
- Use LIMIT ALL / FETCH FIRST ALL ROWS (or omit the clause) to remove the limit
- If SQL is generated programmatically, validate the limit value is a non-negative long before emission
- Check client/ORM dialect settings that may be quoting the limit value
Example fix
// before SELECT * FROM t FETCH FIRST '25' ROWS ONLY; // after SELECT * FROM t FETCH FIRST 25 ROWS ONLY;
Defensive patterns
Strategy: validation
Validate before calling
// Validate LIMIT value before building SQL
String limit = "25";
if (!limit.equalsIgnoreCase("all") && !limit.matches("\\d+")) {
throw new IllegalArgumentException("Invalid limit: " + limit);
}
String sql = "SELECT * FROM t LIMIT " + limit; Type guard
boolean isValidLimit(String limit) {
return limit != null && (limit.equalsIgnoreCase("all") || limit.matches("\\d+"));
} Try / catch
try {
result = statement.execute(sql);
} catch (PrestoException e) {
if (e.getErrorCode().getName().equals("INVALID_LIMIT_CLAUSE")) {
throw new IllegalArgumentException("Fix LIMIT/FETCH FIRST value to an integer or ALL", e);
}
throw e;
} Prevention
- Never quote LIMIT values in generated SQL
- Sanitize user-supplied page sizes to non-negative integers before SQL emission
- Use LIMIT ALL (or omit) instead of non-numeric sentinels
- Test SQL generation templates for limit injection points
When it happens
Trigger: A query whose LIMIT/FETCH FIRST value, after analysis, is a non-numeric string other than 'ALL' — e.g. FETCH FIRST 'ten' ROWS ONLY, or a parameterized/quoted limit that analysis resolved to a bad literal.
Common situations: Hand-written SQL with quoted or malformed limit values; generated SQL where a limit placeholder was substituted with a non-numeric string; dialect-translation bugs producing LIMIT 'N'.
Related errors
- NOT_SUPPORTED
- NODE_SELECTION_NOT_SUPPORTED
- QUERY_HAS_TOO_MANY_STAGES
- QUERY_PLANNING_TIMEOUT
- EXCEEDED_PLAN_NODE_LIMIT
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/1767788aa78d738c.
Report an issue: GitHub.