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

  1. Count the '?' placeholders in the statement and supply exactly that many parameter values
  2. Check the EXECUTE ... USING value list matches the PREPARE statement's placeholder count
  3. 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

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


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/1125079b2a47a220. Report an issue: GitHub.