apache/druid · error · UnsupportedOperationException

Not implemented

Error message

Not implemented

What it means

Bitmap64ExactCountBuildAggregator.getFloat() is an intentionally unimplemented stub in the druid-exact-count-bitmap extension. The build-side aggregator only supports producing its Roaring64Bitmap object (via get()); numeric scalar accessors are unsupported because the aggregation's result type is a serialized bitmap, not a number. Calling getFloat() therefore 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/Bitmap64ExactCountBuildAggregator.java:56

  @Override
  public void aggregate()
  {
    if (!selector.isNull()) {
      bitmap.add(selector.getLong());
    }
  }

  @Nullable
  @Override
  public Object get()
  {
    return bitmap;
  }

  @Override
  public float getFloat()
  {
    throw new UnsupportedOperationException("Not implemented");
  }

  @Override
  public long getLong()
  {
    throw new UnsupportedOperationException("Not implemented");
  }

  @Override
  public void close()
  {
    bitmap = null;
  }
}

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Read the aggregated value with get() (the Roaring64Bitmap) or via the matching bitmap accessor instead of getFloat().
  2. If a numeric count is needed at query time, use the MERGE aggregator type (BITMAP64_EXACT_COUNT) which returns the cardinality as a long via getLong().
  3. Check ColumnValueSelector usage: only call getFloat() when the column capabilities report a FLOAT value type; dispatch on ValueType before accessing.
  4. If you control the extension, implement getFloat() to throw a more descriptive message or return the bitmap cardinality cast to float.

Example fix

// before
float v = selector.getFloat();

// after
Object raw = selector.getObject();
if (raw instanceof Roaring64Bitmap) {
  long cardinality = ((Roaring64Bitmap) raw).getLongCardinality();
  float v = (float) cardinality;
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (selector != null && selector.getObject() instanceof Roaring64Bitmap) { /* safe to read bitmap */ }

Type guard

boolean isBitmapValue(ColumnValueSelector<?> s) { return s != null && s.getObject() instanceof Roaring64Bitmap; }

Try / catch

try { v = selector.getFloat(); } catch (UnsupportedOperationException e) { Object o = selector.getObject(); v = o instanceof Roaring64Bitmap ? (float) ((Roaring64Bitmap) o).getLongCardinality() : 0f; }

Prevention

When it happens

Trigger: A query or aggregation pipeline requests a FLOAT result from the Bitmap64ExactCount build aggregator, e.g. a post-aggregator or SQL layer calls aggregator.getFloat() instead of getObject()/get() on the aggregated column.

Common situations: Wrapping the BITMAP64_BUILD_SIGNED/BITMAP64_BUILD_UNSIGNED aggregator in a generic metric-reading loop that iterates getDouble/getFloat/getLong; generic result-rendering code that assumes numeric aggregators; writing a custom post-aggregator that reads the intermediate bitmap value as a float.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/584dbda2714d2447. Report an issue: GitHub.