{"record":{"id":"06b47588fa8f3cec","repo":"apache/seatunnel","slug":"expected-column-expression-but-got-expr-getcla","errorCode":null,"errorMessage":"Expected Column expression, but got: ${expr.getClass().getSimpleName()}","messagePattern":"Expected Column expression, but got: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-paimon/src/main/java/org/apache/seatunnel/connectors/seatunnel/paimon/source/converter/SqlToPaimonPredicateConverter.java","lineNumber":351,"sourceCode":"            Object rawVal = getJSQLParserDataTypeValue(expression);\n            if (rawVal == null) {\n                throw new IllegalArgumentException(\"Null value found in IN clause values\");\n            }\n            Object convertedVal =\n                    convertValueByPaimonDataType(rowType, column.getColumnName(), rawVal);\n            if (convertedVal == null) {\n                throw new IllegalArgumentException(\n                        \"Failed to convert value in IN clause: \" + rawVal);\n            }\n            values.add(convertedVal);\n        }\n\n        return expr.isNot() ? builder.notIn(index, values) : builder.in(index, values);\n    }\n\n    private static Column safeGetColumn(Expression expr) {\n        if (!(expr instanceof Column)) {\n            throw new IllegalArgumentException(\n                    \"Expected Column expression, but got: \" + expr.getClass().getSimpleName());\n        }\n        return (Column) expr;\n    }\n\n    private static Object convertValueByPaimonDataType(\n            RowType rowType, String columnName, Object jsqlParserDataTypeValue) {\n        Optional<DataField> theFiled =\n                rowType.getFields().stream()\n                        .filter(field -> field.name().equalsIgnoreCase(columnName.replace(\"`\", \"\")))\n                        .findFirst();\n        String strValue = jsqlParserDataTypeValue.toString();\n        if (theFiled.isPresent()) {\n            DataType dataType = theFiled.get().type();\n            switch (dataType.getTypeRoot()) {\n                case CHAR:\n                case VARCHAR:\n                    return jsqlParserDataTypeValue;","sourceCodeStart":333,"sourceCodeEnd":369,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-paimon/src/main/java/org/apache/seatunnel/connectors/seatunnel/paimon/source/converter/SqlToPaimonPredicateConverter.java#L333-L369","documentation":"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.","triggerScenarios":"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.","commonSituations":"Users applying functions in filters expecting pushdown; literal-first comparisons; CASTs inserted by SQL dialect adapters.","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."],"exampleFix":"// before: WHERE UPPER(name) = 'JOHN' | // after: WHERE name = 'JOHN' (or filter after read)","handlingStrategy":"validation","validationCode":"if (e instanceof BinaryExpression) { Expression left = ((BinaryExpression) e).getLeftExpression(); if (!(left instanceof Column)) throw new IllegalArgumentException(\"Left side must be a bare column\"); }","typeGuard":"boolean isColumn(Expression e) { return e instanceof Column; }","tryCatchPattern":"try { pred = converter.convertSqlWhereToPaimonPredicate(where, rowType); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith(\"Expected Column\")) { /* push filter to post-read */ } throw e; }","preventionTips":["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."],"tags":["sql","paimon","predicate-pushdown","column-expression"],"backgroundTag":"unsupported-operation","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}