You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@drill.apache.org by hg...@apache.org on 2015/06/24 23:36:38 UTC

[3/4] drill git commit: DRILL-2447: Add already-closed checks to remaining ResultSet methods.

DRILL-2447: Add already-closed checks to remaining ResultSet methods.

Extended coverage from just selected methods to all methods.  Added wrapper
methods checking state before delegating.  (Couldn't implement at just a few
choke points because Avatica makes them private and doesn't provide hooks.)
[DrillResultSetImpl]

Defined DrillResultSet.getQueryId() to throw SQLException as other methods do.
[DrillResultSet]

Re-enabled ResultSet test methods.  (Also re-enabled other test methods that
pass now with DRILL-2782 changes.  [Drill2489CallsAfterCloseThrowExceptionsTest]


Project: http://git-wip-us.apache.org/repos/asf/drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/drill/commit/4dc476d5
Tree: http://git-wip-us.apache.org/repos/asf/drill/tree/4dc476d5
Diff: http://git-wip-us.apache.org/repos/asf/drill/diff/4dc476d5

Branch: refs/heads/master
Commit: 4dc476d540bc4d091105f4b017732b70e59d26e3
Parents: 064af80
Author: dbarclay <db...@maprtech.com>
Authored: Fri Apr 24 16:48:55 2015 -0700
Committer: Hanifi Gunes <hg...@maprtech.com>
Committed: Wed Jun 24 14:40:45 2015 -0700

----------------------------------------------------------------------
 .../org/apache/drill/jdbc/DrillResultSet.java   |   22 +-
 .../drill/jdbc/impl/DrillResultSetImpl.java     | 1257 +++++++++++++++++-
 ...l2489CallsAfterCloseThrowExceptionsTest.java |  239 +---
 3 files changed, 1244 insertions(+), 274 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/drill/blob/4dc476d5/exec/jdbc/src/main/java/org/apache/drill/jdbc/DrillResultSet.java
----------------------------------------------------------------------
diff --git a/exec/jdbc/src/main/java/org/apache/drill/jdbc/DrillResultSet.java b/exec/jdbc/src/main/java/org/apache/drill/jdbc/DrillResultSet.java
index e0a7763..858fd61 100644
--- a/exec/jdbc/src/main/java/org/apache/drill/jdbc/DrillResultSet.java
+++ b/exec/jdbc/src/main/java/org/apache/drill/jdbc/DrillResultSet.java
@@ -17,27 +17,9 @@
  */
 package org.apache.drill.jdbc;
 
-import java.io.InputStream;
-import java.io.Reader;
 import java.math.BigDecimal;
-import java.net.URL;
-import java.sql.Array;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.Date;
-import java.sql.NClob;
-import java.sql.Ref;
 import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.RowId;
 import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.sql.SQLXML;
-import java.sql.Statement;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.util.Calendar;
-import java.util.Map;
 
 
 /**
@@ -49,8 +31,10 @@ public interface DrillResultSet extends ResultSet  {
   /**
    * Gets the ID of the associated query (the query whose results this ResultSet
    * presents).
+   *
+   * @throws  SQLException  if this method is called on a closed result set
    */
-  String getQueryId();
+  String getQueryId() throws SQLException;
 
   /**
    * {@inheritDoc}

http://git-wip-us.apache.org/repos/asf/drill/blob/4dc476d5/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillResultSetImpl.java
----------------------------------------------------------------------
diff --git a/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillResultSetImpl.java b/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillResultSetImpl.java
index 31593bf..1b37dc1 100644
--- a/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillResultSetImpl.java
+++ b/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillResultSetImpl.java
@@ -17,18 +17,31 @@
  */
 package org.apache.drill.jdbc.impl;
 
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.NClob;
+import java.sql.Ref;
 import java.sql.ResultSetMetaData;
+import java.sql.RowId;
 import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
 import java.util.TimeZone;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.LinkedBlockingDeque;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
 
 import net.hydromatic.avatica.AvaticaPrepareResult;
 import net.hydromatic.avatica.AvaticaResultSet;
-import net.hydromatic.avatica.AvaticaStatement;
 
 import org.apache.drill.common.exceptions.UserException;
 import org.apache.drill.exec.ExecConstants;
@@ -72,6 +85,7 @@ class DrillResultSetImpl extends AvaticaResultSet implements DrillResultSet {
   final DrillCursor cursor;
   boolean hasPendingCancelationNotification;
 
+
   DrillResultSetImpl(DrillStatementImpl statement, AvaticaPrepareResult prepareResult,
                      ResultSetMetaData resultSetMetaData, TimeZone timeZone) {
     super(statement, prepareResult, resultSetMetaData, timeZone);
@@ -87,10 +101,6 @@ class DrillResultSetImpl extends AvaticaResultSet implements DrillResultSet {
     cursor = new DrillCursor(this);
   }
 
-  public DrillStatementImpl getStatement() {
-    return statement;
-  }
-
   /**
    * Throws AlreadyClosedSqlException or QueryCanceledSqlException if this
    * ResultSet is closed.
@@ -115,13 +125,6 @@ class DrillResultSetImpl extends AvaticaResultSet implements DrillResultSet {
   }
 
   @Override
-  public ResultSetMetaData getMetaData() throws SQLException {
-    checkNotClosed();
-    return super.getMetaData();
-  }
-
-
-  @Override
   protected void cancel() {
     hasPendingCancelationNotification = true;
     cleanup();
@@ -136,6 +139,10 @@ class DrillResultSetImpl extends AvaticaResultSet implements DrillResultSet {
     batchLoader.clear();
   }
 
+  ////////////////////////////////////////
+  // ResultSet-defined methods (in same order as in ResultSet):
+
+  // (Not delegated.)
   @Override
   public boolean next() throws SQLException {
     checkNotClosed();
@@ -157,46 +164,1210 @@ class DrillResultSetImpl extends AvaticaResultSet implements DrillResultSet {
   }
 
   @Override
-  protected DrillResultSetImpl execute() throws SQLException{
-    DrillConnectionImpl connection = (DrillConnectionImpl) statement.getConnection();
+  public void close() {
+    // Note:  No already-closed exception for close().
+    super.close();
+  }
 
-    connection.getClient().runQuery(QueryType.SQL, this.prepareResult.getSql(),
-                                    resultsListener);
-    connection.getDriver().handler.onStatementExecute(statement, null);
+  @Override
+  public boolean wasNull() throws SQLException {
+    checkNotClosed();
+    return super.wasNull();
+  }
 
-    super.execute();
+  // Methods for accessing results by column index
+  @Override
+  public String getString( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getString( columnIndex );
+  }
 
-    // don't return with metadata until we've achieved at least one return message.
-    try {
-      // TODO:  Revisit:  Why reaching directly into ResultsListener rather than
-      // calling some wait method?
-      resultsListener.latch.await();
-    } catch ( InterruptedException e ) {
-      // Preserve evidence that the interruption occurred so that code higher up
-      // on the call stack can learn of the interruption and respond to it if it
-      // wants to.
-      Thread.currentThread().interrupt();
+  @Override
+  public boolean getBoolean( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getBoolean( columnIndex );
+  }
 
-      // Not normally expected--Drill doesn't interrupt in this area (right?)--
-      // but JDBC client certainly could.
-      throw new SQLException( "Interrupted", e );
-    }
+  @Override
+  public byte getByte( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getByte( columnIndex );
+  }
 
-    // Read first (schema-only) batch to initialize result-set metadata from
-    // (initial) schema before Statement.execute...(...) returns result set:
-    cursor.loadInitialSchema();
+  @Override
+  public short getShort( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getShort( columnIndex );
+  }
 
-    return this;
+  @Override
+  public int getInt( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getInt( columnIndex );
   }
 
-  public String getQueryId() {
-    if (resultsListener.getQueryId() != null) {
-      return QueryIdHelper.getQueryId(resultsListener.getQueryId());
-    } else {
-      return null;
-    }
+  @Override
+  public long getLong( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getLong( columnIndex );
+  }
+
+  @Override
+  public float getFloat( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getFloat( columnIndex );
+  }
+
+  @Override
+  public double getDouble( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getDouble( columnIndex );
+  }
+
+  @Override
+  public BigDecimal getBigDecimal( int columnIndex, int scale ) throws SQLException {
+    checkNotClosed();
+    return super.getBigDecimal( columnIndex, scale );
+  }
+
+  @Override
+  public byte[] getBytes( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getBytes( columnIndex );
+  }
+
+  @Override
+  public Date getDate( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getDate( columnIndex );
+  }
+
+  @Override
+  public Time getTime( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getTime( columnIndex );
+  }
+
+  @Override
+  public Timestamp getTimestamp( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getTimestamp( columnIndex );
+  }
+
+  @Override
+  public InputStream getAsciiStream( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getAsciiStream( columnIndex );
+  }
+
+  @Override
+  public InputStream getUnicodeStream( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getUnicodeStream( columnIndex );
+  }
+
+  @Override
+  public InputStream getBinaryStream( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getBinaryStream( columnIndex );
+  }
+
+  // Methods for accessing results by column label
+  @Override
+  public String getString( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getString( columnLabel );
+  }
+
+  @Override
+  public boolean getBoolean( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getBoolean( columnLabel );
+  }
+
+  @Override
+  public byte getByte( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getByte( columnLabel );
+  }
+
+  @Override
+  public short getShort( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getShort( columnLabel );
+  }
+
+  @Override
+  public int getInt( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getInt( columnLabel );
+  }
+
+  @Override
+  public long getLong( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getLong( columnLabel );
+  }
+
+  @Override
+  public float getFloat( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getFloat( columnLabel );
+  }
+
+  @Override
+  public double getDouble( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getDouble( columnLabel );
+  }
+
+  @Override
+  public BigDecimal getBigDecimal( String columnLabel, int scale ) throws SQLException {
+    checkNotClosed();
+    return super.getBigDecimal( columnLabel, scale );
+  }
+
+  @Override
+  public byte[] getBytes( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getBytes( columnLabel );
+  }
+
+  @Override
+  public Date getDate( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getDate( columnLabel );
+  }
+
+  @Override
+  public Time getTime( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getTime( columnLabel );
+  }
+
+  @Override
+  public Timestamp getTimestamp( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getTimestamp( columnLabel );
+  }
+
+  @Override
+  public InputStream getAsciiStream( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getAsciiStream( columnLabel );
+  }
+
+  @Override
+  public InputStream getUnicodeStream( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getUnicodeStream( columnLabel );
+  }
+
+  @Override
+  public InputStream getBinaryStream( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getBinaryStream( columnLabel );
+  }
+
+  // Advanced features:
+  @Override
+  public SQLWarning getWarnings() throws SQLException {
+    checkNotClosed();
+    return super.getWarnings();
+  }
+
+  @Override
+  public void clearWarnings() throws SQLException {
+    checkNotClosed();
+      super.clearWarnings();
+  }
+
+  @Override
+  public String getCursorName() throws SQLException {
+    checkNotClosed();
+    return super.getCursorName();
+  }
+
+  // (Not delegated.)
+  @Override
+  public ResultSetMetaData getMetaData() throws SQLException {
+    checkNotClosed();
+    return super.getMetaData();
+  }
+
+  @Override
+  public Object getObject( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getObject( columnIndex );
+  }
+
+  @Override
+  public Object getObject( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getObject( columnLabel );
+  }
+
+  //----------------------------------------------------------------
+  @Override
+  public int findColumn( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.findColumn( columnLabel );
+  }
+
+  //--------------------------JDBC 2.0-----------------------------------
+  //---------------------------------------------------------------------
+  // Getters and Setters
+  //---------------------------------------------------------------------
+  @Override
+  public Reader getCharacterStream( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getCharacterStream( columnIndex );
+  }
+
+  @Override
+  public Reader getCharacterStream( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getCharacterStream( columnLabel );
+  }
+
+  @Override
+  public BigDecimal getBigDecimal( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getBigDecimal( columnIndex );
+  }
+
+  @Override
+  public BigDecimal getBigDecimal( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getBigDecimal( columnLabel );
+  }
+
+  //---------------------------------------------------------------------
+  // Traversal/Positioning
+  //---------------------------------------------------------------------
+  @Override
+  public boolean isBeforeFirst() throws SQLException {
+    checkNotClosed();
+    return super.isBeforeFirst();
+  }
+
+  @Override
+  public boolean isAfterLast() throws SQLException {
+    checkNotClosed();
+    return super.isAfterLast();
+  }
+
+  @Override
+  public boolean isFirst() throws SQLException {
+    checkNotClosed();
+    return super.isFirst();
+  }
+
+  @Override
+  public boolean isLast() throws SQLException {
+    checkNotClosed();
+    return super.isLast();
+  }
+
+  @Override
+  public void beforeFirst() throws SQLException {
+    checkNotClosed();
+    super.beforeFirst();
+  }
+
+  @Override
+  public void afterLast() throws SQLException {
+    checkNotClosed();
+    super.afterLast();
+  }
+
+  @Override
+  public boolean first() throws SQLException {
+    checkNotClosed();
+    return super.first();
+  }
+
+  @Override
+  public boolean last() throws SQLException {
+    checkNotClosed();
+    return super.last();
+  }
+
+  @Override
+  public int getRow() throws SQLException {
+    checkNotClosed();
+    return super.getRow();
+  }
+
+  @Override
+  public boolean absolute( int row ) throws SQLException {
+    checkNotClosed();
+    return super.absolute( row );
+  }
+
+  @Override
+  public boolean relative( int rows ) throws SQLException {
+    checkNotClosed();
+    return super.relative( rows );
   }
 
+  @Override
+  public boolean previous() throws SQLException {
+    checkNotClosed();
+    return super.previous();
+  }
+
+  //---------------------------------------------------------------------
+  // Properties
+  //---------------------------------------------------------------------
+
+  @Override
+  public void setFetchDirection( int direction ) throws SQLException {
+    checkNotClosed();
+    super.setFetchDirection( direction );
+  }
+
+  @Override
+  public int getFetchDirection() throws SQLException {
+    checkNotClosed();
+    return super.getFetchDirection();
+  }
+
+  @Override
+  public void setFetchSize( int rows ) throws SQLException {
+    checkNotClosed();
+    super.setFetchSize( rows );
+  }
+
+  @Override
+  public int getFetchSize() throws SQLException {
+    checkNotClosed();
+    return super.getFetchSize();
+  }
+
+  @Override
+  public int getType() throws SQLException {
+    checkNotClosed();
+    return super.getType();
+  }
+
+  @Override
+  public int getConcurrency() throws SQLException {
+    checkNotClosed();
+    return super.getConcurrency();
+  }
+
+  //---------------------------------------------------------------------
+  // Updates
+  //---------------------------------------------------------------------
+  @Override
+  public boolean rowUpdated() throws SQLException {
+    checkNotClosed();
+    return super.rowUpdated();
+  }
+
+  @Override
+  public boolean rowInserted() throws SQLException {
+    checkNotClosed();
+    return super.rowInserted();
+  }
+
+  @Override
+  public boolean rowDeleted() throws SQLException {
+    checkNotClosed();
+    return super.rowDeleted();
+  }
+
+  @Override
+  public void updateNull( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    super.updateNull( columnIndex );
+  }
+
+  @Override
+  public void updateBoolean( int columnIndex, boolean x ) throws SQLException {
+    checkNotClosed();
+    super.updateBoolean( columnIndex, x );
+  }
+
+  @Override
+  public void updateByte( int columnIndex, byte x ) throws SQLException {
+    checkNotClosed();
+    super.updateByte( columnIndex, x );
+  }
+
+  @Override
+  public void updateShort( int columnIndex, short x ) throws SQLException {
+    checkNotClosed();
+    super.updateShort( columnIndex, x );
+  }
+
+  @Override
+  public void updateInt( int columnIndex, int x ) throws SQLException {
+    checkNotClosed();
+    super.updateInt( columnIndex, x );
+  }
+
+  @Override
+  public void updateLong( int columnIndex, long x ) throws SQLException {
+    checkNotClosed();
+    super.updateLong( columnIndex, x );
+  }
+
+  @Override
+  public void updateFloat( int columnIndex, float x ) throws SQLException {
+    checkNotClosed();
+    super.updateFloat( columnIndex, x );
+  }
+
+  @Override
+  public void updateDouble( int columnIndex, double x ) throws SQLException {
+    checkNotClosed();
+    super.updateDouble( columnIndex, x );
+  }
+
+  @Override
+  public void updateBigDecimal( int columnIndex, BigDecimal x ) throws SQLException {
+    checkNotClosed();
+    super.updateBigDecimal( columnIndex, x );
+  }
+
+  @Override
+  public void updateString( int columnIndex, String x ) throws SQLException {
+    checkNotClosed();
+    super.updateString( columnIndex, x );
+  }
+
+  @Override
+  public void updateBytes( int columnIndex, byte[] x ) throws SQLException {
+    checkNotClosed();
+    super.updateBytes( columnIndex, x );
+  }
+
+  @Override
+  public void updateDate( int columnIndex, Date x ) throws SQLException {
+    checkNotClosed();
+    super.updateDate( columnIndex, x );
+  }
+
+  @Override
+  public void updateTime( int columnIndex, Time x ) throws SQLException {
+    checkNotClosed();
+    super.updateTime( columnIndex, x );
+  }
+
+  @Override
+  public void updateTimestamp( int columnIndex, Timestamp x ) throws SQLException {
+    checkNotClosed();
+    super.updateTimestamp( columnIndex, x );
+  }
+
+  @Override
+  public void updateAsciiStream( int columnIndex, InputStream x, int length ) throws SQLException {
+    checkNotClosed();
+    super.updateAsciiStream( columnIndex, x, length );
+  }
+
+  @Override
+  public void updateBinaryStream( int columnIndex, InputStream x, int length ) throws SQLException {
+    checkNotClosed();
+    super.updateBinaryStream( columnIndex, x, length );
+  }
+
+  @Override
+  public void updateCharacterStream( int columnIndex, Reader x, int length ) throws SQLException {
+    checkNotClosed();
+    super.updateCharacterStream( columnIndex, x, length );
+  }
+
+  @Override
+  public void updateObject( int columnIndex, Object x, int scaleOrLength ) throws SQLException {
+    checkNotClosed();
+    super.updateObject( columnIndex, x, scaleOrLength );
+  }
+
+  @Override
+  public void updateObject( int columnIndex, Object x ) throws SQLException {
+    checkNotClosed();
+    super.updateObject( columnIndex, x );
+  }
+
+  @Override
+  public void updateNull( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    super.updateNull( columnLabel );
+  }
+
+  @Override
+  public void updateBoolean( String columnLabel, boolean x ) throws SQLException {
+    checkNotClosed();
+    super.updateBoolean( columnLabel, x );
+  }
+
+  @Override
+  public void updateByte( String columnLabel, byte x ) throws SQLException {
+    checkNotClosed();
+    super.updateByte( columnLabel, x );
+  }
+
+  @Override
+  public void updateShort( String columnLabel, short x ) throws SQLException {
+    checkNotClosed();
+    super.updateShort( columnLabel, x );
+  }
+
+  @Override
+  public void updateInt( String columnLabel, int x ) throws SQLException {
+    checkNotClosed();
+    super.updateInt( columnLabel, x );
+  }
+
+  @Override
+  public void updateLong( String columnLabel, long x ) throws SQLException {
+    checkNotClosed();
+    super.updateLong( columnLabel, x );
+  }
+
+  @Override
+  public void updateFloat( String columnLabel, float x ) throws SQLException {
+    checkNotClosed();
+    super.updateFloat( columnLabel, x );
+  }
+
+  @Override
+  public void updateDouble( String columnLabel, double x ) throws SQLException {
+    checkNotClosed();
+    super.updateDouble( columnLabel, x );
+  }
+
+  @Override
+  public void updateBigDecimal( String columnLabel, BigDecimal x ) throws SQLException {
+    checkNotClosed();
+    super.updateBigDecimal( columnLabel, x );
+  }
+
+  @Override
+  public void updateString( String columnLabel, String x ) throws SQLException {
+    checkNotClosed();
+    super.updateString( columnLabel, x );
+  }
+
+  @Override
+  public void updateBytes( String columnLabel, byte[] x ) throws SQLException {
+    checkNotClosed();
+    super.updateBytes( columnLabel, x );
+  }
+
+  @Override
+  public void updateDate( String columnLabel, Date x ) throws SQLException {
+    checkNotClosed();
+    super.updateDate( columnLabel, x );
+  }
+
+  @Override
+  public void updateTime( String columnLabel, Time x ) throws SQLException {
+    checkNotClosed();
+    super.updateTime( columnLabel, x );
+  }
+
+  @Override
+  public void updateTimestamp( String columnLabel, Timestamp x ) throws SQLException {
+    checkNotClosed();
+    super.updateTimestamp( columnLabel, x );
+  }
+
+  @Override
+  public void updateAsciiStream( String columnLabel, InputStream x, int length ) throws SQLException {
+    checkNotClosed();
+    super.updateAsciiStream( columnLabel, x, length );
+  }
+
+  @Override
+  public void updateBinaryStream( String columnLabel, InputStream x, int length ) throws SQLException {
+    checkNotClosed();
+    super.updateBinaryStream( columnLabel, x, length );
+  }
+
+  @Override
+  public void updateCharacterStream( String columnLabel, Reader reader, int length ) throws SQLException {
+    checkNotClosed();
+    super.updateCharacterStream( columnLabel, reader, length );
+  }
+
+  @Override
+  public void updateObject( String columnLabel, Object x, int scaleOrLength ) throws SQLException {
+    checkNotClosed();
+    super.updateObject( columnLabel, x, scaleOrLength );
+  }
+
+  @Override
+  public void updateObject( String columnLabel, Object x ) throws SQLException {
+    checkNotClosed();
+    super.updateObject( columnLabel, x );
+  }
+
+  @Override
+  public void insertRow() throws SQLException {
+    checkNotClosed();
+    super.insertRow();
+  }
+
+  @Override
+  public void updateRow() throws SQLException {
+    checkNotClosed();
+    super.updateRow();
+  }
+
+  @Override
+  public void deleteRow() throws SQLException {
+    checkNotClosed();
+    super.deleteRow();
+  }
+
+  @Override
+  public void refreshRow() throws SQLException {
+    checkNotClosed();
+    super.refreshRow();
+  }
+
+  @Override
+  public void cancelRowUpdates() throws SQLException {
+    checkNotClosed();
+    super.cancelRowUpdates();
+  }
+
+  @Override
+  public void moveToInsertRow() throws SQLException {
+    checkNotClosed();
+    super.moveToInsertRow();
+  }
+
+  @Override
+  public void moveToCurrentRow() throws SQLException {
+    checkNotClosed();
+    super.moveToCurrentRow();
+  }
+
+  @Override
+  public DrillStatementImpl getStatement() {
+    // Note:  No already-closed exception for close().
+    return statement;
+  }
+
+  @Override
+  public Object getObject( int columnIndex, java.util.Map<String,Class<?>> map ) throws SQLException {
+    checkNotClosed();
+    return super.getObject( columnIndex, map );
+  }
+
+  @Override
+  public Ref getRef( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getRef( columnIndex );
+  }
+
+  @Override
+  public Blob getBlob( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getBlob( columnIndex );
+  }
+
+  @Override
+  public Clob getClob( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getClob( columnIndex );
+  }
+
+  @Override
+  public Array getArray( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getArray( columnIndex );
+  }
+
+  @Override
+  public Object getObject( String columnLabel, java.util.Map<String,Class<?>> map ) throws SQLException {
+    checkNotClosed();
+    return super.getObject( columnLabel, map );
+  }
+
+  @Override
+  public Ref getRef( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getRef( columnLabel );
+  }
+
+  @Override
+  public Blob getBlob( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getBlob( columnLabel );
+  }
+
+  @Override
+  public Clob getClob( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getClob( columnLabel );
+  }
+
+  @Override
+  public Array getArray( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getArray( columnLabel );
+  }
+
+  @Override
+  public Date getDate( int columnIndex, Calendar cal ) throws SQLException {
+    checkNotClosed();
+    return super.getDate( columnIndex, cal );
+  }
+
+  @Override
+  public Date getDate( String columnLabel, Calendar cal ) throws SQLException {
+    checkNotClosed();
+    return super.getDate( columnLabel, cal );
+  }
+
+  @Override
+  public Time getTime( int columnIndex, Calendar cal ) throws SQLException {
+    checkNotClosed();
+    return super.getTime( columnIndex, cal );
+  }
+
+  @Override
+  public Time getTime( String columnLabel, Calendar cal ) throws SQLException {
+    checkNotClosed();
+    return super.getTime( columnLabel, cal );
+  }
+
+  @Override
+  public Timestamp getTimestamp( int columnIndex, Calendar cal ) throws SQLException {
+    checkNotClosed();
+    return super.getTimestamp( columnIndex, cal );
+  }
+
+  @Override
+  public Timestamp getTimestamp( String columnLabel, Calendar cal ) throws SQLException {
+    checkNotClosed();
+    return super.getTimestamp( columnLabel, cal );
+  }
+
+  //-------------------------- JDBC 3.0 ----------------------------------------
+
+  @Override
+  public java.net.URL getURL( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getURL( columnIndex );
+  }
+
+  @Override
+  public java.net.URL getURL( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getURL( columnLabel );
+  }
+
+  @Override
+  public void updateRef( int columnIndex, Ref x ) throws SQLException {
+    checkNotClosed();
+    super.updateRef( columnIndex, x );
+  }
+
+  @Override
+  public void updateRef( String columnLabel, Ref x ) throws SQLException {
+    checkNotClosed();
+    super.updateRef( columnLabel, x );
+  }
+
+  @Override
+  public void updateBlob( int columnIndex, Blob x ) throws SQLException {
+    checkNotClosed();
+    super.updateBlob( columnIndex, x );
+  }
+
+  @Override
+  public void updateBlob( String columnLabel, Blob x ) throws SQLException {
+    checkNotClosed();
+    super.updateBlob( columnLabel, x );
+  }
+
+  @Override
+  public void updateClob( int columnIndex, Clob x ) throws SQLException {
+    checkNotClosed();
+    super.updateClob( columnIndex, x );
+  }
+
+  @Override
+  public void updateClob( String columnLabel, Clob x ) throws SQLException {
+    checkNotClosed();
+    super.updateClob( columnLabel, x );
+  }
+
+  @Override
+  public void updateArray( int columnIndex, Array x ) throws SQLException {
+    checkNotClosed();
+    super.updateArray( columnIndex, x );
+  }
+
+  @Override
+  public void updateArray( String columnLabel, Array x ) throws SQLException {
+    checkNotClosed();
+    super.updateArray( columnLabel, x );
+  }
+
+  //------------------------- JDBC 4.0 -----------------------------------
+  @Override
+  public RowId getRowId( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getRowId( columnIndex );
+  }
+
+  @Override
+  public RowId getRowId( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getRowId( columnLabel );
+  }
+
+  @Override
+  public void updateRowId( int columnIndex, RowId x ) throws SQLException {
+    checkNotClosed();
+    super.updateRowId( columnIndex, x );
+  }
+
+  @Override
+  public void updateRowId( String columnLabel, RowId x ) throws SQLException {
+    checkNotClosed();
+    super.updateRowId( columnLabel, x );
+  }
+
+  @Override
+  public int getHoldability() throws SQLException {
+    checkNotClosed();
+    return super.getHoldability();
+  }
+
+  @Override
+  public boolean isClosed() throws SQLException {
+    // Note:  No already-closed exception for isClosed().
+    return super.isClosed();
+  }
+
+  @Override
+  public void updateNString( int columnIndex, String nString ) throws SQLException {
+    checkNotClosed();
+    super.updateNString( columnIndex, nString );
+  }
+
+  @Override
+  public void updateNString( String columnLabel, String nString ) throws SQLException {
+    checkNotClosed();
+    super.updateNString( columnLabel, nString );
+  }
+
+  @Override
+  public void updateNClob( int columnIndex, NClob nClob ) throws SQLException {
+    checkNotClosed();
+    super.updateNClob( columnIndex, nClob );
+  }
+
+  @Override
+  public void updateNClob( String columnLabel, NClob nClob ) throws SQLException {
+    checkNotClosed();
+    super.updateNClob( columnLabel, nClob );
+  }
+
+  @Override
+  public NClob getNClob( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getNClob( columnIndex );
+  }
+
+  @Override
+  public NClob getNClob( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getNClob( columnLabel );
+  }
+
+  @Override
+  public SQLXML getSQLXML( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getSQLXML( columnIndex );
+  }
+
+  @Override
+  public SQLXML getSQLXML( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getSQLXML( columnLabel );
+  }
+
+  @Override
+  public void updateSQLXML( int columnIndex, SQLXML xmlObject ) throws SQLException {
+    checkNotClosed();
+    super.updateSQLXML( columnIndex, xmlObject );
+  }
+
+  @Override
+  public void updateSQLXML( String columnLabel, SQLXML xmlObject ) throws SQLException {
+    checkNotClosed();
+    super.updateSQLXML( columnLabel, xmlObject );
+  }
+
+  @Override
+  public String getNString( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getNString( columnIndex );
+  }
+
+  @Override
+  public String getNString( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getNString( columnLabel );
+  }
+
+  @Override
+  public Reader getNCharacterStream( int columnIndex ) throws SQLException {
+    checkNotClosed();
+    return super.getNCharacterStream( columnIndex );
+  }
+
+  @Override
+  public Reader getNCharacterStream( String columnLabel ) throws SQLException {
+    checkNotClosed();
+    return super.getNCharacterStream( columnLabel );
+  }
+
+  @Override
+  public void updateNCharacterStream( int columnIndex, Reader x, long length ) throws SQLException {
+    checkNotClosed();
+    super.updateNCharacterStream( columnIndex, x, length );
+  }
+
+  @Override
+  public void updateNCharacterStream( String columnLabel, Reader reader, long length ) throws SQLException {
+    checkNotClosed();
+    super.updateNCharacterStream( columnLabel, reader, length );
+  }
+
+  @Override
+  public void updateAsciiStream( int columnIndex, InputStream x, long length ) throws SQLException {
+    checkNotClosed();
+    super.updateAsciiStream( columnIndex, x, length );
+  }
+
+  @Override
+  public void updateBinaryStream( int columnIndex, InputStream x, long length ) throws SQLException {
+    checkNotClosed();
+    super.updateBinaryStream( columnIndex, x, length );
+  }
+
+  @Override
+  public void updateCharacterStream( int columnIndex, Reader x, long length ) throws SQLException {
+    checkNotClosed();
+    super.updateCharacterStream( columnIndex, x, length );
+  }
+
+  @Override
+  public void updateAsciiStream( String columnLabel, InputStream x, long length ) throws SQLException {
+    checkNotClosed();
+    super.updateAsciiStream( columnLabel, x, length );
+  }
+
+  @Override
+  public void updateBinaryStream( String columnLabel, InputStream x, long length ) throws SQLException {
+    checkNotClosed();
+    super.updateBinaryStream( columnLabel, x, length );
+  }
+
+  @Override
+  public void updateCharacterStream( String columnLabel, Reader reader, long length ) throws SQLException {
+    checkNotClosed();
+    super.updateCharacterStream( columnLabel, reader, length );
+  }
+
+  @Override
+  public void updateBlob( int columnIndex, InputStream inputStream, long length ) throws SQLException {
+    checkNotClosed();
+    super.updateBlob( columnIndex, inputStream, length );
+  }
+
+  @Override
+  public void updateBlob( String columnLabel, InputStream inputStream, long length ) throws SQLException {
+    checkNotClosed();
+    super.updateBlob( columnLabel, inputStream, length );
+  }
+
+  @Override
+  public void updateClob( int columnIndex,  Reader reader, long length ) throws SQLException {
+    checkNotClosed();
+    super.updateClob( columnIndex, reader, length );
+  }
+
+  @Override
+  public void updateClob( String columnLabel,  Reader reader, long length ) throws SQLException {
+    checkNotClosed();
+    super.updateClob( columnLabel, reader, length );
+  }
+
+  @Override
+  public void updateNClob( int columnIndex,  Reader reader, long length ) throws SQLException {
+    checkNotClosed();
+    super.updateNClob( columnIndex, reader, length );
+  }
+
+  @Override
+  public void updateNClob( String columnLabel,  Reader reader, long length ) throws SQLException {
+    checkNotClosed();
+    super.updateNClob( columnLabel, reader, length );
+  }
+
+  //---
+  @Override
+  public void updateNCharacterStream( int columnIndex, Reader x ) throws SQLException {
+    checkNotClosed();
+    super.updateNCharacterStream( columnIndex, x );
+  }
+
+  @Override
+  public void updateNCharacterStream( String columnLabel, Reader reader ) throws SQLException {
+    checkNotClosed();
+    super.updateNCharacterStream( columnLabel, reader );
+  }
+
+  @Override
+  public void updateAsciiStream( int columnIndex, InputStream x ) throws SQLException {
+    checkNotClosed();
+    super.updateAsciiStream( columnIndex, x );
+  }
+
+  @Override
+  public void updateBinaryStream( int columnIndex, InputStream x ) throws SQLException {
+    checkNotClosed();
+    super.updateBinaryStream( columnIndex, x );
+  }
+
+  @Override
+  public void updateCharacterStream( int columnIndex, Reader x ) throws SQLException {
+    checkNotClosed();
+    super.updateCharacterStream( columnIndex, x );
+  }
+
+  @Override
+  public void updateAsciiStream( String columnLabel, InputStream x ) throws SQLException {
+    checkNotClosed();
+    super.updateAsciiStream( columnLabel, x );
+  }
+
+  @Override
+  public void updateBinaryStream( String columnLabel, InputStream x ) throws SQLException {
+    checkNotClosed();
+    super.updateBinaryStream( columnLabel, x );
+  }
+
+  @Override
+  public void updateCharacterStream( String columnLabel, Reader reader ) throws SQLException {
+    checkNotClosed();
+    super.updateCharacterStream( columnLabel, reader );
+  }
+
+  @Override
+  public void updateBlob( int columnIndex, InputStream inputStream ) throws SQLException {
+    checkNotClosed();
+    super.updateBlob( columnIndex, inputStream );
+  }
+
+  @Override
+  public void updateBlob( String columnLabel, InputStream inputStream ) throws SQLException {
+    checkNotClosed();
+    super.updateBlob( columnLabel, inputStream );
+  }
+
+  @Override
+  public void updateClob( int columnIndex,  Reader reader ) throws SQLException {
+    checkNotClosed();
+    super.updateClob( columnIndex, reader );
+  }
+
+  @Override
+  public void updateClob( String columnLabel,  Reader reader ) throws SQLException {
+    checkNotClosed();
+    super.updateClob( columnLabel, reader );
+  }
+
+  @Override
+  public void updateNClob( int columnIndex,  Reader reader ) throws SQLException {
+    checkNotClosed();
+    super.updateNClob( columnIndex, reader );
+  }
+
+  @Override
+  public void updateNClob( String columnLabel,  Reader reader ) throws SQLException {
+    checkNotClosed();
+    super.updateNClob( columnLabel, reader );
+  }
+
+  //------------------------- JDBC 4.1 -----------------------------------
+  @Override
+  public <T> T getObject( int columnIndex, Class<T> type ) throws SQLException {
+    checkNotClosed();
+    return super.getObject( columnIndex, type );
+  }
+
+  @Override
+  public <T> T getObject( String columnLabel, Class<T> type ) throws SQLException {
+    checkNotClosed();
+    return super.getObject( columnLabel, type );
+  }
+
+
+  ////////////////////////////////////////
+  // DrillResultSet methods:
+
+  public String getQueryId() throws SQLException {
+    checkNotClosed();
+    if (resultsListener.getQueryId() != null) {
+      return QueryIdHelper.getQueryId(resultsListener.getQueryId());
+    } else {
+      return null;
+    }
+  }
+
+
+  ////////////////////////////////////////
+
+  @Override
+  protected DrillResultSetImpl execute() throws SQLException{
+    DrillConnectionImpl connection = (DrillConnectionImpl) statement.getConnection();
+
+    connection.getClient().runQuery(QueryType.SQL, this.prepareResult.getSql(),
+                                    resultsListener);
+    connection.getDriver().handler.onStatementExecute(statement, null);
+
+    super.execute();
+
+    // don't return with metadata until we've achieved at least one return message.
+    try {
+      // TODO:  Revisit:  Why reaching directly into ResultsListener rather than
+      // calling some wait method?
+      resultsListener.latch.await();
+    } catch ( InterruptedException e ) {
+      // Preserve evidence that the interruption occurred so that code higher up
+      // on the call stack can learn of the interruption and respond to it if it
+      // wants to.
+      Thread.currentThread().interrupt();
+
+      // Not normally expected--Drill doesn't interrupt in this area (right?)--
+      // but JDBC client certainly could.
+      throw new SQLException( "Interrupted", e );
+    }
+
+    // Read first (schema-only) batch to initialize result-set metadata from
+    // (initial) schema before Statement.execute...(...) returns result set:
+    cursor.loadInitialSchema();
+
+    return this;
+  }
+
+
+  ////////////////////////////////////////
+  // ResultsListener:
+
   static class ResultsListener implements UserResultsListener {
     private static final Logger logger = getLogger( ResultsListener.class );