{"record":{"id":"38d38b59f0eb7d5e","repo":"apache/druid","slug":"hyperuniquesaggregator-does-not-support-getlong","errorCode":null,"errorMessage":"HyperUniquesAggregator does not support getLong()","messagePattern":"HyperUniquesAggregator 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/HyperUniquesAggregator.java","lineNumber":75,"sourceCode":"  {\n    if (collector == null) {\n      return null;\n    }\n    // Must make a new collector duplicating the underlying buffer to ensure the object from \"get\" is usable\n    // in a thread-safe manner.\n    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":57,"sourceCodeEnd":90,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/query/aggregation/hyperloglog/HyperUniquesAggregator.java#L57-L90","documentation":"HyperUniquesAggregator cannot return a long: the aggregator's product is an HLL sketch whose cardinality estimate is a double obtained through the sketch, not a long primitive. getLong() throws UnsupportedOperationException to prevent silent precision/type errors.","triggerScenarios":"Calling getLong() on a HyperUniquesAggregator when result extraction assumes integer metrics.","commonSituations":"Custom result serialization treating every aggregator as long; plugins replacing a count aggregator with hyperUnique without changing downstream accessors.","solutions":["Read the sketch via get()/getHyperLogLogCollector() and use its estimate (cast to long if integral output is desired)","Keep using the native query uniques result/post-aggregator path (e.g. cardinality post-agg) instead of direct getLong","Check the factory type name before calling getLong","In SQL, use APPROX_COUNT_DISTINCT_DS_HLL which yields a BIGINT-typed result"],"exampleFix":"// before\nlong l = agg.getLong(); // throws\n// after\nHyperLogLogCollector hll = ((HyperUniquesAggregator) agg).getHyperLogLogCollector();\nlong l2 = hll == null ? 0L : (long) hll.estimateCardinality();","handlingStrategy":"try-catch","validationCode":"if (!\"hyperUnique\".equals(factory.getTypeName())) { l = agg.getLong(); }","typeGuard":"static Long safeLong(Aggregator a) { try { return a.getLong(); } catch (UnsupportedOperationException e) { return null; } }","tryCatchPattern":"try { l = agg.getLong(); } catch (UnsupportedOperationException e) { l = (long) sketchEstimate(agg); }","preventionTips":["Derive cardinality estimates from the HLL sketch, then cast to long if needed","Check getTypeName() before integer access","Update integrations when swapping count metrics for hyperUnique"],"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"}