-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Include ON DELETE CASCADE
associations in the delete order computation
#10913
Merged
Conversation
This file contains 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
X-ref #9376 |
Hi @mpdude, |
mpdude
force-pushed
the
on-delete-cascade-order
branch
from
January 2, 2024 18:43
49b9ee7
to
fb9ff08
Compare
@Dallas62 Could you please try the change suggested in this PR? |
mpdude
force-pushed
the
on-delete-cascade-order
branch
from
January 3, 2024 08:53
4dbc2f8
to
b95529d
Compare
This was referenced Jan 3, 2024
greg0ire
reviewed
Jan 3, 2024
Feedback addressed |
greg0ire
approved these changes
Jan 3, 2024
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.
Looks good to me 👍
More than that, it was a very interesting read! Thanks for all the effort you put in this!
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 NULL
or... CASCADE
need 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,
odc
meansON DELETE CASCADE
, andref
is a regular foreign key with no extraON DELETE
semantics.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
odc
edges 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
odc
edges 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 CASCADE
associations 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 NULL
can 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.