Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
71440: sql/catalog/resolver: return UndefinedDatabase in more cases r=ajwerner a=ajwerner

In 21.1 and prior, we returned UndefinedDatabase (3D000) in cases where a
table name was used to signify a virtual table and the database did not
exist. It turns out that this behavior was important. It existed for
arbitrary implementation reasons. When that code was refactored
earlier in the 21.2 release, the behavior was removed. Now we restore
that behavior and make the behavior more consistent. When we know that
we're trying to resolve a relation in the current database and we know
that the current database does not exist, we now return the
UndefinedDatabase error.

Fixes cockroachdb#71495

Release note (bug fix): In prior betas of 21.2, some error codes returned when
looking for a descriptor in a non-existent database were changed from
UndefinedDatabase (3D000) to UndefinedObject (42704). The behavior has been
reverted and more generally name resolution when the current database is
undefined will return UndefinedDatabase.

Co-authored-by: Andrew Werner <[email protected]>
  • Loading branch information
craig[bot] and ajwerner committed Oct 14, 2021
2 parents 44226ec + a7c58d6 commit 1013cdb
Show file tree
Hide file tree
Showing 9 changed files with 52 additions and 28 deletions.
16 changes: 8 additions & 8 deletions pkg/ccl/logictestccl/testdata/logic_test/as_of
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ CREATE TABLE t (
statement ok
INSERT INTO t VALUES (2)

statement error pq: relation "t" does not exist
statement error pgcode 3D000 pq: database "test" does not exist
SELECT * FROM t AS OF SYSTEM TIME follower_read_timestamp()

statement error pq: relation "t" does not exist
statement error pgcode 3D000 pq: database "test" does not exist
SELECT * FROM t AS OF SYSTEM TIME experimental_follower_read_timestamp()

statement error pq: relation "t" does not exist
statement error pgcode 3D000 pq: database "test" does not exist
BEGIN; SET TRANSACTION AS OF SYSTEM TIME follower_read_timestamp(); SELECT * FROM t

statement ok
ROLLBACK

statement error pq: relation "t" does not exist
statement error pgcode 3D000 pq: database "test" does not exist
BEGIN AS OF SYSTEM TIME follower_read_timestamp(); SELECT * FROM t

statement ok
Expand All @@ -32,13 +32,13 @@ ROLLBACK
statement ok
SET DEFAULT_TRANSACTION_USE_FOLLOWER_READS TO TRUE

statement error pq: relation "t" does not exist
statement error pgcode 3D000 pq: database "test" does not exist
SELECT * FROM t

statement error pq: cannot execute CREATE DATABASE in a read-only transaction
CREATE DATABASE IF NOT EXISTS d2

statement error pq: relation "t" does not exist
statement error pgcode 3D000 pq: database "test" does not exist
BEGIN; SELECT * FROM t

statement ok
Expand Down Expand Up @@ -74,13 +74,13 @@ BEGIN; CREATE DATABASE IF NOT EXISTS d2; COMMIT
statement ok
SET SESSION CHARACTERISTICS AS TRANSACTION AS OF SYSTEM TIME follower_read_timestamp()

statement error pq: relation "t" does not exist
statement error pgcode 3D000 pq: database "test" does not exist
SELECT * FROM t

statement error pq: cannot execute CREATE DATABASE in a read-only transaction
CREATE DATABASE IF NOT EXISTS d2

statement error pq: relation "t" does not exist
statement error pgcode 3D000 pq: database "test" does not exist
BEGIN; SELECT * FROM t

statement ok
Expand Down
34 changes: 27 additions & 7 deletions pkg/sql/catalog/resolver/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,11 @@ func GetForDatabase(
// components because LookupObject retains those components. This is error
// prone and exists only for backwards compatibility with certain error
// reporting behaviors.
//
// Note also that if the implied current database does not exist and the name
// is either unqualified or qualified by a virtual schema, an error will be
// returned to indicate that the database does not exist. This error will be
// returned regardless of the value set on the Required flag.
func ResolveExisting(
ctx context.Context,
u *tree.UnresolvedObjectName,
Expand All @@ -387,11 +392,10 @@ func ResolveExisting(
// schema name is for a virtual schema.
_, isVirtualSchema := catconstants.VirtualSchemaNames[u.Schema()]
if isVirtualSchema || curDb != "" {
if found, prefix, result, err = r.LookupObject(ctx, lookupFlags, curDb, u.Schema(), u.Object()); found ||
err != nil || isVirtualSchema {
prefix.ExplicitDatabase = false
prefix.ExplicitSchema = true
if !found && err == nil && isVirtualSchema && prefix.Database == nil {
if found, prefix, result, err = r.LookupObject(
ctx, lookupFlags, curDb, u.Schema(), u.Object(),
); found || err != nil || isVirtualSchema {
if !found && err == nil && prefix.Database == nil { // && isVirtualSchema
// If the database was not found during the lookup for a virtual schema
// we should return a database not found error. We will use the prefix
// information to confirm this, since its possible that someone might
Expand All @@ -402,6 +406,10 @@ func ResolveExisting(
// or databases.
err = sqlerrors.NewUndefinedDatabaseError(curDb)
}
// Special case the qualification of virtual schema accesses for
// backwards compatibility.
prefix.ExplicitDatabase = false
prefix.ExplicitSchema = true
return found, prefix, result, err
}
}
Expand All @@ -417,11 +425,23 @@ func ResolveExisting(

// This is a naked object name. Use the search path.
iter := searchPath.Iter()
foundDatabase := false
for next, ok := iter.Next(); ok; next, ok = iter.Next() {
if found, prefix, result, err = r.LookupObject(ctx, lookupFlags, curDb, next,
u.Object()); found || err != nil {
if found, prefix, result, err = r.LookupObject(
ctx, lookupFlags, curDb, next, u.Object(),
); found || err != nil {
return found, prefix, result, err
}
foundDatabase = foundDatabase || prefix.Database != nil
}

// If we have a database, and we didn't find it, then we're never going to
// find it because it must not exist. This error return path is a bit of
// a rough edge, but it preserves backwards compatibility and makes sure
// we return a database does not exist error in cases where the current
// database definitely does not exist.
if curDb != "" && !foundDatabase {
return false, prefix, nil, sqlerrors.NewUndefinedDatabaseError(curDb)
}
return false, prefix, nil, nil
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/sql/catalog/resolver/resolver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ func (f *fakeMetadata) LookupObject(
if !hasDb {
return false, prefix, nil, nil
}
prefix.Database = dbdesc.NewBuilder(&descpb.DatabaseDescriptor{Name: dbName}).
BuildImmutableDatabase()
}
// Db valid, check the table name.
for tbIdx, tb := range v.tables {
Expand All @@ -148,6 +150,8 @@ func (f *fakeMetadata) LookupObject(
for i := range f.knownCatalogs {
c := &f.knownCatalogs[i]
if dbName == string(c.ctName) {
prefix.Database = dbdesc.NewBuilder(&descpb.DatabaseDescriptor{Name: dbName}).
BuildImmutableDatabase()
for j := range c.schemas {
s := &c.schemas[j]
if scName == string(s.scName) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/sql/logictest/testdata/logic_test/as_of
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ SELECT * FROM t AS OF SYSTEM TIME cluster_logical_timestamp()
statement error pq: subqueries are not allowed in AS OF SYSTEM TIME
SELECT * FROM t AS OF SYSTEM TIME (SELECT '-1h'::INTERVAL)

statement error pq: relation "t" does not exist
statement error pgcode 3D000 pq: database "test" does not exist
SELECT * FROM t AS OF SYSTEM TIME '-1h'

query T noticetrace
Expand Down
2 changes: 1 addition & 1 deletion pkg/sql/logictest/testdata/logic_test/distsql_stats
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ s1 {a} 256 4 0

# Test AS OF SYSTEM TIME

statement error pgcode 42P01 relation "data" does not exist
statement error pgcode 3D000 database "test" does not exist
CREATE STATISTICS s2 ON a FROM data AS OF SYSTEM TIME '2017'

statement ok
Expand Down
4 changes: 2 additions & 2 deletions pkg/sql/logictest/testdata/logic_test/prepare
Original file line number Diff line number Diff line change
Expand Up @@ -1019,7 +1019,7 @@ ap35145
statement ok
DROP DATABASE d35145

query error relation "pg_settings" does not exist
query error pgcode 3D000 database "d35145" does not exist
EXECUTE display_appname

statement ok
Expand All @@ -1035,7 +1035,7 @@ ap35145
statement ok
CREATE DATABASE d35145_2; SET database = d35145_2; DROP DATABASE d35145_2

query error relation "pg_settings" does not exist
query error pgcode 3D000 database "d35145_2" does not exist
EXECUTE display_appname

# Check what happens when the stmt is executed over no db whatsoever.
Expand Down
2 changes: 1 addition & 1 deletion pkg/sql/logictest/testdata/logic_test/rename_database
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ statement ok
SET sql_safe_updates = FALSE;
ALTER DATABASE test RENAME TO u

statement error pgcode 42P01 relation "kv" does not exist
statement error pgcode 3D000 database "test" does not exist
SELECT * FROM kv

statement error target database or schema does not exist
Expand Down
6 changes: 3 additions & 3 deletions pkg/sql/logictest/testdata/logic_test/scrub
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,13 @@ EXPERIMENTAL SCRUB TABLE test.fk_parent WITH OPTIONS CONSTRAINT (fkey)

# Test AS OF SYSTEM TIME

statement error pgcode 42P01 relation "xz" does not exist
statement error pgcode 3D000 database "test" does not exist
EXPERIMENTAL SCRUB TABLE xz AS OF SYSTEM TIME '2017' WITH OPTIONS PHYSICAL

statement error pgcode 42P01 relation "xz" does not exist
statement error pgcode 3D000 database "test" does not exist
EXPERIMENTAL SCRUB TABLE xz AS OF SYSTEM TIME '2017' WITH OPTIONS INDEX ALL

statement error pgcode 42P01 relation "xz" does not exist
statement error pgcode 3D000 database "test" does not exist
EXPERIMENTAL SCRUB TABLE xz AS OF SYSTEM TIME '2017' WITH OPTIONS CONSTRAINT ALL

# Test scrubbing sequences.
Expand Down
10 changes: 5 additions & 5 deletions pkg/sql/logictest/testdata/logic_test/txn_as_of
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ INSERT INTO t VALUES (2)
# Verify that transacations can be used for historical reads using BEGIN
# or SET TRANSACTION

statement error pq: relation "t" does not exist
statement error pgcode 3D000 pq: database "test" does not exist
BEGIN AS OF SYSTEM TIME '-1h'; SELECT * FROM t

statement ok
COMMIT

statement error pq: relation "t" does not exist
statement error pgcode 3D000 pq: database "test" does not exist
BEGIN; SET TRANSACTION AS OF SYSTEM TIME '-1h'; SELECT * FROM t

statement ok
Expand Down Expand Up @@ -59,13 +59,13 @@ BEGIN AS OF SYSTEM TIME '-1h'; SELECT * FROM t AS OF SYSTEM TIME '-1h'
statement ok
COMMIT

statement error pq: relation "t" does not exist
statement error pgcode 3D000 pq: database "test" does not exist
BEGIN AS OF SYSTEM TIME '2018-12-30'; SELECT * FROM t AS OF SYSTEM TIME '2018-12-30'

statement ok
COMMIT

statement error pq: relation "t" does not exist
statement error pgcode 3D000 pq: database "test" does not exist
BEGIN; SET TRANSACTION AS OF SYSTEM TIME '2018-12-30'; SELECT * FROM t AS OF SYSTEM TIME '2018-12-30'

statement ok
Expand Down Expand Up @@ -111,7 +111,7 @@ COMMIT
statement ok
BEGIN AS OF SYSTEM TIME '-1h'; SET TRANSACTION PRIORITY HIGH;

statement error pq: relation "t" does not exist
statement error pgcode 3D000 pq: database "test" does not exist
SELECT * FROM t

statement ok
Expand Down

0 comments on commit 1013cdb

Please sign in to comment.