apache/beam · error · RuntimeException

Encountered an unexpected node kind: ${node.getKind()}

Error message

Encountered an unexpected node kind: ${node.getKind()}

What it means

After the operand and AND/OR handling in MongoDbTable.translateRexNodeToBson, any remaining RexNode kind falls through the switch and reaches the terminal throw reporting the unhandled SqlKind. It is a catch-all for predicate shapes the BSON filter builder never learned to translate.

Source

Thrown at sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/meta/provider/mongodb/MongoDbTable.java:279

        switch (node.getKind()) {
          case AND:
            // Recursively construct filter for each operand of conjunction.
            return Filters.and(
                compositeNode.getOperands().stream()
                    .map(this::translateRexNodeToBson)
                    .collect(Collectors.toList()));
          case OR:
            // Recursively construct filter for each operand of disjunction.
            return Filters.or(
                compositeNode.getOperands().stream()
                    .map(this::translateRexNodeToBson)
                    .collect(Collectors.toList()));
          default:
            // Encountered an unexpected node kind, RuntimeException below.
            break;
        }
      }
      throw new RuntimeException(
          "Encountered an unexpected node kind: " + node.getKind().toString());
    } else if (node instanceof RexInputRef
        && node.getType().getSqlTypeName().equals(SqlTypeName.BOOLEAN)) {
      // Boolean field, must be true. Ex: `select * from table where bool_field`
      return Filters.eq(fieldIdToName.apply(((RexInputRef) node).getIndex()), true);
    }

    throw new RuntimeException(
        "Was expecting a RexCall or a boolean RexInputRef, but received: "
            + node.getClass().getSimpleName());
  }

  private Object convertToExpectedType(RexInputRef inputRef, RexLiteral literal) {
    FieldType beamFieldType = getSchema().getField(inputRef.getIndex()).getType();

    return literal.getValueAs(
        FieldTypeDescriptors.javaTypeForFieldType(beamFieldType).getRawType());
  }

View on GitHub (pinned to 12126d8942)

Solutions

  1. Replace IS NULL/IS NOT NULL predicates with equivalent comparisons (e.g. field IS NOT NULL with a range check or handle client-side).
  2. Restructure the query so unsupported predicates are evaluated post-scan by Beam rather than pushed down.
  3. Extend the switch in translateRexNodeToBson to translate the missing SqlKind (e.g. Filters.exists for IS NOT NULL).

Example fix

// before
SELECT * FROM t WHERE field IS NOT NULL
// after
SELECT * FROM t WHERE field >= 0 OR field < 0  -- or evaluate client-side
Defensive patterns

Strategy: validation

Validate before calling

Set<SqlKind> known = EnumSet.of(SqlKind.EQUALS, SqlKind.NOT_EQUALS, SqlKind.LESS_THAN, SqlKind.GREATER_THAN, SqlKind.LESS_THAN_OR_EQUAL, SqlKind.GREATER_THAN_OR_EQUAL, SqlKind.AND, SqlKind.OR);
if (!known.contains(node.getKind())) throw new IllegalArgumentException("Not pushable: " + node.getKind());

Try / catch

try { return MongoDbFilter.create(cnf); } catch (RuntimeException e) { return null; /* full scan */ }

Prevention

When it happens

Trigger: A WHERE clause predicate whose RexNode kind is outside the implemented set (e.g. CASE, IS NULL/IS NOT NULL, IN with unusual shapes) reaches the fall-through 'throw new RuntimeException("Encountered an unexpected node kind: ...")'.

Common situations: Using IS NULL / IS NOT NULL checks or IN lists against MongoDb external tables; complex boolean expressions produced by the Calcite optimizer's rewrites.

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/24f3593e1e2a6bdb. Report an issue: GitHub.