Include ON DELETE CASCADE associations in the delete order computation#10913
Merged
mpdude merged 6 commits intodoctrine:2.17.xfrom Jan 12, 2024
Merged
Include ON DELETE CASCADE associations in the delete order computation#10913mpdude merged 6 commits intodoctrine:2.17.xfrom
ON DELETE CASCADE associations in the delete order computation#10913mpdude merged 6 commits intodoctrine:2.17.xfrom
Conversation
Contributor
Author
|
X-ref #9376 |
|
Hi @mpdude, |
49b9ee7 to
fb9ff08
Compare
Contributor
Author
|
@Dallas62 Could you please try the change suggested in this PR? |
4dbc2f8 to
b95529d
Compare
This was referenced Jan 3, 2024
greg0ire
reviewed
Jan 3, 2024
Contributor
Author
|
Feedback addressed |
greg0ire
approved these changes
Jan 3, 2024
Member
greg0ire
left a comment
There was a problem hiding this comment.
Looks good to me 👍
More than that, it was a very interesting read! Thanks for all the effort you put in this!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
In order to resolve #10348, some changes were included in #10547 to improve the computed delete order for entities.
One assumption was that foreign key references with
ON DELETE SET NULLor... CASCADEneed not need to be taken into consideration when planning the deletion order, since the RDBMS would unset or cascade-delete such associations by itself when necessary. Only associations that do not use RDBMS-level cascade handling would be sequenced, to make sure the referring entity is deleted before the referred-to one.This assumption is wrong for
ON DELETE CASCADE. The following examples give reasons why we need to also consider such associations, and in addition, we need to be able to deal with cycles formed by them.In the following diagrams,
odcmeansON DELETE CASCADE, andrefis a regular foreign key with no extraON DELETEsemantics.In this example, C must be removed before B and A. If we ignore the B->A dependency in the delete order computation, the result may not to be correct. ACB is not a working solution.
This is the situation in #10912. We have to deal with a cycle in the graph. C must be removed before A as well as B. If we ignore the B->A dependency (e.g. because we set it to "optional" to get away with the cycle), we might end up with an incorrect order ACB.
This example has no possible remove order. But, if we treat
odcedges as optional, A -> C -> B would wrongly be deemed suitable.Here, we must first remove A and D in any order; then, B and C in any order. If we treat one of the
odcedges as optional, we might find the invalid solutions ABDC or DCAB.Solution implemented in this PR
First, build a graph with a node for every to-be-removed entity, and edges for
ON DELETE CASCADEassociations between those entities. Then, use Tarjan's algorithm to find strongly connected components (SCCs) in this graph. The significance of SCCs is that whenever we remove one of the entities in a SCC from the database (no matter which one), the DBMS will immediately remove all the other entities of that group as well.For every SCC, pick one (arbitrary) entity from the group to represent all entities of that group.
Then, build a second graph. Again we have nodes for all entities that are to be removed. This time, we insert edges for all regular (foreign key) associations and those with
ON DELETE CASCADE.ON DELETE SET NULLcan be left out. The edges are not added between the entities themselves, but between the entities representing the respective SCCs.Also, for all non-trivial SCCs (those containing more than a single entity), add dependency edges to indicate that all entities of the SCC shall be processed after the entity representing the group. This is to make sure we do not remove a SCC inadvertedly by removing one of its entities too early.
Run a topological sort on the second graph to get the actual delete order. Cycles in this second graph are a problem, there is no delete order.
Fixes #10912.