apache/beam · error · java.lang.UnsupportedOperationException
Unexpected RexNode encountered
Error message
Unexpected RexNode encountered: ${className} What it means
During I/O push-down optimization, BeamIOPushDownRule walks the RexNode expressions of a Calc to determine which input fields are used. Only RexInputRef (column refs) and RexLiteral are handled; any other RexNode subclass triggers an UnsupportedOperationException.
Solutions
- Simplify the SQL expression so it uses only plain column references and literals
- Restructure the query to move complex expressions out of the pushed-down Calc
- Upgrade Beam, which may add handling for more RexNode types
Example fix
// before SELECT CASE WHEN f1 > 0 THEN f1 ELSE -f1 END FROM t // after SELECT f1 FROM t -- compute the CASE expression after IO push-down, outside the optimized Calc
Defensive patterns
Strategy: type-guard
Type guard
boolean isSupportedRexNode(RexNode n) { return n instanceof RexInputRef || n instanceof RexLiteral; } Try / catch
try { plan = optimizer.transform(...) } catch (UnsupportedOperationException e) { plan = unoptimizedPlan; } Prevention
- Keep pushed-down projections to simple column refs and literals
- Test queries with complex CASE/function expressions against the Beam version
- Handle the exception by falling back to the unoptimized plan
When it happens
Trigger: A Calc node whose condition/expression list contains an unhandled RexNode type (e.g. RexCall composed in an unexpected way, RexFieldAccess) while the push-down rule calls findUtilizedInputRefs via onMatch.
Common situations: Complex SQL projections or filters (CASE expressions, nested function calls, subquery-derived refs) hitting the optimizer; often surfaces after Calcite upgrades change RexNode shape.
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
- Aggregator [ ] is not supported
- Attempting to create database
- Attempting to 'USE CATALOG
- Does not support
- Encountered an unexpected node type
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/8f5b675eba335c63.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/rule/BeamIOPushDownRule.java:210
while (!prerequisites.isEmpty()) {
RexNode node = prerequisites.poll();
if (node instanceof RexCall) { // Composite expression, example: "=($t11, $t12)"
RexCall compositeNode = (RexCall) node;
// Expression from example above contains 2 operands: $t11, $t12
prerequisites.addAll(compositeNode.getOperands());
} else if (node instanceof RexInputRef) { // Input reference
// Find a field in an inputRowType for the input reference
int inputFieldIndex = ((RexInputRef) node).getIndex();
RelDataTypeField field = inputRowType.getFieldList().get(inputFieldIndex);
// If we have not seen it before - add it to the list (hash set)
usedFields.add(field.getName());
} else if (node instanceof RexLiteral) {
// Does not contain information about columns utilized by a Calc
} else {
throw new UnsupportedOperationException(
"Unexpected RexNode encountered: " + node.getClass().getSimpleName());
}
}
}
/**
* Recursively reconstruct a {@code RexNode}, mapping old RexInputRefs to new.
*
* @param node {@code RexNode} to reconstruct.
* @param inputRefMapping Mapping from old {@code RexInputRefNode} indexes to new, where list
* index is the new {@code RexInputRefNode} and the value is old {@code RexInputRefNode}.
* @return reconstructed {@code RexNode} with {@code RexInputRefNode} remapped to new values.
*/
@VisibleForTesting
RexNode reMapRexNodeToNewInputs(RexNode node, List<Integer> inputRefMapping) {
if (node instanceof RexInputRef) {
int oldInputIndex = ((RexInputRef) node).getIndex();
int newInputIndex = inputRefMapping.indexOf(oldInputIndex);View on GitHub (pinned to 12126d8942)