diff --git a/exec/jdbc/src/main/java/org/apache/drill/jdbc/DrillConnection.java b/exec/jdbc/src/main/java/org/apache/drill/jdbc/DrillConnection.java index 698b433c876..16ea520726e 100644 --- a/exec/jdbc/src/main/java/org/apache/drill/jdbc/DrillConnection.java +++ b/exec/jdbc/src/main/java/org/apache/drill/jdbc/DrillConnection.java @@ -15,7 +15,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.apache.drill.jdbc; import java.sql.Connection; diff --git a/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillConnectionImpl.java b/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillConnectionImpl.java index f8e5d8ebb92..1ff2693f4f1 100644 --- a/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillConnectionImpl.java +++ b/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillConnectionImpl.java @@ -17,17 +17,32 @@ */ package org.apache.drill.jdbc.impl; +import java.io.IOException; +import java.sql.Array; +import java.sql.Blob; +import java.sql.CallableStatement; +import java.sql.Clob; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.NClob; import java.sql.PreparedStatement; +import java.sql.SQLClientInfoException; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.sql.SQLNonTransientConnectionException; +import java.sql.SQLWarning; +import java.sql.SQLXML; import java.sql.Savepoint; +import java.sql.Statement; +import java.sql.Struct; +import java.util.Map; import java.util.Properties; import java.util.TimeZone; import java.util.concurrent.Executor; import net.hydromatic.avatica.AvaticaConnection; import net.hydromatic.avatica.AvaticaFactory; +import net.hydromatic.avatica.AvaticaStatement; import net.hydromatic.avatica.Helper; import net.hydromatic.avatica.Meta; import net.hydromatic.avatica.UnregisteredDriver; @@ -58,8 +73,9 @@ // interface methods, but now newer versions would probably use Java 8's default // methods for compatibility.) class DrillConnectionImpl extends AvaticaConnection - implements DrillConnection { - private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(DrillConnection.class); + implements DrillConnection { + private static final org.slf4j.Logger logger = + org.slf4j.LoggerFactory.getLogger(DrillConnection.class); final DrillStatementRegistry openStatementsRegistry = new DrillStatementRegistry(); final DrillConnectionConfig config; @@ -69,7 +85,9 @@ class DrillConnectionImpl extends AvaticaConnection private Drillbit bit; private RemoteServiceSet serviceSet; - protected DrillConnectionImpl(DriverImpl driver, AvaticaFactory factory, String url, Properties info) throws SQLException { + + protected DrillConnectionImpl(DriverImpl driver, AvaticaFactory factory, + String url, Properties info) throws SQLException { super(driver, factory, url, info); // Initialize transaction-related settings per Drill behavior. @@ -145,8 +163,9 @@ protected DrillConnectionImpl(DriverImpl driver, AvaticaFactory factory, String /** * Throws AlreadyClosedSqlException iff this Connection is closed. * - * @throws AlreadyClosedSqlException if Connection is closed */ - private void checkNotClosed() throws AlreadyClosedSqlException { + * @throws AlreadyClosedSqlException if Connection is closed + */ + private void throwIfClosed() throws AlreadyClosedSqlException { if ( isClosed() ) { throw new AlreadyClosedSqlException( "Connection is already closed." ); } @@ -177,7 +196,7 @@ public DrillClient getClient() { @Override public void setAutoCommit( boolean autoCommit ) throws SQLException { - checkNotClosed(); + throwIfClosed(); if ( ! autoCommit ) { throw new SQLFeatureNotSupportedException( "Can't turn off auto-committing; transactions are not supported. " @@ -188,7 +207,7 @@ public void setAutoCommit( boolean autoCommit ) throws SQLException { @Override public void commit() throws SQLException { - checkNotClosed(); + throwIfClosed(); if ( getAutoCommit() ) { throw new JdbcApiSqlException( "Can't call commit() in auto-commit mode." ); } @@ -201,7 +220,7 @@ public void commit() throws SQLException { @Override public void rollback() throws SQLException { - checkNotClosed(); + throwIfClosed(); if ( getAutoCommit() ) { throw new JdbcApiSqlException( "Can't call rollback() in auto-commit mode." ); } @@ -231,28 +250,28 @@ public boolean isClosed() { @Override public Savepoint setSavepoint() throws SQLException { - checkNotClosed(); + throwIfClosed(); throw new SQLFeatureNotSupportedException( "Savepoints are not supported. (Drill is not transactional.)" ); } @Override public Savepoint setSavepoint(String name) throws SQLException { - checkNotClosed(); + throwIfClosed(); throw new SQLFeatureNotSupportedException( "Savepoints are not supported. (Drill is not transactional.)" ); } @Override public void rollback(Savepoint savepoint) throws SQLException { - checkNotClosed(); + throwIfClosed(); throw new SQLFeatureNotSupportedException( "Savepoints are not supported. (Drill is not transactional.)" ); } @Override public void releaseSavepoint(Savepoint savepoint) throws SQLException { - checkNotClosed(); + throwIfClosed(); throw new SQLFeatureNotSupportedException( "Savepoints are not supported. (Drill is not transactional.)" ); } @@ -272,7 +291,7 @@ private String isolationValueToString( final int level ) { @Override public void setTransactionIsolation(int level) throws SQLException { - checkNotClosed(); + throwIfClosed(); switch ( level ) { case TRANSACTION_NONE: // No-op. (Is already set in constructor, and we disallow changing it.) @@ -299,15 +318,15 @@ public void setNetworkTimeout( Executor executor, int milliseconds ) throws AlreadyClosedSqlException, JdbcApiSqlException, SQLFeatureNotSupportedException { - checkNotClosed(); + throwIfClosed(); if ( null == executor ) { throw new InvalidParameterSqlException( "Invalid (null) \"executor\" parameter to setNetworkTimeout(...)" ); } else if ( milliseconds < 0 ) { throw new InvalidParameterSqlException( - "Invalid (negative) \"milliseconds\" parameter to setNetworkTimeout(...)" - + " (" + milliseconds + ")" ); + "Invalid (negative) \"milliseconds\" parameter to" + + " setNetworkTimeout(...) (" + milliseconds + ")" ); } else { if ( 0 != milliseconds ) { @@ -317,21 +336,22 @@ else if ( milliseconds < 0 ) { } } - @Override public int getNetworkTimeout() throws AlreadyClosedSqlException { - checkNotClosed(); - return 0; // (No no timeout.) + throwIfClosed(); + return 0; // (No timeout.) } @Override - public DrillStatementImpl createStatement(int resultSetType, int resultSetConcurrency, + public DrillStatementImpl createStatement(int resultSetType, + int resultSetConcurrency, int resultSetHoldability) throws SQLException { - checkNotClosed(); + throwIfClosed(); DrillStatementImpl statement = - (DrillStatementImpl) super.createStatement(resultSetType, resultSetConcurrency, + (DrillStatementImpl) super.createStatement(resultSetType, + resultSetConcurrency, resultSetHoldability); return statement; } @@ -340,7 +360,7 @@ public DrillStatementImpl createStatement(int resultSetType, int resultSetConcur public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { - checkNotClosed(); + throwIfClosed(); try { DrillPrepareResult prepareResult = new DrillPrepareResult(sql); DrillPreparedStatementImpl statement = @@ -360,6 +380,279 @@ public TimeZone getTimeZone() { return config.getTimeZone(); } + + // Note: Using dynamic proxies would reduce the quantity (450?) of method + // overrides by eliminating those that exist solely to check whether the + // object is closed. It would also eliminate the need to throw non-compliant + // RuntimeExceptions when Avatica's method declarations won't let us throw + // proper SQLExceptions. (Check performance before applying to frequently + // called ResultSet.) + + // No isWrapperFor(Class) (it doesn't throw SQLException if already closed). + // No unwrap(Class) (it doesn't throw SQLException if already closed). + + @Override + public AvaticaStatement createStatement() throws SQLException { + throwIfClosed(); + return super.createStatement(); + } + + @Override + public PreparedStatement prepareStatement(String sql) throws SQLException { + throwIfClosed(); + return super.prepareStatement(sql); + } + + @Override + public CallableStatement prepareCall(String sql) throws SQLException { + throwIfClosed(); + return super.prepareCall(sql); + } + + @Override + public String nativeSQL(String sql) throws SQLException { + throwIfClosed(); + return super.nativeSQL(sql); + } + + + @Override + public boolean getAutoCommit() throws SQLException { + throwIfClosed(); + return super.getAutoCommit(); + } + + // No close() (it doesn't throw SQLException if already closed). + + @Override + public DatabaseMetaData getMetaData() throws SQLException { + throwIfClosed(); + return super.getMetaData(); + } + + @Override + public void setReadOnly(boolean readOnly) throws SQLException { + throwIfClosed(); + super.setReadOnly(readOnly); + } + + @Override + public boolean isReadOnly() throws SQLException { + throwIfClosed(); + return super.isReadOnly(); + } + + @Override + public void setCatalog(String catalog) throws SQLException { + throwIfClosed(); + super.setCatalog(catalog); + } + + @Override + public String getCatalog() { + // Can't throw any SQLException because AvaticaConnection's getCatalog() is + // missing "throws SQLException". + try { + throwIfClosed(); + } catch (AlreadyClosedSqlException e) { + throw new RuntimeException(e.getMessage(), e); + } + return super.getCatalog(); + } + + @Override + public int getTransactionIsolation() throws SQLException { + throwIfClosed(); + return super.getTransactionIsolation(); + } + + @Override + public SQLWarning getWarnings() throws SQLException { + throwIfClosed(); + return super.getWarnings(); + } + + @Override + public void clearWarnings() throws SQLException { + throwIfClosed(); + super.clearWarnings(); + } + + @Override + public Statement createStatement(int resultSetType, + int resultSetConcurrency) throws SQLException { + throwIfClosed(); + return super.createStatement(resultSetType, resultSetConcurrency); + } + + @Override + public PreparedStatement prepareStatement(String sql, int resultSetType, + int resultSetConcurrency) throws SQLException { + throwIfClosed(); + return super.prepareStatement(sql, resultSetType, resultSetConcurrency); + } + + @Override + public CallableStatement prepareCall(String sql, int resultSetType, + int resultSetConcurrency) throws SQLException { + throwIfClosed(); + return super.prepareCall(sql, resultSetType, resultSetConcurrency); + } + + @Override + public Map> getTypeMap() throws SQLException { + throwIfClosed(); + return super.getTypeMap(); + } + + @Override + public void setTypeMap(Map> map) throws SQLException { + throwIfClosed(); + super.setTypeMap(map); + } + + @Override + public void setHoldability(int holdability) throws SQLException { + throwIfClosed(); + super.setHoldability(holdability); + } + + @Override + public int getHoldability() throws SQLException { + throwIfClosed(); + return super.getHoldability(); + } + + @Override + public CallableStatement prepareCall(String sql, int resultSetType, + int resultSetConcurrency, + int resultSetHoldability) throws SQLException { + throwIfClosed(); + return super.prepareCall(sql, resultSetType, resultSetConcurrency, + resultSetHoldability); + } + + @Override + public PreparedStatement prepareStatement(String sql, + int autoGeneratedKeys) throws SQLException { + throwIfClosed(); + return super.prepareStatement(sql, autoGeneratedKeys); + } + + @Override + public PreparedStatement prepareStatement(String sql, + int columnIndexes[]) throws SQLException { + throwIfClosed(); + return super.prepareStatement(sql, columnIndexes); + } + + @Override + public PreparedStatement prepareStatement(String sql, + String columnNames[]) throws SQLException { + throwIfClosed(); + return super.prepareStatement(sql, columnNames); + } + + @Override + public Clob createClob() throws SQLException { + throwIfClosed(); + return super.createClob(); + } + + @Override + public Blob createBlob() throws SQLException { + throwIfClosed(); + return super.createBlob(); + } + + @Override + public NClob createNClob() throws SQLException { + throwIfClosed(); + return super.createNClob(); + } + + @Override + public SQLXML createSQLXML() throws SQLException { + throwIfClosed(); + return super.createSQLXML(); + } + + @Override + public boolean isValid(int timeout) throws SQLException { + throwIfClosed(); + return super.isValid(timeout); + } + + @Override + public void setClientInfo(String name, String value) throws SQLClientInfoException { + try { + throwIfClosed(); + } catch (AlreadyClosedSqlException e) { + throw new SQLClientInfoException(e.getMessage(), null, e); + } + super.setClientInfo(name, value); + } + + @Override + public void setClientInfo(Properties properties) throws SQLClientInfoException { + try { + throwIfClosed(); + } catch (AlreadyClosedSqlException e) { + throw new SQLClientInfoException(e.getMessage(), null, e); + } + super.setClientInfo(properties); + } + + @Override + public String getClientInfo(String name) throws SQLException { + throwIfClosed(); + return super.getClientInfo(name); + } + + @Override + public Properties getClientInfo() throws SQLException { + throwIfClosed(); + return super.getClientInfo(); + } + + @Override + public Array createArrayOf(String typeName, Object[] elements) throws SQLException { + throwIfClosed(); + return super.createArrayOf(typeName, elements); + } + + @Override + public Struct createStruct(String typeName, Object[] attributes) throws SQLException { + throwIfClosed(); + return super.createStruct(typeName, attributes); + } + + @Override + public void setSchema(String schema) throws SQLException { + throwIfClosed(); + super.setSchema(schema); + } + + @Override + public String getSchema() { + // Can't throw any SQLException because AvaticaConnection's getCatalog() is + // missing "throws SQLException". + try { + throwIfClosed(); + } catch (AlreadyClosedSqlException e) { + throw new RuntimeException(e.getMessage(), e); + } + return super.getSchema(); + } + + @Override + public void abort(Executor executor) throws SQLException { + throwIfClosed(); + super.abort(executor); + } + + + // do not make public UnregisteredDriver getDriver() { return driver; diff --git a/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillDatabaseMetaDataImpl.java b/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillDatabaseMetaDataImpl.java index 6a1d625be9a..0855b01d144 100644 --- a/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillDatabaseMetaDataImpl.java +++ b/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillDatabaseMetaDataImpl.java @@ -20,6 +20,7 @@ import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.ResultSet; +import java.sql.RowIdLifetime; import java.sql.SQLException; import org.apache.drill.jdbc.AlreadyClosedSqlException; @@ -45,8 +46,8 @@ protected DrillDatabaseMetaDataImpl( AvaticaConnection connection ) { * @throws AlreadyClosedSqlException if Connection is closed * @throws SQLException if error in calling {@link Connection#isClosed()} */ - private void checkNotClosed() throws AlreadyClosedSqlException, - SQLException { + private void throwIfClosed() throws AlreadyClosedSqlException, + SQLException { if ( getConnection().isClosed() ) { throw new AlreadyClosedSqlException( "DatabaseMetaData's Connection is already closed." ); @@ -54,76 +55,1113 @@ private void checkNotClosed() throws AlreadyClosedSqlException, } + // Note: Dynamic proxies could be used to reduce the quantity (450?) of + // method overrides by eliminating those that exist solely to check whether + // the object is closed. (Check performance before applying to frequently + // called ResultSet.) + + // Note: Methods are in same order as in java.sql.DatabaseMetaData. + + // No isWrapperFor(Class) (it doesn't throw SQLException if already closed). + // No unwrap(Class) (it doesn't throw SQLException if already closed). + + @Override + public boolean allProceduresAreCallable() throws SQLException { + throwIfClosed(); + return super.allProceduresAreCallable(); + } + + @Override + public boolean allTablesAreSelectable() throws SQLException { + throwIfClosed(); + return super.allTablesAreSelectable(); + } + + @Override + public String getURL() throws SQLException { + throwIfClosed(); + return super.getURL(); + } + + @Override + public String getUserName() throws SQLException { + throwIfClosed(); + return super.getUserName(); + } + + @Override + public boolean isReadOnly() throws SQLException { + throwIfClosed(); + return super.isReadOnly(); + } + + // For omitted NULLS FIRST/NULLS HIGH, Drill sort NULL sorts as highest value: @Override public boolean nullsAreSortedHigh() throws SQLException { - checkNotClosed(); + throwIfClosed(); return true; } @Override public boolean nullsAreSortedLow() throws SQLException { - checkNotClosed(); + throwIfClosed(); return false; } @Override public boolean nullsAreSortedAtStart() throws SQLException { - checkNotClosed(); + throwIfClosed(); return false; } @Override public boolean nullsAreSortedAtEnd() throws SQLException { - checkNotClosed(); + throwIfClosed(); return false; } + + @Override + public String getDatabaseProductName() throws SQLException { + throwIfClosed(); + return super.getDatabaseProductName(); + } + + @Override + public String getDatabaseProductVersion() throws SQLException { + throwIfClosed(); + return super.getDatabaseProductVersion(); + } + + @Override + public String getDriverName() throws SQLException { + throwIfClosed(); + return super.getDriverName(); + } + + @Override + public String getDriverVersion() throws SQLException { + throwIfClosed(); + return super.getDriverVersion(); + } + + @Override + public int getDriverMajorVersion() { + // No already-closed exception required or allowed by JDBC. + return super.getDriverMajorVersion(); + } + + @Override + public int getDriverMinorVersion() { + // No already-closed exception required or allowed by JDBC. + return super.getDriverMinorVersion(); + } + + @Override + public boolean usesLocalFiles() throws SQLException { + throwIfClosed(); + return super.usesLocalFiles(); + } + + @Override + public boolean usesLocalFilePerTable() throws SQLException { + throwIfClosed(); + return super.usesLocalFilePerTable(); + } + + @Override + public boolean supportsMixedCaseIdentifiers() throws SQLException { + throwIfClosed(); + return super.supportsMixedCaseIdentifiers(); + } + + @Override + public boolean storesUpperCaseIdentifiers() throws SQLException { + throwIfClosed(); + return super.storesUpperCaseIdentifiers(); + } + + @Override + public boolean storesLowerCaseIdentifiers() throws SQLException { + throwIfClosed(); + return super.storesLowerCaseIdentifiers(); + } + + @Override + public boolean storesMixedCaseIdentifiers() throws SQLException { + throwIfClosed(); + return super.storesMixedCaseIdentifiers(); + } + + @Override + public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException { + throwIfClosed(); + return super.supportsMixedCaseQuotedIdentifiers(); + } + + @Override + public boolean storesUpperCaseQuotedIdentifiers() throws SQLException { + throwIfClosed(); + return super.storesUpperCaseQuotedIdentifiers(); + } + + @Override + public boolean storesLowerCaseQuotedIdentifiers() throws SQLException { + throwIfClosed(); + return super.storesLowerCaseQuotedIdentifiers(); + } + + @Override + public boolean storesMixedCaseQuotedIdentifiers() throws SQLException { + throwIfClosed(); + return super.storesMixedCaseQuotedIdentifiers(); + } + // TODO(DRILL-3510): Update when Drill accepts standard SQL's double quote. @Override public String getIdentifierQuoteString() throws SQLException { - checkNotClosed(); + throwIfClosed(); return "`"; } + @Override + public String getSQLKeywords() throws SQLException { + throwIfClosed(); + return super.getSQLKeywords(); + } + + @Override + public String getNumericFunctions() throws SQLException { + throwIfClosed(); + return super.getNumericFunctions(); + } - // For now, check whether connection is closed for most important methods - // (DRILL-2565 (partial fix for DRILL-2489)): + @Override + public String getStringFunctions() throws SQLException { + throwIfClosed(); + return super.getStringFunctions(); + } + @Override + public String getSystemFunctions() throws SQLException { + throwIfClosed(); + return super.getSystemFunctions(); + } @Override - public ResultSet getCatalogs() throws SQLException { - checkNotClosed(); - return super.getCatalogs(); + public String getTimeDateFunctions() throws SQLException { + throwIfClosed(); + return super.getTimeDateFunctions(); } + @Override + public String getSearchStringEscape() throws SQLException { + throwIfClosed(); + return super.getSearchStringEscape(); + } + + @Override + public String getExtraNameCharacters() throws SQLException { + throwIfClosed(); + return super.getExtraNameCharacters(); + } + + @Override + public boolean supportsAlterTableWithAddColumn() throws SQLException { + throwIfClosed(); + return super.supportsAlterTableWithAddColumn(); + } + + @Override + public boolean supportsAlterTableWithDropColumn() throws SQLException { + throwIfClosed(); + return super.supportsAlterTableWithDropColumn(); + } + + @Override + public boolean supportsColumnAliasing() throws SQLException { + throwIfClosed(); + return super.supportsColumnAliasing(); + } + + @Override + public boolean nullPlusNonNullIsNull() throws SQLException { + throwIfClosed(); + return super.nullPlusNonNullIsNull(); + } + + @Override + public boolean supportsConvert() throws SQLException { + throwIfClosed(); + return super.supportsConvert(); + } + + @Override + public boolean supportsConvert(int fromType, int toType) throws SQLException { + throwIfClosed(); + return super.supportsConvert(fromType, toType); + } + + @Override + public boolean supportsTableCorrelationNames() throws SQLException { + throwIfClosed(); + return super.supportsTableCorrelationNames(); + } + + @Override + public boolean supportsDifferentTableCorrelationNames() throws SQLException { + throwIfClosed(); + return super.supportsDifferentTableCorrelationNames(); + } + + @Override + public boolean supportsExpressionsInOrderBy() throws SQLException { + throwIfClosed(); + return super.supportsExpressionsInOrderBy(); + } + + @Override + public boolean supportsOrderByUnrelated() throws SQLException { + throwIfClosed(); + return super.supportsOrderByUnrelated(); + } + + @Override + public boolean supportsGroupBy() throws SQLException { + throwIfClosed(); + return super.supportsGroupBy(); + } + + @Override + public boolean supportsGroupByUnrelated() throws SQLException { + throwIfClosed(); + return super.supportsGroupByUnrelated(); + } + + @Override + public boolean supportsGroupByBeyondSelect() throws SQLException { + throwIfClosed(); + return super.supportsGroupByBeyondSelect(); + } + + @Override + public boolean supportsLikeEscapeClause() throws SQLException { + throwIfClosed(); + return super.supportsLikeEscapeClause(); + } + + @Override + public boolean supportsMultipleResultSets() throws SQLException { + throwIfClosed(); + return super.supportsMultipleResultSets(); + } + + @Override + public boolean supportsMultipleTransactions() throws SQLException { + throwIfClosed(); + return super.supportsMultipleTransactions(); + } + + @Override + public boolean supportsNonNullableColumns() throws SQLException { + throwIfClosed(); + return super.supportsNonNullableColumns(); + } + + @Override + public boolean supportsMinimumSQLGrammar() throws SQLException { + throwIfClosed(); + return super.supportsMinimumSQLGrammar(); + } + + @Override + public boolean supportsCoreSQLGrammar() throws SQLException { + throwIfClosed(); + return super.supportsCoreSQLGrammar(); + } + + @Override + public boolean supportsExtendedSQLGrammar() throws SQLException { + throwIfClosed(); + return super.supportsExtendedSQLGrammar(); + } + + @Override + public boolean supportsANSI92EntryLevelSQL() throws SQLException { + throwIfClosed(); + return super.supportsANSI92EntryLevelSQL(); + } + + @Override + public boolean supportsANSI92IntermediateSQL() throws SQLException { + throwIfClosed(); + return super.supportsANSI92IntermediateSQL(); + } + + @Override + public boolean supportsANSI92FullSQL() throws SQLException { + throwIfClosed(); + return super.supportsANSI92FullSQL(); + } + + @Override + public boolean supportsIntegrityEnhancementFacility() throws SQLException { + throwIfClosed(); + return super.supportsIntegrityEnhancementFacility(); + } + + @Override + public boolean supportsOuterJoins() throws SQLException { + throwIfClosed(); + return super.supportsOuterJoins(); + } + + @Override + public boolean supportsFullOuterJoins() throws SQLException { + throwIfClosed(); + return super.supportsFullOuterJoins(); + } + + @Override + public boolean supportsLimitedOuterJoins() throws SQLException { + throwIfClosed(); + return super.supportsLimitedOuterJoins(); + } + + @Override + public String getSchemaTerm() throws SQLException { + throwIfClosed(); + return super.getSchemaTerm(); + } + + @Override + public String getProcedureTerm() throws SQLException { + throwIfClosed(); + return super.getProcedureTerm(); + } + + @Override + public String getCatalogTerm() throws SQLException { + throwIfClosed(); + return super.getCatalogTerm(); + } + + @Override + public boolean isCatalogAtStart() throws SQLException { + throwIfClosed(); + return super.isCatalogAtStart(); + } + + @Override + public String getCatalogSeparator() throws SQLException { + throwIfClosed(); + return super.getCatalogSeparator(); + } + + @Override + public boolean supportsSchemasInDataManipulation() throws SQLException { + throwIfClosed(); + return super.supportsSchemasInDataManipulation(); + } + + @Override + public boolean supportsSchemasInProcedureCalls() throws SQLException { + throwIfClosed(); + return super.supportsSchemasInProcedureCalls(); + } + + @Override + public boolean supportsSchemasInTableDefinitions() throws SQLException { + throwIfClosed(); + return super.supportsSchemasInTableDefinitions(); + } + + @Override + public boolean supportsSchemasInIndexDefinitions() throws SQLException { + throwIfClosed(); + return super.supportsSchemasInIndexDefinitions(); + } + + @Override + public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException { + throwIfClosed(); + return super.supportsSchemasInPrivilegeDefinitions(); + } + + @Override + public boolean supportsCatalogsInDataManipulation() throws SQLException { + throwIfClosed(); + return super.supportsCatalogsInDataManipulation(); + } + + @Override + public boolean supportsCatalogsInProcedureCalls() throws SQLException { + throwIfClosed(); + return super.supportsCatalogsInProcedureCalls(); + } + + @Override + public boolean supportsCatalogsInTableDefinitions() throws SQLException { + throwIfClosed(); + return super.supportsCatalogsInTableDefinitions(); + } + + @Override + public boolean supportsCatalogsInIndexDefinitions() throws SQLException { + throwIfClosed(); + return super.supportsCatalogsInIndexDefinitions(); + } + + @Override + public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException { + throwIfClosed(); + return super.supportsCatalogsInPrivilegeDefinitions(); + } + + @Override + public boolean supportsPositionedDelete() throws SQLException { + throwIfClosed(); + return super.supportsPositionedDelete(); + } + + @Override + public boolean supportsPositionedUpdate() throws SQLException { + throwIfClosed(); + return super.supportsPositionedUpdate(); + } + + @Override + public boolean supportsSelectForUpdate() throws SQLException { + throwIfClosed(); + return super.supportsSelectForUpdate(); + } + + @Override + public boolean supportsStoredProcedures() throws SQLException { + throwIfClosed(); + return super.supportsStoredProcedures(); + } + + @Override + public boolean supportsSubqueriesInComparisons() throws SQLException { + throwIfClosed(); + return super.supportsSubqueriesInComparisons(); + } + + @Override + public boolean supportsSubqueriesInExists() throws SQLException { + throwIfClosed(); + return super.supportsSubqueriesInExists(); + } + + @Override + public boolean supportsSubqueriesInIns() throws SQLException { + throwIfClosed(); + return super.supportsSubqueriesInIns(); + } + + @Override + public boolean supportsSubqueriesInQuantifieds() throws SQLException { + throwIfClosed(); + return super.supportsSubqueriesInQuantifieds(); + } + + @Override + public boolean supportsCorrelatedSubqueries() throws SQLException { + throwIfClosed(); + return super.supportsCorrelatedSubqueries(); + } + + @Override + public boolean supportsUnion() throws SQLException { + throwIfClosed(); + return super.supportsUnion(); + } + + @Override + public boolean supportsUnionAll() throws SQLException { + throwIfClosed(); + return super.supportsUnionAll(); + } + + @Override + public boolean supportsOpenCursorsAcrossCommit() throws SQLException { + throwIfClosed(); + return super.supportsOpenCursorsAcrossCommit(); + } + + @Override + public boolean supportsOpenCursorsAcrossRollback() throws SQLException { + throwIfClosed(); + return super.supportsOpenCursorsAcrossRollback(); + } + + @Override + public boolean supportsOpenStatementsAcrossCommit() throws SQLException { + throwIfClosed(); + return super.supportsOpenStatementsAcrossCommit(); + } + + @Override + public boolean supportsOpenStatementsAcrossRollback() throws SQLException { + throwIfClosed(); + return super.supportsOpenStatementsAcrossRollback(); + } + + @Override + public int getMaxBinaryLiteralLength() throws SQLException { + throwIfClosed(); + return super.getMaxBinaryLiteralLength(); + } + + @Override + public int getMaxCharLiteralLength() throws SQLException { + throwIfClosed(); + return super.getMaxCharLiteralLength(); + } + + @Override + public int getMaxColumnNameLength() throws SQLException { + throwIfClosed(); + return super.getMaxColumnNameLength(); + } + + @Override + public int getMaxColumnsInGroupBy() throws SQLException { + throwIfClosed(); + return super.getMaxColumnsInGroupBy(); + } + + @Override + public int getMaxColumnsInIndex() throws SQLException { + throwIfClosed(); + return super.getMaxColumnsInIndex(); + } + + @Override + public int getMaxColumnsInOrderBy() throws SQLException { + throwIfClosed(); + return super.getMaxColumnsInOrderBy(); + } + + @Override + public int getMaxColumnsInSelect() throws SQLException { + throwIfClosed(); + return super.getMaxColumnsInSelect(); + } + + @Override + public int getMaxColumnsInTable() throws SQLException { + throwIfClosed(); + return super.getMaxColumnsInTable(); + } + + @Override + public int getMaxConnections() throws SQLException { + throwIfClosed(); + return super.getMaxConnections(); + } + + @Override + public int getMaxCursorNameLength() throws SQLException { + throwIfClosed(); + return super.getMaxCursorNameLength(); + } + + @Override + public int getMaxIndexLength() throws SQLException { + throwIfClosed(); + return super.getMaxIndexLength(); + } + + @Override + public int getMaxSchemaNameLength() throws SQLException { + throwIfClosed(); + return super.getMaxSchemaNameLength(); + } + + @Override + public int getMaxProcedureNameLength() throws SQLException { + throwIfClosed(); + return super.getMaxProcedureNameLength(); + } + + @Override + public int getMaxCatalogNameLength() throws SQLException { + throwIfClosed(); + return super.getMaxCatalogNameLength(); + } + + @Override + public int getMaxRowSize() throws SQLException { + throwIfClosed(); + return super.getMaxRowSize(); + } + + @Override + public boolean doesMaxRowSizeIncludeBlobs() throws SQLException { + throwIfClosed(); + return super.doesMaxRowSizeIncludeBlobs(); + } + + @Override + public int getMaxStatementLength() throws SQLException { + throwIfClosed(); + return super.getMaxStatementLength(); + } + + @Override + public int getMaxStatements() throws SQLException { + throwIfClosed(); + return super.getMaxStatements(); + } + + @Override + public int getMaxTableNameLength() throws SQLException { + throwIfClosed(); + return super.getMaxTableNameLength(); + } + + @Override + public int getMaxTablesInSelect() throws SQLException { + throwIfClosed(); + return super.getMaxTablesInSelect(); + } + + @Override + public int getMaxUserNameLength() throws SQLException { + throwIfClosed(); + return super.getMaxUserNameLength(); + } + + @Override + public int getDefaultTransactionIsolation() throws SQLException { + throwIfClosed(); + return super.getDefaultTransactionIsolation(); + } + + @Override + public boolean supportsTransactions() throws SQLException { + throwIfClosed(); + return super.supportsTransactions(); + } + + @Override + public boolean supportsTransactionIsolationLevel(int level) throws SQLException { + throwIfClosed(); + return super.supportsTransactionIsolationLevel(level); + } + + @Override + public boolean supportsDataDefinitionAndDataManipulationTransactions() + throws SQLException { + throwIfClosed(); + return super.supportsDataDefinitionAndDataManipulationTransactions(); + } + + @Override + public boolean supportsDataManipulationTransactionsOnly() throws SQLException { + throwIfClosed(); + return super.supportsDataManipulationTransactionsOnly(); + } + + @Override + public boolean dataDefinitionCausesTransactionCommit() throws SQLException { + throwIfClosed(); + return super.dataDefinitionCausesTransactionCommit(); + } + + @Override + public boolean dataDefinitionIgnoredInTransactions() throws SQLException { + throwIfClosed(); + return super.dataDefinitionIgnoredInTransactions(); + } + + @Override + public ResultSet getProcedures(String catalog, String schemaPattern, + String procedureNamePattern) throws SQLException { + throwIfClosed(); + return super.getProcedures(catalog, schemaPattern, procedureNamePattern); + } + + @Override + public ResultSet getProcedureColumns(String catalog, String schemaPattern, + String procedureNamePattern, + String columnNamePattern) throws SQLException { + throwIfClosed(); + return super.getProcedureColumns(catalog, schemaPattern, + procedureNamePattern, columnNamePattern); + } + + @Override + public ResultSet getTables(String catalog, + String schemaPattern, + String tableNamePattern, + String[] types) throws SQLException { + throwIfClosed(); + return super.getTables(catalog, schemaPattern,tableNamePattern, types); + } + + @Override public ResultSet getSchemas() throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getSchemas(); } @Override - public ResultSet getSchemas( String catalog, String schemaPattern ) throws SQLException { - checkNotClosed(); - return super.getSchemas( catalog, schemaPattern ); + public ResultSet getCatalogs() throws SQLException { + throwIfClosed(); + return super.getCatalogs(); + } + + @Override + public ResultSet getTableTypes() throws SQLException { + throwIfClosed(); + return super.getTableTypes(); + } + + @Override + public ResultSet getColumns(String catalog, String schema, String table, + String columnNamePattern) throws SQLException { + throwIfClosed(); + return super.getColumns(catalog, schema, table, columnNamePattern); + } + + @Override + public ResultSet getColumnPrivileges(String catalog, String schema, + String table, + String columnNamePattern) throws SQLException { + throwIfClosed(); + return super.getColumnPrivileges(catalog, schema, table, columnNamePattern); + } + + @Override + public ResultSet getTablePrivileges(String catalog, String schemaPattern, + String tableNamePattern) throws SQLException { + throwIfClosed(); + return super.getTablePrivileges(catalog, schemaPattern, tableNamePattern); + } + + @Override + public ResultSet getBestRowIdentifier(String catalog, String schema, + String table, int scope, + boolean nullable) throws SQLException { + throwIfClosed(); + return super.getBestRowIdentifier(catalog, schema, table, scope, nullable); + } + + @Override + public ResultSet getVersionColumns(String catalog, String schema, + String table) throws SQLException { + throwIfClosed(); + return super.getVersionColumns(catalog, schema, table); + } + + @Override + public ResultSet getPrimaryKeys(String catalog, String schema, + String table) throws SQLException { + throwIfClosed(); + return super.getPrimaryKeys(catalog, schema, table); + } + + @Override + public ResultSet getImportedKeys(String catalog, String schema, + String table) throws SQLException { + throwIfClosed(); + return super.getImportedKeys(catalog, schema, table); } @Override - public ResultSet getTables( String catalog, - String schemaPattern, - String tableNamePattern, - String[] types ) throws SQLException { - checkNotClosed(); - return super.getTables( catalog, schemaPattern,tableNamePattern, types ); + public ResultSet getExportedKeys(String catalog, String schema, + String table) throws SQLException { + throwIfClosed(); + return super.getExportedKeys(catalog, schema, table); } @Override - public ResultSet getColumns( String catalog, String schema, String table, - String columnNamePattern ) throws SQLException { - checkNotClosed(); - return super.getColumns( catalog, schema, table, columnNamePattern ); + public ResultSet getCrossReference( + String parentCatalog, String parentSchema, String parentTable, + String foreignCatalog, String foreignSchema, + String foreignTable ) throws SQLException { + throwIfClosed(); + return super.getCrossReference(parentCatalog, parentSchema, parentTable, + foreignCatalog, foreignSchema, foreignTable ); } + @Override + public ResultSet getTypeInfo() throws SQLException { + throwIfClosed(); + return super.getTypeInfo(); + } + + @Override + public ResultSet getIndexInfo(String catalog, String schema, String table, + boolean unique, + boolean approximate) throws SQLException { + throwIfClosed(); + return super.getIndexInfo(catalog, schema, table, unique, approximate); + } + + @Override + public boolean supportsResultSetType(int type) throws SQLException { + throwIfClosed(); + return super.supportsResultSetType(type); + } + + @Override + public boolean supportsResultSetConcurrency(int type, + int concurrency) throws SQLException { + throwIfClosed(); + return super.supportsResultSetConcurrency(type, concurrency); + } + + @Override + public boolean ownUpdatesAreVisible(int type) throws SQLException { + throwIfClosed(); + return super.ownUpdatesAreVisible(type); + } + + @Override + public boolean ownDeletesAreVisible(int type) throws SQLException { + throwIfClosed(); + return super.ownDeletesAreVisible(type); + } + + @Override + public boolean ownInsertsAreVisible(int type) throws SQLException { + throwIfClosed(); + return super.ownInsertsAreVisible(type); + } + + @Override + public boolean othersUpdatesAreVisible(int type) throws SQLException { + throwIfClosed(); + return super.othersUpdatesAreVisible(type); + } + + @Override + public boolean othersDeletesAreVisible(int type) throws SQLException { + throwIfClosed(); + return super.othersDeletesAreVisible(type); + } + + @Override + public boolean othersInsertsAreVisible(int type) throws SQLException { + throwIfClosed(); + return super.othersInsertsAreVisible(type); + } + + @Override + public boolean updatesAreDetected(int type) throws SQLException { + throwIfClosed(); + return super.updatesAreDetected(type); + } + + @Override + public boolean deletesAreDetected(int type) throws SQLException { + throwIfClosed(); + return super.deletesAreDetected(type); + } + + @Override + public boolean insertsAreDetected(int type) throws SQLException { + throwIfClosed(); + return super.insertsAreDetected(type); + } + + @Override + public boolean supportsBatchUpdates() throws SQLException { + throwIfClosed(); + return super.supportsBatchUpdates(); + } + + @Override + public ResultSet getUDTs(String catalog, String schemaPattern, + String typeNamePattern, + int[] types) throws SQLException { + throwIfClosed(); + return super.getUDTs(catalog, schemaPattern, typeNamePattern, types); + } + + @Override + public Connection getConnection() throws SQLException { + // No already-closed exception required by JDBC. + return super.getConnection(); + } + + @Override + public boolean supportsSavepoints() throws SQLException { + throwIfClosed(); + return super.supportsSavepoints(); + } + + @Override + public boolean supportsNamedParameters() throws SQLException { + throwIfClosed(); + return super.supportsNamedParameters(); + } + + @Override + public boolean supportsMultipleOpenResults() throws SQLException { + throwIfClosed(); + return super.supportsMultipleOpenResults(); + } + + @Override + public boolean supportsGetGeneratedKeys() throws SQLException { + throwIfClosed(); + return super.supportsGetGeneratedKeys(); + } + + @Override + public ResultSet getSuperTypes(String catalog, String schemaPattern, + String typeNamePattern) throws SQLException { + throwIfClosed(); + return super.getSuperTypes(catalog, schemaPattern, typeNamePattern); + } + + @Override + public ResultSet getSuperTables(String catalog, String schemaPattern, + String tableNamePattern) throws SQLException { + throwIfClosed(); + return super.getSuperTables(catalog, schemaPattern, tableNamePattern); + } + + @Override + public ResultSet getAttributes(String catalog, String schemaPattern, + String typeNamePattern, + String attributeNamePattern) throws SQLException { + throwIfClosed(); + return super.getAttributes(catalog, schemaPattern, typeNamePattern, + attributeNamePattern); + } + + @Override + public boolean supportsResultSetHoldability(int holdability) throws SQLException { + throwIfClosed(); + return super.supportsResultSetHoldability(holdability); + } + + @Override + public int getResultSetHoldability() { + // Can't throw any SQLException because Avatica's getResultSetHoldability() + // is missing "throws SQLException". + try { + throwIfClosed(); + } catch (AlreadyClosedSqlException e) { + throw new RuntimeException(e.getMessage(), e); + } catch (SQLException e) { + throw new RuntimeException(e.getMessage(), e); + } + return super.getResultSetHoldability(); + } + + @Override + public int getDatabaseMajorVersion() throws SQLException { + throwIfClosed(); + return super.getDatabaseMajorVersion(); + } + + @Override + public int getDatabaseMinorVersion() throws SQLException { + throwIfClosed(); + return super.getDatabaseMinorVersion(); + } + + @Override + public int getJDBCMajorVersion() throws SQLException { + throwIfClosed(); + return super.getJDBCMajorVersion(); + } + + @Override + public int getJDBCMinorVersion() throws SQLException { + throwIfClosed(); + return super.getJDBCMinorVersion(); + } + + @Override + public int getSQLStateType() throws SQLException { + throwIfClosed(); + return super.getSQLStateType(); + } + + @Override + public boolean locatorsUpdateCopy() throws SQLException { + throwIfClosed(); + return super.locatorsUpdateCopy(); + } + + @Override + public boolean supportsStatementPooling() throws SQLException { + throwIfClosed(); + return super.supportsStatementPooling(); + } + + @Override + public RowIdLifetime getRowIdLifetime() throws SQLException { + throwIfClosed(); + return super.getRowIdLifetime(); + } + + @Override + public ResultSet getSchemas(String catalog, + String schemaPattern) throws SQLException { + throwIfClosed(); + return super.getSchemas(catalog, schemaPattern); + } + + @Override + public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException { + throwIfClosed(); + return super.supportsStoredFunctionsUsingCallSyntax(); + } + + @Override + public boolean autoCommitFailureClosesAllResultSets() throws SQLException { + throwIfClosed(); + return super.autoCommitFailureClosesAllResultSets(); + } + + @Override + public ResultSet getClientInfoProperties() throws SQLException { + throwIfClosed(); + return super.getClientInfoProperties(); + } + + @Override + public ResultSet getFunctions(String catalog, String schemaPattern, + String functionNamePattern) throws SQLException { + throwIfClosed(); + return super.getFunctions(catalog, schemaPattern, functionNamePattern); + } + + @Override + public ResultSet getFunctionColumns(String catalog, String schemaPattern, + String functionNamePattern, + String columnNamePattern) throws SQLException { + throwIfClosed(); + return super.getFunctionColumns(catalog, schemaPattern, functionNamePattern, + columnNamePattern); + } + + @Override + public ResultSet getPseudoColumns(String catalog, String schemaPattern, + String tableNamePattern, + String columnNamePattern) throws SQLException { + throwIfClosed(); + return super.getPseudoColumns(catalog, schemaPattern, tableNamePattern, + columnNamePattern); + } + + @Override + public boolean generatedKeyAlwaysReturned() throws SQLException { + throwIfClosed(); + return super.generatedKeyAlwaysReturned(); + } + + } diff --git a/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillJdbc41Factory.java b/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillJdbc41Factory.java index 9723358ef73..4a8d3bc5582 100644 --- a/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillJdbc41Factory.java +++ b/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillJdbc41Factory.java @@ -31,8 +31,6 @@ import net.hydromatic.avatica.AvaticaConnection; import net.hydromatic.avatica.AvaticaPrepareResult; -import net.hydromatic.avatica.AvaticaPreparedStatement; -import net.hydromatic.avatica.AvaticaResultSetMetaData; import net.hydromatic.avatica.AvaticaStatement; import net.hydromatic.avatica.ColumnMetaData; @@ -109,7 +107,7 @@ public DrillResultSetImpl newResultSet(AvaticaStatement statement, @Override public ResultSetMetaData newResultSetMetaData(AvaticaStatement statement, List columnMetaDataList) { - return new AvaticaResultSetMetaData(statement, null, columnMetaDataList); + return new DrillResultSetMetaDataImpl(statement, null, columnMetaDataList); } @@ -127,6 +125,8 @@ private static class DrillJdbc41PreparedStatement extends DrillPreparedStatement resultSetType, resultSetConcurrency, resultSetHoldability); } + // These don't need throwIfClosed(), since getParameter already calls it. + @Override public void setRowId(int parameterIndex, RowId x) throws SQLException { getParameter(parameterIndex).setRowId(x); @@ -138,7 +138,8 @@ public void setNString(int parameterIndex, String value) throws SQLException { } @Override - public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException { + public void setNCharacterStream(int parameterIndex, Reader value, + long length) throws SQLException { getParameter(parameterIndex).setNCharacterStream(value, length); } @@ -148,17 +149,20 @@ public void setNClob(int parameterIndex, NClob value) throws SQLException { } @Override - public void setClob(int parameterIndex, Reader reader, long length) throws SQLException { + public void setClob(int parameterIndex, Reader reader, + long length) throws SQLException { getParameter(parameterIndex).setClob(reader, length); } @Override - public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException { + public void setBlob(int parameterIndex, InputStream inputStream, + long length) throws SQLException { getParameter(parameterIndex).setBlob(inputStream, length); } @Override - public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException { + public void setNClob(int parameterIndex, Reader reader, + long length) throws SQLException { getParameter(parameterIndex).setNClob(reader, length); } @@ -168,37 +172,44 @@ public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException } @Override - public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException { + public void setAsciiStream(int parameterIndex, InputStream x, + long length) throws SQLException { getParameter(parameterIndex).setAsciiStream(x, length); } @Override - public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException { + public void setBinaryStream(int parameterIndex, InputStream x, + long length) throws SQLException { getParameter(parameterIndex).setBinaryStream(x, length); } @Override - public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException { + public void setCharacterStream(int parameterIndex, Reader reader, + long length) throws SQLException { getParameter(parameterIndex).setCharacterStream(reader, length); } @Override - public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException { + public void setAsciiStream(int parameterIndex, + InputStream x) throws SQLException { getParameter(parameterIndex).setAsciiStream(x); } @Override - public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException { + public void setBinaryStream(int parameterIndex, + InputStream x) throws SQLException { getParameter(parameterIndex).setBinaryStream(x); } @Override - public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException { + public void setCharacterStream(int parameterIndex, + Reader reader) throws SQLException { getParameter(parameterIndex).setCharacterStream(reader); } @Override - public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException { + public void setNCharacterStream(int parameterIndex, + Reader value) throws SQLException { getParameter(parameterIndex).setNCharacterStream(value); } @@ -208,7 +219,8 @@ public void setClob(int parameterIndex, Reader reader) throws SQLException { } @Override - public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException { + public void setBlob(int parameterIndex, + InputStream inputStream) throws SQLException { getParameter(parameterIndex).setBlob(inputStream); } diff --git a/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillPreparedStatementImpl.java b/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillPreparedStatementImpl.java index 871298f0223..f84e14ea8d8 100644 --- a/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillPreparedStatementImpl.java +++ b/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillPreparedStatementImpl.java @@ -17,10 +17,15 @@ */ package org.apache.drill.jdbc.impl; +import org.apache.drill.jdbc.AlreadyClosedSqlException; import org.apache.drill.jdbc.DrillPreparedStatement; +import java.sql.ParameterMetaData; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; +import java.sql.SQLWarning; import net.hydromatic.avatica.AvaticaParameter; import net.hydromatic.avatica.AvaticaPrepareResult; @@ -49,13 +54,40 @@ protected DrillPreparedStatementImpl(DrillConnectionImpl connection, connection.openStatementsRegistry.addStatement(this); } + /** + * Throws AlreadyClosedSqlException iff this PreparedStatement is closed. + * + * @throws AlreadyClosedSqlException if PreparedStatement is closed + */ + private void throwIfClosed() throws AlreadyClosedSqlException { + if (isClosed()) { + throw new AlreadyClosedSqlException("PreparedStatement is already closed."); + } + } + + + // Note: Using dynamic proxies would reduce the quantity (450?) of method + // overrides by eliminating those that exist solely to check whether the + // object is closed. It would also eliminate the need to throw non-compliant + // RuntimeExceptions when Avatica's method declarations won't let us throw + // proper SQLExceptions. (Check performance before applying to frequently + // called ResultSet.) + @Override public DrillConnectionImpl getConnection() { + try { + throwIfClosed(); + } catch (AlreadyClosedSqlException e) { + // Can't throw any SQLException because AvaticaConnection's + // getConnection() is missing "throws SQLException". + throw new RuntimeException(e.getMessage(), e); + } return (DrillConnectionImpl) super.getConnection(); } @Override protected AvaticaParameter getParameter(int param) throws SQLException { + throwIfClosed(); throw new SQLFeatureNotSupportedException( "Prepared-statement dynamic parameters are not supported."); } @@ -66,4 +98,382 @@ public void cleanUp() { connection1.openStatementsRegistry.removeStatement(this); } + // Note: Methods are in same order as in java.sql.PreparedStatement. + + // No isWrapperFor(Class) (it doesn't throw SQLException if already closed). + // No unwrap(Class) (it doesn't throw SQLException if already closed). + + @Override + public ResultSet executeQuery(String sql) throws SQLException { + throwIfClosed(); + return super.executeQuery(sql); + } + + @Override + public int executeUpdate(String sql) throws SQLException { + throwIfClosed(); + return super.executeUpdate(sql); + } + + // No close() (it doesn't throw SQLException if already closed). + + @Override + public int getMaxFieldSize() throws SQLException { + throwIfClosed(); + return super.getMaxFieldSize(); + } + + @Override + public void setMaxFieldSize(int max) throws SQLException { + throwIfClosed(); + super.setMaxFieldSize(max); + } + + @Override + public int getMaxRows() { + try { + throwIfClosed(); + } catch (AlreadyClosedSqlException e) { + // Can't throw any SQLException because AvaticaConnection's + // getMaxRows() is missing "throws SQLException". + throw new RuntimeException(e.getMessage(), e); + } + return super.getMaxRows(); + } + + @Override + public void setMaxRows(int max) throws SQLException { + throwIfClosed(); + super.setMaxRows(max); + } + + @Override + public void setEscapeProcessing(boolean enable) throws SQLException { + throwIfClosed(); + super.setEscapeProcessing(enable); + } + + @Override + public int getQueryTimeout() throws SQLException { + throwIfClosed(); + return super.getQueryTimeout(); + } + + @Override + public void setQueryTimeout(int seconds) throws SQLException { + throwIfClosed(); + super.setQueryTimeout(seconds); + } + + @Override + public void cancel() throws SQLException { + throwIfClosed(); + super.cancel(); + } + + @Override + public SQLWarning getWarnings() throws SQLException { + throwIfClosed(); + return super.getWarnings(); + } + + @Override + public void clearWarnings() throws SQLException { + throwIfClosed(); + super.clearWarnings(); + } + + @Override + public void setCursorName(String name) throws SQLException { + throwIfClosed(); + super.setCursorName(name); + } + + @Override + public boolean execute(String sql) throws SQLException { + throwIfClosed(); + return super.execute(sql); + } + + @Override + public ResultSet getResultSet() throws SQLException { + throwIfClosed(); + return super.getResultSet(); + } + + @Override + public int getUpdateCount() throws SQLException { + throwIfClosed(); + return super.getUpdateCount(); + } + + @Override + public boolean getMoreResults() throws SQLException { + throwIfClosed(); + return super.getMoreResults(); + } + + @Override + public void setFetchDirection(int direction) throws SQLException { + throwIfClosed(); + super.setFetchDirection(direction); + } + + @Override + public int getFetchDirection(){ + try { + throwIfClosed(); + } catch (AlreadyClosedSqlException e) { + // Can't throw any SQLException because AvaticaConnection's + // getFetchDirection() is missing "throws SQLException". + throw new RuntimeException(e.getMessage(), e); + } + return super.getFetchDirection(); + } + + @Override + public void setFetchSize(int rows) throws SQLException { + throwIfClosed(); + super.setFetchSize(rows); + } + + @Override + public int getFetchSize() { + try { + throwIfClosed(); + } catch (AlreadyClosedSqlException e) { + // Can't throw any SQLException because AvaticaConnection's + // getFetchSize() is missing "throws SQLException". + throw new RuntimeException(e.getMessage(), e); + } + return super.getFetchSize(); + } + + @Override + public int getResultSetConcurrency() throws SQLException { + throwIfClosed(); + return super.getResultSetConcurrency(); + } + + @Override + public int getResultSetType() throws SQLException { + throwIfClosed(); + return super.getResultSetType(); + } + + @Override + public void addBatch(String sql) throws SQLException { + throwIfClosed(); + super.addBatch(sql); + } + + @Override + public void clearBatch() throws SQLException { + throwIfClosed(); + super.clearBatch(); + } + + @Override + public int[] executeBatch() throws SQLException { + throwIfClosed(); + return super.executeBatch(); + } + + @Override + public boolean getMoreResults(int current) throws SQLException { + throwIfClosed(); + return super.getMoreResults(current); + } + + @Override + public ResultSet getGeneratedKeys() throws SQLException { + throwIfClosed(); + return super.getGeneratedKeys(); + } + + @Override + public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { + throwIfClosed(); + return super.executeUpdate(sql, autoGeneratedKeys); + } + + @Override + public int executeUpdate(String sql, int columnIndexes[]) throws SQLException { + throwIfClosed(); + return super.executeUpdate(sql, columnIndexes); + } + + @Override + public int executeUpdate(String sql, String columnNames[]) throws SQLException { + throwIfClosed(); + return super.executeUpdate(sql, columnNames); + } + + @Override + public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { + throwIfClosed(); + return super.execute(sql, autoGeneratedKeys); + } + + @Override + public boolean execute(String sql, int columnIndexes[]) throws SQLException { + throwIfClosed(); + return super.execute(sql, columnIndexes); + } + + @Override + public boolean execute(String sql, String columnNames[]) throws SQLException { + throwIfClosed(); + return super.execute(sql, columnNames); + } + + @Override + public int getResultSetHoldability() throws SQLException { + throwIfClosed(); + return super.getResultSetHoldability(); + } + + @Override + public boolean isClosed() { + try { + return super.isClosed(); + } catch (SQLException e) { + throw new RuntimeException( + "Unexpected " + e + " from AvaticaPreparedStatement.isClosed" ); + } + } + + @Override + public void setPoolable(boolean poolable) throws SQLException { + throwIfClosed(); + super.setPoolable(poolable); + } + + @Override + public boolean isPoolable() throws SQLException { + throwIfClosed(); + return super.isPoolable(); + } + + @Override + public void closeOnCompletion() throws SQLException { + throwIfClosed(); + super.closeOnCompletion(); + } + + @Override + public boolean isCloseOnCompletion() throws SQLException { + throwIfClosed(); + return super.isCloseOnCompletion(); + } + + @Override + public ResultSet executeQuery() throws SQLException { + throwIfClosed(); + return super.executeQuery(); + } + + @Override + public int executeUpdate() throws SQLException { + throwIfClosed(); + return super.executeUpdate(); + } + + // Covered by superclass methods' calls to getParameter(int): + // - setNull(int, int) + // - setBoolean(int, boolean) + // - setByte(int, byte) + // - setShort(int, short) + // - setInt(int, int) + // - setLong(int, long) + // - setFloat(int, float) + // - setDouble(int, double) + // - setBigDecimal(int, BigDecimal) + // - setString(int, String) + // - setBytes(int, byte[]) + // - setDate(int, Date) + // - setTime(int, Time) + // - setTimestamp(int, Timestamp) + // - setAsciiStream(int, InputStream, int) + // - setUnicodeStream(int, InputStream, int) + // - setBinaryStream(int, InputStream, int) + + @Override + public void clearParameters() throws SQLException { + throwIfClosed(); + super.clearParameters(); + } + + // Covered by superclass methods' calls to getParameter(int): + // - setObject(int, Object, int) + // - setObject(int, Object) + + @Override + public boolean execute() throws SQLException { + throwIfClosed(); + return super.execute(); + } + + @Override + public void addBatch() throws SQLException { + throwIfClosed(); + super.addBatch(); + } + + // Covered by superclass methods' calls to getParameter(int): + // - setCharacterStream(int, Reader, int) + // - setRef(int, Ref) + // - setBlob(int, Blob) + // - setClob(int, Clob) + // - setArray(int, Array) + + @Override + public ResultSetMetaData getMetaData() { + try { + throwIfClosed(); + } catch (AlreadyClosedSqlException e) { + // Can't throw any SQLException because AvaticaConnection's + // getMetaData() is missing "throws SQLException". + throw new RuntimeException(e.getMessage(), e); + } + return super.getMetaData(); + } + + // Covered by superclass methods' calls to getParameter(int): + // - setDate(int, Date, Calendar) + // - setTime(int, Time, Calendar) + // - setTimestamp(int, Timestamp, Calendar) + // - setNull(int, int, String) + // - setURL(int, URL) + + @Override + public ParameterMetaData getParameterMetaData() throws SQLException { + throwIfClosed(); + return super.getParameterMetaData(); + } + + // The following methods are abstract in AvaticaPreparedStatement, and so + // cannot be overridden here to add throwIfClosed calls. They are addressed + // via DrillJdbc41Factory (which calls back to getParameter(int) in here, + // which calls throwIfClosed()). + // - setRowId(int, RowId) + // - setNString(int, String) + // - setNCharacterStream(int, Reader, long) + // - setNClob(int, NClob) + // - setClob(int, Reader, long) + // - setBlob(int, InputStream, long) + // - setNClob(int, Reader, long) + // - setSQLXML(int, SQLXML xmlObject) + // - setObject(int, Object, int, int) + // - setAsciiStream(int, InputStream, long) + // - setBinaryStream(int, InputStream, long) + // - setCharacterStream(int, Reader, long) + // - setAsciiStream(int, InputStream) + // - setBinaryStream(int, InputStream) + // - setCharacterStream(int, Reader) + // - setNCharacterStream(int, Reader) + // - setClob(int, Reader) + // - setBlob(int, InputStream) + // - setNClob(int, Reader) + } diff --git a/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillResultSetImpl.java b/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillResultSetImpl.java index 039d1335371..9f3e0f7eadb 100644 --- a/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillResultSetImpl.java +++ b/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillResultSetImpl.java @@ -20,6 +20,7 @@ import java.io.InputStream; import java.io.Reader; import java.math.BigDecimal; +import java.net.URL; import java.sql.Array; import java.sql.Blob; import java.sql.Clob; @@ -35,6 +36,7 @@ import java.sql.Time; import java.sql.Timestamp; import java.util.Calendar; +import java.util.Map; import java.util.TimeZone; import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingDeque; @@ -63,6 +65,7 @@ import org.apache.drill.jdbc.SchemaChangeListener; import static org.slf4j.LoggerFactory.getLogger; + import org.slf4j.Logger; import com.google.common.collect.Queues; @@ -111,7 +114,9 @@ class DrillResultSetImpl extends AvaticaResultSet implements DrillResultSet { * @throws AlreadyClosedSqlException if ResultSet is closed * @throws SQLException if error in calling {@link #isClosed()} */ - private void checkNotClosed() throws SQLException { + private void throwIfClosed() throws AlreadyClosedSqlException, + ExecutionCanceledSqlException, + SQLException { if ( isClosed() ) { if ( hasPendingCancelationNotification ) { hasPendingCancelationNotification = false; @@ -124,6 +129,14 @@ private void checkNotClosed() throws SQLException { } } + + // Note: Using dynamic proxies would reduce the quantity (450?) of method + // overrides by eliminating those that exist solely to check whether the + // object is closed. It would also eliminate the need to throw non-compliant + // RuntimeExceptions when Avatica's method declarations won't let us throw + // proper SQLExceptions. (Check performance before applying to frequently + // called ResultSet.) + @Override protected void cancel() { hasPendingCancelationNotification = true; @@ -142,13 +155,16 @@ synchronized void cleanup() { //////////////////////////////////////// // ResultSet-defined methods (in same order as in ResultSet): + // No isWrapperFor(Class) (it doesn't throw SQLException if already closed). + // No unwrap(Class) (it doesn't throw SQLException if already closed). + // (Not delegated.) @Override public boolean next() throws SQLException { - checkNotClosed(); + throwIfClosed(); // TODO: Resolve following comments (possibly obsolete because of later - // addition of preceding call to checkNotClosed. Also, NOTE that the - // following check, and maybe some checkNotClosed() calls, probably must + // addition of preceding call to throwIfClosed. Also, NOTE that the + // following check, and maybe some throwIfClosed() calls, probably must // synchronize on the statement, per the comment on AvaticaStatement's // openResultSet: @@ -171,246 +187,248 @@ public void close() { @Override public boolean wasNull() throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.wasNull(); } // Methods for accessing results by column index @Override public String getString( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getString( columnIndex ); } @Override public boolean getBoolean( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getBoolean( columnIndex ); } @Override public byte getByte( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getByte( columnIndex ); } @Override public short getShort( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getShort( columnIndex ); } @Override public int getInt( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getInt( columnIndex ); } @Override public long getLong( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getLong( columnIndex ); } @Override public float getFloat( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getFloat( columnIndex ); } @Override public double getDouble( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getDouble( columnIndex ); } @Override - public BigDecimal getBigDecimal( int columnIndex, int scale ) throws SQLException { - checkNotClosed(); + public BigDecimal getBigDecimal( int columnIndex, + int scale ) throws SQLException { + throwIfClosed(); return super.getBigDecimal( columnIndex, scale ); } @Override public byte[] getBytes( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getBytes( columnIndex ); } @Override public Date getDate( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getDate( columnIndex ); } @Override public Time getTime( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getTime( columnIndex ); } @Override public Timestamp getTimestamp( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getTimestamp( columnIndex ); } @Override public InputStream getAsciiStream( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getAsciiStream( columnIndex ); } @Override public InputStream getUnicodeStream( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getUnicodeStream( columnIndex ); } @Override public InputStream getBinaryStream( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getBinaryStream( columnIndex ); } // Methods for accessing results by column label @Override public String getString( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getString( columnLabel ); } @Override public boolean getBoolean( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getBoolean( columnLabel ); } @Override public byte getByte( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getByte( columnLabel ); } @Override public short getShort( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getShort( columnLabel ); } @Override public int getInt( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getInt( columnLabel ); } @Override public long getLong( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getLong( columnLabel ); } @Override public float getFloat( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getFloat( columnLabel ); } @Override public double getDouble( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getDouble( columnLabel ); } @Override - public BigDecimal getBigDecimal( String columnLabel, int scale ) throws SQLException { - checkNotClosed(); + public BigDecimal getBigDecimal( String columnLabel, + int scale ) throws SQLException { + throwIfClosed(); return super.getBigDecimal( columnLabel, scale ); } @Override public byte[] getBytes( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getBytes( columnLabel ); } @Override public Date getDate( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getDate( columnLabel ); } @Override public Time getTime( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getTime( columnLabel ); } @Override public Timestamp getTimestamp( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getTimestamp( columnLabel ); } @Override public InputStream getAsciiStream( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getAsciiStream( columnLabel ); } @Override public InputStream getUnicodeStream( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getUnicodeStream( columnLabel ); } @Override public InputStream getBinaryStream( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getBinaryStream( columnLabel ); } // Advanced features: @Override public SQLWarning getWarnings() throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getWarnings(); } @Override public void clearWarnings() throws SQLException { - checkNotClosed(); - super.clearWarnings(); + throwIfClosed(); + super.clearWarnings(); } @Override public String getCursorName() throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getCursorName(); } // (Not delegated.) @Override public ResultSetMetaData getMetaData() throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getMetaData(); } @Override public Object getObject( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getObject( columnIndex ); } @Override public Object getObject( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getObject( columnLabel ); } //---------------------------------------------------------------- @Override public int findColumn( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.findColumn( columnLabel ); } @@ -420,25 +438,25 @@ public int findColumn( String columnLabel ) throws SQLException { //--------------------------------------------------------------------- @Override public Reader getCharacterStream( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getCharacterStream( columnIndex ); } @Override public Reader getCharacterStream( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getCharacterStream( columnLabel ); } @Override public BigDecimal getBigDecimal( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getBigDecimal( columnIndex ); } @Override public BigDecimal getBigDecimal( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getBigDecimal( columnLabel ); } @@ -447,73 +465,73 @@ public BigDecimal getBigDecimal( String columnLabel ) throws SQLException { //--------------------------------------------------------------------- @Override public boolean isBeforeFirst() throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.isBeforeFirst(); } @Override public boolean isAfterLast() throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.isAfterLast(); } @Override public boolean isFirst() throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.isFirst(); } @Override public boolean isLast() throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.isLast(); } @Override public void beforeFirst() throws SQLException { - checkNotClosed(); + throwIfClosed(); super.beforeFirst(); } @Override public void afterLast() throws SQLException { - checkNotClosed(); + throwIfClosed(); super.afterLast(); } @Override public boolean first() throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.first(); } @Override public boolean last() throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.last(); } @Override public int getRow() throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getRow(); } @Override public boolean absolute( int row ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.absolute( row ); } @Override public boolean relative( int rows ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.relative( rows ); } @Override public boolean previous() throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.previous(); } @@ -523,37 +541,37 @@ public boolean previous() throws SQLException { @Override public void setFetchDirection( int direction ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.setFetchDirection( direction ); } @Override public int getFetchDirection() throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getFetchDirection(); } @Override public void setFetchSize( int rows ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.setFetchSize( rows ); } @Override public int getFetchSize() throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getFetchSize(); } @Override public int getType() throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getType(); } @Override public int getConcurrency() throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getConcurrency(); } @@ -562,484 +580,505 @@ public int getConcurrency() throws SQLException { //--------------------------------------------------------------------- @Override public boolean rowUpdated() throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.rowUpdated(); } @Override public boolean rowInserted() throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.rowInserted(); } @Override public boolean rowDeleted() throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.rowDeleted(); } @Override public void updateNull( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateNull( columnIndex ); } @Override public void updateBoolean( int columnIndex, boolean x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateBoolean( columnIndex, x ); } @Override public void updateByte( int columnIndex, byte x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateByte( columnIndex, x ); } @Override public void updateShort( int columnIndex, short x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateShort( columnIndex, x ); } @Override public void updateInt( int columnIndex, int x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateInt( columnIndex, x ); } @Override public void updateLong( int columnIndex, long x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateLong( columnIndex, x ); } @Override public void updateFloat( int columnIndex, float x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateFloat( columnIndex, x ); } @Override public void updateDouble( int columnIndex, double x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateDouble( columnIndex, x ); } @Override - public void updateBigDecimal( int columnIndex, BigDecimal x ) throws SQLException { - checkNotClosed(); + public void updateBigDecimal( int columnIndex, + BigDecimal x ) throws SQLException { + throwIfClosed(); super.updateBigDecimal( columnIndex, x ); } @Override public void updateString( int columnIndex, String x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateString( columnIndex, x ); } @Override public void updateBytes( int columnIndex, byte[] x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateBytes( columnIndex, x ); } @Override public void updateDate( int columnIndex, Date x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateDate( columnIndex, x ); } @Override public void updateTime( int columnIndex, Time x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateTime( columnIndex, x ); } @Override public void updateTimestamp( int columnIndex, Timestamp x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateTimestamp( columnIndex, x ); } @Override - public void updateAsciiStream( int columnIndex, InputStream x, int length ) throws SQLException { - checkNotClosed(); + public void updateAsciiStream( int columnIndex, InputStream x, + int length ) throws SQLException { + throwIfClosed(); super.updateAsciiStream( columnIndex, x, length ); } @Override - public void updateBinaryStream( int columnIndex, InputStream x, int length ) throws SQLException { - checkNotClosed(); + public void updateBinaryStream( int columnIndex, InputStream x, + int length ) throws SQLException { + throwIfClosed(); super.updateBinaryStream( columnIndex, x, length ); } @Override - public void updateCharacterStream( int columnIndex, Reader x, int length ) throws SQLException { - checkNotClosed(); + public void updateCharacterStream( int columnIndex, Reader x, + int length ) throws SQLException { + throwIfClosed(); super.updateCharacterStream( columnIndex, x, length ); } @Override - public void updateObject( int columnIndex, Object x, int scaleOrLength ) throws SQLException { - checkNotClosed(); + public void updateObject( int columnIndex, Object x, + int scaleOrLength ) throws SQLException { + throwIfClosed(); super.updateObject( columnIndex, x, scaleOrLength ); } @Override public void updateObject( int columnIndex, Object x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateObject( columnIndex, x ); } @Override public void updateNull( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateNull( columnLabel ); } @Override public void updateBoolean( String columnLabel, boolean x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateBoolean( columnLabel, x ); } @Override public void updateByte( String columnLabel, byte x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateByte( columnLabel, x ); } @Override public void updateShort( String columnLabel, short x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateShort( columnLabel, x ); } @Override public void updateInt( String columnLabel, int x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateInt( columnLabel, x ); } @Override public void updateLong( String columnLabel, long x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateLong( columnLabel, x ); } @Override public void updateFloat( String columnLabel, float x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateFloat( columnLabel, x ); } @Override public void updateDouble( String columnLabel, double x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateDouble( columnLabel, x ); } @Override - public void updateBigDecimal( String columnLabel, BigDecimal x ) throws SQLException { - checkNotClosed(); + public void updateBigDecimal( String columnLabel, + BigDecimal x ) throws SQLException { + throwIfClosed(); super.updateBigDecimal( columnLabel, x ); } @Override public void updateString( String columnLabel, String x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateString( columnLabel, x ); } @Override public void updateBytes( String columnLabel, byte[] x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateBytes( columnLabel, x ); } @Override public void updateDate( String columnLabel, Date x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateDate( columnLabel, x ); } @Override public void updateTime( String columnLabel, Time x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateTime( columnLabel, x ); } @Override public void updateTimestamp( String columnLabel, Timestamp x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateTimestamp( columnLabel, x ); } @Override - public void updateAsciiStream( String columnLabel, InputStream x, int length ) throws SQLException { - checkNotClosed(); + public void updateAsciiStream( String columnLabel, InputStream x, + int length ) throws SQLException { + throwIfClosed(); super.updateAsciiStream( columnLabel, x, length ); } @Override - public void updateBinaryStream( String columnLabel, InputStream x, int length ) throws SQLException { - checkNotClosed(); + public void updateBinaryStream( String columnLabel, InputStream x, + int length ) throws SQLException { + throwIfClosed(); super.updateBinaryStream( columnLabel, x, length ); } @Override - public void updateCharacterStream( String columnLabel, Reader reader, int length ) throws SQLException { - checkNotClosed(); + public void updateCharacterStream( String columnLabel, Reader reader, + int length ) throws SQLException { + throwIfClosed(); super.updateCharacterStream( columnLabel, reader, length ); } @Override - public void updateObject( String columnLabel, Object x, int scaleOrLength ) throws SQLException { - checkNotClosed(); + public void updateObject( String columnLabel, Object x, + int scaleOrLength ) throws SQLException { + throwIfClosed(); super.updateObject( columnLabel, x, scaleOrLength ); } @Override public void updateObject( String columnLabel, Object x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateObject( columnLabel, x ); } @Override public void insertRow() throws SQLException { - checkNotClosed(); + throwIfClosed(); super.insertRow(); } @Override public void updateRow() throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateRow(); } @Override public void deleteRow() throws SQLException { - checkNotClosed(); + throwIfClosed(); super.deleteRow(); } @Override public void refreshRow() throws SQLException { - checkNotClosed(); + throwIfClosed(); super.refreshRow(); } @Override public void cancelRowUpdates() throws SQLException { - checkNotClosed(); + throwIfClosed(); super.cancelRowUpdates(); } @Override public void moveToInsertRow() throws SQLException { - checkNotClosed(); + throwIfClosed(); super.moveToInsertRow(); } @Override public void moveToCurrentRow() throws SQLException { - checkNotClosed(); + throwIfClosed(); super.moveToCurrentRow(); } @Override public AvaticaStatement getStatement() { - // Note: No already-closed exception for getStatement(). + try { + throwIfClosed(); + } catch (AlreadyClosedSqlException e) { + // Can't throw any SQLException because AvaticaConnection's + // getStatement() is missing "throws SQLException". + throw new RuntimeException(e.getMessage(), e); + } catch (SQLException e) { + throw new RuntimeException(e.getMessage(), e); + } return super.getStatement(); } @Override - public Object getObject( int columnIndex, java.util.Map> map ) throws SQLException { - checkNotClosed(); + public Object getObject( int columnIndex, + Map> map ) throws SQLException { + throwIfClosed(); return super.getObject( columnIndex, map ); } @Override public Ref getRef( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getRef( columnIndex ); } @Override public Blob getBlob( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getBlob( columnIndex ); } @Override public Clob getClob( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getClob( columnIndex ); } @Override public Array getArray( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getArray( columnIndex ); } @Override - public Object getObject( String columnLabel, java.util.Map> map ) throws SQLException { - checkNotClosed(); + public Object getObject( String columnLabel, + Map> map ) throws SQLException { + throwIfClosed(); return super.getObject( columnLabel, map ); } @Override public Ref getRef( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getRef( columnLabel ); } @Override public Blob getBlob( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getBlob( columnLabel ); } @Override public Clob getClob( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getClob( columnLabel ); } @Override public Array getArray( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getArray( columnLabel ); } @Override public Date getDate( int columnIndex, Calendar cal ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getDate( columnIndex, cal ); } @Override public Date getDate( String columnLabel, Calendar cal ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getDate( columnLabel, cal ); } @Override public Time getTime( int columnIndex, Calendar cal ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getTime( columnIndex, cal ); } @Override public Time getTime( String columnLabel, Calendar cal ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getTime( columnLabel, cal ); } @Override public Timestamp getTimestamp( int columnIndex, Calendar cal ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getTimestamp( columnIndex, cal ); } @Override - public Timestamp getTimestamp( String columnLabel, Calendar cal ) throws SQLException { - checkNotClosed(); + public Timestamp getTimestamp( String columnLabel, + Calendar cal ) throws SQLException { + throwIfClosed(); return super.getTimestamp( columnLabel, cal ); } //-------------------------- JDBC 3.0 ---------------------------------------- @Override - public java.net.URL getURL( int columnIndex ) throws SQLException { - checkNotClosed(); + public URL getURL( int columnIndex ) throws SQLException { + throwIfClosed(); return super.getURL( columnIndex ); } @Override - public java.net.URL getURL( String columnLabel ) throws SQLException { - checkNotClosed(); + public URL getURL( String columnLabel ) throws SQLException { + throwIfClosed(); return super.getURL( columnLabel ); } @Override public void updateRef( int columnIndex, Ref x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateRef( columnIndex, x ); } @Override public void updateRef( String columnLabel, Ref x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateRef( columnLabel, x ); } @Override public void updateBlob( int columnIndex, Blob x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateBlob( columnIndex, x ); } @Override public void updateBlob( String columnLabel, Blob x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateBlob( columnLabel, x ); } @Override public void updateClob( int columnIndex, Clob x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateClob( columnIndex, x ); } @Override public void updateClob( String columnLabel, Clob x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateClob( columnLabel, x ); } @Override public void updateArray( int columnIndex, Array x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateArray( columnIndex, x ); } @Override public void updateArray( String columnLabel, Array x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateArray( columnLabel, x ); } //------------------------- JDBC 4.0 ----------------------------------- @Override public RowId getRowId( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getRowId( columnIndex ); } @Override public RowId getRowId( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getRowId( columnLabel ); } @Override public void updateRowId( int columnIndex, RowId x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateRowId( columnIndex, x ); } @Override public void updateRowId( String columnLabel, RowId x ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateRowId( columnLabel, x ); } @Override public int getHoldability() throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getHoldability(); } @@ -1051,267 +1090,294 @@ public boolean isClosed() throws SQLException { @Override public void updateNString( int columnIndex, String nString ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateNString( columnIndex, nString ); } @Override - public void updateNString( String columnLabel, String nString ) throws SQLException { - checkNotClosed(); + public void updateNString( String columnLabel, + String nString ) throws SQLException { + throwIfClosed(); super.updateNString( columnLabel, nString ); } @Override public void updateNClob( int columnIndex, NClob nClob ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateNClob( columnIndex, nClob ); } @Override public void updateNClob( String columnLabel, NClob nClob ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateNClob( columnLabel, nClob ); } @Override public NClob getNClob( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getNClob( columnIndex ); } @Override public NClob getNClob( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getNClob( columnLabel ); } @Override public SQLXML getSQLXML( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getSQLXML( columnIndex ); } @Override public SQLXML getSQLXML( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getSQLXML( columnLabel ); } @Override - public void updateSQLXML( int columnIndex, SQLXML xmlObject ) throws SQLException { - checkNotClosed(); + public void updateSQLXML( int columnIndex, + SQLXML xmlObject ) throws SQLException { + throwIfClosed(); super.updateSQLXML( columnIndex, xmlObject ); } @Override - public void updateSQLXML( String columnLabel, SQLXML xmlObject ) throws SQLException { - checkNotClosed(); + public void updateSQLXML( String columnLabel, + SQLXML xmlObject ) throws SQLException { + throwIfClosed(); super.updateSQLXML( columnLabel, xmlObject ); } @Override public String getNString( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getNString( columnIndex ); } @Override public String getNString( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getNString( columnLabel ); } @Override public Reader getNCharacterStream( int columnIndex ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getNCharacterStream( columnIndex ); } @Override public Reader getNCharacterStream( String columnLabel ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getNCharacterStream( columnLabel ); } @Override - public void updateNCharacterStream( int columnIndex, Reader x, long length ) throws SQLException { - checkNotClosed(); + public void updateNCharacterStream( int columnIndex, Reader x, + long length ) throws SQLException { + throwIfClosed(); super.updateNCharacterStream( columnIndex, x, length ); } @Override - public void updateNCharacterStream( String columnLabel, Reader reader, long length ) throws SQLException { - checkNotClosed(); + public void updateNCharacterStream( String columnLabel, Reader reader, + long length ) throws SQLException { + throwIfClosed(); super.updateNCharacterStream( columnLabel, reader, length ); } @Override - public void updateAsciiStream( int columnIndex, InputStream x, long length ) throws SQLException { - checkNotClosed(); + public void updateAsciiStream( int columnIndex, InputStream x, + long length ) throws SQLException { + throwIfClosed(); super.updateAsciiStream( columnIndex, x, length ); } @Override - public void updateBinaryStream( int columnIndex, InputStream x, long length ) throws SQLException { - checkNotClosed(); + public void updateBinaryStream( int columnIndex, InputStream x, + long length ) throws SQLException { + throwIfClosed(); super.updateBinaryStream( columnIndex, x, length ); } @Override - public void updateCharacterStream( int columnIndex, Reader x, long length ) throws SQLException { - checkNotClosed(); + public void updateCharacterStream( int columnIndex, Reader x, + long length ) throws SQLException { + throwIfClosed(); super.updateCharacterStream( columnIndex, x, length ); } @Override - public void updateAsciiStream( String columnLabel, InputStream x, long length ) throws SQLException { - checkNotClosed(); + public void updateAsciiStream( String columnLabel, InputStream x, + long length ) throws SQLException { + throwIfClosed(); super.updateAsciiStream( columnLabel, x, length ); } @Override - public void updateBinaryStream( String columnLabel, InputStream x, long length ) throws SQLException { - checkNotClosed(); + public void updateBinaryStream( String columnLabel, InputStream x, + long length ) throws SQLException { + throwIfClosed(); super.updateBinaryStream( columnLabel, x, length ); } @Override - public void updateCharacterStream( String columnLabel, Reader reader, long length ) throws SQLException { - checkNotClosed(); + public void updateCharacterStream( String columnLabel, Reader reader, + long length ) throws SQLException { + throwIfClosed(); super.updateCharacterStream( columnLabel, reader, length ); } @Override - public void updateBlob( int columnIndex, InputStream inputStream, long length ) throws SQLException { - checkNotClosed(); + public void updateBlob( int columnIndex, InputStream inputStream, + long length ) throws SQLException { + throwIfClosed(); super.updateBlob( columnIndex, inputStream, length ); } @Override - public void updateBlob( String columnLabel, InputStream inputStream, long length ) throws SQLException { - checkNotClosed(); + public void updateBlob( String columnLabel, InputStream inputStream, + long length ) throws SQLException { + throwIfClosed(); super.updateBlob( columnLabel, inputStream, length ); } @Override - public void updateClob( int columnIndex, Reader reader, long length ) throws SQLException { - checkNotClosed(); + public void updateClob( int columnIndex, Reader reader, + long length ) throws SQLException { + throwIfClosed(); super.updateClob( columnIndex, reader, length ); } @Override - public void updateClob( String columnLabel, Reader reader, long length ) throws SQLException { - checkNotClosed(); + public void updateClob( String columnLabel, Reader reader, + long length ) throws SQLException { + throwIfClosed(); super.updateClob( columnLabel, reader, length ); } @Override - public void updateNClob( int columnIndex, Reader reader, long length ) throws SQLException { - checkNotClosed(); + public void updateNClob( int columnIndex, Reader reader, + long length ) throws SQLException { + throwIfClosed(); super.updateNClob( columnIndex, reader, length ); } @Override - public void updateNClob( String columnLabel, Reader reader, long length ) throws SQLException { - checkNotClosed(); + public void updateNClob( String columnLabel, Reader reader, + long length ) throws SQLException { + throwIfClosed(); super.updateNClob( columnLabel, reader, length ); } //--- @Override - public void updateNCharacterStream( int columnIndex, Reader x ) throws SQLException { - checkNotClosed(); + public void updateNCharacterStream( int columnIndex, + Reader x ) throws SQLException { + throwIfClosed(); super.updateNCharacterStream( columnIndex, x ); } @Override - public void updateNCharacterStream( String columnLabel, Reader reader ) throws SQLException { - checkNotClosed(); + public void updateNCharacterStream( String columnLabel, + Reader reader ) throws SQLException { + throwIfClosed(); super.updateNCharacterStream( columnLabel, reader ); } @Override - public void updateAsciiStream( int columnIndex, InputStream x ) throws SQLException { - checkNotClosed(); + public void updateAsciiStream( int columnIndex, + InputStream x ) throws SQLException { + throwIfClosed(); super.updateAsciiStream( columnIndex, x ); } @Override - public void updateBinaryStream( int columnIndex, InputStream x ) throws SQLException { - checkNotClosed(); + public void updateBinaryStream( int columnIndex, + InputStream x ) throws SQLException { + throwIfClosed(); super.updateBinaryStream( columnIndex, x ); } @Override - public void updateCharacterStream( int columnIndex, Reader x ) throws SQLException { - checkNotClosed(); + public void updateCharacterStream( int columnIndex, + Reader x ) throws SQLException { + throwIfClosed(); super.updateCharacterStream( columnIndex, x ); } @Override - public void updateAsciiStream( String columnLabel, InputStream x ) throws SQLException { - checkNotClosed(); + public void updateAsciiStream( String columnLabel, + InputStream x ) throws SQLException { + throwIfClosed(); super.updateAsciiStream( columnLabel, x ); } @Override - public void updateBinaryStream( String columnLabel, InputStream x ) throws SQLException { - checkNotClosed(); + public void updateBinaryStream( String columnLabel, + InputStream x ) throws SQLException { + throwIfClosed(); super.updateBinaryStream( columnLabel, x ); } @Override - public void updateCharacterStream( String columnLabel, Reader reader ) throws SQLException { - checkNotClosed(); + public void updateCharacterStream( String columnLabel, + Reader reader ) throws SQLException { + throwIfClosed(); super.updateCharacterStream( columnLabel, reader ); } @Override - public void updateBlob( int columnIndex, InputStream inputStream ) throws SQLException { - checkNotClosed(); + public void updateBlob( int columnIndex, + InputStream inputStream ) throws SQLException { + throwIfClosed(); super.updateBlob( columnIndex, inputStream ); } @Override - public void updateBlob( String columnLabel, InputStream inputStream ) throws SQLException { - checkNotClosed(); + public void updateBlob( String columnLabel, + InputStream inputStream ) throws SQLException { + throwIfClosed(); super.updateBlob( columnLabel, inputStream ); } @Override public void updateClob( int columnIndex, Reader reader ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateClob( columnIndex, reader ); } @Override public void updateClob( String columnLabel, Reader reader ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateClob( columnLabel, reader ); } @Override public void updateNClob( int columnIndex, Reader reader ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateNClob( columnIndex, reader ); } @Override public void updateNClob( String columnLabel, Reader reader ) throws SQLException { - checkNotClosed(); + throwIfClosed(); super.updateNClob( columnLabel, reader ); } //------------------------- JDBC 4.1 ----------------------------------- @Override public T getObject( int columnIndex, Class type ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getObject( columnIndex, type ); } @Override public T getObject( String columnLabel, Class type ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.getObject( columnLabel, type ); } @@ -1320,7 +1386,7 @@ public T getObject( String columnLabel, Class type ) throws SQLException // DrillResultSet methods: public String getQueryId() throws SQLException { - checkNotClosed(); + throwIfClosed(); if (resultsListener.getQueryId() != null) { return QueryIdHelper.getQueryId(resultsListener.getQueryId()); } else { diff --git a/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillResultSetMetaDataImpl.java b/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillResultSetMetaDataImpl.java new file mode 100644 index 00000000000..4be93b46b61 --- /dev/null +++ b/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillResultSetMetaDataImpl.java @@ -0,0 +1,198 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.drill.jdbc.impl; + +import java.sql.SQLException; +import java.util.List; + +import org.apache.drill.jdbc.AlreadyClosedSqlException; + +import net.hydromatic.avatica.AvaticaResultSetMetaData; +import net.hydromatic.avatica.AvaticaStatement; +import net.hydromatic.avatica.ColumnMetaData; + + +public class DrillResultSetMetaDataImpl extends AvaticaResultSetMetaData { + + private final AvaticaStatement statement; + + + public DrillResultSetMetaDataImpl(AvaticaStatement statement, + Object query, + List columnMetaDataList) { + super(statement, query, columnMetaDataList); + this.statement = statement; + } + + /** + * Throws AlreadyClosedSqlException if the associated ResultSet is closed. + * + * @throws AlreadyClosedSqlException if ResultSet is closed + * @throws SQLException if error in checking ResultSet's status + */ + private void throwIfClosed() throws AlreadyClosedSqlException, + SQLException { + // Statement.isClosed() call is to avoid exception from getResultSet(). + if (statement.isClosed() + || statement.getResultSet().isClosed()) { + throw new AlreadyClosedSqlException( + "ResultSetMetaData's ResultSet is already closed." ); + } + } + + + // Note: Using dynamic proxies would reduce the quantity (450?) of method + // overrides by eliminating those that exist solely to check whether the + // object is closed. It would also eliminate the need to throw non-compliant + // RuntimeExceptions when Avatica's method declarations won't let us throw + // proper SQLExceptions. (Check performance before applying to frequently + // called ResultSet.) + + // Note: Methods are in same order as in java.sql.ResultSetMetaData. + + // No isWrapperFor(Class) (it doesn't throw SQLException if already closed). + // No unwrap(Class) (it doesn't throw SQLException if already closed). + + @Override + public int getColumnCount() throws SQLException { + throwIfClosed(); + return super.getColumnCount(); + } + + @Override + public boolean isAutoIncrement(int column) throws SQLException { + throwIfClosed(); + return super.isAutoIncrement(column); + } + + @Override + public boolean isCaseSensitive(int column) throws SQLException { + throwIfClosed(); + return super.isCaseSensitive(column); + } + + @Override + public boolean isSearchable(int column) throws SQLException { + throwIfClosed(); + return super.isSearchable(column); + } + + @Override + public boolean isCurrency(int column) throws SQLException { + throwIfClosed(); + return super.isCurrency(column); + } + + @Override + public int isNullable(int column) throws SQLException { + throwIfClosed(); + return super.isNullable(column); + } + + @Override + public boolean isSigned(int column) throws SQLException { + throwIfClosed(); + return super.isSigned(column); + } + + @Override + public int getColumnDisplaySize(int column) throws SQLException { + throwIfClosed(); + return super.getColumnDisplaySize(column); + } + + @Override + public String getColumnLabel(int column) throws SQLException { + throwIfClosed(); + return super.getColumnLabel(column); + } + + @Override + public String getColumnName(int column) throws SQLException { + throwIfClosed(); + return super.getColumnName(column); + } + + @Override + public String getSchemaName(int column) throws SQLException { + throwIfClosed(); + return super.getSchemaName(column); + } + + @Override + public int getPrecision(int column) throws SQLException { + throwIfClosed(); + return super.getPrecision(column); + } + + @Override + public int getScale(int column) throws SQLException { + throwIfClosed(); + return super.getScale(column); + } + + @Override + public String getTableName(int column) throws SQLException { + throwIfClosed(); + return super.getTableName(column); + } + + @Override + public String getCatalogName(int column) throws SQLException { + throwIfClosed(); + return super.getCatalogName(column); + } + + @Override + public int getColumnType(int column) throws SQLException { + throwIfClosed(); + return super.getColumnType(column); + } + + @Override + public String getColumnTypeName(int column) throws SQLException { + throwIfClosed(); + return super.getColumnTypeName(column); + } + + @Override + public boolean isReadOnly(int column) throws SQLException { + throwIfClosed(); + return super.isReadOnly(column); + } + + @Override + public boolean isWritable(int column) throws SQLException { + throwIfClosed(); + return super.isWritable(column); + } + + @Override + public boolean isDefinitelyWritable(int column) throws SQLException { + throwIfClosed(); + return super.isDefinitelyWritable(column); + } + + @Override + public String getColumnClassName(int column) throws SQLException { + throwIfClosed(); + return super.getColumnClassName(column); + } + +} diff --git a/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillStatementImpl.java b/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillStatementImpl.java index 077ebd7212f..54b27096d37 100644 --- a/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillStatementImpl.java +++ b/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillStatementImpl.java @@ -20,6 +20,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; +import java.sql.SQLWarning; import java.sql.Statement; import org.apache.drill.common.exceptions.DrillRuntimeException; @@ -52,14 +53,28 @@ class DrillStatementImpl extends AvaticaStatement implements DrillStatement, * * @throws AlreadyClosedSqlException if Statement is closed */ - private void checkNotClosed() throws AlreadyClosedSqlException { + private void throwIfClosed() throws AlreadyClosedSqlException { if ( isClosed() ) { throw new AlreadyClosedSqlException( "Statement is already closed." ); } } + // Note: Using dynamic proxies would reduce the quantity (450?) of method + // overrides by eliminating those that exist solely to check whether the + // object is closed. It would also eliminate the need to throw non-compliant + // RuntimeExceptions when Avatica's method declarations won't let us throw + // proper SQLExceptions. (Check performance before applying to frequently + // called ResultSet.) + @Override public DrillConnectionImpl getConnection() { + // Can't throw any SQLException because AvaticaConnection's getConnection() is + // missing "throws SQLException". + try { + throwIfClosed(); + } catch (AlreadyClosedSqlException e) { + throw new RuntimeException(e.getMessage(), e); + } return connection; } @@ -81,7 +96,7 @@ private SQLException unwrapIfExtra( final SQLException superMethodException ) { @Override public boolean execute( String sql ) throws SQLException { - checkNotClosed(); + throwIfClosed(); try { return super.execute( sql ); } @@ -93,7 +108,7 @@ public boolean execute( String sql ) throws SQLException { @Override public ResultSet executeQuery( String sql ) throws SQLException { try { - checkNotClosed(); + throwIfClosed(); return super.executeQuery( sql ); } catch ( final SQLException possiblyExtraWrapperException ) { @@ -103,7 +118,7 @@ public ResultSet executeQuery( String sql ) throws SQLException { @Override public int executeUpdate( String sql ) throws SQLException { - checkNotClosed(); + throwIfClosed(); try { return super.executeUpdate( sql ); } @@ -114,13 +129,13 @@ public int executeUpdate( String sql ) throws SQLException { @Override public int executeUpdate( String sql, int[] columnIndexes ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.executeUpdate( sql, columnIndexes ); } @Override public int executeUpdate( String sql, String[] columnNames ) throws SQLException { - checkNotClosed(); + throwIfClosed(); return super.executeUpdate( sql, columnNames ); } @@ -133,7 +148,7 @@ public void cleanUp() { @Override public int getQueryTimeout() throws AlreadyClosedSqlException { - checkNotClosed(); + throwIfClosed(); return 0; // (No no timeout.) } @@ -142,7 +157,7 @@ public void setQueryTimeout( int milliseconds ) throws AlreadyClosedSqlException, InvalidParameterSqlException, SQLFeatureNotSupportedException { - checkNotClosed(); + throwIfClosed(); if ( milliseconds < 0 ) { throw new InvalidParameterSqlException( "Invalid (negative) \"milliseconds\" parameter to setQueryTimeout(...)" @@ -171,4 +186,225 @@ public boolean isClosed() { } } + // Note: Methods are in same order as in java.sql.Statement. + + // No isWrapperFor(Class) (it doesn't throw SQLException if already closed). + // No unwrap(Class) (it doesn't throw SQLException if already closed). + // No close() (it doesn't throw SQLException if already closed). + + @Override + public int getMaxFieldSize() throws SQLException { + throwIfClosed(); + return super.getMaxFieldSize(); + } + + @Override + public void setMaxFieldSize(int max) throws SQLException { + throwIfClosed(); + super.setMaxFieldSize(max); + } + + @Override + public int getMaxRows() { + try { + throwIfClosed(); + } catch (AlreadyClosedSqlException e) { + // Can't throw any SQLException because AvaticaConnection's + // getMaxRows() is missing "throws SQLException". + throw new RuntimeException(e.getMessage(), e); + } + return super.getMaxRows(); + } + + @Override + public void setMaxRows(int max) throws SQLException { + throwIfClosed(); + super.setMaxRows(max); + } + + @Override + public void setEscapeProcessing(boolean enable) throws SQLException { + throwIfClosed(); + super.setEscapeProcessing(enable); + } + + @Override + public void cancel() throws SQLException { + throwIfClosed(); + super.cancel(); + } + + @Override + public SQLWarning getWarnings() throws SQLException { + throwIfClosed(); + return super.getWarnings(); + } + + @Override + public void clearWarnings() throws SQLException { + throwIfClosed(); + super.clearWarnings(); + } + + @Override + public void setCursorName(String name) throws SQLException { + throwIfClosed(); + super.setCursorName(name); + } + + @Override + public ResultSet getResultSet() throws SQLException { + throwIfClosed(); + return super.getResultSet(); + } + + @Override + public int getUpdateCount() throws SQLException { + throwIfClosed(); + return super.getUpdateCount(); + } + + @Override + public boolean getMoreResults() throws SQLException { + throwIfClosed(); + return super.getMoreResults(); + } + + @Override + public void setFetchDirection(int direction) throws SQLException { + throwIfClosed(); + super.setFetchDirection(direction); + } + + @Override + public int getFetchDirection() { + try { + throwIfClosed(); + } catch (AlreadyClosedSqlException e) { + // Can't throw any SQLException because AvaticaConnection's + // getFetchDirection() is missing "throws SQLException". + throw new RuntimeException(e.getMessage(), e); + } + return super.getFetchDirection(); + } + + @Override + public void setFetchSize(int rows) throws SQLException { + throwIfClosed(); + super.setFetchSize(rows); + } + + @Override + public int getFetchSize() { + try { + throwIfClosed(); + } catch (AlreadyClosedSqlException e) { + // Can't throw any SQLException because AvaticaConnection's + // getFetchSize() is missing "throws SQLException". + throw new RuntimeException(e.getMessage(), e); + } + return super.getFetchSize(); + } + + @Override + public int getResultSetConcurrency() throws SQLException { + throwIfClosed(); + return super.getResultSetConcurrency(); + } + + @Override + public int getResultSetType() throws SQLException { + throwIfClosed(); + return super.getResultSetType(); + } + + @Override + public void addBatch(String sql) throws SQLException { + throwIfClosed(); + try { + super.addBatch(sql); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } + } + + @Override + public void clearBatch() throws SQLException { + throwIfClosed(); + super.clearBatch(); + } + + @Override + public int[] executeBatch() throws SQLException { + throwIfClosed(); + return super.executeBatch(); + } + + @Override + public boolean getMoreResults(int current) throws SQLException { + throwIfClosed(); + return super.getMoreResults(current); + } + + @Override + public ResultSet getGeneratedKeys() throws SQLException { + throwIfClosed(); + return super.getGeneratedKeys(); + } + + @Override + public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { + throwIfClosed(); + return super.executeUpdate(sql, autoGeneratedKeys); + } + + @Override + public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { + throwIfClosed(); + return super.execute(sql, autoGeneratedKeys); + } + + @Override + public boolean execute(String sql, int columnIndexes[]) throws SQLException { + throwIfClosed(); + return super.execute(sql, columnIndexes); + } + + @Override + public boolean execute(String sql, String columnNames[]) throws SQLException { + throwIfClosed(); + return super.execute(sql, columnNames); + } + + @Override + public int getResultSetHoldability() throws SQLException { + throwIfClosed(); + return super.getResultSetHoldability(); + } + + @Override + public void setPoolable(boolean poolable) throws SQLException { + throwIfClosed(); + super.setPoolable(poolable); + } + + @Override + public boolean isPoolable() throws SQLException { + throwIfClosed(); + return super.isPoolable(); + } + + @Override + public void closeOnCompletion() throws SQLException { + throwIfClosed(); + super.closeOnCompletion(); + } + + @Override + public boolean isCloseOnCompletion() throws SQLException { + throwIfClosed(); + return super.isCloseOnCompletion(); + } + } diff --git a/exec/jdbc/src/test/java/org/apache/drill/jdbc/ConnectionTest.java b/exec/jdbc/src/test/java/org/apache/drill/jdbc/ConnectionTest.java index 198cf4c0ad1..d8ca84906f3 100644 --- a/exec/jdbc/src/test/java/org/apache/drill/jdbc/ConnectionTest.java +++ b/exec/jdbc/src/test/java/org/apache/drill/jdbc/ConnectionTest.java @@ -1,10 +1,10 @@ /** - * Licensed to the Apache Software Foundation ( ASF ) under one + * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 ( the - * "License" ); you may not use this file except in compliance + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 diff --git a/exec/jdbc/src/test/java/org/apache/drill/jdbc/ConnectionTransactionMethodsTest.java b/exec/jdbc/src/test/java/org/apache/drill/jdbc/ConnectionTransactionMethodsTest.java index 1aff9182b14..f79d447c4ff 100644 --- a/exec/jdbc/src/test/java/org/apache/drill/jdbc/ConnectionTransactionMethodsTest.java +++ b/exec/jdbc/src/test/java/org/apache/drill/jdbc/ConnectionTransactionMethodsTest.java @@ -1,10 +1,10 @@ /** - * Licensed to the Apache Software Foundation ( ASF ) under one + * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 ( the - * "License" ); you may not use this file except in compliance + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 diff --git a/exec/jdbc/src/test/java/org/apache/drill/jdbc/StatementTest.java b/exec/jdbc/src/test/java/org/apache/drill/jdbc/StatementTest.java index 3e64fcb38b0..ea6c7160635 100644 --- a/exec/jdbc/src/test/java/org/apache/drill/jdbc/StatementTest.java +++ b/exec/jdbc/src/test/java/org/apache/drill/jdbc/StatementTest.java @@ -1,10 +1,10 @@ /** - * Licensed to the Apache Software Foundation ( ASF ) under one + * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 ( the - * "License" ); you may not use this file except in compliance + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 diff --git a/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2489CallsAfterCloseThrowExceptionsTest.java b/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2489CallsAfterCloseThrowExceptionsTest.java index 1f25effe487..ee94fd2433c 100644 --- a/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2489CallsAfterCloseThrowExceptionsTest.java +++ b/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2489CallsAfterCloseThrowExceptionsTest.java @@ -17,1664 +17,700 @@ */ package org.apache.drill.jdbc.test; -import static org.junit.Assert.assertThat; +import static org.junit.Assert.*; import static org.hamcrest.CoreMatchers.*; +import org.junit.AfterClass; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Test; +import org.slf4j.Logger; -import java.io.InputStream; -import java.io.Reader; -import java.math.BigDecimal; +import static org.slf4j.LoggerFactory.getLogger; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.sql.Array; -import java.sql.Blob; -import java.sql.Clob; +import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DatabaseMetaData; -import java.sql.Date; -import java.sql.NClob; -import java.sql.Ref; +import java.sql.PreparedStatement; import java.sql.ResultSet; -import java.sql.RowId; +import java.sql.ResultSetMetaData; +import java.sql.SQLClientInfoException; import java.sql.SQLException; -import java.sql.SQLXML; -import java.sql.Savepoint; import java.sql.Statement; import java.sql.Struct; -import java.sql.Time; -import java.sql.Timestamp; -import java.util.Map; -import java.util.Properties; -import java.util.concurrent.Executor; +import java.util.ArrayList; +import java.util.List; import org.apache.drill.jdbc.Driver; import org.apache.drill.jdbc.JdbcTestBase; import org.apache.drill.jdbc.AlreadyClosedSqlException; + /** - * Test for JDBC requirement that almost all methods throw {@link SQLException} - * when called on a closed object (Connection, Statement, ResultSet, etc.). + * Test class for JDBC requirement that almost all methods throw + * {@link SQLException} when called on a closed primary object (e.g., + * {@code Connection}, {@code ResultSet}, etc.). *

