{"record":{"id":"82a3344ca795aee7","repo":"apache/druid","slug":"hyperuniquesbufferaggregator-does-not-support-getd","errorCode":null,"errorMessage":"HyperUniquesBufferAggregator does not support getDouble()","messagePattern":"HyperUniquesBufferAggregator does not support getDouble\\(\\)","errorType":"exception","errorClass":"java.lang.UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/query/aggregation/hyperloglog/HyperUniquesBufferAggregator.java","lineNumber":112,"sourceCode":"  }\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);\n  }\n}\n","sourceCodeStart":94,"sourceCodeEnd":127,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/query/aggregation/hyperloglog/HyperUniquesBufferAggregator.java#L94-L127","documentation":"Companion to the getLong() stub: HyperUniquesBufferAggregator accumulates HLL sketches in ByteBuffer state and cannot produce a double, so getDouble() throws UnsupportedOperationException unconditionally. The only supported extraction is the complex HyperLogLogCollector via get()/getComplexBufferAggregator-style accessors.","triggerScenarios":"Calling getDouble(ByteBuffer, int) on a hyperUnique buffer aggregator — typically from a double-typed post-aggregator or a numeric column-processor iterating over a sketch-typed metric.","commonSituations":"Same family as 1350: custom post-aggregation over uniques metrics, engines or tooling assuming all aggregators yield doubles/longs, incorrect query layer choosing numeric finalization for a complex metric.","solutions":["Use HyperUniqueFinalizingPostAggregator or a sketch-specific finalizer to obtain the estimate instead of getDouble().","Cast/inspect the aggregator type before invoking numeric accessors in custom code.","Switch the metric to a numeric aggregator if a raw double is truly what is needed."],"exampleFix":"// before\ndouble d = agg.getDouble(buf, pos);\n// after\nObject sketch = agg.get(buf, pos);\ndouble d = ((HyperLogLogCollector) sketch).estimate().doubleValue();","handlingStrategy":"type-guard","validationCode":"if (aggregator instanceof HyperUniquesBufferAggregator) { throw new IllegalStateException(\"hyperUnique aggregator supports no getDouble(); finalize via HyperUniqueFinalizingPostAggregator\"); }","typeGuard":"boolean isHyperUniqueBufferAgg(Aggregator a) { return a instanceof HyperUniquesBufferAggregator; }","tryCatchPattern":"try { return agg.getDouble(buf, pos); } catch (UnsupportedOperationException e) { return ((HyperLogLogCollector) agg.get(buf, pos)).estimate().doubleValue(); }","preventionTips":["Route sketch metrics through finalizing post-aggregators before any double arithmetic.","Inspect AggregatorFactory.getType() — expect 'hyperUnique'/'complex' and avoid numeric accessor paths.","Do not assume every Aggregator implements getDouble; the interface allows throwing.","Use QueryToolChest finalization hooks rather than manual buffer access."],"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"}