{"record":{"id":"841fe110327832d5","repo":"apache/druid","slug":"hyperuniquesbufferaggregator-does-not-support-getl","errorCode":null,"errorMessage":"HyperUniquesBufferAggregator does not support getLong()","messagePattern":"HyperUniquesBufferAggregator does not support getLong\\(\\)","errorType":"exception","errorClass":"java.lang.UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/query/aggregation/hyperloglog/HyperUniquesBufferAggregator.java","lineNumber":106,"sourceCode":"  }\n\n  @Override\n  public Object get(ByteBuffer buf, int position)\n  {\n    return doGet(buf, position);\n  }\n\n  @Override\n  public float getFloat(ByteBuffer buf, int position)\n  {\n    throw new UnsupportedOperationException(\"HyperUniquesBufferAggregator does not support getFloat()\");\n  }\n\n\n  @Override\n  public long getLong(ByteBuffer buf, int position)\n  {\n    throw new UnsupportedOperationException(\"HyperUniquesBufferAggregator does not support getLong()\");\n  }\n\n  @Override\n  public double getDouble(ByteBuffer buf, int position)\n  {\n    throw new UnsupportedOperationException(\"HyperUniquesBufferAggregator does not support getDouble()\");\n  }\n\n  @Override\n  public void close()\n  {\n    // no resources to cleanup\n  }\n\n  @Override\n  public void inspectRuntimeShape(RuntimeShapeInspector inspector)\n  {\n    inspector.visit(\"selector\", selector);","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/query/aggregation/hyperloglog/HyperUniquesBufferAggregator.java#L88-L124","documentation":"HyperUniquesAggregator aggregates HyperLogLog sketches which only support metric extraction as a complex object (HyperLogLogCollector). Druid's Aggregator interface requires getLong/getDouble/getFloat stubs, but sketch aggregation has no meaningful numeric value, so these accessors unconditionally throw UnsupportedOperationException to fail fast rather than return garbage.","triggerScenarios":"A query, post-aggregator, or aggregation code path calls getLong() on an uniques ('HLLSketch') aggregator — e.g. using a long-typed post-aggregator or a numeric accessor on a theta/hyperUnique metric instead of the appropriate sketch finalizer.","commonSituations":"Users write a custom post-aggregator or JavaScript post-aggregator over a hyperUnique metric expecting a numeric value; queries with finalization disabled reading raw aggregator state; version upgrades where the engine calls numeric accessors for a metric that only supports estimate()/sketch extraction.","solutions":["Do not read a hyperUnique aggregator as a long; use its finalized form (approxCountDistinct / HyperUniqueFinalizingPostAggregator or the estimate of the returned HyperLogLogCollector).","If a numeric value is needed in a post-aggregator, wrap the metric with HyperUniqueFinalizingPostAggregator (or in newer Druid use the sketch finalization) so the estimate is computed before numeric use.","If you implement custom aggregation code, check aggregator instanceof ComplexAggregator / cast to the expected type before calling getLong()."],"exampleFix":"// before\nPostAggregator est = new ArithmeticPostAggregator(\"est\", \"+\", Collections.singletonList(new FieldAccessPostAggregator(\"u\", \"uniques\")));\n// after\nPostAggregator est = new HyperUniqueFinalizingPostAggregator(\"est\", \"uniques\");","handlingStrategy":"type-guard","validationCode":"if (aggregator instanceof HyperUniquesAggregator || aggregator instanceof HyperUniquesBufferAggregator) { throw new IllegalStateException(\"Use HyperUniqueFinalizingPostAggregator for hyperUnique metrics, not numeric accessors\"); }","typeGuard":"boolean isSketchAggregator(Object agg) { return agg instanceof HyperUniquesAggregator || agg instanceof HyperUniquesBufferAggregator; }","tryCatchPattern":"try { return agg.getLong(); } catch (UnsupportedOperationException e) { return ((HyperLogLogCollector) agg.get()).estimate().longValue(); }","preventionTips":["Never attach numeric post-aggregators directly to hyperUnique metrics; wrap with HyperUniqueFinalizingPostAggregator.","Check the metric type from the aggregator factory before choosing numeric extraction code paths.","Treat sketch aggregators as complex metrics: always finalize before arithmetic.","Prefer ApproximateHistogram/sketch-aware query APIs over raw accessor calls."],"tags":["druid","aggregation","hyperloglog","unsupported-operation"],"backgroundTag":"unsupported-operation","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}