diff --git a/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillAccessorList.java b/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillAccessorList.java index 92848758eb6..6f6841588d3 100644 --- a/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillAccessorList.java +++ b/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillAccessorList.java @@ -26,15 +26,34 @@ import org.apache.drill.exec.vector.ValueVector; import org.apache.drill.exec.vector.accessor.BoundCheckingAccessor; import org.apache.drill.exec.vector.accessor.SqlAccessor; +import org.apache.drill.jdbc.JdbcApiSqlException; -class DrillAccessorList extends BasicList{ - static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(DrillAccessorList.class); +class DrillAccessorList extends BasicList { + + @SuppressWarnings("unused") + private static final org.slf4j.Logger logger = + org.slf4j.LoggerFactory.getLogger(DrillAccessorList.class); + /** "None" value for rowLastColumnOffset. */ + // (Not -1, since -1 can result from 0 (bad 1-based index) minus 1 (offset + // from 1-based to 0-based indexing.) + private static final int NULL_LAST_COLUMN_INDEX = -2; private AvaticaDrillSqlAccessor[] accessors = new AvaticaDrillSqlAccessor[0]; - // TODO Rename to lastColumnAccessed and/or document. - // TODO Why 1, rather than, say, -1? - private int lastColumn = 1; + + /** Zero-based offset of last column referenced in current row. + * For {@link #wasNull()}. */ + private int rowLastColumnOffset = NULL_LAST_COLUMN_INDEX; + + + /** + * Resets last-column-referenced information for {@link #wasNull}. + * Must be called whenever row is advanced (when {@link ResultSet#next()} + * is called). + */ + void clearLastColumnIndexedInRow() { + rowLastColumnOffset = NULL_LAST_COLUMN_INDEX; + } void generateAccessors(DrillCursor cursor, RecordBatchLoader currentBatch) { int cnt = currentBatch.getSchema().getFieldCount(); @@ -47,16 +66,29 @@ void generateAccessors(DrillCursor cursor, RecordBatchLoader currentBatch) { ); accessors[i] = new AvaticaDrillSqlAccessor(acc, cursor); } + clearLastColumnIndexedInRow(); } + /** + * @param accessorOffset 0-based index of accessor array (not 1-based SQL + * column index/ordinal value) + */ @Override - public AvaticaDrillSqlAccessor get(int index) { - lastColumn = index; - return accessors[index]; + public AvaticaDrillSqlAccessor get(final int accessorOffset) { + final AvaticaDrillSqlAccessor accessor = accessors[accessorOffset]; + // Update lastColumnIndexedInRow after indexing accessors to not touch + // lastColumnIndexedInRow in case of out-of-bounds exception. + rowLastColumnOffset = accessorOffset; + return accessor; } boolean wasNull() throws SQLException{ - return accessors[lastColumn].wasNull(); + if (NULL_LAST_COLUMN_INDEX == rowLastColumnOffset) { + throw new JdbcApiSqlException( + "ResultSet.wasNull() called without a preceding call to a column" + + " getter method since the last call to ResultSet.next()"); + } + return accessors[rowLastColumnOffset].wasNull(); } @Override 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 1ff2693f4f1..fc7b66745e8 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 @@ -406,13 +406,23 @@ public PreparedStatement prepareStatement(String sql) throws SQLException { @Override public CallableStatement prepareCall(String sql) throws SQLException { throwIfClosed(); - return super.prepareCall(sql); + try { + return super.prepareCall(sql); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public String nativeSQL(String sql) throws SQLException { throwIfClosed(); - return super.nativeSQL(sql); + try { + return super.nativeSQL(sql); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @@ -496,19 +506,34 @@ public PreparedStatement prepareStatement(String sql, int resultSetType, public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { throwIfClosed(); - return super.prepareCall(sql, resultSetType, resultSetConcurrency); + try { + return super.prepareCall(sql, resultSetType, resultSetConcurrency); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public Map> getTypeMap() throws SQLException { throwIfClosed(); - return super.getTypeMap(); + try { + return super.getTypeMap(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void setTypeMap(Map> map) throws SQLException { throwIfClosed(); - super.setTypeMap(map); + try { + super.setTypeMap(map); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override @@ -528,59 +553,104 @@ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { throwIfClosed(); - return super.prepareCall(sql, resultSetType, resultSetConcurrency, - resultSetHoldability); + try { + return super.prepareCall(sql, resultSetType, resultSetConcurrency, + resultSetHoldability); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { throwIfClosed(); - return super.prepareStatement(sql, autoGeneratedKeys); + try { + return super.prepareStatement(sql, autoGeneratedKeys); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public PreparedStatement prepareStatement(String sql, int columnIndexes[]) throws SQLException { throwIfClosed(); - return super.prepareStatement(sql, columnIndexes); + try { + return super.prepareStatement(sql, columnIndexes); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public PreparedStatement prepareStatement(String sql, String columnNames[]) throws SQLException { throwIfClosed(); - return super.prepareStatement(sql, columnNames); + try { + return super.prepareStatement(sql, columnNames); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public Clob createClob() throws SQLException { throwIfClosed(); - return super.createClob(); + try { + return super.createClob(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public Blob createBlob() throws SQLException { throwIfClosed(); - return super.createBlob(); + try { + return super.createBlob(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public NClob createNClob() throws SQLException { throwIfClosed(); - return super.createNClob(); + try { + return super.createNClob(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public SQLXML createSQLXML() throws SQLException { throwIfClosed(); - return super.createSQLXML(); + try { + return super.createSQLXML(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public boolean isValid(int timeout) throws SQLException { throwIfClosed(); - return super.isValid(timeout); + try { + return super.isValid(timeout); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override @@ -590,7 +660,14 @@ public void setClientInfo(String name, String value) throws SQLClientInfoExcepti } catch (AlreadyClosedSqlException e) { throw new SQLClientInfoException(e.getMessage(), null, e); } - super.setClientInfo(name, value); + try { + super.setClientInfo(name, value); + } + catch (UnsupportedOperationException e) { + SQLFeatureNotSupportedException intended = + new SQLFeatureNotSupportedException(e.getMessage(), e); + throw new SQLClientInfoException(e.getMessage(), null, intended); + } } @Override @@ -600,31 +677,58 @@ public void setClientInfo(Properties properties) throws SQLClientInfoException { } catch (AlreadyClosedSqlException e) { throw new SQLClientInfoException(e.getMessage(), null, e); } - super.setClientInfo(properties); + try { + super.setClientInfo(properties); + } + catch (UnsupportedOperationException e) { + SQLFeatureNotSupportedException intended = + new SQLFeatureNotSupportedException(e.getMessage(), e); + throw new SQLClientInfoException(e.getMessage(), null, intended); + } } @Override public String getClientInfo(String name) throws SQLException { throwIfClosed(); - return super.getClientInfo(name); + try { + return super.getClientInfo(name); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public Properties getClientInfo() throws SQLException { throwIfClosed(); - return super.getClientInfo(); + try { + return super.getClientInfo(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public Array createArrayOf(String typeName, Object[] elements) throws SQLException { throwIfClosed(); - return super.createArrayOf(typeName, elements); + try { + return super.createArrayOf(typeName, elements); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public Struct createStruct(String typeName, Object[] attributes) throws SQLException { throwIfClosed(); - return super.createStruct(typeName, attributes); + try { + return super.createStruct(typeName, attributes); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override @@ -648,7 +752,12 @@ public String getSchema() { @Override public void abort(Executor executor) throws SQLException { throwIfClosed(); - super.abort(executor); + try { + super.abort(executor); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @@ -692,6 +801,10 @@ void cleanup() { closeOrWarn(serviceSet, "Exception while closing service set.", logger); } + // TODO(DRILL-xxxx): Eliminate this test-specific hack from production code. + // If we're not going to have tests themselves explicitly handle making names + // unique, then at least move this logic into a test base class, and have it + // go through DrillConnection.getClient(). /** * Test only code to make JDBC tests run concurrently. If the property drillJDBCUnitTests is set to * true in connection properties: diff --git a/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillCursor.java b/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillCursor.java index 51103ddaf1d..b36658b0935 100644 --- a/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillCursor.java +++ b/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillCursor.java @@ -317,6 +317,7 @@ else if ( returnTrueForNextCallToNext ) { return true; } else { + accessors.clearLastColumnIndexedInRow(); return nextRowInternally(); } } 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 0855b01d144..a986749bdb6 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 @@ -22,6 +22,7 @@ import java.sql.ResultSet; import java.sql.RowIdLifetime; import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; import org.apache.drill.jdbc.AlreadyClosedSqlException; import org.apache.drill.jdbc.DrillDatabaseMetaData; @@ -122,7 +123,6 @@ public boolean nullsAreSortedAtEnd() throws SQLException { return false; } - @Override public String getDatabaseProductName() throws SQLException { throwIfClosed(); @@ -921,55 +921,154 @@ public boolean supportsResultSetConcurrency(int type, @Override public boolean ownUpdatesAreVisible(int type) throws SQLException { throwIfClosed(); - return super.ownUpdatesAreVisible(type); + try { + return super.ownUpdatesAreVisible(type); + } + catch (RuntimeException e) { + if ("todo: implement this method".equals(e.getMessage())) { + throw new SQLFeatureNotSupportedException( + "ownUpdatesAreVisible(int) is not supported", e); + } + else { + throw new SQLException(e.getMessage(), e); + } + } } @Override public boolean ownDeletesAreVisible(int type) throws SQLException { throwIfClosed(); - return super.ownDeletesAreVisible(type); + try { + return super.ownDeletesAreVisible(type); + } + catch (RuntimeException e) { + if ("todo: implement this method".equals(e.getMessage())) { + throw new SQLFeatureNotSupportedException( + "ownDeletesAreVisible(int) is not supported", e); + } + else { + throw new SQLException(e.getMessage(), e); + } + } } @Override public boolean ownInsertsAreVisible(int type) throws SQLException { throwIfClosed(); - return super.ownInsertsAreVisible(type); + try { + return super.ownInsertsAreVisible(type); + } + catch (RuntimeException e) { + if ("todo: implement this method".equals(e.getMessage())) { + throw new SQLFeatureNotSupportedException( + "ownInsertsAreVisible(int) is not supported", e); + } + else { + throw new SQLException(e.getMessage(), e); + } + } } @Override public boolean othersUpdatesAreVisible(int type) throws SQLException { throwIfClosed(); - return super.othersUpdatesAreVisible(type); + try { + return super.othersUpdatesAreVisible(type); + } + catch (RuntimeException e) { + if ("todo: implement this method".equals(e.getMessage())) { + throw new SQLFeatureNotSupportedException( + "othersUpdatesAreVisible(int) is not supported", e); + } + else { + throw new SQLException(e.getMessage(), e); + } + } } @Override public boolean othersDeletesAreVisible(int type) throws SQLException { throwIfClosed(); - return super.othersDeletesAreVisible(type); + try { + return super.othersDeletesAreVisible(type); + } + catch (RuntimeException e) { + if ("todo: implement this method".equals(e.getMessage())) { + throw new SQLFeatureNotSupportedException( + "othersDeletesAreVisible(int) is not supported", e); + } + else { + throw new SQLException(e.getMessage(), e); + } + } } @Override public boolean othersInsertsAreVisible(int type) throws SQLException { throwIfClosed(); - return super.othersInsertsAreVisible(type); + try { + return super.othersInsertsAreVisible(type); + } + catch (RuntimeException e) { + if ("todo: implement this method".equals(e.getMessage())) { + throw new SQLFeatureNotSupportedException( + "othersInsertsAreVisible(int) is not supported", e); + } + else { + throw new SQLException(e.getMessage(), e); + } + } } @Override public boolean updatesAreDetected(int type) throws SQLException { throwIfClosed(); - return super.updatesAreDetected(type); + try { + return super.updatesAreDetected(type); + } + catch (RuntimeException e) { + if ("todo: implement this method".equals(e.getMessage())) { + throw new SQLFeatureNotSupportedException( + "updatesAreDetected(int) is not supported", e); + } + else { + throw new SQLException(e.getMessage(), e); + } + } } @Override public boolean deletesAreDetected(int type) throws SQLException { throwIfClosed(); - return super.deletesAreDetected(type); + try { + return super.deletesAreDetected(type); + } + catch (RuntimeException e) { + if ("todo: implement this method".equals(e.getMessage())) { + throw new SQLFeatureNotSupportedException( + "deletesAreDetected(int) is not supported", e); + } + else { + throw new SQLException(e.getMessage(), e); + } + } } @Override public boolean insertsAreDetected(int type) throws SQLException { throwIfClosed(); - return super.insertsAreDetected(type); + try { + return super.insertsAreDetected(type); + } + catch (RuntimeException e) { + if ("todo: implement this method".equals(e.getMessage())) { + throw new SQLFeatureNotSupportedException( + "insertsAreDetected(int) is not supported", e); + } + else { + throw new SQLException(e.getMessage(), e); + } + } } @Override @@ -1042,7 +1141,18 @@ public ResultSet getAttributes(String catalog, String schemaPattern, @Override public boolean supportsResultSetHoldability(int holdability) throws SQLException { throwIfClosed(); - return super.supportsResultSetHoldability(holdability); + try { + return super.supportsResultSetHoldability(holdability); + } + catch (RuntimeException e) { + if ("todo: implement this method".equals(e.getMessage())) { + throw new SQLFeatureNotSupportedException( + "supportsResultSetHoldability(int) is not supported", e); + } + else { + throw new SQLException(e.getMessage(), e); + } + } } @Override 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 f84e14ea8d8..f86edc6ba97 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 @@ -106,13 +106,23 @@ public void cleanUp() { @Override public ResultSet executeQuery(String sql) throws SQLException { throwIfClosed(); - return super.executeQuery(sql); + try { + return super.executeQuery(sql); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public int executeUpdate(String sql) throws SQLException { throwIfClosed(); - return super.executeUpdate(sql); + try { + return super.executeUpdate(sql); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } // No close() (it doesn't throw SQLException if already closed). @@ -120,13 +130,23 @@ public int executeUpdate(String sql) throws SQLException { @Override public int getMaxFieldSize() throws SQLException { throwIfClosed(); - return super.getMaxFieldSize(); + try { + return super.getMaxFieldSize(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void setMaxFieldSize(int max) throws SQLException { throwIfClosed(); - super.setMaxFieldSize(max); + try { + super.setMaxFieldSize(max); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override @@ -150,7 +170,12 @@ public void setMaxRows(int max) throws SQLException { @Override public void setEscapeProcessing(boolean enable) throws SQLException { throwIfClosed(); - super.setEscapeProcessing(enable); + try { + super.setEscapeProcessing(enable); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override @@ -186,7 +211,12 @@ public void clearWarnings() throws SQLException { @Override public void setCursorName(String name) throws SQLException { throwIfClosed(); - super.setCursorName(name); + try { + super.setCursorName(name); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override @@ -210,7 +240,12 @@ public int getUpdateCount() throws SQLException { @Override public boolean getMoreResults() throws SQLException { throwIfClosed(); - return super.getMoreResults(); + try { + return super.getMoreResults(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override @@ -252,85 +287,155 @@ public int getFetchSize() { @Override public int getResultSetConcurrency() throws SQLException { throwIfClosed(); - return super.getResultSetConcurrency(); + try { + return super.getResultSetConcurrency(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public int getResultSetType() throws SQLException { throwIfClosed(); - return super.getResultSetType(); + try { + return super.getResultSetType(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void addBatch(String sql) throws SQLException { throwIfClosed(); - super.addBatch(sql); + try { + super.addBatch(sql); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void clearBatch() throws SQLException { throwIfClosed(); - super.clearBatch(); + try { + super.clearBatch(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public int[] executeBatch() throws SQLException { throwIfClosed(); - return super.executeBatch(); + try { + return super.executeBatch(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public boolean getMoreResults(int current) throws SQLException { throwIfClosed(); - return super.getMoreResults(current); + try { + return super.getMoreResults(current); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public ResultSet getGeneratedKeys() throws SQLException { throwIfClosed(); - return super.getGeneratedKeys(); + try { + return super.getGeneratedKeys(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { throwIfClosed(); - return super.executeUpdate(sql, autoGeneratedKeys); + try { + return super.executeUpdate(sql, autoGeneratedKeys); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public int executeUpdate(String sql, int columnIndexes[]) throws SQLException { throwIfClosed(); - return super.executeUpdate(sql, columnIndexes); + try { + return super.executeUpdate(sql, columnIndexes); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public int executeUpdate(String sql, String columnNames[]) throws SQLException { throwIfClosed(); - return super.executeUpdate(sql, columnNames); + try { + return super.executeUpdate(sql, columnNames); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { throwIfClosed(); - return super.execute(sql, autoGeneratedKeys); + try { + return super.execute(sql, autoGeneratedKeys); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public boolean execute(String sql, int columnIndexes[]) throws SQLException { throwIfClosed(); - return super.execute(sql, columnIndexes); + try { + return super.execute(sql, columnIndexes); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public boolean execute(String sql, String columnNames[]) throws SQLException { throwIfClosed(); - return super.execute(sql, columnNames); + try { + return super.execute(sql, columnNames); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public int getResultSetHoldability() throws SQLException { throwIfClosed(); - return super.getResultSetHoldability(); + try { + return super.getResultSetHoldability(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override @@ -346,13 +451,23 @@ public boolean isClosed() { @Override public void setPoolable(boolean poolable) throws SQLException { throwIfClosed(); - super.setPoolable(poolable); + try { + super.setPoolable(poolable); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public boolean isPoolable() throws SQLException { throwIfClosed(); - return super.isPoolable(); + try { + return super.isPoolable(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override @@ -376,7 +491,12 @@ public ResultSet executeQuery() throws SQLException { @Override public int executeUpdate() throws SQLException { throwIfClosed(); - return super.executeUpdate(); + try { + return super.executeUpdate(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } // Covered by superclass methods' calls to getParameter(int): @@ -401,7 +521,12 @@ public int executeUpdate() throws SQLException { @Override public void clearParameters() throws SQLException { throwIfClosed(); - super.clearParameters(); + try { + super.clearParameters(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } // Covered by superclass methods' calls to getParameter(int): @@ -411,13 +536,23 @@ public void clearParameters() throws SQLException { @Override public boolean execute() throws SQLException { throwIfClosed(); - return super.execute(); + try { + return super.execute(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void addBatch() throws SQLException { throwIfClosed(); - super.addBatch(); + try { + super.addBatch(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } // Covered by superclass methods' calls to getParameter(int): 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 9f3e0f7eadb..d7de6773bb9 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 @@ -31,6 +31,7 @@ import java.sql.ResultSetMetaData; import java.sql.RowId; import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; import java.sql.SQLWarning; import java.sql.SQLXML; import java.sql.Time; @@ -403,7 +404,12 @@ public void clearWarnings() throws SQLException { @Override public String getCursorName() throws SQLException { throwIfClosed(); - return super.getCursorName(); + try { + return super.getCursorName(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } // (Not delegated.) @@ -484,31 +490,56 @@ public boolean isFirst() throws SQLException { @Override public boolean isLast() throws SQLException { throwIfClosed(); - return super.isLast(); + try { + return super.isLast(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void beforeFirst() throws SQLException { throwIfClosed(); - super.beforeFirst(); + try { + super.beforeFirst(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void afterLast() throws SQLException { throwIfClosed(); - super.afterLast(); + try { + super.afterLast(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public boolean first() throws SQLException { throwIfClosed(); - return super.first(); + try { + return super.first(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public boolean last() throws SQLException { throwIfClosed(); - return super.last(); + try { + return super.last(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override @@ -520,19 +551,34 @@ public int getRow() throws SQLException { @Override public boolean absolute( int row ) throws SQLException { throwIfClosed(); - return super.absolute( row ); + try { + return super.absolute( row ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public boolean relative( int rows ) throws SQLException { throwIfClosed(); - return super.relative( rows ); + try { + return super.relative( rows ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public boolean previous() throws SQLException { throwIfClosed(); - return super.previous(); + try { + return super.previous(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } //--------------------------------------------------------------------- @@ -599,281 +645,506 @@ public boolean rowDeleted() throws SQLException { @Override public void updateNull( int columnIndex ) throws SQLException { throwIfClosed(); - super.updateNull( columnIndex ); + try { + super.updateNull( columnIndex ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateBoolean( int columnIndex, boolean x ) throws SQLException { throwIfClosed(); - super.updateBoolean( columnIndex, x ); + try { + super.updateBoolean( columnIndex, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateByte( int columnIndex, byte x ) throws SQLException { throwIfClosed(); - super.updateByte( columnIndex, x ); + try { + super.updateByte( columnIndex, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateShort( int columnIndex, short x ) throws SQLException { throwIfClosed(); - super.updateShort( columnIndex, x ); + try { + super.updateShort( columnIndex, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateInt( int columnIndex, int x ) throws SQLException { throwIfClosed(); - super.updateInt( columnIndex, x ); + try { + super.updateInt( columnIndex, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateLong( int columnIndex, long x ) throws SQLException { throwIfClosed(); - super.updateLong( columnIndex, x ); + try { + super.updateLong( columnIndex, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateFloat( int columnIndex, float x ) throws SQLException { throwIfClosed(); - super.updateFloat( columnIndex, x ); + try { + super.updateFloat( columnIndex, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateDouble( int columnIndex, double x ) throws SQLException { throwIfClosed(); - super.updateDouble( columnIndex, x ); + try { + super.updateDouble( columnIndex, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateBigDecimal( int columnIndex, BigDecimal x ) throws SQLException { throwIfClosed(); - super.updateBigDecimal( columnIndex, x ); + try { + super.updateBigDecimal( columnIndex, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateString( int columnIndex, String x ) throws SQLException { throwIfClosed(); - super.updateString( columnIndex, x ); + try { + super.updateString( columnIndex, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateBytes( int columnIndex, byte[] x ) throws SQLException { throwIfClosed(); - super.updateBytes( columnIndex, x ); + try { + super.updateBytes( columnIndex, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateDate( int columnIndex, Date x ) throws SQLException { throwIfClosed(); - super.updateDate( columnIndex, x ); + try { + super.updateDate( columnIndex, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateTime( int columnIndex, Time x ) throws SQLException { throwIfClosed(); - super.updateTime( columnIndex, x ); + try { + super.updateTime( columnIndex, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateTimestamp( int columnIndex, Timestamp x ) throws SQLException { throwIfClosed(); - super.updateTimestamp( columnIndex, x ); + try { + super.updateTimestamp( columnIndex, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateAsciiStream( int columnIndex, InputStream x, int length ) throws SQLException { throwIfClosed(); - super.updateAsciiStream( columnIndex, x, length ); + try { + super.updateAsciiStream( columnIndex, x, length ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateBinaryStream( int columnIndex, InputStream x, int length ) throws SQLException { throwIfClosed(); - super.updateBinaryStream( columnIndex, x, length ); + try { + super.updateBinaryStream( columnIndex, x, length ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateCharacterStream( int columnIndex, Reader x, int length ) throws SQLException { throwIfClosed(); - super.updateCharacterStream( columnIndex, x, length ); + try { + super.updateCharacterStream( columnIndex, x, length ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateObject( int columnIndex, Object x, int scaleOrLength ) throws SQLException { throwIfClosed(); - super.updateObject( columnIndex, x, scaleOrLength ); + try { + super.updateObject( columnIndex, x, scaleOrLength ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateObject( int columnIndex, Object x ) throws SQLException { throwIfClosed(); - super.updateObject( columnIndex, x ); + try { + super.updateObject( columnIndex, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateNull( String columnLabel ) throws SQLException { throwIfClosed(); - super.updateNull( columnLabel ); + try { + super.updateNull( columnLabel ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateBoolean( String columnLabel, boolean x ) throws SQLException { throwIfClosed(); - super.updateBoolean( columnLabel, x ); + try { + super.updateBoolean( columnLabel, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateByte( String columnLabel, byte x ) throws SQLException { throwIfClosed(); - super.updateByte( columnLabel, x ); + try { + super.updateByte( columnLabel, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateShort( String columnLabel, short x ) throws SQLException { throwIfClosed(); - super.updateShort( columnLabel, x ); + try { + super.updateShort( columnLabel, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateInt( String columnLabel, int x ) throws SQLException { throwIfClosed(); - super.updateInt( columnLabel, x ); + try { + super.updateInt( columnLabel, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateLong( String columnLabel, long x ) throws SQLException { throwIfClosed(); - super.updateLong( columnLabel, x ); + try { + super.updateLong( columnLabel, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateFloat( String columnLabel, float x ) throws SQLException { throwIfClosed(); - super.updateFloat( columnLabel, x ); + try { + super.updateFloat( columnLabel, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateDouble( String columnLabel, double x ) throws SQLException { throwIfClosed(); - super.updateDouble( columnLabel, x ); + try { + super.updateDouble( columnLabel, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateBigDecimal( String columnLabel, BigDecimal x ) throws SQLException { throwIfClosed(); - super.updateBigDecimal( columnLabel, x ); + try { + super.updateBigDecimal( columnLabel, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateString( String columnLabel, String x ) throws SQLException { throwIfClosed(); - super.updateString( columnLabel, x ); + try { + super.updateString( columnLabel, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateBytes( String columnLabel, byte[] x ) throws SQLException { throwIfClosed(); - super.updateBytes( columnLabel, x ); + try { + super.updateBytes( columnLabel, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateDate( String columnLabel, Date x ) throws SQLException { throwIfClosed(); - super.updateDate( columnLabel, x ); + try { + super.updateDate( columnLabel, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateTime( String columnLabel, Time x ) throws SQLException { throwIfClosed(); - super.updateTime( columnLabel, x ); + try { + super.updateTime( columnLabel, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateTimestamp( String columnLabel, Timestamp x ) throws SQLException { throwIfClosed(); - super.updateTimestamp( columnLabel, x ); + try { + super.updateTimestamp( columnLabel, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateAsciiStream( String columnLabel, InputStream x, int length ) throws SQLException { throwIfClosed(); - super.updateAsciiStream( columnLabel, x, length ); + try { + super.updateAsciiStream( columnLabel, x, length ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateBinaryStream( String columnLabel, InputStream x, int length ) throws SQLException { throwIfClosed(); - super.updateBinaryStream( columnLabel, x, length ); + try { + super.updateBinaryStream( columnLabel, x, length ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateCharacterStream( String columnLabel, Reader reader, int length ) throws SQLException { throwIfClosed(); - super.updateCharacterStream( columnLabel, reader, length ); + try { + super.updateCharacterStream( columnLabel, reader, length ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateObject( String columnLabel, Object x, int scaleOrLength ) throws SQLException { throwIfClosed(); - super.updateObject( columnLabel, x, scaleOrLength ); + try { + super.updateObject( columnLabel, x, scaleOrLength ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateObject( String columnLabel, Object x ) throws SQLException { throwIfClosed(); - super.updateObject( columnLabel, x ); + try { + super.updateObject( columnLabel, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void insertRow() throws SQLException { throwIfClosed(); - super.insertRow(); + try { + super.insertRow(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateRow() throws SQLException { throwIfClosed(); - super.updateRow(); + try { + super.updateRow(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void deleteRow() throws SQLException { throwIfClosed(); - super.deleteRow(); + try { + super.deleteRow(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void refreshRow() throws SQLException { throwIfClosed(); - super.refreshRow(); + try { + super.refreshRow(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void cancelRowUpdates() throws SQLException { throwIfClosed(); - super.cancelRowUpdates(); + try { + super.cancelRowUpdates(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void moveToInsertRow() throws SQLException { throwIfClosed(); - super.moveToInsertRow(); + try { + super.moveToInsertRow(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void moveToCurrentRow() throws SQLException { throwIfClosed(); - super.moveToCurrentRow(); + try { + super.moveToCurrentRow(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override @@ -1006,74 +1277,134 @@ public URL getURL( String columnLabel ) throws SQLException { @Override public void updateRef( int columnIndex, Ref x ) throws SQLException { throwIfClosed(); - super.updateRef( columnIndex, x ); + try { + super.updateRef( columnIndex, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateRef( String columnLabel, Ref x ) throws SQLException { throwIfClosed(); - super.updateRef( columnLabel, x ); + try { + super.updateRef( columnLabel, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateBlob( int columnIndex, Blob x ) throws SQLException { throwIfClosed(); - super.updateBlob( columnIndex, x ); + try { + super.updateBlob( columnIndex, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateBlob( String columnLabel, Blob x ) throws SQLException { throwIfClosed(); - super.updateBlob( columnLabel, x ); + try { + super.updateBlob( columnLabel, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateClob( int columnIndex, Clob x ) throws SQLException { throwIfClosed(); - super.updateClob( columnIndex, x ); + try { + super.updateClob( columnIndex, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateClob( String columnLabel, Clob x ) throws SQLException { throwIfClosed(); - super.updateClob( columnLabel, x ); + try { + super.updateClob( columnLabel, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateArray( int columnIndex, Array x ) throws SQLException { throwIfClosed(); - super.updateArray( columnIndex, x ); + try { + super.updateArray( columnIndex, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateArray( String columnLabel, Array x ) throws SQLException { throwIfClosed(); - super.updateArray( columnLabel, x ); + try { + super.updateArray( columnLabel, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } //------------------------- JDBC 4.0 ----------------------------------- @Override public RowId getRowId( int columnIndex ) throws SQLException { throwIfClosed(); - return super.getRowId( columnIndex ); + try { + return super.getRowId( columnIndex ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public RowId getRowId( String columnLabel ) throws SQLException { throwIfClosed(); - return super.getRowId( columnLabel ); + try { + return super.getRowId( columnLabel ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateRowId( int columnIndex, RowId x ) throws SQLException { throwIfClosed(); - super.updateRowId( columnIndex, x ); + try { + super.updateRowId( columnIndex, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateRowId( String columnLabel, RowId x ) throws SQLException { throwIfClosed(); - super.updateRowId( columnLabel, x ); + try { + super.updateRowId( columnLabel, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override @@ -1091,26 +1422,46 @@ public boolean isClosed() throws SQLException { @Override public void updateNString( int columnIndex, String nString ) throws SQLException { throwIfClosed(); - super.updateNString( columnIndex, nString ); + try { + super.updateNString( columnIndex, nString ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateNString( String columnLabel, String nString ) throws SQLException { throwIfClosed(); - super.updateNString( columnLabel, nString ); + try { + super.updateNString( columnLabel, nString ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateNClob( int columnIndex, NClob nClob ) throws SQLException { throwIfClosed(); - super.updateNClob( columnIndex, nClob ); + try { + super.updateNClob( columnIndex, nClob ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateNClob( String columnLabel, NClob nClob ) throws SQLException { throwIfClosed(); - super.updateNClob( columnLabel, nClob ); + try { + super.updateNClob( columnLabel, nClob ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override @@ -1141,14 +1492,24 @@ public SQLXML getSQLXML( String columnLabel ) throws SQLException { public void updateSQLXML( int columnIndex, SQLXML xmlObject ) throws SQLException { throwIfClosed(); - super.updateSQLXML( columnIndex, xmlObject ); + try { + super.updateSQLXML( columnIndex, xmlObject ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateSQLXML( String columnLabel, SQLXML xmlObject ) throws SQLException { throwIfClosed(); - super.updateSQLXML( columnLabel, xmlObject ); + try { + super.updateSQLXML( columnLabel, xmlObject ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override @@ -1179,98 +1540,168 @@ public Reader getNCharacterStream( String columnLabel ) throws SQLException { public void updateNCharacterStream( int columnIndex, Reader x, long length ) throws SQLException { throwIfClosed(); - super.updateNCharacterStream( columnIndex, x, length ); + try { + super.updateNCharacterStream( columnIndex, x, length ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateNCharacterStream( String columnLabel, Reader reader, long length ) throws SQLException { throwIfClosed(); - super.updateNCharacterStream( columnLabel, reader, length ); + try { + super.updateNCharacterStream( columnLabel, reader, length ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateAsciiStream( int columnIndex, InputStream x, long length ) throws SQLException { throwIfClosed(); - super.updateAsciiStream( columnIndex, x, length ); + try { + super.updateAsciiStream( columnIndex, x, length ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateBinaryStream( int columnIndex, InputStream x, long length ) throws SQLException { throwIfClosed(); - super.updateBinaryStream( columnIndex, x, length ); + try { + super.updateBinaryStream( columnIndex, x, length ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateCharacterStream( int columnIndex, Reader x, long length ) throws SQLException { throwIfClosed(); - super.updateCharacterStream( columnIndex, x, length ); + try { + super.updateCharacterStream( columnIndex, x, length ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateAsciiStream( String columnLabel, InputStream x, long length ) throws SQLException { throwIfClosed(); - super.updateAsciiStream( columnLabel, x, length ); + try { + super.updateAsciiStream( columnLabel, x, length ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateBinaryStream( String columnLabel, InputStream x, long length ) throws SQLException { throwIfClosed(); - super.updateBinaryStream( columnLabel, x, length ); + try { + super.updateBinaryStream( columnLabel, x, length ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateCharacterStream( String columnLabel, Reader reader, long length ) throws SQLException { throwIfClosed(); - super.updateCharacterStream( columnLabel, reader, length ); + try { + super.updateCharacterStream( columnLabel, reader, length ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateBlob( int columnIndex, InputStream inputStream, long length ) throws SQLException { throwIfClosed(); - super.updateBlob( columnIndex, inputStream, length ); + try { + super.updateBlob( columnIndex, inputStream, length ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateBlob( String columnLabel, InputStream inputStream, long length ) throws SQLException { throwIfClosed(); - super.updateBlob( columnLabel, inputStream, length ); + try { + super.updateBlob( columnLabel, inputStream, length ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateClob( int columnIndex, Reader reader, long length ) throws SQLException { throwIfClosed(); - super.updateClob( columnIndex, reader, length ); + try { + super.updateClob( columnIndex, reader, length ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateClob( String columnLabel, Reader reader, long length ) throws SQLException { throwIfClosed(); - super.updateClob( columnLabel, reader, length ); + try { + super.updateClob( columnLabel, reader, length ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateNClob( int columnIndex, Reader reader, long length ) throws SQLException { throwIfClosed(); - super.updateNClob( columnIndex, reader, length ); + try { + super.updateNClob( columnIndex, reader, length ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateNClob( String columnLabel, Reader reader, long length ) throws SQLException { throwIfClosed(); - super.updateNClob( columnLabel, reader, length ); + try { + super.updateNClob( columnLabel, reader, length ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } //--- @@ -1278,94 +1709,164 @@ public void updateNClob( String columnLabel, Reader reader, public void updateNCharacterStream( int columnIndex, Reader x ) throws SQLException { throwIfClosed(); - super.updateNCharacterStream( columnIndex, x ); + try { + super.updateNCharacterStream( columnIndex, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateNCharacterStream( String columnLabel, Reader reader ) throws SQLException { throwIfClosed(); - super.updateNCharacterStream( columnLabel, reader ); + try { + super.updateNCharacterStream( columnLabel, reader ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateAsciiStream( int columnIndex, InputStream x ) throws SQLException { throwIfClosed(); - super.updateAsciiStream( columnIndex, x ); + try { + super.updateAsciiStream( columnIndex, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateBinaryStream( int columnIndex, InputStream x ) throws SQLException { throwIfClosed(); - super.updateBinaryStream( columnIndex, x ); + try { + super.updateBinaryStream( columnIndex, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateCharacterStream( int columnIndex, Reader x ) throws SQLException { throwIfClosed(); - super.updateCharacterStream( columnIndex, x ); + try { + super.updateCharacterStream( columnIndex, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateAsciiStream( String columnLabel, InputStream x ) throws SQLException { throwIfClosed(); - super.updateAsciiStream( columnLabel, x ); + try { + super.updateAsciiStream( columnLabel, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateBinaryStream( String columnLabel, InputStream x ) throws SQLException { throwIfClosed(); - super.updateBinaryStream( columnLabel, x ); + try { + super.updateBinaryStream( columnLabel, x ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateCharacterStream( String columnLabel, Reader reader ) throws SQLException { throwIfClosed(); - super.updateCharacterStream( columnLabel, reader ); + try { + super.updateCharacterStream( columnLabel, reader ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateBlob( int columnIndex, InputStream inputStream ) throws SQLException { throwIfClosed(); - super.updateBlob( columnIndex, inputStream ); + try { + super.updateBlob( columnIndex, inputStream ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateBlob( String columnLabel, InputStream inputStream ) throws SQLException { throwIfClosed(); - super.updateBlob( columnLabel, inputStream ); + try { + super.updateBlob( columnLabel, inputStream ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateClob( int columnIndex, Reader reader ) throws SQLException { throwIfClosed(); - super.updateClob( columnIndex, reader ); + try { + super.updateClob( columnIndex, reader ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateClob( String columnLabel, Reader reader ) throws SQLException { throwIfClosed(); - super.updateClob( columnLabel, reader ); + try { + super.updateClob( columnLabel, reader ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateNClob( int columnIndex, Reader reader ) throws SQLException { throwIfClosed(); - super.updateNClob( columnIndex, reader ); + try { + super.updateNClob( columnIndex, reader ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void updateNClob( String columnLabel, Reader reader ) throws SQLException { throwIfClosed(); - super.updateNClob( columnLabel, reader ); + try { + super.updateNClob( columnLabel, reader ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } //------------------------- JDBC 4.1 ----------------------------------- diff --git a/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillResultSetMetaDataImpl.java b/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillResultSetMetaDataImpl.java index 4be93b46b61..79a3455ca8a 100644 --- a/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillResultSetMetaDataImpl.java +++ b/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillResultSetMetaDataImpl.java @@ -22,6 +22,7 @@ import java.util.List; import org.apache.drill.jdbc.AlreadyClosedSqlException; +import org.apache.drill.jdbc.InvalidParameterSqlException; import net.hydromatic.avatica.AvaticaResultSetMetaData; import net.hydromatic.avatica.AvaticaStatement; @@ -56,6 +57,17 @@ private void throwIfClosed() throws AlreadyClosedSqlException, } } + private void throwIfClosedOrOutOfBounds(int columnNumber) + throws InvalidParameterSqlException, + SQLException { + throwIfClosed(); + if (1 > columnNumber || columnNumber > getColumnCount()) { + throw new InvalidParameterSqlException( + "Column number " + columnNumber + " out of range of from 1 through " + + getColumnCount() + " (column count)"); + } + } + // Note: Using dynamic proxies would reduce the quantity (450?) of method // overrides by eliminating those that exist solely to check whether the @@ -76,123 +88,123 @@ public int getColumnCount() throws SQLException { } @Override - public boolean isAutoIncrement(int column) throws SQLException { - throwIfClosed(); - return super.isAutoIncrement(column); + public boolean isAutoIncrement(int columnNumber) throws SQLException { + throwIfClosedOrOutOfBounds(columnNumber); + return super.isAutoIncrement(columnNumber); } @Override - public boolean isCaseSensitive(int column) throws SQLException { - throwIfClosed(); - return super.isCaseSensitive(column); + public boolean isCaseSensitive(int columnNumber) throws SQLException { + throwIfClosedOrOutOfBounds(columnNumber); + return super.isCaseSensitive(columnNumber); } @Override - public boolean isSearchable(int column) throws SQLException { - throwIfClosed(); - return super.isSearchable(column); + public boolean isSearchable(int columnNumber) throws SQLException { + throwIfClosedOrOutOfBounds(columnNumber); + return super.isSearchable(columnNumber); } @Override - public boolean isCurrency(int column) throws SQLException { - throwIfClosed(); - return super.isCurrency(column); + public boolean isCurrency(int columnNumber) throws SQLException { + throwIfClosedOrOutOfBounds(columnNumber); + return super.isCurrency(columnNumber); } @Override - public int isNullable(int column) throws SQLException { - throwIfClosed(); - return super.isNullable(column); + public int isNullable(int columnNumber) throws SQLException { + throwIfClosedOrOutOfBounds(columnNumber); + return super.isNullable(columnNumber); } @Override - public boolean isSigned(int column) throws SQLException { - throwIfClosed(); - return super.isSigned(column); + public boolean isSigned(int columnNumber) throws SQLException { + throwIfClosedOrOutOfBounds(columnNumber); + return super.isSigned(columnNumber); } @Override - public int getColumnDisplaySize(int column) throws SQLException { - throwIfClosed(); - return super.getColumnDisplaySize(column); + public int getColumnDisplaySize(int columnNumber) throws SQLException { + throwIfClosedOrOutOfBounds(columnNumber); + return super.getColumnDisplaySize(columnNumber); } @Override - public String getColumnLabel(int column) throws SQLException { - throwIfClosed(); - return super.getColumnLabel(column); + public String getColumnLabel(int columnNumber) throws SQLException { + throwIfClosedOrOutOfBounds(columnNumber); + return super.getColumnLabel(columnNumber); } @Override - public String getColumnName(int column) throws SQLException { - throwIfClosed(); - return super.getColumnName(column); + public String getColumnName(int columnNumber) throws SQLException { + throwIfClosedOrOutOfBounds(columnNumber); + return super.getColumnName(columnNumber); } @Override - public String getSchemaName(int column) throws SQLException { - throwIfClosed(); - return super.getSchemaName(column); + public String getSchemaName(int columnNumber) throws SQLException { + throwIfClosedOrOutOfBounds(columnNumber); + return super.getSchemaName(columnNumber); } @Override - public int getPrecision(int column) throws SQLException { - throwIfClosed(); - return super.getPrecision(column); + public int getPrecision(int columnNumber) throws SQLException { + throwIfClosedOrOutOfBounds(columnNumber); + return super.getPrecision(columnNumber); } @Override - public int getScale(int column) throws SQLException { - throwIfClosed(); - return super.getScale(column); + public int getScale(int columnNumber) throws SQLException { + throwIfClosedOrOutOfBounds(columnNumber); + return super.getScale(columnNumber); } @Override - public String getTableName(int column) throws SQLException { - throwIfClosed(); - return super.getTableName(column); + public String getTableName(int columnNumber) throws SQLException { + throwIfClosedOrOutOfBounds(columnNumber); + return super.getTableName(columnNumber); } @Override - public String getCatalogName(int column) throws SQLException { - throwIfClosed(); - return super.getCatalogName(column); + public String getCatalogName(int columnNumber) throws SQLException { + throwIfClosedOrOutOfBounds(columnNumber); + return super.getCatalogName(columnNumber); } @Override - public int getColumnType(int column) throws SQLException { - throwIfClosed(); - return super.getColumnType(column); + public int getColumnType(int columnNumber) throws SQLException { + throwIfClosedOrOutOfBounds(columnNumber); + return super.getColumnType(columnNumber); } @Override - public String getColumnTypeName(int column) throws SQLException { - throwIfClosed(); - return super.getColumnTypeName(column); + public String getColumnTypeName(int columnNumber) throws SQLException { + throwIfClosedOrOutOfBounds(columnNumber); + return super.getColumnTypeName(columnNumber); } @Override - public boolean isReadOnly(int column) throws SQLException { - throwIfClosed(); - return super.isReadOnly(column); + public boolean isReadOnly(int columnNumber) throws SQLException { + throwIfClosedOrOutOfBounds(columnNumber); + return super.isReadOnly(columnNumber); } @Override - public boolean isWritable(int column) throws SQLException { - throwIfClosed(); - return super.isWritable(column); + public boolean isWritable(int columnNumber) throws SQLException { + throwIfClosedOrOutOfBounds(columnNumber); + return super.isWritable(columnNumber); } @Override - public boolean isDefinitelyWritable(int column) throws SQLException { - throwIfClosed(); - return super.isDefinitelyWritable(column); + public boolean isDefinitelyWritable(int columnNumber) throws SQLException { + throwIfClosedOrOutOfBounds(columnNumber); + return super.isDefinitelyWritable(columnNumber); } @Override - public String getColumnClassName(int column) throws SQLException { - throwIfClosed(); - return super.getColumnClassName(column); + public String getColumnClassName(int columnNumber) throws SQLException { + throwIfClosedOrOutOfBounds(columnNumber); + return super.getColumnClassName(columnNumber); } } diff --git a/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillStatementImpl.java b/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillStatementImpl.java index 54b27096d37..5bdf5f82bba 100644 --- a/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillStatementImpl.java +++ b/exec/jdbc/src/main/java/org/apache/drill/jdbc/impl/DrillStatementImpl.java @@ -130,13 +130,23 @@ public int executeUpdate( String sql ) throws SQLException { @Override public int executeUpdate( String sql, int[] columnIndexes ) throws SQLException { throwIfClosed(); - return super.executeUpdate( sql, columnIndexes ); + try { + return super.executeUpdate( sql, columnIndexes ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public int executeUpdate( String sql, String[] columnNames ) throws SQLException { throwIfClosed(); - return super.executeUpdate( sql, columnNames ); + try { + return super.executeUpdate( sql, columnNames ); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override @@ -195,13 +205,23 @@ public boolean isClosed() { @Override public int getMaxFieldSize() throws SQLException { throwIfClosed(); - return super.getMaxFieldSize(); + try { + return super.getMaxFieldSize(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void setMaxFieldSize(int max) throws SQLException { throwIfClosed(); - super.setMaxFieldSize(max); + try { + super.setMaxFieldSize(max); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override @@ -225,7 +245,12 @@ public void setMaxRows(int max) throws SQLException { @Override public void setEscapeProcessing(boolean enable) throws SQLException { throwIfClosed(); - super.setEscapeProcessing(enable); + try { + super.setEscapeProcessing(enable); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override @@ -249,7 +274,12 @@ public void clearWarnings() throws SQLException { @Override public void setCursorName(String name) throws SQLException { throwIfClosed(); - super.setCursorName(name); + try { + super.setCursorName(name); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override @@ -267,7 +297,12 @@ public int getUpdateCount() throws SQLException { @Override public boolean getMoreResults() throws SQLException { throwIfClosed(); - return super.getMoreResults(); + try { + return super.getMoreResults(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override @@ -309,13 +344,23 @@ public int getFetchSize() { @Override public int getResultSetConcurrency() throws SQLException { throwIfClosed(); - return super.getResultSetConcurrency(); + try { + return super.getResultSetConcurrency(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public int getResultSetType() throws SQLException { throwIfClosed(); - return super.getResultSetType(); + try { + return super.getResultSetType(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override @@ -332,67 +377,122 @@ public void addBatch(String sql) throws SQLException { @Override public void clearBatch() throws SQLException { throwIfClosed(); - super.clearBatch(); + try { + super.clearBatch(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public int[] executeBatch() throws SQLException { throwIfClosed(); - return super.executeBatch(); + try { + return super.executeBatch(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public boolean getMoreResults(int current) throws SQLException { throwIfClosed(); - return super.getMoreResults(current); + try { + return super.getMoreResults(current); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public ResultSet getGeneratedKeys() throws SQLException { throwIfClosed(); - return super.getGeneratedKeys(); + try { + return super.getGeneratedKeys(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { throwIfClosed(); - return super.executeUpdate(sql, autoGeneratedKeys); + try { + return super.executeUpdate(sql, autoGeneratedKeys); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { throwIfClosed(); - return super.execute(sql, autoGeneratedKeys); + try { + return super.execute(sql, autoGeneratedKeys); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public boolean execute(String sql, int columnIndexes[]) throws SQLException { throwIfClosed(); - return super.execute(sql, columnIndexes); + try { + return super.execute(sql, columnIndexes); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public boolean execute(String sql, String columnNames[]) throws SQLException { throwIfClosed(); - return super.execute(sql, columnNames); + try { + return super.execute(sql, columnNames); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public int getResultSetHoldability() throws SQLException { throwIfClosed(); - return super.getResultSetHoldability(); + try { + return super.getResultSetHoldability(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public void setPoolable(boolean poolable) throws SQLException { throwIfClosed(); - super.setPoolable(poolable); + try { + super.setPoolable(poolable); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override public boolean isPoolable() throws SQLException { throwIfClosed(); - return super.isPoolable(); + try { + return super.isPoolable(); + } + catch (UnsupportedOperationException e) { + throw new SQLFeatureNotSupportedException(e.getMessage(), e); + } } @Override diff --git a/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2769UnsupportedReportsUseSqlExceptionTest.java b/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2769UnsupportedReportsUseSqlExceptionTest.java new file mode 100644 index 00000000000..a673d870c45 --- /dev/null +++ b/exec/jdbc/src/test/java/org/apache/drill/jdbc/test/Drill2769UnsupportedReportsUseSqlExceptionTest.java @@ -0,0 +1,459 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.drill.jdbc.test; + +import static org.junit.Assert.*; +import static org.hamcrest.CoreMatchers.*; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.slf4j.Logger; + +import static org.slf4j.LoggerFactory.getLogger; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.sql.Array; +import java.sql.CallableStatement; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLClientInfoException; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Struct; +import java.util.ArrayList; +import java.util.List; + +import org.apache.drill.common.util.TestTools; +import org.apache.drill.jdbc.Driver; +import org.apache.drill.jdbc.JdbcTestBase; +import org.apache.drill.jdbc.AlreadyClosedSqlException; + + +/** + * Test that non-SQLException exceptions used by Drill's current version of + * Avatica to indicate unsupported features are wrapped in or mapped to + * SQLException exceptions. + * + *

+ * As of 2015-08-24, Drill's version of Avatica used non-SQLException exception + * class to report that methods/features were not implemented. + *

+ *
+ *   5 UnsupportedOperationException in ArrayImpl
+ *  29 UnsupportedOperationException in AvaticaConnection
+ *  10 Helper.todo() (RuntimeException) in AvaticaDatabaseMetaData
+ *  21 UnsupportedOperationException in AvaticaStatement
+ *   4 UnsupportedOperationException in AvaticaPreparedStatement
+ * 103 UnsupportedOperationException in AvaticaResultSet
+ * 
+ */ +public class Drill2769UnsupportedReportsUseSqlExceptionTest extends JdbcTestBase { + private static final Logger logger = + getLogger(Drill2769UnsupportedReportsUseSqlExceptionTest.class); + + @Rule + public TestRule TIMEOUT = TestTools.getTimeoutRule(180_000 /* ms */); + + private static Connection connection; + private static Statement plainStatement; + private static PreparedStatement preparedStatement; + // No CallableStatement. + private static ResultSet resultSet; + private static ResultSetMetaData resultSetMetaData; + private static DatabaseMetaData databaseMetaData; + + + @BeforeClass + public static void setUpObjects() throws Exception { + // (Note: Can't use JdbcTest's connect(...) for this test class.) + + connection = new Driver().connect("jdbc:drill:zk=local", + JdbcAssert.getDefaultProperties()); + + plainStatement = connection.createStatement(); + preparedStatement = + connection.prepareStatement("VALUES 'PreparedStatement query'"); + + try { + connection.prepareCall("VALUES 'CallableStatement query'"); + fail("Test seems to be out of date. Was prepareCall(...) implemented?"); + } + catch (SQLException | UnsupportedOperationException e) { + // Expected. + } + try { + connection.createArrayOf("INTEGER", new Object[0]); + fail("Test seems to be out of date. Were arrays implemented?"); + } + catch (SQLException | UnsupportedOperationException e) { + // Expected. + } + + resultSet = plainStatement.executeQuery("VALUES 'plain Statement query'"); + resultSet.next(); + + resultSetMetaData = resultSet.getMetaData(); + databaseMetaData = connection.getMetaData(); + + + // Self-check that member variables are set: + assertFalse("Test setup error", connection.isClosed()); + assertFalse("Test setup error", plainStatement.isClosed()); + assertFalse("Test setup error", preparedStatement.isClosed()); + assertFalse("Test setup error", resultSet.isClosed()); + // (No ResultSetMetaData.isClosed() or DatabaseMetaData.isClosed():) + assertNotNull("Test setup error", resultSetMetaData); + assertNotNull("Test setup error", databaseMetaData); + } + + @AfterClass + public static void tearDownConnection() throws Exception { + connection.close(); + } + + + /** + * Reflection-based checker that exceptions thrown by JDBC interfaces' + * implementation methods for unsupported-operation cases are SQLExceptions + * (not UnsupportedOperationExceptions). + * + * @param JDBC interface type + */ + private static class NoNonSqlExceptionsChecker { + private final Class jdbcIntf; + private final INTF jdbcObject; + + private final StringBuilder failureLinesBuf = new StringBuilder(); + private final StringBuilder successLinesBuf = new StringBuilder(); + + + NoNonSqlExceptionsChecker(final Class jdbcIntf, + final INTF jdbcObject) { + this.jdbcIntf = jdbcIntf; + this.jdbcObject = jdbcObject; + } + + /** + * Hook/factory method to allow context to provide fresh object for each + * method. Needed for Statement and PrepareStatement, whose execute... + * methods can close the statement (at least given our minimal dummy + * argument values). + */ + protected INTF getJdbcObject() throws SQLException { + return jdbcObject; + } + + /** + * Gets minimal value suitable for use as actual parameter value for given + * formal parameter type. + */ + private static Object getDummyValueForType(Class type) { + final Object result; + if (! type.isPrimitive()) { + result = null; + } + else { + if (type == boolean.class) { + result = false; + } + else if (type == byte.class) { + result = (byte) 0; + } + else if (type == short.class) { + result = (short) 0; + } + else if (type == int.class) { + result = 0; + } + else if (type == long.class) { + result = (long) 0L; + } + else if (type == float.class) { + result = 0F; + } + else if (type == double.class) { + result = 0.0; + } + else { + fail("Test needs to be updated to handle type " + type); + result = null; // Not executed; for "final". + } + } + return result; + } + + /** + * Assembles method signature text for given method. + */ + private String makeLabel(Method method) { + String methodLabel; + methodLabel = jdbcIntf.getSimpleName() + "." + method.getName() + "("; + boolean first = true; + for (Class paramType : method.getParameterTypes()) { + if (! first) { + methodLabel += ", "; + } + first = false; + methodLabel += paramType.getSimpleName(); + } + methodLabel += ")"; + return methodLabel; + } + + /** + * Assembles (minimal) arguments array for given method. + */ + private Object[] makeArgs(Method method) { + final List argsList = new ArrayList<>(); + for (Class paramType : method.getParameterTypes()) { + argsList.add(getDummyValueForType(paramType)); + } + Object[] argsArray = argsList.toArray(); + return argsArray; + } + + /** + * Tests one method. + * (Disturbs members set by makeArgsAndLabel, but those shouldn't be used + * except by this method.) + */ + private void testOneMethod(Method method) { + final String methodLabel = makeLabel(method); + + try { + final INTF jdbcObject; + try { + jdbcObject = getJdbcObject(); + } catch (SQLException e) { + fail("Unexpected exception: " + e + " from getJdbcObject()"); + throw new RuntimeException("DUMMY; so compiler know block throws"); + } + + // See if method throws exception: + method.invoke(jdbcObject, makeArgs(method)); + + // If here, method didn't throw--check if it's an expected non-throwing + // method (e.g., an isClosed). (If not, report error.) + final String resultLine = "- " + methodLabel + " didn't throw\n"; + + successLinesBuf.append(resultLine); + } + catch (InvocationTargetException wrapperEx) { + final Throwable cause = wrapperEx.getCause(); + final String resultLine = "- " + methodLabel + " threw <" + cause + ">\n"; + + if (SQLException.class.isAssignableFrom(cause.getClass()) + && + ! AlreadyClosedSqlException.class.isAssignableFrom(cause.getClass()) + ) { + // Good case--almost any exception should be SQLException or subclass + // (but make sure not accidentally closed). + successLinesBuf.append(resultLine); + } + else if (NullPointerException.class == cause.getClass() + && (method.getName().equals("isWrapperFor") + || method.getName().equals("unwrap"))) { + // Known good-enough case--these methods throw NullPointerException + // because of the way we call them (with null) and the way Avatica + // code implements them. + successLinesBuf.append(resultLine); + } + else { + final String badResultLine = + "- " + methodLabel + " threw <" + cause + "> instead" + + " of a " + SQLException.class.getSimpleName() + "\n"; + logger.trace("Failure: " + resultLine); + failureLinesBuf.append(badResultLine); + } + } + catch (IllegalAccessException | IllegalArgumentException e) { + fail("Unexpected exception: " + e + ", cause = " + e.getCause() + + " from " + method); + } + } + + public void testMethods() { + for (Method method : jdbcIntf.getMethods()) { + final String methodLabel = makeLabel(method); + if ("close".equals(method.getName())) { + logger.debug("Skipping (because closes): " + methodLabel); + } + /* Uncomment to suppress calling DatabaseMetaData.getColumns(...), which + sometimes takes about 2 minutes, and other DatabaseMetaData methods + that query, collectively taking a while too: + else if (DatabaseMetaData.class == jdbcIntf + && "getColumns".equals(method.getName())) { + logger.debug("Skipping (because really slow): " + methodLabel); + } + else if (DatabaseMetaData.class == jdbcIntf + && ResultSet.class == method.getReturnType()) { + logger.debug("Skipping (because a bit slow): " + methodLabel); + } + */ + else { + logger.debug("Testing method " + methodLabel); + testOneMethod(method); + } + } + } + + public boolean hadAnyFailures() { + return 0 != failureLinesBuf.length(); + } + + public String getFailureLines() { + return failureLinesBuf.toString(); + } + + public String getSuccessLines() { + return successLinesBuf.toString(); + } + + public String getReport() { + final String report = + "Failures:\n" + + getFailureLines() + + "(Successes:\n" + + getSuccessLines() + + ")"; + return report; + } + + } // class NoNonSqlExceptionsChecker + + + @Test + public void testConnectionMethodsThrowRight() { + NoNonSqlExceptionsChecker checker = + new NoNonSqlExceptionsChecker(Connection.class, connection); + + checker.testMethods(); + + if (checker.hadAnyFailures()) { + System.err.println(checker.getReport()); + fail("Non-SQLException exception error(s): \n" + checker.getReport()); + } + } + + + private static class PlainStatementChecker + extends NoNonSqlExceptionsChecker { + + private final Connection factoryConnection; + + PlainStatementChecker(Connection factoryConnection) { + super(Statement.class, null); + this.factoryConnection = factoryConnection; + } + + protected Statement getJdbcObject() throws SQLException { + return factoryConnection.createStatement(); + } + + } // class PlainStatementChecker + + @Test + public void testPlainStatementMethodsThrowRight() { + NoNonSqlExceptionsChecker checker = + new PlainStatementChecker(connection); + + checker.testMethods(); + + if (checker.hadAnyFailures()) { + fail("Non-SQLException exception error(s): \n" + checker.getReport()); + } + } + + + private static class PreparedStatementChecker + extends NoNonSqlExceptionsChecker { + + private final Connection factoryConnection; + + PreparedStatementChecker(Connection factoryConnection) { + super(PreparedStatement.class, null); + this.factoryConnection = factoryConnection; + } + + protected PreparedStatement getJdbcObject() throws SQLException { + return factoryConnection.prepareStatement(null); + } + + } // class PlainStatementChecker + + @Test + public void testPreparedStatementMethodsThrowRight() { + NoNonSqlExceptionsChecker checker = + new PreparedStatementChecker(connection); + + checker.testMethods(); + + if (checker.hadAnyFailures()) { + fail("Non-SQLException exception error(s): \n" + checker.getReport()); + } + } + + + @Test + public void testResultSetMethodsThrowRight() { + NoNonSqlExceptionsChecker checker = + new NoNonSqlExceptionsChecker(ResultSet.class, resultSet); + + checker.testMethods(); + + if (checker.hadAnyFailures()) { + fail("Non-SQLException exception error(s): \n" + checker.getReport()); + } + } + + + @Test + public void testResultSetMetaDataMethodsThrowRight() { + NoNonSqlExceptionsChecker checker = + new NoNonSqlExceptionsChecker(ResultSetMetaData.class, + resultSetMetaData); + + checker.testMethods(); + + if (checker.hadAnyFailures()) { + fail("Non-SQLException exception error(s): \n" + checker.getReport()); + } + } + + + @Test + public void testDatabaseMetaDataMethodsThrowRight() { + NoNonSqlExceptionsChecker checker = + new NoNonSqlExceptionsChecker(DatabaseMetaData.class, + databaseMetaData); + + checker.testMethods(); + + if (checker.hadAnyFailures()) { + fail("Non-SQLException exception error(s): \n" + checker.getReport()); + } + } + +}