You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs: sharpen distinction between cascade() and restrict()
Lead each description with its purpose rather than using parallel
structure. cascade() prepares a delete (one-shot, trims graph, OR).
restrict() selects a data subset (chainable, preserves graph, AND).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: src/explanation/whats-new-22.md
+4-6Lines changed: 4 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -234,15 +234,13 @@ This is valuable when working with unfamiliar pipelines, large datasets, or mult
234
234
235
235
### Two Propagation Modes
236
236
237
-
The diagram supports two restriction propagation modes with different convergence semantics:
237
+
The diagram supports two restriction propagation modes designed for fundamentally different tasks.
238
238
239
-
**`cascade()`uses OR at convergence.**When a child table has multiple restricted ancestors, the child row is affected if *any* parent path reaches it. This is the right semantics for delete — if any reason exists to remove a row, it should be removed. `cascade()` is one-shot: it can only be called once on an unrestricted diagram.
239
+
**`cascade()`prepares a delete.**It takes a single restricted table expression, propagates the restriction downstream through all descendants, and **trims the diagram** to the resulting subgraph — ancestors and unrelated tables are removed entirely. Convergence uses OR: a descendant row is marked for deletion if *any* ancestor path reaches it, because if any reason exists to remove a row, it should be removed. `cascade()` is one-shot and is always followed by `preview()` or `delete()`.
240
240
241
-
**`restrict()`uses AND at convergence.**A child row is included only if *all* restricted ancestors match. This is the right semantics for data subsetting and export — only rows satisfying every condition are selected. `restrict()`is chainable: call it multiple times to build up conditions from different tables.
241
+
**`restrict()`selects a data subset.**It propagates a restriction downstream but **preserves the full diagram**, allowing `restrict()` to be called again from a different seed table. This makes it possible to build up multi-condition subsets incrementally — for example, restricting by species from one table and by date from another. Convergence uses AND: a descendant row is included only if *all* restricted ancestors match, because an export should contain only rows satisfying every condition. After chaining restrictions, use `prune()`to remove empty tables and `preview()` to inspect the result.
242
242
243
-
Both modes propagate **downstream only** — from the seed table to its descendants. `cascade()` goes further: it trims the returned Diagram to the cascade subgraph, removing all ancestors and unrelated tables. This means `delete()` operates on the entire trimmed diagram with no additional filtering. `restrict()` keeps the full graph intact (to support chaining from multiple seed tables) but only restricts the seed's descendants. This matches the semantics of foreign key cascades: deleting a session deletes its trials, not its subject.
244
-
245
-
The two modes are mutually exclusive on the same diagram. This prevents accidental mixing of incompatible semantics.
243
+
The two modes are mutually exclusive on the same diagram. This prevents accidental mixing of incompatible semantics — a delete diagram should never be reused for subsetting, and vice versa.
Apply a cascade restriction and propagate it downstream through the dependency graph. The returned Diagram is trimmed to the **cascade subgraph** — only the seed table and its descendants remain. All ancestors and unrelated tables are removed. Uses **OR** semantics at convergence — a child row is affected if *any* restricted ancestor reaches it. Designed for delete operations.
133
+
Prepare a cascading delete. Starting from a restricted table expression, propagate the restriction downstream through all descendants using **OR** semantics — a descendant row is marked for deletion if *any* ancestor path reaches it. The returned Diagram is **trimmed** to the cascade subgraph: only the seed table and its descendants remain; all ancestors and unrelated tables are removed. The trimmed diagram is ready for `preview()` and `delete()`.
134
134
135
135
| Parameter | Type | Default | Description |
136
136
|-----------|------|---------|-------------|
@@ -141,8 +141,8 @@ Apply a cascade restriction and propagate it downstream through the dependency g
141
141
142
142
**Constraints:**
143
143
144
-
-`cascade()`can only be called **once** on an unrestricted Diagram
145
-
-Cannot be mixed with `restrict()` — the two modes are mutually exclusive
144
+
-**One-shot** — can only be called once on an unrestricted Diagram
145
+
-Mutually exclusive with `restrict()`
146
146
-`table_expr.full_table_name` must be a node in the diagram
Apply a restrict condition and propagate it downstream. Only the seed table and its descendants receive restrictions — ancestors remain in the diagram but are not restricted. Unlike `cascade()`, the diagram is not trimmed (to support chaining from multiple seed tables). Uses **AND** semantics at convergence — a child row is included only if it satisfies *all* restricted ancestors. Designed for data subsetting and export operations.
168
+
Select a subset of data for export or inspection. Starting from a restricted table expression, propagate the restriction downstream through all descendants using **AND** semantics — a descendant row is included only if *all* restricted ancestors match. The full diagram is preserved (ancestors, unrelated tables) so that `restrict()` can be called again from a different seed table, building up a multi-condition subset incrementally.
169
169
170
170
| Parameter | Type | Default | Description |
171
171
|-----------|------|---------|-------------|
172
172
|`table_expr`| QueryExpression | — | A restricted table expression |
173
173
174
-
**Returns:** New `Diagram` with restrict conditions applied.
174
+
**Returns:** New `Diagram` with restrict conditions applied. The graph is not trimmed.
175
175
176
176
**Constraints:**
177
177
178
-
- Cannot be called on a cascade-restricted Diagram (mutually exclusive with `cascade()`)
178
+
-**Chainable** — call multiple times to add conditions from different seed tables
179
+
- Mutually exclusive with `cascade()`
179
180
-`table_expr.full_table_name` must be a node in the diagram
180
-
-**Can be chained** — call `restrict()` multiple times to add conditions from different tables
0 commit comments