feat(linter): extend rollback compatibility rules - #1382
Closed
t-monaghan wants to merge 21 commits into
Closed
t-monaghan wants to merge 21 commits into
t-monaghan wants to merge 21 commits into
Conversation
…lit generated drop
👷 Deploy request for squawkhq pending review.Visit the deploys page to approve it
|
This was referenced Oct 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose
At Culture Amp we are proposing to use Squawk to review SQL migrations and to give us confidence that we can roll back our applications. As we adopt blue/green deployments, this check becomes more important: an earlier application revision may need to run against a database that has already been migrated.
Rolling back the application does not roll back the database migration or remove data written by the newer revision. The earlier revision must still be able to read and write using the migrated database. We want Squawk to flag migrations that could break functionality if we deploy an earlier application revision, such as changes to columns, write restrictions, or permissions. These rules add those compatibility checks so we can review the risks before deployment. They increase our confidence in application rollback, alongside testing earlier revisions against the migrated database.
Context
Default rules flag operations that directly change or remove database contracts used by earlier application revisions. Opt-in rules flag operations whose compatibility depends more on application usage or database configuration.
This PR adds 33 rules (9 default, 24 opt-in) and extends 9 existing rules.
New default rules
ban-drop-schema,ban-drop-sequence,ban-drop-domaindetectDROP SCHEMA,DROP SEQUENCE, andDROP DOMAIN. Queries that reference the dropped object fail.ban-drop-constraintdetectsDROP CONSTRAINT. Dropping a unique constraint can make an oldINSERT ... ON CONFLICTfail.ban-drop-generated-expressiondetectsDROP EXPRESSION, which changes a generated column into an ordinary column.ban-drop-extensiondetectsDROP EXTENSION, which can remove functions, types, and operators used by the old application.ban-alter-identitydetects identity column additions, changes, and removals. For example, changingidtoGENERATED ALWAYSrejects an earlier application'sINSERT INTO t (id) VALUES (1)unless it usesOVERRIDING SYSTEM VALUE. An application that omitsidmay continue to work.renaming-objectdetects renames of views, sequences, types, enum values, foreign tables, routines, aggregates, roles, databases, triggers, policies, and constraints.ban-set-schemadetectsSET SCHEMAon tables, foreign tables, views, types, sequences, functions, procedures, routines, aggregates, and extensions.New opt-in rules
ban-alter-generated-expressiondetects added generated columns andSET EXPRESSION. Stored-value rewrites are an availability concern separate from whether old clients understand the new values.ban-drop-indexdetectsDROP INDEX, which can remove a unique or exclusion guarantee.ban-set-defaultdetectsSET DEFAULTon table, foreign table, view, and domain columns.ban-disable-triggerdetects disabling or enabling triggers and rules, replica-only or always firing, andFORCE/NO FORCE ROW LEVEL SECURITY. Diagnostics distinguish lost side effects from access errors.ban-replica-identitydetects replica identity changes, dropped publications, and changes to published tables or options.ban-drop-policydetectsDROP POLICYandDROP RULE.ban-revokedetectsREVOKE,ALTER GROUP ... DROP USER,DROP ROLE,OWNER TO,REASSIGN OWNED, andDROP OWNED.ban-replace-view-functiondetectsCREATE OR REPLACEon views, functions, procedures, triggers, rules, and aggregates.ban-create-policy,ban-alter-policy-roles,ban-alter-policy-condition, andban-alter-row-level-securitydetect policy and RLS changes that can change access for the old application's role.ban-alter-function-options,ban-alter-view-options,ban-alter-role-options,ban-alter-database-options, andban-alter-system-optionsdetect option and configuration changes that can affect permissions, connection behavior, name resolution, or results.ban-alter-function-optionscovers procedures and routines;ban-alter-role-optionscoversALTER USER.ban-alter-extensiondetects extension updates and member removal. Extension schema moves useban-set-schema.ban-new-write-restrictiondetects new table, domain, and foreign-table restrictions, includingNOT VALIDconstraints,NOT NULLconstraints, constrained added columns, unique indexes builtCONCURRENTLY, and tighter constraint timing or enforcement.ban-add-columndetects columns added to existing tables and foreign tables. Added columns can changeSELECT *results and break positional inserts.ban-add-enum-valueandban-add-composite-attributedetect new values or attributes that can break old decoders and positional composite input.ban-detach-inheritancedetectsDETACH PARTITIONandNO INHERIT, which can remove rows from parent-table queries.ban-alter-sequence-valuesdetects sequence and identity-sequence changes that can reissue identifiers or change their range. It excludes options that do not change generated values.Extended existing rules
adding-not-nullable-field,ban-drop-default,ban-drop-not-null: also check domains and foreign tables;ban-drop-defaultalso checks view columns.ban-drop-column,changing-column-type,renaming-column: also check foreign tables and composite type attributes;renaming-columnalso checks views and materialized views.ban-drop-function: also checksDROP AGGREGATEandDROP ROUTINE.ban-drop-table: also checksDROP FOREIGN TABLE.ban-drop-type: also checksDROP OPERATOR,DROP OPERATOR CLASS,DROP OPERATOR FAMILY, andDROP CAST.For objects created unconditionally earlier in the migration, some rules suppress warnings. This is a statement-level approximation: the linter does not query the schema.
The PR adds tests, diagnostics, rule documentation, and changelog entries.
Verification
cargo test -p squawk-linter --lib: 444 passed, 0 failed (Rust 1.98.1 with native macOS linker).git diff --checkpassed.ALTER SYSTEM,ALTER EXTENSION, andALTER AGGREGATEtest statements without syntax errors.cargo test --workspacewith a compatible Rust toolchain.