{"record":{"id":"2fc86841c9899d0c","repo":"prestodb/presto","slug":"max-rows-must-be-positive","errorCode":null,"errorMessage":"Max rows must be positive","messagePattern":"Max rows must be positive","errorType":"validation","errorClass":"SQLException","httpStatus":null,"severity":"warning","filePath":"presto-jdbc/src/main/java/com/facebook/presto/jdbc/PrestoStatement.java","lineNumber":144,"sourceCode":"    {\n        checkOpen();\n        return maxRows.get();\n    }\n\n    @Override\n    public void setMaxRows(int max)\n            throws SQLException\n    {\n        setLargeMaxRows(max);\n    }\n\n    @Override\n    public void setLargeMaxRows(long max)\n            throws SQLException\n    {\n        checkOpen();\n        if (max < 0) {\n            throw new SQLException(\"Max rows must be positive\");\n        }\n        maxRows.set(max);\n    }\n\n    @Override\n    public void setEscapeProcessing(boolean enable)\n            throws SQLException\n    {\n        checkOpen();\n        escapeProcessing.set(enable);\n    }\n\n    @Override\n    public int getQueryTimeout()\n            throws SQLException\n    {\n        checkOpen();\n        return queryTimeoutSeconds.get();","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-jdbc/src/main/java/com/facebook/presto/jdbc/PrestoStatement.java#L126-L162","documentation":"setLargeMaxRows validates the argument after checkOpen(): a negative max is rejected with this SQLException. JDBC requires max-rows limits to be non-negative; 0 typically means no limit. The validated value is stored in an AtomicLong used to cap returned rows.","triggerScenarios":"Calling PrestoStatement.setLargeMaxRows (directly or via setMaxRows) with a negative long, often from an unvalidated user-supplied limit or a subtraction that underflowed.","commonSituations":"Computing a limit as remaining - used where remaining < used (underflow to negative); user input like 'limit = -10'; using -1 as an unlimited sentinel.","solutions":["Clamp or validate the limit before calling: Math.max(0, limit)","Fix arithmetic that can produce negative limits (e.g. compute with saturating subtraction)","Treat 0 as the unlimited value instead of negative sentinels"],"exampleFix":"// before\nstmt.setLargeMaxRows(remaining - used); // may be negative\n// after\nlong limit = Math.max(0, remaining - used);\nstmt.setLargeMaxRows(limit);","handlingStrategy":"validation","validationCode":"if (maxRows < 0) {\n    throw new IllegalArgumentException(\"maxRows must be >= 0 (0 = no limit), got \" + maxRows);\n}\nstmt.setLargeMaxRows(maxRows);","typeGuard":null,"tryCatchPattern":"try {\n    stmt.setLargeMaxRows(n);\n} catch (SQLException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"Max rows must be positive\")) {\n        stmt.setLargeMaxRows(0); // treat as unlimited\n    } else { throw e; }\n}","preventionTips":["Clamp computed limits with Math.max(0, value) to prevent underflow","Validate user-supplied limits before passing to JDBC setters","Use 0 rather than negative values to mean 'no limit'"],"tags":["jdbc","statement","validation"],"backgroundTag":"jdbc-invalid-parameter","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}