Repository navigation
Commit ecea80e
LAV-3804: Support ALTER SCHEMA SWAP WITH parity (#4246)
* LAV-3804: implement atomic ALTER SCHEMA SWAP WITH parity
Parse schema SWAP explicitly and exchange the existing namespaces and catalog
identities through the shared schema movement machinery, without copying or
deleting schemas. Preserve grants, schema properties, descendants, and session
name slots. Serialize with the existing container graph lock, sorted relation
locks (using separate name parts for quoted identifiers), then the RBAC lock.
Cloud-captured tests establish current-database target resolution, same-target
no-ops, qualified view name rebinding, missing-object/privilege precedence,
cross-database exchange, and exact error positions. Reuse the existing transform
and stale-view repair paths to retain view declarations and report missing
references or changed query shapes. No existing snapshots or tests changed.
Verification:
- make check: passed.
- New schema swap compat file: 30 passed.
- Existing schemas, cross-database rename, UNDROP schema, sequence clone, and
stale-view files: 93 passed with unchanged snapshots.
- Existing schema clone selection: 14 passed with unchanged snapshots.
- Existing table swap plus schema swap selection: 27 passed (before the four
additional missing-database cases, all of which passed in the final replay).
- make test-vendored-sqlparser: passed, including 44 doc tests.
Co-authored-by: Przemek Denkiewicz <przemyslaw.denkiewicz@localstack.cloud>
## Deviations
The Cloud grant observations exposed an existing unqualified SHOW GRANTS ON
SCHEMA database-resolution defect. Corrected its producer in show_rewriter.rs
so the swap's grant assertions observe the actual schema edges.
Qualified views must resolve the exchanged name slots, not retain PostgreSQL
OID bindings. Added stored-query planning through the existing transform and
extended existing stale-view repair to preserve declared column names/counts;
the new Cloud snapshots uniquely establish the required errors and recovery.
## Test matrix
Populated schemas / tables, sequences, metadata, schema and table grants / success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_populated
Same target / success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_rejections[False-same]
Same target / IF EXISTS success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_rejections[True-same]
Missing source / error and preserved contents -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_rejections[False-missing_source]
Missing source / IF EXISTS no-op and preserved contents -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_rejections[True-missing_source]
Missing target / error and preserved contents -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_rejections[False-missing_target]
Missing target / IF EXISTS error and preserved contents -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_rejections[True-missing_target]
Both missing / source error precedence -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_rejections[False-both_missing]
Both missing / IF EXISTS target error precedence -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_rejections[True-both_missing]
Qualified mixed-case quoted schemas / same-database success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_qualified[False]
Qualified mixed-case quoted schemas / cross-database success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_qualified[True]
Unqualified, qualified, transitive and outside views / name resolution -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_view_names
Target ownership missing / error and preserved contents -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_ownership[False]
Ownership without CREATE SCHEMA / success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_ownership[True]
Qualified source with unqualified target / current-database resolution -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_target_database_resolution
Transient schema plus future grants / success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_schema_properties[transient]
Managed-access schema plus future grants / success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_schema_properties[managed]
Two sessions / same-database namespace slots -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_session_slots[False]
Two sessions / cross-database namespace slots -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_session_slots[True]
Quoted dotted names containing SWAP WITH and comments / success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_quoted_dots
Over-depth source / exact positioned error -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_over_depth[True]
Over-depth target / exact positioned error -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_over_depth[False]
Missing qualified view base / exact error and swap-back recovery -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_dependent_errors[missing]
Changed qualified view shape / exact error and swap-back recovery -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_dependent_errors[different_shape]
Quoted dotted view/table references, single-quoted and dollar-quoted literals / success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_quoted_view_references
IF EXISTS missing source, inaccessible target and non-owned same target / privilege precedence -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_if_exists_target_privileges
Missing source database / exact error -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_missing_database[False-False]
Missing target database / exact error -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_missing_database[False-True]
Missing source database / IF EXISTS exact error -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_missing_database[True-False]
Missing target database / IF EXISTS exact error -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_missing_database[True-True]
Defensive stored-definition parse/transform expectations and non-query guards
protect catalog invariants; malformed internal catalog entries are not a SQL
surface or a reason to remove those guards. The generated temporary-name
collision loop protects occupied catalog/physical namespace slots.
* LAV-3804: repair schema swap stale views, cycles, and session identity
Replan contained and affected views from their stored Snowflake definitions on
every swap, including already-stale views, and refresh the named reader at the
current destination. Resolve physical view names and catalog updates by their
owning session, and carry that session's post-swap temporary bindings into the
existing AST transform. Preserve declared column names and logical diagnostics.
Detect swap-created cyclic components without rejecting the swap. Bound repair's
stale dependency depth traversal with PostgreSQL CYCLE, leave cyclic components
tombstoned, and expose Cloud's verbatim 002037 view-name error and wire shape.
Propagate dependency errors only into unresolved swap readers; preserve the
existing nested expansion diagnostics produced by DROP/REPLACE machinery.
Swept schema-swap planning, pre-mutation lock selection, named readers, stale
closure, dependency expansion, catalog replay updates, and view re-owning for
stale-location and logical-name-only identity defects; fixed temporary/permanent
and cross-session collisions throughout these paths. Swept self and mutual
cycles, permanent/temporary external dependents, and swap-back recovery; bounded
stale depth traversal and preserved each cycle member's own diagnostic. AST
lowering remains lexical-safe for quoted identifiers, strings, dollar strings,
and comments. Schema rename's existing stale-view filter remains unchanged.
Added 28 serially Cloud-captured compat cases. No existing tests or snapshots
changed. Initial replay reproduced all six stale-location failures, including
missing-reference and shape-error recovery. All added cases now replay green.
Verification:
- make check: passed (formatting, clippy, warning checks and vendored parser tests).
- New schema-swap view file: 28 passed against emulator; all snapshots from Cloud.
- Schema swap, schemas/rename, cross-database rename, UNDROP, stale views, table
swap, temporary-view session scope and view row-access-policy files: 193 passed.
- Schema clone selection across test_clones.py and test_sequence_clone.py:
15 passed with unchanged snapshots.
- ViewBindings JSON decoding expect is an internal producer-invariant guard:
SQL always builds the session_id/relations object, so malformed bindings are
not reachable from the Snowflake surface.
Co-authored-by: Przemek Denkiewicz <przemyslaw.denkiewicz@localstack.cloud>
## Deviations
Session-scoped repair also required updating existing stale-view closure/replay
and RBAC re-owning helpers to use physical relation identities; swap-local fixes
alone would still conflate temporary/permanent rows or re-own the caller's namesake.
The new Cloud-qualified temporary-view invisibility errors include the role/privilege
suffix. Extended the existing unavailable-relation error producer, restricted to
AST-qualified references, to match these errors while retaining unqualified
temporary-view snapshots.
## Test matrix
Populated schemas / tables, sequences, metadata and grants / success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_populated
Same target / success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_rejections[False-same]
Same target / IF EXISTS success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_rejections[True-same]
Missing source / error and preservation -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_rejections[False-missing_source]
Missing source / IF EXISTS no-op and preservation -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_rejections[True-missing_source]
Missing target / error and preservation -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_rejections[False-missing_target]
Missing target / IF EXISTS error and preservation -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_rejections[True-missing_target]
Both missing / source error precedence -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_rejections[False-both_missing]
Both missing / IF EXISTS target error precedence -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_rejections[True-both_missing]
Quoted qualified schemas / same-database success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_qualified[False]
Quoted qualified schemas / cross-database success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_qualified[True]
Qualified, unqualified, transitive and outside views / success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_view_names
Missing target ownership / rejection and preservation -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_ownership[False]
Ownership without CREATE SCHEMA / success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_ownership[True]
Unqualified target / current-database resolution -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_target_database_resolution
Transient schema / future grants and properties -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_schema_properties[transient]
Managed-access schema / future grants and properties -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_schema_properties[managed]
Two sessions / same-database namespace slots -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_session_slots[False]
Two sessions / cross-database namespace slots -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_session_slots[True]
Quoted dotted schema names / success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_quoted_dots
Over-depth source / error -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_over_depth[True]
Over-depth target / error -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_over_depth[False]
Outside dependent / missing-reference error and swap-back recovery -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_dependent_errors[missing]
Outside dependent / shape error and swap-back recovery -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_dependent_errors[different_shape]
Quoted references and literals / success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_quoted_view_references
IF EXISTS / target privilege precedence -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_if_exists_target_privileges
Missing source database / error -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_missing_database[False-False]
Missing source database / IF EXISTS error -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_missing_database[True-False]
Missing target database / error -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_missing_database[False-True]
Missing target database / IF EXISTS error -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_missing_database[True-True]
Contained mixed-qualified view / same-database unread double-swap recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_stale_location[unread-False]
Contained mixed-qualified view / cross-database unread double-swap recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_stale_location[unread-True]
Contained view and chain / same-database missing-reference error and swap-back recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_stale_location[missing-False]
Contained view and chain / cross-database missing-reference error and swap-back recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_stale_location[missing-True]
Contained view and chain / same-database shape error and swap-back recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_stale_location[shape-False]
Contained view and chain / cross-database shape error and swap-back recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_stale_location[shape-True]
Self cycle / same-database swap success, read error, and swap-back recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_view_cycle[self-False]
Self cycle / cross-database swap success, read error, and swap-back recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_view_cycle[self-True]
Mutual cycle / same-database member-specific errors and swap-back recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_view_cycle[mutual-False]
Mutual cycle / cross-database member-specific errors and swap-back recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_view_cycle[mutual-True]
Two temporary sessions without permanent namesake / same-database reads, outsider errors, and swap-back -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_temporary_view_identity[False-False]
Two temporary sessions without permanent namesake / cross-database reads, outsider errors, and swap-back -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_temporary_view_identity[False-True]
Two temporary sessions with permanent namesake / same-database independent results and swap-back -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_temporary_view_identity[True-False]
Two temporary sessions with permanent namesake / cross-database independent results and swap-back -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_temporary_view_identity[True-True]
Two sessions' temporary dependencies / same-database namesake binding and unread double-swap recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_temporary_dependencies[False]
Two sessions' temporary dependencies / cross-database namesake binding and unread double-swap recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_temporary_dependencies[True]
Temporary namesake / same-database logical shape errors and recovery in two sessions -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_temporary_expansion_recovery[False]
Temporary namesake / cross-database logical shape errors and recovery in two sessions -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_temporary_expansion_recovery[True]
Quoted dotted identifiers, ordinary strings, dollar strings and comments / same-database round-trip -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_quoted_view_lexical_forms[False]
Quoted dotted identifiers, ordinary strings, dollar strings and comments / cross-database round-trip -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_quoted_view_lexical_forms[True]
Permanent external cycle dependent / same-database exact cycle errors and recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_external_cycle_dependent[False-False]
Permanent external cycle dependent / cross-database exact cycle errors and recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_external_cycle_dependent[False-True]
Temporary external cycle dependent / same-database exact cycle errors and recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_external_cycle_dependent[True-False]
Temporary external cycle dependent / cross-database exact cycle errors and recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_external_cycle_dependent[True-True]
Permanent transitive shape error / same-database exact dependency error and recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_transitive_shape_error[False-False]
Permanent transitive shape error / cross-database exact dependency error and recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_transitive_shape_error[False-True]
Temporary transitive shape error / same-database exact dependency error and recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_transitive_shape_error[True-False]
Temporary transitive shape error / cross-database exact dependency error and recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_transitive_shape_error[True-True]
Legacy nested DROP expansion error / unchanged snapshot -> tests/queries/test_stale_views.py::test_drop_table_dependent_view_chain_goes_stale
Schema clone / contained sequence and defaults -> tests/queries/ddl/test_sequence_clone.py::test_schema_clone_rebinds_table_default
Schema UNDROP / restored contents -> tests/queries/ddl/test_undrop_schema.py::test_undrop_schema_restores_tables_and_rows
Table swap / rows and swap-back -> tests/queries/test_alter_table_swap.py::test_swap_dml_then_swap_back
* LAV-3804: investigator: resume repaired tip for review; do not repeat Cloud capture
Attempt 1 exhausted wall_clock after steady progress, not a blocked implementation or repeated terminal failure. Initial implementation a087ac4db was reviewed; 1a41df664 then addressed the three added stale-location, cycle, and session-identity ACs. Current content tip 75f46f4fb includes origin/main 08cbbcf1f. git status --porcelain was empty and git diff --check origin/main passed.
Evidence: /var/lib/spiral/transcripts/driver.log lines 12-23 records two successful implementation turns, reviewer feedback, and two driver checks phases. The second checks phase ended ok (skipped: the scripts tests) at 2026-10-07T23:24:35Z; wall_clock exhaustion followed at 23:24:37Z, before a fresh reviewer turn. Each driver gate took about 55 minutes. checks.log lines 68-96 records 126 state-snapshot tests passed, 1 skipped, in 2863.98s, and scripts tests deferred because only 16s remained. The first gate had timed out its state-snapshot lane; the second completed it. These were driver-owned gates, not evidence of a forbidden duplicate manual gate.
The second implementer transcript records serial Cloud captures and failing repros turning green: 193 regression tests at 22:25:45Z, 28 new schema-swap view cases at 22:27:47Z, and final make check at 22:28:40Z. Clone selection passed 15 tests at 22:22:43Z. /tmp/lav3804-check-handoff.log ends Quick check passed. Existing tests and snapshots have no changes versus origin/main.
Read-only verification: schema.rs now includes already-stale views, replans stored definitions at their destination, uses session-aware physical names, and scopes catalog updates with session_id IS NOT DISTINCT FROM the owning session. dependent_views.rs bounds recursive depth traversal with CYCLE. New test_schema_swap_views.py and its 28 Cloud snapshot cases cover consecutive unread swaps, contained expansion recovery, self/mutual cycles, and two-session temporary/permanent identity, in same- and cross-database forms.
Next round: resume the repaired tip rather than reimplementing historical reviewer feedback or recapturing unchanged Cloud snapshots. Run make check and focused compat replay if needed after the final main merge or any new edit, then hand off promptly for the driver-owned gate and fresh reviewer assessment. Never run .spiral/check.sh manually or skip/modify its gates. The scripts lane was not verified on this worker and must run through the normal gate/CI; the fixed revision has not yet received a fresh reviewer verdict. No waiver or production-code change is granted by this note. The next dispatch starts from completed captures and committed repairs instead of repeating the original implementation and feedback cycle.
Co-authored-by: Przemek Denkiewicz <przemyslaw.denkiewicz@localstack.cloud>
* LAV-3804: verify repaired schema swap after main merge
Resumed the repaired implementation at 472716a3b as directed by the investigator. Historical reviewer gaps are already addressed by 1a41df664; no source, tests, or snapshots required further changes, and no Cloud captures were repeated.
Verification on the merged tip:
- make check: passed, including clippy, warnings-as-errors, formatting and vendored sqlparser tests.
- make test-compat across test_schema_swap.py, test_schema_swap_views.py, test_schemas.py, test_schema_cross_database_rename.py, test_undrop_schema.py, test_stale_views.py, test_alter_table_swap.py, test_temporary_view_session_scope.py and test_view_row_access_policy.py: 197 passed.
- make test-compat across test_clones.py and test_sequence_clone.py with -k schema: 17 passed.
- git diff --check origin/main...HEAD: passed; working tree remains clean.
The complete implementation test matrix and deviations remain recorded in 1a41df664. Existing tests and snapshots remain unchanged. Driver-owned checks and fresh review are still required; .spiral/check.sh was not run manually.
Co-authored-by: Przemek Denkiewicz <przemyslaw.denkiewicz@localstack.cloud>
* LAV-3804: attribute schema swap view errors to the current reader
Address the latest reviewer-gaps feedback. Schema swap now stores a canonical
missing-reference payload, not the swapper's primary/secondary-role diagnostic.
The named tombstone reader formats that payload using the reading session's
current role and secondary-role settings. Its exception hint carries the
canonical payload through transitive repair and legacy tombstone naming without
persisting a previous reader's formatted context. Existing SQLSTATEs and the
three-part repair-location detail remain unchanged.
Collect and qualify unqualified lowered relations on the AST, with a stack of
query-local CTE scopes, so probing and subsequent repair use the moved view's
namespace. Replay existing object grants when either the root repair or the
dependent reconstruction drops/recreates a view. No catalog, lock protocol,
wire retry policy, or independent-root repair behavior is introduced.
Add 16 serially Cloud-captured cases: eight permanent role-transition cases,
four temporary role-transition cases, and four nested-CTE/unqualified-reference
cases. The permanent tests distinguish view owner, schema swapper and another
session's reader, switch NONE/ALL/NONE after the swap, exercise both read orders,
and verify preserved reader access after swap-back. Existing test functions and
all 28 pre-existing snapshot entries in this file are unchanged.
Verification:
- Initial Cloud-captured role-transition replay: eight failures on the starting
tip, including frozen swapper attribution and lost reconstructed-view grants.
- make check: passed, including formatting, clippy, warnings-as-errors, and
vendored sqlparser tests.
- make test-compat across test_schema_swap.py, test_schema_swap_views.py,
test_schemas.py, test_schema_cross_database_rename.py, test_undrop_schema.py,
test_stale_views.py, test_alter_table_swap.py,
test_temporary_view_session_scope.py, and test_view_row_access_policy.py:
213 passed, including all 44 schema-swap view cases.
- make test-compat across test_clones.py and test_sequence_clone.py with
PYTEST_ARGS='-k schema': 17 passed.
- git diff --check: passed. Structured comparison confirms no existing
snapshot entries changed or disappeared; only 16 Cloud-captured entries added.
- The driver's .spiral/check.sh was not run manually.
Co-authored-by: Przemek Denkiewicz <przemyslaw.denkiewicz@localstack.cloud>
## Sweep
Swept schema.rs, table.rs, and dependent_views.rs named-tombstone producers and
exception-copying paths for session-frozen diagnostics; fixed swap construction,
transitive propagation, and legacy naming. Plain expansion, shape, and cycle
errors retain their previous messages. Swept lowered unqualified references
and both root/dependent rebuild sites; also fixed missing dependency edges,
wrong probing namespaces, and grant reprojection. CTE aliases remain scoped
and unmodified. Existing ordinary/dollar literals, quoted identifiers, comments,
temporary/permanent namesakes, cycles, and two-session cases replay green.
Independent stale roots remain the separate LAV-3887 work, unchanged here.
## Deviations
The new reader-context captures also exposed incomplete unqualified-reference
tracking and lost PG grants after view reconstruction. Normalizing these
references on the AST and reusing existing grant reprojection at both rebuild
sites are necessary for Cloud-matching transitive diagnostics and swap-back
access; neither changes the namespace/catalog/locking architecture.
## Test matrix
Resource-index denominator: ALTER SCHEMA [IF EXISTS] <name> SWAP WITH <target>.
Other ALTER SCHEMA clauses are unchanged. The existing AC/name/lifecycle matrix
is included below; additional reader-context and reference-scope cells follow.
Permanent / NONE swapper, direct-first, same DB / direct and transitive errors under ACCOUNTADMIN and another session's reader, NONE/ALL/NONE -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_missing_reference_reader_context[NONE-False-False]
Permanent / NONE swapper, direct-first, cross DB / direct and transitive errors under ACCOUNTADMIN and another session's reader, NONE/ALL/NONE -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_missing_reference_reader_context[NONE-False-True]
Permanent / NONE swapper, transitive-first, same DB / direct and transitive errors under ACCOUNTADMIN and another session's reader, NONE/ALL/NONE -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_missing_reference_reader_context[NONE-True-False]
Permanent / NONE swapper, transitive-first, cross DB / direct and transitive errors under ACCOUNTADMIN and another session's reader, NONE/ALL/NONE -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_missing_reference_reader_context[NONE-True-True]
Permanent / ALL swapper, direct-first, same DB / direct and transitive errors under ACCOUNTADMIN and another session's reader, NONE/ALL/NONE -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_missing_reference_reader_context[ALL-False-False]
Permanent / ALL swapper, direct-first, cross DB / direct and transitive errors under ACCOUNTADMIN and another session's reader, NONE/ALL/NONE -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_missing_reference_reader_context[ALL-False-True]
Permanent / ALL swapper, transitive-first, same DB / direct and transitive errors under ACCOUNTADMIN and another session's reader, NONE/ALL/NONE -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_missing_reference_reader_context[ALL-True-False]
Permanent / ALL swapper, transitive-first, cross DB / direct and transitive errors under ACCOUNTADMIN and another session's reader, NONE/ALL/NONE -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_missing_reference_reader_context[ALL-True-True]
Permanent / NONE swapper, direct-first, same DB / swap-back rows and preserved reader SELECT grants, NONE/ALL -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_missing_reference_reader_context[NONE-False-False]
Permanent / NONE swapper, direct-first, cross DB / swap-back rows and preserved reader SELECT grants, NONE/ALL -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_missing_reference_reader_context[NONE-False-True]
Permanent / NONE swapper, transitive-first, same DB / swap-back rows and preserved reader SELECT grants, NONE/ALL -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_missing_reference_reader_context[NONE-True-False]
Permanent / NONE swapper, transitive-first, cross DB / swap-back rows and preserved reader SELECT grants, NONE/ALL -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_missing_reference_reader_context[NONE-True-True]
Permanent / ALL swapper, direct-first, same DB / swap-back rows and preserved reader SELECT grants, NONE/ALL -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_missing_reference_reader_context[ALL-False-False]
Permanent / ALL swapper, direct-first, cross DB / swap-back rows and preserved reader SELECT grants, NONE/ALL -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_missing_reference_reader_context[ALL-False-True]
Permanent / ALL swapper, transitive-first, same DB / swap-back rows and preserved reader SELECT grants, NONE/ALL -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_missing_reference_reader_context[ALL-True-False]
Permanent / ALL swapper, transitive-first, cross DB / swap-back rows and preserved reader SELECT grants, NONE/ALL -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_missing_reference_reader_context[ALL-True-True]
Temporary / NONE swapper, same DB / direct/transitive errors after changing primary role and NONE/ALL/NONE -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_temporary_missing_reference_reader_context[NONE-False]
Temporary / NONE swapper, cross DB / direct/transitive errors after changing primary role and NONE/ALL/NONE -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_temporary_missing_reference_reader_context[NONE-True]
Temporary / ALL swapper, same DB / direct/transitive errors after changing primary role and NONE/ALL/NONE -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_temporary_missing_reference_reader_context[ALL-False]
Temporary / ALL swapper, cross DB / direct/transitive errors after changing primary role and NONE/ALL/NONE -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_temporary_missing_reference_reader_context[ALL-True]
Temporary / NONE swapper, same DB / transitive-first swap-back restores rows -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_temporary_missing_reference_reader_context[NONE-False]
Temporary / NONE swapper, cross DB / transitive-first swap-back restores rows -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_temporary_missing_reference_reader_context[NONE-True]
Temporary / ALL swapper, same DB / transitive-first swap-back restores rows -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_temporary_missing_reference_reader_context[ALL-False]
Temporary / ALL swapper, cross DB / transitive-first swap-back restores rows -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_temporary_missing_reference_reader_context[ALL-True]
Unqualified base with nested CTE shadow, missing target / same DB / direct/transitive errors and swap-back recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_unqualified_reference_scopes[False-False]
Unqualified base with nested CTE shadow, missing target / cross DB / direct/transitive errors and swap-back recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_unqualified_reference_scopes[False-True]
Unqualified base with nested CTE shadow, populated target / same DB / moved namespace rows and swap-back rows -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_unqualified_reference_scopes[True-False]
Unqualified base with nested CTE shadow, populated target / cross DB / moved namespace rows and swap-back rows -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_unqualified_reference_scopes[True-True]
CTE-only view / same DB, no underlying relation / unchanged reads through swaps -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_unqualified_reference_scopes[False-False]
CTE-only view / cross DB, no underlying relation / unchanged reads through swaps -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_unqualified_reference_scopes[False-True]
Inherited matrix (retained behavior, also replayed this round):
Populated schemas / tables, sequences, metadata and grants / success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_populated
Same target / success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_rejections[False-same]
Same target / IF EXISTS success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_rejections[True-same]
Missing source / error and preservation -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_rejections[False-missing_source]
Missing source / IF EXISTS no-op and preservation -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_rejections[True-missing_source]
Missing target / error and preservation -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_rejections[False-missing_target]
Missing target / IF EXISTS error and preservation -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_rejections[True-missing_target]
Both missing / source error precedence -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_rejections[False-both_missing]
Both missing / IF EXISTS target error precedence -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_rejections[True-both_missing]
Quoted qualified schemas / same-database success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_qualified[False]
Quoted qualified schemas / cross-database success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_qualified[True]
Qualified, unqualified, transitive and outside views / success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_view_names
Missing target ownership / rejection and preservation -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_ownership[False]
Ownership without CREATE SCHEMA / success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_ownership[True]
Unqualified target / current-database resolution -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_target_database_resolution
Transient schema / future grants and properties -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_schema_properties[transient]
Managed-access schema / future grants and properties -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_schema_properties[managed]
Two sessions / same-database namespace slots -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_session_slots[False]
Two sessions / cross-database namespace slots -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_session_slots[True]
Quoted dotted schema names / success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_quoted_dots
Over-depth source / error -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_over_depth[True]
Over-depth target / error -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_over_depth[False]
Outside dependent / missing-reference error and swap-back recovery -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_dependent_errors[missing]
Outside dependent / shape error and swap-back recovery -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_dependent_errors[different_shape]
Quoted references and literals / success -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_quoted_view_references
IF EXISTS / target privilege precedence -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_if_exists_target_privileges
Missing source database / error -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_missing_database[False-False]
Missing source database / IF EXISTS error -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_missing_database[True-False]
Missing target database / error -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_missing_database[False-True]
Missing target database / IF EXISTS error -> tests/queries/ddl/test_schema_swap.py::test_schema_swap_missing_database[True-True]
Contained mixed-qualified view / same-database unread double-swap recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_stale_location[unread-False]
Contained mixed-qualified view / cross-database unread double-swap recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_stale_location[unread-True]
Contained view and chain / same-database missing-reference error and swap-back recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_stale_location[missing-False]
Contained view and chain / cross-database missing-reference error and swap-back recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_stale_location[missing-True]
Contained view and chain / same-database shape error and swap-back recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_stale_location[shape-False]
Contained view and chain / cross-database shape error and swap-back recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_stale_location[shape-True]
Self cycle / same-database swap success, read error, and swap-back recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_view_cycle[self-False]
Self cycle / cross-database swap success, read error, and swap-back recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_view_cycle[self-True]
Mutual cycle / same-database member-specific errors and swap-back recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_view_cycle[mutual-False]
Mutual cycle / cross-database member-specific errors and swap-back recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_view_cycle[mutual-True]
Two temporary sessions without permanent namesake / same-database reads, outsider errors, and swap-back -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_temporary_view_identity[False-False]
Two temporary sessions without permanent namesake / cross-database reads, outsider errors, and swap-back -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_temporary_view_identity[False-True]
Two temporary sessions with permanent namesake / same-database independent results and swap-back -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_temporary_view_identity[True-False]
Two temporary sessions with permanent namesake / cross-database independent results and swap-back -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_temporary_view_identity[True-True]
Two sessions' temporary dependencies / same-database namesake binding and unread double-swap recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_temporary_dependencies[False]
Two sessions' temporary dependencies / cross-database namesake binding and unread double-swap recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_temporary_dependencies[True]
Temporary namesake / same-database logical shape errors and recovery in two sessions -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_temporary_expansion_recovery[False]
Temporary namesake / cross-database logical shape errors and recovery in two sessions -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_temporary_expansion_recovery[True]
Quoted dotted identifiers, ordinary strings, dollar strings and comments / same-database round-trip -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_quoted_view_lexical_forms[False]
Quoted dotted identifiers, ordinary strings, dollar strings and comments / cross-database round-trip -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_quoted_view_lexical_forms[True]
Permanent external cycle dependent / same-database exact cycle errors and recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_external_cycle_dependent[False-False]
Permanent external cycle dependent / cross-database exact cycle errors and recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_external_cycle_dependent[False-True]
Temporary external cycle dependent / same-database exact cycle errors and recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_external_cycle_dependent[True-False]
Temporary external cycle dependent / cross-database exact cycle errors and recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_external_cycle_dependent[True-True]
Permanent transitive shape error / same-database exact dependency error and recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_transitive_shape_error[False-False]
Permanent transitive shape error / cross-database exact dependency error and recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_transitive_shape_error[False-True]
Temporary transitive shape error / same-database exact dependency error and recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_transitive_shape_error[True-False]
Temporary transitive shape error / cross-database exact dependency error and recovery -> tests/queries/ddl/test_schema_swap_views.py::test_schema_swap_transitive_shape_error[True-True]
Legacy nested DROP expansion error / unchanged snapshot -> tests/queries/test_stale_views.py::test_drop_table_dependent_view_chain_goes_stale
Schema clone / contained sequence and defaults -> tests/queries/ddl/test_sequence_clone.py::test_schema_clone_rebinds_table_default
Schema UNDROP / restored contents -> tests/queries/ddl/test_undrop_schema.py::test_undrop_schema_restores_tables_and_rows
Table swap / rows and swap-back -> tests/queries/test_alter_table_swap.py::test_swap_dml_then_swap_back
---------
Co-authored-by: spiral <spiral@localhost>
Co-authored-by: Przemek Denkiewicz <przemyslaw.denkiewicz@localstack.cloud>1 parent 8b00692 commit ecea80e
3 files changed
Lines changed: 12 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5501 | 5501 | | |
5502 | 5502 | | |
5503 | 5503 | | |
| 5504 | + | |
| 5505 | + | |
| 5506 | + | |
| 5507 | + | |
| 5508 | + | |
5504 | 5509 | | |
5505 | 5510 | | |
5506 | 5511 | | |
| |||
5526 | 5531 | | |
5527 | 5532 | | |
5528 | 5533 | | |
| 5534 | + | |
5529 | 5535 | | |
5530 | 5536 | | |
5531 | 5537 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2841 | 2841 | | |
2842 | 2842 | | |
2843 | 2843 | | |
2844 | | - | |
| 2844 | + | |
| 2845 | + | |
| 2846 | + | |
2845 | 2847 | | |
2846 | 2848 | | |
2847 | 2849 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13946 | 13946 | | |
13947 | 13947 | | |
13948 | 13948 | | |
| 13949 | + | |
| 13950 | + | |
| 13951 | + | |
13949 | 13952 | | |
13950 | 13953 | | |
13951 | 13954 | | |
| |||
0 commit comments