-
-
Notifications
You must be signed in to change notification settings - Fork 530
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
Bug fix: Allow unresolved FKs to merge with resolved FKs #7965
Conversation
…rolling whether an unresolved FK will match with a resolved FK or not.
Additional work is required for integration with DoltgreSQL. |
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! It's failing integration with Doltgres, so that needs to be investigated.
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.
This is fine for a customer fix.
But the fact that we have two different byte-incompatible representations for foreign keys depending on what statements have been run previously is bad on multiple levels. It breaks history independence. It produces an invisible schema diff. And it leads to really weird bugs like this one.
A better design would be to serialize foreign key constraints identically in all cases, and always resolve them as part of analysis. Can you please file an issue so we don't lose track of this work?
Added tracking issue for the larger work to clean up FK resolution: #7982 |
Dolt foreign keys can be in a "resolved" or "unresolved" state. A resolved FK has resolved the table and columns it references, and contains unique identifiers for the referenced columns. An unresolved FK only knows the table and column names that it references. Because of these two states, the way Dolt matches FKs differs depending on whether each key is resolved or unresolved.
Dolt has logic (
ForeignKeyCollection.GetMatchingKey()
) to match a resolved FK with an unresolved FK, but this function didn't support matching an unresolved FK with a resolved FK. That code assumed that theForeignKeyCollection
would always be from an ancestor root value and therefore it wasn't valid for the ancestor to be resolved, while a more recent root value was unresolved. However, since then, we have used this logic in our root merging logic that breaks that assumption.In a multi-session environment, one client can create a table with an unresolved FK, then a second session can load that table, resolve the FK, and commit the changes to disk. If the first session still contains references to the unresolved FK, then when it goes to commit, Dolt's merge logic wasn't able to match the unresolved FK in the session with the resolved FK that was written to disk, and the FK constraints were silently dropped from the new table version.
This PR adds a new parameter to
ForeignKeyCollection.GetMatchingKey()
to allow the caller to control whether a resolved FK should match with unresolved FKs or not. This meansForeignKeyCollection.GetMatchingKey()
doesn't have to assume its receiver instance is a ForeignKeyCollection from an ancestor root value, and instead the caller is responsible for specifying which behavior is needed.Related to #7956