You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by tl...@apache.org on 2022/06/14 09:02:00 UTC

[ignite] branch master updated: IGNITE-17145 Fix handle BinaryObjectException at the thin JDBC (#10084)

This is an automated email from the ASF dual-hosted git repository.

tledkov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new f6c434ed815 IGNITE-17145 Fix handle BinaryObjectException at the thin JDBC (#10084)
f6c434ed815 is described below

commit f6c434ed8153ac4dc91bef58bd9b50a8521313e9
Author: Taras Ledkov <tl...@gridgain.com>
AuthorDate: Tue Jun 14 12:01:53 2022 +0300

    IGNITE-17145 Fix handle BinaryObjectException at the thin JDBC (#10084)
---
 .../jdbc/thin/JdbcThinStatementSelfTest.java       | 43 ++++++++++++++++++++++
 .../internal/jdbc/thin/JdbcThinConnection.java     | 13 +++++++
 .../internal/processors/odbc/SqlStateCode.java     |  3 ++
 3 files changed, 59 insertions(+)

diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementSelfTest.java
index cbc600887e1..37f6cb1ef84 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinStatementSelfTest.java
@@ -26,11 +26,15 @@ import java.sql.SQLFeatureNotSupportedException;
 import java.sql.Statement;
 import java.util.concurrent.Callable;
 import org.apache.ignite.IgniteCache;
+import org.apache.ignite.binary.BinaryInvalidTypeException;
+import org.apache.ignite.binary.BinaryObjectBuilder;
 import org.apache.ignite.cache.query.annotations.QuerySqlField;
 import org.apache.ignite.cache.query.annotations.QuerySqlFunction;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.processors.odbc.SqlStateCode;
 import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.X;
 import org.apache.ignite.testframework.GridTestUtils;
 import org.apache.ignite.testframework.GridTestUtils.RunnableX;
 import org.junit.Ignore;
@@ -1096,6 +1100,45 @@ public class JdbcThinStatementSelfTest extends JdbcThinAbstractSelfTest {
             rs.getInt(1));
     }
 
+    /**
+     *
+     */
+    @org.junit.Test
+    public void testExceptionOnDeserializeResponse() throws SQLException {
+        try (Connection c = connect(grid(0), null)) {
+            execute(c, "CREATE TABLE TEST_DESERIALIZE(id int primary key, name varchar, BINFIELD OTHER) WITH " +
+                "\"cache_name=TEST_DESERIALIZE,VALUE_TYPE=TEST_TYPE\"");
+
+            IgniteCache<Object, Object> cc = grid(0).cache("TEST_DESERIALIZE");
+
+            BinaryObjectBuilder bobFld = grid(0).binary().builder("TestType");
+            bobFld.setField("fld0", 0);
+
+            BinaryObjectBuilder bob = grid(0).binary().builder("TEST_TYPE");
+            bob.setField("NAME", "name0");
+            bob.setField("BINFIELD", bobFld.build());
+
+            cc.put(0, bob.build());
+
+            try (Statement stmt = c.createStatement()) {
+                SQLException ex = (SQLException)GridTestUtils.assertThrows(
+                    log,
+                    () -> stmt.executeQuery("SELECT * FROM TEST_DESERIALIZE"),
+                    SQLException.class,
+                    "Serialization error during sending an sql request"
+                );
+
+                assertEquals(SqlStateCode.DATA_EXCEPTION, ex.getSQLState());
+                assertTrue(X.hasCause(ex, "TestType", BinaryInvalidTypeException.class));
+
+                ResultSet rs = stmt.executeQuery("SELECT id FROM TEST_DESERIALIZE");
+
+                rs.next();
+                assertEquals(0, rs.getInt(1));
+            }
+        }
+    }
+
     /** */
     private void fillCache() {
         IgniteCache<String, Person> cachePerson = grid(0).cache(DEFAULT_CACHE_NAME);
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 072858948f9..737cbebb80f 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
@@ -132,6 +132,7 @@ import static java.sql.ResultSet.TYPE_FORWARD_ONLY;
 import static org.apache.ignite.internal.processors.odbc.SqlStateCode.CLIENT_CONNECTION_FAILED;
 import static org.apache.ignite.internal.processors.odbc.SqlStateCode.CONNECTION_CLOSED;
 import static org.apache.ignite.internal.processors.odbc.SqlStateCode.CONNECTION_FAILURE;
+import static org.apache.ignite.internal.processors.odbc.SqlStateCode.DATA_EXCEPTION;
 import static org.apache.ignite.internal.processors.odbc.SqlStateCode.INTERNAL_ERROR;
 import static org.apache.ignite.marshaller.MarshallerUtils.processSystemClasses;
 
@@ -1018,6 +1019,18 @@ public class JdbcThinConnection implements Connection {
 
                     throw e;
                 }
+                catch (BinaryObjectException e) {
+                    String err = "Serialization error during sending an sql request. " +
+                        "The error can be caused by the fact that the classes used on the node are missing " +
+                        "on the client. Try to use JDBC connection option 'keepBinary=true' " +
+                        "to to avoid deserialization. Also you can use system property " +
+                        "IGNITE_SENSITIVE_DATA_LOGGING=\"plain\" to readable print content of a BinaryObject";
+
+                    if (LOG.isLoggable(Level.FINE))
+                        LOG.log(Level.FINE, err, e);
+
+                    throw new SQLException(err, DATA_EXCEPTION, e);
+                }
                 catch (Exception e) {
                     if (LOG.isLoggable(Level.FINE))
                         LOG.log(Level.FINE, "Exception during sending an sql request.", e);
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlStateCode.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlStateCode.java
index 2257f956d09..50a13a396fb 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlStateCode.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/SqlStateCode.java
@@ -42,6 +42,9 @@ public final class SqlStateCode {
     /** IO error during communication. */
     public static final String CONNECTION_FAILURE = "08006";
 
+    /** Generic data exception. */
+    public static final String DATA_EXCEPTION = "22000";
+
     /** Null value occurred where it wasn't expected to. */
     public static final String NULL_VALUE = "22004";