Skip to content

Commit

Permalink
Merge #62878
Browse files Browse the repository at this point in the history
62878: catalog: fix descriptor validation early exit r=postamar a=postamar

This patch fixes a bug in doctor and crdb_internal.invalid_objects
preventing multiple validation errors originating from different
validation levels from being properly reported.

Release note: None

Co-authored-by: Marius Posta <[email protected]>
  • Loading branch information
craig[bot] and Marius Posta committed Apr 2, 2021
2 parents 9891b8d + 3ca9d16 commit 65e2090
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 15 deletions.
5 changes: 4 additions & 1 deletion pkg/sql/catalog/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,12 @@ func (vea *validationErrorAccumulator) validateDescriptorsAtLevel(
}
}
vea.currentDescriptor = nil // ensures we don't needlessly hold a reference.
if len(vea.errors) > 0 {
// Stop validating when self-validation is unsuccessful.
// This prevents panics in subsequent validation levels.
if level == ValidationLevelSelfOnly && len(vea.errors) > 0 {
return false
}
// Stop validating when target level is reached.
if vea.targetLevel <= vea.currentLevel {
return false
}
Expand Down
28 changes: 28 additions & 0 deletions pkg/sql/doctor/doctor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,34 @@ func TestExamineDescriptors(t *testing.T) {
},
expected: `Examining 2 descriptors and 2 namespace entries...
ParentID 2, ParentSchemaID 29: namespace entry "t" (1): no matching name info in draining names of dropped relation
`,
},
{ // 19
descTable: doctor.DescriptorTable{
{ID: 1, DescBytes: toBytes(t, func() *descpb.Descriptor {
desc := protoutil.Clone(validTableDesc).(*descpb.Descriptor)
tbl, _, _, _ := descpb.FromDescriptor(desc)
tbl.PrimaryIndex.Disabled = true
tbl.PrimaryIndex.InterleavedBy = make([]descpb.ForeignKeyReference, 1)
tbl.PrimaryIndex.InterleavedBy[0].Name = "bad_backref"
tbl.PrimaryIndex.InterleavedBy[0].Table = 500
tbl.PrimaryIndex.InterleavedBy[0].Index = 1
return desc
}())},
{
ID: 2,
DescBytes: toBytes(t, &descpb.Descriptor{Union: &descpb.Descriptor_Database{
Database: &descpb.DatabaseDescriptor{Name: "db", ID: 2},
}}),
},
},
namespaceTable: doctor.NamespaceTable{
{NameInfo: descpb.NameInfo{ParentID: 2, ParentSchemaID: 29, Name: "t"}, ID: 1},
{NameInfo: descpb.NameInfo{Name: "db"}, ID: 2},
},
expected: `Examining 2 descriptors and 2 namespace entries...
ParentID 2, ParentSchemaID 29: relation "t" (1): invalid interleave backreference table=500 index=1: referenced table ID 500: descriptor not found
ParentID 2, ParentSchemaID 29: relation "t" (1): unimplemented: primary key dropped without subsequent addition of new primary key in same transaction
`,
},
}
Expand Down
27 changes: 13 additions & 14 deletions pkg/sql/testdata/telemetry/error
Original file line number Diff line number Diff line change
Expand Up @@ -9,37 +9,36 @@ sql.schema.validation_errors.*

# Table descriptor validation failure on read.
feature-usage
CREATE DATABASE t;
CREATE TABLE t.test (k INT);
CREATE TABLE fktbl (id INT PRIMARY KEY);
CREATE TABLE tbl (customer INT NOT NULL REFERENCES fktbl (id));
INSERT INTO system.users VALUES ('node', NULL, true);
GRANT node TO root;
DELETE FROM system.descriptor WHERE id=52;
DELETE FROM system.descriptor WHERE id=54;
UPDATE system.descriptor
SET descriptor=decode('0a86020a05666b74626c1834203228023a00422f0a02696410011a1a080110401800300050145a0c0800100018003000501060006000200030006800700078008001004802524d0a077072696d6172791001180122026964300140004a10080010001a00200028003000380040005a007a0408002000800100880100900102980100a20106080012001800a80100b20100ba010060026a1d0a090a0561646d696e10020a080a04726f6f7410021204726f6f741801800101880103980100b201130a077072696d61727910001a02696420012800b80101c20100e80100f2010408001200f801008002009202009a020a08f8e8fdaba793e2b816b20200b80200c0021dc80200e00200', 'hex')
WHERE id IN (SELECT id FROM system.namespace WHERE name='fktbl');
REVOKE node FROM root;
DELETE FROM system.users WHERE username = 'node';
SELECT * FROM tbl;
----
error: pq: relation "tbl" (55): invalid foreign key: missing table=54: referenced table ID 54: descriptor not found
errorcodes.XXUUU
othererror.XXUUU
error: pq: internal error: relation "tbl" (53): missing fk back reference "fk_customer_ref_fktbl" to "tbl" from "fktbl"
errorcodes.XX000
sql.schema.validation_errors.read.cross_references.relation

# Type descriptor validation failure on read.
feature-usage
CREATE TYPE greeting AS ENUM('hello', 'hi');
INSERT INTO system.users VALUES ('node', NULL, true);
GRANT node TO root;
DELETE FROM system.descriptor WHERE id=57;
UPDATE system.descriptor
SET descriptor=decode('1a5d0832101d1a0020362800320e0a0140120568656c6c6f18002000320b0a018012026869180020004037480152006800722a0a090a0561646d696e10020a0b0a067075626c69631080040a080a04726f6f7410021204726f6f7418017a00', 'hex')
WHERE id IN (SELECT id FROM system.namespace WHERE name='greeting');
REVOKE node FROM root;
DELETE FROM system.users WHERE username = 'node';
SELECT 'hello'::greeting;
SELECT 'hi'::greeting
----
error: pq: type "greeting" (56): arrayTypeID 57 does not exist for "ENUM": referenced type ID 57: descriptor not found
errorcodes.XXUUU
othererror.XXUUU
sql.schema.validation_errors.read.cross_references.type
error: pq: type "" (54): empty type name
errorcodes.42601
sql.schema.validation_errors.read.self.type

# Table descriptor validation failure on transaction commit.
feature-usage
Expand All @@ -48,7 +47,7 @@ BEGIN;
ALTER TABLE t DROP CONSTRAINT "primary";
COMMIT;
----
error: pq: relation "t" (58): unimplemented: primary key dropped without subsequent addition of new primary key in same transaction
error: pq: relation "t" (56): unimplemented: primary key dropped without subsequent addition of new primary key in same transaction
errorcodes.0A000
sql.schema.validation_errors.write.pre_txn_commit.relation
unimplemented.#48026
Expand Down

0 comments on commit 65e2090

Please sign in to comment.