prestodb/presto · error · PrestoException
INVALID_ARGUMENTS
INVALID_ARGUMENTS
Error message
Type %s does not allow ordering
What it means
The less-than operator for DISTINCT types requires the distinct type to be orderable. During specialize(), Presto verifies isOrderable() on the bound DistinctType because the operator is implemented by resolving a LESS_THAN operator on the type's base type; if the base type has no ordering, resolution is impossible and INVALID_ARGUMENTS is thrown. A distinct type is assumed orderable iff its parent (base) type is orderable.
Source
Thrown at presto-main-base/src/main/java/com/facebook/presto/operator/scalar/distinct/DistinctTypeLessThanOperator.java:60
public static final DistinctTypeLessThanOperator DISTINCT_TYPE_LESS_THAN_OPERATOR = new DistinctTypeLessThanOperator();
private DistinctTypeLessThanOperator()
{
super(LESS_THAN,
ImmutableList.of(withVariadicBound("T", DISTINCT_TYPE)),
ImmutableList.of(),
parseTypeSignature(BOOLEAN),
ImmutableList.of(parseTypeSignature("T"), parseTypeSignature("T")));
}
@Override
public BuiltInScalarFunctionImplementation specialize(BoundVariables boundVariables, int arity, FunctionAndTypeManager functionAndTypeManager)
{
DistinctType type = (DistinctType) boundVariables.getTypeVariable("T");
// We assume that a distinct type is orderable iff its parent is orderable.
// So we only check orderability of the common supertype when comparing.
if (!type.isOrderable()) {
throw new PrestoException(INVALID_ARGUMENTS, format("Type %s does not allow ordering", type.getDisplayName()));
}
Type baseType = type.getBaseType();
FunctionHandle functionHandle = functionAndTypeManager.resolveOperator(LESS_THAN, fromTypes(baseType, baseType));
return new BuiltInScalarFunctionImplementation(
false,
ImmutableList.of(valueTypeArgumentProperty(RETURN_NULL_ON_NULL), valueTypeArgumentProperty(RETURN_NULL_ON_NULL)),
functionAndTypeManager.getJavaScalarFunctionImplementation(functionHandle).getMethodHandle(),
Optional.empty());
}
}
View on GitHub (pinned to 55bb57d202)
Solutions
- Verify the distinct type's base type is orderable before using < comparisons
- Use equality comparison instead of ordering for non-orderable types
- Cast operands to an orderable type and compare those
- Recreate the distinct type over an orderable base type
Example fix
// before SELECT * FROM t WHERE a < b; -- a,b are distinct type over non-orderable base // after SELECT * FROM t WHERE a = b; -- equality only, or cast to an orderable type
Defensive patterns
Strategy: validation
Validate before calling
if (!distinctType.isOrderable()) { throw new IllegalArgumentException("Type " + distinctType.getDisplayName() + " does not allow ordering; use equality instead"); } Type guard
if (type instanceof DistinctType && ((DistinctType) type).isOrderable()) { /* safe to use < operator */ } Try / catch
try { return functionAndTypeManager.resolveOperator(LESS_THAN, fromTypes(baseType, baseType)); } catch (PrestoException e) { if (INVALID_ARGUMENTS.toErrorCode().equals(e.getErrorCode())) { /* rewrite to equality or cast */ } throw e; } Prevention
- Check isOrderable() before generating < comparisons against distinct types
- Only declare distinct types over orderable base types
- Use equality predicates when the base type lacks ordering
- Cover distinct-type comparisons in unit tests
When it happens
Trigger: Calling the less_than operator with a DISTINCT type argument whose base type is not orderable; the check fails in specialize() when bound type variable 'T' has isOrderable() == false.
Common situations: Comparing distinct-typed columns with < in WHERE clauses, JOIN conditions, or ORDER BY where the distinct type was declared over a non-orderable base type.
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/28a53a3997d3e831.
Report an issue: GitHub.