prestodb/presto · error · IllegalArgumentException

Substituting %s in %s is not supported.

Error message

Substituting %s in %s is not supported.

What it means

After parsing successfully, the original function call spec must be one of the supported expression types: FunctionCall or CurrentTime (SUPPORTED_ORIGINAL_FUNCTIONS). Any other expression kind (e.g. arithmetic, comparison, literal-only expression) is rejected with this IllegalArgumentException, because the rewriter only knows how to substitute whole function calls or current-time expressions.

Source

Thrown at presto-verifier/src/main/java/com/facebook/presto/verifier/rewrite/FunctionCallRewriter.java:458

                }
            }
            return false;
        }
    }

    private static Expression parseOriginalFunctionCall(String functionCallSpec)
    {
        SqlParser sqlParser = new SqlParser();
        Expression expression;
        try {
            expression = sqlParser.createExpression(functionCallSpec, PARSING_OPTIONS);
        }
        catch (ParsingException e) {
            throw new IllegalArgumentException(String.format("Function call spec %s is not in a valid format.", functionCallSpec), e);
        }

        if (SUPPORTED_ORIGINAL_FUNCTIONS.stream().noneMatch(clazz -> clazz.equals(expression.getClass()))) {
            throw new IllegalArgumentException(String.format("Substituting %s in %s is not supported.", expression.getClass().getSimpleName(), functionCallSpec));
        }

        if (expression instanceof FunctionCall) {
            FunctionCall functionCall = (FunctionCall) expression;

            Stream<Expression> arguments = functionCall.getArguments().stream();
            arguments = Stream.concat(arguments, functionCall.getOrderBy().map(OrderBy::getSortItems).orElse(ImmutableList.of()).stream().map(SortItem::getSortKey));
            arguments = Stream.concat(arguments, functionCall.getWindow().map(Window::getPartitionBy).orElse(ImmutableList.of()).stream());
            arguments = Stream.concat(arguments, functionCall.getWindow().flatMap(Window::getOrderBy).map(OrderBy::getSortItems).orElse(ImmutableList.of()).stream().map(SortItem::getSortKey));

            arguments.forEach(argument -> {
                if (argument instanceof Identifier || argument instanceof Literal) {
                    return;
                }
                if (argument instanceof ArrayConstructor) {
                    if (((ArrayConstructor) argument).getValues().stream().allMatch(Literal.class::isInstance)) {
                        return;
                    }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Use a supported original form: a function call like 'myfunc(x)' or a current-time expression like 'current_date'
  2. If you need to rewrite a non-function expression, do it in the query setup (e.g. wrap it in a function or use a different verifier rewrite mechanism)

Example fix

// before
functionCallSubstitutes = x + 1/myfunc(x)
// after
functionCallSubstitutes = add_one(x)/myfunc(x)
Defensive patterns

Strategy: type-guard

Validate before calling

Expression e = new SqlParser().createExpression(spec, PARSING_OPTIONS);
boolean ok = e instanceof FunctionCall || e instanceof CurrentTime;

Type guard

boolean isSupportedOriginal(Expression e) {
    return e instanceof FunctionCall || e instanceof CurrentTime;
}

Try / catch

try {
    rewriter = FunctionCallRewriter.getInstance(functionCallSubstitutes, typeManager);
} catch (IllegalArgumentException e) {
    LOG.error("Original spec must be a FunctionCall or CurrentTime: %s", e.getMessage());
    rewriter = Optional.empty();
}

Prevention

When it happens

Trigger: Passing an original spec that parses but is not a FunctionCall or CurrentTime, e.g. '1 + 2', 'a > b', or 'CASE WHEN ...' as the original side of a function-call-substitutes entry.

Common situations: Trying to substitute arbitrary expressions instead of function calls; config entries copied from query rewrites; misunderstanding that only function-call-shaped originals are supported.

Related errors


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