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

sql: fix decimal evaluation edge cases #106472

Merged
merged 1 commit into from
Jul 14, 2023

Conversation

DrewKimball
Copy link
Collaborator

Previously, the logic for decimal and float division, floor division and mod operators was incorrect for a few edge cases involving NaN or Infinity values. For example, 'NaN'::DECIMAL / 0 would throw a division-by-zero error when it should evaluate to NaN and 0/'inf'::DECIMAL returned 0E-2019 instead of just 0.

This patch updates the special-case logic to mirror that of postgres, so division-by-zero errors always check the NaN case and the division by infinity case returns a 0 without extra digits.

Fixes #40929
Fixes #103633

Release note (bug fix): Fixed edge cases in decimal and float evaluation for division operators. 'NaN'::DECIMAL / 0 will now return NaN instead of a division-by-zero error, and 0 / 'inf'::DECIMAL will return 0 instead of 0E-2019.

@DrewKimball DrewKimball requested review from a team as code owners July 8, 2023 07:05
@cockroach-teamcity
Copy link
Member

This change is Reviewable

@knz knz added backport-22.2.x backport-23.1.x Flags PRs that need to be backported to 23.1 labels Jul 8, 2023
Copy link
Member

@yuzefovich yuzefovich left a comment

Choose a reason for hiding this comment

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

Reviewed 14 of 14 files at r1, all commit messages.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @DrewKimball)


-- commits line 14 at r1:
Nice! We probably should've fixed it long time ago 😅 You should also adjust sqlsmith roachtest to remove the skip for the error due to #40929.


pkg/sql/sem/tree/datum.go line 1168 at r1 (raw file):

	// DNaNDecimal is the decimal constant 'NaN'.
	DNaNDecimal = &DDecimal{Decimal: apd.Decimal{Form: apd.NaN}}

nit: it doesn't look like DNaNDecimal and DPosInfDecimal are used in other packages, so maybe not export them?


pkg/sql/logictest/testdata/logic_test/decimal line 484 at r1 (raw file):

NaN        Infinity   NaN                      NaN   NaN
-Infinity  NaN        NaN                      NaN   NaN
-Infinity  -Infinity  0                        NaN   NaN

There are some minor differences from postgres in this table. I think Inf % Inf in PG returns NaN whereas we now return 0. It'd be good to adjust these queries a bit to add ORDER BY x1, x2 and compare so that we match PG exactly.


pkg/sql/logictest/testdata/logic_test/decimal line 627 at r1 (raw file):

# infinity. The results should only have one digit each.
statement ok
CREATE TABLE regression_40929 AS SELECT g FROM generate_series(1, 1) AS g;

nit: since we have generate_series(1, 1) we could simply it to just VALUES (1), right?

Copy link
Collaborator Author

@DrewKimball DrewKimball left a comment

Choose a reason for hiding this comment

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

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @yuzefovich)


-- commits line 14 at r1:

Previously, yuzefovich (Yahor Yuzefovich) wrote…

Nice! We probably should've fixed it long time ago 😅 You should also adjust sqlsmith roachtest to remove the skip for the error due to #40929.

Good catch, Done.


pkg/sql/sem/tree/datum.go line 1168 at r1 (raw file):

Previously, yuzefovich (Yahor Yuzefovich) wrote…

nit: it doesn't look like DNaNDecimal and DPosInfDecimal are used in other packages, so maybe not export them?

Done.


pkg/sql/logictest/testdata/logic_test/decimal line 484 at r1 (raw file):

Previously, yuzefovich (Yahor Yuzefovich) wrote…

There are some minor differences from postgres in this table. I think Inf % Inf in PG returns NaN whereas we now return 0. It'd be good to adjust these queries a bit to add ORDER BY x1, x2 and compare so that we match PG exactly.

Oh, good catch - the infinity checks should check that the left side is Finite, not that it isn't NaN. I added an id column to ensure the ordering, since postgres is different for both NULL and NaN.


pkg/sql/logictest/testdata/logic_test/decimal line 627 at r1 (raw file):

