apache/iceberg · error · UnsupportedOperationException
BelowMin has no comparator
Error message
BelowMin has no comparator
What it means
Same rationale as AboveMax: the BelowMin sentinel carries no value, so no Comparator can be produced for it. Ordering of the sentinel is defined implicitly by predicate-binding semantics (anything is greater than belowMin), not by a comparator object.
Source
Thrown at api/src/main/java/org/apache/iceberg/expressions/Literals.java:219
static class BelowMin<T> implements Literal<T> {
private static final BelowMin INSTANCE = new BelowMin();
private BelowMin() {}
@Override
public T value() {
throw new UnsupportedOperationException("BelowMin has no value");
}
@Override
public <X> Literal<X> to(Type type) {
throw new UnsupportedOperationException("Cannot change the type of BelowMin");
}
@Override
public Comparator<T> comparator() {
throw new UnsupportedOperationException("BelowMin has no comparator");
}
@Override
public String toString() {
return "belowMin";
}
}
static class BooleanLiteral extends ComparableLiteral<Boolean> {
BooleanLiteral(Boolean value) {
super(value);
}
@Override
@SuppressWarnings("unchecked")
public <T> Literal<T> to(Type type) {
if (type.typeId() == Type.TypeID.BOOLEAN) {
return (Literal<T>) this;View on GitHub (pinned to 86d9c8fc54)
Solutions
- Exclude belowMin/aboveMax sentinels before requesting a comparator and resolve comparisons via operation semantics
- Inspect the predicate after binding; bound predicates from sentinels are typically rewritten to always-true/false
- Validate literal ranges against the column type up front so sentinels are never produced
Example fix
// before
Comparator<T> cmp = lit.comparator();
// after
if (lit == Literals.belowMin()) {
// belowMin compares less than everything; no comparator needed
} else {
Comparator<T> cmp = lit.comparator();
} Defensive patterns
Strategy: type-guard
Validate before calling
if (lit == Literals.belowMin() || lit == Literals.aboveMax()) { throw new IllegalArgumentException("Sentinel literal has no comparator"); } Type guard
static boolean hasComparator(Literal<?> lit) { return lit != Literals.belowMin() && lit != Literals.aboveMax(); } Try / catch
try { Comparator<?> cmp = lit.comparator(); } catch (UnsupportedOperationException e) { /* belowMin is less than everything; decide via operation */ } Prevention
- Exclude sentinels before requesting comparators in evaluators
- Rely on bound-predicate evaluation which encodes sentinel ordering
- Add regression tests with literals that underflow the column type
When it happens
Trigger: Calling comparator() on Literals.belowMin(), e.g. in generic expression evaluation code that obtains a comparator for every literal or bound term.
Common situations: Custom predicate evaluators or metrics-based filter pushdown that uniformly request comparators and trip over sentinel literals produced by conversion overflow/underflow.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- AboveMax has no comparator
- BelowMin has no value
- Cannot change the type of BelowMin
- Unsupported aggregate type: %s
- Cannot convert JSON to literal: " + node
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/e60e6f1022d8796e.
Report an issue: GitHub.