DRILL-2489: Throw exception from remaining methods for closed JDBC objects.
Refactored unit test to check all methods per interface. (Replaced individual, static test methods with bulk reflection-based checking.) [Drill2489CallsAfterCloseThrowExceptionsTest] Added DrillResultSetMetaDataImpl. Added method overrides to check state for remaining methods from Connection, Statement, PreparedStatement, ResultSet, ResultSetMetaData and DatabaseMetaData. Also: - renamed checkNotClosed to throwIfClosed. Project: http://git-wip-us.apache.org/repos/asf/drill/repo Commit: http://git-wip-us.apache.org/repos/asf/drill/commit/daf816cb Tree: http://git-wip-us.apache.org/repos/asf/drill/tree/daf816cb Diff: http://git-wip-us.apache.org/repos/asf/drill/diff/daf816cb Branch: refs/heads/master Commit: daf816cbce11e7384b78216eda96783097c37520 Parents: e78e286 Author: dbarclay <[email protected]> Authored: Wed Aug 19 16:55:40 2015 -0700 Committer: Hanifi Gunes <[email protected]> Committed: Mon Nov 9 12:17:02 2015 -0800 ---------------------------------------------------------------------- .../org/apache/drill/jdbc/DrillConnection.java | 1 - .../drill/jdbc/impl/DrillConnectionImpl.java | 339 ++- .../jdbc/impl/DrillDatabaseMetaDataImpl.java | 1090 ++++++++- .../drill/jdbc/impl/DrillJdbc41Factory.java | 42 +- .../jdbc/impl/DrillPreparedStatementImpl.java | 410 ++++ .../drill/jdbc/impl/DrillResultSetImpl.java | 538 +++-- .../jdbc/impl/DrillResultSetMetaDataImpl.java | 198 ++ .../drill/jdbc/impl/DrillStatementImpl.java | 252 +- .../org/apache/drill/jdbc/ConnectionTest.java | 6 +- .../jdbc/ConnectionTransactionMethodsTest.java | 6 +- .../org/apache/drill/jdbc/StatementTest.java | 6 +- ...l2489CallsAfterCloseThrowExceptionsTest.java | 2162 +++++------------- 12 files changed, 3169 insertions(+), 1881 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/drill/blob/daf816cb/exec/jdbc/src/main/java/org/apache/drill/jdbc/DrillConnection.java ---------------------------------------------------------------------- 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 698b433..16ea520 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; http://git-wip-us.apache.org/repos/asf/drill/blob/daf816cb/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillConnectionImpl.java ---------------------------------------------------------------------- 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 f8e5d8e..1ff2693 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 @@ import org.slf4j.Logger; // 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 @@ class DrillConnectionImpl extends AvaticaConnection /** * Throws AlreadyClosedSqlException <i>iff</i> 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 @@ class DrillConnectionImpl extends AvaticaConnection @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 @@ class DrillConnectionImpl extends AvaticaConnection @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 @@ class DrillConnectionImpl extends AvaticaConnection @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 @@ class DrillConnectionImpl extends AvaticaConnection @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 @@ class DrillConnectionImpl extends AvaticaConnection @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 @@ class DrillConnectionImpl extends AvaticaConnection 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 @@ class DrillConnectionImpl extends AvaticaConnection } } - @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 @@ class DrillConnectionImpl extends AvaticaConnection 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 @@ class DrillConnectionImpl extends AvaticaConnection 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<T>) (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<String,Class<?>> getTypeMap() throws SQLException { + throwIfClosed(); + return super.getTypeMap(); + } + + @Override + public void setTypeMap(Map<String,Class<?>> 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; http://git-wip-us.apache.org/repos/asf/drill/blob/daf816cb/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillDatabaseMetaDataImpl.java ---------------------------------------------------------------------- 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 6a1d625..0855b01 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 @@ package org.apache.drill.jdbc.impl; 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 @@ class DrillDatabaseMetaDataImpl extends AvaticaDatabaseMetaData * @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 @@ class DrillDatabaseMetaDataImpl extends AvaticaDatabaseMetaData } + // 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<T>) (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(); + } + + } http://git-wip-us.apache.org/repos/asf/drill/blob/daf816cb/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillJdbc41Factory.java ---------------------------------------------------------------------- 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 9723358..4a8d3bc 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 java.util.TimeZone; 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 class DrillJdbc41Factory extends DrillFactory { @Override public ResultSetMetaData newResultSetMetaData(AvaticaStatement statement, List<ColumnMetaData> columnMetaDataList) { - return new AvaticaResultSetMetaData(statement, null, columnMetaDataList); + return new DrillResultSetMetaDataImpl(statement, null, columnMetaDataList); } @@ -127,6 +125,8 @@ public class DrillJdbc41Factory extends DrillFactory { 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 class DrillJdbc41Factory extends DrillFactory { } @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 class DrillJdbc41Factory extends DrillFactory { } @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 class DrillJdbc41Factory extends DrillFactory { } @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 class DrillJdbc41Factory extends DrillFactory { } @Override - public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException { + public void setBlob(int parameterIndex, + InputStream inputStream) throws SQLException { getParameter(parameterIndex).setBlob(inputStream); } http://git-wip-us.apache.org/repos/asf/drill/blob/daf816cb/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillPreparedStatementImpl.java ---------------------------------------------------------------------- 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 871298f..f84e14e 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 @@ abstract class DrillPreparedStatementImpl extends AvaticaPreparedStatement connection.openStatementsRegistry.addStatement(this); } + /** + * Throws AlreadyClosedSqlException <i>iff</i> 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 @@ abstract class DrillPreparedStatementImpl extends AvaticaPreparedStatement 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<T>) (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) + }
