{"record":{"id":"5a2eed38e2ba72e8","repo":"apache/druid","slug":"operator-s-in-expression-s-s-s-is-not-supp","errorCode":null,"errorMessage":"operator '%s' in expression (%s %s %s) is not supported on type STRING.","messagePattern":"operator '(.+?)' in expression \\((.+?) (.+?) (.+?)\\) is not supported on type STRING\\.","errorType":"exception","errorClass":"IAE","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/math/expr/BinaryEvalOpExprBase.java","lineNumber":155,"sourceCode":"\n    ExpressionType type = ExpressionTypeConversion.autoDetect(leftVal, rightVal);\n    switch (type.getType()) {\n      case STRING:\n        return evalString(leftVal.asString(), rightVal.asString());\n      case LONG:\n        return ExprEval.of(evalLong(leftVal.asLong(), rightVal.asLong()));\n      case DOUBLE:\n      default:\n        if (leftVal.isNumericNull() || rightVal.isNumericNull()) {\n          return ExprEval.ofMissing();\n        }\n        return ExprEval.of(evalDouble(leftVal.asDouble(), rightVal.asDouble()));\n    }\n  }\n\n  protected ExprEval evalString(@Nullable String left, @Nullable String right)\n  {\n    throw new IAE(\n        \"operator '%s' in expression (%s %s %s) is not supported on type STRING.\",\n        this.op,\n        this.left.stringify(),\n        this.op,\n        this.right.stringify()\n    );\n  }\n\n  protected abstract long evalLong(long left, long right);\n\n  protected abstract double evalDouble(double left, double right);\n}\n\n@SuppressWarnings(\"ClassName\")\nabstract class BinaryBooleanOpExprBase extends BinaryOpExprBase\n{\n  BinaryBooleanOpExprBase(String op, Expr left, Expr right)\n  {","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/math/expr/BinaryEvalOpExprBase.java#L137-L173","documentation":"Binary operator expressions (e.g. '+', '&&', comparisons) in Druid expressions cannot be applied to STRING-typed operands. When the binary op's eval path dispatches to evalString, it unconditionally throws IllegalArgumentException because the operator has no defined string semantics.","triggerScenarios":"Evaluating a Druid native expression such as 'a + b' or 'a < b' where left or right operand evaluates to type STRING instead of a numeric/boolean type.","commonSituations":"Ingestion spec transforms/filters or SQL-level virtual columns referencing a string column with arithmetic; a column that was expected to be numeric is actually stored as string (schema drift); missing a CAST in the expression.","solutions":["Add an explicit cast in the expression, e.g. CAST(a AS DOUBLE) + CAST(b AS DOUBLE) or use numeric parse functions like ParseLong/ParseDouble","Verify the actual column types in the datasource; fix ingestion specs so the column is ingested as long/double instead of string","Rewrite the expression to use string-appropriate operators/functions instead of arithmetic/comparison ops"],"exampleFix":"// before: expression \"dim1 + dim2\" with string columns\n// after\n\"CAST(dim1 AS DOUBLE) + CAST(dim2 AS DOUBLE)\"","handlingStrategy":"type-guard","validationCode":"// Java-side guard before evaluating\nif (leftType.is(ExpressionType.STRING) || rightType.is(ExpressionType.STRING)) {\n  throw new IllegalArgumentException(\"string operands need CAST before binary operator\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  result = expr.eval(bindings);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"not supported on type STRING\")) {\n    // re-evaluate with casts or fail gracefully\n  } else { throw e; }\n}","preventionTips":["Never apply arithmetic/comparison ops directly on string columns","Use CAST or ParseLong/ParseDouble on string inputs","Validate column types against the expression before deployment"],"tags":["expressions","type-mismatch","string"],"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"}