prestodb/presto · error · SemanticException
INVALID_PARAMETER_USAGE
INVALID_PARAMETER_USAGE
Error message
Incorrect number of parameters: expected %s but found %s
What it means
Before analyzing a statement with parameters, the preparer validates that the number of supplied parameter values exactly equals the number of '?' placeholders found in the statement. A mismatch throws SemanticException with code INVALID_PARAMETER_USAGE.
Source
Thrown at presto-analyzer/src/main/java/com/facebook/presto/sql/analyzer/BuiltInQueryPreparer.java:145
if (analyzerOptions.isLogFormattedQueryEnabled()) {
formattedQuery = Optional.of(getFormattedQuery(statement, parameters));
}
return new BuiltInPreparedQuery(wrappedStatement, statement, parameters, formattedQuery, prepareSql, distributedProcedureName);
}
private static String getFormattedQuery(Statement statement, List<Expression> parameters)
{
String formattedQuery = formatSql(
statement,
parameters.isEmpty() ? Optional.empty() : Optional.of(parameters));
return format("-- Formatted Query:%n%s", formattedQuery);
}
private static void validateParameters(Statement node, List<Expression> parameterValues)
{
int parameterCount = getParameterCount(node);
if (parameterValues.size() != parameterCount) {
throw new SemanticException(INVALID_PARAMETER_USAGE, node, "Incorrect number of parameters: expected %s but found %s", parameterCount, parameterValues.size());
}
for (Expression expression : parameterValues) {
verifyExpressionIsConstant(ImmutableSet.of(), expression);
}
}
public static class BuiltInPreparedQuery
extends PreparedQuery
{
private final Statement statement;
private final Statement wrappedStatement;
private final List<Expression> parameters;
private final Optional<QualifiedObjectName> distributedProcedureName;
public BuiltInPreparedQuery(
Statement wrappedStatement,
Statement statement, List<Expression> parameters,
Optional<String> formattedQuery, Optional<String> prepareSql,View on GitHub (pinned to 55bb57d202)
Solutions
- Count the '?' placeholders in the statement and supply exactly that many parameter values
- Check the EXECUTE ... USING value list matches the PREPARE statement's placeholder count
- Regenerate the SQL or parameter list if the query text was changed without updating bindings
Example fix
// before PREPARE p FROM SELECT * FROM t WHERE a = ? AND b = ?; EXECUTE p USING 1; // after EXECUTE p USING 1, 2;
Defensive patterns
Strategy: validation
Validate before calling
int placeholders = getParameterCount(statement);
if (parameterValues.size() != placeholders) {
throw new IllegalArgumentException("Expected " + placeholders + " parameters but got " + parameterValues.size());
} Try / catch
try {
preparer.prepareQuery(options, sql, params, warnings);
} catch (SemanticException e) {
if (e.getCode() == SemanticErrorCode.INVALID_PARAMETER_USAGE) { /* log placeholder count vs supplied values and re-bind */ }
throw e;
} Prevention
- Count '?' placeholders and parameter values in one place when building dynamic SQL
- Validate EXECUTE ... USING arity against the PREPARE statement at client side
- Write tests asserting placeholder count for every prepared statement template
When it happens
Trigger: Calling prepareQuery with a statement containing N '?' placeholders but a preparedStatements/parameterValues list whose size differs from N; commonly via EXECUTE of a prepared statement with the wrong number of USING values.
Common situations: EXECUTE stmt USING fewer/more values than placeholders; client drivers binding parameter lists that don't match the SQL text; dynamic SQL generation with incorrect parameter counts.
Related errors
- EXPRESSION_NOT_CONSTANT
- MISSING_ATTRIBUTE
- setURL
- No value specified for parameter
- Batch prepared statement must be executed using executeBatch
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/1125079b2a47a220.
Report an issue: GitHub.