prestodb/presto · warning · SQLException

Max rows must be positive

Error message

Max rows must be positive

What it means

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.

Source

Thrown at presto-jdbc/src/main/java/com/facebook/presto/jdbc/PrestoStatement.java:144

    {
        checkOpen();
        return maxRows.get();
    }

    @Override
    public void setMaxRows(int max)
            throws SQLException
    {
        setLargeMaxRows(max);
    }

    @Override
    public void setLargeMaxRows(long max)
            throws SQLException
    {
        checkOpen();
        if (max < 0) {
            throw new SQLException("Max rows must be positive");
        }
        maxRows.set(max);
    }

    @Override
    public void setEscapeProcessing(boolean enable)
            throws SQLException
    {
        checkOpen();
        escapeProcessing.set(enable);
    }

    @Override
    public int getQueryTimeout()
            throws SQLException
    {
        checkOpen();
        return queryTimeoutSeconds.get();

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Clamp or validate the limit before calling: Math.max(0, limit)
  2. Fix arithmetic that can produce negative limits (e.g. compute with saturating subtraction)
  3. Treat 0 as the unlimited value instead of negative sentinels

Example fix

// before
stmt.setLargeMaxRows(remaining - used); // may be negative
// after
long limit = Math.max(0, remaining - used);
stmt.setLargeMaxRows(limit);
Defensive patterns

Strategy: validation

Validate before calling

if (maxRows < 0) {
    throw new IllegalArgumentException("maxRows must be >= 0 (0 = no limit), got " + maxRows);
}
stmt.setLargeMaxRows(maxRows);

Try / catch

try {
    stmt.setLargeMaxRows(n);
} catch (SQLException e) {
    if (e.getMessage() != null && e.getMessage().contains("Max rows must be positive")) {
        stmt.setLargeMaxRows(0); // treat as unlimited
    } else { throw e; }
}

Prevention

When it happens

Trigger: Calling PrestoStatement.setLargeMaxRows (directly or via setMaxRows) with a negative long, often from an unvalidated user-supplied limit or a subtraction that underflowed.

Common situations: Computing a limit as remaining - used where remaining < used (underflow to negative); user input like 'limit = -10'; using -1 as an unlimited sentinel.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/2fc86841c9899d0c. Report an issue: GitHub.