Skip to content

feat: Support decimal type for the Spark checked_add and checked_subtract functions#16302

Closed
n0r0shi wants to merge 10 commits intofacebookincubator:mainfrom
n0r0shi:checked-decimal-add-subtract
Closed

feat: Support decimal type for the Spark checked_add and checked_subtract functions#16302
n0r0shi wants to merge 10 commits intofacebookincubator:mainfrom
n0r0shi:checked-decimal-add-subtract

Conversation

@n0r0shi
Copy link
Contributor

@n0r0shi n0r0shi commented Feb 8, 2026

Summary

  • Add checked_add and checked_subtract for decimal types that throw on
    overflow instead of returning null, enabling Spark ANSI mode support for
    decimal arithmetic

Test plan

  • Normal cases: all 4 input type combinations (short+short, short+long,
    long+short, long+long)
  • Edge cases: add/subtract zero, negative numbers
  • Precision capped at 38, no overflow (small values and near-boundary)
  • Positive overflow throws error
  • Negative overflow throws error
  • Boundary overflow (max +/- 1) throws error

Closes #16301

@meta-cla
Copy link

meta-cla bot commented Feb 8, 2026

Hi @kaishu-dev!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks!

@netlify
Copy link

netlify bot commented Feb 8, 2026

Deploy Preview for meta-velox canceled.

Name Link
🔨 Latest commit f97bc38
🔍 Latest deploy log https://app.netlify.com/projects/meta-velox/deploys/69a87077ec05ac00082a106a

@n0r0shi n0r0shi force-pushed the checked-decimal-add-subtract branch from e3d80dc to b22b85d Compare February 8, 2026 16:46
@meta-cla meta-cla bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Feb 8, 2026
@n0r0shi n0r0shi force-pushed the checked-decimal-add-subtract branch 5 times, most recently from 9b2aa0e to bbe0e86 Compare February 9, 2026 07:10
Copy link
Collaborator

@rui-mo rui-mo left a comment

Choose a reason for hiding this comment

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

@n0r0shi
Copy link
Contributor Author

n0r0shi commented Feb 13, 2026

Updated the doc. Unchecked add and subtract were missing, so I added them as well. Please let me know if there's anything else needed for this PR.

Thanks! @rui-mo

Add checked decimal add and subtract functions that throw on overflow
instead of returning null. These are needed for Spark's ANSI mode where
arithmetic overflow should raise an error rather than silently produce null.
Copy link
Collaborator

@rui-mo rui-mo left a comment

Choose a reason for hiding this comment

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

Thanks. I added some nits and this change LGTM overall.

@n0r0shi
Copy link
Contributor Author

n0r0shi commented Feb 21, 2026

@rui-mo I believe I've addressed all the review comments. We'll proceed with the checked_* approach for add and subtract, as aligned in the discussion on #16361. Please let me know if there's anything else that needs to be updated. Thanks!

Copy link
Collaborator

@rui-mo rui-mo 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 all your efforts!

The allow-precision-loss flag applies to both regular and checked (ANSI mode) arithmetic functions.
In Spark, there are no separate checked expression classes. The same expression (e.g., ``Add``)
handles both ANSI and non-ANSI behavior, controlled by an ``EvalMode`` flag. In Velox, the checked
variants are registered as separate functions (e.g., ``checked_add``, ``checked_subtract``).
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: perhaps mention that they are registered as separate functions to support the TRY evaluation mode.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

addressed in 8dc879f

Copy link
Collaborator

Choose a reason for hiding this comment

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

@n0r0shi Thanks. There are some workflow failures:
https://github.com/facebookincubator/velox/actions/runs/22347057553/job/64672777202?pr=16302 and format issues. Would you please take a look?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I just added a fix in 28d89e9. I will check the next run, thanks.

@n0r0shi
Copy link
Contributor Author

n0r0shi commented Feb 26, 2026

Fixed the format issue and AddSubtractArgTypesGenerator in 28d89e9. Thanks!

@n0r0shi
Copy link
Contributor Author

n0r0shi commented Feb 27, 2026

There are 3 failures at this point, as far as I checked

20260226 14:12:32.165205 19022 File.cpp:254] preadv failed with error: Bad file descriptor

this can be related to #16543

[  FAILED  ] TaskTest.addSplitAfterBarrier

which looks relevant to #16510

So it doesn't look like my PR has introduced these failures. Please let me know otherwise @rui-mo

@rui-mo
Copy link
Collaborator

rui-mo commented Feb 27, 2026

@n0r0shi Can you please rebase to latest main? The Linux test failures should be fixed, and the Aggregate fuzzer issue is going to be fixed in #16548.

