Skip to content

fix: preserve operand width in DecimalValue checked arithmetic#7380

Open
abnobdoss wants to merge 5 commits into
vortex-data:developfrom
abnobdoss:fix/decimal-checked-add-no-upcast
Open

fix: preserve operand width in DecimalValue checked arithmetic#7380
abnobdoss wants to merge 5 commits into
vortex-data:developfrom
abnobdoss:fix/decimal-checked-add-no-upcast

Conversation

@abnobdoss
Copy link
Copy Markdown

Summary

Closes: #7022

DecimalValue::checked_add/sub/mul/div unconditionally upcast both operands to i256 and returned DecimalValue::I256, producing unnecessarily wide scalars even when both inputs were narrow (e.g. I32 + I32 → I256).

Operate at max(self, other) width instead, matching the pattern in aggregate_fn/fns/sum/decimal.rs. The old checked_binary_op helper was replaced with a local macro so each op dispatches with its own trait.

AI disclosure: Analysis, implementation, and tests were done with Claude Code under my direction and review.

API Changes

No public API signature changes (verified via ./scripts/public-api.sh).

Overflow is now caught at the target width rather than silently widening (e.g. I8(i8::MAX) + I8(1) now returns None instead of I256(128)). This felt like the most faithful reading of the issue, but I'd appreciate a sanity check that returning None on target-width overflow is the desired semantics rather than, say, promoting to the next wider variant. No in-tree caller depends on the old behavior: sum/mod.rs pre-widens the accumulator by +10 precision, decimal/scalar.rs::checked_binary_numeric requires both operands to share the same width, and sum/constant.rs uses I128 as the multiplier.

Testing

  • Updated test_decimal_value_checked_* to assert the correct variant.
  • Added tests for variant preservation, mixed-width promotion, and overflow at the target width (including i8::MIN / -1).
  • All existing tests pass (212 decimal, 14 sum).

…thmetic (vortex-data#7022)

Signed-off-by: Abanoub Doss <abanoub.doss@gmail.com>
@joseph-isaacs
Copy link
Copy Markdown
Contributor

I256 is not the maximum of the inputs. I would accept a PR doing this

@github-actions
Copy link
Copy Markdown
Contributor

This PR has been marked as stale because it has been open for 14 days with no activity. Please comment or remove the stale label if you wish to keep it active, otherwise it will be closed in 7 days

@github-actions github-actions Bot added the stale This PR is stale and will be auto-closed soon label May 18, 2026
@abnobdoss
Copy link
Copy Markdown
Author

Hi @joseph-isaacs, sorry not sure I understood - are you saying this change is fine? If so, what would the process be to get this approved / merged?

@github-actions github-actions Bot removed the stale This PR is stale and will be auto-closed soon label May 20, 2026
Comment on lines +29 to +30
let a: T = $self.cast()?;
let b: T = $other.cast()?;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can this fail?

use crate::match_each_decimal_value_type;

/// Performs a checked binary operation at the wider of the two operand types.
macro_rules! checked_binary_op {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we signify the upcast

Suggested change
macro_rules! checked_binary_op {
macro_rules! checked_widening_binary_op {

Copy link
Copy Markdown
Contributor

@joseph-isaacs joseph-isaacs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this sorry, for delay just a few small ones and we are good to go

claude and others added 4 commits May 21, 2026 00:19
…rt widening cast

Address review feedback on vortex-data#7380:
- Rename `checked_binary_op!` to `checked_widening_binary_op!` to make
  the upcast to the wider operand type explicit at call sites.
- Replace `cast()?` with `vortex_expect`, since widening a
  `DecimalValue` to a type at least as wide as itself cannot fail.

Signed-off-by: Abanoub Doss <abnobdoss@proton.me>
Signed-off-by: Claude <noreply@anthropic.com>
Signed-off-by: Abanoub Doss <abnobdoss@proton.me>
Signed-off-by: Claude <noreply@anthropic.com>
Improve error handling in decimal checked operations
@abnobdoss
Copy link
Copy Markdown
Author

abnobdoss commented May 21, 2026

Thank you @joseph-isaacs! I've updated the PR per the comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DecimalValue checked_add should not upcast to i256 unconditionally

3 participants