{"record":{"id":"367b6e8e52fb3cb6","repo":"apache/beam","slug":"operator-s-is-not-supported-in-join-condition","errorCode":null,"errorMessage":"Operator %s is not supported in join condition","messagePattern":"Operator (.+?) is not supported in join condition","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/transform/BeamJoinTransforms.java","lineNumber":140,"sourceCode":"      factJoinIdx = new ArrayList<>();\n      List<Schema.Field> lkpJoinFields = new ArrayList<>();\n\n      RexCall call = (RexCall) joinCondition;\n      if (\"AND\".equals(call.getOperator().getName())) {\n        List<RexNode> operands = call.getOperands();\n        for (RexNode rexNode : operands) {\n          factJoinIdx.add(\n              ((RexInputRef) ((RexCall) rexNode).getOperands().get(0)).getIndex() - factColOffset);\n          int lkpJoinIdx =\n              ((RexInputRef) ((RexCall) rexNode).getOperands().get(1)).getIndex() - lkpColOffset;\n          lkpJoinFields.add(lkpSchema.getField(lkpJoinIdx));\n        }\n      } else if (\"=\".equals(call.getOperator().getName())) {\n        factJoinIdx.add(((RexInputRef) call.getOperands().get(0)).getIndex() - factColOffset);\n        int lkpJoinIdx = ((RexInputRef) call.getOperands().get(1)).getIndex() - lkpColOffset;\n        lkpJoinFields.add(lkpSchema.getField(lkpJoinIdx));\n      } else {\n        throw new UnsupportedOperationException(\n            \"Operator \" + call.getOperator().getName() + \" is not supported in join condition\");\n      }\n\n      joinSubsetType = Schema.builder().addFields(lkpJoinFields).build();\n    }\n\n    @Override\n    public PCollection<Row> expand(PCollection<Row> input) {\n      return input\n          .apply(\n              \"join_as_lookup\",\n              ParDo.of(\n                  new DoFn<Row, Row>() {\n                    @Setup\n                    public void setup() {\n                      seekableTable.setUp(joinSubsetType);\n                    }\n","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/transform/BeamJoinTransforms.java#L122-L158","documentation":"BeamJoinTransforms.JoinAsLookup.joinFieldsMapping only handles equality ('=') predicates when extracting the join condition between the fact table and the lookup side. Any other operator in the join condition throws UnsupportedOperationException naming the offending operator.","triggerScenarios":"Declaring a JOIN whose ON clause uses !=, <, >, <=, >=, LIKE, or a compound non-equality condition on a join that Beam SQL resolves through the lookup-join transform.","commonSituations":"Writing theta joins or range joins (e.g. ON a.id != b.id or ON a.ts < b.ts) against a side input/lookup table; expecting general join predicates where only equi-joins are supported.","solutions":["Rewrite the join condition as an equality predicate (equi-join)","Pre-filter or pre-compute the relationship outside the JOIN (e.g. filter after joining on equality keys)","Re-implement the join manually with CoGroupByKey or side inputs supporting the predicate","Use a join strategy in Beam SQL that supports non-equi predicates if available in your version"],"exampleFix":"// before\nString sql = \"SELECT * FROM orders o JOIN dim d ON o.country <> d.code\";\n// after\nString sql = \"SELECT * FROM orders o JOIN dim d ON o.country = d.code WHERE o.country <> d.code\";","handlingStrategy":"validation","validationCode":"// Inspect join condition operators before submitting the SQL\nif (!joinConditionOps.stream().allMatch(op -> op.equals(\"=\"))) {\n  throw new IllegalArgumentException(\"Lookup join supports only '=' conditions, found: \" + joinConditionOps);\n}","typeGuard":null,"tryCatchPattern":"try {\n  result = beamSqlCtx.run(sql);\n} catch (UnsupportedOperationException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"not supported in join condition\")) {\n    throw new IllegalArgumentException(\"Rewrite join as equi-join\", e);\n  }\n  throw e;\n}","preventionTips":["Use equi-joins (ON a.key = b.key) with lookup joins","Apply inequality filters after the join","Check supported join predicate documentation for your Beam version","Validate join conditions in query linting before submission"],"tags":["java","apache-beam","sql","join","unsupported-operation"],"backgroundTag":"unsupported-operation","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}