{"record":{"id":"4f95be3b4e86f484","repo":"prestodb/presto","slug":"substituting-s-in-s-is-not-supported","errorCode":null,"errorMessage":"Substituting %s in %s is not supported.","messagePattern":"Substituting (.+?) in (.+?) is not supported\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"presto-verifier/src/main/java/com/facebook/presto/verifier/rewrite/FunctionCallRewriter.java","lineNumber":458,"sourceCode":"                }\n            }\n            return false;\n        }\n    }\n\n    private static Expression parseOriginalFunctionCall(String functionCallSpec)\n    {\n        SqlParser sqlParser = new SqlParser();\n        Expression expression;\n        try {\n            expression = sqlParser.createExpression(functionCallSpec, PARSING_OPTIONS);\n        }\n        catch (ParsingException e) {\n            throw new IllegalArgumentException(String.format(\"Function call spec %s is not in a valid format.\", functionCallSpec), e);\n        }\n\n        if (SUPPORTED_ORIGINAL_FUNCTIONS.stream().noneMatch(clazz -> clazz.equals(expression.getClass()))) {\n            throw new IllegalArgumentException(String.format(\"Substituting %s in %s is not supported.\", expression.getClass().getSimpleName(), functionCallSpec));\n        }\n\n        if (expression instanceof FunctionCall) {\n            FunctionCall functionCall = (FunctionCall) expression;\n\n            Stream<Expression> arguments = functionCall.getArguments().stream();\n            arguments = Stream.concat(arguments, functionCall.getOrderBy().map(OrderBy::getSortItems).orElse(ImmutableList.of()).stream().map(SortItem::getSortKey));\n            arguments = Stream.concat(arguments, functionCall.getWindow().map(Window::getPartitionBy).orElse(ImmutableList.of()).stream());\n            arguments = Stream.concat(arguments, functionCall.getWindow().flatMap(Window::getOrderBy).map(OrderBy::getSortItems).orElse(ImmutableList.of()).stream().map(SortItem::getSortKey));\n\n            arguments.forEach(argument -> {\n                if (argument instanceof Identifier || argument instanceof Literal) {\n                    return;\n                }\n                if (argument instanceof ArrayConstructor) {\n                    if (((ArrayConstructor) argument).getValues().stream().allMatch(Literal.class::isInstance)) {\n                        return;\n                    }","sourceCodeStart":440,"sourceCodeEnd":476,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-verifier/src/main/java/com/facebook/presto/verifier/rewrite/FunctionCallRewriter.java#L440-L476","documentation":"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.","triggerScenarios":"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.","commonSituations":"Trying to substitute arbitrary expressions instead of function calls; config entries copied from query rewrites; misunderstanding that only function-call-shaped originals are supported.","solutions":["Use a supported original form: a function call like 'myfunc(x)' or a current-time expression like 'current_date'","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)"],"exampleFix":"// before\nfunctionCallSubstitutes = x + 1/myfunc(x)\n// after\nfunctionCallSubstitutes = add_one(x)/myfunc(x)","handlingStrategy":"type-guard","validationCode":"Expression e = new SqlParser().createExpression(spec, PARSING_OPTIONS);\nboolean ok = e instanceof FunctionCall || e instanceof CurrentTime;","typeGuard":"boolean isSupportedOriginal(Expression e) {\n    return e instanceof FunctionCall || e instanceof CurrentTime;\n}","tryCatchPattern":"try {\n    rewriter = FunctionCallRewriter.getInstance(functionCallSubstitutes, typeManager);\n} catch (IllegalArgumentException e) {\n    LOG.error(\"Original spec must be a FunctionCall or CurrentTime: %s\", e.getMessage());\n    rewriter = Optional.empty();\n}","preventionTips":["Only substitute function calls (or current-time expressions) as originals","Rewrite non-function expressions upstream in the query, not via this config","Check SUPPORTED_ORIGINAL_FUNCTIONS before adding entries"],"tags":["unsupported","validation","sql-parser","verifier"],"backgroundTag":"unsupported-expression-type","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}