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

ptupitsyn pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new 921f974d5d IGNITE-23157 Improve column value type validation when 
serializing Tuples (#4414)
921f974d5d is described below

commit 921f974d5df35af9c35cca1d731ffe85c4f25365
Author: Pavel Tupitsyn <[email protected]>
AuthorDate: Thu Sep 19 06:48:03 2024 +0300

    IGNITE-23157 Improve column value type validation when serializing Tuples 
(#4414)
    
    * Fix NPE when assertions are disabled
    * Throw `MarshallerException` with descriptive message
    * Add test for client and embedded modes
---
 .../client/proto/ClientBinaryTupleUtils.java         | 19 ++++++++++++++++---
 .../app/client/ItThinClientMarshallingTest.java      | 19 +++++++++++++++++++
 .../schema/marshaller/TupleMarshallerImpl.java       | 20 +++++++++++++++++---
 3 files changed, 52 insertions(+), 6 deletions(-)

diff --git 
a/modules/client-common/src/main/java/org/apache/ignite/internal/client/proto/ClientBinaryTupleUtils.java
 
b/modules/client-common/src/main/java/org/apache/ignite/internal/client/proto/ClientBinaryTupleUtils.java
index 5b30458977..db638b21f3 100644
--- 
a/modules/client-common/src/main/java/org/apache/ignite/internal/client/proto/ClientBinaryTupleUtils.java
+++ 
b/modules/client-common/src/main/java/org/apache/ignite/internal/client/proto/ClientBinaryTupleUtils.java
@@ -39,7 +39,9 @@ import 
org.apache.ignite.internal.binarytuple.BinaryTupleReader;
 import org.apache.ignite.internal.type.NativeType;
 import org.apache.ignite.internal.type.NativeTypeSpec;
 import org.apache.ignite.internal.type.NativeTypes;
+import org.apache.ignite.lang.ErrorGroups.Marshalling;
 import org.apache.ignite.lang.IgniteException;
+import org.apache.ignite.lang.MarshallerException;
 import org.apache.ignite.sql.ColumnType;
 import org.jetbrains.annotations.Nullable;
 
@@ -120,7 +122,7 @@ public class ClientBinaryTupleUtils {
         }
     }
 
-    static Function<Integer, Object> readerForType(BinaryTupleReader binTuple, 
ColumnType type) {
+    private static Function<Integer, Object> readerForType(BinaryTupleReader 
binTuple, ColumnType type) {
         switch (type) {
             case INT8:
                 return binTuple::byteValue;
@@ -436,8 +438,19 @@ public class ClientBinaryTupleUtils {
             }
         } catch (ClassCastException e) {
             NativeType nativeType = NativeTypes.fromObject(v);
-            // A null is handled separately, so nativeType should not be null.
-            assert nativeType != null;
+
+            if (nativeType == null) {
+                // Unsupported type (does not map to any Ignite type) - throw 
(same behavior as embedded).
+                throw new MarshallerException(
+                        UUID.randomUUID(),
+                        Marshalling.COMMON_ERR,
+                        String.format(
+                                "Invalid value type provided for column 
[name='%s', expected='%s', actual='%s']",
+                                name,
+                                type.javaClass().getName(),
+                                v.getClass().getName()),
+                        e);
+            }
 
             NativeTypeSpec actualType = nativeType.spec();
             NativeTypeSpec expectedType = NativeTypeSpec.fromColumnType(type);
diff --git 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/client/ItThinClientMarshallingTest.java
 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/client/ItThinClientMarshallingTest.java
index cc3c1608c6..e41b6279db 100644
--- 
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/client/ItThinClientMarshallingTest.java
+++ 
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/client/ItThinClientMarshallingTest.java
@@ -28,6 +28,8 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
 import java.math.BigDecimal;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.lang.IgniteException;
+import org.apache.ignite.lang.MarshallerException;
+import org.apache.ignite.table.RecordView;
 import org.apache.ignite.table.Table;
 import org.apache.ignite.table.Tuple;
 import org.apache.ignite.table.mapper.Mapper;
@@ -355,6 +357,23 @@ public class ItThinClientMarshallingTest extends 
ItAbstractThinClientTest {
         assertThat(ex.getMessage(), containsString("Numeric field overflow in 
column 'VAL'"));
     }
 
+    @Test
+    public void testUnsupportedObjectInTuple() {
+        Table table = ignite().tables().table(TABLE_NAME);
+        RecordView<Tuple> tupleView = table.recordView();
+
+        Tuple rec = Tuple.create()
+                .set("KEY", 1)
+                .set("VAL", new TestPojo2());
+
+        MarshallerException ex = assertThrows(MarshallerException.class, () -> 
tupleView.upsert(null, rec));
+
+        assertEquals(
+                "Invalid value type provided for column [name='VAL', 
expected='java.lang.String', actual='"
+                        + TestPojo2.class.getName() + "']",
+                ex.getMessage());
+    }
+
     private static class TestPojo2 {
         public int key;
 
diff --git 
a/modules/table/src/main/java/org/apache/ignite/internal/schema/marshaller/TupleMarshallerImpl.java
 
b/modules/table/src/main/java/org/apache/ignite/internal/schema/marshaller/TupleMarshallerImpl.java
index 30bfe749d2..1055764cd4 100644
--- 
a/modules/table/src/main/java/org/apache/ignite/internal/schema/marshaller/TupleMarshallerImpl.java
+++ 
b/modules/table/src/main/java/org/apache/ignite/internal/schema/marshaller/TupleMarshallerImpl.java
@@ -25,6 +25,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.UUID;
 import org.apache.ignite.internal.binarytuple.BinaryTupleCommon;
 import org.apache.ignite.internal.binarytuple.BinaryTupleContainer;
 import org.apache.ignite.internal.binarytuple.BinaryTupleReader;
@@ -39,6 +40,7 @@ import org.apache.ignite.internal.schema.row.RowAssembler;
 import org.apache.ignite.internal.type.DecimalNativeType;
 import org.apache.ignite.internal.type.NativeType;
 import org.apache.ignite.internal.type.NativeTypeSpec;
+import org.apache.ignite.lang.ErrorGroups.Marshalling;
 import org.apache.ignite.lang.MarshallerException;
 import org.apache.ignite.table.Tuple;
 import org.apache.ignite.table.TupleHelper;
@@ -214,9 +216,21 @@ public class TupleMarshallerImpl implements 
TupleMarshaller {
 
             if (val != null) {
                 if (!colType.spec().fixedLength()) {
-                    val = shrinkValue(val, col.type());
-
-                    estimatedValueSize += getValueSize(val, colType);
+                    try {
+                        val = shrinkValue(val, col.type());
+
+                        estimatedValueSize += getValueSize(val, colType);
+                    } catch (ClassCastException e) {
+                        throw new MarshallerException(
+                                UUID.randomUUID(),
+                                Marshalling.COMMON_ERR,
+                                String.format(
+                                        "Invalid value type provided for 
column [name='%s', expected='%s', actual='%s']",
+                                        col.name(),
+                                        
col.type().spec().asColumnType().javaClass().getName(),
+                                        val.getClass().getName()),
+                                e);
+                    }
                 }
             }
 

Reply via email to