Commit Detail
Commit 0ad3f10
sqlite: allow PRAGMA legacy_alter_table There's certain kinds of schema changes that are really painful to do in SQLite; this makes things a little easier. For example, let's say you want to change the "users.email" column's collation to be case-insensitive (COLLATE NOCASE). You can't do that with ALTER TABLE, so what you have to do instead is a three-step dance*: 1: rename users to users_old 2: create a new table users with the same schema as users_old, except for the collation, and copy the data over 3: drop users_old The problem comes in with foreign keys. If you've got a "favorites.user_id" column that's a foreign key to users.id, then doing the above dance will delete all your users' favorites (assuming ON DELETE CASCADE, otherwise it'll error out). 1: after the rename, all the foreign keys now reference users_old.id 2: no effect 3: dropping users_old cascades and deletes all the rows from favorites This is where legacy_alter_table is helpful. If you start off by setting this, then you can do the dance without losing other rows. 0: PRAGMA legacy_alter_table=on 1: rename users to users_old. This now leaves the foreign-key relationship in a dangling state; favorites.user_id references users.id, but there is no users table. 2: create the new table and copy the data over. The foreign keys are now pointing to the new table. 3: drop users_old; since there are no foreign keys referencing it, nothing gets deleted It's a pretty confusing behavior, which is why it's off by default, but SQLite's ALTER TABLE isn't flexible enough for all situations so sometimes users need this kind of workaround. * yes, you could specify COLLATE NOCASE in every query that touches the column instead of relying on the default, but not everybody is willing to do that
Files changed
1 file changed~1 modified