On 1/3/16, Luuk <luuk34 at gmail.com> wrote: > > > On 03-01-16 00:11, richard parkins wrote: >> An INSERT statement which fails with no explicit conflict clause appears >> to throw away a pending SAVEPOINT. >> The following sequence demonstrates this behaviour >> SAVEPOINT demonstration; >> CREATE TABLE IF NOT EXISTS "PK" ( "first name" "TEXT", >> "last name" "TEXT", >> "address", >> PRIMARY KEY ( "first name", "last name" ) >> ) WITHOUT ROWID; >> INSERT INTO "PK" default values; >> ROLLBACK TO demonstration; >> >> As expected, the insert fails with Error: NOT NULL constraint, but the >> ROLLBACK statement then also fails with Error: no such savepoint. > > a ROLLBACK was done because of the Error... >
Yeah, but a constraint failure should only terminate the one statement that encountered the problem and should *not* rollback the transaction. The problem is that the NOT NULL constraint on the PRIMARY KEY of a WITHOUT ROWID table was defaulting to give ON CONFLICT ROLLBACK behavior instead of ON CONFLICT ABORT, as it should. I'm currently testing the following fix: Index: src/build.c ================================================================== --- src/build.c +++ src/build.c @@ -1772,11 +1772,11 @@ /* Make sure every column of the PRIMARY KEY is NOT NULL. (Except, ** do not enforce this for imposter tables.) */ if( !db->init.imposterTable ){ for(i=0; i<nPk; i++){ - pTab->aCol[pPk->aiColumn[i]].notNull = 1; + pTab->aCol[pPk->aiColumn[i]].notNull = OE_Abort; } pPk->uniqNotNull = 1; } /* The root page of the PRIMARY KEY is the table root page */ Assuming the patch above works, I'll check in the fix in a few minutes... -- D. Richard Hipp drh at sqlite.org