apache/druid · error · UnsupportedOperationException
Not implemented
Error message
Not implemented
What it means
Bitmap64ExactCountBuildBufferAggregator.getLong(ByteBuffer, int) is an intentionally unimplemented stub. The off-heap (buffer) variant of the build aggregator stores a serialized Roaring64Bitmap in the aggregation buffer and cannot yield a long scalar, so getLong() always throws UnsupportedOperationException("Not implemented").
Source
Thrown at extensions-contrib/druid-exact-count-bitmap/src/main/java/org/apache/druid/query/aggregation/exact/count/bitmap64/Bitmap64ExactCountBuildBufferAggregator.java:71
if (!selector.isNull()) {
bitmap64Counter.add(selector.getLong());
}
}
finally {
buf.position(oldPosition);
}
}
@Override
public Object get(ByteBuffer buf, int position)
{
return getOrCreateCollector(buf, position);
}
@Override
public long getLong(ByteBuffer buf, int position)
{
throw new UnsupportedOperationException("Not implemented");
}
@Override
public double getDouble(ByteBuffer buf, int position)
{
throw new UnsupportedOperationException("Not implemented");
}
@Override
public float getFloat(ByteBuffer buf, int position)
{
throw new UnsupportedOperationException("Not implemented");
}
@Override
public void close()
{
View on GitHub (pinned to 9b90983fd2)
Solutions
- Use the merge/counter aggregation type (whose getLong returns cardinality) in the query instead of the build type.
- Read the value via get(buf, position) (returns the bitmap/collector object) and call getLongCardinality() on it.
- Fix the query layer/post-aggregator to treat the build aggregation output as an object, not a long.
- If this is your fork, implement getLong() delegating to the collector's counter value if appropriate.
Example fix
// before
long v = bufferAggregator.getLong(buf, position);
// after
Object collector = bufferAggregator.get(buf, position);
long v = (collector instanceof Roaring64Bitmap)
? ((Roaring64Bitmap) collector).getLongCardinality()
: 0L; Defensive patterns
Strategy: type-guard
Validate before calling
Object c = bufferAggregator.get(buf, position); boolean ok = c instanceof Roaring64Bitmap; // then read cardinality from c
Type guard
boolean isBitmapSlot(BufferAggregator agg, ByteBuffer buf, int pos) { return agg.get(buf, pos) instanceof Roaring64Bitmap; } Try / catch
try { v = bufferAggregator.getLong(buf, position); } catch (UnsupportedOperationException e) { v = ((Roaring64Bitmap) bufferAggregator.get(buf, position)).getLongCardinality(); } Prevention
- Never call numeric getters on BITMAP64_BUILD_* buffer aggregators
- Use get(buf, position) and operate on the bitmap/collector object
- Switch to the merge aggregation for numeric results
When it happens
Trigger: Group-by or timeseries engine finalizes a result and calls bufferAggregator.getLong(buf, position) on the bitmap build aggregation slot, e.g. because the aggregation was declared with a LONG output type or generic finalization code reads a long.
Common situations: Using the BITMAP64_BUILD_* aggregator where the merge/exact-count type was intended; custom query engines or tests calling getLong directly on buffer aggregators; post-aggregators declared over the build aggregation expecting numeric input.
Related errors
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/3059cde97071adf6.
Report an issue: GitHub.