prestodb/presto · error · ParsingException
No alter routine characteristics specified
Error message
No alter routine characteristics specified
What it means
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.
Source
Thrown at presto-parser/src/main/java/com/facebook/presto/sql/parser/AstBuilder.java:3099
throw new ParsingException(format("Duplicate null-call clause: %s", characteristic.nullCallClause().getText()), getLocation(characteristic.nullCallClause()));
}
nullCallClause = characteristic.nullCallClause().CALLED() != null ? CALLED_ON_NULL_INPUT : RETURNS_NULL_ON_NULL_INPUT;
}
else {
throw new IllegalArgumentException(format("Unsupported RoutineCharacteristic: %s", characteristic.getText()));
}
}
return new RoutineCharacteristics(
Optional.ofNullable(language),
Optional.ofNullable(determinism),
Optional.ofNullable(nullCallClause));
}
private AlterRoutineCharacteristics getAlterRoutineCharacteristics(SqlBaseParser.AlterRoutineCharacteristicsContext context)
{
if (context.alterRoutineCharacteristic().isEmpty()) {
throw new ParsingException("No alter routine characteristics specified");
}
NullCallClause nullCallClause = null;
for (SqlBaseParser.AlterRoutineCharacteristicContext characteristic : context.alterRoutineCharacteristic()) {
if (characteristic.nullCallClause() != null) {
if (nullCallClause != null) {
throw new ParsingException(format("Duplicate null-call clause: %s", characteristic.nullCallClause().getText()), getLocation(characteristic.nullCallClause()));
}
nullCallClause = characteristic.nullCallClause().CALLED() != null ? CALLED_ON_NULL_INPUT : RETURNS_NULL_ON_NULL_INPUT;
}
}
return new AlterRoutineCharacteristics(Optional.ofNullable(nullCallClause));
}
private String typeParameterToString(SqlBaseParser.TypeParameterContext typeParameter)
{View on GitHub (pinned to 55bb57d202)
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.
Example fix
// before ALTER FUNCTION f() CHARACTERISTICS; // after ALTER FUNCTION f() CHARACTERISTICS RETURNS NULL ON NULL INPUT;
Defensive patterns
Strategy: validation
Validate before calling
if (characteristics.isEmpty() && sql.toLowerCase(Locale.ROOT).contains("characteristics")) {
throw new IllegalArgumentException("CHARACTERISTICS clause requires at least one characteristic");
} Type guard
boolean canEmitCharacteristics(List<String> characteristics) {
return characteristics != null && !characteristics.isEmpty();
} Try / catch
try {
parser.createStatement(sql);
} catch (ParsingException e) {
if (e.getMessage().equals("No alter routine characteristics specified")) {
throw new IllegalArgumentException("ALTER FUNCTION CHARACTERISTICS needs at least one clause", e);
}
throw e;
} Prevention
- 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.
When it happens
Trigger: Parsing 'ALTER FUNCTION f() CHARACTERISTICS' (or equivalent grammar form) with an empty characteristic list.
Common situations: SQL builders that always emit the CHARACTERISTICS keyword even when no settings changed, or users dropping all clauses in an edit.
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/1fad7461bed818c1.
Report an issue: GitHub.