apache/beam · error · java.lang.UnsupportedOperationException

Operator ${operatorName} is not supported in join condition

Error message

Operator ${operatorName} is not supported in join condition

What it means

extractJoinRexNodes only understands join conditions that are AND-combinations or plain '=' comparisons. Any other operator at the top of the condition tree (OR, <, >, LIKE, etc.) cannot be decomposed into equi-join pairs, so it throws UnsupportedOperationException.

Source

Thrown at sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/rel/BeamJoinRel.java:182

  static List<Pair<RexNode, RexNode>> extractJoinRexNodes(RexNode condition) {
    // it's a CROSS JOIN because: condition == true
    // or it's a JOIN ON false because: condition == false
    if (condition instanceof RexLiteral) {
      throw new UnsupportedOperationException("CROSS JOIN, JOIN ON FALSE is not supported!");
    }

    RexCall call = (RexCall) condition;
    List<Pair<RexNode, RexNode>> pairs = new ArrayList<>();
    if ("AND".equals(call.getOperator().getName())) {
      List<RexNode> operands = call.getOperands();
      for (RexNode rexNode : operands) {
        Pair<RexNode, RexNode> pair = extractJoinPairOfRexNodes((RexCall) rexNode);
        pairs.add(pair);
      }
    } else if ("=".equals(call.getOperator().getName())) {
      pairs.add(extractJoinPairOfRexNodes(call));
    } else {
      throw new UnsupportedOperationException(
          "Operator " + call.getOperator().getName() + " is not supported in join condition");
    }

    return pairs;
  }

  private static Pair<RexNode, RexNode> extractJoinPairOfRexNodes(RexCall rexCall) {
    if (!rexCall.getOperator().getName().equals("=")) {
      throw new UnsupportedOperationException("Non equi-join is not supported");
    }

    if (isIllegalJoinConjunctionClause(rexCall)) {
      throw new UnsupportedOperationException(
          "Only support column reference or struct field access in conjunction clause");
    }

    int leftIndex = getColumnIndex(rexCall.getOperands().get(0));
    int rightIndex = getColumnIndex(rexCall.getOperands().get(1));

View on GitHub (pinned to 12126d8942)

Solutions

  1. Rewrite the condition to a conjunction of equality predicates (AND of column = column)
  2. Push non-equi predicates (ranges, ORs) into WHERE after the equi-join instead of the ON clause
  3. Use a JOIN with UDF-based co-grouping or flatten to a cross join plus filter if semantics require it

Example fix

// before
SELECT * FROM a JOIN b ON a.ts < b.ts;
// after
SELECT * FROM a JOIN b ON a.key = b.key WHERE a.ts < b.ts;
Defensive patterns

Strategy: validation

Validate before calling

// Only AND of '=' comparisons allowed at the top level
if (!(isAndCondition(joinCondition) || isEqualsCondition(joinCondition))) {
  throw new IllegalArgumentException("Join condition must be AND of '=' comparisons");
}

Try / catch

try {
  result = sqlEnv.sqlQuery(q).evaluate();
} catch (UnsupportedOperationException e) {
  if (e.getMessage().contains("is not supported in join condition")) {
    q = pushNonEquiPredicatesToWhere(q);
  } else throw e;
}

Prevention

When it happens

Trigger: A JOIN whose ON clause uses a top-level operator other than AND or =, e.g. JOIN ON a.id < b.id or ON a.id = b.id OR a.type = b.type.

Common situations: Writing range joins or OR-combined join keys common in relational SQL; migrating analytical queries that assume full join-condition support.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/5a47dfa4838c99a3. Report an issue: GitHub.