Skip to content

opt: normalize comparison with addition/subtraction of TS and INTERVALs#118307

Merged
craig[bot] merged 2 commits intocockroachdb:masterfrom
mgartner:allow-norm-comp-plus-minus-timestamp
Jan 30, 2024
Merged

opt: normalize comparison with addition/subtraction of TS and INTERVALs#118307
craig[bot] merged 2 commits intocockroachdb:masterfrom
mgartner:allow-norm-comp-plus-minus-timestamp

Conversation

@mgartner
Copy link
Copy Markdown
Contributor

@mgartner mgartner commented Jan 25, 2024

opt: add TIMESTAMP, TIMESTAMPTZ, and INTERVAL columns to comp norm tests

Release note: None

opt: normalize comparison with addition/subtraction of TS and INTERVALs

This commit lifts some of the limitations placed on comparison
normalization rules in #90266. That PR limited algebraic transformations
of comparison expressions when the types involved were anything other
than integers, decimals, or floats. Other types, like TIME, can
overflow without error during addition or subtraction, making the
transformation incorrect.

TIMESTAMP and TIMESTAMPTZ types will error on overflow when an
INTERVAL is added to or subtracted from them. So this commit allows
the rule to apply for expressions with these types. Specifically, the
following transformations are now made:

ts + const_interval [cmp] const_ts
=>
ts [cmp] const_ts - const_interval

ts - const_interval [cmp] const_ts
=>
ts [cmp] const_ts + const_interval

const_ts - ts [cmp] const_interval
=>
const_ts - const_interval [cmp] ts

This ultimately allows more rules to match, like
GenerateConstrainedScans.

Epic: None

Release note (performance improvement): The optimizer now generates more
efficient query plans for queries with comparison of timestamp and
interval columns, e.g., timestamp_col - '1 day'::INTERVAL > now().

This commit lifts some of the limitations placed on comparison
normalization rules in cockroachdb#90266. That PR limited algebraic transformations
of comparison expressions when the types involved were anything other
than integers, decimals, or floats. Other types, like `TIME`, can
overflow without error during addition or subtraction, making the
transformation incorrect.

`TIMESTAMP` and `TIMESTAMPTZ` types will error on overflow when an
`INTERVAL` is added to or subtracted from them. So this commit allows
the rule to apply for expressions with these types. Specifically, the
following transformations are now made:

    ts + const_interval [cmp] const_ts
    =>
    ts [cmp] const_ts - const_interval

    ts - const_interval [cmp] const_ts
    =>
    ts [cmp] const_ts + const_interval

    const_ts - ts [cmp] const_interval
    =>
    const_ts - const_interval [cmp] ts

This ultimately allows more rules to match, like
GenerateConstrainedScans.

Release note (performance improvement): The optimizer now generates more
efficient query plans for queries with comparison of timestamp and
interval columns, e.g., `timestamp_col - '1 day'::INTERVAL > now()`.
@mgartner mgartner requested review from a team, DrewKimball and yuzefovich January 25, 2024 14:56
@mgartner mgartner requested a review from a team as a code owner January 25, 2024 14:56
@cockroach-teamcity
Copy link
Copy Markdown
Member

This change is Reviewable

Copy link
Copy Markdown
Collaborator

@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.

:lgtm: as-is, but I think we could potentially relax the restrictions even further.

Reviewed 1 of 1 files at r1, 2 of 2 files at r2, all commit messages.
Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @mgartner and @yuzefovich)


-- commits line 13 at r2:
I think it's only TIME and TIMETZ that have this problem, since their arithmetic is modular. Maybe we can omit those specifically and allow all other arithmetic types?


pkg/sql/opt/norm/testdata/rules/comp line 167 at r2 (raw file):


# The rule does not currently apply when it would subtract two TIMESTAMPs.
# TODO(mgartner): Determine if this case is safe to allow.

FWIW, I think this is safe.

@mgartner
Copy link
Copy Markdown
Contributor Author

pkg/sql/opt/norm/testdata/rules/comp line 167 at r2 (raw file):

Previously, DrewKimball (Drew Kimball) wrote…

FWIW, I think this is safe.

It looks like INTERVALs can wrap around:

defaultdb> select '99999999999999999 years'::interval + '1000000000000000001 years'::INTERVAL;
              ?column?
-------------------------------------
  -437228672809129301 years -4 mons

Copy link
Copy Markdown
Collaborator

@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! 1 of 0 LGTMs obtained (waiting on @mgartner and @yuzefovich)


pkg/sql/opt/norm/testdata/rules/comp line 167 at r2 (raw file):

Previously, mgartner (Marcus Gartner) wrote…

It looks like INTERVALs can wrap around:

defaultdb> select '99999999999999999 years'::interval + '1000000000000000001 years'::INTERVAL;
              ?column?
-------------------------------------
  -437228672809129301 years -4 mons

Hm, well they're not supposed to...

postgres=# select '99999999999999999 years'::interval + '1000000000000000001 years'::INTERVAL;
ERROR:  interval field value out of range: "99999999999999999 years"
LINE 1: select '99999999999999999 years'::interval + '10000000000000...
               ^

@mgartner
Copy link
Copy Markdown
Contributor Author

pkg/sql/opt/norm/testdata/rules/comp line 167 at r2 (raw file):

Previously, DrewKimball (Drew Kimball) wrote…

Hm, well they're not supposed to...

postgres=# select '99999999999999999 years'::interval + '1000000000000000001 years'::INTERVAL;
ERROR:  interval field value out of range: "99999999999999999 years"
LINE 1: select '99999999999999999 years'::interval + '10000000000000...
               ^

Ya our INTERVAL type is fairly broken. They don't match Postgres semantics closely: #84078

Well, I guess it wouldn't be possible to wrap around like this when subtracting two timestamps.

Copy link
Copy Markdown
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.

Thanks for the quick fix! I'll defer to Drew on this one.

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

Copy link
Copy Markdown
Collaborator

@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.

I think it's alright to keep the limitations until our interval handling is fixed.

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

@mgartner
Copy link
Copy Markdown
Contributor Author

I've created #118475 to track lifting the restrictions further.

TFTRs!

bors r+

@craig
Copy link
Copy Markdown
Contributor

craig bot commented Jan 30, 2024

Build succeeded:

@craig craig bot merged commit 61efb1e into cockroachdb:master Jan 30, 2024
@mgartner mgartner deleted the allow-norm-comp-plus-minus-timestamp branch January 30, 2024 19:32
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.

4 participants