Saved query delete guard inspects one node but the delete removes every node
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 39.9k
- Forks
- 3.4k
- Avg merge
- 6h 51m
- Merged PRs (30d)
- 232
Description
Bug description
The dependents guard that protects a saved query from being deleted out from under a live
dependent inspects a single node, while the delete itself removes every node the saved query
has. For a saved query with nodes in more than one DAG, a live dependent in another DAG passes
the guard, has its edge cascade-deleted, and then loses its source table.
No error is raised.
Mechanism
In products/data_modeling/backend/logic/saved_query_dag_sync.py:
- line 311 — the guard resolves one node:
Node.objects.filter(...).first() - lines 331-333 — the delete is a bulk queryset delete over every matching node
So the guard's scope and the delete's scope disagree. The guard answers "does this node have
dependents", and the delete acts on all of them.
Why it is reachable
A saved query can legitimately have nodes in several DAGs, so the asymmetry is not hypothetical.
Whether .first() returns the node whose dependents matter is arbitrary.
Suggested direction
Check dependents across every node the delete will touch, not one.
Worth doing red-first: a test with a saved query in two DAGs and a live dependent in the second
should fail on master today.
Note that tightening this will make some deletes that currently succeed start raising, so it
needs a decision about what the user sees when a cross-DAG dependent blocks a delete.
Notes
Static check on master today — both halves read in the same file. Not executed.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in products/data_modeling/backend/logic/saved_query_dag_sync.py, reading the guard around line 311 and the bulk delete at lines 331-333. Add the described red-first case with a saved query in two DAGs and a live dependent in the second. Done means dependents are checked across every node the delete touches and the cross-DAG blocking behavior is decided and covered.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100