{"record":{"id":"a3de2eb349485aaa","repo":"apache/shardingsphere","slug":"gettime-string-columnlabel-calendar-cal","errorCode":null,"errorMessage":"getTime(String columnLabel, Calendar cal)","messagePattern":"getTime\\(String columnLabel, Calendar cal\\)","errorType":"exception","errorClass":"SQLFeatureNotSupportedException","httpStatus":null,"severity":"error","filePath":"jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedDatabaseMetaDataResultSet.java","lineNumber":136,"sourceCode":"    \n    @Override\n    public final Date getDate(final int columnIndex, final Calendar cal) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"getDate(int columnIndex, Calendar cal)\");\n    }\n    \n    @Override\n    public final Date getDate(final String columnLabel, final Calendar cal) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"getDate(String columnLabel, Calendar cal)\");\n    }\n    \n    @Override\n    public final Time getTime(final int columnIndex, final Calendar cal) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"getTime(int columnIndex, Calendar cal)\");\n    }\n    \n    @Override\n    public final Time getTime(final String columnLabel, final Calendar cal) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"getTime(String columnLabel, Calendar cal)\");\n    }\n    \n    @Override\n    public final Timestamp getTimestamp(final int columnIndex, final Calendar cal) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"getTime(int columnIndex, Calendar cal)\");\n    }\n    \n    @Override\n    public final Timestamp getTimestamp(final String columnLabel, final Calendar cal) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"getTime(String columnLabel, Calendar cal)\");\n    }\n    \n    @Override\n    public final SQLXML getSQLXML(final int columnIndex) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"getSQLXML\");\n    }\n    \n    @Override","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedDatabaseMetaDataResultSet.java#L118-L154","documentation":"java.sql.SQLFeatureNotSupportedException thrown by the Apache ShardingSphere JDBC driver when ResultSet.getTime(String columnLabel, Calendar cal) 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. getTime(String columnLabel, Calendar cal) is declared final in AbstractUnsupportedDatabaseMetaDataResultSet and always throws, so this is a permanent, intentional limitation, not a version bug. Note that only the Calendar overloads are blocked; the single-argument rs.getTime(columnLabel) IS implemented and works. The driver materialized the underlying value once, so per-Calendar reinterpretation of a live driver value is not possible.","triggerScenarios":"Calling getTime(String columnLabel, Calendar cal) on the ResultSet returned by ShardingSphereDatabaseMetaData, e.g. connection.getMetaData().getTables(null, null, \"%\", new String[]{\"TABLE\"}\") followed by rs.getTime(\"TABLE_NAME\", Calendar cal)) 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.","commonSituations":"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. Calendar-arg getters are a common habit in multi-timezone services and in code copied from JDBC documentation examples.","solutions":["Replace the Calendar overload with the single-argument getter rs.getTime(columnLabel), which DatabaseMetaDataResultSet implements.","If you needed the Calendar for timezone handling, do the conversion yourself: rs.getTimestamp(i) gives the value; use a SimpleDateFormat with TimeZone set, or java.time conversion, instead of the Calendar argument.","If per-datasource timezone semantics matter, configure them on the underlying JDBC pools so values arrive already correct.","If you do not control the calling code (third-party tool), run its metadata introspection against the physical datasource.","Do not wait for a driver upgrade: only the Calendar overloads are blocked and that is by design."],"exampleFix":"// before - Calendar overloads throw SQLFeatureNotSupportedException on ShardingSphere metadata result sets\nTimestamp ts = metaDataRs.getTimestamp(\"REMARKS\", Calendar.getInstance(TimeZone.getTimeZone(\"UTC\")));\n\n// after - single-argument getter is implemented; apply timezone yourself\nTimestamp ts = metaDataRs.getTimestamp(\"REMARKS\");\nZonedDateTime utc = ts == null ? null : ts.toInstant().atZone(ZoneOffset.UTC);","handlingStrategy":"try-catch","validationCode":"// Run BEFORE using exotic getters: detect a ShardingSphere-synthesized metadata ResultSet\nstatic boolean isShardingSphereMetaDataResultSet(final ResultSet rs) {\n    return rs != null && \"org.apache.shardingsphere.driver.jdbc.core.resultset.DatabaseMetaDataResultSet\"\n            .equals(rs.getClass().getName());\n}\n\nstatic boolean supportsMetaDataGetter(final Connection c) throws SQLException {\n    // jdbc:shardingsphere: URLs return the synthesized metadata result set\n    return c != null && !c.getMetaData().getURL().startsWith(\"jdbc:shardingsphere:\");\n}","typeGuard":"private static boolean isUnsupportedMetaDataResultSet(final ResultSet rs) {\n    return rs != null && rs.getClass().getName().startsWith(\"org.apache.shardingsphere.driver.jdbc.core.resultset.DatabaseMetaDataResultSet\");\n}","tryCatchPattern":"try {\n    return rs.getTime(String columnLabel, Calendar cal);\n} catch (final SQLFeatureNotSupportedException e) {\n    // ShardingSphere metadata result sets: fall back to the implemented scalar getter\n    final var v = rs.getTime(columnLabel);\n}","preventionTips":["Never assume a JDBC driver implements every ResultSet getter; DatabaseMetaData results are the most commonly stubbed surface.","When adding ShardingSphere in front of an existing datasource, smoke-test the metadata paths your frameworks use (getTables/getColumns loops) before shipping.","Prefer the simplest getter (getString/getObject/getBytes) and convert in application code; it is portable across drivers.","Treat SQLFeatureNotSupportedException (an SQLException subclass) as a signal about capability, not a transient failure - never retry it.","Avoid Calendar-arg getters in shared code: several drivers and wrappers skip them; single-arg getters plus explicit timezone conversion are safer."],"tags":["jdbc","shardingsphere","database-metadata","time","calendar"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}