{"record":{"id":"1fad7461bed818c1","repo":"prestodb/presto","slug":"no-alter-routine-characteristics-specified","errorCode":null,"errorMessage":"No alter routine characteristics specified","messagePattern":"No alter routine characteristics specified","errorType":"exception","errorClass":"ParsingException","httpStatus":null,"severity":"error","filePath":"presto-parser/src/main/java/com/facebook/presto/sql/parser/AstBuilder.java","lineNumber":3099,"sourceCode":"                    throw new ParsingException(format(\"Duplicate null-call clause: %s\", characteristic.nullCallClause().getText()), getLocation(characteristic.nullCallClause()));\n                }\n                nullCallClause = characteristic.nullCallClause().CALLED() != null ? CALLED_ON_NULL_INPUT : RETURNS_NULL_ON_NULL_INPUT;\n            }\n            else {\n                throw new IllegalArgumentException(format(\"Unsupported RoutineCharacteristic: %s\", characteristic.getText()));\n            }\n        }\n\n        return new RoutineCharacteristics(\n                Optional.ofNullable(language),\n                Optional.ofNullable(determinism),\n                Optional.ofNullable(nullCallClause));\n    }\n\n    private AlterRoutineCharacteristics getAlterRoutineCharacteristics(SqlBaseParser.AlterRoutineCharacteristicsContext context)\n    {\n        if (context.alterRoutineCharacteristic().isEmpty()) {\n            throw new ParsingException(\"No alter routine characteristics specified\");\n        }\n\n        NullCallClause nullCallClause = null;\n\n        for (SqlBaseParser.AlterRoutineCharacteristicContext characteristic : context.alterRoutineCharacteristic()) {\n            if (characteristic.nullCallClause() != null) {\n                if (nullCallClause != null) {\n                    throw new ParsingException(format(\"Duplicate null-call clause: %s\", characteristic.nullCallClause().getText()), getLocation(characteristic.nullCallClause()));\n                }\n                nullCallClause = characteristic.nullCallClause().CALLED() != null ? CALLED_ON_NULL_INPUT : RETURNS_NULL_ON_NULL_INPUT;\n            }\n        }\n\n        return new AlterRoutineCharacteristics(Optional.ofNullable(nullCallClause));\n    }\n\n    private String typeParameterToString(SqlBaseParser.TypeParameterContext typeParameter)\n    {","sourceCodeStart":3081,"sourceCodeEnd":3117,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-parser/src/main/java/com/facebook/presto/sql/parser/AstBuilder.java#L3081-L3117","documentation":"getAlterRoutineCharacteristics throws ParsingException when an ALTER FUNCTION ... CHARACTERISTICS clause contains no characteristics at all (the alterRoutineCharacteristic list is empty). The grammar allows an empty list, but the builder requires at least one characteristic to alter.","triggerScenarios":"Parsing 'ALTER FUNCTION f() CHARACTERISTICS' (or equivalent grammar form) with an empty characteristic list.","commonSituations":"SQL builders that always emit the CHARACTERISTICS keyword even when no settings changed, or users dropping all clauses in an edit.","solutions":["Add at least one characteristic, e.g. RETURNS NULL ON NULL INPUT, to the CHARACTERISTICS clause.","Omit the CHARACTERISTICS clause entirely when there is nothing to change.","Make DDL generation emit the clause only if the characteristics set is non-empty.","Guard application code to reject empty characteristics before issuing ALTER FUNCTION."],"exampleFix":"// before\nALTER FUNCTION f() CHARACTERISTICS;\n// after\nALTER FUNCTION f() CHARACTERISTICS RETURNS NULL ON NULL INPUT;","handlingStrategy":"validation","validationCode":"if (characteristics.isEmpty() && sql.toLowerCase(Locale.ROOT).contains(\"characteristics\")) {\n    throw new IllegalArgumentException(\"CHARACTERISTICS clause requires at least one characteristic\");\n}","typeGuard":"boolean canEmitCharacteristics(List<String> characteristics) {\n    return characteristics != null && !characteristics.isEmpty();\n}","tryCatchPattern":"try {\n    parser.createStatement(sql);\n} catch (ParsingException e) {\n    if (e.getMessage().equals(\"No alter routine characteristics specified\")) {\n        throw new IllegalArgumentException(\"ALTER FUNCTION CHARACTERISTICS needs at least one clause\", e);\n    }\n    throw e;\n}","preventionTips":["Skip the CHARACTERISTICS clause entirely when the settings list is empty.","Disable the ALTER button/action in UIs until a characteristic is selected.","Validate characteristics size before building DDL."],"tags":["sql-parser","alter-function","empty-input"],"backgroundTag":"empty-clause","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"}