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);