apache/seatunnel · error · IllegalArgumentException

Empty value list in IN clause is not allowed

Error message

Empty value list in IN clause is not allowed

What it means

An IN clause whose parenthesized list contains no values (col IN ()) is rejected. An empty IN predicate is semantically always false, and the converter refuses to build a Paimon predicate from an empty value list instead of producing a vacuous filter.

Solutions

  1. Guard the caller: if the collection is empty, skip the predicate or short-circuit the query to no rows.
  2. Emit `1 = 0` (always false) when an empty filter must remain valid SQL.
  3. Add a size check before building the WHERE clause.

Example fix

// before: 'id IN (' + join(ids) + ')' with empty ids | // after: if (ids.isEmpty()) skip pushdown or force empty result
Defensive patterns

Strategy: validation

Validate before calling

if (values == null || values.isEmpty()) { /* skip predicate or force empty result */ } else { buildSql(values); }

Try / catch

try { pred = converter.convertSqlWhereToPaimonPredicate(where, rowType); } catch (IllegalArgumentException e) { if (e.getMessage().contains("Empty value list")) return emptyResult(); throw e; }

Prevention

When it happens

Trigger: Dynamic SQL generation produces `col IN ()` when the caller's value collection is empty; string concatenation joins an empty list.

Common situations: Code building 'IN (' + join(values) + ')' with empty values; query builders emitting empty IN for empty collections.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/fd4ae9291f584d95. Report an issue: GitHub.

Appendix: source

Thrown at seatunnel-connectors-v2/connector-paimon/src/main/java/org/apache/seatunnel/connectors/seatunnel/paimon/source/converter/SqlToPaimonPredicateConverter.java:328

                "Unsupported expression type: " + expression.getClass().getSimpleName());
    }

    private static Predicate handleInExpression(
            PredicateBuilder builder, RowType rowType, InExpression expr) {
        Expression left = expr.getLeftExpression();
        Column column = safeGetColumn(left);
        int index = getColumnIndex(builder, column);

        Expression right = expr.getRightExpression();
        if (!(right instanceof ParenthesedExpressionList)) {
            throw new IllegalArgumentException(
                    "Unsupported right expression in IN: expected a parenthesized expression list");
        }

        ParenthesedExpressionList list = (ParenthesedExpressionList) right;
        List<Expression> expressions = list.getExpressions();
        if (expressions.isEmpty()) {
            throw new IllegalArgumentException("Empty value list in IN clause is not allowed");
        }

        List<Object> values = new ArrayList<>(expressions.size());
        for (Expression expression : expressions) {
            Object rawVal = getJSQLParserDataTypeValue(expression);
            if (rawVal == null) {
                throw new IllegalArgumentException("Null value found in IN clause values");
            }
            Object convertedVal =
                    convertValueByPaimonDataType(rowType, column.getColumnName(), rawVal);
            if (convertedVal == null) {
                throw new IllegalArgumentException(
                        "Failed to convert value in IN clause: " + rawVal);
            }
            values.add(convertedVal);
        }

        return expr.isNot() ? builder.notIn(index, values) : builder.in(index, values);

View on GitHub (pinned to cf67b549a7)