apache/shardingsphere · error · SQLFeatureNotSupportedException
executeQuery with SQL for PreparedStatement
Error message
executeQuery with SQL for PreparedStatement
What it means
SQLFeatureNotSupportedException('executeQuery with SQL for PreparedStatement') thrown by AbstractUnsupportedOperationPreparedStatement.executeQuery(String). Per the JDBC contract, a PreparedStatement executes its precompiled SQL and executeQuery(String) must throw; ShardingSphere enforces this with a final override. Only the no-arg executeQuery() is implemented (ShardingSpherePreparedStatement:167), because routing depends on the bound parameters.
Source
Thrown at jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedOperationPreparedStatement.java:89
@Override
public final void setNCharacterStream(final int parameterIndex, final Reader x, final long length) throws SQLException {
throw new SQLFeatureNotSupportedException("setNCharacterStream");
}
@Override
public final void setRowId(final int parameterIndex, final RowId x) throws SQLException {
throw new SQLFeatureNotSupportedException("setRowId");
}
@Override
public final void setRef(final int parameterIndex, final Ref x) throws SQLException {
throw new SQLFeatureNotSupportedException("setRef");
}
@Override
public final ResultSet executeQuery(final String sql) throws SQLException {
throw new SQLFeatureNotSupportedException("executeQuery with SQL for PreparedStatement");
}
@Override
public final int executeUpdate(final String sql) throws SQLException {
throw new SQLFeatureNotSupportedException("executeUpdate with SQL for PreparedStatement");
}
@Override
public final int executeUpdate(final String sql, final int autoGeneratedKeys) throws SQLException {
throw new SQLFeatureNotSupportedException("executeUpdate with SQL for PreparedStatement");
}
@Override
public final int executeUpdate(final String sql, final int[] columnIndexes) throws SQLException {
throw new SQLFeatureNotSupportedException("executeUpdate with SQL for PreparedStatement");
}
@OverrideView on GitHub (pinned to e952770a21)
Solutions
- Use ps.executeQuery() with parameters set via setXXX.
- For dynamic SQL strings, create a Statement: conn.createStatement().executeQuery(sql).
- Fix generic helpers to dispatch on instanceof PreparedStatement and use the no-arg execute methods.
Example fix
// before
try (PreparedStatement ps = conn.prepareStatement(sql)) {
ResultSet rs = ps.executeQuery(sql);
}
// after
try (PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setInt(1, id);
ResultSet rs = ps.executeQuery();
} Defensive patterns
Strategy: validation
Validate before calling
// Validate: PreparedStatement executes only its own precompiled SQL
if (stmt instanceof PreparedStatement) { rs = ((PreparedStatement) stmt).executeQuery(); } else { rs = stmt.executeQuery(sql); } Type guard
static ResultSet query(final Statement stmt, final String sql) throws SQLException {
return (stmt instanceof PreparedStatement) ? ((PreparedStatement) stmt).executeQuery() : stmt.executeQuery(sql);
} Prevention
- Never pass SQL to PreparedStatement execute methods
- Use conn.createStatement() for raw SQL queries
- Type-check generic query helpers with instanceof PreparedStatement
When it happens
Trigger: ps.executeQuery(sql) on a ShardingSphere PreparedStatement; produced by copy-pasted Statement code, or by generic query helpers that take (statement, sql) and never learned the statement's concrete type.
Common situations: DAO base classes centralizing execute calls for both Statement and PreparedStatement; refactoring Statement code to PreparedStatement without dropping the sql argument; tutorial-derived code.
Related errors
AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14).
Data as JSON: /api/errors/b69fbac4d42f4a8e.
Report an issue: GitHub.