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 8833d7571af IGNITE-27739 Fix decimal precision validation (#7639)
8833d7571af is described below

commit 8833d7571af4fdc152fe224573e90a0cb5d23924
Author: Tiago Marques Godinho <[email protected]>
AuthorDate: Tue Feb 24 10:32:26 2026 +0000

    IGNITE-27739 Fix decimal precision validation (#7639)
    
    Add step in column to validate Decimals
    Move validation from the RowAssembler class to Column. Therefore, the 
exception is triggered on validation.
---
 .../app/client/ItThinClientMarshallingTest.java    | 20 +++++++++++++++++--
 .../org/apache/ignite/internal/schema/Column.java  | 23 ++++++++++++----------
 .../ignite/internal/schema/row/RowAssembler.java   |  6 ------
 .../marshaller/TupleMarshallerStatisticsTest.java  |  2 +-
 4 files changed, 32 insertions(+), 19 deletions(-)

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 52c6a983b4b..ffa74c5f19c 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
@@ -25,6 +25,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 
 import java.math.BigDecimal;
+import java.util.Map;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.lang.ErrorGroups.Marshalling;
 import org.apache.ignite.lang.MarshallerException;
@@ -32,7 +33,6 @@ 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;
-import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.function.Executable;
 
@@ -352,7 +352,6 @@ public class ItThinClientMarshallingTest extends 
ItAbstractThinClientTest {
     }
 
     @Test
-    @Disabled("https://issues.apache.org/jira/browse/IGNITE-22965";)
     public void testDecimalColumnOverflow() {
         var tableName = "testDecimalColumnOverflow";
 
@@ -366,6 +365,23 @@ public class ItThinClientMarshallingTest extends 
ItAbstractThinClientTest {
                 "Numeric field overflow in column 'VAL'");
     }
 
+    @Test
+    void testDecimalColumnOverflow2() {
+        var tableName = "testDecimalColumnOverflow2";
+
+        ignite().sql().execute("CREATE TABLE " + tableName + " (KEY INT 
PRIMARY KEY, STR VARCHAR(10), VAL DECIMAL(6,2))");
+
+        Table table = ignite().tables().table(tableName);
+        var view = table.keyValueView();
+
+        Tuple key = Tuple.create(Map.of("key", 1));
+        Tuple value = Tuple.create(Map.of("val", new 
BigDecimal("89900.123456")));
+
+        assertThrowsMarshallerException(
+                () -> view.put(key, value),
+                "Numeric field overflow in column 'VAL'");
+    }
+
     @Test
     public void testUnsupportedObjectInTuple() {
         Table table = ignite().tables().table(TABLE_NAME);
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 8b1fd49948a..c717fca248b 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
@@ -19,11 +19,14 @@ package org.apache.ignite.internal.schema;
 
 import static org.apache.ignite.internal.lang.IgniteStringFormatter.format;
 
+import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.time.Instant;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import org.apache.ignite.internal.tostring.IgniteToStringExclude;
 import org.apache.ignite.internal.tostring.S;
+import org.apache.ignite.internal.type.DecimalNativeType;
 import org.apache.ignite.internal.type.NativeType;
 import org.apache.ignite.internal.type.NativeTypes;
 import org.apache.ignite.internal.type.VarlenNativeType;
@@ -236,6 +239,8 @@ public class Column {
             checkBounds((LocalDateTime) val, SchemaUtils.DATETIME_MIN, 
SchemaUtils.DATETIME_MAX);
         } else if (type.spec() == ColumnType.TIMESTAMP) {
             checkBounds((Instant) val, SchemaUtils.TIMESTAMP_MIN, 
SchemaUtils.TIMESTAMP_MAX);
+        } else if (type.spec() == ColumnType.DECIMAL) {
+            checkPrecision((BigDecimal) val);
         }
     }
 
@@ -246,6 +251,14 @@ public class Column {
         }
     }
 
+    private void checkPrecision(BigDecimal val) throws SchemaMismatchException 
{
+        DecimalNativeType dnt = (DecimalNativeType) type;
+        BigDecimal scaled = val.setScale(dnt.scale(), RoundingMode.HALF_UP);
+        if (scaled.precision() > dnt.precision()) {
+            throw new SchemaMismatchException(format("Numeric field overflow 
in column '{}'", name));
+        }
+    }
+
     /**
      * Creates copy of the column with assigned positions.
      *
@@ -281,14 +294,4 @@ 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 5dbb941cd70..cdf190ffdd8 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
@@ -18,7 +18,6 @@
 package org.apache.ignite.internal.schema.row;
 
 import java.math.BigDecimal;
-import java.math.RoundingMode;
 import java.time.Instant;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
@@ -361,11 +360,6 @@ public class RowAssembler {
 
         DecimalNativeType type = (DecimalNativeType) col.type();
 
-        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());
 
         shiftColumn();
diff --git 
a/modules/table/src/test/java/org/apache/ignite/internal/schema/marshaller/TupleMarshallerStatisticsTest.java
 
b/modules/table/src/test/java/org/apache/ignite/internal/schema/marshaller/TupleMarshallerStatisticsTest.java
index 89d51858072..7a6dbaf7a09 100644
--- 
a/modules/table/src/test/java/org/apache/ignite/internal/schema/marshaller/TupleMarshallerStatisticsTest.java
+++ 
b/modules/table/src/test/java/org/apache/ignite/internal/schema/marshaller/TupleMarshallerStatisticsTest.java
@@ -53,7 +53,7 @@ public class TupleMarshallerStatisticsTest {
     @ValueSource(ints = {3, 1024, CatalogUtils.MAX_DECIMAL_SCALE - PRECISION})
     public void testDecimalSizeEstimation(int columnScale) {
         SchemaDescriptor schema = new SchemaDescriptor(1,
-                new Column[]{new Column("KEY", 
NativeTypes.decimalOf(PRECISION, columnScale), false)},
+                new Column[]{new Column("KEY", NativeTypes.decimalOf(PRECISION 
+ columnScale, columnScale), false)},
                 new Column[]{new Column("UNUSED", NativeTypes.INT32, true)});
 
         TupleMarshallerImpl marshaller = 
KeyValueTestUtils.createMarshaller(schema);

Reply via email to