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

ppa 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 739de69ff8 IGNITE-22873 Sql. InvalidTypeException should not include a 
value in its error message (#4199)
739de69ff8 is described below

commit 739de69ff8787ffba1c39fbae59fed6d18c10c2f
Author: Max Zhuravkov <[email protected]>
AuthorDate: Wed Aug 14 14:48:54 2024 +0300

    IGNITE-22873 Sql. InvalidTypeException should not include a value in its 
error message (#4199)
---
 .../client/proto/ClientBinaryTupleUtils.java       | 21 +++++++--
 .../org/apache/ignite/client/ClientTableTest.java  |  2 +-
 .../ignite/internal/type/DecimalNativeType.java    |  8 ++++
 .../apache/ignite/internal/type/NativeType.java    |  9 ++++
 .../ignite/internal/type/NativeTypeSpec.java       | 46 +++++++++++++++++++
 .../ignite/internal/type/TemporalNativeType.java   |  8 ++++
 .../ignite/internal/type/VarlenNativeType.java     |  9 ++++
 .../ignite/internal/type/NativeTypeSpecTest.java   | 51 ++++++++++++++++++++++
 .../app/client/ItThinClientMarshallingTest.java    | 48 ++++++++++++++++++--
 .../org/apache/ignite/internal/schema/Column.java  | 28 +++++++++---
 .../ignite/internal/schema/row/RowAssembler.java   |  7 ++-
 .../internal/table/MutableRowTupleAdapterTest.java | 10 +++--
 .../table/RecordBinaryViewOperationsTest.java      | 38 +++++++---------
 .../table/type/NumericTypesSerializerTest.java     |  8 ++--
 14 files changed, 247 insertions(+), 46 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 01ab88cbd5..abd3582c7e 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
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.internal.client.proto;
 
+import static org.apache.ignite.internal.lang.IgniteStringFormatter.format;
 import static org.apache.ignite.lang.ErrorGroups.Client.PROTOCOL_ERR;
 
 import java.math.BigDecimal;
@@ -35,6 +36,9 @@ import java.util.function.Consumer;
 import java.util.function.Function;
 import org.apache.ignite.internal.binarytuple.BinaryTupleBuilder;
 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.IgniteException;
 import org.apache.ignite.marshalling.Marshaller;
 import org.apache.ignite.sql.ColumnType;
@@ -435,11 +439,20 @@ public class ClientBinaryTupleUtils {
                     throw new IllegalArgumentException("Unsupported type: " + 
type);
             }
         } catch (ClassCastException e) {
+            NativeType nativeType = NativeTypes.fromObject(v);
+            // A null is handled separately, so nativeType should not be null.
+            assert nativeType != null;
+
+            NativeTypeSpec actualType = nativeType.spec();
+            NativeTypeSpec expectedType = NativeTypeSpec.fromColumnType(type);
+
             // Exception message is similar to embedded mode - see 
o.a.i.i.schema.Column#validate
-            throw new IgniteException(PROTOCOL_ERR, "Column's type mismatch ["
-                    + "column=" + name
-                    + ", expectedType=" + type
-                    + ", actualType=" + v.getClass() + ']', e);
+            String error = format(
+                    "Value type does not match [column='{}', expected={}, 
actual={}]",
+                    name, expectedType.name(), actualType.name()
+            );
+
+            throw new IgniteException(PROTOCOL_ERR, error, e);
         }
     }
 
diff --git 
a/modules/client/src/test/java/org/apache/ignite/client/ClientTableTest.java 
b/modules/client/src/test/java/org/apache/ignite/client/ClientTableTest.java
index 9c3cb5806f..ca97cb0dad 100644
--- a/modules/client/src/test/java/org/apache/ignite/client/ClientTableTest.java
+++ b/modules/client/src/test/java/org/apache/ignite/client/ClientTableTest.java
@@ -461,7 +461,7 @@ public class ClientTableTest extends 
AbstractClientTableTest {
         var tuple = Tuple.create().set("id", "str");
 
         var ex = assertThrows(IgniteException.class, () -> 
defaultTable().recordView().upsert(null, tuple));
-        assertEquals("Column's type mismatch [column=ID, expectedType=INT64, 
actualType=class java.lang.String]", ex.getMessage());
+        assertEquals("Value type does not match [column='ID', expected=INT64, 
actual=STRING]", ex.getMessage());
     }
 
     @Test
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/type/DecimalNativeType.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/type/DecimalNativeType.java
index b5c75bad4b..dce0e6c0aa 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/type/DecimalNativeType.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/type/DecimalNativeType.java
@@ -17,6 +17,8 @@
 
 package org.apache.ignite.internal.type;
 