std::optional<T> t,
std::optional<U> u) {
return evaluateOnce<int128_t>(
"checked_subtract(c0, c1)", {tType, uType}, t, u);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please also review this comment: #16307 (comment), and consider adding try_* tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added try_* tests in 69afcb2. Also consolidated the default and denyPrecisionLoss cases — they now share a common helper that tests the same core scenarios, while denyPrecisionLoss retains additional test cases for its specific behavior.

@rui-mo rui-mo changed the title feat: Add checked_add and checked_subtract for Spark decimal types feat: Support decimal type for the Spark checked_add and checked_subtract functions Mar 2, 2026
Copy link
Collaborator

@rui-mo rui-mo left a comment

Choose a reason for hiding this comment

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

Thanks!

@rui-mo rui-mo added the ready-to-merge PR that have been reviewed and are ready for merging. PRs with this tag notify the Velox Meta oncall label Mar 2, 2026
@meta-codesync
Copy link

meta-codesync bot commented Mar 2, 2026

@kKPulla has imported this pull request. If you are a Meta employee, you can view this in D94939837.

@n0r0shi
Copy link
Contributor Author

n0r0shi commented Mar 3, 2026

Some checks failed but they don't appear related to my change — do I need to take any action?

@kKPulla
Copy link
Contributor

kKPulla commented Mar 3, 2026

Some checks failed but they don't appear related to my change — do I need to take any action?

Yeah the failures are for the newly added tests failing in debug mode

Note: Google Test filter = DecimalArithmeticTest.checkedSubtractDenyPrecisionLoss
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from DecimalArithmeticTest
[ RUN      ] DecimalArithmeticTest.checkedSubtractDenyPrecisionLoss

fbcode/velox/functions/sparksql/DecimalArithmetic.cpp:184:40: runtime error: signed integer overflow: 0x4b3b4ca85a86c47a098a223fffffffff + 0x4b3b4ca85a86c47a098a223fffffffff cannot be represented in type '__int128'
    #0 0x7fa39b4562bb in __int128 facebook::velox::functions::sparksql::(anonymous namespace)::DecimalAddSubtractBase::addLargeNonNegative<__int128, __int128, __int128>(__int128, __int128, unsigned char, unsigned char, unsigned char, bool&) fbcode/velox/functions/sparksql/DecimalArithmetic.cpp:184

...

SUMMARY: UndefinedBehaviorSanitizer: signed-integer-overflow fbcode/velox/functions/sparksql/DecimalArithmetic.cpp:184:40 

We also have another internal CI that detects build speed regression for sparksql/ directory that failed. @kgpai any thoughts for that?

@n0r0shi
Copy link
Contributor Author

n0r0shi commented Mar 3, 2026

It looks like the addition of whole parts at this line is undefined behavior when the sum overflows int128_t, and my test cases are the first to hit that path with values large enough to trigger it:

  const auto whole = TResult(aWhole) + TResult(bWhole) + TResult(carryToLeft);

I can wrap this with __builtin_add_overflow to detect the overflow safely:

  TResult whole;
  if (__builtin_add_overflow(TResult(aWhole), TResult(bWhole), &whole) ||
      __builtin_add_overflow(whole, TResult(carryToLeft), &whole)) {
    overflow = true;
    return 0;
  }

Does that look right to you? @kKPulla

@n0r0shi
Copy link
Contributor Author

n0r0shi commented Mar 4, 2026

@kKPulla @kgpai Pushed the change above. Let me know if there's anything I should check regarding the build speed regression.

@kKPulla
Copy link
Contributor

kKPulla commented Mar 4, 2026

@kKPulla @kgpai Pushed the change above. Let me know if there's anything I should check regarding the build speed regression.

Thanks for the update. I am reimporting to run the CI again to confirm, will keep you posted.

@kKPulla
Copy link
Contributor

kKPulla commented Mar 4, 2026

@n0r0shi @rui-mo The test failures seem to have been fixed but the build speed regression is still there. Looking further into the change, it is very likely because of the templatizing we are doing in this PR. If you have any ways to optimize build speed for sparksql functions, would appreciate if you can look into it as we are trying to reduce build speeds generally in Velox. cc: @kgpai

@n0r0shi
Copy link
Contributor Author

n0r0shi commented Mar 5, 2026

Thanks for looking into this, @kKPulla @kgpai.

The regression comes from 20 new SimpleFunctionAdapter instantiations (4 registerDecimalBinary calls × 5 type combinations each), following the exact same pattern as the existing non-checked add/subtract/multiply/divide in this file. I looked into reducing the cost but the only options would sacrifice runtime performance or change the registration framework architecture.

These checked functions are necessary for Spark ANSI and TRY mode support. Build time improvements are worth pursuing separately at the framework level, but I don't think individual feature work should be blocked by costs inherent to the existing registration pattern.

Let me know how you'd like to proceed.

@kgpai
Copy link
Contributor

kgpai commented Mar 5, 2026

@kKPulla Lets go ahead and merge this and pursue build speed improvements as a separate overall topic.

@meta-codesync meta-codesync bot closed this in 7bc1be1 Mar 5, 2026
@meta-codesync
Copy link

meta-codesync bot commented Mar 5, 2026

@kKPulla merged this pull request in 7bc1be1.

n0r0shi added a commit to n0r0shi/incubator-gluten that referenced this pull request Mar 5, 2026
Routes decimal `Add` and `Subtract` to Velox's `checked_add` and
`checked_subtract` functions when ANSI mode is enabled
(`nullOnOverflow = false`). These checked variants throw on overflow
instead of returning null, matching Spark's ANSI behavior.

Depends on facebookincubator/velox#16302 which adds `checked_add` and
`checked_subtract` support for decimal types.
n0r0shi added a commit to n0r0shi/velox that referenced this pull request Mar 5, 2026
Resolve conflicts with merged checked_add/checked_subtract (PR facebookincubator#16302).
Update multiply tests to use generic checkedDecimalArithmetic helpers.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Merged ready-to-merge PR that have been reviewed and are ready for merging. PRs with this tag notify the Velox Meta oncall

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add checked_add and checked_subtract for Spark decimal types

6 participants