-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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: prevent DROP SCHEMA CASCADE from droping types with references #59281
sql: prevent DROP SCHEMA CASCADE from droping types with references #59281
Conversation
This doesn't quite work for subtle reasons. We need to filter out any dependencies which are already dropped. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change looks good. Maybe I'm missing something here, but if the dependency is already dropped, then wouldn't that mean the reference is removed from the type descriptor as well?
Reviewable status: complete! 0 of 0 LGTMs obtained
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The root of the problem is in
cockroach/pkg/sql/drop_table.go
Lines 360 to 367 in a106e2f
// Remove any references to types that this table has if a job is meant to be | |
// queued. If not, then the job that is handling the drop table will also | |
// clean up all of the types to be dropped. | |
if !droppingParent { | |
if err := p.removeBackRefsFromAllTypesInTable(ctx, tableDesc); err != nil { | |
return droppedViews, err | |
} | |
} |
It turns out this thing is actually totally bogus.
CREATE SCHEMA sc1;
CREATE SCHEMA sc2;
CREATE TYPE sc2.typ AS ENUM ('a');
CREATE TABLE sc1.tab (k sc2.typ);
DROP SCHEMA sc1 CASCADE;
DROP TYPE sc2.typ;
ERROR: type "typ" has dependent objects: descriptor not found
😬
I'll add another commit.
Reviewable status: complete! 0 of 0 LGTMs obtained
f5a87ce
to
ae4ddea
Compare
Okay, added another commit to deal with the drop cascade problem. I removes an optimization that occurs during |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 2 of 4 files at r1, 1 of 1 files at r2, 2 of 2 files at r3.
Reviewable status: complete! 0 of 0 LGTMs obtained (waiting on @ajwerner)
pkg/sql/resolver.go, line 407 at r3 (raw file):
) (fullyQualifiedNames []*tree.TableName, _ error) { for _, id := range ids { desc, err := p.Descriptors().GetMutableTableVersionByID(ctx, id, p.txn)
Ideally we'd use GetImmutableTableByID
with AvoidCached: true, IncludeDropped: true, IncludeOffline: true
here. It is clunky and I do wonder whether we should just include dropped/offline descriptors by default when resolving by ID, but that's a separate topic.
pkg/sql/logictest/testdata/logic_test/drop_type, line 369 at r3 (raw file):
DROP SCHEMA schema_to_drop CASCADE;
nit: extra newline
pkg/sql/logictest/testdata/logic_test/drop_type, line 371 at r3 (raw file):
# We also want to test that it's not a problem when dropping tables which are # being deleted but show up as a dependency
Can you clarify this comment to say that we're testing that DROP SCHEMA CASCADE
correctly removes backreferences on types in a different schema?
pkg/sql/logictest/testdata/logic_test/drop_type, line 385 at r3 (raw file):
Quoted 4 lines of code…
statement ok DROP TABLE t; statement ok DROP SCHEMA schema_to_drop CASCADE;
Don't you want these to go with the previous set of statements?
ae4ddea
to
29b7664
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: complete! 0 of 0 LGTMs obtained (waiting on @lucy-zhang)
pkg/sql/resolver.go, line 407 at r3 (raw file):
Previously, lucy-zhang (Lucy Zhang) wrote…
Ideally we'd use
GetImmutableTableByID
withAvoidCached: true, IncludeDropped: true, IncludeOffline: true
here. It is clunky and I do wonder whether we should just include dropped/offline descriptors by default when resolving by ID, but that's a separate topic.
Done.
pkg/sql/logictest/testdata/logic_test/drop_type, line 371 at r3 (raw file):
Previously, lucy-zhang (Lucy Zhang) wrote…
# We also want to test that it's not a problem when dropping tables which are # being deleted but show up as a dependency
Can you clarify this comment to say that we're testing that
DROP SCHEMA CASCADE
correctly removes backreferences on types in a different schema?
Done.
pkg/sql/logictest/testdata/logic_test/drop_type, line 385 at r3 (raw file):
Previously, lucy-zhang (Lucy Zhang) wrote…
statement ok DROP TABLE t; statement ok DROP SCHEMA schema_to_drop CASCADE;
Don't you want these to go with the previous set of statements?
very much yes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 3 of 3 files at r4, 2 of 2 files at r5.
Reviewable status: complete! 0 of 0 LGTMs obtained (waiting on @ajwerner)
pkg/sql/resolver.go, line 407 at r3 (raw file):
Previously, ajwerner wrote…
Done.
FWIW Required
doesn't do anything when looking up descriptors by ID. You'll always get an error if it doesn't exist.
pkg/sql/logictest/testdata/logic_test/drop_type, line 387 at r5 (raw file):
statement ok DROP SCHEMA sc2 CASCADE;
Does the success of this statement alone indicate that removing the backreferences worked?
Before this patch, a DROP SCHEMA CASCADE could cause database corruption by dropping types which were referenced by other tables. This would lead to bad errors like: ``` ERROR: object already exists: desc 687: type ID 685 in descriptor not found: descriptor not found SQLSTATE: 42710 ``` And doctor errors like: ``` Table 687: ParentID 50, ParentSchemaID 29, Name 't': type ID 685 in descriptor not found: descriptor not found ``` Fixes cockroachdb#59021. Release note (bug fix): Fixed a bug where `DROP SCHEMA ... CASCADE` could result in types which are referenced being dropped.
Before this commit we'd errantly skip dropping type references under a false assumption that all the types were also being dropped. This could lead to dangling backreferences to types from tables in other schemas. Release note (bug fix): Fixed a bug whereby dropping a schema with a table that used a user-defined type which was not being dropped (because it is in a different schema) would result in a descriptor corruption due to a dangling back-reference to a dropped table on the type descriptor.
29b7664
to
8ba36eb
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: complete! 0 of 0 LGTMs obtained (waiting on @lucy-zhang)
pkg/sql/resolver.go, line 407 at r3 (raw file):
Previously, lucy-zhang (Lucy Zhang) wrote…
FWIW
Required
doesn't do anything when looking up descriptors by ID. You'll always get an error if it doesn't exist.
Removed.
pkg/sql/logictest/testdata/logic_test/drop_type, line 387 at r5 (raw file):
Previously, lucy-zhang (Lucy Zhang) wrote…
Does the success of this statement alone indicate that removing the backreferences worked?
It's actually the the DROP TYPE sc2.typ
which indicates that removing the backreferences worked. I split it out and added a comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 3 of 3 files at r6, 2 of 2 files at r7.
Reviewable status: complete! 0 of 0 LGTMs obtained
TFTR! bors r+ |
Build succeeded: |
Before this patch, a DROP SCHEMA CASCADE could cause database corruption
by dropping types which were referenced by other tables. This would lead to
bad errors like:
And doctor errors like:
Fixes #59021.
Release note (bug fix): Fixed a bug where
DROP SCHEMA ... CASCADE
couldresult in types which are referenced being dropped.