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
sql: fix float to integer casting #117798
Conversation
Thank you for contributing to CockroachDB. Please ensure you have followed the guidelines for creating a PR. Before a member of our team reviews your PR, I have some potential action items for you:
🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is dev-inf. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello! The updated test code all matches with postgres.
Reviewable status: complete! 0 of 0 LGTMs obtained (waiting on @DrewKimball)
pkg/ccl/logictestccl/testdata/logic_test/udf_plpgsql
line 2419 at r1 (raw file):
SELECT f(); ---- 106
postgres=# CREATE OR REPLACE FUNCTION f() RETURNS INT AS $$
postgres$# BEGIN
postgres$# RETURN 105.67::FLOAT;
postgres$# END
postgres$# $$ LANGUAGE PLpgSQL;
CREATE FUNCTION
postgres=# SELECT f();
f
-----
106
(1 row)
pkg/sql/logictest/testdata/logic_test/aggregate
line 992 at r1 (raw file):
SELECT round(variance(n), 2), round(variance(n), 2), round(variance(p)) FROM mnop ---- 0.08 0.08 9
postgres=# CREATE TABLE mnop (
postgres(# m INT PRIMARY KEY,
postgres(# n FLOAT,
postgres(# o DECIMAL,
postgres(# p BIGINT
postgres(# )
postgres-# ;
CREATE TABLE
postgres=# INSERT INTO mnop (m, n) SELECT i, (1e9 + i/100.0)::float FROM
postgres-# generate_series(1, 100) AS i(i) ;
INSERT 0 100
postgres=# UPDATE mnop SET o = n::decimal, p = (n * 10)::bigint;
UPDATE 100
postgres=# select round(variance(p)) from mnop;
round
-------
9
(1 row)
pkg/sql/logictest/testdata/logic_test/aggregate
line 997 at r1 (raw file):
SELECT round(var_pop(n), 2), round(var_pop(n), 2), round(var_pop(p)) FROM mnop ---- 0.08 0.08 9
postgres=# select round(var_pop(p)) FROM mnop;
round
-------
9
(1 row)
pkg/sql/logictest/testdata/logic_test/target_names
line 76 at r1 (raw file):
---- a column1 cos 123 1 1
postgres=# SELECT (SELECT 123 AS a),
postgres-# (VALUES (cos(1)::INT)),
postgres-# (SELECT cos(0)::INT);
a | column1 | cos
-----+---------+-----
123 | 1 | 1
(1 row)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the contribution! This looks great. I left one comment about the commit message.
Reviewed 7 of 7 files at r1, all commit messages.
Reviewable status: complete! 0 of 0 LGTMs obtained (waiting on @da-ket and @DrewKimball)
-- commits
line 9 at r1:
Can you add a release note at the bottom of the commit, like:
Release note (bug fix): A bug has been fix where casts of floats to integers truncated
the value. These casts now round a float to the nearest integer, rounding ties to even
integers.
37fe58f
to
2b6e917
Compare
Thank you for updating your pull request. My owl senses detect your PR is good for review. Please keep an eye out for any test failures in CI. 🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is dev-inf. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the review! I followed your guidance on writing the release notes.
Reviewable status: complete! 0 of 0 LGTMs obtained (waiting on @DrewKimball and @mgartner)
Previously, mgartner (Marcus Gartner) wrote…
Can you add a release note at the bottom of the commit, like:
Release note (bug fix): A bug has been fix where casts of floats to integers truncated the value. These casts now round a float to the nearest integer, rounding ties to even integers.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @mgartner , just a gentle reminder about the pending review of this pull request.
Your feedback would be greatly appreciated!
Reviewable status: complete! 0 of 0 LGTMs obtained (waiting on @DrewKimball and @mgartner)
@@ -271,7 +271,7 @@ func floatToInt(intWidth, floatWidth int32) castFunc { | |||
if math.IsNaN(float64(%[2]s)) || %[2]s <= float%[4]d(math.MinInt%[3]d) || %[2]s >= float%[4]d(math.MaxInt%[3]d) { | |||
colexecerror.ExpectedError(tree.ErrIntOutOfRange) | |||
} | |||
%[1]s = int%[3]d(%[2]s) | |||
%[1]s = int%[3]d(math.RoundToEven(%[2]s)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why RoundToEven? Does postgres do that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I was reading the postgres docs for the ROUND function. I couldn't find specific documentation on casting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the comments!
Reviewable status: complete! 0 of 0 LGTMs obtained (waiting on @DrewKimball, @mgartner, and @RaduBerinde)
pkg/sql/colexec/execgen/cmd/execgen/cast_gen_util.go
line 274 at r2 (raw file):
Previously, RaduBerinde wrote…
Ah, I was reading the postgres docs for the ROUND function. I couldn't find specific documentation on casting.
Yes, I used RoundToEven
since postgres does do that when casting floats to integers. It isn't clearly mentioned in the documentation, but it can be found in their code for built-in functions for float type. PostgreSQL follows the round to nearest, ties to even rule for both rounding of float types and their casting to integers. CRDB was follows the same tie-breaking rule for rounding, but it just truncates when casting. I thought the issue #112515 wants to align this difference to be consistent.
Previously, da-ket (daket) wrote…
Makes sense, thank you! |
Previously, casting a float value to an integer simply truncates the float. This commit fixes that by rounding the float value to the nearest integer, rounding ties to even, as in postgres. Epic: None Fixes: cockroachdb#112515 Release note (bug fix): A bug has been fixed where casts of floats to integers truncated the value. These casts now round a float to the nearest integer, rounding ties to even integers.
2b6e917
to
66be939
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great. Thanks again from contributing! I added a regression test for the change in the vectorized engine cast_gen_util.go
. I'll go ahead and merge this once all the tests pass.
Reviewed 1 of 1 files at r3, all commit messages.
Reviewable status: complete! 1 of 0 LGTMs obtained (waiting on @da-ket and @DrewKimball)
bors r+ |
Build succeeded: |
Previously, casting a float value to an integer simply truncates the float. This commit fixes that by rounding the float value to the nearest integer, rounding ties to even, as in postgres.
Epic: None
Fixes: #112515
Release note (bug fix): A bug has been fixed where casts of floats to integers
truncated the value. These casts now round a float to the nearest integer,
rounding ties to even integers.