Skip to content

Implemented reverse-edge handling for cascade-deleted nodes in the de…#20

Open
vschmittprisma wants to merge 4 commits into
mainfrom
fix-node-deletion
Open

Implemented reverse-edge handling for cascade-deleted nodes in the de…#20
vschmittprisma wants to merge 4 commits into
mainfrom
fix-node-deletion

Conversation

@vschmittprisma

Copy link
Copy Markdown

…pendent graph, enhancing filter logic to prevent incorrect existence checks for deleted nodes.

…pendent graph, enhancing filter logic to prevent incorrect existence checks for deleted nodes.
@vschmittprisma

Copy link
Copy Markdown
Author

With the publisher selection tags { tag { id brandedContents(where:{isActive:true}){ brandKey } } }, the dependency path is Article → tags (reverse-edge) → tag (edge) → brandedContents (reverse-edge). A cascading Tag deletion emits NodeDeletion(Tag) + N×NodeDeletion(ArticleTag) + M×NodeDeletion(TagBrandedContent) in one change-set.

The brandedContents reverse-edge maps each NodeDeletion(TagBrandedContent) (via its originalEdge → Tag) into a tail re-read filter Tag{id:900}. That bubbles up into EdgeExists(tag, Tag{id:900}) → tags_some: { tag: { id: 900 } } → EXISTS articleTag WHERE tagIntId=900 — redundant (the articles are already in _id_in) and a full-scan trigger. I reproduced exactly that on current main:

{ "OR": [ { "_id_in": [11,22,33] }, { "tags_some": { "tag": { "id": "…900" } } } ] }
You were right: it's not the Edge/NodeDeletion branch (unreachable). It's the reverse-edge synthesizing an existence pinned to a tail that is itself deleted.

The fix (dependent-graph.ts)
In the reverse-edge branch of graphFilter, when a NodeDeletion synthesizes a re-read of its referenced tail, I now drop it ([]) if that tail is deleted in the same change-set. The existing folding (OrOperation.create([]) → FalseValue, and *ExistsFilter.create(..., headFilter.isFalse()) → FalseValue) then collapses the whole redundant EXISTS, leaving just the primary-key lookup. To know which ids are deleted, graphFilter now receives the MutationContextChanges (threaded from the root DependentGraph, where it was already stored as this.changes).

Result on the repro: upsertFilter = { _id_in: [11, 22, 33] }.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant