apache/shardingsphere · error · ColumnIndexOutOfRangeException

Column index '%d' is out of range.

Error message

Column index '%d' is out of range.

What it means

ColumnIndexOutOfRangeException from ShardingSphereResultSetMetaData.checkColumnIndex, used by getColumnName(int): for SELECT statements containing derived projections (ORDER BY items, derived columns added by ShardingSphere), the requested column index must not exceed the expanded projections list size, otherwise the JDBC-standard out-of-range error is thrown.

Source

Thrown at jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSetMetaData.java:110

            checkColumnIndex(column);
            return ((SelectStatementContext) sqlStatementContext).getProjectionsContext().getExpandProjections().get(column - 1).getColumnLabel();
        }
        return resultSetMetaData.getColumnLabel(column);
    }
    
    @Override
    public String getColumnName(final int column) throws SQLException {
        if (sqlStatementContext instanceof SelectStatementContext && ((SelectStatementContext) sqlStatementContext).containsDerivedProjections()) {
            checkColumnIndex(column);
            return ((SelectStatementContext) sqlStatementContext).getProjectionsContext().getExpandProjections().get(column - 1).getColumnName();
        }
        return resultSetMetaData.getColumnName(column);
    }
    
    private void checkColumnIndex(final int column) throws SQLException {
        List<Projection> actualProjections = ((SelectStatementContext) sqlStatementContext).getProjectionsContext().getExpandProjections();
        if (column > actualProjections.size()) {
            throw new ColumnIndexOutOfRangeException(column).toSQLException();
        }
    }
    
    @Override
    public String getSchemaName(final int column) {
        return DefaultDatabase.LOGIC_NAME;
    }
    
    @Override
    public int getPrecision(final int column) throws SQLException {
        return resultSetMetaData.getPrecision(column);
    }
    
    @Override
    public int getScale(final int column) throws SQLException {
        return resultSetMetaData.getScale(column);
    }
    

View on GitHub (pinned to e952770a21)

Solutions

  1. Always loop 1..getColumnCount() inclusive and never assume extra columns beyond it.
  2. Prefer label-based access over positional access for rewritten sharded queries.
  3. If a mismatch between getColumnCount() and projections persists on a derived-projection query, capture SQL + config and report as a potential bug; as a workaround select the ORDER BY column explicitly.

Example fix

// before
for (int i = 0; i < md.getColumnCount(); i++) { md.getColumnName(i); } // 0-based -> throws
// after
for (int i = 1; i <= md.getColumnCount(); i++) { md.getColumnName(i); }
Defensive patterns

Strategy: validation

Validate before calling

int count = md.getColumnCount();
if (column < 1 || column > count) throw new IndexOutOfBoundsException("1.." + count);

Try / catch

catch (SQLException ex) { if (column > md.getColumnCount()) fallbackToLabelAccess(); else throw ex; }

Prevention

When it happens

Trigger: Calling getColumnName/getColumnLabel on a ShardingSphere ResultSetMetaData with an index greater than the number of expand projections, on a query where ShardingSphere added derived projections (e.g. ORDER BY on a column not in SELECT).

Common situations: Report/ORM tools iterating up to getColumnCount() of the underlying driver metadata while the projection context has a different expanded size; index mismatches after sharding rewrites queries with derived order-by columns; off-by-one with 0-based loops.

Related errors


AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14). Data as JSON: /api/errors/b0a0e580c25d27f8. Report an issue: GitHub.