Repository navigation
Commit b67bea0
authored
feat(migrations): keep old model names working with expiring compatibility views (#871)
* feat(migrations): keep old model names working with expiring compatibility views
Model migrations now archive the old relation after the destination builds and
create a view at the old name that reads the new relation, with column renames
aliased back to their old names. Tables and views accept migrate_from and use
the same migration path. State is recorded as append-only, deterministic-ID
facts in a new _sqlbuild_old_name_views table; a required fact gates the new
behaviour so moves recorded before the upgrade keep today's behaviour. A model
that would replace a compatibility view is a planning error (M114).
Configured with [migrations] old_name_views (default 30d) and the old_name_view
model header; false keeps today's behaviour.
Refs CHI-391
* feat(janitor): drop expired compatibility views and reject old-name reads
The janitor lists compatibility views at old model names, drops them once they
expire or when named with --drop-old-name-view, and records each drop as an
append-only fact. General cleanup no longer archives a live compatibility view.
P008 now also rejects literal Python SQL that reads a declared old name at
compile time, and a discovered old name at plan time.
Refs CHI-391
* fix(migrations): report old-name step failures as M117
A failure while archiving the old relation or creating its compatibility view
now fails the model with M117 and its resume hint instead of the generic worker
error. View publication is isolated in one step so later privilege handling has
a single place to attach.
Refs CHI-391
* feat(docs): document compatibility views at renamed models' old names
Rewrites the migration contract that the old relation is never modified,
documents old-name views, their retention and janitor handling, the
[migrations] config and old_name_view header, and the upgrade note that janitor
and builds should run the same version.
Refs CHI-391
* test(migrations): cover old-name views end to end and every resume window
Refs CHI-391
* fix(migrations): rebind Postgres compatibility views inside the promotion transaction
Compatibility views bound to a model's relation are no longer dropped before
the build and restored afterwards. The swap, build-aside rename, and column
drop or type change of the destination now run in one transaction with the
views' rebinding, so a crash at any point leaves each view present with its
old or new definition. Views are replaced in place when their columns allow
it, so views stacked on them outside SQLBuild keep working.
Nested adapter transactions now join the outer transaction.
Refs CHI-391
* feat(migrations): copy old relations' grants to compatibility views on every adapter
The compatibility view at a renamed model's old name gets the privileges
that were granted on the old relation, read from its archive with each
warehouse's own mechanism: Snowflake SHOW GRANTS (skipping OWNERSHIP and
shares, keeping grant option), PostgreSQL table ACLs, BigQuery table IAM
bindings, Unity Catalog grants, and SQL Server object permissions. Nothing
new is granted. The statements are recorded on view_created as the additive
grants_copied column and reapplied whenever the view is re-created.
Old-name views now run on BigQuery, Databricks and SQL Server too, so the
supports_old_name_views capability and its plan note are removed. BigQuery
cannot rename views, so an old view model is re-created at the archive name.
Refs CHI-391
* feat(plan): show each old-name fact on its own row
sqb plan nests the old name under each migration with one row each for the
view expiry, column aliases, copied grants and the archive. The janitor
lists compatibility views as a tree with their expiry or drop reason, and
plan JSON gains old_name.grants_copied.
Refs CHI-391
* docs(migrations): document copied grants and old-name views on every adapter
Refs CHI-391
* test(migrations): cover copied grants, nested plan rows, and real crash windows
Postgres crash tests now close the session at the fault, as a killed process
would, so nothing after the fault can clean up; every crash point leaves the
compatibility view readable.
Refs CHI-391
* fix(migrations): read old-name view facts from the columns the state table has
Readers inspect the stored _sqlbuild_old_name_views schema and select only
the known columns it has, reading columns added later as NULL, as the
additive state-schema rule requires.
Refs CHI-391
* fix(migrations): apply the old-name skip checks when resuming pending steps
A move whose archive or view is still pending no longer resumes when the old
name is now a project destination, is a compatibility view of another move,
or the model has turned old-name views off; nothing is archived or created
and the plan shows the reason under 'left for janitor'.
Refs CHI-391
* fix(migrations): keep compatibility view privileges exact across copies, rebuilds, and archives
- Adapters read grants as structured facts and render them for the view's
exposed columns. SQL Server now copies column-level GRANT and DENY, and
PostgreSQL copies column privileges; a column the view does not expose is
skipped.
- Redefining a view keeps its current privileges instead of replaying the
grants recorded at creation: CREATE OR REPLACE on PostgreSQL, COPY GRANTS
on Snowflake, ALTER VIEW on SQL Server and Databricks. BigQuery, and a
PostgreSQL view that must be dropped, re-read the view's grants just
before and reapply them.
- Builds redefine only views that exist; a recorded view that is absent is
left for janitor's missing reconcile.
- BigQuery copies a view's IAM bindings to the archive when archiving a
view model.
- BigQuery warns with M118 which principals kept access to the old name
and also need read access on the destination table; nothing is granted.
Refs CHI-391
* fix(janitor): never drop a relation the project built at a compatibility view's name
When a recorded view's name is a project model's destination and that model
has a fingerprint there newer than the view's creation, the relation is the
project's: janitor runs no DDL, records the view as dropped with reason
missing, and lists 'name now built by model:x'. Otherwise the view is still
SQLBuild's, so expiry and --drop-old-name-view proceed, keeping the M114
remedy. Drops re-check this evidence just before running.
Refs CHI-391
* fix(migrations): trust the recorded move as ownership evidence when resuming
A resumed archive or view no longer requires the origin's own fingerprint,
which the destination build of a same-model alias move supersedes; the
recorded move and its required fact prove SQLBuild owned the origin. Resume
keeps the name-reuse, compatibility-view, and disabled checks.
Refs CHI-391
* fix(migrations): decide view ownership from definitions and reconcile view grants exactly
- Janitor drops a recorded compatibility view only when the relation at the
old name is a view whose stored definition matches the SQL SQLBuild
renders for the move, or the SQL recorded on view_created (new additive
view_sql column). Any other relation is left alone, listed as 'name now
used by another relation', and the view is recorded as missing. Drops
re-check just before running; fingerprints are no longer consulted.
PostgreSQL compares through a rolled-back temporary view, since it
rewrites stored definitions.
- Every create, replace, or re-create of a compatibility view reconciles its
privileges to the ones it had just before (or the old relation's, for a
new view): missing grants are granted and grants added by default
privileges or schema future grants are revoked. Owner privileges are
never read or changed.
- On adapters whose views bind by name at query time, a build skips
redefining a view whose SQL is unchanged.
Refs CHI-391
* fix(migrations): never redefine a compatibility view whose old name a project model now uses
A recorded compatibility view whose old name is a project model's
destination (for example after an interrupted early drop) is no longer
refreshed, rebound, or released by builds of the destination. Before, when
the project's model built at that name before the destination, the
destination's refresh overwrote the project's view with the compatibility
SQL; concurrent builds made that order likely.
Refs CHI-3911 parent 4ec1624 commit b67bea0
145 files changed
Lines changed: 9655 additions & 219 deletions
File tree
- src/sqlbuild
- .agents/skills/sqlbuild/references/docs
- cli
- concepts
- models
- python-nodes
- adapters
- bigquery
- _helpers
- classes
- databricks
- _helpers
- classes
- postgres
- _helpers
- classes
- snowflake
- _helpers
- classes
- sqlserver
- _helpers
- classes
- adapter/contract
- _helpers
- classes
- main
- cli
- commands
- _helpers
- build_planning
- entry
- janitor_output
- janitor_runtime
- classes
- output/_helpers
- compiler
- compile
- _helpers
- config
- explicit_references
- main
- discovery/_helpers/yml
- migrations
- _helpers
- main
- planner
- _helpers
- migrations
- planning
- warehouse
- classes
- references
- _helpers
- main
- executor
- build/classes
- janitor
- main
- migrations
- _helpers
- classes
- main
- old_name_views
- _helpers
- main
- run
- _helpers
- execution
- materializations
- main
- spec/contracts
- tests
- e2e/src/sqlbuild/cli/commands/main
- model_migrations
- postgres
- integration/src/sqlbuild/cli/commands/main
- model_migrations
- old_name_views
- unit/src/sqlbuild
- adapters
- adapter/contract
- classes/connection
- main
- compiler
- discovery/_helpers
- migrations/main
- planner
- _helpers/migrations
- main/pre_build
- executor/migrations/_helpers
- website/src/content/docs/docs
- cli
- concepts
- models
- python-nodes
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
278 | 278 | | |
279 | 279 | | |
280 | 280 | | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
41 | | - | |
| 41 | + | |
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| 14 | + | |
14 | 15 | | |
15 | 16 | | |
16 | 17 | | |
| |||
34 | 35 | | |
35 | 36 | | |
36 | 37 | | |
| 38 | + | |
37 | 39 | | |
38 | 40 | | |
39 | 41 | | |
| |||
58 | 60 | | |
59 | 61 | | |
60 | 62 | | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
61 | 77 | | |
62 | 78 | | |
63 | 79 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
46 | 46 | | |
47 | 47 | | |
48 | 48 | | |
49 | | - | |
| 49 | + | |
50 | 50 | | |
51 | 51 | | |
52 | 52 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
26 | | - | |
| 26 | + | |
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
| |||
81 | 81 | | |
82 | 82 | | |
83 | 83 | | |
84 | | - | |
85 | | - | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
86 | 87 | | |
87 | 88 | | |
88 | 89 | | |
| |||
0 commit comments