IGNITE-5620: Implemented SQLSTATE error code for server-side logic and JDBC thin client. This closes #2541.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/7c4d0bc2 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/7c4d0bc2 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/7c4d0bc2 Branch: refs/heads/ignite-6149 Commit: 7c4d0bc2a84cfcc9c240f41c48aa129b5f60eca0 Parents: 9fd8221 Author: Alexander Paschenko <[email protected]> Authored: Sat Sep 16 17:41:34 2017 +0300 Committer: devozerov <[email protected]> Committed: Sat Sep 16 17:41:34 2017 +0300 ---------------------------------------------------------------------- .../jdbc2/JdbcDynamicIndexAbstractSelfTest.java | 39 +- .../jdbc2/JdbcInsertStatementSelfTest.java | 9 +- .../ignite/jdbc/JdbcErrorsAbstractSelfTest.java | 158 +++++++ .../jdbc/suite/IgniteJdbcDriverTestSuite.java | 2 + .../jdbc/thin/JdbcThinConnectionSelfTest.java | 2 +- .../JdbcThinDynamicIndexAbstractSelfTest.java | 4 +- .../jdbc/thin/JdbcThinErrorsSelfTest.java | 467 +++++++++++++++++++ .../thin/JdbcThinInsertStatementSelfTest.java | 2 +- .../jdbc/thin/JdbcThinNoDefaultSchemaTest.java | 2 +- .../jdbc/thin/JdbcThinResultSetSelfTest.java | 2 +- .../internal/jdbc/thin/JdbcThinConnection.java | 67 ++- .../jdbc/thin/JdbcThinDatabaseMetadata.java | 142 ++---- .../jdbc/thin/JdbcThinPreparedStatement.java | 54 +-- .../internal/jdbc/thin/JdbcThinResultSet.java | 111 ++--- .../internal/jdbc/thin/JdbcThinStatement.java | 39 +- .../internal/jdbc/thin/JdbcThinTcpIo.java | 234 +++------- .../cache/query/IgniteQueryErrorCode.java | 48 +- .../internal/processors/odbc/SqlStateCode.java | 69 +++ .../odbc/jdbc/JdbcRequestHandler.java | 74 ++- .../processors/query/IgniteSQLException.java | 84 +++- .../query/h2/DmlStatementsProcessor.java | 79 ++-- .../query/h2/sql/GridSqlQueryParser.java | 35 +- .../query/h2/sql/GridQueryParsingTest.java | 2 +- 23 files changed, 1178 insertions(+), 547 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/7c4d0bc2/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcDynamicIndexAbstractSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcDynamicIndexAbstractSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcDynamicIndexAbstractSelfTest.java index 7bbda6f..9485d0d 100644 --- a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcDynamicIndexAbstractSelfTest.java +++ b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcDynamicIndexAbstractSelfTest.java @@ -23,7 +23,6 @@ import java.sql.SQLException; import java.sql.Statement; import java.util.Collections; import java.util.List; -import javax.cache.CacheException; import org.apache.ignite.IgniteCache; import org.apache.ignite.cache.CacheAtomicityMode; import org.apache.ignite.cache.CacheMode; @@ -31,8 +30,6 @@ import org.apache.ignite.cache.CacheWriteSynchronizationMode; import org.apache.ignite.cache.query.SqlFieldsQuery; import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.configuration.NearCacheConfiguration; -import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode; -import org.apache.ignite.internal.processors.query.IgniteSQLException; import org.apache.ignite.internal.util.typedef.F; /** @@ -176,7 +173,7 @@ public abstract class JdbcDynamicIndexAbstractSelfTest extends JdbcAbstractDmlSt @Override public void run() throws Exception { jdbcRun(CREATE_INDEX); } - }, IgniteQueryErrorCode.INDEX_ALREADY_EXISTS); + }); } /** @@ -227,7 +224,7 @@ public abstract class JdbcDynamicIndexAbstractSelfTest extends JdbcAbstractDmlSt @Override public void run() throws Exception { jdbcRun(DROP_INDEX); } - }, IgniteQueryErrorCode.INDEX_NOT_FOUND); + }); } /** @@ -312,45 +309,21 @@ public abstract class JdbcDynamicIndexAbstractSelfTest extends JdbcAbstractDmlSt * Ensure that SQL exception is thrown. * * @param r Runnable. - * @param expCode Error code. */ - private static void assertSqlException(RunnableX r, int expCode) { + private static void assertSqlException(RunnableX r) { // We expect IgniteSQLException with given code inside CacheException inside JDBC SQLException. try { r.run(); } - catch (SQLException ex) { - if (ex.getCause() != null) { - try { - throw ex.getCause(); - } - catch (CacheException ex1) { - if (ex1.getCause() != null) { - try { - throw ex1.getCause(); - } - catch (IgniteSQLException e) { - assertEquals("Unexpected error code [expected=" + expCode + ", actual=" + e.statusCode() + ']', - expCode, e.statusCode()); - - return; - } - catch (Throwable t) { - fail("Unexpected exception: " + t); - } - } - } - catch (Throwable t) { - fail("Unexpected exception: " + t); - } - } + catch (SQLException e) { + return; } catch (Exception e) { fail("Unexpected exception: " + e); } - fail(IgniteSQLException.class.getSimpleName() + " is not thrown."); + fail(SQLException.class.getSimpleName() + " is not thrown."); } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/7c4d0bc2/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcInsertStatementSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcInsertStatementSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcInsertStatementSelfTest.java index 407d6e2..44a45b7 100644 --- a/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcInsertStatementSelfTest.java +++ b/modules/clients/src/test/java/org/apache/ignite/internal/jdbc2/JdbcInsertStatementSelfTest.java @@ -164,15 +164,12 @@ public class JdbcInsertStatementSelfTest extends JdbcAbstractDmlStatementSelfTes } }, SQLException.class, null); - assertNotNull(reason.getCause()); - - reason = reason.getCause().getCause(); + reason = reason.getCause(); assertNotNull(reason); - assertEquals(IgniteSQLException.class, reason.getClass()); - - assertEquals("Failed to INSERT some keys because they are already in cache [keys=[p2]]", reason.getMessage()); + assertTrue(reason.getMessage().contains( + "Failed to INSERT some keys because they are already in cache [keys=[p2]]")); assertEquals(3, jcache(0).withKeepBinary().getAll(new HashSet<>(Arrays.asList("p1", "p2", "p3"))).size()); } http://git-wip-us.apache.org/repos/asf/ignite/blob/7c4d0bc2/modules/clients/src/test/java/org/apache/ignite/jdbc/JdbcErrorsAbstractSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/JdbcErrorsAbstractSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/JdbcErrorsAbstractSelfTest.java new file mode 100644 index 0000000..f600e73 --- /dev/null +++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/JdbcErrorsAbstractSelfTest.java @@ -0,0 +1,158 @@ +/* + * 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.ignite.jdbc; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.Collections; +import org.apache.ignite.cache.QueryEntity; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.lang.IgniteCallable; +import org.apache.ignite.testframework.GridTestUtils; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; + +/** + * Test SQLSTATE codes propagation with (any) Ignite JDBC driver. + */ +public abstract class JdbcErrorsAbstractSelfTest extends GridCommonAbstractTest { + /** {@inheritDoc} */ + @Override protected void beforeTestsStarted() throws Exception { + super.beforeTestsStarted(); + + startGrid(getConfiguration(getTestIgniteInstanceName(0)) + .setCacheConfiguration(new CacheConfiguration("test") + .setQueryEntities(Collections.singletonList(new QueryEntity(Integer.class, Integer.class))))); + } + + /** {@inheritDoc} */ + @Override protected void afterTestsStopped() throws Exception { + stopAllGrids(); + + super.afterTestsStopped(); + } + + /** + * Test that H2 specific error codes get propagated to Ignite SQL exceptions. + * @throws SQLException if failed. + */ + public void testParsingErrors() throws SQLException { + checkErrorState("gibberish", "42000"); + } + + /** + * Test that error codes from tables related DDL operations get propagated to Ignite SQL exceptions. + * @throws SQLException if failed. + */ + public void testTableErrors() throws SQLException { + checkErrorState("DROP TABLE \"PUBLIC\".missing", "42000"); + } + + /** + * Test that error codes from indexes related DDL operations get propagated to Ignite SQL exceptions. + * @throws SQLException if failed. + */ + public void testIndexErrors() throws SQLException { + checkErrorState("DROP INDEX \"PUBLIC\".missing", "42000"); + } + + /** + * Test that error codes from DML operations get propagated to Ignite SQL exceptions. + * @throws SQLException if failed. + */ + public void testDmlErrors() throws SQLException { + checkErrorState("INSERT INTO \"test\".INTEGER(_key, _val) values(1, null)", "22004"); + + checkErrorState("INSERT INTO \"test\".INTEGER(_key, _val) values(1, 'zzz')", "50000"); + } + + /** + * Test error code for the case when user attempts to refer a future currently unsupported. + * @throws SQLException if failed. + */ + public void testUnsupportedSql() throws SQLException { + checkErrorState("ALTER TABLE \"test\".Integer DROP COLUMN _key", "0A000"); + } + + /** + * @return Connection to execute statements on. + * @throws SQLException if failed. + */ + protected abstract Connection getConnection() throws SQLException; + + /** + * Test that running given SQL statement yields expected SQLSTATE code. + * @param sql statement. + * @param expState expected SQLSTATE code. + * @throws SQLException if failed. + */ + @SuppressWarnings("ThrowableResultOfMethodCallIgnored") + private void checkErrorState(final String sql, String expState) throws SQLException { + checkErrorState(new ConnClosure() { + @Override public void run(Connection conn) throws Exception { + try (final PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.execute(); + } + } + }, expState); + } + + /** + * Test that running given closure yields expected SQLSTATE code. + * @param clo closure. + * @param expState expected SQLSTATE code. + * @throws SQLException if failed. + */ + @SuppressWarnings("ThrowableResultOfMethodCallIgnored") + protected void checkErrorState(final ConnClosure clo, String expState) throws SQLException { + checkErrorState(new IgniteCallable<Void>() { + @Override public Void call() throws Exception { + try (final Connection conn = getConnection()) { + clo.run(conn); + + fail(); + + return null; + } + } + }, expState); + } + + /** + * Test that running given closure yields expected SQLSTATE code. + * @param clo closure. + * @param expState expected SQLSTATE code. + * @throws SQLException if failed. + */ + @SuppressWarnings("ThrowableResultOfMethodCallIgnored") + protected void checkErrorState(final IgniteCallable<Void> clo, String expState) throws SQLException { + SQLException ex = (SQLException)GridTestUtils.assertThrows(null, clo, SQLException.class, null); + + assertEquals(expState, ex.getSQLState()); + } + + /** + * Runnable that accepts a {@link Connection} and can throw an exception. + */ + protected interface ConnClosure { + /** + * @throws Exception On error. + */ + void run(Connection conn) throws Exception; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/7c4d0bc2/modules/clients/src/test/java/org/apache/ignite/jdbc/suite/IgniteJdbcDriverTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/suite/IgniteJdbcDriverTestSuite.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/suite/IgniteJdbcDriverTestSuite.java index c2ac6cb..424ec21 100644 --- a/modules/clients/src/test/java/org/apache/ignite/jdbc/suite/IgniteJdbcDriverTestSuite.java +++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/suite/IgniteJdbcDriverTestSuite.java @@ -46,6 +46,7 @@ import org.apache.ignite.jdbc.thin.JdbcThinDynamicIndexTransactionalPartitionedN import org.apache.ignite.jdbc.thin.JdbcThinDynamicIndexTransactionalPartitionedSelfTest; import org.apache.ignite.jdbc.thin.JdbcThinDynamicIndexTransactionalReplicatedSelfTest; import org.apache.ignite.jdbc.thin.JdbcThinEmptyCacheSelfTest; +import org.apache.ignite.jdbc.thin.JdbcThinErrorsSelfTest; import org.apache.ignite.jdbc.thin.JdbcThinInsertStatementSelfTest; import org.apache.ignite.jdbc.thin.JdbcThinMergeStatementSelfTest; import org.apache.ignite.jdbc.thin.JdbcThinMetadataSelfTest; @@ -124,6 +125,7 @@ public class IgniteJdbcDriverTestSuite extends TestSuite { suite.addTest(new TestSuite(JdbcThinNoDefaultSchemaTest.class)); suite.addTest(new TestSuite(JdbcThinEmptyCacheSelfTest.class)); suite.addTest(new TestSuite(JdbcThinMetadataSelfTest.class)); + suite.addTest(new TestSuite(JdbcThinErrorsSelfTest.class)); suite.addTest(new TestSuite(JdbcThinInsertStatementSelfTest.class)); suite.addTest(new TestSuite(JdbcThinUpdateStatementSelfTest.class)); http://git-wip-us.apache.org/repos/asf/ignite/blob/7c4d0bc2/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionSelfTest.java index 9bf6282..95068c5 100644 --- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionSelfTest.java +++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinConnectionSelfTest.java @@ -346,7 +346,7 @@ public class JdbcThinConnectionSelfTest extends JdbcThinAbstractSelfTest { private static JdbcThinTcpIo io(Connection conn) throws Exception { JdbcThinConnection conn0 = conn.unwrap(JdbcThinConnection.class); - return conn0.io(); + return GridTestUtils.getFieldValue(conn0, JdbcThinConnection.class, "cliIo"); } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/7c4d0bc2/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinDynamicIndexAbstractSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinDynamicIndexAbstractSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinDynamicIndexAbstractSelfTest.java index 3f762fc..5089894 100644 --- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinDynamicIndexAbstractSelfTest.java +++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinDynamicIndexAbstractSelfTest.java @@ -183,7 +183,7 @@ public abstract class JdbcThinDynamicIndexAbstractSelfTest extends JdbcThinAbstr return null; } - }, IgniteCheckedException.class, "Index already exists: IDX"); + }, SQLException.class, "Index already exists: IDX"); } /** @@ -237,7 +237,7 @@ public abstract class JdbcThinDynamicIndexAbstractSelfTest extends JdbcThinAbstr return null; } - }, IgniteCheckedException.class, "Index doesn't exist: IDX"); + }, SQLException.class, "Index doesn't exist: IDX"); } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/7c4d0bc2/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinErrorsSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinErrorsSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinErrorsSelfTest.java new file mode 100644 index 0000000..706be27 --- /dev/null +++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinErrorsSelfTest.java @@ -0,0 +1,467 @@ +/* + * 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.ignite.jdbc.thin; + +import java.net.URL; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.Date; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.List; +import org.apache.ignite.jdbc.JdbcErrorsAbstractSelfTest; +import org.apache.ignite.lang.IgniteCallable; + +/** + * Test SQLSTATE codes propagation with thin client driver. + */ +public class JdbcThinErrorsSelfTest extends JdbcErrorsAbstractSelfTest { + /** {@inheritDoc} */ + @Override protected Connection getConnection() throws SQLException { + return DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1"); + } + + /** + * Test error code for the case when connection string is fine but client can't reach server + * due to <b>communication problems</b> (not due to clear misconfiguration). + * @throws SQLException if failed. + */ + public void testConnectionError() throws SQLException { + checkErrorState(new IgniteCallable<Void>() { + @Override public Void call() throws Exception { + DriverManager.getConnection("jdbc:ignite:thin://unknown.host"); + + return null; + } + }, "08001"); + } + + /** + * Test error code for the case when connection string is a mess. + * @throws SQLException if failed. + */ + public void testInvalidConnectionStringFormat() throws SQLException { + checkErrorState(new IgniteCallable<Void>() { + @Override public Void call() throws Exception { + // Invalid port number yields an error. + DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1:1000000"); + + return null; + } + }, "08001"); + } + + /* ALL TESTS PAST THIS POINT MUST BE MOVED TO PARENT CLASS JdbcErrorsAbstractSelfTest + * ONCE ERROR CODES RELATED WORK ON JDBC2 DRIVER IS FINISHED */ + + /** + * Test error code for the case when user attempts to use a closed connection. + * @throws SQLException if failed. + */ + public void testConnectionClosed() throws SQLException { + checkErrorState(new IgniteCallable<Void>() { + @Override public Void call() throws Exception { + Connection conn = getConnection(); + + conn.close(); + + conn.prepareStatement("SELECT 1"); + + return null; + } + }, "08003"); + + checkErrorState(new IgniteCallable<Void>() { + @Override public Void call() throws Exception { + Connection conn = getConnection(); + + conn.close(); + + conn.createStatement(); + + return null; + } + }, "08003"); + + checkErrorState(new IgniteCallable<Void>() { + @Override public Void call() throws Exception { + Connection conn = getConnection(); + + conn.close(); + + conn.getMetaData(); + + return null; + } + }, "08003"); + + checkErrorState(new IgniteCallable<Void>() { + @Override public Void call() throws Exception { + Connection conn = getConnection(); + + DatabaseMetaData meta = conn.getMetaData(); + + conn.close(); + + meta.getIndexInfo(null, null, null, false, false); + + return null; + } + }, "08003"); + + checkErrorState(new IgniteCallable<Void>() { + @Override public Void call() throws Exception { + Connection conn = getConnection(); + + DatabaseMetaData meta = conn.getMetaData(); + + conn.close(); + + meta.getColumns(null, null, null, null); + + return null; + } + }, "08003"); + + checkErrorState(new IgniteCallable<Void>() { + @Override public Void call() throws Exception { + Connection conn = getConnection(); + + DatabaseMetaData meta = conn.getMetaData(); + + conn.close(); + + meta.getPrimaryKeys(null, null, null); + + return null; + } + }, "08003"); + + checkErrorState(new IgniteCallable<Void>() { + @Override public Void call() throws Exception { + Connection conn = getConnection(); + + DatabaseMetaData meta = conn.getMetaData(); + + conn.close(); + + meta.getSchemas(null, null); + + return null; + } + }, "08003"); + + checkErrorState(new IgniteCallable<Void>() { + @Override public Void call() throws Exception { + Connection conn = getConnection(); + + DatabaseMetaData meta = conn.getMetaData(); + + conn.close(); + + meta.getTables(null, null, null, null); + + return null; + } + }, "08003"); + } + + /** + * Test error code for the case when user attempts to use a closed result set. + * @throws SQLException if failed. + */ + public void testResultSetClosed() throws SQLException { + checkErrorState(new ConnClosure() { + @Override public void run(Connection conn) throws Exception { + try (PreparedStatement stmt = conn.prepareStatement("SELECT 1")) { + ResultSet rs = stmt.executeQuery(); + + rs.next(); + + rs.close(); + + rs.getInt(1); + } + } + }, "24000"); + } + + /** + * Test error code for the case when user attempts to set an invalid isolation level to a connection. + * @throws SQLException if failed. + */ + @SuppressWarnings("MagicConstant") + public void testInvalidIsolationLevel() throws SQLException { + checkErrorState(new ConnClosure() { + @Override public void run(Connection conn) throws Exception { + conn.setTransactionIsolation(1000); + } + }, "0700E"); + } + + /** + * Test error code for the case when user attempts to get {@code int} value + * from column whose value can't be converted to an {@code int}. + * @throws SQLException if failed. + */ + public void testInvalidIntFormat() throws SQLException { + checkErrorState(new ConnClosure() { + @Override public void run(Connection conn) throws Exception { + try (PreparedStatement stmt = conn.prepareStatement("SELECT 'zzz'")) { + ResultSet rs = stmt.executeQuery(); + + rs.next(); + + rs.getLong(1); + } + } + }, "0700B"); + } + + /** + * Test error code for the case when user attempts to get {@code long} value + * from column whose value can't be converted to an {@code long}. + * @throws SQLException if failed. + */ + public void testInvalidLongFormat() throws SQLException { + checkErrorState(new ConnClosure() { + @Override public void run(Connection conn) throws Exception { + try (PreparedStatement stmt = conn.prepareStatement("SELECT 'zzz'")) { + ResultSet rs = stmt.executeQuery(); + + rs.next(); + + rs.getLong(1); + } + } + }, "0700B"); + } + + /** + * Test error code for the case when user attempts to get {@code float} value + * from column whose value can't be converted to an {@code float}. + * @throws SQLException if failed. + */ + public void testInvalidFloatFormat() throws SQLException { + checkErrorState(new ConnClosure() { + @Override public void run(Connection conn) throws Exception { + try (PreparedStatement stmt = conn.prepareStatement("SELECT 'zzz'")) { + ResultSet rs = stmt.executeQuery(); + + rs.next(); + + rs.getFloat(1); + } + } + }, "0700B"); + } + + /** + * Test error code for the case when user attempts to get {@code double} value + * from column whose value can't be converted to an {@code double}. + * @throws SQLException if failed. + */ + public void testInvalidDoubleFormat() throws SQLException { + checkErrorState(new ConnClosure() { + @Override public void run(Connection conn) throws Exception { + try (PreparedStatement stmt = conn.prepareStatement("SELECT 'zzz'")) { + ResultSet rs = stmt.executeQuery(); + + rs.next(); + + rs.getDouble(1); + } + } + }, "0700B"); + } + + /** + * Test error code for the case when user attempts to get {@code byte} value + * from column whose value can't be converted to an {@code byte}. + * @throws SQLException if failed. + */ + public void testInvalidByteFormat() throws SQLException { + checkErrorState(new ConnClosure() { + @Override public void run(Connection conn) throws Exception { + try (PreparedStatement stmt = conn.prepareStatement("SELECT 'zzz'")) { + ResultSet rs = stmt.executeQuery(); + + rs.next(); + + rs.getByte(1); + } + } + }, "0700B"); + } + + /** + * Test error code for the case when user attempts to get {@code short} value + * from column whose value can't be converted to an {@code short}. + * @throws SQLException if failed. + */ + public void testInvalidShortFormat() throws SQLException { + checkErrorState(new ConnClosure() { + @Override public void run(Connection conn) throws Exception { + try (PreparedStatement stmt = conn.prepareStatement("SELECT 'zzz'")) { + ResultSet rs = stmt.executeQuery(); + + rs.next(); + + rs.getShort(1); + } + } + }, "0700B"); + } + + /** + * Test error code for the case when user attempts to get {@code BigDecimal} value + * from column whose value can't be converted to an {@code BigDecimal}. + * @throws SQLException if failed. + */ + public void testInvalidBigDecimalFormat() throws SQLException { + checkErrorState(new ConnClosure() { + @Override public void run(Connection conn) throws Exception { + try (PreparedStatement stmt = conn.prepareStatement("SELECT 'zzz'")) { + ResultSet rs = stmt.executeQuery(); + + rs.next(); + + rs.getBigDecimal(1); + } + } + }, "0700B"); + } + + /** + * Test error code for the case when user attempts to get {@code boolean} value + * from column whose value can't be converted to an {@code boolean}. + * @throws SQLException if failed. + */ + public void testInvalidBooleanFormat() throws SQLException { + checkErrorState(new ConnClosure() { + @Override public void run(Connection conn) throws Exception { + try (PreparedStatement stmt = conn.prepareStatement("SELECT 'zzz'")) { + ResultSet rs = stmt.executeQuery(); + + rs.next(); + + rs.getBoolean(1); + } + } + }, "0700B"); + } + + /** + * Test error code for the case when user attempts to get {@code boolean} value + * from column whose value can't be converted to an {@code boolean}. + * @throws SQLException if failed. + */ + public void testInvalidObjectFormat() throws SQLException { + checkErrorState(new ConnClosure() { + @Override public void run(Connection conn) throws Exception { + try (PreparedStatement stmt = conn.prepareStatement("SELECT 'zzz'")) { + ResultSet rs = stmt.executeQuery(); + + rs.next(); + + rs.getObject(1, List.class); + } + } + }, "0700B"); + } + + /** + * Test error code for the case when user attempts to get {@link Date} value + * from column whose value can't be converted to a {@link Date}. + * @throws SQLException if failed. + */ + public void testInvalidDateFormat() throws SQLException { + checkErrorState(new ConnClosure() { + @Override public void run(Connection conn) throws Exception { + try (PreparedStatement stmt = conn.prepareStatement("SELECT 'zzz'")) { + ResultSet rs = stmt.executeQuery(); + + rs.next(); + + rs.getDate(1); + } + } + }, "0700B"); + } + + /** + * Test error code for the case when user attempts to get {@link Time} value + * from column whose value can't be converted to a {@link Time}. + * @throws SQLException if failed. + */ + public void testInvalidTimeFormat() throws SQLException { + checkErrorState(new ConnClosure() { + @Override public void run(Connection conn) throws Exception { + try (PreparedStatement stmt = conn.prepareStatement("SELECT 'zzz'")) { + ResultSet rs = stmt.executeQuery(); + + rs.next(); + + rs.getTime(1); + } + } + }, "0700B"); + } + + /** + * Test error code for the case when user attempts to get {@link Timestamp} value + * from column whose value can't be converted to a {@link Timestamp}. + * @throws SQLException if failed. + */ + public void testInvalidTimestampFormat() throws SQLException { + checkErrorState(new ConnClosure() { + @Override public void run(Connection conn) throws Exception { + try (PreparedStatement stmt = conn.prepareStatement("SELECT 'zzz'")) { + ResultSet rs = stmt.executeQuery(); + + rs.next(); + + rs.getTimestamp(1); + } + } + }, "0700B"); + } + + /** + * Test error code for the case when user attempts to get {@link URL} value + * from column whose value can't be converted to a {@link URL}. + * @throws SQLException if failed. + */ + public void testInvalidUrlFormat() throws SQLException { + checkErrorState(new ConnClosure() { + @Override public void run(Connection conn) throws Exception { + try (PreparedStatement stmt = conn.prepareStatement("SELECT 'zzz'")) { + ResultSet rs = stmt.executeQuery(); + + rs.next(); + + rs.getURL(1); + } + } + }, "0700B"); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/7c4d0bc2/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinInsertStatementSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinInsertStatementSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinInsertStatementSelfTest.java index 3b86757..8ab5760 100644 --- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinInsertStatementSelfTest.java +++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinInsertStatementSelfTest.java @@ -177,7 +177,7 @@ public class JdbcThinInsertStatementSelfTest extends JdbcThinAbstractDmlStatemen @Override public Object call() throws Exception { return stmt.execute(SQL); } - }, IgniteCheckedException.class, + }, SQLException.class, "Failed to INSERT some keys because they are already in cache [keys=[p2]]"); assertEquals(3, jcache(0).withKeepBinary().getAll(new HashSet<>(Arrays.asList("p1", "p2", "p3"))).size()); http://git-wip-us.apache.org/repos/asf/ignite/blob/7c4d0bc2/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinNoDefaultSchemaTest.java ---------------------------------------------------------------------- diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinNoDefaultSchemaTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinNoDefaultSchemaTest.java index 7b226e5..65ebf9a 100644 --- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinNoDefaultSchemaTest.java +++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinNoDefaultSchemaTest.java @@ -217,7 +217,7 @@ public class JdbcThinNoDefaultSchemaTest extends JdbcThinAbstractSelfTest { return null; } - }, SQLException.class, "Failed to query Ignite"); + }, SQLException.class, "Failed to parse query"); conn.setSchema("cache1"); http://git-wip-us.apache.org/repos/asf/ignite/blob/7c4d0bc2/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinResultSetSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinResultSetSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinResultSetSelfTest.java index 76eb5bc..5a3c5df 100644 --- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinResultSetSelfTest.java +++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinResultSetSelfTest.java @@ -695,7 +695,7 @@ public class JdbcThinResultSetSelfTest extends JdbcThinAbstractSelfTest { return null; } - }, IgniteCheckedException.class, "Custom objects are not supported"); + }, SQLException.class, "Custom objects are not supported"); } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/7c4d0bc2/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java index 23235dc..511eba0 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinConnection.java @@ -37,7 +37,14 @@ import java.util.Map; import java.util.Properties; import java.util.concurrent.Executor; import java.util.logging.Logger; +import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode; +import org.apache.ignite.internal.processors.odbc.ClientListenerResponse; +import org.apache.ignite.internal.processors.odbc.SqlStateCode; +import org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest; +import org.apache.ignite.internal.processors.odbc.jdbc.JdbcResponse; +import org.apache.ignite.internal.processors.odbc.jdbc.JdbcResult; import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.lang.IgniteProductVersion; import static java.sql.ResultSet.CLOSE_CURSORS_AT_COMMIT; import static java.sql.ResultSet.CONCUR_READ_ONLY; @@ -138,7 +145,8 @@ public class JdbcThinConnection implements Connection { catch (Exception e) { cliIo.close(); - throw new SQLException("Failed to connect to Ignite node [host=" + host + ", port=" + port + ']', e); + throw new SQLException("Failed to connect to Ignite cluster [host=" + host + ", port=" + port + ']', + SqlStateCode.CLIENT_CONNECTION_FAILED, e); } } @@ -347,7 +355,7 @@ public class JdbcThinConnection implements Connection { break; default: - throw new SQLException("Invalid transaction isolation level."); + throw new SQLException("Invalid transaction isolation level.", SqlStateCode.INVALID_TRANSACTION_LEVEL); } txIsolation = level; @@ -626,16 +634,49 @@ public class JdbcThinConnection implements Connection { * * @throws SQLException If connection is closed. */ - private void ensureNotClosed() throws SQLException { + public void ensureNotClosed() throws SQLException { if (closed) - throw new SQLException("Connection is closed."); + throw new SQLException("Connection is closed.", SqlStateCode.CONNECTION_CLOSED); } /** - * @return Ignite endpoint and I/O protocol. + * @return Ignite server version. */ - public JdbcThinTcpIo io() { - return cliIo; + IgniteProductVersion igniteVersion() { + return cliIo.igniteVersion(); + } + + /** + * @return Auto close server cursors flag. + */ + boolean autoCloseServerCursor() { + return cliIo.autoCloseServerCursor(); + } + + /** + * Send request for execution via {@link #cliIo}. + * @param req Request. + * @return Server response. + * @throws SQLException On any error. + */ + @SuppressWarnings("unchecked") + <R extends JdbcResult> R sendRequest(JdbcRequest req) throws SQLException { + try { + JdbcResponse res = cliIo.sendRequest(req); + + if (res.status() != ClientListenerResponse.STATUS_SUCCESS) + throw new SQLException(res.error(), IgniteQueryErrorCode.codeToSqlState(res.status())); + + return (R)res.response(); + } + catch (SQLException e) { + throw e; + } + catch (Exception e) { + close(); + + throw new SQLException("Failed to communicate with Ignite cluster.", SqlStateCode.CONNECTION_FAILURE, e); + } } /** @@ -652,7 +693,7 @@ public class JdbcThinConnection implements Connection { host = host.trim(); if (F.isEmpty(host)) - throw new SQLException("Host name is empty."); + throw new SQLException("Host name is empty.", SqlStateCode.CLIENT_CONNECTION_FAILED); return host; } @@ -676,10 +717,10 @@ public class JdbcThinConnection implements Connection { port = Integer.parseInt(portStr); if (port <= 0 || port > 0xFFFF) - throw new SQLException("Invalid port: " + portStr); + throw new SQLException("Invalid port: " + portStr, SqlStateCode.CLIENT_CONNECTION_FAILED); } catch (NumberFormatException e) { - throw new SQLException("Invalid port: " + portStr, e); + throw new SQLException("Invalid port: " + portStr, SqlStateCode.CLIENT_CONNECTION_FAILED); } return port; @@ -706,7 +747,7 @@ public class JdbcThinConnection implements Connection { return false; else throw new SQLException("Failed to parse boolean property [name=" + JdbcThinUtils.trimPrefix(propName) + - ", value=" + strVal + ']'); + ", value=" + strVal + ']', SqlStateCode.CLIENT_CONNECTION_FAILED); } /** @@ -723,7 +764,7 @@ public class JdbcThinConnection implements Connection { if (res < 0) throw new SQLException("Property cannot be negative [name=" + JdbcThinUtils.trimPrefix(propName) + - ", value=" + res + ']'); + ", value=" + res + ']', SqlStateCode.CLIENT_CONNECTION_FAILED); return res; } @@ -748,7 +789,7 @@ public class JdbcThinConnection implements Connection { } catch (NumberFormatException e) { throw new SQLException("Failed to parse int property [name=" + JdbcThinUtils.trimPrefix(propName) + - ", value=" + strVal + ']'); + ", value=" + strVal + ']', SqlStateCode.CLIENT_CONNECTION_FAILED); } } http://git-wip-us.apache.org/repos/asf/ignite/blob/7c4d0bc2/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinDatabaseMetadata.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinDatabaseMetadata.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinDatabaseMetadata.java index 1f20bb2..d13ef68 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinDatabaseMetadata.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinDatabaseMetadata.java @@ -17,7 +17,6 @@ package org.apache.ignite.internal.jdbc.thin; -import java.io.IOException; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.ResultSet; @@ -29,15 +28,19 @@ import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; import java.util.List; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.IgniteVersionUtils; import org.apache.ignite.internal.jdbc2.JdbcUtils; import org.apache.ignite.internal.processors.odbc.jdbc.JdbcColumnMeta; import org.apache.ignite.internal.processors.odbc.jdbc.JdbcIndexMeta; +import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaColumnsRequest; import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaColumnsResult; +import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaIndexesRequest; import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaIndexesResult; +import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaPrimaryKeysRequest; import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaPrimaryKeysResult; +import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaSchemasRequest; import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaSchemasResult; +import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaTablesRequest; import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaTablesResult; import org.apache.ignite.internal.processors.odbc.jdbc.JdbcPrimaryKeyMeta; import org.apache.ignite.internal.processors.odbc.jdbc.JdbcTableMeta; @@ -119,7 +122,7 @@ public class JdbcThinDatabaseMetadata implements DatabaseMetaData { /** {@inheritDoc} */ @Override public String getDatabaseProductVersion() throws SQLException { - return conn.io().igniteVersion().toString(); + return conn.igniteVersion().toString(); } /** {@inheritDoc} */ @@ -702,10 +705,9 @@ public class JdbcThinDatabaseMetadata implements DatabaseMetaData { } /** {@inheritDoc} */ - @Override public ResultSet getTables(String catalog, String schemaPtrn, String tblNamePtrn, - String[] tblTypes) throws SQLException { - if (conn.isClosed()) - throw new SQLException("Connection is closed."); + @Override public ResultSet getTables(String catalog, String schemaPtrn, String tblNamePtrn, String[] tblTypes) + throws SQLException { + conn.ensureNotClosed(); final List<JdbcColumnMeta> meta = Arrays.asList( new JdbcColumnMeta(null, null, "TABLE_CAT", String.class), @@ -736,24 +738,14 @@ public class JdbcThinDatabaseMetadata implements DatabaseMetaData { if (!validCatalogPattern(catalog) || !tblTypeMatch) return new JdbcThinResultSet(Collections.<List<Object>>emptyList(), meta); - try { - JdbcMetaTablesResult res = conn.io().tablesMeta(schemaPtrn, tblNamePtrn); + JdbcMetaTablesResult res = conn.sendRequest(new JdbcMetaTablesRequest(schemaPtrn, tblNamePtrn)); - List<List<Object>> rows = new LinkedList<>(); + List<List<Object>> rows = new LinkedList<>(); - for (JdbcTableMeta tblMeta : res.meta()) - rows.add(tableRow(tblMeta)); + for (JdbcTableMeta tblMeta : res.meta()) + rows.add(tableRow(tblMeta)); - return new JdbcThinResultSet(rows, meta); - } - catch (IOException e) { - conn.close(); - - throw new SQLException("Failed to query Ignite.", e); - } - catch (IgniteCheckedException e) { - throw new SQLException("Failed to query Ignite.", e); - } + return new JdbcThinResultSet(rows, meta); } /** @@ -797,10 +789,9 @@ public class JdbcThinDatabaseMetadata implements DatabaseMetaData { } /** {@inheritDoc} */ - @Override public ResultSet getColumns(String catalog, String schemaPtrn, String tblNamePtrn, - String colNamePtrn) throws SQLException { - if (conn.isClosed()) - throw new SQLException("Connection is closed."); + @Override public ResultSet getColumns(String catalog, String schemaPtrn, String tblNamePtrn, String colNamePtrn) + throws SQLException { + conn.ensureNotClosed(); final List<JdbcColumnMeta> meta = Arrays.asList( new JdbcColumnMeta(null, null, "TABLE_CAT", String.class), @@ -827,24 +818,14 @@ public class JdbcThinDatabaseMetadata implements DatabaseMetaData { if (!validCatalogPattern(catalog)) return new JdbcThinResultSet(Collections.<List<Object>>emptyList(), meta); - try { - JdbcMetaColumnsResult res = conn.io().columnsMeta(schemaPtrn, tblNamePtrn, colNamePtrn); + JdbcMetaColumnsResult res = conn.sendRequest(new JdbcMetaColumnsRequest(schemaPtrn, tblNamePtrn, colNamePtrn)); - List<List<Object>> rows = new LinkedList<>(); + List<List<Object>> rows = new LinkedList<>(); - for (int i = 0; i < res.meta().size(); ++i) - rows.add(columnRow(res.meta().get(i), i + 1)); + for (int i = 0; i < res.meta().size(); ++i) + rows.add(columnRow(res.meta().get(i), i + 1)); - return new JdbcThinResultSet(rows, meta); - } - catch (IOException e) { - conn.close(); - - throw new SQLException("Failed to query Ignite.", e); - } - catch (IgniteCheckedException e) { - throw new SQLException("Failed to query Ignite.", e); - } + return new JdbcThinResultSet(rows, meta); } /** @@ -939,8 +920,7 @@ public class JdbcThinDatabaseMetadata implements DatabaseMetaData { /** {@inheritDoc} */ @Override public ResultSet getPrimaryKeys(String catalog, String schema, String tbl) throws SQLException { - if (conn.isClosed()) - throw new SQLException("Connection is closed."); + conn.ensureNotClosed(); final List<JdbcColumnMeta> meta = Arrays.asList( new JdbcColumnMeta(null, null, "TABLE_CAT", String.class), @@ -953,24 +933,14 @@ public class JdbcThinDatabaseMetadata implements DatabaseMetaData { if (!validCatalogPattern(catalog)) return new JdbcThinResultSet(Collections.<List<Object>>emptyList(), meta); - try { - JdbcMetaPrimaryKeysResult res = conn.io().primaryKeysMeta(schema, tbl); + JdbcMetaPrimaryKeysResult res = conn.sendRequest(new JdbcMetaPrimaryKeysRequest(schema, tbl)); - List<List<Object>> rows = new LinkedList<>(); + List<List<Object>> rows = new LinkedList<>(); - for (JdbcPrimaryKeyMeta pkMeta : res.meta()) - rows.addAll(primaryKeyRows(pkMeta)); - - return new JdbcThinResultSet(rows, meta); - } - catch (IOException e) { - conn.close(); + for (JdbcPrimaryKeyMeta pkMeta : res.meta()) + rows.addAll(primaryKeyRows(pkMeta)); - throw new SQLException("Failed to query Ignite.", e); - } - catch (IgniteCheckedException e) { - throw new SQLException("Failed to query Ignite.", e); - } + return new JdbcThinResultSet(rows, meta); } /** @@ -1170,8 +1140,7 @@ public class JdbcThinDatabaseMetadata implements DatabaseMetaData { /** {@inheritDoc} */ @Override public ResultSet getIndexInfo(String catalog, String schema, String tbl, boolean unique, boolean approximate) throws SQLException { - if (conn.isClosed()) - throw new SQLException("Connection is closed."); + conn.ensureNotClosed(); final List<JdbcColumnMeta> meta = Arrays.asList( new JdbcColumnMeta(null, null, "TABLE_CAT", String.class), @@ -1191,24 +1160,14 @@ public class JdbcThinDatabaseMetadata implements DatabaseMetaData { if (!validCatalogPattern(catalog)) return new JdbcThinResultSet(Collections.<List<Object>>emptyList(), meta); - try { - JdbcMetaIndexesResult res = conn.io().indexMeta(schema, tbl); - - List<List<Object>> rows = new LinkedList<>(); + JdbcMetaIndexesResult res = conn.sendRequest(new JdbcMetaIndexesRequest(schema, tbl)); - for (JdbcIndexMeta idxMeta : res.meta()) - rows.addAll(indexRows(idxMeta)); + List<List<Object>> rows = new LinkedList<>(); - return new JdbcThinResultSet(rows, meta); - } - catch (IOException e) { - conn.close(); + for (JdbcIndexMeta idxMeta : res.meta()) + rows.addAll(indexRows(idxMeta)); - throw new SQLException("Failed to query Ignite.", e); - } - catch (IgniteCheckedException e) { - throw new SQLException("Failed to query Ignite.", e); - } + return new JdbcThinResultSet(rows, meta); } /** @@ -1404,12 +1363,12 @@ public class JdbcThinDatabaseMetadata implements DatabaseMetaData { /** {@inheritDoc} */ @Override public int getDatabaseMajorVersion() throws SQLException { - return conn.io().igniteVersion().major(); + return conn.igniteVersion().major(); } /** {@inheritDoc} */ @Override public int getDatabaseMinorVersion() throws SQLException { - return conn.io().igniteVersion().minor(); + return conn.igniteVersion().minor(); } /** {@inheritDoc} */ @@ -1444,8 +1403,7 @@ public class JdbcThinDatabaseMetadata implements DatabaseMetaData { /** {@inheritDoc} */ @Override public ResultSet getSchemas(String catalog, String schemaPtrn) throws SQLException { - if (conn.isClosed()) - throw new SQLException("Connection is closed."); + conn.ensureNotClosed(); final List<JdbcColumnMeta> meta = Arrays.asList( new JdbcColumnMeta(null, null, "TABLE_SCHEM", String.class), @@ -1455,30 +1413,20 @@ public class JdbcThinDatabaseMetadata implements DatabaseMetaData { if (!validCatalogPattern(catalog)) return new JdbcThinResultSet(Collections.<List<Object>>emptyList(), meta); - try { - JdbcMetaSchemasResult res = conn.io().schemasMeta(schemaPtrn); + JdbcMetaSchemasResult res = conn.sendRequest(new JdbcMetaSchemasRequest(schemaPtrn)); - List<List<Object>> rows = new LinkedList<>(); + List<List<Object>> rows = new LinkedList<>(); - for (String schema : res.schemas()) { - List<Object> row = new ArrayList<>(2); + for (String schema : res.schemas()) { + List<Object> row = new ArrayList<>(2); - row.add(schema); - row.add(null); + row.add(schema); + row.add(null); - rows.add(row); - } - - return new JdbcThinResultSet(rows, meta); + rows.add(row); } - catch (IOException e) { - conn.close(); - throw new SQLException("Failed to query Ignite.", e); - } - catch (IgniteCheckedException e) { - throw new SQLException("Failed to query Ignite.", e); - } + return new JdbcThinResultSet(rows, meta); } /** {@inheritDoc} */ http://git-wip-us.apache.org/repos/asf/ignite/blob/7c4d0bc2/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java index 5aa503c..ce1b65c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java @@ -17,7 +17,6 @@ package org.apache.ignite.internal.jdbc.thin; -import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.math.BigDecimal; @@ -40,8 +39,9 @@ import java.sql.Time; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Calendar; -import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.processors.odbc.SqlStateCode; import org.apache.ignite.internal.processors.odbc.SqlListenerUtils; +import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaParamsRequest; import org.apache.ignite.internal.processors.odbc.jdbc.JdbcMetaParamsResult; import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQuery; import org.apache.ignite.internal.processors.odbc.jdbc.JdbcStatementType; @@ -79,14 +79,15 @@ public class JdbcThinPreparedStatement extends JdbcThinStatement implements Prep ResultSet rs = getResultSet(); if (rs == null) - throw new SQLException("The query isn't SELECT query: " + sql); + throw new SQLException("The query isn't SELECT query: " + sql, SqlStateCode.PARSING_EXCEPTION); return rs; } /** {@inheritDoc} */ @Override public ResultSet executeQuery(String sql) throws SQLException { - throw new SQLException("The method 'executeQuery(String)' is called on PreparedStatement instance."); + throw new SQLException("The method 'executeQuery(String)' is called on PreparedStatement instance.", + SqlStateCode.UNSUPPORTED_OPERATION); } /** {@inheritDoc} */ @@ -96,29 +97,33 @@ public class JdbcThinPreparedStatement extends JdbcThinStatement implements Prep int res = getUpdateCount(); if (res == -1) - throw new SQLException("The query is not DML statement: " + sql); + throw new SQLException("The query is not DML statement: " + sql, SqlStateCode.PARSING_EXCEPTION); return res; } /** {@inheritDoc} */ @Override public int executeUpdate(String sql) throws SQLException { - throw new SQLException("The method 'executeUpdate(String)' is called on PreparedStatement instance."); + throw new SQLException("The method 'executeUpdate(String)' is called on PreparedStatement instance.", + SqlStateCode.UNSUPPORTED_OPERATION); } /** {@inheritDoc} */ @Override public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { - throw new SQLException("The method 'executeUpdate(String, int)' is called on PreparedStatement instance."); + throw new SQLException("The method 'executeUpdate(String, int)' is called on PreparedStatement instance.", + SqlStateCode.UNSUPPORTED_OPERATION); } /** {@inheritDoc} */ @Override public int executeUpdate(String sql, int columnIndexes[]) throws SQLException { - throw new SQLException("The method 'executeUpdate(String, int[])' is called on PreparedStatement instance."); + throw new SQLException("The method 'executeUpdate(String, int[])' is called on PreparedStatement instance.", + SqlStateCode.UNSUPPORTED_OPERATION); } /** {@inheritDoc} */ @Override public int executeUpdate(String sql, String columnNames[]) throws SQLException { - throw new SQLException("The method 'executeUpdate(String, String[])' is called on PreparedStatement instance."); + throw new SQLException("The method 'executeUpdate(String, String[])' is called on PreparedStatement " + + "instance.", SqlStateCode.UNSUPPORTED_OPERATION); } /** {@inheritDoc} */ @@ -248,7 +253,8 @@ public class JdbcThinPreparedStatement extends JdbcThinStatement implements Prep /** {@inheritDoc} */ @Override public boolean execute(String sql) throws SQLException { - throw new SQLException("The method 'execute(String)' is called on PreparedStatement instance."); + throw new SQLException("The method 'execute(String)' is called on PreparedStatement instance.", + SqlStateCode.UNSUPPORTED_OPERATION); } /** {@inheritDoc} */ @@ -268,7 +274,8 @@ public class JdbcThinPreparedStatement extends JdbcThinStatement implements Prep /** {@inheritDoc} */ @Override public void addBatch(String sql) throws SQLException { - throw new SQLException("The method 'addBatch(String)' is called on PreparedStatement instance."); + throw new SQLException("The method 'addBatch(String)' is called on PreparedStatement instance.", + SqlStateCode.UNSUPPORTED_OPERATION); } /** {@inheritDoc} */ @@ -346,27 +353,15 @@ public class JdbcThinPreparedStatement extends JdbcThinStatement implements Prep /** {@inheritDoc} */ @Override public ParameterMetaData getParameterMetaData() throws SQLException { ensureNotClosed(); - try { - if (conn.isClosed()) - throw new SQLException("Connection is closed."); - if (metaData != null) - return metaData; - - JdbcMetaParamsResult res = conn.io().parametersMeta(conn.getSchema(), sql); + if (metaData != null) + return metaData; - metaData = new JdbcThinParameterMetadata(res.meta()); + JdbcMetaParamsResult res = conn.sendRequest(new JdbcMetaParamsRequest(conn.getSchema(), sql)); - return metaData; - } - catch (IOException e) { - conn.close(); + metaData = new JdbcThinParameterMetadata(res.meta()); - throw new SQLException("Failed to query Ignite.", e); - } - catch (IgniteCheckedException e) { - throw new SQLException("Failed to query Ignite.", e); - } + return metaData; } /** {@inheritDoc} */ @@ -525,7 +520,8 @@ public class JdbcThinPreparedStatement extends JdbcThinStatement implements Prep ensureNotClosed(); if (val != null && !SqlListenerUtils.isPlainType(val.getClass())) - throw new SQLException("Parameter type is unsupported. [cls=" + val.getClass() + ']'); + throw new SQLException("Parameter type is unsupported. [cls=" + val.getClass() + ']', + SqlStateCode.INVALID_PARAMETER_VALUE); if (paramIdx < 1) throw new SQLException("Parameter index is invalid: " + paramIdx); http://git-wip-us.apache.org/repos/asf/ignite/blob/7c4d0bc2/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinResultSet.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinResultSet.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinResultSet.java index 0a0c978..189175b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinResultSet.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinResultSet.java @@ -17,7 +17,6 @@ package org.apache.ignite.internal.jdbc.thin; -import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.math.BigDecimal; @@ -47,9 +46,12 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; -import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.processors.odbc.SqlStateCode; import org.apache.ignite.internal.processors.odbc.jdbc.JdbcColumnMeta; +import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQueryCloseRequest; +import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQueryFetchRequest; import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQueryFetchResult; +import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQueryMetadataRequest; import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQueryMetadataResult; /** @@ -197,22 +199,12 @@ public class JdbcThinResultSet implements ResultSet { ensureNotClosed(); if ((rowsIter == null || !rowsIter.hasNext()) && !finished) { - try { - JdbcQueryFetchResult res = stmt.connection().io().queryFetch(qryId, fetchSize); - - rows = res.items(); - finished = res.last(); + JdbcQueryFetchResult res = stmt.conn.sendRequest(new JdbcQueryFetchRequest(qryId, fetchSize)); - rowsIter = rows.iterator(); - } - catch (IOException e) { - stmt.connection().close(); + rows = res.items(); + finished = res.last(); - throw new SQLException("Failed to query Ignite.", e); - } - catch (IgniteCheckedException e) { - throw new SQLException("Failed to query Ignite.", e); - } + rowsIter = rows.iterator(); } if (rowsIter != null) { @@ -249,20 +241,10 @@ public class JdbcThinResultSet implements ResultSet { if (isClosed()) return; - try { - if (!finished || (isQuery && !autoClose)) - stmt.connection().io().queryClose(qryId); - - closed = true; - } - catch (IOException e) { - stmt.connection().close(); + if (!finished || (isQuery && !autoClose)) + stmt.conn.sendRequest(new JdbcQueryCloseRequest(qryId)); - throw new SQLException("Failed to close Ignite query.", e); - } - catch (IgniteCheckedException e) { - throw new SQLException("Failed to close Ignite query.", e); - } + closed = true; } /** {@inheritDoc} */ @@ -298,11 +280,11 @@ public class JdbcThinResultSet implements ResultSet { return Integer.parseInt(val.toString()) != 0; } catch (NumberFormatException e) { - throw new SQLException("Cannot convert to boolean: " + val, e); + throw new SQLException("Cannot convert to boolean: " + val, SqlStateCode.CONVERSION_FAILED, e); } } else - throw new SQLException("Cannot convert to boolean: " + val); + throw new SQLException("Cannot convert to boolean: " + val, SqlStateCode.CONVERSION_FAILED); } /** {@inheritDoc} */ @@ -323,11 +305,11 @@ public class JdbcThinResultSet implements ResultSet { return Byte.parseByte(val.toString()); } catch (NumberFormatException e) { - throw new SQLException("Cannot convert to byte: " + val, e); + throw new SQLException("Cannot convert to byte: " + val, SqlStateCode.CONVERSION_FAILED, e); } } else - throw new SQLException("Cannot convert to byte: " + val); + throw new SQLException("Cannot convert to byte: " + val, SqlStateCode.CONVERSION_FAILED); } /** {@inheritDoc} */ @@ -348,11 +330,11 @@ public class JdbcThinResultSet implements ResultSet { return Short.parseShort(val.toString()); } catch (NumberFormatException e) { - throw new SQLException("Cannot convert to short: " + val, e); + throw new SQLException("Cannot convert to short: " + val, SqlStateCode.CONVERSION_FAILED, e); } } else - throw new SQLException("Cannot convert to short: " + val); + throw new SQLException("Cannot convert to short: " + val, SqlStateCode.CONVERSION_FAILED); } /** {@inheritDoc} */ @@ -373,11 +355,11 @@ public class JdbcThinResultSet implements ResultSet { return Integer.parseInt(val.toString()); } catch (NumberFormatException e) { - throw new SQLException("Cannot convert to int: " + val, e); + throw new SQLException("Cannot convert to int: " + val, SqlStateCode.CONVERSION_FAILED, e); } } else - throw new SQLException("Cannot convert to int: " + val); + throw new SQLException("Cannot convert to int: " + val, SqlStateCode.CONVERSION_FAILED); } /** {@inheritDoc} */ @@ -398,11 +380,11 @@ public class JdbcThinResultSet implements ResultSet { return Long.parseLong(val.toString()); } catch (NumberFormatException e) { - throw new SQLException("Cannot convert to long: " + val, e); + throw new SQLException("Cannot convert to long: " + val, SqlStateCode.CONVERSION_FAILED, e); } } else - throw new SQLException("Cannot convert to long: " + val); + throw new SQLException("Cannot convert to long: " + val, SqlStateCode.CONVERSION_FAILED); } /** {@inheritDoc} */ @@ -423,11 +405,11 @@ public class JdbcThinResultSet implements ResultSet { return Float.parseFloat(val.toString()); } catch (NumberFormatException e) { - throw new SQLException("Cannot convert to float: " + val, e); + throw new SQLException("Cannot convert to float: " + val, SqlStateCode.CONVERSION_FAILED, e); } } else - throw new SQLException("Cannot convert to float: " + val); + throw new SQLException("Cannot convert to float: " + val, SqlStateCode.CONVERSION_FAILED); } /** {@inheritDoc} */ @@ -448,11 +430,11 @@ public class JdbcThinResultSet implements ResultSet { return Double.parseDouble(val.toString()); } catch (NumberFormatException e) { - throw new SQLException("Cannot convert to double: " + val, e); + throw new SQLException("Cannot convert to double: " + val, SqlStateCode.CONVERSION_FAILED, e); } } else - throw new SQLException("Cannot convert to double: " + val); + throw new SQLException("Cannot convert to double: " + val, SqlStateCode.CONVERSION_FAILED); } /** {@inheritDoc} */ @@ -494,7 +476,7 @@ public class JdbcThinResultSet implements ResultSet { else if (cls == String.class) return ((String)val).getBytes(); else - throw new SQLException("Cannot convert to byte[]: " + val); + throw new SQLException("Cannot convert to byte[]: " + val, SqlStateCode.CONVERSION_FAILED); } /** {@inheritDoc} */ @@ -511,7 +493,7 @@ public class JdbcThinResultSet implements ResultSet { else if (cls == java.util.Date.class || cls == Time.class || cls == Timestamp.class) return new Date(((java.util.Date)val).getTime()); else - throw new SQLException("Cannot convert to date: " + val); + throw new SQLException("Cannot convert to date: " + val, SqlStateCode.CONVERSION_FAILED); } /** {@inheritDoc} */ @@ -528,7 +510,7 @@ public class JdbcThinResultSet implements ResultSet { else if (cls == java.util.Date.class || cls == Date.class || cls == Timestamp.class) return new Time(((java.util.Date)val).getTime()); else - throw new SQLException("Cannot convert to time: " + val); + throw new SQLException("Cannot convert to time: " + val, SqlStateCode.CONVERSION_FAILED); } /** {@inheritDoc} */ @@ -545,7 +527,7 @@ public class JdbcThinResultSet implements ResultSet { else if (cls == java.util.Date.class || cls == Date.class || cls == Time.class) return new Timestamp(((java.util.Date)val).getTime()); else - throw new SQLException("Cannot convert to timestamp: " + val); + throw new SQLException("Cannot convert to timestamp: " + val, SqlStateCode.CONVERSION_FAILED); } /** {@inheritDoc} */ @@ -564,11 +546,11 @@ public class JdbcThinResultSet implements ResultSet { return new URL(val.toString()); } catch (MalformedURLException e) { - throw new SQLException("Cannot convert to URL: " + val, e); + throw new SQLException("Cannot convert to URL: " + val, SqlStateCode.CONVERSION_FAILED, e); } } else - throw new SQLException("Cannot convert to URL: " + val); + throw new SQLException("Cannot convert to URL: " + val, SqlStateCode.CONVERSION_FAILED); } @@ -753,7 +735,7 @@ public class JdbcThinResultSet implements ResultSet { Integer order = columnOrder().get(colLb.toUpperCase()); if (order == null) - throw new SQLException("Column not found: " + colLb); + throw new SQLException("Column not found: " + colLb, SqlStateCode.PARSING_EXCEPTION); assert order >= 0; @@ -794,11 +776,11 @@ public class JdbcThinResultSet implements ResultSet { return (BigDecimal)decimalFormat.get().parse(val.toString()); } catch (ParseException e) { - throw new SQLException("Cannot convert to BigDecimal: " + val, e); + throw new SQLException("Cannot convert to BigDecimal: " + val, SqlStateCode.CONVERSION_FAILED, e); } } else - throw new SQLException("Cannot convert to BigDecimal: " + val); + throw new SQLException("Cannot convert to BigDecimal: " + val, SqlStateCode.CONVERSION_FAILED); } /** {@inheritDoc} */ @@ -1834,7 +1816,8 @@ public class JdbcThinResultSet implements ResultSet { if (targetCls == cls) return val; else - throw new SQLException("Cannot convert to " + targetCls.getName() + ": " + val); + throw new SQLException("Cannot convert to " + targetCls.getName() + ": " + val, + SqlStateCode.CONVERSION_FAILED); } } @@ -1858,7 +1841,7 @@ public class JdbcThinResultSet implements ResultSet { return val; } catch (IndexOutOfBoundsException e) { - throw new SQLException("Invalid column index: " + colIdx, e); + throw new SQLException("Invalid column index: " + colIdx, SqlStateCode.PARSING_EXCEPTION, e); } } @@ -1869,7 +1852,7 @@ public class JdbcThinResultSet implements ResultSet { */ private void ensureNotClosed() throws SQLException { if (closed) - throw new SQLException("Result set is closed."); + throw new SQLException("Result set is closed.", SqlStateCode.INVALID_CURSOR_STATE); } /** @@ -1888,24 +1871,14 @@ public class JdbcThinResultSet implements ResultSet { */ private List<JdbcColumnMeta> meta() throws SQLException { if (finished && (!isQuery || autoClose)) - throw new SQLException("Server cursor is already closed."); + throw new SQLException("Server cursor is already closed.", SqlStateCode.INVALID_CURSOR_STATE); if (!metaInit) { - try { - JdbcQueryMetadataResult res = stmt.connection().io().queryMeta(qryId); + JdbcQueryMetadataResult res = stmt.conn.sendRequest(new JdbcQueryMetadataRequest(qryId)); - meta = res.meta(); + meta = res.meta(); - metaInit = true; - } - catch (IOException e) { - stmt.connection().close(); - - throw new SQLException("Failed to get query metadata.", e); - } - catch (IgniteCheckedException e) { - throw new SQLException("Failed to get query metadata.", e); - } + metaInit = true; } return meta; http://git-wip-us.apache.org/repos/asf/ignite/blob/7c4d0bc2/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java index d9bef54..6ab50de 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java @@ -17,7 +17,6 @@ package org.apache.ignite.internal.jdbc.thin; -import java.io.IOException; import java.sql.BatchUpdateException; import java.sql.Connection; import java.sql.ResultSet; @@ -27,11 +26,13 @@ import java.sql.SQLWarning; import java.sql.Statement; import java.util.ArrayList; import java.util.List; -import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.cache.query.SqlQuery; +import org.apache.ignite.internal.processors.odbc.SqlStateCode; import org.apache.ignite.internal.processors.odbc.ClientListenerResponse; +import org.apache.ignite.internal.processors.odbc.jdbc.JdbcBatchExecuteRequest; import org.apache.ignite.internal.processors.odbc.jdbc.JdbcBatchExecuteResult; import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQuery; +import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQueryExecuteRequest; import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQueryExecuteResult; import org.apache.ignite.internal.processors.odbc.jdbc.JdbcStatementType; @@ -96,7 +97,7 @@ public class JdbcThinStatement implements Statement { ResultSet rs = getResultSet(); if (rs == null) - throw new SQLException("The query isn't SELECT query: " + sql); + throw new SQLException("The query isn't SELECT query: " + sql, SqlStateCode.PARSING_EXCEPTION); return rs; } @@ -122,23 +123,13 @@ public class JdbcThinStatement implements Statement { if (sql == null || sql.isEmpty()) throw new SQLException("SQL query is empty."); - try { - JdbcQueryExecuteResult res = conn.io().queryExecute(stmtType, conn.getSchema(), pageSize, maxRows, - sql, args); - - assert res != null; + JdbcQueryExecuteResult res = conn.sendRequest(new JdbcQueryExecuteRequest(stmtType, conn.getSchema(), pageSize, + maxRows, sql, args == null ? null : args.toArray(new Object[args.size()]))); - rs = new JdbcThinResultSet(this, res.getQueryId(), pageSize, res.last(), res.items(), - res.isQuery(), conn.io().autoCloseServerCursor(), res.updateCount(), closeOnCompletion); - } - catch (IOException e) { - conn.close(); + assert res != null; - throw new SQLException("Failed to query Ignite.", e); - } - catch (IgniteCheckedException e) { - throw new SQLException("Failed to query Ignite [err=\"" + e.getMessage() + "\"]", e); - } + rs = new JdbcThinResultSet(this, res.getQueryId(), pageSize, res.last(), res.items(), + res.isQuery(), conn.autoCloseServerCursor(), res.updateCount(), closeOnCompletion); } /** {@inheritDoc} */ @@ -148,7 +139,7 @@ public class JdbcThinStatement implements Statement { int res = getUpdateCount(); if (res == -1) - throw new SQLException("The query is not DML statememt: " + sql); + throw new SQLException("The query is not DML statement: " + sql, SqlStateCode.PARSING_EXCEPTION); return res; } @@ -378,21 +369,13 @@ public class JdbcThinStatement implements Statement { throw new SQLException("Batch is empty."); try { - JdbcBatchExecuteResult res = conn.io().batchExecute(conn.getSchema(), batch); + JdbcBatchExecuteResult res = conn.sendRequest(new JdbcBatchExecuteRequest(conn.getSchema(), batch)); if (res.errorCode() != ClientListenerResponse.STATUS_SUCCESS) throw new BatchUpdateException(res.errorMessage(), null, res.errorCode(), res.updateCounts()); return res.updateCounts(); } - catch (IOException e) { - conn.close(); - - throw new SQLException("Failed to query Ignite.", e); - } - catch (IgniteCheckedException e) { - throw new SQLException("Failed to query Ignite.", e); - } finally { batch = null; }
