-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
schemadiff: validate and apply foreign key indexes #12026
Conversation
Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
…nKeyColumnCountError, MismatchingForeignKeyColumnTypeError Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
…nstraint columns Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
…ition splits into 'id int' and 'primary key (id)' parts. Primary key is always the first key in the list of keys. Handle queries such as 'modify id int primary key' (validate there isn't already a primary key, or that the existing primary key is over 'id'. add column with primary key definition... Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
Review ChecklistHello reviewers! 👋 Please follow this checklist when reviewing this Pull Request. General
If a new flag is being introduced:
If a workflow is added or modified:
Bug fixes
Non-trivial changes
New/Existing features
Backward compatibility
|
Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
…smatchError Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
Ready for review |
…eded Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
sqlescape.EscapeID(e.Key), | ||
sqlescape.EscapeID(e.Table), | ||
) | ||
} |
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.
Hmm, I'm not sure why these are 3 different error types when they seem all pretty similar? Would it be simpler to model this as one?
The first two seem to be the case of there's an FK constraint to the table itself, but in that case I think it's ok if Table
and ReferencedTable
contain the same value?
Not sure about the 3rd one, but that seems to not have a constraint name and not sure when that happens? Don't we always have to generate a constraint name anyway if it's missing and would it be fine if that name was set then on the same error?
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.
Good catch on the 1st error, MissingForeignKeyIndexError
: I've just removed it. It can never fire because, compatible with MySQL's behavior, we always add an index if one is needed, either in a CREATE TABLE
statement or in a ALTER TABLE ... ADD ... FOREIGN KEY
statement.
2nd error, MissingForeignKeyReferencedIndexError
, is when the parent table does not have an index covering the referenced columns. Here, MySQL does not add anything implicitly, because that's on a different table. The error is compatible with MySQL.
3rd error, IndexNeededByForeignKeyError
is for when you attempt to ALTER TABLE ... DROP KEY
and when that leaves a foreign key without an index covering its local columns. Compatible with MySQL, that's an error.
go/vt/schemadiff/table.go
Outdated
for i, col := range columns { | ||
// the index must cover same columns, in order, wih possibly more columns covered than requested. | ||
indexCol := index.Columns[i] | ||
if col.String() != indexCol.Column.String() { |
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.
Should this be case insensitive? So like using !strings.EqualFold
instead of !=
?
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.
Good catch, fixed
go/vt/schemadiff/table_test.go
Outdated
require.NoError(t, err) | ||
tableColumns := map[string]sqlparser.IdentifierCI{} | ||
for _, col := range c.CreateTable.TableSpec.Columns { | ||
tableColumns[col.Name.String()] = col.Name |
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.
Should this be using strings.ToLower()
as well? And should we extend the tests to have some more case mismatch cases to verify the behavior when those exist?
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.
Good catch, fixed, and added a test!
…n tests Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
…QL behavior, we implicitly add the index if missing Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
Looking for a 2nd review/approval |
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.
lgtm
* more testing for getViewDependentTableNames() * getForeignKeyParentTableNames * schema normalization: sort tables by fk reference order * minor test addition * ForeignKeyDependencyUnresolvedError * InvalidReferencedColumnInForeignKeyConstraintError, MismatchingForeignKeyColumnCountError, MismatchingForeignKeyColumnTypeError * validate or autogenerate index on local table based on foreign key constraint columns * validate referenced table key * ColumnKeyOption consts become public * adding DuplicateKeyNameError * normalize PRIMARY KEY definition: a 'id int primary key' column definition splits into 'id int' and 'primary key (id)' parts. Primary key is always the first key in the list of keys. Handle queries such as 'modify id int primary key' (validate there isn't already a primary key, or that the existing primary key is over 'id'. add column with primary key definition... * further unit test adaptations * adapting tests: adding required local index over foreign key columns * implicitly add key over foreign key columns if no appropriate key exists * normalize CREATE TABLE statement to include missing foreign key indexes * rename error: ForeignKeyColumnCountMismatchError * rename MismatchingForeignKeyColumnTypeError to ForeignKeyColumnTypeMismatchError * changes per review * add a few tests that validate an implicit index isn't added if not needed * case insensitive column comparison in indexCoversColumnsInOrder and in tests * MissingForeignKeyIndexError is not needed bcause, compatible with MySQL behavior, we implicitly add the index if missing --------- Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com>
Description
This PR extends both #11944 and #12016
(at this time both unmerged).In this PR,
schemadiff
runs the following:foreign key
constraint, table validation verifies there's an appropriate index on the local table columnsforeign key
constraint, schema validation verifies there's an appropriate index on the remote table columnsApply()
ing aADD CONSTRAINT ... FOREIGN KEY
auto-adds an appropriate index on the local table, if one does not exist. This is compliant with MySQL behavior.CREATE TABLE
is normalized to have an implicit index, if need be, for every foreign key definition. This is compliant with MySQL behavior.Tests added to validate new behavior.
Related Issue(s)
PRIMARY KEY
definition #12016Checklist
Deployment Notes