SQLite4
Check-in [367fdc8463]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add placeholder code to make ROLLBACK (and OR ROLLBACK constraints) work a bit.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | primary-keys
Files: files | file ages | folders
SHA1: 367fdc84630cfc5074bb152aa7708ad3c604b79b
User & Date: dan 2012-04-13 10:35:21
Context
2012-04-13
16:45
Fix a problem in kvmemRemoveNode() causing a pUp (parent node) pointer to be set incorrectly. check-in: 7faa762755 user: dan tags: primary-keys
10:35
Add placeholder code to make ROLLBACK (and OR ROLLBACK constraints) work a bit. check-in: 367fdc8463 user: dan tags: primary-keys
05:50
Ensure that kvmemSeek() does not come to rest on a deleted node. check-in: 21991a932a user: dan tags: primary-keys
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

2356
2357
2358
2359
2360
2361
2362




















2363
2364
2365
2366
2367
2368
2369
** back any currently active btree transactions. If there are any active
** VMs (apart from this one), then a ROLLBACK fails.  A COMMIT fails if
** there are active writing VMs or active VMs that use shared cache.
**
** This instruction causes the VM to halt.
*/
case OP_AutoCommit: {




















  break;
}

/* Opcode: Transaction P1 P2 * * *
**
** Begin a transaction.
**







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
** back any currently active btree transactions. If there are any active
** VMs (apart from this one), then a ROLLBACK fails.  A COMMIT fails if
** there are active writing VMs or active VMs that use shared cache.
**
** This instruction causes the VM to halt.
*/
case OP_AutoCommit: {
  int bAutoCommit;                /* New value for auto-commit flag */
  int bRollback;                  /* True to do transaction rollback */

  bAutoCommit = pOp->p1;
  bRollback = pOp->p2;
  assert( bAutoCommit==1 || bRollback==0 );

  if( bAutoCommit==0 ){
    db->autoCommit = 0;
  }else{
    if( bRollback ){
      sqlite4RollbackAll(db);
    }else if( sqlite4VdbeCheckFk(p, 1) ){
      goto vdbe_return;
    }

    sqlite4VdbeHalt(p);
  }

  db->autoCommit = bAutoCommit;
  break;
}

