{"record":{"id":"d332254b3eb9693f","repo":"apache/shardingsphere","slug":"sql-federation-pagination-parameter-value-s-mus","errorCode":null,"errorMessage":"SQL federation pagination parameter value `%s` must be an integer.","messagePattern":"SQL federation pagination parameter value `(.+?)` must be an integer\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/engine/processor/impl/StandardSQLFederationProcessor.java","lineNumber":191,"sourceCode":"        paginationContext.getOffsetParameterIndex().ifPresent(result::add);\n        paginationContext.getRowCountParameterIndex().ifPresent(result::add);\n    }\n    \n    private Object convertPaginationParameter(final Object value) {\n        if (!(value instanceof Number)) {\n            return value;\n        }\n        BigInteger integerValue = getIntegerValue((Number) value);\n        ShardingSpherePreconditions.checkState(integerValue.compareTo(MIN_PAGINATION_PARAMETER) >= 0 && integerValue.compareTo(MAX_PAGINATION_PARAMETER) <= 0,\n                () -> new IllegalArgumentException(String.format(\"SQL federation pagination parameter value `%s` is out of integer range.\", value)));\n        return integerValue.intValue();\n    }\n    \n    private BigInteger getIntegerValue(final Number value) {\n        try {\n            return new BigDecimal(value.toString()).toBigIntegerExact();\n        } catch (final NumberFormatException | ArithmeticException ex) {\n            throw new IllegalArgumentException(String.format(\"SQL federation pagination parameter value `%s` must be an integer.\", value), ex);\n        }\n    }\n    \n    @Override\n    public Convention getConvention() {\n        return EnumerableConvention.INSTANCE;\n    }\n}\n","sourceCodeStart":173,"sourceCodeEnd":200,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/engine/processor/impl/StandardSQLFederationProcessor.java#L173-L200","documentation":"StandardSQLFederationProcessor validates LIMIT/OFFSET pagination parameter values for federated execution. A Number parameter whose decimal form is not exactly an integer (e.g. 1.5, or a double with fraction) fails BigDecimal.toBigIntegerExact() and throws IllegalArgumentException stating the value must be an integer. A separate sibling check enforces the 0..Integer.MAX_VALUE range.","triggerScenarios":"Binding a non-integral Number (float/double/BigDecimal with fraction) as a LIMIT or OFFSET parameter of a federated query; getIntegerValue is called from pagination parameter conversion during plan execution.","commonSituations":"Applications computing LIMIT dynamically (page size division, percentages) producing fractional values; passing Double parameters through PreparedStatement.setObject; upstream data producing 10.0-style decimals that carry fractions elsewhere.","solutions":["Bind integral types for LIMIT/OFFSET parameters (setInt/setLong), or round/truncate to whole numbers before binding.","Validate computed pagination values in application code before executing the query.","If a decimal like 10.0 arrives as Double, normalize it: BigDecimal.valueOf(d).setScale(0, RoundingMode.DOWN) when the semantic is a whole count."],"exampleFix":"// before\nps.setObject(1, pageSizePercent * total / 100.0); // may be 7.5\n// after\nint limit = (int) Math.floor(pageSizePercent * total / 100.0);\nps.setInt(1, limit);","handlingStrategy":"validation","validationCode":"static int paginationParam(Object v) {\n    if (!(v instanceof Number)) throw new IllegalArgumentException(\"pagination param must be Number\");\n    BigInteger i = new BigDecimal(v.toString()).toBigIntegerExact(); // throws early, clearly\n    if (i.signum() < 0 || i.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0) {\n        throw new IllegalArgumentException(\"pagination param out of range: \" + v);\n    }\n    return i.intValue();\n}\n// call paginationParam(limit) before ps.setXxx(...) and before executing federated query","typeGuard":null,"tryCatchPattern":"try {\n    rs = stmt.executeQuery();\n} catch (final IllegalArgumentException ex) {\n    if (ex.getMessage().contains(\"must be an integer\")) { fixPaginationAndRetry(); } else { throw ex; }\n}","preventionTips":["Always bind LIMIT/OFFSET with setInt/setLong.","Never bind computed fractional values directly.","Centralize pagination parameter validation in one helper."],"tags":["sql-federation","pagination","limit","validation"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}