apache/druid · error · java.lang.UnsupportedOperationException
StringLastAggregator does not support getLong()
Error message
StringLastAggregator does not support getLong()
What it means
StringLastAggregator aggregates last string values per time column, so its numeric accessors are meaningless. The Aggregator interface requires getFloat/getLong/getDouble, but a string-typed aggregator cannot produce numeric primitives, so all unsupported accessors throw UnsupportedOperationException. This is a deliberate contract guard, not a transient failure.
Solutions
- Use the string accessor (aggregate() then inspect the value via the appropriate result path / getSerializedString / result object) instead of getLong()
- Change the aggregation to a numeric aggregator (e.g. doubleLast/longFirst) if a numeric result is actually needed
- Check the aggregator's type (AggregatorFactory.getTypeName()) before dispatching to numeric accessors
- If getLong is legitimately needed, convert the string value at query time with SQL CAST
Example fix
// before
Aggregator agg = factory.factorize(colSelectorFactory);
long v = agg.getLong(); // throws UnsupportedOperationException
// after
if ("string".equals(factory.getTypeName())) {
Object v = agg.get(); // string result
} else {
long v2 = agg.getLong();
} Defensive patterns
Strategy: type-guard
Validate before calling
if ("string".equals(factory.getTypeName())) { /* use string result path */ } Type guard
static boolean supportsLong(AggregatorFactory f) { return !"string".equals(f.getTypeName()) && !"hyperUnique".equals(f.getTypeName()); } Try / catch
try { v = agg.getLong(); } catch (UnsupportedOperationException e) { v = parseOrNull(String.valueOf(agg.get())); } Prevention
- Consult AggregatorFactory.getTypeName() before calling typed accessors
- Prefer SQL CAST or a numeric aggregator over numeric accessors on string aggregators
- Keep custom result code type-dispatched, not accessor-uniform
When it happens
Trigger: Calling aggregator.getLong() on a StringLastAggregator instance, typically reached when a query/factory declares this aggregator but the row-reading or result-layer code assumes a numeric column type and invokes the long accessor.
Common situations: Running a last(string) aggregation and then post-processing results with numeric accessors; custom query tooling iterating Aggregator objects generically without consulting the aggregator's type; tests or plugins that expect all aggregators to be numeric.
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
- ApproximateHistogramBufferAggregator does not support…
- ApproximateHistogramBufferAggregator does not support…
- ApproximateHistogramBufferAggregator does not support…
- ApproximateHistogramFoldingAggregator does not support…
- ApproximateHistogramFoldingAggregator does not support…
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/ad67110551c32c8a.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/StringLastAggregator.java:101
}
}
@Override
public Object get()
{
return new SerializablePairLongString(lastTime, StringUtils.chop(lastValue, maxStringBytes));
}
@Override
public float getFloat()
{
throw new UnsupportedOperationException("StringLastAggregator does not support getFloat()");
}
@Override
public long getLong()
{
throw new UnsupportedOperationException("StringLastAggregator does not support getLong()");
}
@Override
public double getDouble()
{
throw new UnsupportedOperationException("StringLastAggregator does not support getDouble()");
}
@Override
public void close()
{
// no resources to cleanup
}
}
View on GitHub (pinned to 9b90983fd2)