{"record":{"id":"d1c21532ff201d29","repo":"apache/shardingsphere","slug":"unsupported-operator-s-in-page-expression","errorCode":null,"errorMessage":"Unsupported operator: %s in page expression","messagePattern":"Unsupported operator: (.+?) in page expression","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/dml/pagination/rownum/ExpressionRowNumberValueSegment.java","lineNumber":75,"sourceCode":"        }\n        throw new UnsupportedOperationException(String.format(\"Unsupported expression: %s in page expression\", expressionSegment.getClass().getName()));\n    }\n    \n    private Long getValueFromBinaryOperationExpression(final BinaryOperationExpression binaryOperationExpression, final List<Object> params) {\n        String operator = binaryOperationExpression.getOperator();\n        Long leftValue = getValueFromExpression(binaryOperationExpression.getLeft(), params);\n        Long rightValue = getValueFromExpression(binaryOperationExpression.getRight(), params);\n        switch (operator) {\n            case \"+\":\n                return leftValue + rightValue;\n            case \"-\":\n                return leftValue - rightValue;\n            case \"*\":\n                return leftValue * rightValue;\n            case \"/\":\n                return leftValue / rightValue;\n            default:\n                throw new UnsupportedOperationException(String.format(\"Unsupported operator: %s in page expression\", operator));\n        }\n    }\n}\n","sourceCodeStart":57,"sourceCodeEnd":79,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/dml/pagination/rownum/ExpressionRowNumberValueSegment.java#L57-L79","documentation":"Thrown by ExpressionRowNumberValueSegment.getValueFromBinaryOperationExpression when a pagination expression is a binary operation whose operator is not +, -, *, or /. The evaluator recursively resolves left/right values and switches on the operator string; division, multiplication, addition, subtraction are supported, anything else (%, concatenation, comparisons) throws UnsupportedOperationException naming the operator.","triggerScenarios":"ROWNUM-style pagination using modulo ('ROWNUM % 10'), bitwise operators, or any non-arithmetic operator inside the value expression; also triggered if a grammar change produces an operator token string not in the four supported cases.","commonSituations":"Ported pagination idioms from other languages/databases (% for cycling); generated SQL using modulo arithmetic for paging; edge operator tokens after upgrades.","solutions":["Express the pagination bound with only +, -, *, / arithmetic","Precompute values like modulo results in the application and bind them as parameter markers or literals","Remove comparison/logical operators from the value expression (they belong outside the row-number bound)"],"exampleFix":"// before\nWHERE ROWNUM <= 10 % 3\n\n// after\nWHERE ROWNUM <= 1","handlingStrategy":"validation","validationCode":"Set<String> ARITH = Set.of(\"+\", \"-\", \"*\", \"/\");\nif (!ARITH.contains(op)) throw new IllegalArgumentException(\"Pagination bound supports only + - * /\");","typeGuard":null,"tryCatchPattern":"try { rewriteEngine.rewrite(query); } catch (UnsupportedOperationException e) { /* precompute the value and re-bind */ }","preventionTips":["Use only +, -, *, / in rownum pagination expressions","Precompute modulo/bitwise results in application code"],"tags":["pagination","rownum","operator","rewrite","arithmetic"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}