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

Cast to Integer when there are no decimals #37

Merged
merged 3 commits into from
Nov 28, 2022
Merged

Conversation

composerinteralia
Copy link
Contributor

@composerinteralia composerinteralia commented Nov 23, 2022

Prior to this commit we'd always cast a SUM query to BigDecimal, since the column type we get from the server is 246 (i.e. TRILOGY_TYPE_NEWDECIMAL).

After this commit we'll only cast to BigDecimal if the column includes decimal digits. If there are none (i.e. if column->decimals is 0), we cast to Integer instead.

Closes #36

@matthewd
Copy link
Contributor

Just for my own future re-reading, I'll note that this is branching on whether the returned column type has any decimal digits -- i.e. DECIMAL(10,2) vs DECIMAL(10,0) -- rather than anything to do with the specific row values being returned.

@composerinteralia
Copy link
Contributor Author

composerinteralia commented Nov 23, 2022

Just for my own future re-reading, I'll note that this is branching on whether the returned column type has any decimal digits -- i.e. DECIMAL(10,2) vs DECIMAL(10,0) -- rather than anything to do with the specific row values being returned.

Thank you for reading what I meant instead of what I wrote 🤦🏻. I'll update it to say something more like that.

Prior to this commit we'd always cast a SUM query to `BigDecimal`, since
the column type we get from the server is 246 (i.e.
TRILOGY_TYPE_NEWDECIMAL).

After this commit we'll only cast to `BigDecimal` if there are digits in
the decimal place. If there are none (i.e. if column->decimals is 0), we
cast to `Integer` instead.

Closes #36
VALUE str = rb_str_new(value->data, value->data_len);
return rb_funcall(rb_mKernel, id_BigDecimal, 1, str);
if (column->decimals == 0) {
return rb_cstr2inum(value->data, 10);
Copy link
Contributor Author

@composerinteralia composerinteralia Nov 23, 2022

Choose a reason for hiding this comment

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

@HParker asked me some questions about value->data and now I wonder whether this should be rb_cstr_parse_inum (or something like that), which takes a length.

Copy link
Contributor Author

@composerinteralia composerinteralia Nov 23, 2022

Choose a reason for hiding this comment

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

Well not that, since I don't think it's public. Maybe safer to do the same thing we do in the else branch—create a Ruby string and then call the function to cast it?

Copy link
Contributor Author

@composerinteralia composerinteralia Nov 23, 2022

Choose a reason for hiding this comment

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

create a Ruby string and then call the function to cast it?

I'm going to go with that for now and leave possible optimizations as a TODO

rb_cstr2inum takes a NUL-terminated string, which `value->data` does not
appear to be. To be safe, this follows the existing pattern of casting
with a Ruby string passed to the Integer() function.
Also clean up a few duplicated lines
@composerinteralia composerinteralia requested a review from a team November 28, 2022 14:13
Copy link
Contributor

@HParker HParker left a comment

Choose a reason for hiding this comment

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

Good choice saving the optimization for later!

@composerinteralia composerinteralia merged commit b387379 into main Nov 28, 2022
@composerinteralia composerinteralia deleted the cast-to-integer branch November 28, 2022 17:42
nickborromeo added a commit that referenced this pull request Mar 18, 2023
In #37 there was a change that updated the value of SUM to be Integer if what is
being summed are all Integers. It used to be that it will _always_ return a Decimal type.

When we pulled in that change, there were tests that failed because we were doing arthimitic operations on the result of
queries that have SUM. Ruby will have different results if you divide intergers and decimals.

In order to keep that behavior for us (GitHub) while allows other consumers to use SUM and expect the _right_ type we
are introducing a new query flag that we can set in our adapter. This query flag will be what will determine if we
should be casting the value of SUM to follow the _new_ behavior or roll back to the _old_ behavior
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.

[Bug?] Performing SUM function on integer column returns BigDecimal result
3 participants