{"record":{"id":"2f2432037bf4b262","repo":"apache/seatunnel","slug":"unsupported-expression-type-expression-getclass","errorCode":null,"errorMessage":"Unsupported expression type: ${expression.getClass().getSimpleName()}","messagePattern":"Unsupported expression type: (.+?)","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":309,"sourceCode":"            Pattern CONTAINS_PATTERN = Pattern.compile(\"^%([^%]+)%$\");\n            Matcher containsMatcher = CONTAINS_PATTERN.matcher(rightVal.toString());\n            if (containsMatcher.matches()) {\n                return builder.contains(\n                        columnIndex, BinaryString.fromString(containsMatcher.group(1)));\n            }\n            throw new IllegalArgumentException(\n                    String.format(\n                            \"Invalid LIKE pattern: '%s'. Supported patterns are: 'prefix%%', '%%suffix', and '%%substring%%'. \"\n                                    + \"Please ensure your pattern matches one of these formats.\",\n                            rightVal.toString()));\n\n        } else if (expression instanceof Parenthesis) {\n            Parenthesis parenthesis = (Parenthesis) expression;\n            return parseExpressionToPredicate(builder, rowType, parenthesis.getExpression());\n        } else if (expression instanceof InExpression) {\n            return handleInExpression(builder, rowType, (InExpression) expression);\n        }\n        throw new IllegalArgumentException(\n                \"Unsupported expression type: \" + expression.getClass().getSimpleName());\n    }\n\n    private static Predicate handleInExpression(\n            PredicateBuilder builder, RowType rowType, InExpression expr) {\n        Expression left = expr.getLeftExpression();\n        Column column = safeGetColumn(left);\n        int index = getColumnIndex(builder, column);\n\n        Expression right = expr.getRightExpression();\n        if (!(right instanceof ParenthesedExpressionList)) {\n            throw new IllegalArgumentException(\n                    \"Unsupported right expression in IN: expected a parenthesized expression list\");\n        }\n\n        ParenthesedExpressionList list = (ParenthesedExpressionList) right;\n        List<Expression> expressions = list.getExpressions();\n        if (expressions.isEmpty()) {","sourceCodeStart":291,"sourceCodeEnd":327,"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#L291-L327","documentation":"parseExpressionToPredicate throws this when a JSqlParser expression type in the WHERE clause has no conversion branch in the converter. Only comparison operators, LikeExpression, Parenthesis, InExpression, and logical AND/OR are handled; any other expression type reaches the final throw.","triggerScenarios":"A WHERE clause contains an unsupported expression type passed into convertSqlWhereToPaimonPredicate, e.g. BETWEEN, IS NULL / IS NOT NULL, function calls like UPPER(col)='X', arithmetic (a+1>5), or CASE expressions.","commonSituations":"Users assume full SQL predicate pushdown; upstream SQL generators emit IS NULL or BETWEEN clauses; JSqlParser version upgrades change the Expression class hierarchy so existing instanceof checks no longer match.","solutions":["Rewrite the WHERE clause using only supported operators: =, <>, >, >=, <, <=, LIKE (3 supported shapes), IN, AND/OR, parentheses.","Replace BETWEEN with col >= a AND col <= b.","Handle NULL checks outside pushdown or filter after read.","Add an instanceof branch to parseExpressionToPredicate if the expression type should be supported."],"exampleFix":"// before: WHERE ts BETWEEN '2024-01-01' AND '2024-02-01' | // after: WHERE ts >= '2024-01-01' AND ts <= '2024-02-01'","handlingStrategy":"validation","validationCode":"Set<Class<?>> OK = Set.of(EqualsTo.class, NotEqualsTo.class, GreaterThan.class, GreaterThanEquals.class, MinorThan.class, MinorThanEquals.class, LikeExpression.class, Parenthesis.class, InExpression.class, AndExpression.class, OrExpression.class); boolean convertible = OK.stream().anyMatch(c -> c.isInstance(expr));","typeGuard":"boolean isConvertible(Expression e) { return e instanceof BinaryExpression || e instanceof Parenthesis || e instanceof InExpression; }","tryCatchPattern":"try { pred = converter.convertSqlWhereToPaimonPredicate(where, rowType); } catch (IllegalArgumentException e) { log.warn(\"Unsupported expression, dropping pushdown: {}\", e.getMessage()); pred = null; }","preventionTips":["Restrict generated WHERE clauses to =,<>,>,>=,<,<=,LIKE,IN,AND/OR,parens.","Replace BETWEEN and IS NULL with supported equivalents or post-filters.","Pin the JSqlParser version and re-test after upgrades.","Add instanceof coverage tests for every operator your SQL layer can emit."],"tags":["sql","paimon","predicate-pushdown","unsupported-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-14T05:17:10.506Z"}