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

Reply via email to