/* Opcode: Transaction P1 P2 * * *
**
** Begin a transaction.
**

Changes to src/vdbeaux.c.

1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
....
1850
1851
1852
1853
1854
1855
1856
1857




1858
1859
1860


1861
1862
1863
1864
1865
1866
1867
  }else{
    /* eAction:
    **
    **    0 - Do commit, either statement or transaction.
    **    1 - Do rollback, either statement or transaction.
    **    2 - Do transaction rollback.
    */
    int eAction;

    /* Check if an error has already occurred */
    if( p->rc==SQLITE_CONSTRAINT ){
      if( p->errorAction==OE_Rollback ){
        eAction = 2;
      }else if( p->errorAction==OE_Fail ){
        eAction = 0;
      }
    }else if( p->rc ){
      eAction = 1;
    }

    if( eAction==0 && sqlite4VdbeCheckFk(p, 0) ){
      eAction = 1;
    }

    if( eAction==2 || ( 
          !sqlite4VtabInSync(db)==0 
       && db->writeVdbeCnt==(p->readOnly==0) 
       && db->autoCommit 
    )){
      if( eAction==0 && sqlite4VdbeCheckFk(p, 1) ){
        eAction = 1;
      }

................................................................................

      if( eAction ){
        sqlite4RollbackAll(db);
      }

      db->nDeferredCons = 0;
    }else if( p->stmtTransMask ){
      int i;




      int (*xFunc)(KVStore *,int);
      xFunc = (eAction ? sqlite4KVStoreRollback : sqlite4KVStoreCommit);



      for(i=0; i<db->nDb; i++){
        if( p->stmtTransMask & ((yDbMask)1)<<i ){
          KVStore *pKV = db->aDb[i].pKV;
          rc = xFunc(pKV, pKV->iTransLevel-1);
          if( rc ){
            sqlite4RollbackAll(db);
            break;







|

<






<
<







|







 







|
>
>
>
>
|
<

>
>







1807
1808
1809
1810
1811
1812
1813
1814
1815

1816
1817
1818
1819
1820
1821


1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
....
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859

1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
  }else{
    /* eAction:
    **
    **    0 - Do commit, either statement or transaction.
    **    1 - Do rollback, either statement or transaction.
    **    2 - Do transaction rollback.
    */
    int eAction = (p->rc!=SQLITE_OK);


    if( p->rc==SQLITE_CONSTRAINT ){
      if( p->errorAction==OE_Rollback ){
        eAction = 2;
      }else if( p->errorAction==OE_Fail ){
        eAction = 0;
      }


    }

    if( eAction==0 && sqlite4VdbeCheckFk(p, 0) ){
      eAction = 1;
    }

    if( eAction==2 || ( 
          sqlite4VtabInSync(db)==0 
       && db->writeVdbeCnt==(p->readOnly==0) 
       && db->autoCommit 
    )){
      if( eAction==0 && sqlite4VdbeCheckFk(p, 1) ){
        eAction = 1;
      }

................................................................................

      if( eAction ){
        sqlite4RollbackAll(db);
      }

      db->nDeferredCons = 0;
    }else if( p->stmtTransMask ){
      /* Auto-commit mode is turned off and no "OR ROLLBACK" constraint was
      ** encountered. So either commit (if eAction==0) or rollback (if 
      ** eAction==1) any statement transactions opened by this VM.  */

      int i;                           /* Used to iterate thru attached dbs */
      int (*xFunc)(KVStore *,int);     /* Commit or rollback function */


      assert( eAction==0 || eAction==1 );
      xFunc = (eAction ? sqlite4KVStoreRollback : sqlite4KVStoreCommit);
      for(i=0; i<db->nDb; i++){
        if( p->stmtTransMask & ((yDbMask)1)<<i ){
          KVStore *pKV = db->aDb[i].pKV;
          rc = xFunc(pKV, pKV->iTransLevel-1);
          if( rc ){
            sqlite4RollbackAll(db);
            break;

Changes to test/simple.test.

311
312
313
314
315
316
317

318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
...
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371

do_execsql_test 14.2 { DROP TABLE t1 }
do_execsql_test 14.3 { SELECT * FROM t3 } 1

#-------------------------------------------------------------------------
reset_db


do_execsql_test 15.1.1 {
  CREATE TABLE t1(x PRIMARY KEY);
  BEGIN;
    INSERT INTO t1 VALUES('rollback is not implemented yet');
}

do_execsql_test 15.1.2 { ROLLBACK }
do_execsql_test 15.1.3 { SELECT * FROM t1 } {}

#-------------------------------------------------------------------------
reset_db

do_execsql_test 16.1.1 {
  PRAGMA foreign_keys = ON;
  CREATE TABLE p1(x PRIMARY KEY);
................................................................................
  INSERT INTO t2 VALUES(1, 'A');
  INSERT INTO t2 VALUES(2, 'B');
  INSERT INTO t2 VALUES(3, 'C');
  INSERT INTO t2 VALUES(4, 'D');
  INSERT INTO t2 VALUES(5, 'A');
}

breakpoint
do_catchsql_test 17.2 { 
  INSERT INTO t1 SELECT b FROM t2;
} {1 {column x is not unique}}

do_execsql_test 17.3 { SELECT * FROM t1 } {X}

finish_test







>
|
<



<
|
|







 







<







311
312
313
314
315
316
317
318
319

320
321
322

323
324
325
326
327
328
329
330
331
...
356
357
358
359
360
361
362

363
364
365
366
367
368
369

do_execsql_test 14.2 { DROP TABLE t1 }
do_execsql_test 14.3 { SELECT * FROM t3 } 1

#-------------------------------------------------------------------------
reset_db

do_execsql_test 15.1.1 { CREATE TABLE t1(x PRIMARY KEY) }
do_execsql_test 15.1.2 { 

  BEGIN;
    INSERT INTO t1 VALUES('rollback is not implemented yet');
}

do_execsql_test 15.1.3 { ROLLBACK }
do_execsql_test 15.1.4 { SELECT * FROM t1 } {}

#-------------------------------------------------------------------------
reset_db

do_execsql_test 16.1.1 {
  PRAGMA foreign_keys = ON;
  CREATE TABLE p1(x PRIMARY KEY);
................................................................................
  INSERT INTO t2 VALUES(1, 'A');
  INSERT INTO t2 VALUES(2, 'B');
  INSERT INTO t2 VALUES(3, 'C');
  INSERT INTO t2 VALUES(4, 'D');
  INSERT INTO t2 VALUES(5, 'A');
}


do_catchsql_test 17.2 { 
  INSERT INTO t1 SELECT b FROM t2;
} {1 {column x is not unique}}

do_execsql_test 17.3 { SELECT * FROM t1 } {X}

finish_test