Skip to content

optbuilder: do not create invalid casts when building COALESCE and IF#77608

Merged
craig[bot] merged 1 commit intocockroachdb:masterfrom
mgartner:76807-invalid-casts
Mar 12, 2022
Merged

optbuilder: do not create invalid casts when building COALESCE and IF#77608
craig[bot] merged 1 commit intocockroachdb:masterfrom
mgartner:76807-invalid-casts

Conversation

@mgartner
Copy link
Copy Markdown
Contributor

@mgartner mgartner commented Mar 10, 2022

The optbuilder no longer creates invalid casts when building COALESCE
and IF expressions that have children with different types. Expressions
that previously caused internal errors now result in user-facing errors.
Both UNION and CASE expressions had similar bugs that were recently
fixed in #75219 and #76193.

This commit also updates the tree.ReType function to return ok=false
if there is no valid cast to re-type the expression to the given type.
This forces callers to explicitly deal with situations where re-typing
is not possible and it ensures that the function never creates invalid
casts. This will make it easier to track down future related bugs
because internal errors should originate from the call site of
tree.ReType rather than from logic further along in the optimization
process (in the case of #76807 the internal error originated from the
logical props builder when it attempted to lookup the volatility of the
invalid cast).

This commit also adds special logic to make casts from any tuple type to
types.AnyTuple valid immutable, implicit casts. Evaluation of these
casts are no-ops. Users cannot construct these casts, but they are built
by optbuilder in some cases.

Fixes #76807

Release justification: This is a low-risk change that fixes a minor bug.

Release note (bug fix): A bug has been fixed that caused internal errors
when COALESCE and IF expressions had inner expressions with different
types that could not be cast to a common type.

@mgartner mgartner requested review from a team, msirek and rharding6373 March 10, 2022 16:10
@mgartner mgartner requested a review from a team as a code owner March 10, 2022 16:10
@cockroach-teamcity
Copy link
Copy Markdown
Member

This change is Reviewable

@mgartner mgartner force-pushed the 76807-invalid-casts branch from a899814 to e54d1f3 Compare March 10, 2022 16:14
Copy link
Copy Markdown
Collaborator

@rharding6373 rharding6373 left a comment

Choose a reason for hiding this comment

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

Happy to see sqlsmith finding useful issues! Thanks for the quick fix. :lgtm:

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


pkg/sql/sem/tree/normalize.go, line 138 at r1 (raw file):

	case treebin.Plus:
		if v.isNumericZero(right) {
			final, _ = ReType(left, expectedType)

Why don't we care whether or not the ReType was successful here?

Copy link
Copy Markdown
Contributor

@msirek msirek left a comment

Choose a reason for hiding this comment

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

Nice observability improvement for bad casts!

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


pkg/sql/opt/optbuilder/scalar.go, line 247 at r1 (raw file):

					pgcode.DatatypeMismatch,
					"CASE types %s and %s cannot be matched",
					t.Whens[i].Val.(tree.TypedExpr).ResolvedType(), valType,

nit: Should we change the text to CASE WHEN types %s and %s cannot be matched and in the error below indicate CASE ELSE types... ?


pkg/sql/sem/tree/normalize.go, line 138 at r1 (raw file):

Previously, rharding6373 (Rachael Harding) wrote…

Why don't we care whether or not the ReType was successful here?

I had the same question.

@mgartner mgartner force-pushed the 76807-invalid-casts branch from e54d1f3 to 3becbbd Compare March 10, 2022 20:52
Copy link
Copy Markdown
Contributor Author

@mgartner mgartner 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 reviews!

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


pkg/sql/opt/optbuilder/scalar.go, line 247 at r1 (raw file):

Previously, msirek (Mark Sirek) wrote…

nit: Should we change the text to CASE WHEN types %s and %s cannot be matched and in the error below indicate CASE ELSE types... ?

Done.


pkg/sql/sem/tree/normalize.go, line 138 at r1 (raw file):

Previously, msirek (Mark Sirek) wrote…

I had the same question.

ReType returns nil, false when it's unsuccessful, and there's a check below for if final == nil {} that handles this case by returning the original expression unchanged. I added a comment below to explain.

Also, this normalization code is a remnant from the pre-cost-based-optimizer era, and I've been trying to rip it out for a few weeks. Maybe something I can finish up during breather week.

Copy link
Copy Markdown
Collaborator

@rharding6373 rharding6373 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 @rharding6373)


