Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(go/adbc/driver/snowflake): handling of integer values sent for NUMBER columns #1267

Merged
merged 9 commits into from
Nov 9, 2023

Conversation

CurtHagenlocher
Copy link
Contributor

@CurtHagenlocher CurtHagenlocher commented Nov 7, 2023

Fixes #1242.

Copy link

github-actions bot commented Nov 7, 2023

⚠️ Please follow the Conventional Commits format in CONTRIBUTING.md for PR titles.

@CurtHagenlocher CurtHagenlocher changed the title Fix handling of integer values sent by Snowflake for NUMBER columns fix(go/driver/snowflake): handling of integer values sent for NUMBER columns Nov 7, 2023
query := "SELECT CAST('" + numberString + fmt.Sprintf("' AS NUMBER(%d, %d)) AS RESULT", precision, scale)
decimalNumber, err := decimal128.FromString(numberString, int32(precision), int32(scale))
suite.NoError(err)
number := int64(decimalNumber.LowBits())
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 don't think this is great behavior for the driver, but it is the current behavior.

Copy link
Member

Choose a reason for hiding this comment

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

Can you add a comment here as to why the resulting value is equal to the low bits?

Copy link
Member

Choose a reason for hiding this comment

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

Do you mind filing an issue to update this? It sounds like we must error here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Filed #1277

Copy link
Contributor

@davidhcoe davidhcoe left a comment

Choose a reason for hiding this comment

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

All the driver tests pass, and my tests with data that were previously failing in #1242 are now passing with these changes.

Comment on lines +286 to +290
// We can't do a cast directly into the destination type because the numbers we get from Snowflake
// are scaled integers. So not only would the cast produce the wrong value, it also risks producing
// an error of precisions which e.g. can't hold every int64. To work around these problems, we instead
// cast into a decimal type of a precision and scale which we know will hold all values and won't
// require scaling, We then substitute the type on this array with the actual return type.
Copy link
Member

Choose a reason for hiding this comment

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

I hate this so much, but it makes sense that we have to do this because of how snowflake works.

Comment on lines +109 to +110
// For precisions of 16, 17 and 18, a conversion from int64 to float64 fails with an error
// So for these precisions, we instead convert first to a decimal128 and then to a float64.
Copy link
Member

Choose a reason for hiding this comment

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

What's the error? Should those precisions instead work and we should push a fix upstream to the Arrow lib?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The error message is "invalid: integer value 99999999999999999 not in range: -9007199254740992 to 9007199254740992". I do think that it makes sense to allow a lossy conversion in Arrow from int64 to float64 and that would avoid the need for this special case. This may require some design work in Arrow -- for instance, having the Divide kernel take a CastOptions or adding AllowFloatTruncate to ArithmeticOptions.

@lidavidm lidavidm added this to the ADBC Libraries 0.9.0 milestone Nov 7, 2023
@lidavidm
Copy link
Member

lidavidm commented Nov 7, 2023

BTW Curt: please use "fixes" or "closes" in the commit message so that GitHub picks up on it, "addresses" doesn't appear to be in its keyword list

@davidhcoe
Copy link
Contributor

@zeroshade or @lidavidm - is anything else needed to merge this?

query := "SELECT CAST('" + numberString + fmt.Sprintf("' AS NUMBER(%d, %d)) AS RESULT", precision, scale)
decimalNumber, err := decimal128.FromString(numberString, int32(precision), int32(scale))
suite.NoError(err)
number := int64(decimalNumber.LowBits())
Copy link
Member

Choose a reason for hiding this comment

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

Do you mind filing an issue to update this? It sounds like we must error here

@lidavidm lidavidm changed the title fix(go/driver/snowflake): handling of integer values sent for NUMBER columns fix(go/adbc/driver/snowflake): handling of integer values sent for NUMBER columns Nov 9, 2023
@lidavidm lidavidm merged commit 04543d2 into apache:main Nov 9, 2023
35 checks passed
vleslief-ms added a commit to vleslief-ms/arrow-adbc that referenced this pull request Nov 9, 2023
vleslief-ms pushed a commit to vleslief-ms/arrow-adbc that referenced this pull request Nov 9, 2023
vleslief-ms added a commit to vleslief-ms/arrow-adbc that referenced this pull request Nov 9, 2023
@CurtHagenlocher CurtHagenlocher deleted the dev/curth/decimals branch November 10, 2023 14:05
vleslief-ms added a commit to vleslief-ms/arrow-adbc that referenced this pull request Nov 15, 2023
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.

go/adbc/driver/snowflake: improved support for decimal128 types
4 participants