apache/shardingsphere · error · SQLFeatureNotSupportedException

getBinaryStream

Error message

getBinaryStream

What it means

java.sql.SQLFeatureNotSupportedException thrown by the Apache ShardingSphere JDBC driver when ResultSet.getBinaryStream(int columnIndex) is called on a DatabaseMetaData result set. Metadata calls such as Connection.getMetaData().getTables()/getColumns()/getIndexInfo()/getPrimaryKeys() on a jdbc:shardingsphere: URL return a synthesized DatabaseMetaDataResultSet that buffers every row as plain Java objects, so only scalar getters (getString, getInt, getBytes, single-arg getDate/getTime/getTimestamp, ...) are implemented. getBinaryStream(int columnIndex) is declared final in AbstractUnsupportedDatabaseMetaDataResultSet and always throws, so this is a permanent, intentional limitation, not a version bug.

Source

Thrown at jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedDatabaseMetaDataResultSet.java:61

    
    @Override
    public final InputStream getAsciiStream(final String columnLabel) throws SQLException {
        throw new SQLFeatureNotSupportedException("getAsciiStream");
    }
    
    @Override
    public final InputStream getUnicodeStream(final int columnIndex) throws SQLException {
        throw new SQLFeatureNotSupportedException("getUnicodeStream");
    }
    
    @Override
    public final InputStream getUnicodeStream(final String columnLabel) throws SQLException {
        throw new SQLFeatureNotSupportedException("getUnicodeStream");
    }
    
    @Override
    public final InputStream getBinaryStream(final int columnIndex) throws SQLException {
        throw new SQLFeatureNotSupportedException("getBinaryStream");
    }
    
    @Override
    public final InputStream getBinaryStream(final String columnLabel) throws SQLException {
        throw new SQLFeatureNotSupportedException("getBinaryStream");
    }
    
    @Override
    public final SQLWarning getWarnings() throws SQLException {
        throw new SQLFeatureNotSupportedException("getWarnings");
    }
    
    @Override
    public final void clearWarnings() throws SQLException {
        throw new SQLFeatureNotSupportedException("clearWarnings");
    }
    
    @Override

View on GitHub (pinned to e952770a21)

Solutions

  1. Replace rs.getBinaryStream(int columnIndex) with rs.getBytes(...): DatabaseMetaDataResultSet implements getBytes(int)/getBytes(String), then wrap the byte[] in a ByteArrayInputStream if an InputStream is required.
  2. For character streams (getAsciiStream/getCharacterStream/getUnicodeStream shape), use rs.getString(...) plus new StringReader/ByteArrayInputStream.
  3. If you do not control the calling code (third-party tool), point its metadata introspection at the underlying physical datasource instead of the ShardingSphere datasource, or run the tool against the real database.
  4. As a last resort wrap the metadata ResultSet in a delegating adapter that implements the stream getters on top of getString/getBytes.
  5. Do not wait for a driver upgrade: the throw is final and by design in every ShardingSphere 5.x release.

Example fix

// before - throws SQLFeatureNotSupportedException on ShardingSphere metadata result sets
InputStream in = metaDataRs.getBinaryStream("TABLE_NAME");

// after - getBytes is implemented by DatabaseMetaDataResultSet
byte[] bytes = metaDataRs.getBytes("TABLE_NAME");
InputStream in = bytes == null ? null : new ByteArrayInputStream(bytes);
Defensive patterns

Strategy: try-catch

Validate before calling

// Run BEFORE using exotic getters: detect a ShardingSphere-synthesized metadata ResultSet
static boolean isShardingSphereMetaDataResultSet(final ResultSet rs) {
    return rs != null && "org.apache.shardingsphere.driver.jdbc.core.resultset.DatabaseMetaDataResultSet"
            .equals(rs.getClass().getName());
}

static boolean supportsMetaDataGetter(final Connection c) throws SQLException {
    // jdbc:shardingsphere: URLs return the synthesized metadata result set
    return c != null && !c.getMetaData().getURL().startsWith("jdbc:shardingsphere:");
}

Type guard

private static boolean isUnsupportedMetaDataResultSet(final ResultSet rs) {
    return rs != null && rs.getClass().getName().startsWith("org.apache.shardingsphere.driver.jdbc.core.resultset.DatabaseMetaDataResultSet");
}

Try / catch

try {
    return rs.getBinaryStream(int columnIndex);
} catch (final SQLFeatureNotSupportedException e) {
    // ShardingSphere metadata result sets: fall back to the implemented scalar getter
    final byte[] bytes = rs.getBytes(col);
}

Prevention

When it happens

Trigger: Calling getBinaryStream(int columnIndex) on the ResultSet returned by ShardingSphereDatabaseMetaData, e.g. connection.getMetaData().getTables(null, null, "%", new String[]{"TABLE"}") followed by rs.getBinaryStream(1)) where connection was opened with the org.apache.shardingsphere.driver JDBC URL (jdbc:shardingsphere:classpath:sharding.yaml or jdbc:shardingsphere:...). Both the int-columnIndex and String-columnLabel overloads of every listed getter throw; the methods are final so no subclass can override them.

Common situations: Code that ran unchanged against the native MySQL/PostgreSQL/OpenGauss driver and is repointed to the ShardingSphere driver URL, so the same metadata loop now hits the stubbed getter; generic schema tooling that enumerates JDBC metadata with feature-rich getters (DBeaver, Squirrel SQL, Liquibase/Hibernate/Flyway schema validators, code generators, DBDiff tools); hand-written metadata loops that defensively call getWarnings()/clearWarnings() or use the Calendar overloads to pin a timezone.

Related errors


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