Commit 8e0e965
feat(alter): scope-aware RENAME COLUMN in multi-table view/trigger bodies (A-rn3-edge)
When a view or trigger body reaches the renamed column through sources where
that column name is NOT globally unique, the flat global-uniqueness prover
could not tell whether a bare `old` bound to the renamed table or another
scope's table, so it bailed — leaving the body byte-unchanged. For a nested
subquery whose FROM owns `old` while an outer source shares the name, that was
a silent wrong-results bug: e.g. `SELECT a, (SELECT c FROM u) FROM t` after
`ALTER TABLE u RENAME COLUMN c TO cc` kept a stale `(SELECT c FROM u)` that then
re-bound bare `c` to the outer `t.c`.
Add a scope-aware fallback that runs when the flat check declines. It walks the
body with a scope stack and resolves each bare `old` innermost-scope-first to
its owning table: if every bare `old` binds to the renamed table it rewrites all
bare tokens; if none does, only the qualified `renamed.old` refs rewrite; a
genuinely mixed body (the same bare name binding to different tables in one
statement) still declines untouched. No `Expr::Column` source-span refactor is
needed — the same "uniqueness/scope, not spans" insight as the multi-source
slice, now generalized across nesting levels.
New helpers (exec/mod.rs): `walk_own_scope_columns` (exhaustive own-scope column
walk incl. `IN (SELECT)` LHS and inline `OVER(...)` parts), `resolve_bare_owner`,
`resolve_exprs_bare_owners`, `collect_bare_old_owners`, `scope_bare_old_decision`
(views) and `scope_bare_old_decision_trigger` / `collect_trigger_stmt_bare_owners`
(triggers, honouring the UPDATE/DELETE target as the outer scope). Wired into
`view_global_unique_quals` / `trigger_global_unique_quals`.
Byte-exact vs sqlite3 3.50.4 for views (scalar / EXISTS / IN-SELECT subqueries,
joins, N-level nesting, qualified-only rewrites) and trigger bodies
(INSERT … SELECT/VALUES-subquery, UPDATE/DELETE target scope). The now-passing
cases move from the `bail` invariants into the differential-equality sets; each
test keeps a genuinely-mixed case as the remaining residual.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>1 parent 7137f29 commit 8e0e965
5 files changed
Lines changed: 448 additions & 61 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
977 | 977 | | |
978 | 978 | | |
979 | 979 | | |
980 | | - | |
981 | | - | |
| 980 | + | |
| 981 | + | |
| 982 | + | |
982 | 983 | | |
983 | 984 | | |
984 | 985 | | |
985 | | - | |
986 | | - | |
987 | | - | |
988 | | - | |
989 | | - | |
990 | | - | |
991 | | - | |
992 | | - | |
993 | | - | |
994 | | - | |
| 986 | + | |
| 987 | + | |
| 988 | + | |
| 989 | + | |
| 990 | + | |
| 991 | + | |
| 992 | + | |
| 993 | + | |
| 994 | + | |
| 995 | + | |
| 996 | + | |
| 997 | + | |
| 998 | + | |
| 999 | + | |
| 1000 | + | |
| 1001 | + | |
| 1002 | + | |
| 1003 | + | |
| 1004 | + | |
| 1005 | + | |
| 1006 | + | |
| 1007 | + | |
| 1008 | + | |
995 | 1009 | | |
996 | 1010 | | |
997 | 1011 | | |
| |||
1445 | 1459 | | |
1446 | 1460 | | |
1447 | 1461 | | |
1448 | | - | |
1449 | | - | |
1450 | | - | |
| 1462 | + | |
| 1463 | + | |
| 1464 | + | |
| 1465 | + | |
1451 | 1466 | | |
1452 | 1467 | | |
1453 | 1468 | | |
| |||
1459 | 1474 | | |
1460 | 1475 | | |
1461 | 1476 | | |
1462 | | - | |
1463 | | - | |
| 1477 | + | |
| 1478 | + | |
| 1479 | + | |
| 1480 | + | |
1464 | 1481 | | |
0 commit comments