- * NOTE: This test currently covers only {@link Connection}, - * {@link Statement}, {@link ResultSet} and part of {@link DatabaseMetaData} - * (but not {@link Statement} subclasses, {@link ResultsetMetadata}, or any - * relevant secondary objects such as {@link Array} or {@link Struct}). + * NOTE: This test currently covers: + * {@link Connection}, + * {@link Statement}, + * {@link PreparedStatement}, + * {@link ResultSet}, + * {@link ResultSetMetadata}, and + * {@link DatabaseMetaData}. *

*

- * Additionally, for JDBC interfaces other than ResultSet, only key methods - * currently implement the check, so many test methods are currently disabled - * with @{@link Ignore}. + * It does not cover unimplemented {@link CallableStatement} or any relevant + * secondary objects such as {@link Array} or {@link Struct}). *

*/ public class Drill2489CallsAfterCloseThrowExceptionsTest extends JdbcTestBase { + private static final Logger logger = + getLogger(Drill2489CallsAfterCloseThrowExceptionsTest.class); + + private static Connection closedConn; + private static Connection openConn; + private static Statement closedPlainStmtOfOpenConn; + private static PreparedStatement closedPreparedStmtOfOpenConn; + // No CallableStatement. + private static ResultSet closedResultSetOfClosedStmt; + private static ResultSet closedResultSetOfOpenStmt; + private static ResultSetMetaData resultSetMetaDataOfClosedResultSet; + private static ResultSetMetaData resultSetMetaDataOfClosedStmt; + private static DatabaseMetaData databaseMetaDataOfClosedConn; - private static Connection closedConnection; - private static Statement closedStatement; - private static ResultSet closedResultSet; - private static DatabaseMetaData closedDatabaseMetaData; @BeforeClass - public static void setUpConnection() throws Exception { + public static void setUpClosedObjects() throws Exception { // (Note: Can't use JdbcTest's connect(...) for this test class.) - final Connection connection = - new Driver().connect( "jdbc:drill:zk=local", JdbcAssert.getDefaultProperties() ); - final Statement stmt = connection.createStatement(); - final ResultSet result = - stmt.executeQuery( "SELECT * FROM INFORMATION_SCHEMA.CATALOGS" ); - result.next(); - final DatabaseMetaData dbmd = connection.getMetaData(); - - result.close(); - closedResultSet = result; - stmt.close(); - closedStatement = stmt; - connection.close(); - closedConnection = connection; - closedDatabaseMetaData = dbmd; + + final Connection connToClose = + new Driver().connect("jdbc:drill:zk=local", + JdbcAssert.getDefaultProperties()); + final Connection connToKeep = + new Driver().connect("jdbc:drill:zk=local", + JdbcAssert.getDefaultProperties()); + + final Statement plainStmtToClose = connToKeep.createStatement(); + final Statement plainStmtToKeep = connToKeep.createStatement(); + final PreparedStatement preparedStmtToClose = + connToKeep.prepareStatement("VALUES 'PreparedStatement query'"); + try { + connToKeep.prepareCall("VALUES 'CallableStatement query'"); + fail("Test seems to be out of date. Was prepareCall(...) implemented?"); + } + catch (SQLException | UnsupportedOperationException e) { + // Expected. + } + + final ResultSet resultSetToCloseOnStmtToClose = + plainStmtToClose.executeQuery("VALUES 'plain Statement query'"); + resultSetToCloseOnStmtToClose.next(); + final ResultSet resultSetToCloseOnStmtToKeep = + plainStmtToKeep.executeQuery("VALUES 'plain Statement query'"); + resultSetToCloseOnStmtToKeep.next(); + + final ResultSetMetaData rsmdForClosedStmt = + resultSetToCloseOnStmtToKeep.getMetaData(); + final ResultSetMetaData rsmdForOpenStmt = + resultSetToCloseOnStmtToClose.getMetaData(); + + final DatabaseMetaData dbmd = connToClose.getMetaData(); + + connToClose.close(); + plainStmtToClose.close(); + preparedStmtToClose.close(); + resultSetToCloseOnStmtToClose.close(); + resultSetToCloseOnStmtToKeep.close(); + + closedConn = connToClose; + openConn = connToKeep; + closedPlainStmtOfOpenConn = plainStmtToClose; + closedPreparedStmtOfOpenConn = preparedStmtToClose; + closedResultSetOfClosedStmt = resultSetToCloseOnStmtToClose; + closedResultSetOfOpenStmt = resultSetToCloseOnStmtToKeep; + resultSetMetaDataOfClosedResultSet = rsmdForOpenStmt; + resultSetMetaDataOfClosedStmt = rsmdForClosedStmt; + databaseMetaDataOfClosedConn = dbmd; + + + // Self-check that member variables are set (and objects are in right open + // or closed state): + assertTrue( "Test setup error", closedConn.isClosed()); + assertFalse("Test setup error", openConn.isClosed()); + assertTrue( "Test setup error", closedPlainStmtOfOpenConn.isClosed()); + assertTrue( "Test setup error", closedPreparedStmtOfOpenConn.isClosed()); + assertTrue( "Test setup error", closedResultSetOfClosedStmt.isClosed()); + assertTrue( "Test setup error", closedResultSetOfOpenStmt.isClosed()); + // (No ResultSetMetaData.isClosed() or DatabaseMetaData.isClosed():) + assertNotNull("Test setup error", resultSetMetaDataOfClosedResultSet); + assertNotNull("Test setup error", resultSetMetaDataOfClosedStmt); + assertNotNull("Test setup error", databaseMetaDataOfClosedConn); + } + + @AfterClass + public static void tearDownConnection() throws Exception { + openConn.close(); } - /////////////////////////////////////////////////////////////// - // Connection methods: - //////////////////////////////////////// - // - methods that do _not_ throw exception for closed Connection: + /////////////////////////////////////////////////////////////// + // 1. Check that isClosed() and close() do not throw, and isClosed() returns + // true. @Test public void testClosedConnection_close_doesNotThrow() throws SQLException { - closedConnection.close(); + closedConn.close(); } @Test public void testClosedConnection_isClosed_returnsTrue() throws SQLException { - assertThat( closedConnection.isClosed(), equalTo( true ) ); + assertThat(closedConn.isClosed(), equalTo(true)); } - @Ignore( "until isValid is implemented" ) @Test - public void testClosedConnection_isValid_returnsTrue() throws SQLException { - assertThat( closedConnection.isValid( 1_000 ), equalTo( true ) ); - } - - //////////////////////////////////////// - // - methods that do throw exception for closed Connection: - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_abort_throws() throws SQLException { - closedConnection.abort( (Executor) null ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_clearWarnings_throws() throws SQLException { - closedConnection.clearWarnings(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_commit_throws() throws SQLException { - closedConnection.commit(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_createArrayOf_throws() throws SQLException { - closedConnection.createArrayOf( "typeName" , (Object[]) null ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_createBlob_throws() throws SQLException { - closedConnection.createBlob(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_createClob_throws() throws SQLException { - closedConnection.createClob(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_createNClob_throws() throws SQLException { - closedConnection.createNClob(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_createSQLXML_throws() throws SQLException { - closedConnection.createSQLXML(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_createStatement1_throws() throws SQLException { - closedConnection.createStatement(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_createStatement2_throws() throws SQLException { - closedConnection.createStatement( -1, -2 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_createStatement3_throws() throws SQLException { - closedConnection.createStatement( -1, -2 ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_createStruct_throws() throws SQLException { - closedConnection.createStruct( "typeName", (Object[]) null ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_getAutoCommit_throws() throws SQLException { - closedConnection.getAutoCommit(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_getCatalog_throws() throws SQLException { - closedConnection.getCatalog(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_getClientInfo1_throws() throws SQLException { - closedConnection.getClientInfo(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_getClientInfo2_throws() throws SQLException { - closedConnection.getClientInfo( " name" ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_getHoldability_throws() throws SQLException { - closedConnection.getHoldability(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_getMetaData_throws() throws SQLException { - closedConnection.getMetaData(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_getNetworkTimeout_throws() throws SQLException { - closedConnection.getNetworkTimeout(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_getSchema_throws() throws SQLException { - closedConnection.getSchema(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_getTransactionIsolation_throws() throws SQLException { - closedConnection.getTransactionIsolation(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_getTypeMap_throws() throws SQLException { - closedConnection.getTypeMap(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_getWarnings_throws() throws SQLException { - closedConnection.getWarnings(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_isReadOnly_throws() throws SQLException { - closedConnection.isReadOnly(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_nativeSQL_throws() throws SQLException { - closedConnection.nativeSQL( "sql" ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_prepareCall1_throws() throws SQLException { - closedConnection.prepareCall( "sql" ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_prepareCall2_throws() throws SQLException { - closedConnection.prepareCall( "sql", -1, -2 ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_prepareCall3_throws() throws SQLException { - closedConnection.prepareCall( "sql", -1, -2, -3 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_prepareStatement1_throws() throws SQLException { - closedConnection.prepareStatement( "sql" ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_prepareStatement2_throws() throws SQLException { - closedConnection.prepareStatement( "sql", (String[]) null ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_prepareStatement3_throws() throws SQLException { - closedConnection.prepareStatement( "sql", -4 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_prepareStatement4_throws() throws SQLException { - closedConnection.prepareStatement( "sql", -1, -2 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_prepareStatement5_throws() throws SQLException { - closedConnection.prepareStatement( "sql", -1, -2, -3 ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_prepareStatement6_throws() throws SQLException { - closedConnection.prepareStatement( "sql", (int[]) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_releaseSavepoint_throws() throws SQLException { - closedConnection.releaseSavepoint( (Savepoint) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_rollback1_throws() throws SQLException { - closedConnection.rollback(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_rollback2_throws() throws SQLException { - closedConnection.rollback( (Savepoint) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_setAutoCommit_throws() throws SQLException { - closedConnection.setAutoCommit( true ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_setCatalog_throws() throws SQLException { - closedConnection.setCatalog( "catalog" ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_setClientInfo1_throws() throws SQLException { - closedConnection.setClientInfo( (Properties) null ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_setClientInfo2_throws() throws SQLException { - closedConnection.setClientInfo( "name", "value" ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_setHoldability_throws() throws SQLException { - closedConnection.setHoldability( ResultSet.CLOSE_CURSORS_AT_COMMIT ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_setNetworkTimeout_throws() throws SQLException { - closedConnection.setNetworkTimeout( (Executor) null, 1_000 ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_setReadOnly_throws() throws SQLException { - closedConnection.setReadOnly( true ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_setSavepoint1_throws() throws SQLException { - closedConnection.setSavepoint(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_setSavepoint2_throws() throws SQLException { - closedConnection.setSavepoint( "name" ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_setSchema_throws() throws SQLException { - closedConnection.setSchema( "schema" ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_setTransactionIsolation_throws() throws SQLException { - closedConnection.setTransactionIsolation( -1 ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedConnection_setTypeMap_throws() throws SQLException { - closedConnection.setTypeMap( (Map>) null ); + public void testClosedPlainStatement_close_doesNotThrow() throws SQLException { + closedPlainStmtOfOpenConn.close(); } - - /////////////////////////////////////////////////////////////// - // Statement methods: - - //////////////////////////////////////// - // - methods that do _not_ throw exception for closed Statement: - @Test - public void testClosedStatement_close_doesNotThrow() throws SQLException { - closedStatement.close(); + public void testClosedPlainStatement_isClosed_returnsTrue() throws SQLException { + assertThat(closedPlainStmtOfOpenConn.isClosed(), equalTo(true)); } @Test - public void testClosedStatement_isClosed_returnsTrue() throws SQLException { - assertThat( closedStatement.isClosed(), equalTo( true ) ); - } - - //////////////////////////////////////// - // - methods that do throw exception for closed Statement: - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_addBatch_throws() throws SQLException { - closedStatement.addBatch( "USE dfs_test.tmp" ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_cancel_throws() throws SQLException { - closedStatement.cancel(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_clearBatch_throws() throws SQLException { - closedStatement.clearBatch(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_clearWarnings_throws() throws SQLException { - closedStatement.clearWarnings(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_execute1_throws() throws SQLException { - closedStatement.execute( "USE dfs_test.tmp", Statement.RETURN_GENERATED_KEYS ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_execute2_throws() throws SQLException { - closedStatement.execute( "USE dfs_test.tmp" ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_execute3_throws() throws SQLException { - closedStatement.execute( "USE dfs_test.tmp", (int[]) null ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_execute4_throws() throws SQLException { - closedStatement.execute( "USE dfs_test.tmp", (String[]) null ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_executeBatch_throws() throws SQLException { - closedStatement.executeBatch(); + public void testClosedPreparedStatement_close_doesNotThrow() throws SQLException { + closedPreparedStmtOfOpenConn.close(); } - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_executeQuery_throws() throws SQLException { - closedStatement.executeQuery( "USE dfs_test.tmp" ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_executeUpdate1_throws() throws SQLException { - closedStatement.executeUpdate( "USE dfs_test.tmp", Statement.RETURN_GENERATED_KEYS ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_executeUpdate2_throws() throws SQLException { - closedStatement.executeUpdate( "USE dfs_test.tmp", (int[]) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_executeUpdate3_throws() throws SQLException { - closedStatement.executeUpdate( "USE dfs_test.tmp", (String[]) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_executeUpdate4_throws() throws SQLException { - closedStatement.executeUpdate( "USE dfs_test.tmp" ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_getConnection_throws() throws SQLException { - closedStatement.getConnection(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_getFetchDirection_throws() throws SQLException { - closedStatement.getFetchDirection(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_getFetchSize_throws() throws SQLException { - closedStatement.getFetchSize(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_getGeneratedKeys_throws() throws SQLException { - closedStatement.getGeneratedKeys(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_getMaxFieldSize_throws() throws SQLException { - closedStatement.getMaxFieldSize(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_getMaxRows_throws() throws SQLException { - closedStatement.getMaxRows(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_getMoreResults1_throws() throws SQLException { - closedStatement.getMoreResults(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_getMoreResults2_throws() throws SQLException { - closedStatement.getMoreResults( 1 ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_getQueryTimeout_throws() throws SQLException { - closedStatement.getQueryTimeout(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_getResultSet_throws() throws SQLException { - closedStatement.getResultSet(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_getResultSetConcurrency_throws() throws SQLException { - closedStatement.getResultSetConcurrency(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_getResultSetHoldability_throws() throws SQLException { - closedStatement.getResultSetHoldability(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_getResultSetType_throws() throws SQLException { - closedStatement.getResultSetType(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_getUpdateCount_throws() throws SQLException { - closedStatement.getUpdateCount(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_getWarnings_throws() throws SQLException { - closedStatement.getWarnings(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_isCloseOnCompletion_throws() throws SQLException { - closedStatement.isCloseOnCompletion(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_isPoolable_throws() throws SQLException { - closedStatement.isPoolable(); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_setCursorName_throws() throws SQLException { - closedStatement.setCursorName( "name" ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_setEscapeProcessing_throws() throws SQLException { - closedStatement.setEscapeProcessing( true ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_setFetchDirection_throws() throws SQLException { - closedStatement.setFetchDirection( 123 ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_setFetchSize_throws() throws SQLException { - closedStatement.setFetchSize( 1 ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_setMaxFieldSize_throws() throws SQLException { - closedStatement.setMaxFieldSize( 1 ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_setMaxRows_throws() throws SQLException { - closedStatement.setMaxRows(1 ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_setQueryTimeout_throws() throws SQLException { - closedStatement.setQueryTimeout( 60 ); - } - - @Ignore( "until DRILL-2489 addressed" ) - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedStatement_setPoolable_throws() throws SQLException { - closedStatement.setPoolable( false ); + @Test + public void testClosedPreparedStatement_isClosed_returnsTrue() throws SQLException { + assertThat(closedPreparedStmtOfOpenConn.isClosed(), equalTo(true)); } - - /////////////////////////////////////////////////////////////// - // ResultSet methods: - - //////////////////////////////////////// - // - methods that do _not_ throw exception for closed ResultSet: - @Test public void testClosedResultSet_close_doesNotThrow() throws SQLException { - closedResultSet.close(); + closedResultSetOfOpenStmt.close(); } @Test public void testClosedResultSet_isClosed_returnsTrue() throws SQLException { - assertThat( closedResultSet.isClosed(), equalTo( true ) ); + assertThat(closedResultSetOfOpenStmt.isClosed(), equalTo(true)); } - /////////////////////////////////////////////////////////////// - // PreparedStatement methods: - - //////////////////////////////////////// - // - methods that do _not_ throw exception for closed PreparedStatement: - - //////////////////////////////////////// - // - methods that do throw exception for closed PreparedStatement: - - // TODO - /////////////////////////////////////////////////////////////// - // CallableStatement methods: - - //////////////////////////////////////// - // - methods that do _not_ throw exception for closed CallableStatement: - - //////////////////////////////////////// - // - methods that do throw exception for closed CallableStatement: - - // TODO - - - //////////////////////////////////////// - // - methods that do throw exception for closed ResultSet: - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_absolute_throws() throws SQLException { - closedResultSet.absolute( 1 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_afterLast_throws() throws SQLException { - closedResultSet.afterLast(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_beforeFirst_throws() throws SQLException { - closedResultSet.beforeFirst(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_cancelRowUpdates_throws() throws SQLException { - closedResultSet.cancelRowUpdates(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_clearWarnings_throws() throws SQLException { - closedResultSet.clearWarnings(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_deleteRow_throws() throws SQLException { - closedResultSet.deleteRow(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_findColumn_throws() throws SQLException { - closedResultSet.findColumn( "columnLabel" ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_first_throws() throws SQLException { - closedResultSet.first(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getArray1_throws() throws SQLException { - closedResultSet.getArray( 1 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getArray2_throws() throws SQLException { - closedResultSet.getArray( "columnLabel" ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getAsciiStream1_throws() throws SQLException { - closedResultSet.getAsciiStream( 123 ); - } + // 2. Check that all methods throw or not appropriately (either as specified + // by JDBC or currently intended as partial Avatica workaround). + + + /** + * Reflection-based checker of throwing of "already closed" exception by JDBC + * interfaces' implementation methods. + * + * @param JDBC interface type + */ + private static abstract class ThrowsClosedBulkChecker { + private final Class jdbcIntf; + private final INTF jdbcObject; + protected final String normalClosedExceptionText; + + private String methodLabel; // for inter-method multi-return passing + private Object[] argsArray; // for inter-method multi-return passing + + private final StringBuilder failureLinesBuf = new StringBuilder(); + private final StringBuilder successLinesBuf = new StringBuilder(); + + + ThrowsClosedBulkChecker(final Class jdbcIntf, + final INTF jdbcObject, + final String normalClosedExceptionText) { + this.jdbcIntf = jdbcIntf; + this.jdbcObject = jdbcObject; + this.normalClosedExceptionText = normalClosedExceptionText; + } + + /** + * Gets minimal value suitable for use as actual parameter value for given + * formal parameter type. + */ + private static Object getDummyValueForType(Class type) { + final Object result; + if (! type.isPrimitive()) { + result = null; + } + else { + if (type == boolean.class) { + result = false; + } + else if (type == byte.class) { + result = (byte) 0; + } + else if (type == short.class) { + result = (short) 0; + } + else if (type == char.class) { + result = (char) 0; + } + else if (type == int.class) { + result = 0; + } + else if (type == long.class) { + result = (long) 0L; + } + else if (type == float.class) { + result = 0F; + } + else if (type == double.class) { + result = 0.0; + } + else { + fail("Test needs to be updated to handle type " + type); + result = null; // Not executed; for "final". + } + } + return result; + } + + /** + * Assembles arguments array and method signature text for given method. + * Updates members args and methodLabel. + */ + private void makeArgsAndLabel(Method method) { + final List argsList = new ArrayList<>(); + methodLabel = jdbcIntf.getSimpleName() + "." + method.getName() + "("; + boolean first = true; + for (Class paramType : method.getParameterTypes()) { + if (! first) { + methodLabel += ", "; + } + first = false; + methodLabel += paramType.getSimpleName(); + argsList.add(getDummyValueForType(paramType)); + } + methodLabel += ")"; + argsArray = argsList.toArray(); + } + + /** + * Reports whether it's okay if given method didn't throw any exception. + */ + protected boolean isOkayNonthrowingMethod(Method method) { + return + "isClosed".equals(method.getName()) + || "close".equals(method.getName()); + } + + /** + * Reports whether it's okay if given method throw given exception (that is + * not preferred AlreadyClosedException with regular message). + */ + protected boolean isOkaySpecialCaseException(Method method, + Throwable cause) { + return false; + } + + /** + * Tests one method. + * (Disturbs members set by makeArgsAndLabel, but those shouldn't be used + * except by this method.) + */ + private void testOneMethod(Method method) { + makeArgsAndLabel(method); + logger.debug("Testing method " + methodLabel); + + try { + // See if method throws exception: + method.invoke(jdbcObject, argsArray); + + // If here, method didn't throw--check if it's an expected non-throwing + // method (e.g., an isClosed). (If not, report error.) + final String resultLine = "- " + methodLabel + " didn't throw\n"; + + if (isOkayNonthrowingMethod(method)) { + successLinesBuf.append(resultLine); + } + else { + logger.trace("Failure: " + resultLine); + failureLinesBuf.append(resultLine); + } + } + catch (InvocationTargetException e) { + final Throwable cause = e.getCause(); + final String resultLine = "- " + methodLabel + " threw <" + cause + ">\n"; + + if (AlreadyClosedSqlException.class == cause.getClass() + && normalClosedExceptionText.equals(cause.getMessage())) { + // Common good case--our preferred exception class with our message. + successLinesBuf.append(resultLine); + } + else if (NullPointerException.class == cause.getClass() + && (method.getName().equals("isWrapperFor") + || method.getName().equals("unwrap"))) { + // Known good-enough case--these methods don't throw already-closed + // exception, but do throw NullPointerException because of the way + // we call them (with null) and the way Avatica code implements them. + successLinesBuf.append(resultLine); + } + else { + // Not a case that base-class code here recognizes, but subclass may + // know that it's okay. + if (isOkaySpecialCaseException(method, cause)) { + successLinesBuf.append(resultLine); + } + else { + final String badResultLine = + "- " + methodLabel + " threw <" + cause + "> instead" + + " of " + AlreadyClosedSqlException.class.getSimpleName() + + " with \"" + + normalClosedExceptionText.replaceAll("\"", "\"\"") + + "\"" + "\n"; + logger.trace("Failure: " + resultLine); + failureLinesBuf.append(badResultLine); + } + } + } + catch (IllegalAccessException | IllegalArgumentException e) { + fail("Unexpected exception: " + e + ", cause = " + e.getCause() + + " from " + method); + } + } + + public void testAllMethods() { + for (Method method : jdbcIntf.getMethods()) { + testOneMethod(method); + } + } + + public boolean hadAnyFailures() { + return 0 != failureLinesBuf.length(); + } + + public String getFailureLines() { + return failureLinesBuf.toString(); + } + + public String getSuccessLines() { + return successLinesBuf.toString(); + } + + public String getReport() { + final String report = + "Failures:\n" + + getFailureLines() + + "(Successes:\n" + + getSuccessLines() + + ")"; + return report; + } + + } // class ThrowsClosedChecker + + + private static class ClosedConnectionChecker + extends ThrowsClosedBulkChecker { + + private static final String STATEMENT_CLOSED_MESSAGE = + "Connection is already closed."; + + + ClosedConnectionChecker(Class intf, Connection jdbcObject) { + super(intf, jdbcObject, STATEMENT_CLOSED_MESSAGE); + } + + @Override + protected boolean isOkaySpecialCaseException(Method method, Throwable cause) { + final boolean result; + if (super.isOkaySpecialCaseException(method, cause)) { + result = true; + } + else if (SQLClientInfoException.class == cause.getClass() + && normalClosedExceptionText.equals(cause.getMessage()) + && (false + || method.getName().equals("setClientInfo") + || method.getName().equals("getClientInfo") + )) { + // Special good case--we had to use SQLClientInfoException from those. + result = true; + } + else if (RuntimeException.class == cause.getClass() + && normalClosedExceptionText.equals(cause.getMessage()) + && (false + || method.getName().equals("getCatalog") + || method.getName().equals("getSchema") + )) { + // Special good-enough case--we had to use RuntimeException for now. + result = true; + } + else { + result = false; + } + return result; + } + + } // class ClosedConnectionChecker - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getAsciiStream2_throws() throws SQLException { - closedResultSet.getAsciiStream( "columnLabel" ); - } + @Test + public void testClosedConnectionMethodsThrowRight() { + ThrowsClosedBulkChecker checker = + new ClosedConnectionChecker(Connection.class, closedConn); + + checker.testAllMethods(); + + if (checker.hadAnyFailures()) { + System.err.println(checker.getReport()); + fail("Already-closed exception error(s): \n" + checker.getReport()); + } + } + + + private static class ClosedPlainStatementChecker + extends ThrowsClosedBulkChecker { + + private static final String PLAIN_STATEMENT_CLOSED_MESSAGE = + "Statement is already closed."; + + ClosedPlainStatementChecker(Class intf, Statement jdbcObject) { + super(intf, jdbcObject, PLAIN_STATEMENT_CLOSED_MESSAGE); + } + + @Override + protected boolean isOkaySpecialCaseException(Method method, Throwable cause) { + final boolean result; + if (super.isOkaySpecialCaseException(method, cause)) { + result = true; + } + else if (RuntimeException.class == cause.getClass() + && normalClosedExceptionText.equals(cause.getMessage()) + && (false + || method.getName().equals("getConnection") + || method.getName().equals("getFetchDirection") + || method.getName().equals("getFetchSize") + || method.getName().equals("getMaxRows") + )) { + // Special good-enough case--we had to use RuntimeException for now. + result = true; + } + else { + result = false; + } + return result; + } + + } // class ClosedPlainStatementChecker - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getBigDecimal1_throws() throws SQLException { - closedResultSet.getBigDecimal( 123 ); - } + @Test + public void testClosedPlainStatementMethodsThrowRight() { + ThrowsClosedBulkChecker checker = + new ClosedPlainStatementChecker(Statement.class, closedPlainStmtOfOpenConn); + + checker.testAllMethods(); + + if (checker.hadAnyFailures()) { + fail("Already-closed exception error(s): \n" + checker.getReport()); + } + } + + + private static class ClosedPreparedStatementChecker + extends ThrowsClosedBulkChecker { + + private static final String PREPAREDSTATEMENT_CLOSED_MESSAGE = + "PreparedStatement is already closed."; + + ClosedPreparedStatementChecker(Class intf, + PreparedStatement jdbcObject) { + super(intf, jdbcObject, PREPAREDSTATEMENT_CLOSED_MESSAGE); + } + + @Override + protected boolean isOkaySpecialCaseException(Method method, Throwable cause) { + final boolean result; + if (super.isOkaySpecialCaseException(method, cause)) { + result = true; + } + else if (RuntimeException.class == cause.getClass() + && normalClosedExceptionText.equals(cause.getMessage()) + && (false + || method.getName().equals("getConnection") + || method.getName().equals("getFetchDirection") + || method.getName().equals("getFetchSize") + || method.getName().equals("getMaxRows") + || method.getName().equals("getMetaData") + )) { + // Special good-enough case--we had to use RuntimeException for now. + result = true; + } + else { + result = false; + } + return result; + } + + } // class closedPreparedStmtOfOpenConnChecker - @Test( expected = AlreadyClosedSqlException.class ) - @SuppressWarnings( "deprecation" ) - public void testClosedResultSet_getBigDecimal2_throws() throws SQLException { - closedResultSet.getBigDecimal( 123, 2 ); - } + @Test + public void testclosedPreparedStmtOfOpenConnMethodsThrowRight() { + ThrowsClosedBulkChecker checker = + new ClosedPreparedStatementChecker(PreparedStatement.class, + closedPreparedStmtOfOpenConn); - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getBigDecimal3_throws() throws SQLException { - closedResultSet.getBigDecimal( "columnLabel" ); - } + checker.testAllMethods(); - @Test( expected = AlreadyClosedSqlException.class ) - @SuppressWarnings( "deprecation" ) - public void testClosedResultSet_getBigDecimal_throws() throws SQLException { - closedResultSet.getBigDecimal( "columnLabel", 2 ); + if (checker.hadAnyFailures()) { + fail("Already-closed exception error(s): \n" + checker.getReport()); + } } - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getBinaryStream1_throws() throws SQLException { - closedResultSet.getBinaryStream( 123 ); - } - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getBinaryStream2_throws() throws SQLException { - closedResultSet.getBinaryStream( "columnLabel" ); - } + private static class ClosedResultSetChecker + extends ThrowsClosedBulkChecker { - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getBlob1_throws() throws SQLException { - closedResultSet.getBlob( 123 ); - } + private static final String RESULTSET_CLOSED_MESSAGE = + "ResultSet is already closed."; - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getBlob2_throws() throws SQLException { - closedResultSet.getBlob( "columnLabel" ); - } + ClosedResultSetChecker(Class intf, ResultSet jdbcObject) { + super(intf, jdbcObject, RESULTSET_CLOSED_MESSAGE); + } - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getBoolean1_throws() throws SQLException { - closedResultSet.getBoolean( 123 ); - } + @Override + protected boolean isOkaySpecialCaseException(Method method, Throwable cause) { + final boolean result; + if (super.isOkaySpecialCaseException(method, cause)) { + result = true; + } + else if (RuntimeException.class == cause.getClass() + && normalClosedExceptionText.equals(cause.getMessage()) + && method.getName().equals("getStatement")) { + // Special good-enough case--we had to use RuntimeException for now. + result = true; + } + else { + result = false; + } + return result; + } - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getBoolean2_throws() throws SQLException { - closedResultSet.getBoolean( "columnLabel" ); - } + } // class ClosedResultSetChecker - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getByte1_throws() throws SQLException { - closedResultSet.getByte( 123 ); - } + @Test + public void testClosedResultSetMethodsThrowRight1() { + ThrowsClosedBulkChecker checker = + new ClosedResultSetChecker(ResultSet.class, closedResultSetOfClosedStmt); - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getByte2_throws() throws SQLException { - closedResultSet.getByte( "columnLabel" ); - } + checker.testAllMethods(); - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getBytes1_throws() throws SQLException { - closedResultSet.getBytes( 123 ); + if (checker.hadAnyFailures()) { + fail("Already-closed exception error(s): \n" + checker.getReport()); + } } - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getBytes2_throws() throws SQLException { - closedResultSet.getBytes( "columnLabel" ); - } + @Test + public void testClosedResultSetMethodsThrowRight2() { + ThrowsClosedBulkChecker checker = + new ClosedResultSetChecker(ResultSet.class, closedResultSetOfOpenStmt); - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getCharacterStream1_throws() throws SQLException { - closedResultSet.getCharacterStream( 123 ); - } + checker.testAllMethods(); - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getCharacterStream2_throws() throws SQLException { - closedResultSet.getCharacterStream( "columnLabel" ); + if (checker.hadAnyFailures()) { + fail("Already-closed exception error(s): \n" + checker.getReport()); + } } - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getClob1_throws() throws SQLException { - closedResultSet.getClob( 123 ); - } - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getClob2_throws() throws SQLException { - closedResultSet.getClob( "columnLabel" ); - } + private static class ClosedResultSetMetaDataChecker + extends ThrowsClosedBulkChecker { - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getConcurrency_throws() throws SQLException { - closedResultSet.getConcurrency(); - } + private static final String RESULTSETMETADATA_CLOSED_MESSAGE = + "ResultSetMetaData's ResultSet is already closed."; - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getCursorName_throws() throws SQLException { - closedResultSet.getCursorName(); - } + ClosedResultSetMetaDataChecker(Class intf, + ResultSetMetaData jdbcObject) { + super(intf, jdbcObject, RESULTSETMETADATA_CLOSED_MESSAGE); + } - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getDate1_throws() throws SQLException { - closedResultSet.getDate( 123 ); - } + } // class ClosedResultSetMetaDataChecker - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getDate2_throws() throws SQLException { - closedResultSet.getDate( 123, null ); - } + @Test + public void testClosedResultSetMetaDataMethodsThrowRight1() { + ThrowsClosedBulkChecker checker = + new ClosedResultSetMetaDataChecker(ResultSetMetaData.class, + resultSetMetaDataOfClosedResultSet); - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getDate3_throws() throws SQLException { - closedResultSet.getDate( "columnLabel" ); - } + checker.testAllMethods(); - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getDate4_throws() throws SQLException { - closedResultSet.getDate( "columnLabel", null ); + if (checker.hadAnyFailures()) { + fail("Already-closed exception error(s): \n" + checker.getReport()); + } } - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getDouble1_throws() throws SQLException { - closedResultSet.getDouble( 123 ); - } + @Test + public void testClosedResultSetMetaDataMethodsThrowRight2() { + ThrowsClosedBulkChecker checker = + new ClosedResultSetMetaDataChecker(ResultSetMetaData.class, + resultSetMetaDataOfClosedStmt); + + checker.testAllMethods(); + + if (checker.hadAnyFailures()) { + fail("Already-closed exception error(s): \n" + checker.getReport()); + } + } + + + private static class ClosedDatabaseMetaDataChecker + extends ThrowsClosedBulkChecker { + + private static final String DATABASEMETADATA_CLOSED_MESSAGE = + "DatabaseMetaData's Connection is already closed."; + + ClosedDatabaseMetaDataChecker(Class intf, + DatabaseMetaData jdbcObject) { + super(intf, jdbcObject, DATABASEMETADATA_CLOSED_MESSAGE); + } + + protected boolean isOkayNonthrowingMethod(Method method) { + return + super.isOkayNonthrowingMethod(method) + || method.getName().equals("getDriverMajorVersion") + || method.getName().equals("getDriverMinorVersion") + || method.getName().equals("getConnection"); + } + + @Override + protected boolean isOkaySpecialCaseException(Method method, Throwable cause) { + final boolean result; + if (super.isOkaySpecialCaseException(method, cause)) { + result = true; + } + else if (RuntimeException.class == cause.getClass() + && normalClosedExceptionText.equals(cause.getMessage()) + && method.getName().equals("getResultSetHoldability")) { + // Special good-enough case--we had to use RuntimeException for now. + result = true; + } + else { + result = false; + } + return result; + } + + } // class ClosedDatabaseMetaDataChecker - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getDouble2_throws() throws SQLException { - closedResultSet.getDouble( "columnLabel" ); - } - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getFetchDirection_throws() throws SQLException { - closedResultSet.getFetchDirection(); - } + @Test + public void testClosedDatabaseMetaDataMethodsThrowRight() { + ThrowsClosedBulkChecker checker = + new ClosedDatabaseMetaDataChecker(DatabaseMetaData.class, + databaseMetaDataOfClosedConn); - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getFetchSize_throws() throws SQLException { - closedResultSet.getFetchSize(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getFloat1_throws() throws SQLException { - closedResultSet.getFloat( 123 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getFloat2_throws() throws SQLException { - closedResultSet.getFloat( "columnLabel" ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getHoldability_throws() throws SQLException { - closedResultSet.getHoldability(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getInt1_throws() throws SQLException { - closedResultSet.getInt( 123 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getInt2_throws() throws SQLException { - closedResultSet.getInt( "columnLabel" ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getLong1_throws() throws SQLException { - closedResultSet.getLong( 123 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getLong2_throws() throws SQLException { - closedResultSet.getLong( "columnLabel" ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getMetaData_throws() throws SQLException { - closedResultSet.getMetaData(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getNCharacterStream1_throws() throws SQLException { - closedResultSet.getNCharacterStream( 123 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getNCharacterStream2_throws() throws SQLException { - closedResultSet.getNCharacterStream( "columnLabel" ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getNClob1_throws() throws SQLException { - closedResultSet.getNClob( 123 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getNClob2_throws() throws SQLException { - closedResultSet.getNClob( "columnLabel" ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getNString1_throws() throws SQLException { - closedResultSet.getNString( 123 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getNString2_throws() throws SQLException { - closedResultSet.getNString( "columnLabel" ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getObject1_throws() throws SQLException { - closedResultSet.getObject( 123 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getObject2_throws() throws SQLException { - closedResultSet.getObject( 123, String.class ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getObject3_throws() throws SQLException { - closedResultSet.getObject( 123, (Map>) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getObject4_throws() throws SQLException { - closedResultSet.getObject( "columnLabel" ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getObject5_throws() throws SQLException { - closedResultSet.getObject( "columnLabel", String.class ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getObject6_throws() throws SQLException { - closedResultSet.getObject( "columnLabel", (Map>) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getRef1_throws() throws SQLException { - closedResultSet.getRef( 123 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getRef2_throws() throws SQLException { - closedResultSet.getRef( "columnLabel" ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getRow_throws() throws SQLException { - closedResultSet.getRow(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getRowId1_throws() throws SQLException { - closedResultSet.getRowId( 123 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getRowId2_throws() throws SQLException { - closedResultSet.getRowId( "columnLabel" ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getShort1_throws() throws SQLException { - closedResultSet.getShort( 123 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getShort2_throws() throws SQLException { - closedResultSet.getShort( "columnLabel" ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getSQLXML1_throws() throws SQLException { - closedResultSet.getSQLXML( 123 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getSQLXML2_throws() throws SQLException { - closedResultSet.getSQLXML( "columnLabel" ); - } - - @Test - public void testClosedResultSet_getStatement_doesNotThrow() throws SQLException { - closedResultSet.getStatement(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getString1_throws() throws SQLException { - closedResultSet.getString( 123 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getString2_throws() throws SQLException { - closedResultSet.getString( "columnLabel" ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getTime1_throws() throws SQLException { - closedResultSet.getTime( 123 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getTime2_throws() throws SQLException { - closedResultSet.getTime( 123, null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getTime3_throws() throws SQLException { - closedResultSet.getTime( "columnLabel" ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getTime4_throws() throws SQLException { - closedResultSet.getTime( "columnLabel", null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getTimestamp1_throws() throws SQLException { - closedResultSet.getTimestamp( 123 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getTimestamp2_throws() throws SQLException { - closedResultSet.getTimestamp( 123, null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getTimestamp3_throws() throws SQLException { - closedResultSet.getTimestamp( "columnLabel" ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getTimestamp4_throws() throws SQLException { - closedResultSet.getTimestamp( "columnLabel", null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getType_throws() throws SQLException { - closedResultSet.getType(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - @SuppressWarnings( "deprecation" ) - public void testClosedResultSet_getUnicodeStream1_throws() throws SQLException { - closedResultSet.getUnicodeStream( 123 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - @SuppressWarnings( "deprecation" ) - public void testClosedResultSet_getUnicodeStream2_throws() throws SQLException { - closedResultSet.getUnicodeStream( "columnLabel" ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getURL1_throws() throws SQLException { - closedResultSet.getURL( 123 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getURL2_throws() throws SQLException { - closedResultSet.getURL( "columnLabel" ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_getWarnings_throws() throws SQLException { - closedResultSet.getWarnings(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_insertRow_throws() throws SQLException { - closedResultSet.insertRow(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_isAfterLast_throws() throws SQLException { - closedResultSet.isAfterLast(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_isBeforeFirst_throws() throws SQLException { - closedResultSet.isBeforeFirst(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_isFirst_throws() throws SQLException { - closedResultSet.isFirst(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_isLast_throws() throws SQLException { - closedResultSet.isLast(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_last_throws() throws SQLException { - closedResultSet.last(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_moveToCurrentRow_throws() throws SQLException { - closedResultSet.moveToCurrentRow(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_moveToInsertRow_throws() throws SQLException { - closedResultSet.moveToInsertRow(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_next_throws() throws SQLException { - closedResultSet.next(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_previous_throws() throws SQLException { - closedResultSet.previous(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_refreshRow_throws() throws SQLException { - closedResultSet.refreshRow(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_relative_throws() throws SQLException { - closedResultSet.relative( 2 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_rowDeleted_throws() throws SQLException { - closedResultSet.rowDeleted(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_rowInserted_throws() throws SQLException { - closedResultSet.rowInserted(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_rowUpdated_throws() throws SQLException { - closedResultSet.rowUpdated(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_setFetchDirection_throws() throws SQLException { - closedResultSet.setFetchDirection( -123 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_setFetchSize_throws() throws SQLException { - closedResultSet.setFetchSize( 1 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateArray1_throws() throws SQLException { - closedResultSet.updateArray( 123, (Array) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateArray_throws() throws SQLException { - closedResultSet.updateArray( "columnLabel2", (Array) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateAsciiStream1_throws() throws SQLException { - closedResultSet.updateAsciiStream( 123, (InputStream) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateAsciiStream2_throws() throws SQLException { - closedResultSet.updateAsciiStream( 123, (InputStream) null, 12 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateAsciiStream3_throws() throws SQLException { - closedResultSet.updateAsciiStream( 123, (InputStream) null, 12 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateAsciiStream4_throws() throws SQLException { - closedResultSet.updateAsciiStream( "columnLabel", (InputStream) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateAsciiStream5_throws() throws SQLException { - closedResultSet.updateAsciiStream( "columnLabel", (InputStream) null, 12 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateAsciiStream6_throws() throws SQLException { - closedResultSet.updateAsciiStream( "columnLabel", (InputStream) null, 12 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateBigDecimal1_throws() throws SQLException { - closedResultSet.updateBigDecimal( 123, (BigDecimal) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateBigDecimal2_throws() throws SQLException { - closedResultSet.updateBigDecimal( "columnLabel", (BigDecimal) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateBinaryStream3_throws() throws SQLException { - closedResultSet.updateBinaryStream( 123, (InputStream) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateBinaryStream4_throws() throws SQLException { - closedResultSet.updateBinaryStream( 123, (InputStream) null, 12 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateBinaryStream5_throws() throws SQLException { - closedResultSet.updateBinaryStream( 123, (InputStream) null, 12 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateBinaryStream6_throws() throws SQLException { - closedResultSet.updateBinaryStream( "columnLabel", (InputStream) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateBinaryStream7_throws() throws SQLException { - closedResultSet.updateBinaryStream( "columnLabel", (InputStream) null, 12 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateBinaryStream8_throws() throws SQLException { - closedResultSet.updateBinaryStream( "columnLabel", (InputStream) null, 12 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateBlob1_throws() throws SQLException { - closedResultSet.updateBlob( 123, (Blob) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateBlob2_throws() throws SQLException { - closedResultSet.updateBlob( 123, (InputStream) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateBlob3_throws() throws SQLException { - closedResultSet.updateBlob( 123, (InputStream) null, 12 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateBlob4_throws() throws SQLException { - closedResultSet.updateBlob( "columnLabel", (Blob) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateBlob5_throws() throws SQLException { - closedResultSet.updateBlob( "columnLabel", (InputStream) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateBlob6_throws() throws SQLException { - closedResultSet.updateBlob( "columnLabel", (InputStream) null, 12 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateBoolean1_throws() throws SQLException { - closedResultSet.updateBoolean( 123, true ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateBoolean2_throws() throws SQLException { - closedResultSet.updateBoolean( "columnLabel", true ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateByte1_throws() throws SQLException { - closedResultSet.updateByte( 123, (byte) 0 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateByte2_throws() throws SQLException { - closedResultSet.updateByte( "columnLabel", (byte) 0 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateBytes1_throws() throws SQLException { - closedResultSet.updateBytes( 123, (byte[]) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateBytes2_throws() throws SQLException { - closedResultSet.updateBytes( "columnLabel", (byte[]) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateCharacterStream1_throws() throws SQLException { - closedResultSet.updateCharacterStream( 123, (Reader) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateCharacterStream2_throws() throws SQLException { - closedResultSet.updateCharacterStream( 123, (Reader) null, 12 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateCharacterStream3_throws() throws SQLException { - closedResultSet.updateCharacterStream( 123, (Reader) null, 12 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateCharacterStream4_throws() throws SQLException { - closedResultSet.updateCharacterStream( "columnLabel", (Reader) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateCharacterStream5_throws() throws SQLException { - closedResultSet.updateCharacterStream( "columnLabel", (Reader) null, 12 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateCharacterStream6_throws() throws SQLException { - closedResultSet.updateCharacterStream( "columnLabel", (Reader) null, 12 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateClob1_throws() throws SQLException { - closedResultSet.updateClob( 123, (Clob) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateClob2_throws() throws SQLException { - closedResultSet.updateClob( 123, (Reader) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateClob3_throws() throws SQLException { - closedResultSet.updateClob( 123, (Reader) null, 12 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateClob4_throws() throws SQLException { - closedResultSet.updateClob( "columnLabel", (Clob) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateClob5_throws() throws SQLException { - closedResultSet.updateClob( "columnLabel", (Reader) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateClob6_throws() throws SQLException { - closedResultSet.updateClob( "columnLabel", (Reader) null, 12 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateDate1() throws SQLException { - closedResultSet.updateDate( 123, (Date) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateDate2_throws() throws SQLException { - closedResultSet.updateDate( "columnLabel", (Date) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateDouble1_throws() throws SQLException { - closedResultSet.updateDouble( 123, (double) 123 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateDouble2_throws() throws SQLException { - closedResultSet.updateDouble( "columnLabel", 456 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateFloat1_throws() throws SQLException { - closedResultSet.updateFloat( 123, 1f ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateFloat2_throws() throws SQLException { - closedResultSet.updateFloat( "columnLabel", 345 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateInt1_throws() throws SQLException { - closedResultSet.updateInt( 123, 1 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateInt2_throws() throws SQLException { - closedResultSet.updateInt( "columnLabel", 234 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateLong1_throws() throws SQLException { - closedResultSet.updateLong( 123, 234 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateLong2_throws() throws SQLException { - closedResultSet.updateLong( "columnLabel", 234 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateNCharacterStream1_throws() throws SQLException { - closedResultSet.updateNCharacterStream( 123, (Reader) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateNCharacterStream2_throws() throws SQLException { - closedResultSet.updateNCharacterStream( 123, (Reader) null, 12 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateNCharacterStream3_throws() throws SQLException { - closedResultSet.updateNCharacterStream( "columnLabel", (Reader) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateNCharacterStream4_throws() throws SQLException { - closedResultSet.updateNCharacterStream( "columnLabel", (Reader) null, 12 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateNClob1_throws() throws SQLException { - closedResultSet.updateNClob( 123, (NClob) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateNClob2_throws() throws SQLException { - closedResultSet.updateNClob( 123, (Reader) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateNClob3_throws() throws SQLException { - closedResultSet.updateNClob( 123, (Reader) null, 12 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateNClob4_throws() throws SQLException { - closedResultSet.updateNClob( "columnLabel", (NClob) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateNClob5_throws() throws SQLException { - closedResultSet.updateNClob( "columnLabel", (Reader) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateNClob6_throws() throws SQLException { - closedResultSet.updateNClob( "columnLabel", (Reader) null, 12 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateNString1_throws() throws SQLException { - closedResultSet.updateNString( 123, (String) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateNString2_throws() throws SQLException { - closedResultSet.updateNString( "columnLabel", (String) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateNull1_throws() throws SQLException { - closedResultSet.updateNull( 123 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateNull2_throws() throws SQLException { - closedResultSet.updateNull( "columnLabel" ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateObject1_throws() throws SQLException { - closedResultSet.updateObject( 123, (Object) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateObject2_throws() throws SQLException { - closedResultSet.updateObject( 123, (Object) null, 7 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateObject3_throws() throws SQLException { - closedResultSet.updateObject( "columnLabel", (Object) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateObject4_throws() throws SQLException { - closedResultSet.updateObject( "columnLabel", (Object) null, 17 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateRef1_throws() throws SQLException { - closedResultSet.updateRef( 123, (Ref) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateRef2_throws() throws SQLException { - closedResultSet.updateRef( "columnLabel", (Ref) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateRow_throws() throws SQLException { - closedResultSet.updateRow(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateRowId1_throws() throws SQLException { - closedResultSet.updateRowId( 123, (RowId) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateRowId2_throws() throws SQLException { - closedResultSet.updateRowId( "columnLabel", (RowId) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateShort1_throws() throws SQLException { - closedResultSet.updateShort( 123, (short) 127 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateShort2_throws() throws SQLException { - closedResultSet.updateShort( "columnLabel", (short) 127 ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateSQLXML1_throws() throws SQLException { - closedResultSet.updateSQLXML( 123, (SQLXML) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateSQLXML2_throws() throws SQLException { - closedResultSet.updateSQLXML( "columnLabel", (SQLXML) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateString1_throws() throws SQLException { - closedResultSet.updateString( 123, (String) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateString2_throws() throws SQLException { - closedResultSet.updateString( "columnLabel", (String) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateTime1_throws() throws SQLException { - closedResultSet.updateTime( 123, (Time) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateTime2_throws() throws SQLException { - closedResultSet.updateTime( "columnLabel", (Time) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateTimestamp1_throws() throws SQLException { - closedResultSet.updateTimestamp( 123, (Timestamp) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_updateTimestamp2_throws() throws SQLException { - closedResultSet.updateTimestamp( "columnLabel", (Timestamp) null ); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedResultSet_wasNull_throws() throws SQLException { - closedResultSet.wasNull(); - } - - - /////////////////////////////////////////////////////////////// - // ResultSetMetadata methods: - - //////////////////////////////////////// - // - methods that do _not_ throw exception for closed ResultSetMetadata: - - // TODO - - //////////////////////////////////////// - // - methods that do throw exception for closed ResultSetMetadata: - - // None? - - - /////////////////////////////////////////////////////////////// - // DatabaseMetaData methods: - - //////////////////////////////////////// - // - methods that do _not_ throw exception for closed DatabaseMetaData: - - //////////////////////////////////////// - // - methods that do throw exception for closed DatabaseMetaData: - - // TODO - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedDatabaseMetaData_getCatalog_throws() throws SQLException { - closedDatabaseMetaData.getCatalogs(); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedDatabaseMetaData_getSchemas_throws() throws SQLException { - closedDatabaseMetaData.getSchemas( null, null); - } - - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedDatabaseMetaData_getTables_throws() throws SQLException { - closedDatabaseMetaData.getTables( null, null, null, null ); - } + checker.testAllMethods(); - @Test( expected = AlreadyClosedSqlException.class ) - public void testClosedDatabaseMetaData_getColumns_throws() throws SQLException { - closedDatabaseMetaData.getColumns( null, null, null, null ); + if (checker.hadAnyFailures()) { + fail("Already-closed exception error(s): \n" + checker.getReport()); + } } }