IGNITE-27739 Fix decimal precision validation#7639
IGNITE-27739 Fix decimal precision validation#7639tmgodinho wants to merge 4 commits intoapache:mainfrom
Conversation
|
This should also fix: https://issues.apache.org/jira/browse/IGNITE-22965 However, there is another TODO related to that ticket: I'm not sure what we are supposed to do with that TODO: Should we make the exceptions the same in both clients?? |
290e5ed to
942ba44
Compare
| } | ||
|
|
||
| private void checkPrecision(BigDecimal val) throws SchemaMismatchException { | ||
| DecimalNativeType dnt = (DecimalNativeType) type; |
There was a problem hiding this comment.
Can this cast fail in some case?
There was a problem hiding this comment.
I don't think so, we have:
Moreover, the other bound validations are also casting explicitly:
|
|
||
| DecimalNativeType type = (DecimalNativeType) col.type(); | ||
|
|
||
| BigDecimal scaled = val.setScale(type.scale(), RoundingMode.HALF_UP); |
There was a problem hiding this comment.
Was there a test for this removed behavior that still passes?
There was a problem hiding this comment.
Good question. Yes. The actual tests that are checking for the exceptions are:
Essentially, before the PR, the validation for decimals was done here. After the PR, the validation is now done on Column#validate() with seemed to me more similar to the other checks. For instance:
I also did not find much validation code on row assembler besides checkNull and checkType and this decimals stuff. That's why I removed the check here.
The only smell I found is that the validation itself is now done under the gatherStatistics (
) method. This definitely flexes a bit for whoever is interested in finding the validation method. Nonetheless, it was already that way before.There was a problem hiding this comment.
Pull request overview
Fixes DECIMAL precision/scale overflow validation (IGNITE-27739) by relocating the overflow check from low-level row assembly to column-level validation, and updates/extends tests to cover the corrected behavior.
Changes:
- Add DECIMAL precision validation to
Column.validate(...)(triggering overflow errors during validation). - Remove DECIMAL overflow validation from
RowAssembler.appendDecimalNotNull(...). - Update and expand tests for decimal overflow and decimal size estimation.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| modules/table/src/test/java/org/apache/ignite/internal/schema/marshaller/TupleMarshallerStatisticsTest.java | Adjusts DECIMAL type parameters in the estimation test to use a valid precision/scale combination. |
| modules/schema/src/main/java/org/apache/ignite/internal/schema/row/RowAssembler.java | Removes DECIMAL overflow validation previously done during row assembly. |
| modules/schema/src/main/java/org/apache/ignite/internal/schema/Column.java | Adds DECIMAL precision validation in validate() and removes the now-unused overflow message helper. |
| modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/client/ItThinClientMarshallingTest.java | Re-enables the existing decimal overflow test and adds another overflow regression test case. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| 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) { |
There was a problem hiding this comment.
validate() unconditionally casts val to BigDecimal for DECIMAL columns. If an unsupported value type reaches here (i.e., NativeTypes.fromObject(val) returns null so the mismatch branch is skipped), this will throw a ClassCastException and bypass the usual marshalling error wrapping. Consider guarding the DECIMAL branch with an instanceof BigDecimal (or similar) so unsupported types fail via the existing, consistent type-mismatch path instead of a raw CCE.
| } else if (type.spec() == ColumnType.DECIMAL) { | |
| } else if (type.spec() == ColumnType.DECIMAL) { | |
| if (!(val instanceof BigDecimal)) { | |
| String actualTypeName = objType != null ? objType.displayName() : val.getClass().getSimpleName(); | |
| String error = format( | |
| "Value type does not match [column='{}', expected={}, actual={}]", | |
| name, type.displayName(), actualTypeName | |
| ); | |
| throw new InvalidTypeException(error); | |
| } |
https://issues.apache.org/jira/browse/IGNITE-27739
What was done: