{"record":{"id":"3535aa2300403c0b","repo":"apache/beam","slug":"cross-join-join-on-false-is-not-supported","errorCode":null,"errorMessage":"CROSS JOIN, JOIN ON FALSE is not supported!","messagePattern":"CROSS JOIN, JOIN ON FALSE is not supported!","errorType":"exception","errorClass":"java.lang.UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/rel/BeamJoinRel.java","lineNumber":168,"sourceCode":"   * This method checks if a join is legal and can be converted into Beam SQL. It is used during\n   * planning and applying {@link\n   * org.apache.beam.sdk.extensions.sql.impl.rule.BeamJoinAssociateRule} and {@link\n   * org.apache.beam.sdk.extensions.sql.impl.rule.BeamJoinPushThroughJoinRule}\n   */\n  public static boolean isJoinLegal(Join join) {\n    try {\n      extractJoinRexNodes(join.getCondition());\n    } catch (UnsupportedOperationException e) {\n      return false;\n    }\n    return true;\n  }\n\n  static List<Pair<RexNode, RexNode>> extractJoinRexNodes(RexNode condition) {\n    // it's a CROSS JOIN because: condition == true\n    // or it's a JOIN ON false because: condition == false\n    if (condition instanceof RexLiteral) {\n      throw new UnsupportedOperationException(\"CROSS JOIN, JOIN ON FALSE is not supported!\");\n    }\n\n    RexCall call = (RexCall) condition;\n    List<Pair<RexNode, RexNode>> pairs = new ArrayList<>();\n    if (\"AND\".equals(call.getOperator().getName())) {\n      List<RexNode> operands = call.getOperands();\n      for (RexNode rexNode : operands) {\n        Pair<RexNode, RexNode> pair = extractJoinPairOfRexNodes((RexCall) rexNode);\n        pairs.add(pair);\n      }\n    } else if (\"=\".equals(call.getOperator().getName())) {\n      pairs.add(extractJoinPairOfRexNodes(call));\n    } else {\n      throw new UnsupportedOperationException(\n          \"Operator \" + call.getOperator().getName() + \" is not supported in join condition\");\n    }\n\n    return pairs;","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/rel/BeamJoinRel.java#L150-L186","documentation":"BeamJoinRel validates join conditions by extracting equi-join predicate pairs from the Calcite RexNode tree. A RexLiteral condition means the join has no column-pair predicate at all (CROSS JOIN, or JOIN ON TRUE/FALSE), which Beam SQL does not support, so it throws UnsupportedOperationException.","triggerScenarios":"Executing SQL like SELECT * FROM a CROSS JOIN b, or an explicit JOIN with a constant condition (ON TRUE / ON FALSE), so extractJoinRexNodes receives a RexLiteral instead of a RexCall.","commonSituations":"Porting queries written for databases that allow cross joins; accidentally omitting the ON clause; programmatic RelNode construction with a literal condition.","solutions":["Rewrite the query to include an equality join predicate, e.g. JOIN ... ON a.id = b.id","If a cartesian product is intended, add an explicit true equality filter inside a WHERE on unique keys or emulate with a cross product via UDFs (e.g. generate pairs then filter)","Handle the UnsupportedOperationException at the API layer and reject/rewrite the query before submission"],"exampleFix":"// before\nSELECT * FROM orders CROSS JOIN customers;\n// after\nSELECT * FROM orders JOIN customers ON orders.customer_id = customers.id;","handlingStrategy":"validation","validationCode":"// Reject constant join conditions client-side\nif (joinCondition == null || isConstantBooleanLiteral(joinCondition)) {\n  throw new IllegalArgumentException(\"CROSS JOIN / JOIN ON literal is not supported; provide an equi-join predicate\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  beamSqlEnv.sqlQuery(q).evaluate();\n} catch (UnsupportedOperationException e) {\n  if (e.getMessage().contains(\"CROSS JOIN, JOIN ON FALSE\")) {\n    q = rewriteToEquiJoinOrFilteredCrossProduct(q); // substitute an ON a.x = b.x predicate\n  } else throw e;\n}","preventionTips":["Always include an equality predicate in ON clauses","Never use ON TRUE/ON FALSE or bare CROSS JOIN","Review migrated SQL for cross-join patterns before running on Beam"],"tags":["sql","join","cross-join","beam"],"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"}