apache/seatunnel · error · IllegalArgumentException
Expected Column expression, but got
Error message
Expected Column expression, but got: ${expr.getClass().getSimpleName()} What it means
safeGetColumn requires the left-hand side of a comparison/IN expression to be a plain JSqlParser Column. Expressions such as function calls, casts, arithmetic, or literals on the left side are rejected because the converter can only resolve a column name to a Paimon predicate index.
Solutions
- Rewrite the predicate so a bare column is on the left: name='a' instead of UPPER(name)='A'.
- Remove CASTs and use literals matching the column type.
- Move function-based filtering to post-read processing or a transform.
- Normalize reversed comparisons (swap operands) before conversion.
Example fix
// before: WHERE UPPER(name) = 'JOHN' | // after: WHERE name = 'JOHN' (or filter after read)
Defensive patterns
Strategy: validation
Validate before calling
if (e instanceof BinaryExpression) { Expression left = ((BinaryExpression) e).getLeftExpression(); if (!(left instanceof Column)) throw new IllegalArgumentException("Left side must be a bare column"); } Type guard
boolean isColumn(Expression e) { return e instanceof Column; } Try / catch
try { pred = converter.convertSqlWhereToPaimonPredicate(where, rowType); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Expected Column")) { /* push filter to post-read */ } throw e; } Prevention
- Do not wrap the left operand in functions or CASTs in pushdown filters.
- Write comparisons as column OP literal, never literal OP column.
- Handle case-normalization (UPPER/LOWER) outside pushdown.
When it happens
Trigger: WHERE clause with a non-column left operand: UPPER(name)='A', CAST(id AS VARCHAR)='5', id+1=3, or a reversed comparison like 'a' = col.
Common situations: Users applying functions in filters expecting pushdown; literal-first comparisons; CASTs inserted by SQL dialect adapters.
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
- Error parsing SQL.
- Invalid LIKE pattern
- Only SELECT statements are supported.
- Only SELECT statements with WHERE clause are supported. The…
- Only simple SELECT statements are supported.
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/06b47588fa8f3cec.
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:351
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);
}
private static Column safeGetColumn(Expression expr) {
if (!(expr instanceof Column)) {
throw new IllegalArgumentException(
"Expected Column expression, but got: " + expr.getClass().getSimpleName());
}
return (Column) expr;
}
private static Object convertValueByPaimonDataType(
RowType rowType, String columnName, Object jsqlParserDataTypeValue) {
Optional<DataField> theFiled =
rowType.getFields().stream()
.filter(field -> field.name().equalsIgnoreCase(columnName.replace("`", "")))
.findFirst();
String strValue = jsqlParserDataTypeValue.toString();
if (theFiled.isPresent()) {
DataType dataType = theFiled.get().type();
switch (dataType.getTypeRoot()) {
case CHAR:
case VARCHAR:
return jsqlParserDataTypeValue;View on GitHub (pinned to cf67b549a7)