pkg/sql/sem/tree/normalize.go, line 138 at r1 (raw file):

Previously, mgartner (Marcus Gartner) wrote…

ReType returns nil, false when it's unsuccessful, and there's a check below for if final == nil {} that handles this case by returning the original expression unchanged. I added a comment below to explain.

Also, this normalization code is a remnant from the pre-cost-based-optimizer era, and I've been trying to rip it out for a few weeks. Maybe something I can finish up during breather week.

Thanks for the explanation.

Copy link
Copy Markdown
Contributor

@msirek msirek 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 (and 1 stale) (waiting on @rharding6373)


pkg/sql/sem/tree/normalize.go, line 138 at r1 (raw file):

Previously, rharding6373 (Rachael Harding) wrote…

Thanks for the explanation.

Yes, thanks!
:lgtm:

@mgartner mgartner force-pushed the 76807-invalid-casts branch from 3becbbd to 96eecb7 Compare March 11, 2022 14:25
@mgartner
Copy link
Copy Markdown
Contributor Author

I've had to add some logic to make casts from any tuple type to the special type types.AnyTuple valid to prevent regressions. Feel free to take another look.

Copy link
Copy Markdown
Collaborator

@rharding6373 rharding6373 left a comment

Choose a reason for hiding this comment

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

:lgtm:

Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (and 1 stale) (waiting on @msirek and @rharding6373)

The optbuilder no longer creates invalid casts when building COALESCE
and IF expressions that have children with different types. Expressions
that previously caused internal errors now result in user-facing errors.
Both UNION and CASE expressions had similar bugs that were recently
fixed in cockroachdb#75219 and cockroachdb#76193.

This commit also updates the `tree.ReType` function to return `ok=false`
if there is no valid cast to re-type the expression to the given type.
This forces callers to explicitly deal with situations where re-typing
is not possible and it ensures that the function never creates invalid
casts. This will make it easier to track down future related bugs
because internal errors should originate from the call site of
`tree.ReType` rather than from logic further along in the optimization
process (in the case of cockroachdb#76807 the internal error originated from the
logical props builder when it attempted to lookup the volatility of the
invalid cast).

This commit also adds special logic to make casts from any tuple type to
`types.AnyTuple` valid immutable, implicit casts. Evaluation of these
casts are no-ops. Users cannot construct these casts, but they are built
by optbuilder in some cases.

Fixes cockroachdb#76807

Release justification: This is a low-risk change that fixes a minor bug.

Release note (bug fix): A bug has been fixed that caused internal errors
when COALESCE and IF expressions had inner expressions with different
types that could not be cast to a common type.
@mgartner mgartner force-pushed the 76807-invalid-casts branch from 96eecb7 to e55e6b6 Compare March 11, 2022 18:52
Copy link
Copy Markdown
Contributor

@msirek msirek left a comment

Choose a reason for hiding this comment

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

:lgtm:

Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (and 1 stale) (waiting on @msirek and @rharding6373)

@mgartner
Copy link
Copy Markdown
Contributor Author

TFTRs!

bors r+

@craig
Copy link
Copy Markdown
Contributor

craig bot commented Mar 12, 2022

Build succeeded:

@craig craig bot merged commit af747e7 into cockroachdb:master Mar 12, 2022
@blathers-crl
Copy link
Copy Markdown

blathers-crl bot commented Mar 12, 2022

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 backport branch refs/heads/blathers/backport-release-21.1-77608: POST https://api.github.com/repos/cockroachlabs/cockroach/git/refs: 403 Resource not accessible by integration []

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


error creating backport branch refs/heads/blathers/backport-release-21.2-77608: POST https://api.github.com/repos/cockroachlabs/cockroach/git/refs: 403 Resource not accessible by integration []

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


🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is otan.

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.

optbuilder: do not add invalid casts when building COALESCE and IF expressions

4 participants