{"record":{"id":"3033cef543adca8f","repo":"apache/druid","slug":"cannot-handle-constant-condition-s","errorCode":null,"errorMessage":"Cannot handle constant condition: %s","messagePattern":"Cannot handle constant condition: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"multi-stage-query/src/main/java/org/apache/druid/msq/querykit/common/SortMergeJoinStageProcessor.java","lineNumber":267,"sourceCode":"        retVal.add(i);\n      }\n    }\n\n    return retVal.toArray(new int[0]);\n  }\n\n  /**\n   * Validates that a join condition can be handled by this processor. Returns the condition if it can be handled.\n   * Throws {@link IllegalArgumentException} if the condition cannot be handled.\n   */\n  public static JoinConditionAnalysis validateCondition(final JoinConditionAnalysis condition)\n  {\n    if (condition.isAlwaysTrue()) {\n      return condition;\n    }\n\n    if (condition.isAlwaysFalse()) {\n      throw new IAE(\"Cannot handle constant condition: %s\", condition.getOriginalExpression());\n    }\n\n    if (condition.getNonEquiConditions().size() > 0) {\n      throw new IAE(\"Cannot handle non-equijoin condition: %s\", condition.getOriginalExpression());\n    }\n\n    if (condition.getEquiConditions().stream().anyMatch(c -> !c.getLeftExpr().isIdentifier())) {\n      throw new IAE(\n          \"Cannot handle equality condition involving left-hand expression: %s\",\n          condition.getOriginalExpression()\n      );\n    }\n\n    return condition;\n  }\n\n  /**\n   * Validates that all signatures from {@link #collectAndReadPartitions(ExecutionContext)} are prefixed by the","sourceCodeStart":249,"sourceCodeEnd":285,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/multi-stage-query/src/main/java/org/apache/druid/msq/querykit/common/SortMergeJoinStageProcessor.java#L249-L285","documentation":"MSQ's sort-merge join only supports equi-join conditions that are neither always-true nor always-false and contain no non-equi predicates. validateCondition rejects a constant FALSE condition (and separately non-equi conditions) because the merge algorithm cannot evaluate such a join. Always-true conditions (cross join) are allowed through.","triggerScenarios":"A JOIN whose ON clause evaluates to a constant false (e.g. ON 1=0, or conflicting literal predicates like ON a.k = b.k AND 1 = 2), reaching SortMergeJoinStageProcessor construction; or an ON clause with non-equi predicates like a.k < b.k.","commonSituations":"Dynamically generated SQL where filters collapse the ON clause to FALSE; hand-written joins with inequality predicates (range joins) assumed to be supported by MSQ; optimizer passthrough of contradictory conditions.","solutions":["Fix the SQL so the ON clause is a real equi-condition on join columns (e.g. a.k = b.k)","Remove contradictory literal predicates from the ON clause; if a cross join is intended, use ON TRUE or a comma join","Move non-equi conditions (e.g. a.start < b.end) to the WHERE clause or restructure as an equi-join plus filter","Run the query on the native engine if a range/non-equi join is truly required"],"exampleFix":"// before\nSELECT * FROM a JOIN b ON a.k = b.k AND 1 = 0\n// after\nSELECT * FROM a JOIN b ON a.k = b.k","handlingStrategy":"validation","validationCode":"// Validate ON clause before running on MSQ\nJoinConditionAnalysis cond = JoinConditionAnalysis.forExpression(onExpr, \"j\", exprParser);\nif (cond.isAlwaysFalse()) {\n  throw new IllegalArgumentException(\"MSQ sort-merge join cannot handle always-false ON: \" + onExpr);\n}\nif (!cond.getNonEquiConditions().isEmpty()) {\n  throw new IllegalArgumentException(\"Only equi-joins are supported by MSQ: \" + onExpr);\n}","typeGuard":null,"tryCatchPattern":"try {\n  runMsqQuery(query);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"Cannot handle\")) {\n    // rewrite SQL to an equi-join or route to the native engine\n  }\n}","preventionTips":["Always write ON clauses as column equality predicates","Strip literal/contradictory conditions from generated SQL","Use WHERE for non-equi filters and keep ON strictly equi-join"],"tags":["msq","join","sql","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-14T11:17:12.474Z"}