-
Notifications
You must be signed in to change notification settings - Fork 48
Implement FOREIGN KEY
constraints
#237
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
Conversation
f2ad6dd
to
a61700a
Compare
a61700a
to
1b95119
Compare
'CREATE TABLE `t2` (', | ||
' `id` int DEFAULT NULL,', | ||
' `t1_id` int DEFAULT NULL,', | ||
' CONSTRAINT `fk1` FOREIGN KEY (`t1_id`) REFERENCES `t1` (`id`) ON DELETE CASCADE', |
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.
Nice, I was looking for this and I'm glad to see we're testing for SHOW CREATE TABLE
Do we support the following FOREIGN KEY options now?
If not, let's throw when they're used. |
Of course the moment I submitted the comment I found unit tests for those. Lovely! |
$this->quote_sqlite_identifier( $referential_constraint['REFERENCED_TABLE_NAME'] ), | ||
implode( ', ', $referenced_column_names ) | ||
); | ||
if ( 'NO ACTION' !== $referential_constraint['DELETE_RULE'] ) { |
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.
It's covered by the tests but I still want to ask – NO ACTION
is the default value of DELETE_RULE
even if there is no explicit ON DELETE %s
, right?
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.
@adamziel Yes, in both MySQL and SQLite. And it never appears explicitly in the SHOW CREATE TABLE
statement. It seems that it's pretty much equivalent to RESTRICT
:
- In MySQL (InnoDB),
NO ACTION
andRESTRICT
behave exactly the same. - In SQLite, there is a tiny difference about the timing of the checks, but overall, they are still equivalent: https://sqlite.org/foreignkeys.html#fk_actions
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.
Maybe to be even more precise, we could consider translating MySQL's NO ACTION
to SQLite's RESTRICT
.
From MySQL docs:
A keyword from standard SQL. For InnoDB, this is equivalent to RESTRICT; the delete or update operation for the parent table is immediately rejected if there is a related foreign key value in the referenced table.
From SQLite docs:
The "RESTRICT" action means that the application is prohibited from deleting (for ON DELETE RESTRICT) or modifying (for ON UPDATE RESTRICT) a parent key when there exists one or more child keys mapped to it. The difference between the effect of a RESTRICT action and normal foreign key constraint enforcement is that the RESTRICT action processing happens as soon as the field is updated - not at the end of the current statement as it would with an immediate constraint, or at the end of the current transaction as it would with a deferred constraint. Even if the foreign key constraint it is attached to is deferred, configuring a RESTRICT action causes SQLite to return an error immediately if a parent key with dependent child keys is deleted or modified.
Sounds like it would be a tiny bit more correct, maybe.
This looks great, thank you @JanJakes! Feel free to merge. Tangentially, would it be easy to add support for |
Implemented in this PR:
FOREIGN KEY
constraints inCREATE TABLE
.REFECENCES
clause inCREATE TABLE
column definitions.ADD FOREIGN KEY
clause inALTER TABLE
.DROP FOREIGN KEY
clause inALTER TABLE
.DROP CONSTRAINT
clause inALTER TABLE
.DROP PRIMARY KEY
clause inALTER TABLE
.Closes #236.
Fixes #229.