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/resolver: wrong error when db does not exist for virtual schemas #69151

Merged
merged 1 commit into from
Aug 23, 2021

Conversation

fqazi
Copy link
Collaborator

@fqazi fqazi commented Aug 19, 2021

Fixes: #68060

Previously, when a database did not exist under a virtual
schema the code would fall through do a normal look up.
Before a recent refactor of the some of the internals,
we accidentally changed behavior, so that an undefined
relation error was returned. To address this, this patch
adds a check inside the resolver layer to return the correct
error instead of falling through.

Release note: None

@fqazi fqazi requested review from ajwerner and a team August 19, 2021 15:57
@cockroach-teamcity
Copy link
Member

This change is Reviewable

Copy link
Contributor

@ajwerner ajwerner 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 @fqazi)


pkg/sql/catalog/resolver/resolver.go, line 377 at r1 (raw file):

Quoted 5 lines of code…
			if found, prefix, result, err = r.LookupObject(ctx, lookupFlags, curDb, u.Schema(), u.Object()); found || err != nil {
				prefix.ExplicitDatabase = false
				prefix.ExplicitSchema = true
				return found, prefix, result, err
			} else if isVirtualSchema && !found && lookupFlags.Required {

how does this work? I see that it does, but it's surprising. The reason it's surprising is that you'll only enter the second condition if Required is true, but that means that I'd expect an err to be non-nil in which case, you would have entered the preceding branch. Did you confirm from coverage that you hit this.

It might be nice also to add more of an integration test. Here's the bad behavior @rafiss saw. Maybe something in pkg/cli/interactive_tests/?

Andrew-Werner's-MacBook-Pro:cockroach ajwerner$ ./cockroach sql --url postgresql://root@localhost:26257/mydb --insecure
#
# Welcome to the CockroachDB SQL shell.
# All statements must be terminated by a semicolon.
# To exit, type: \q.
#
warning: unable to retrieve the server's version: pq: relation "crdb_internal.node_build_info" does not exist
#
# Enter \? for a brief introduction.
#
warning: error retrieving the database name: pq: relation "crdb_internal.session_variables" does not exist
root@localhost:26257/?>

@fqazi fqazi requested a review from a team as a code owner August 20, 2021 13:59
Copy link
Contributor

@ajwerner ajwerner left a comment

Choose a reason for hiding this comment

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

Seems like the behavior change, while seeming sound, breaks stuff.

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

@fqazi fqazi changed the title sql/resolver: wrong error when db does not exist for virtual schemas WIP: sql/resolver: wrong error when db does not exist for virtual schemas Aug 20, 2021
@fqazi fqazi force-pushed the dbNotExistsError branch 3 times, most recently from 98b71d3 to 3fcc8e3 Compare August 21, 2021 01:37
@fqazi fqazi changed the title WIP: sql/resolver: wrong error when db does not exist for virtual schemas sql/resolver: wrong error when db does not exist for virtual schemas Aug 21, 2021
@fqazi fqazi changed the title sql/resolver: wrong error when db does not exist for virtual schemas WIP / Do not merge: sql/resolver: wrong error when db does not exist for virtual schemas Aug 22, 2021
@fqazi fqazi requested review from a team and gh-casper and removed request for a team August 23, 2021 15:10
@fqazi fqazi changed the title WIP / Do not merge: sql/resolver: wrong error when db does not exist for virtual schemas sql/resolver: wrong error when db does not exist for virtual schemas Aug 23, 2021
Copy link
Collaborator Author

@fqazi fqazi left a comment

Choose a reason for hiding this comment

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

Yes, I accidentally left another change in there too. I pushed the error back into ResolveExisting, since we need to know if the schema is virtual. We can move it to a higher level, but it will lead to tons of code duplication since we need to pass around if the prefix was virtual.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @gh-casper and @rafiss)


pkg/sql/catalog/resolver/resolver.go, line 377 at r1 (raw file):

