]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
When an incremental blob cursor is invalidated (occurs when an SQL statement modifies...
authordan <dan@noemail.net>
Fri, 23 Mar 2012 11:09:59 +0000 (11:09 +0000)
committerdan <dan@noemail.net>
Fri, 23 Mar 2012 11:09:59 +0000 (11:09 +0000)
FossilOrigin-Name: 82c3f2ba42f2c75ba6951cc2743148886a4dc0bc

manifest
manifest.uuid
src/btree.c
test/incrblob4.test [new file with mode: 0644]

index 508b8682ec326dbc5455e8f2d063fa21723764ee..42af1dead07613e0ab5c2816975b6ebfad37acf8 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Update\sa\scouple\sof\sexisting\stest\scases.
-D 2012-03-23T11:07:22.067
+C When\san\sincremental\sblob\scursor\sis\sinvalidated\s(occurs\swhen\san\sSQL\sstatement\smodifies\sor\sdeletes\sthe\srow\sthe\sblob\scursor\spoints\sto)\srelease\sall\spage\sreferences\sheld\sby\sthe\scursor.\sOtherwise,\sthe\spresence\sof\sthese\sreferences\smay\scause\sother\scode\sin\sbtree.c\sto\sincorrectly\sinfer\sthat\sthe\sdatabase\sis\scorrupt.
+D 2012-03-23T11:09:59.261
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 2f37e468503dbe79d35c9f6dffcf3fae1ae9ec20
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -125,7 +125,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
 F src/backup.c 6be23a344d3301ae38e92fddb3a33b91c309fce4
 F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef
 F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
-F src/btree.c 253c3147a4ebbaee42cd329dbdc0856200bbbda7
+F src/btree.c 02aeee1f6d425e11f7b9b2d9d461ac501645ed6f
 F src/btree.h 48a013f8964f12d944d90e4700df47b72dd6d923
 F src/btreeInt.h 26d8ca625b141927fe6620c1d2cf58eaf494ca0c
 F src/build.c c4d36e527f457f9992a6663365871dfa7c5094b8
@@ -520,6 +520,7 @@ F test/in4.test 64f3cc1acde1b9161ccdd8e5bde3daefdb5b2617
 F test/incrblob.test 26fde912a1e0aff158b3a84ef3b265f046aad3be
 F test/incrblob2.test edc3a96e557bd61fb39acc8d2edd43371fbbaa19
 F test/incrblob3.test aedbb35ea1b6450c33b98f2b6ed98e5020be8dc7
+F test/incrblob4.test 09be37d3dd996a31ea6993bba7837ece549414a8
 F test/incrblob_err.test d2562d2771ebffd4b3af89ef64c140dd44371597
 F test/incrblobfault.test 917c0292224c64a56ef7215fd633a3a82f805be0
 F test/incrvacuum.test d2a6ddf5e429720b5fe502766af747915ccf6c32
@@ -996,7 +997,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
 F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
-P ecab2083334dcdde24a3c56864114979b7a6f25a
-R 1ee2743e0728dfd5b16085c25faca723
+P dcb8fa0f77a44250df0e8c4f6cfb9f6e181982d7
+R 290f1c272852728c6b51f5c4cfcf23c3
 U dan
-Z 1978b788ff30c8d67f82270e25799f6e
+Z a40c41b170a152c43db8b0f47b2a047b
index c9913b975dc717a92c36500e23af29492589ea7c..4d4b9fb32f5123ea9f2bb25face4baa4bb040621 100644 (file)
@@ -1 +1 @@
-dcb8fa0f77a44250df0e8c4f6cfb9f6e181982d7
\ No newline at end of file
+82c3f2ba42f2c75ba6951cc2743148886a4dc0bc
\ No newline at end of file
index 68345144a8dd1a7cc1ab009ec35a1b4c10a5a90a..d24c2be069678d20c15add38a90965e8eef1fbc2 100644 (file)
@@ -6789,13 +6789,6 @@ int sqlite3BtreeInsert(
   ** blob of associated data.  */
   assert( (pKey==0)==(pCur->pKeyInfo==0) );
 
-  /* If this is an insert into a table b-tree, invalidate any incrblob 
-  ** cursors open on the row being replaced (assuming this is a replace
-  ** operation - if it is not, the following is a no-op).  */
-  if( pCur->pKeyInfo==0 ){
-    invalidateIncrblobCursors(p, nKey, 0);
-  }
-
   /* Save the positions of any other cursors open on this table.
   **
   ** In some cases, the call to btreeMoveto() below is a no-op. For
@@ -6809,6 +6802,14 @@ int sqlite3BtreeInsert(
   */
   rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur);
   if( rc ) return rc;
+
+  /* If this is an insert into a table b-tree, invalidate any incrblob 
+  ** cursors open on the row being replaced (assuming this is a replace
+  ** operation - if it is not, the following is a no-op).  */
+  if( pCur->pKeyInfo==0 ){
+    invalidateIncrblobCursors(p, nKey, 0);
+  }
+
   if( !loc ){
     rc = btreeMoveto(pCur, pKey, nKey, appendBias, &loc);
     if( rc ) return rc;
@@ -6919,12 +6920,6 @@ int sqlite3BtreeDelete(BtCursor *pCur){
     return SQLITE_ERROR;  /* Something has gone awry. */
   }
 
-  /* If this is a delete operation to remove a row from a table b-tree,
-  ** invalidate any incrblob cursors open on the row being deleted.  */
-  if( pCur->pKeyInfo==0 ){
-    invalidateIncrblobCursors(p, pCur->info.nKey, 0);
-  }
-
   iCellDepth = pCur->iPage;
   iCellIdx = pCur->aiIdx[iCellDepth];
   pPage = pCur->apPage[iCellDepth];
@@ -6950,6 +6945,13 @@ int sqlite3BtreeDelete(BtCursor *pCur){
   */
   rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur);
   if( rc ) return rc;
+
+  /* If this is a delete operation to remove a row from a table b-tree,
+  ** invalidate any incrblob cursors open on the row being deleted.  */
+  if( pCur->pKeyInfo==0 ){
+    invalidateIncrblobCursors(p, pCur->info.nKey, 0);
+  }
+
   rc = sqlite3PagerWrite(pPage->pDbPage);
   if( rc ) return rc;
   rc = clearCell(pPage, pCell);
@@ -7231,13 +7233,13 @@ int sqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange){
   sqlite3BtreeEnter(p);
   assert( p->inTrans==TRANS_WRITE );
 
-  /* Invalidate all incrblob cursors open on table iTable (assuming iTable
-  ** is the root of a table b-tree - if it is not, the following call is
-  ** a no-op).  */
-  invalidateIncrblobCursors(p, 0, 1);
-
   rc = saveAllCursors(pBt, (Pgno)iTable, 0);
+
   if( SQLITE_OK==rc ){
+    /* Invalidate all incrblob cursors open on table iTable (assuming iTable
+    ** is the root of a table b-tree - if it is not, the following call is
+    ** a no-op).  */
+    invalidateIncrblobCursors(p, 0, 1);
     rc = clearDatabasePage(pBt, (Pgno)iTable, 0, pnChange);
   }
   sqlite3BtreeLeave(p);
diff --git a/test/incrblob4.test b/test/incrblob4.test
new file mode 100644 (file)
index 0000000..a96356b
--- /dev/null
@@ -0,0 +1,90 @@
+# 2012 March 23
+#
+# The author disclaims copyright to this source code.  In place of
+# a legal notice, here is a blessing:
+#
+#    May you do good and not evil.
+#    May you find forgiveness for yourself and forgive others.
+#    May you share freely, never taking more than you give.
+#
+#***********************************************************************
+#
+#
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+ifcapable {!incrblob} { finish_test ; return }
+set testprefix incrblob4
+
+proc create_t1 {} {
+  execsql {
+    PRAGMA page_size = 1024;
+    CREATE TABLE t1(k INTEGER PRIMARY KEY, v);
+  }
+}
+
+proc populate_t1 {} {
+  set data [list a b c d e f g h i j k l m n o p q r s t u v w x y z]
+  foreach d $data {
+    set blob [string repeat $d 900]
+    execsql { INSERT INTO t1(v) VALUES($blob) }
+  }
+}
+
+
+do_test 1.1 { 
+  create_t1
+  populate_t1 
+} {}
+
+do_test 1.2 {
+  set blob [db incrblob t1 v 5]
+  read $blob 10
+} {eeeeeeeeee}
+
+do_test 1.3 {
+  execsql { DELETE FROM t1 }
+  populate_t1
+} {}
+
+
+
+do_test 2.1 { 
+  reset_db
+  create_t1
+  populate_t1 
+} {}
+
+do_test 2.2 {
+  set blob [db incrblob t1 v 10]
+  read $blob 10
+} {jjjjjjjjjj}
+
+do_test 2.3 {
+  set new [string repeat % 900]
+  execsql { DELETE FROM t1 WHERE k=10 }
+  execsql { DELETE FROM t1 WHERE k=9 }
+  execsql { INSERT INTO t1(v) VALUES($new) }
+} {}
+
+
+
+do_test 3.1 {
+  reset_db
+  create_t1
+  populate_t1 
+} {}
+
+do_test 3.2 {
+  set blob [db incrblob t1 v 20]
+  read $blob 10
+} {tttttttttt}
+
+do_test 3.3 {
+  set new [string repeat % 900]
+  execsql { UPDATE t1 SET v = $new WHERE k = 20 }
+  execsql { DELETE FROM t1 WHERE k=19 }
+  execsql { INSERT INTO t1(v) VALUES($new) }
+} {}
+
+finish_test
+