{"record":{"id":"38ddcb766d9b4863","repo":"apache/druid","slug":"expression-s-has-non-constant-inputs","errorCode":null,"errorMessage":"Expression %s has non-constant inputs.","messagePattern":"Expression (.+?) has non-constant inputs\\.","errorType":"exception","errorClass":"UOE","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/math/expr/InputBindings.java","lineNumber":73,"sourceCode":"   */\n  public static Expr.ObjectBinding nilBindings()\n  {\n    return NIL_BINDINGS;\n  }\n\n  /**\n   * Empty binding that throw a {@link UOE} if anything attempts to lookup an identifier type or value\n   */\n  public static Expr.ObjectBinding validateConstant(Expr expr)\n  {\n    return new Expr.ObjectBinding()\n    {\n      @Nullable\n      @Override\n      public Object get(String name)\n      {\n        // Sanity check. Bindings should not be used for a constant expression so explode if something tried\n        throw new UOE(\"Expression \" + expr.stringify() + \" has non-constant inputs.\");\n      }\n\n      @Nullable\n      @Override\n      public ExpressionType getType(String name)\n      {\n        // Sanity check. Bindings should not be used for a constant expression so explode if something tried\n        throw new UOE(\"Expression \" + expr.stringify() + \" has non-constant inputs.\");\n      }\n    };\n  }\n\n  /**\n   * Create an {@link Expr.InputBindingInspector} backed by a map of binding identifiers to their {@link ExprType}\n   */\n  public static Expr.InputBindingInspector inspectorFromTypeMap(final Map<String, ExpressionType> types)\n  {\n    return new Expr.InputBindingInspector()","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/math/expr/InputBindings.java#L55-L91","documentation":"InputBindings.forMapWithConstantExpr creates an Expr.InputBindingInspector whose get() can never supply inputs; it exists only for constant expressions. If expression evaluation or planning asks this binding for an input identifier, the code treats it as a programming error and throws UOE (Unsupported Operation Exception). It is a sanity-check guard, not a user-input validation.","triggerScenarios":"Calling Parser.parse(..., true) and then evaluating/planning the resulting Expr with constant bindings (InputBindings.forMapWithConstantExpr) when the expression actually references identifiers (e.g. \"x + 1\" instead of \"1 + 1\"). The get(String) binding accessor is then invoked for identifier 'x'.","commonSituations":"Precomputing a constant-folded expression during query planning; using expressions intended to be literal-only (e.g. timestamp math constants) but accidentally passing a column/variable reference; refactoring that changed a literal expression into one with bindings.","solutions":["Fix the expression so it contains no identifiers — make all inputs literal constants.","If bindings are genuinely needed, use InputBindings.forMap(Map) or a real Expr.ObjectBinding instead of the constant-expr binding.","Check the caller that supplies the Expr; ensure only constant expressions are routed through the constant-binding path."],"exampleFix":"// before\nExpr e = Parser.parse(\"x + 1\", null);\neval(e, InputBindings.forMapWithConstantExpr(e));\n// after\nExpr e = Parser.parse(\"1 + 1\", null); // or use InputBindings.forMap(Map.of(\"x\", 1))\neval(e, InputBindings.forMap(Map.of(\"x\", 1)));","handlingStrategy":"validation","validationCode":"if (!expr.analyzeInputs().getRequiredBindings().isEmpty()) {\n  throw new IllegalArgumentException(\"expression must be constant for constant bindings: \" + expr.stringify());\n}","typeGuard":null,"tryCatchPattern":"try { eval(expr, InputBindings.forMapWithConstantExpr(expr)); } catch (UnsupportedOperationException e) { /* fall back to map-backed bindings */ }","preventionTips":["Only route expressions verified to have zero required bindings through constant bindings","Prefer InputBindings.forMap as the default binding choice","Unit-test expression constants with representative inputs"],"tags":["expression","bindings","unsupported-operation","druid"],"backgroundTag":"unsupported-operation","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}