{"record":{"id":"80dd6e4731f7607c","repo":"apache/druid","slug":"requires-a-thetasketch-as-the-argument","errorCode":null,"errorMessage":"requires a ThetaSketch as the argument","messagePattern":"requires a ThetaSketch as the argument","errorType":"exception","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/theta/sql/ThetaPostAggMacros.java","lineNumber":95,"sourceCode":"    {\n      super(macro, args);\n      this.estimateExpr = Iterables.getOnlyElement(args);\n    }\n\n    @Override\n    public ExprEval eval(ObjectBinding bindings)\n    {\n      ExprEval eval = estimateExpr.eval(bindings);\n      final Object valObj = eval.value();\n      if (valObj == null) {\n        return ExprEval.ofDouble(null);\n      }\n      if (valObj instanceof SketchHolder) {\n        SketchHolder thetaSketchHolder = (SketchHolder) valObj;\n        double estimate = thetaSketchHolder.getEstimate();\n        return ExprEval.of(estimate);\n      } else {\n        throw new IllegalArgumentException(\"requires a ThetaSketch as the argument\");\n      }\n    }\n\n    @Nullable\n    @Override\n    public ExpressionType getOutputType(InputBindingInspector inspector)\n    {\n      return ExpressionType.DOUBLE;\n    }\n  }\n\n  public static class ThetaSketchEstimateWithErrorBoundsExpr extends ExprMacroTable.BaseScalarMacroFunctionExpr\n  {\n    private Expr estimateExpr;\n    private Expr numStdDev;\n\n    public ThetaSketchEstimateWithErrorBoundsExpr(ThetaSketchEstimateWithErrorBoundsExprMacro macro, List<Expr> args)\n    {","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/theta/sql/ThetaPostAggMacros.java#L77-L113","documentation":"The THETA_SKETCH_ESTIMATE expression macro evaluates its argument expecting a SketchHolder (a theta sketch aggregation result). If the evaluated value is any other object, it throws an IllegalArgumentException because an estimate can only be computed from a theta sketch.","triggerScenarios":"Calling theta_estimate(expr) in a Druid SQL/expression context where expr resolves to a number, string, or non-theta complex type instead of a SketchHolder produced by a theta sketch aggregator.","commonSituations":"Applying theta_estimate to a plain numeric column or to a stringly-typed sketch column (e.g. base64 stored in a string column rather than a complex sketch column); using theta_estimate outside a query that includes the theta sketch aggregator in the same stage; version skew where the column's complex type registry lacks the theta serializer.","solutions":["Ensure the argument column is produced by a thetaSketch aggregator (a SketchHolder complex column) in the same query","Register/keep the datasketches extension loaded on all nodes so the complex column deserializes as a SketchHolder","Check the SQL query: use THETA_SKETCH_ESTIMATE with the aggregator's output, not a raw column","If reading stored sketches from a string column, convert them into a proper sketch complex column first"],"exampleFix":"// before\nSELECT THETA_SKETCH_ESTIMATE(user_id) FROM events -- user_id is a long\n// after\nSELECT THETA_SKETCH_ESTIMATE(theta_sketch) FROM (\n  SELECT APX_SKETCH_ESTIMATE(...)... -- or\n)\nSELECT APPROX_COUNT_DISTINCT_DS_THETA(user_id) FROM events -- correct: aggregator output is a SketchHolder","handlingStrategy":"type-guard","validationCode":"// in expression/SQL context, ensure the argument is the output of a theta sketch aggregator\nif (!(valObj instanceof SketchHolder)) {\n  throw new IllegalArgumentException(\"theta_estimate argument must be a theta sketch column\");\n}","typeGuard":"boolean isThetaSketch(Object o) {\n  return o instanceof SketchHolder;\n}","tryCatchPattern":"try {\n  ExprEval v = macro.eval(bindings);\n} catch (IllegalArgumentException e) {\n  // argument was not a SketchHolder; check the query uses the theta sketch aggregator output\n}","preventionTips":["Only apply theta_estimate to columns produced by thetaSketch aggregators","Use APPROX_COUNT_DISTINCT_DS_THETA for raw-column counting","Verify with EXPLAIN PLAN that the argument binds to a theta sketch complex column"],"tags":["java","datasketches","sql"],"backgroundTag":"type-mismatch","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}