tnibler.de

SQLite's ALTER TABLE can not DROP unnamed CHECK constraints

Last update:

As of SQLite 3.53.3, DROP CONSTRAINT only works on named constraints like CONSTRAINT name CHECK(...).

The new ALTER TABLE features enable removing and adding constraints to a schema without the usual dance of creating, populating and renaming temporary tables. Unfortunately however, this does not work for constraints defined like this:

CREATE TABLE Things(
     one_column INTEGER NOT NULL CHECK (the_column IN (0, 1))
    , two_column INTEGER
    , CHECK (two_column > 0 OR two_column IS NULL)
) STRICT;

You need to give every constraint a name to be able to change them in migrations:

CREATE TABLE Things(
     one_column INTEGER NOT NULL 
      CONSTRAINT one_is_good CHECK (one_column IN (0, 1))
    , two_column INTEGER
      CONSTRAINT two_is_good CHECK (two_column > 0 OR two_column IS NULL)
    , CONSTRAINT all_is_good CHECK (one_column + two_column = 3)
) STRICT;

Now you can remove and add constraints:

ALTER TABLE Things DROP CONSTRAINT one_is_good;

ALTER TABLE Things ADD CONSTRAINT even_better CHECK (one_column > 100);

Source: sqlite/alter.c. SQLite stores the schema as the literal DDL string used to create it, and ALTER TABLE operations modify these table definitions in text form. The linked function needs a CONSTRAINT token to do anything, and a plain CHECK is not handled.