Skip to content

Add Decimal support for floor preimage#20099

Merged
comphead merged 10 commits intoapache:mainfrom
devanshu0987:preimage_floor_decimal
Feb 4, 2026
Merged

Add Decimal support for floor preimage#20099
comphead merged 10 commits intoapache:mainfrom
devanshu0987:preimage_floor_decimal

Conversation

@devanshu0987
Copy link
Contributor

Which issue does this PR close?

Rationale for this change

What changes are included in this PR?

  • Decimal support
  • SLT Tests for Floor preimage

Are these changes tested?

  • Unit Tests
  • SLT Tests

Are there any user-facing changes?

No

@github-actions github-actions bot added sqllogictest SQL Logic Tests (.slt) functions Changes to functions implementation labels Feb 1, 2026
@devanshu0987
Copy link
Contributor Author

@comphead @sdf-jkl Would request your review when you get time. Thanks.


// floor always returns an integer, so if value has a fractional part, there's no solution
// Check: value % one_scaled != 0 means fractional part exists
if scale > 0 && value % one_scaled != D::Native::ZERO {
Copy link
Member

Choose a reason for hiding this comment

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

What about negative scales ?
Arrow supports them.

Copy link
Contributor Author

@devanshu0987 devanshu0987 Feb 2, 2026

Choose a reason for hiding this comment

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

Hi, the logic here comes from the idea that floor(x) = 1.3 has no pre-image solution. We do not want to optimize it via this.

floor(x) will always return a floor data type but it will actually be an integer.

    // floor always returns an integer, so if n has a fractional part, there's no solution
    if n.fract() != F::zero() {
        return None;
    }

Same logic is carried over here for Decimal.

scale <= 0 is effectively an integer and hence only possibility is to check for overflow which we check in the next line.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Code review comment in the last PR: #20059 (comment)


// Decimal32: i32::MAX
// For scale=2, we add 100, so i32::MAX - 50 would overflow
assert_preimage_none(ScalarValue::Decimal32(Some(i32::MAX - 50), 9, 2));
Copy link
Member

Choose a reason for hiding this comment

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

What exactly is the idea of this test ?
2147483647 - 50 => 2147483597, has 10 digits and does not fit into precision=9
I think there is no call to add 100 at all here.

Copy link
Contributor Author

@devanshu0987 devanshu0987 Feb 2, 2026

Choose a reason for hiding this comment

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

Hi, you are right.
The comment is misleading here. And the test case should move to test_floor_preimage_decimal_non_integer

Decimal32(Some(i32::MAX - 50), 9, 2) is exactly forcing the case explained in your earlier comment.
2147483597 = 21474835.97 which has fractional part and hence the preimage will be None. This test is not the right place for this.

But, 21474835.97 logically is not representable by Decimal(9,2). That is wrong as well. I didn't think too deep here.

Thanks. Let me fix this.

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 removed a bunch of repetitive tests and moved the tests around. Now it should make sense. Please let me know.

Copy link
Contributor

@comphead comphead left a comment

Choose a reason for hiding this comment

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

Thanks @devanshu0987 maybe we can also add overflow slt tests

@devanshu0987
Copy link
Contributor Author

devanshu0987 commented Feb 3, 2026

Thanks @devanshu0987 maybe we can also add overflow slt tests

Hi @comphead , after checking, the situation is following

  • floor only accepts Decimal/Float64/Float32
  • The result is either Float64/Float32/Decimal

  • Hence, all Ints on the right hand side are coerced to Floats/Decimal. Hence, they cannot be tested via SLT tests.
  • For Float precision loss, I have added a SLT test case.
  • For Decimal, via SLT/SQL path, all Decimals are either Decimal128/Decimal256
  • Before reaching preimage stage, the Decimal values are validated against MAX_DECIMAL128_FOR_EACH_PRECISION and MAX_DECIMAL256_FOR_EACH_PRECISION
    • They reject i128:MAX and i256:MAX (which are the only values which can overflow by adding 1) before reaching preimage stage.
  • Due to this, Decimal path is not testable via SQL/SLT path. Hence, no SLT tests.

Please let me know, if the reasoning is valid.

Copy link
Contributor

@comphead comphead left a comment

Choose a reason for hiding this comment

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

Thanks @devanshu0987 it is LGTM, I'll wait for @martin-g if they have anything else to add

@alamb
Copy link
Contributor

alamb commented Feb 3, 2026

@devanshu0987 it seems like a similar technique could be used for ceil -- if you agree I will file a ticket to track

@sdf-jkl
Copy link
Contributor

sdf-jkl commented Feb 3, 2026

@alamb in #20051 (comment) you mention that it's better to keep slt tests in floor.rs instead of floor_preimage.rs, but the original floor slt tests are in a different file for multiple scalar functions:


Should we move all the new slt tests there?

@devanshu0987
Copy link
Contributor Author

devanshu0987 commented Feb 4, 2026

@devanshu0987 it seems like a similar technique could be used for ceil -- if you agree I will file a ticket to track

Hi @alamb , I would like to attempt this technique for the following functions

  • ceil and round
    • ceil(x) = 5 -> (4, 5]
    • round(x) = 5 -> [4.5, 5.5)
  • String Prefix Functions
    • left(s, 2) = 'AB' -> Lexicographically ['AB', 'AC')
      • Not sure if this is already implemented.
      • Not sure how complex this will be for Non latin strings etc.

@comphead comphead added this pull request to the merge queue Feb 4, 2026
Merged via the queue into apache:main with commit 43977da Feb 4, 2026
28 checks passed
@devanshu0987 devanshu0987 deleted the preimage_floor_decimal branch February 5, 2026 01:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

functions Changes to functions implementation sqllogictest SQL Logic Tests (.slt)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Decimal support for floor preimage

5 participants