+import static org.apache.ignite.internal.lang.IgniteStringFormatter.format;
+
 import java.util.Objects;
 import org.apache.ignite.internal.tostring.S;
 
@@ -57,6 +59,12 @@ public class DecimalNativeType extends NativeType {
         return scale;
     }
 
+    /** {@inheritDoc} */
+    @Override
+    public String displayName() {
+        return format("{}({}, {})", super.displayName(), precision, scale);
+    }
+
     /** {@inheritDoc} */
     @Override
     public boolean equals(Object o) {
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/type/NativeType.java 
b/modules/core/src/main/java/org/apache/ignite/internal/type/NativeType.java
index 9bb22fa5b0..2893346591 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/type/NativeType.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/type/NativeType.java
@@ -89,6 +89,15 @@ public class NativeType implements Comparable<NativeType> {
         return this != type && typeSpec != type.typeSpec;
     }
 
+    /**
+     * Return human readable name of this type.
+     *
+     * @return Human readable name of this type.
+     */
+    public String displayName() {
+        return typeSpec.asColumnType().name();
+    }
+
     /** {@inheritDoc} */
     @Override
     public boolean equals(Object o) {
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/type/NativeTypeSpec.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/type/NativeTypeSpec.java
index 79382d1060..fd8fcf9a78 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/type/NativeTypeSpec.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/type/NativeTypeSpec.java
@@ -329,6 +329,52 @@ public enum NativeTypeSpec {
         return val != null ? fromClass(val.getClass()) : null;
     }
 
+    /**
+     * Returns a {@link NativeTypeSpec} that corresponds to the given {@link 
ColumnType}.
+     *
+     * @param columnType Column type.
+     *
+     * @return Native type.
+     * @throws IllegalArgumentException if ColumnType is {@link 
ColumnType#NULL} or is not supported.
+     */
+    public static NativeTypeSpec fromColumnType(ColumnType columnType) {
+        switch (columnType) {
+            case BOOLEAN:
+                return BOOLEAN;
+            case INT8:
+                return INT8;
+            case INT16:
+                return INT16;
+            case INT32:
+                return INT32;
+            case INT64:
+                return INT64;
+            case FLOAT:
+                return FLOAT;
+            case DOUBLE:
+                return DOUBLE;
+            case DECIMAL:
+                return DECIMAL;
+            case DATE:
+                return DATE;
+            case TIME:
+                return TIME;
+            case DATETIME:
+                return DATETIME;
+            case TIMESTAMP:
+                return TIMESTAMP;
+            case UUID:
+                return UUID;
+            case STRING:
+                return STRING;
+            case BYTE_ARRAY:
+                return BYTES;
+            case NULL:
+            default:
+                throw new IllegalArgumentException("No native type spec for 
column type: " + columnType);
+        }
+    }
+
     /** {@inheritDoc} */
     @Override
     public String toString() {
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/type/TemporalNativeType.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/type/TemporalNativeType.java
index 6e47c56efb..44887deaac 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/type/TemporalNativeType.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/type/TemporalNativeType.java
@@ -17,6 +17,8 @@
 
 package org.apache.ignite.internal.type;
 
+import static org.apache.ignite.internal.lang.IgniteStringFormatter.format;
+
 import org.apache.ignite.internal.tostring.S;
 
 /**
@@ -87,6 +89,12 @@ public class TemporalNativeType extends NativeType {
         return precision;
     }
 
+    /** {@inheritDoc} */
+    @Override
+    public String displayName() {
+        return format("{}({})", super.displayName(), precision);
+    }
+
     /** {@inheritDoc} */
     @Override
     public String toString() {
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/type/VarlenNativeType.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/type/VarlenNativeType.java
index b22200a487..713514ae17 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/type/VarlenNativeType.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/type/VarlenNativeType.java
@@ -17,6 +17,8 @@
 
 package org.apache.ignite.internal.type;
 
+import static org.apache.ignite.internal.lang.IgniteStringFormatter.format;
+
 import org.apache.ignite.internal.tostring.S;
 
 /**
@@ -38,11 +40,18 @@ public class VarlenNativeType extends NativeType {
         this.len = len;
     }
 
+    /** {@inheritDoc} */
     @Override
     public boolean mismatch(NativeType type) {
         return super.mismatch(type) || len < ((VarlenNativeType) type).len;
     }
 
+    /** {@inheritDoc} */
+    @Override
+    public String displayName() {
+        return format("{}({})", super.displayName(), len);
+    }
+
     /**
      * Get length of the type, {@link Integer#MAX_VALUE} if not defined.
      */
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/type/NativeTypeSpecTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/type/NativeTypeSpecTest.java
new file mode 100644
index 0000000000..b85568cd51
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/type/NativeTypeSpecTest.java
@@ -0,0 +1,51 @@
+/*
+ * 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.internal.type;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.apache.ignite.sql.ColumnType;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.EnumSource;
+import org.junit.jupiter.params.provider.EnumSource.Mode;
+
+/** NativeType spec tests. */
+public class NativeTypeSpecTest {
+
+    @ParameterizedTest
+    // TODO: https://issues.apache.org/jira/browse/IGNITE-15200: Include 
PERIOD and DURATION after interval type support is added.
+    @EnumSource(value = ColumnType.class, mode = Mode.EXCLUDE, names = 
{"NULL", "PERIOD", "DURATION"})
+    public void testFromColumnType(ColumnType columnType) {
+        NativeTypeSpec typeSpec = NativeTypeSpec.fromColumnType(columnType);
+        assertEquals(typeSpec.asColumnType(), columnType);
+    }
+
+    @Test
+    public void testFromColumnTypeNullVal() {
+        IllegalArgumentException err = 
assertThrows(IllegalArgumentException.class,
+                () -> NativeTypeSpec.fromColumnType(ColumnType.NULL));
+        assertEquals(err.getMessage(), "No native type spec for column type: 
NULL");
+    }
+
+    @Test
+    public void testFromColumnTypeNull() {
+        assertThrows(NullPointerException.class, () -> 
NativeTypeSpec.fromColumnType(null));
+    }
+}
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 b966841c9e..cc3c1608c6 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
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.runner.app.client;
 import static 
org.apache.ignite.internal.testframework.IgniteTestUtils.assertThrowsWithCause;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.endsWith;
 import static org.hamcrest.Matchers.startsWith;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -30,6 +31,7 @@ import org.apache.ignite.lang.IgniteException;
 import org.apache.ignite.table.Table;
 import org.apache.ignite.table.Tuple;
 import org.apache.ignite.table.mapper.Mapper;
+import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 
 /**
@@ -233,13 +235,20 @@ public class ItThinClientMarshallingTest extends 
ItAbstractThinClientTest {
 
     @Test
     public void testIncompatibleTupleElementType() {
-        Table table = ignite().tables().table(TABLE_NAME);
+        var tableName = "testIncompatibleTupleElementType";
+        ignite().sql().execute(null, "CREATE TABLE " + tableName + " (KEY INT 
PRIMARY KEY, VAL VARCHAR NOT NULL)");
+
+        Table table = ignite().tables().table(tableName);
         var tupleView = table.recordView();
 
-        Tuple rec = Tuple.create().set("KEY", "1").set("VAL", BigDecimal.ONE);
+        Tuple rec = Tuple.create().set("KEY", 1).set("VAL", 1L);
 
+        // TODO: https://issues.apache.org/jira/browse/IGNITE-22965.
+        // The validation done on a client side (for a thin client), and 
messages may differ between embedded clients and thin clients.
+        // For an embedded client the message include type precision, but for 
a thin client it doesn't.
         Throwable ex = assertThrows(IgniteException.class, () -> 
tupleView.upsert(null, rec));
-        assertThat(ex.getMessage(), startsWith("Column's type mismatch"));
+        assertThat(ex.getMessage(), startsWith("Value type does not match 
[column='VAL', expected=STRING"));
+        assertThat(ex.getMessage(), endsWith(", actual=INT64]"));
     }
 
     @Test
@@ -313,6 +322,39 @@ public class ItThinClientMarshallingTest extends 
ItAbstractThinClientTest {
         assertThat(ex.getMessage(), containsString("Column 'VAL' does not 
allow NULLs"));
     }
 
+    @Test
+    public void testVarcharColumnOverflow() {
+        var tableName = "testVarcharColumnOverflow";
+
+        ignite().sql().execute(null, "CREATE TABLE " + tableName + " (KEY INT 
PRIMARY KEY, VAL VARCHAR(10))");
+
+        Table table = ignite().tables().table(tableName);
+        var tupleView = table.keyValueView();
+
+        Throwable ex = assertThrowsWithCause(
+                () -> tupleView.put(null, Tuple.create().set("KEY", 1), 
Tuple.create().set("VAL", "1".repeat(20))),
+                IgniteException.class);
+
+        assertThat(ex.getMessage(), containsString("Value too long 
[column='VAL', type=STRING(10)]"));
+    }
+
+    @Test
+    @Disabled("https://issues.apache.org/jira/browse/IGNITE-22965";)
+    public void testDecimalColumnOverflow() {
+        var tableName = "testDecimalColumnOverflow";
+
+        ignite().sql().execute(null, "CREATE TABLE " + tableName + " (KEY INT 
PRIMARY KEY, VAL DECIMAL(3,1))");
+
+        Table table = ignite().tables().table(tableName);
+        var tupleView = table.keyValueView();
+
+        Throwable ex = assertThrowsWithCause(
+                () -> tupleView.put(null, Tuple.create().set("KEY", 1), 
Tuple.create().set("VAL", new BigDecimal("12345.1"))),
+                IgniteException.class);
+
+        assertThat(ex.getMessage(), containsString("Numeric field overflow in 
column 'VAL'"));
+    }
+
     private static class TestPojo2 {
         public int key;
 
diff --git 
a/modules/schema/src/main/java/org/apache/ignite/internal/schema/Column.java 
b/modules/schema/src/main/java/org/apache/ignite/internal/schema/Column.java
index 2f371a6cd0..baf3e93016 100644
--- a/modules/schema/src/main/java/org/apache/ignite/internal/schema/Column.java
+++ b/modules/schema/src/main/java/org/apache/ignite/internal/schema/Column.java
@@ -23,6 +23,7 @@ import 
org.apache.ignite.internal.tostring.IgniteToStringExclude;
 import org.apache.ignite.internal.tostring.S;
 import org.apache.ignite.internal.type.NativeType;
 import org.apache.ignite.internal.type.NativeTypes;
+import org.apache.ignite.internal.type.VarlenNativeType;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -207,11 +208,18 @@ public class Column {
         NativeType objType = NativeTypes.fromObject(val);
 
         if (objType != null && type.mismatch(objType)) {
-            throw new InvalidTypeException("Column's type mismatch ["
-                    + "column=" + this
-                    + ", expectedType=" + type
-                    + ", actualType=" + objType
-                    + ", val=" + val + ']');
+            boolean specMatches = objType.spec() == type.spec();
+
+            if (specMatches &&  type instanceof VarlenNativeType) {
+                String error = format("Value too long [column='{}', type={}]", 
name, type.displayName());
+                throw new InvalidTypeException(error);
+            } else {
+                String error = format(
+                        "Value type does not match [column='{}', expected={}, 
actual={}]",
+                        name, type.displayName(), objType.displayName()
+                );
+                throw new InvalidTypeException(error);
+            }
         }
     }
 
@@ -250,4 +258,14 @@ public class Column {
     public static String nullConstraintViolationMessage(String columnName) {
         return format("Column '{}' does not allow NULLs", columnName);
     }
+
+    /**
+     * Returns an error message for numeric field overflow error.
+     *
+     * @param columnName Column name.
+     * @return Error message.
+     */
+    public static String numericFieldOverflow(String columnName) {
+        return format("Numeric field overflow in column '{}'", columnName);
+    }
 }
diff --git 
a/modules/schema/src/main/java/org/apache/ignite/internal/schema/row/RowAssembler.java
 
b/modules/schema/src/main/java/org/apache/ignite/internal/schema/row/RowAssembler.java
index 1296085fad..c5f7dc5913 100644
--- 
a/modules/schema/src/main/java/org/apache/ignite/internal/schema/row/RowAssembler.java
+++ 
b/modules/schema/src/main/java/org/apache/ignite/internal/schema/row/RowAssembler.java
@@ -361,10 +361,9 @@ public class RowAssembler {
 
         DecimalNativeType type = (DecimalNativeType) col.type();
 
-        if (val.setScale(type.scale(), RoundingMode.HALF_UP).precision() > 
type.precision()) {
-            throw new SchemaMismatchException("Failed to set decimal value for 
column '" + col.name() + "' "
-                    + "(max precision exceeds allocated precision)"
-                    + " [decimal=" + val + ", max precision=" + 
type.precision() + "]");
+        BigDecimal scaled = val.setScale(type.scale(), RoundingMode.HALF_UP);
+        if (scaled.precision() > type.precision()) {
+            throw new 
SchemaMismatchException(Column.numericFieldOverflow(col.name()));
         }
 
         builder.appendDecimalNotNull(val, type.scale());
diff --git 
a/modules/table/src/test/java/org/apache/ignite/internal/table/MutableRowTupleAdapterTest.java
 
b/modules/table/src/test/java/org/apache/ignite/internal/table/MutableRowTupleAdapterTest.java
index 70eaeb857c..a31a53444e 100644
--- 
a/modules/table/src/test/java/org/apache/ignite/internal/table/MutableRowTupleAdapterTest.java
+++ 
b/modules/table/src/test/java/org/apache/ignite/internal/table/MutableRowTupleAdapterTest.java
@@ -412,8 +412,12 @@ public class MutableRowTupleAdapterTest extends 
AbstractMutableTupleTest {
                 .set("string", "abcefghi")
                 .set("bytes", new byte[]{1, 2, 3, 4, 5});
 
-        assertThrowsWithCause(() -> marshaller.marshal(tuple1), 
InvalidTypeException.class, "Column's type mismatch");
-        assertThrowsWithCause(() -> marshaller.marshal(tuple2), 
InvalidTypeException.class, "Column's type mismatch");
+        assertThrowsWithCause(() -> marshaller.marshal(tuple1), 
InvalidTypeException.class,
+                "Value too long [column='BYTES', type=BYTE_ARRAY(5)]"
+        );
+        assertThrowsWithCause(() -> marshaller.marshal(tuple2), 
InvalidTypeException.class,
+                "Value too long [column='STRING', type=STRING(5)]"
+        );
 
         Tuple expected = Tuple.create().set("key", 1)
                 .set("string", "abc")
@@ -438,7 +442,7 @@ public class MutableRowTupleAdapterTest extends 
AbstractMutableTupleTest {
         Tuple tuple1 = Tuple.create().set("key", 1).set("decimal", new 
BigDecimal("123456.7"));
 
         assertThrowsWithCause(() -> marshaller.marshal(tuple1), 
SchemaMismatchException.class,
-                "Failed to set decimal value for column 'DECIMAL' (max 
precision exceeds allocated precision)");
+                "Numeric field overflow in column 'DECIMAL'");
     }
 
     @Test
diff --git 
a/modules/table/src/test/java/org/apache/ignite/internal/table/RecordBinaryViewOperationsTest.java
 
b/modules/table/src/test/java/org/apache/ignite/internal/table/RecordBinaryViewOperationsTest.java
index 27e68fbbfb..bee81c9563 100644
--- 
a/modules/table/src/test/java/org/apache/ignite/internal/table/RecordBinaryViewOperationsTest.java
+++ 
b/modules/table/src/test/java/org/apache/ignite/internal/table/RecordBinaryViewOperationsTest.java
@@ -29,7 +29,6 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Mockito.doReturn;
@@ -50,8 +49,8 @@ import 
org.apache.ignite.internal.schema.marshaller.TupleMarshallerImpl;
 import 
org.apache.ignite.internal.table.distributed.replicator.InternalSchemaVersionMismatchException;
 import org.apache.ignite.internal.table.impl.DummySchemaManagerImpl;
 import org.apache.ignite.internal.table.impl.TestTupleBuilder;
+import org.apache.ignite.internal.testframework.IgniteTestUtils;
 import org.apache.ignite.internal.type.NativeTypes;
-import org.apache.ignite.lang.IgniteException;
 import org.apache.ignite.sql.IgniteSql;
 import org.apache.ignite.table.RecordView;
 import org.apache.ignite.table.Tuple;
@@ -280,17 +279,22 @@ public class RecordBinaryViewOperationsTest extends 
TableKvOperationsTestBase {
         final Tuple tuple0 = new TestTupleBuilder().set("id", 1L).set("str", 
"qweqweqwe").set("val", 11L);
         final Tuple tuple1 = new TestTupleBuilder().set("id", 1L).set("blob", 
new byte[]{0, 1, 2, 3}).set("val", 22L);
 
-        assertThrowsWithCause(InvalidTypeException.class, () -> tbl.get(null, 
keyTuple0));
-        assertThrowsWithCause(SchemaMismatchException.class, () -> 
tbl.get(null, keyTuple1));
+        assertThrowsWithCause(InvalidTypeException.class, () -> tbl.get(null, 
keyTuple0),
+                "Value type does not match [column='ID', expected=INT64, 
actual=INT32]");
+        assertThrowsWithCause(SchemaMismatchException.class, () -> 
tbl.get(null, keyTuple1),
+                "Missed key column: ID");
 
-        assertThrowsWithCause(InvalidTypeException.class, () -> 
tbl.replace(null, tuple0));
-        assertThrowsWithCause(InvalidTypeException.class, () -> 
tbl.replace(null, tuple1));
+        String strTooLongErr = "Value too long [column='STR', type=STRING(3)]";
+        String byteArrayTooLongErr = "Value too long [column='BLOB', 
type=BYTE_ARRAY(3)]";
 
-        assertThrowsWithCause(InvalidTypeException.class, () -> 
tbl.insert(null, tuple0));
-        assertThrowsWithCause(InvalidTypeException.class, () -> 
tbl.insert(null, tuple1));
+        assertThrowsWithCause(InvalidTypeException.class, () -> 
tbl.replace(null, tuple0), strTooLongErr);
+        assertThrowsWithCause(InvalidTypeException.class, () -> 
tbl.replace(null, tuple1), byteArrayTooLongErr);
 
-        assertThrowsWithCause(InvalidTypeException.class, () -> 
tbl.replace(null, tuple0));
-        assertThrowsWithCause(InvalidTypeException.class, () -> 
tbl.replace(null, tuple1));
+        assertThrowsWithCause(InvalidTypeException.class, () -> 
tbl.insert(null, tuple0), strTooLongErr);
+        assertThrowsWithCause(InvalidTypeException.class, () -> 
tbl.insert(null, tuple1), byteArrayTooLongErr);
+
+        assertThrowsWithCause(InvalidTypeException.class, () -> 
tbl.replace(null, tuple0), strTooLongErr);
+        assertThrowsWithCause(InvalidTypeException.class, () -> 
tbl.replace(null, tuple1), byteArrayTooLongErr);
     }
 
     @Test
@@ -736,17 +740,7 @@ public class RecordBinaryViewOperationsTest extends 
TableKvOperationsTestBase {
         }
     }
 
-    private <T extends Throwable> void assertThrowsWithCause(Class<T> 
expectedType, Executable executable) {
-        Throwable ex = assertThrows(IgniteException.class, executable);
-
-        while (ex.getCause() != null) {
-            if (expectedType.isInstance(ex.getCause())) {
-                return;
-            }
-
-            ex = ex.getCause();
-        }
-
-        fail("Expected cause wasn't found.");
+    private <T extends Throwable> void assertThrowsWithCause(Class<T> 
expectedType, Executable executable, String message) {
+        IgniteTestUtils.assertThrowsWithCause(executable::execute, 
expectedType, message);
     }
 }
diff --git 
a/modules/table/src/test/java/org/apache/ignite/internal/table/type/NumericTypesSerializerTest.java
 
b/modules/table/src/test/java/org/apache/ignite/internal/table/type/NumericTypesSerializerTest.java
index f28ed756e0..88abd44b45 100644
--- 
a/modules/table/src/test/java/org/apache/ignite/internal/table/type/NumericTypesSerializerTest.java
+++ 
b/modules/table/src/test/java/org/apache/ignite/internal/table/type/NumericTypesSerializerTest.java
@@ -106,22 +106,22 @@ public class NumericTypesSerializerTest {
         assertThrowsWithCause(
                 () -> marshaller.marshal(badTup.set("decimalCol", new 
BigDecimal("123456789.0123"))),
                 MarshallerException.class,
-                "Failed to set decimal value for column"
+                "Numeric field overflow"
         );
         assertThrowsWithCause(
                 () -> marshaller.marshal(badTup.set("decimalCol", new 
BigDecimal("-1234567890123"))),
                 MarshallerException.class,
-                "Failed to set decimal value for column"
+                "Numeric field overflow"
         );
         assertThrowsWithCause(
                 () -> marshaller.marshal(badTup.set("decimalCol", new 
BigDecimal("1234567"))),
                 MarshallerException.class,
-                "Failed to set decimal value for column"
+                "Numeric field overflow"
         );
         assertThrowsWithCause(
                 () -> marshaller.marshal(badTup.set("decimalCol", new 
BigDecimal("12345678.9"))),
                 MarshallerException.class,
-                "Failed to set decimal value for column"
+                "Numeric field overflow"
         );
     }
 

Reply via email to