Previously, yuzefovich (Yahor Yuzefovich) wrote…

nit: since we have generate_series(1, 1) we could simply it to just VALUES (1), right?

Done.

@DrewKimball DrewKimball requested a review from a team as a code owner July 10, 2023 20:44
@DrewKimball DrewKimball requested review from herkolategan and renatolabs and removed request for a team July 10, 2023 20:44
Copy link
Member

@yuzefovich yuzefovich left a comment

Choose a reason for hiding this comment

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

:lgtm:

Reviewed 8 of 8 files at r2, all commit messages.
Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @herkolategan and @renatolabs)

Copy link
Member

@yuzefovich yuzefovich left a comment

Choose a reason for hiding this comment

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

Reviewed 1 of 1 files at r3, all commit messages.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @DrewKimball, @herkolategan, and @renatolabs)


pkg/sql/colexec/execgen/cmd/execgen/overloads_bin.go line 343 at r3 (raw file):

					colexecerror.ExpectedError(err)
				}
        {{if .CheckRightIsInf}}

nit: the indentation is a bit off.


pkg/sql/colexec/execgen/cmd/execgen/overloads_bin.go line 599 at r3 (raw file):

					colexecerror.ExpectedError(err)
				}
        {{if .CheckRightIsInf}}

nit: ditto.

Previously, the logic for decimal and float division, floor division
and mod operators was incorrect for a few edge cases involving `NaN`
or `Infinity` values. For example, `'NaN'::DECIMAL / 0` would throw
a division-by-zero error when it should evaluate to `NaN` and
`0/'inf'::DECIMAL` returned `0E-2019` instead of just `0`.

This patch updates the special-case logic to mirror that of postgres,
so division-by-zero errors always check the `NaN` case and the division
by infinity case returns a `0` without extra digits.

Fixes cockroachdb#40929
Fixes cockroachdb#103633

Release note (bug fix): Fixed edge cases in decimal and float evaluation
for division operators. `'NaN'::DECIMAL / 0` will now return `NaN` instead
of a division-by-zero error, and `0 / 'inf'::DECIMAL` will return `0`
instead of `0E-2019`.
Copy link
Collaborator Author

@DrewKimball DrewKimball left a comment

Choose a reason for hiding this comment

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

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @herkolategan, @renatolabs, and @yuzefovich)


pkg/sql/colexec/execgen/cmd/execgen/overloads_bin.go line 343 at r3 (raw file):

Previously, yuzefovich (Yahor Yuzefovich) wrote…

nit: the indentation is a bit off.

Done.


pkg/sql/colexec/execgen/cmd/execgen/overloads_bin.go line 599 at r3 (raw file):

Previously, yuzefovich (Yahor Yuzefovich) wrote…

nit: ditto.

Done.

@DrewKimball
Copy link
Collaborator Author

Failure is a known flake: #106579

@DrewKimball
Copy link
Collaborator Author

TFTR!

bors r+

@craig
Copy link
Contributor

craig bot commented Jul 14, 2023

Build succeeded:

@craig craig bot merged commit 115c9ba into cockroachdb:master Jul 14, 2023
@blathers-crl
Copy link

blathers-crl bot commented Jul 14, 2023

Encountered an error creating backports. Some common things that can go wrong:

  1. The backport branch might have already existed.
  2. There was a merge conflict.
  3. The backport branch contained merge commits.

You might need to create your backport manually using the backport tool.


error creating merge commit from a8b42c9 to blathers/backport-release-22.2-106472: POST https://api.github.com/repos/cockroachdb/cockroach/merges: 409 Merge conflict []

you may need to manually resolve merge conflicts with the backport tool.

Backport to branch 22.2.x failed. See errors above.


error creating merge commit from a8b42c9 to blathers/backport-release-23.1-106472: POST https://api.github.com/repos/cockroachdb/cockroach/merges: 409 Merge conflict []

you may need to manually resolve merge conflicts with the backport tool.

Backport to branch 23.1.x failed. See errors above.


🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is dev-inf.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport-23.1.x Flags PRs that need to be backported to 23.1
Projects
None yet
4 participants