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

Overview
Comment:Ensure that kvmemSeek() does not come to rest on a deleted node.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | primary-keys
Files: files | file ages | folders
SHA1: 21991a932a63fa8b97a693efe792d34e83dfa703
User & Date: dan 2012-04-13 05:50:33.610
Context
2012-04-13
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
2012-04-12
19:52
Further fixes to things. check-in: 81fab25002 user: dan tags: primary-keys
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/kvmem.c.
626
627
628
629
630
631
632










































633
634
635
636
637
638
639
    pCur->pOwner->nCursor--;
    kvmemReset(pKVCursor);
    memset(pCur, 0, sizeof(*pCur));
    sqlite4_free(pCur);
  }
  return SQLITE_OK;
}











































/*
** Seek a cursor.
*/
static int kvmemSeek(
  KVCursor *pKVCursor, 
  const KVByteArray *aKey,







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







626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
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
    pCur->pOwner->nCursor--;
    kvmemReset(pKVCursor);
    memset(pCur, 0, sizeof(*pCur));
    sqlite4_free(pCur);
  }
  return SQLITE_OK;
}

/*
** Move a cursor to the next non-deleted node.
*/
static int kvmemNextEntry(KVCursor *pKVCursor){
  KVMemCursor *pCur;
  KVMemNode *pNode;

  pCur = (KVMemCursor*)pKVCursor;
  assert( pCur->iMagicKVMemCur==SQLITE_KVMEMCUR_MAGIC );
  pNode = pCur->pNode;
  kvmemReset(pKVCursor);
  do{
    pNode = kvmemNext(pNode);
  }while( pNode && pNode->pData==0 );
  if( pNode ){
    pCur->pNode = kvmemNodeRef(pNode);
    pCur->pData = kvmemDataRef(pNode->pData);
  }
  return pNode ? SQLITE_OK : SQLITE_NOTFOUND;
}

/*
** Move a cursor to the previous non-deleted node.
*/
static int kvmemPrevEntry(KVCursor *pKVCursor){
  KVMemCursor *pCur;
  KVMemNode *pNode;

  pCur = (KVMemCursor*)pKVCursor;
  assert( pCur->iMagicKVMemCur==SQLITE_KVMEMCUR_MAGIC );
  pNode = pCur->pNode;
  kvmemReset(pKVCursor);
  do{
    pNode = kvmemPrev(pNode);
  }while( pNode && pNode->pData==0 );
  if( pNode ){
    pCur->pNode = kvmemNodeRef(pNode);
    pCur->pData = kvmemDataRef(pNode->pData);
  }
  return pNode ? SQLITE_OK : SQLITE_NOTFOUND;
}

/*
** Seek a cursor.
*/
static int kvmemSeek(
  KVCursor *pKVCursor, 
  const KVByteArray *aKey,
672
673
674
675
676
677
678

















679
680
681
682
683
684
685
    }
  }
  kvmemNodeUnref(pCur->pNode);
  kvmemDataUnref(pCur->pData);
  if( pBest ){
    pCur->pNode = kvmemNodeRef(pBest);
    pCur->pData = kvmemDataRef(pBest->pData);

















  }else{
    pCur->pNode = 0;
    pCur->pData = 0;
  }
  assert( rc!=SQLITE_DONE );
  return rc;
}







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







714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
    }
  }
  kvmemNodeUnref(pCur->pNode);
  kvmemDataUnref(pCur->pData);
  if( pBest ){
    pCur->pNode = kvmemNodeRef(pBest);
    pCur->pData = kvmemDataRef(pBest->pData);

    /* The cursor currently points to a deleted node. If parameter 'direction'
    ** was zero (exact matches only), then the search has failed - return
    ** SQLITE_NOTFOUND. Otherwise, advance to the next (if direction is +ve)
    ** or the previous (if direction is -ve) undeleted node in the tree.  */
    if( pCur->pData==0 ){
      if( direction==0 ){
        rc = SQLITE_NOTFOUND;
      }else{ 
        if( (direction>0 ? kvmemNextEntry : kvmemPrevEntry)(pCur) ){
          rc = SQLITE_NOTFOUND;
        }else{
          rc = SQLITE_INEXACT;
        }
      }
    }

  }else{
    pCur->pNode = 0;
    pCur->pData = 0;
  }
  assert( rc!=SQLITE_DONE );
  return rc;
}
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
  }else{
    kvmemDataUnref(pNode->pData);
    pNode->pData = 0;
  }
  return SQLITE_OK;
}

