drill-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From h.@apache.org
Subject [5/8] drill git commit: DRILL-2489: Throw exception from remaining methods for closed JDBC objects.
Date Tue, 10 Nov 2015 21:49:40 GMT
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 <dbarclay@maprtech.com>
Authored: Wed Aug 19 16:55:40 2015 -0700
Committer: Hanifi Gunes <hanifigunes@gmail.com>
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)
+
 }


Mime
View raw message