apache/seatunnel · error · UnsupportedOperationException

Unsupported condition:

Error message

Unsupported condition: 

What it means

SeaTunnel's Iceberg connector converts a SQL WHERE clause (parsed with JSqlParser) into an Iceberg Expression via ExpressionUtils.convert. When the condition expression's class is not one of the supported comparison types (EqualsTo, GreaterThan, LikeExpression variants, etc.), convert throws UnsupportedOperationException with the Java class name of the condition. This is a deliberate limitation of the predicate push-down translator, not a data error.

Source

Thrown at seatunnel-connectors-v2/connector-iceberg/src/main/java/org/apache/seatunnel/connectors/seatunnel/iceberg/utils/ExpressionUtils.java:250

            Column column = (Column) booleanExpression.getLeftExpression();
            if (booleanExpression.isNot()) {
                return Expressions.notEqual(column.getColumnName(), booleanExpression.isTrue());
            }
            return Expressions.equal(column.getColumnName(), booleanExpression.isTrue());
        }
        if (condition instanceof LikeExpression) {
            LikeExpression expr = (LikeExpression) condition;
            String columnName = ((Column) expr.getLeftExpression()).getColumnName();
            String value = ((StringValue) expr.getRightExpression()).getValue();
            LikeExpression.KeyWord keyWord = expr.getLikeKeyWord();
            if (keyWord == LikeExpression.KeyWord.LIKE) {
                return Expressions.startsWith(columnName, value);
            } else {
                throw new UnsupportedOperationException("Unsupported like keyword: " + keyWord);
            }
        }

        throw new UnsupportedOperationException(
                "Unsupported condition: " + condition.getClass().getName());
    }

    @SneakyThrows
    private static Object convertValueExpression(
            net.sf.jsqlparser.expression.Expression valueExpression,
            Types.NestedField icebergColumn) {
        switch (icebergColumn.type().typeId()) {
            case DECIMAL:
                return new BigDecimal(valueExpression.toString());
            case DATE:
                if (valueExpression instanceof StringValue) {
                    LocalDate date =
                            LocalDate.parse(
                                    ((StringValue) valueExpression).getValue(), ISO_LOCAL_DATE);
                    return DateTimeUtil.daysFromDate(date);
                }
            case TIME:

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Rewrite the WHERE clause to use only supported operators (=, <>, >, >=, <, <=, LIKE with supported keywords) and re-run the job
  2. Push down only supported predicates and apply the remaining filtering downstream, e.g. move IN/BETWEEN logic into a SeaTunnel SQL transform
  3. Add a new branch in ExpressionUtils.convert handling the reported condition class (the class name in the message tells you exactly which node is missing)
  4. Use a SeaTunnel SQL transform instead of source-level predicate push-down for the unsupported expression

Example fix

// before
String query = "SELECT * FROM db.t WHERE id IN (1,2)";
// after (supported predicate)
String query = "SELECT * FROM db.t WHERE id = 1"; // or OR id = 2
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate condition classes before conversion
net.sf.jsqlparser.expression.Expression where = stmt.getWhere();
if (!(where instanceof BinaryExpression || where instanceof LikeExpression)) {
    throw new IllegalArgumentException("Unsupported predicate: " + where.getClass().getSimpleName());
}

Type guard

boolean isSupported(net.sf.jsqlparser.expression.Expression e) {
    return e instanceof EqualsTo || e instanceof NotEqualsTo || e instanceof GreaterThan
        || e instanceof GreaterThanEquals || e instanceof MinorThan || e instanceof MinorThanEquals
        || e instanceof LikeExpression;
}

Try / catch

try {
    Expression icebergExpr = ExpressionUtils.convert(whereClause);
} catch (UnsupportedOperationException e) {
    log.warn("Predicate not pushed down: {}", e.getMessage());
    return Expressions.alwaysTrue(); // fall back to full scan + client-side filter
}

Prevention

When it happens

Trigger: Calling parseWhereClauseToIcebergExpression or convertDeleteSQL with a WHERE clause containing an unsupported condition type, e.g. IS NULL / IS NOT NULL, IN expressions, BETWEEN, a function call, or a subquery — anything whose JSqlParser class is not matched by the if/else chain in convert.

Common situations: Users configure an Iceberg source query with 'WHERE col IN (1,2)' or 'WHERE col BETWEEN a AND b'; developers extend filter support but pass unhandled AST nodes like Parenthesis into ExpressionUtils.convert.

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/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/52d2437bbae5a9ee. Report an issue: GitHub.