[FIx #55866] Fix SQLite3 data loss or corruption when altering tables inside a transaction#57128
Open
emirn wants to merge 3 commits intorails:mainfrom
Open
[FIx #55866] Fix SQLite3 data loss or corruption when altering tables inside a transaction#57128emirn wants to merge 3 commits intorails:mainfrom
emirn wants to merge 3 commits intorails:mainfrom
Conversation
64a3209 to
24250bb
Compare
24250bb to
290732e
Compare
290732e to
60d0b10
Compare
… foreign keys inside `ActiveRecord::Base.connection.transaction`. Silent cascade removal of child records was fixed in rails#55907 but when table alteration code was wrapped by `ActiveRecord::Base.connection.transaction`, SQLite3 ignored `PRAGMA foreign_keys = OFF`. This fix ensures that the transaction (if exists) is now temporarily committed before `disable_referential_integrity` runs for the `PRAGMA` to take effect. Fixes rails#55866
60d0b10 to
dfec2ed
Compare
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.
Motivation:
Addition to the #55907 (created because of #55866) to additionally support case when table alteration is wrapped by
ActiveRecord::Base.connection.transaction.Update 1: This issue is critical for projects using SQLIte with current Rails edge (as of April 3, 2026) and release versions
8.1.3(seetest-full-rails-app.shbelow used for testing) silently removing children records data on renaming or removing columns in a parent table.Detail
#55907 fixed silent data loss during table alterations in SQLite but deletion still happened when table alteration was wrapped by
ActiveRecord::Base.connection.transaction. This fix checks if there is an outer transaction (single joinable transaction, as in db:migrate) and the table is referenced by other tables withON DELETE CASCADEorON DELETE SET NULLforeign keys. In such case the fix temporarily commits the transaction beforedisable_referential_integrityruns so thePRAGMAtakes effect.**Update 2**: **test-full-rails-app.sh** below reproduces locally by creating a new Ruby on Rails apps, adding a migration with User and User's Payments (with FK and set for ON DELETE CASCADE) and demonstrating that renaming a column in the parent table causing a removal of all children records in Payments table:
Output (log.txt):
Additional information
1. **test-fk-cascade.rb** to confirm data loss for `ON DELETE CASCADE`:
2. **test-fk-nullify.rb** to test data corruption with `ON DELETE SET NULL`:
Checklist
Before submitting the PR make sure the following are checked:
[Fix #issue-number]