/*
** Move a cursor to the next non-deleted node.
*/
static int kvmemNextEntry(KVCursor *pKVCursor){
  KVMemCursor *pCur;
  KVMemNode *pNode;

  pCur = (KVMemCursor*)pKVCursor;
  assert( pCur->iMagicKVMemCur==SQLITE_KVMEMCUR_MAGIC );
  pNode = pCur->pNode;
  kvmemReset(pKVCursor);
  do{
    pNode = kvmemNext(pNode);
  }while( pNode && pNode->pData==0 );
  if( pNode ){
    pCur->pNode = kvmemNodeRef(pNode);
    pCur->pData = kvmemDataRef(pNode->pData);
  }
  return pNode ? SQLITE_OK : SQLITE_NOTFOUND;
}

/*
** Move a cursor to the previous non-deleted node.
*/
static int kvmemPrevEntry(KVCursor *pKVCursor){
  KVMemCursor *pCur;
  KVMemNode *pNode;

  pCur = (KVMemCursor*)pKVCursor;
  assert( pCur->iMagicKVMemCur==SQLITE_KVMEMCUR_MAGIC );
  pNode = pCur->pNode;
  kvmemReset(pKVCursor);
  do{
    pNode = kvmemPrev(pNode);
  }while( pNode && pNode->pData==0 );
  if( pNode ){
    pCur->pNode = kvmemNodeRef(pNode);
    pCur->pData = kvmemDataRef(pNode->pData);
  }
  return pNode ? SQLITE_OK : SQLITE_NOTFOUND;
}

/*
** Return the key of the node the cursor is pointing to.
*/
static int kvmemKey(
  KVCursor *pKVCursor,         /* The cursor whose key is desired */
  const KVByteArray **paKey,   /* Make this point to the key */
  KVSize *pN                   /* Make this point to the size of the key */







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







771
772
773
774
775
776
777










































778
779
780
781
782
783
784
  }else{
    kvmemDataUnref(pNode->pData);
    pNode->pData = 0;
  }
  return SQLITE_OK;
}











































/*
** Return the key of the node the cursor is pointing to.
*/
static int kvmemKey(
  KVCursor *pKVCursor,         /* The cursor whose key is desired */
  const KVByteArray **paKey,   /* Make this point to the key */
  KVSize *pN                   /* Make this point to the size of the key */
Changes to test/simple.test.
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216

do_execsql_test 8.1 {
  CREATE TABLE t1(a PRIMARY KEY, b);
  INSERT INTO t1 VALUES('a', 'b');
}

do_execsql_test 8.2 { DELETE FROM t1 WHERE b = 'b' }

execsql {PRAGMA vdbe_trace = 1}
breakpoint
do_execsql_test 8.3 { SELECT * FROM t1 } {}
finish_test

do_execsql_test 8.4 {
  INSERT INTO t1 VALUES('a', 'A');
  INSERT INTO t1 VALUES('b', 'B');
  INSERT INTO t1 VALUES('c', 'A');
  INSERT INTO t1 VALUES('d', 'B');
  INSERT INTO t1 VALUES('e', 'A');







<
<
<

<







198
199
200
201
202
203
204



205

206
207
208
209
210
211
212

do_execsql_test 8.1 {
  CREATE TABLE t1(a PRIMARY KEY, b);
  INSERT INTO t1 VALUES('a', 'b');
}

do_execsql_test 8.2 { DELETE FROM t1 WHERE b = 'b' }



do_execsql_test 8.3 { SELECT * FROM t1 } {}


do_execsql_test 8.4 {
  INSERT INTO t1 VALUES('a', 'A');
  INSERT INTO t1 VALUES('b', 'B');
  INSERT INTO t1 VALUES('c', 'A');
  INSERT INTO t1 VALUES('d', 'B');
  INSERT INTO t1 VALUES('e', 'A');