apache/beam · error · SqlConversionException

RexNode not supported: ${className}

Error message

RexNode not supported: ${className}

What it means

CEPOperation.of(RexNode) converts a Calcite RexNode expression tree into the CEP operation model. It only supports RexCall, RexLiteral, and RexPatternFieldRef; any other RexNode subclass (or unsupported RexCall kind) hits the else branch and raises SqlConversionException naming the offending class.

Source

Thrown at sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/cep/CEPOperation.java:45

/**
 * {@code CEPOperation} is the base class for the evaluation operations defined in the {@code
 * DEFINE} syntax of {@code MATCH_RECOGNIZE}. {@code CEPCall}, {@code CEPFieldRef}, {@code
 * CEPLiteral} are the subclasses of it.
 */
public abstract class CEPOperation implements Serializable {

  public static CEPOperation of(RexNode operation) {
    if (operation.getClass() == RexCall.class) {
      RexCall call = (RexCall) operation;
      return CEPCall.of(call);
    } else if (operation.getClass() == RexLiteral.class) {
      RexLiteral lit = (RexLiteral) operation;
      return CEPLiteral.of(lit);
    } else if (operation.getClass() == RexPatternFieldRef.class) {
      RexPatternFieldRef fieldRef = (RexPatternFieldRef) operation;
      return CEPFieldRef.of(fieldRef);
    } else {
      throw new SqlConversionException("RexNode not supported: " + operation.getClass().getName());
    }
  }
}

View on GitHub (pinned to 12126d8942)

Solutions

  1. Rewrite the query so DEFINE/MEASURES expressions only use simple field references, literals, and supported functions/operators.
  2. Remove subqueries, dynamic parameters, or non-deterministic expressions from the MATCH_RECOGNIZE clause.
  3. If the RexNode type is legitimately needed, extend CEPOperation.of() with a case handling that RexNode subclass.
  4. Check the named class in the message to identify exactly which expression shape was rejected.

Example fix

// before (unsupported)
MATCH_RECOGNIZE (...) DEFINE A AS PREV(A.price) + (SELECT max(x) FROM t)
// after
MATCH_RECOGNIZE (...) DEFINE A AS PREV(A.price) + A.price
Defensive patterns

Strategy: validation

Validate before calling

// Validate expression shapes before running MATCH_RECOGNIZE
for (RexNode n : defineExprs) {
  if (!(n instanceof RexCall || n instanceof RexLiteral || n instanceof RexPatternFieldRef)) {
    throw new IllegalArgumentException("Unsupported RexNode in MATCH_RECOGNIZE: " + n.getClass());
  }
}

Type guard

boolean isSupportedRex(RexNode n) { return n instanceof RexCall || n instanceof RexLiteral || n instanceof RexPatternFieldRef; }

Try / catch

try { return CEPOperation.of(node); } catch (SqlConversionException e) { throw new QueryValidationException("Unsupported expression in MATCH_RECOGNIZE: " + e.getMessage(), e); }

Prevention

When it happens

Trigger: A MATCH_RECOGNIZE query whose PATTERN/DEFINE/MEASURES expression compiles to a RexNode type outside the supported set — e.g. RexDynamicParam, RexInputRef, RexSubQuery, or exotic RexCall operators not mapped by the converter.

Common situations: Using subqueries, dynamic parameters, or unsupported SQL functions inside MATCH_RECOGNIZE clauses; Calcite optimizer rewrites producing RexNode shapes the CEP translator does not anticipate.

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/55c24ecc8f27cf1a. Report an issue: GitHub.