Previously, ajwerner wrote…
			if found, prefix, result, err = r.LookupObject(ctx, lookupFlags, curDb, u.Schema(), u.Object()); found || err != nil {
				prefix.ExplicitDatabase = false
				prefix.ExplicitSchema = true
				return found, prefix, result, err
			} else if isVirtualSchema && !found && lookupFlags.Required {

how does this work? I see that it does, but it's surprising. The reason it's surprising is that you'll only enter the second condition if Required is true, but that means that I'd expect an err to be non-nil in which case, you would have entered the preceding branch. Did you confirm from coverage that you hit this.

It might be nice also to add more of an integration test. Here's the bad behavior @rafiss saw. Maybe something in pkg/cli/interactive_tests/?

Andrew-Werner's-MacBook-Pro:cockroach ajwerner$ ./cockroach sql --url postgresql://root@localhost:26257/mydb --insecure
#
# Welcome to the CockroachDB SQL shell.
# All statements must be terminated by a semicolon.
# To exit, type: \q.
#
warning: unable to retrieve the server's version: pq: relation "crdb_internal.node_build_info" does not exist
#
# Enter \? for a brief introduction.
#
warning: error retrieving the database name: pq: relation "crdb_internal.session_variables" does not exist
root@localhost:26257/?>

Contract wise we expect the higher-level layers to generate errors, but it is extremely tricky in this case. The name prefix resolution stuff would either need to say if the schema is virtual schema or we can modify things so that this layer

Yes, there was an existing test, which I extended to include the full error.

Copy link
Contributor

@ajwerner ajwerner 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 3 files at r4, 1 of 1 files at r5.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @fqazi and @gh-casper)


pkg/ccl/backupccl/backupresolver/targets.go, line 105 at r5 (raw file):

	ctx context.Context, flags tree.ObjectLookupFlags, dbName, scName, obName string,
) (bool, catalog.ResolvedObjectPrefix, catalog.Descriptor, error) {
	resolvedPrefix := catalog.ResolvedObjectPrefix{}

why this change?


pkg/sql/catalog/resolver/resolver.go, line 377 at r5 (raw file):

				prefix.ExplicitDatabase = false
				prefix.ExplicitSchema = true
				if !found && err == nil && isVirtualSchema && prefix.Database == nil {

is the prefix.Database == nil check necessary?


pkg/sql/catalog/resolver/resolver.go, line 378 at r5 (raw file):

				prefix.ExplicitSchema = true
				if !found && err == nil && isVirtualSchema && prefix.Database == nil {
					// If the database was not found during the lookup for a virtual schema

Can you also note that this is ignoring the Required flag.

Fixes: cockroachdb#68060

Previously, when a database did not exist under a virtual
schema the code would fall through do a normal look up.
Before a recent refactor of the some of the internals,
we accidentally changed behavior, so that an undefined
relation error was returned. To address this, this patch
adds a check inside the resolver layer to return the correct
error instead of falling through.

Release note: None
Copy link
Collaborator Author

@fqazi fqazi 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 @ajwerner and @gh-casper)


pkg/ccl/backupccl/backupresolver/targets.go, line 105 at r5 (raw file):

Previously, ajwerner wrote…

why this change?

For the backup/changefeed case the resolver did not follow the same guarantees, so it was previously always returning an empty prefix. We need to know if the table was missing or if the DB was missing. The planner implementations of LookupObject always populate ResolvedObjectPrefix, and this was the only exception. So, this corrects the behaviour and fixes the error returned on a statement like:

EXPERIMENTAL CHANGEFEED FOR information_schema.tables;

I'll add a comment saying:

// LookupObject requires that the ResolvedObjectPrefix is populated even if the object isn't found. If the database and schema are resolved, then we should at least return those.


pkg/sql/catalog/resolver/resolver.go, line 377 at r5 (raw file):

Previously, ajwerner wrote…

is the prefix.Database == nil check necessary?

Yes, we need to distinguish for cases where the database is found but the object itself isn't found. One such case I noticed was:

SELECT 1::pg_catalog.special_int, this should return a type error. I'll make this more clear in the comment too.


pkg/sql/catalog/resolver/resolver.go, line 378 at r5 (raw file):

Previously, ajwerner wrote…

Can you also note that this is ignoring the Required flag.

Good point, let me add that in

@fqazi fqazi requested a review from ajwerner August 23, 2021 17:49
Copy link
Contributor

@ajwerner ajwerner 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 (waiting on @ajwerner and @gh-casper)

@fqazi
Copy link
Collaborator Author

fqazi commented Aug 23, 2021

TFTR @ajwerner!

@fqazi
Copy link
Collaborator Author

fqazi commented Aug 23, 2021

bors r=ajwerner

@craig
Copy link
Contributor

craig bot commented Aug 23, 2021

Build succeeded:

@craig craig bot merged commit afaa938 into cockroachdb:master Aug 23, 2021
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.

sql/resolver: error handling regression on master for database that does not exist
3 participants