{"record":{"id":"93ec38a72b3ef96c","repo":"apache/druid","slug":"hyperuniquesaggregator-does-not-support-getdouble","errorCode":null,"errorMessage":"HyperUniquesAggregator does not support getDouble()","messagePattern":"HyperUniquesAggregator 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/HyperUniquesAggregator.java","lineNumber":81,"sourceCode":"    return HyperLogLogCollector.makeCollectorSharingStorage(collector);\n  }\n\n  @Override\n  public float getFloat()\n  {\n    throw new UnsupportedOperationException(\"HyperUniquesAggregator does not support getFloat()\");\n  }\n\n  @Override\n  public long getLong()\n  {\n    throw new UnsupportedOperationException(\"HyperUniquesAggregator does not support getLong()\");\n  }\n\n  @Override\n  public double getDouble()\n  {\n    throw new UnsupportedOperationException(\"HyperUniquesAggregator does not support getDouble()\");\n  }\n\n  @Override\n  public void close()\n  {\n    // no resources to cleanup\n  }\n}\n","sourceCodeStart":63,"sourceCodeEnd":90,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/query/aggregation/hyperloglog/HyperUniquesAggregator.java#L63-L90","documentation":"HyperUniquesAggregator's getDouble() throws UnsupportedOperationException. Although the sketch estimate is conceptually a double, the aggregator exposes it only through the sketch result path, so direct primitive accessors are deliberately unimplemented.","triggerScenarios":"Calling getDouble() on a HyperUniquesAggregator during generic numeric result extraction.","commonSituations":"Custom merge/extraction layers summing metrics as doubles; query engines or tools built against numeric-only aggregators being pointed at hyperUnique metrics.","solutions":["Use the sketch-based estimate (get()/getHyperLogLogCollector().estimateCardinality()) instead of getDouble()","Use UniquesAggregatorFactory's supported result/post-aggregator path for a double estimate","Branch on the aggregator factory's type name before numeric access","Prefer SQL APPROX_COUNT_DISTINCT_DS_HLL for a typed double result"],"exampleFix":"// before\ndouble d = agg.getDouble(); // throws\n// after\nHyperLogLogCollector hll = ((HyperUniquesAggregator) agg).getHyperLogLogCollector();\ndouble d2 = hll == null ? 0.0 : hll.estimateCardinality();","handlingStrategy":"type-guard","validationCode":"if (\"hyperUnique\".equals(factory.getTypeName())) { estimate = ((HyperUniquesAggregator) agg).getHyperLogLogCollector().estimateCardinality(); }","typeGuard":"static Double safeDouble(Aggregator a) { try { return a.getDouble(); } catch (UnsupportedOperationException e) { return null; } }","tryCatchPattern":"try { d = agg.getDouble(); } catch (UnsupportedOperationException e) { d = estimateFromSketch(agg); }","preventionTips":["Use estimateCardinality() on the sketch for double estimates","Never assume every Aggregator implements numeric getters","Cover non-numeric aggregator types in result-layer tests"],"tags":["java","druid","hyperloglog","aggregation","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"}