Fixed branch control insertion bug #10016
Merged
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.
A user reported that their
dolt_branch_controltable was in a corrupted state, as they could not delete a row even though running the appropriateDELETE FROM dolt_branch_controlwould report that 1 row was affected. RunningSELECTshowed that it was still there.I was able to replicate a way of getting the table into that state, which is to insert the exact same row as an existing row but with a larger permission set.
dolt_branch_controlhandles primary key conflicts differently than other tables, as we throw a conflict when a subset is inserted. For example,'%'will match all entries that's%'can match, so's%'is a subset of'%'. Of course, when taking permissions into account,'s%'may not be a subset if it has a broader permission set than'%', in which case we want to allow the insertion of's%'.The failure case was with exact matches. An exact match is still a subset when the permissions are as restrictive or more restrictive than the original, however it's not a subset when the permissions are broader, and this would result in allowing the insertion of the exact match. We convert all expressions into a specialized integer format, and store those integers in a prefix tree. Since the format will be the exact same, we end up overwriting the old entry, which is an implicit deletion without the accompanying bookkeeping in the rest of the data structure. This is what causes the mismatch, and creates the failure state.
To prevent this, we never allow insertion when there's an exact match, so you must use an
UPDATEin such cases. This will prevent that failure mode from occurring.