Skip to content

Commit ad09435

Browse files
docs: Clarify primary key preservation in query algebra
- PK of result is PK of left operand for most operators - dj.U is not an exception - it follows the same rule as left operand - Join is the only exception where PK depends on functional dependencies Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 19de1df commit ad09435

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

src/reference/specs/query-algebra.md

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,24 @@ restricted = original & "session_date > '2024-01-01'" # New object
1818

1919
### 1.2 Primary Key Preservation
2020

21-
Most operators preserve the primary key of their input. The exceptions are:
22-
23-
- **Join**: May expand or contract PK based on functional dependencies
24-
- **U & table**: Sets PK to U's attributes
21+
For most binary operators, the primary key of the result is the primary key of the **left operand**:
22+
23+
- `A & condition` → PK(A)
24+
- `A - condition` → PK(A)
25+
- `A.proj(...)` → PK(A)
26+
- `A.aggr(B, ...)` → PK(A)
27+
- `A.extend(B)` → PK(A)
28+
- `A + B` → PK(A) = PK(B)
29+
- `dj.U('x', 'y') & table` → PK(U) = (x, y)
30+
31+
The **only exception** is **Join** (`A * B`), where the result's primary key depends on functional dependencies between operands:
32+
33+
| Condition | Result PK |
34+
|-----------|-----------|
35+
| A → B (A determines B) | PK(A) |
36+
| B → A (B determines A) | PK(B) |
37+
| Both directions | PK(A) |
38+
| Neither direction | PK(A) ∪ PK(B) |
2539

2640
### 1.3 Lazy Evaluation
2741

0 commit comments

Comments
 (0)