SQLite4
Check-in [123a055a36]
Not logged in

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

Overview
Comment:Fix an issue with sub-transaction rollback.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | primary-keys
Files: files | file ages | folders
SHA1: 123a055a36f80a6ad76b59458bb2cc9cb83de4d1
User & Date: dan 2012-04-17 05:36:51
Context
2012-04-17
08:23
Fix more problems with triggers and triggers on views. check-in: 77b33bff0a user: dan tags: primary-keys
05:36
Fix an issue with sub-transaction rollback. check-in: 123a055a36 user: dan tags: primary-keys
2012-04-16
19:04
Get most of the trigger logic working again. Still some problems. check-in: b480943c48 user: dan tags: primary-keys
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/kvmem.c.

333
334
335
336
337
338
339
340
341
342

343
344
345
346
347
348
349
...
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
...
825
826
827
828
829
830
831

832
833
834
835
836
837
838
    memcpy(pNode->aKey, aKey, nKey);
    pNode->nKey = nKey;
    pNode->nRef = 1;
    pChng = kvmemNewChng(p, pNode);
    if( pChng==0 ){
      sqlite4_free(pNode);
      pNode = 0;
    }else{
      pChng->pData = 0;
    }

  }
  return pNode;
}

#ifdef SQLITE_DEBUG
/*
** Return the number of times that node pNode occurs in the sub-tree 
................................................................................
  KVMem *p = (KVMem*)pKVStore;
  assert( p->iMagicKVMemBase==SQLITE_KVMEMBASE_MAGIC );
  assert( iLevel>=0 );
  while( p->base.iTransLevel>iLevel && p->base.iTransLevel>1 ){
    KVMemChng *pChng, *pNext;
    for(pChng=p->apLog[p->base.iTransLevel-2]; pChng; pChng=pNext){
      KVMemNode *pNode = pChng->pNode;
      if( pChng->pData ){
        kvmemDataUnref(pNode->pData);
        pNode->pData = pChng->pData;
        pNode->mxTrans = pChng->oldTrans;
      }else{
        kvmemRemoveNode(p, pNode);
      }
      pNext = pChng->pNext;
................................................................................
  assert( p->base.iTransLevel>=2 );
  pNode = pCur->pNode;
  if( pNode==0 ) return SQLITE_OK;
  if( pNode->pData==0 ) return SQLITE_OK;
  if( pNode->mxTrans<p->base.iTransLevel ){
    pChng = kvmemNewChng(p, pNode);
    if( pChng==0 ) return SQLITE_NOMEM;

  }else{
    kvmemDataUnref(pNode->pData);
    pNode->pData = 0;
  }
  return SQLITE_OK;
}








<
<

>







 







|







 







>







333
334
335
336
337
338
339


340
341
342
343
344
345
346
347
348
...
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
...
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
    memcpy(pNode->aKey, aKey, nKey);
    pNode->nKey = nKey;
    pNode->nRef = 1;
    pChng = kvmemNewChng(p, pNode);
    if( pChng==0 ){
      sqlite4_free(pNode);
      pNode = 0;


    }
    assert( pChng==0 || pChng->pData==0 );
  }
  return pNode;
}

#ifdef SQLITE_DEBUG
/*
** Return the number of times that node pNode occurs in the sub-tree 
................................................................................
  KVMem *p = (KVMem*)pKVStore;
  assert( p->iMagicKVMemBase==SQLITE_KVMEMBASE_MAGIC );
  assert( iLevel>=0 );
  while( p->base.iTransLevel>iLevel && p->base.iTransLevel>1 ){
    KVMemChng *pChng, *pNext;
    for(pChng=p->apLog[p->base.iTransLevel-2]; pChng; pChng=pNext){
      KVMemNode *pNode = pChng->pNode;
      if( pChng->pData || pChng->oldTrans>0 ){
        kvmemDataUnref(pNode->pData);
        pNode->pData = pChng->pData;
        pNode->mxTrans = pChng->oldTrans;
      }else{
        kvmemRemoveNode(p, pNode);
      }
      pNext = pChng->pNext;
................................................................................
  assert( p->base.iTransLevel>=2 );
  pNode = pCur->pNode;
  if( pNode==0 ) return SQLITE_OK;
  if( pNode->pData==0 ) return SQLITE_OK;
  if( pNode->mxTrans<p->base.iTransLevel ){
    pChng = kvmemNewChng(p, pNode);
    if( pChng==0 ) return SQLITE_NOMEM;
    assert( pNode->pData==0 );
  }else{
    kvmemDataUnref(pNode->pData);
    pNode->pData = 0;
  }
  return SQLITE_OK;
}

Changes to test/simple.test.

647
648
649
650
651
652
653
654

































655
656
657
658
659
660
661
  CREATE TRIGGER ai_tbl AFTER INSERT ON tbl BEGIN
    INSERT OR IGNORE INTO tbl values (new.a, 0, 0);
  END;
}

do_execsql_test 35.2 { INSERT OR REPLACE INTO tbl values (2, 2, 3) }
do_execsql_test 35.3 { SELECT * from tbl } {1 2 3 2 0 0}
  


































#proc populate_t1 {} {
#  db eval {
#    INSERT INTO t1(a, b) VALUES(4, 'four');
#    INSERT INTO t1(a, b) VALUES(9, 'nine');
#    INSERT INTO t1(a, b) VALUES(5, 'five');
#    INSERT INTO t1(a, b) VALUES(1, 'one');







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
  CREATE TRIGGER ai_tbl AFTER INSERT ON tbl BEGIN
    INSERT OR IGNORE INTO tbl values (new.a, 0, 0);
  END;
}

do_execsql_test 35.2 { INSERT OR REPLACE INTO tbl values (2, 2, 3) }
do_execsql_test 35.3 { SELECT * from tbl } {1 2 3 2 0 0}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 36.1 {
  CREATE TABLE tbl (a primary key, b, c);
  CREATE TRIGGER au_tbl AFTER UPDATE ON tbl BEGIN
    UPDATE OR IGNORE tbl SET a = new.a, c = 10;
  END;

  BEGIN;
  INSERT INTO tbl VALUES(1, 3, 10);
  INSERT INTO tbl VALUES(2, 3, 4);
}
do_catchsql_test 36.2 {
  UPDATE OR ROLLBACK tbl SET a = 4 WHERE a = 1;
} {1 {column a is not unique}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 37.1 {
  CREATE TABLE t1(a PRIMARY KEY, b);
  INSERT INTO t1 VALUES('x', 'xxx');
  INSERT INTO t1 VALUES('y', 'yyy');
}

do_execsql_test 37.2 {
  BEGIN;
    DELETE FROM t1 WHERE a='y';
    INSERT INTO t1 VALUES('y', 'yyy');
    DELETE FROM t1 WHERE a='y';
    INSERT INTO t1 VALUES('y', 'yyy');
  ROLLBACK;
}
 

#proc populate_t1 {} {
#  db eval {
#    INSERT INTO t1(a, b) VALUES(4, 'four');
#    INSERT INTO t1(a, b) VALUES(9, 'nine');
#    INSERT INTO t1(a, b) VALUES(5, 'five');
#    INSERT INTO t1(a, b) VALUES(1, 'one');