]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
When an incremental blob cursor is invalidated (occurs when an SQL statement modifies...
authordrh <drh@noemail.net>
Fri, 23 Mar 2012 14:23:52 +0000 (14:23 +0000)
committerdrh <drh@noemail.net>
Fri, 23 Mar 2012 14:23:52 +0000 (14:23 +0000)
FossilOrigin-Name: 341b703ce16361a64ed8bba64ff46792132c0b56

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

index a8b57dd4e9d3cb98142f9ae794ddfcc73648a300..2a0edd601841c39d4832aaef092a08487051e622 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Always\squote\sthe\snames\sof\stables\sin\sthe\soutput\sof\sthe\sshell's\s".dump"\scommand,\neven\sif\sthe\sname\sis\spure\salphabetic\stext,\sin\scase\sthe\sname\sis\sa\skeyword.
-D 2012-03-22T12:50:34.137
+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-23T14:23:52.727
 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
@@ -516,6 +516,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
@@ -992,7 +993,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
 F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
-P 0fb26c7bfa7a4bb1503f90fd6f5b9c70f444665b
-R 76825aab78a4aec4e0f8b3a0fc8144af
+P 638b71150281a211f89b4057b0d5d32d3fbcf323
+R bf4ea56b709d8c66bd287b12bb865310
 U drh
-Z cbcc6857e5f2528670826efd0ad94a0c
+Z 71976091f9202f9aa459dff852dbcf55
index f6c5dfb8e20f7423e50382acb1e82f93ab8d48bf..a8830b75fe54f340f103f7d75e43a4c73d1b5d53 100644 (file)
@@ -1 +1 @@
-638b71150281a211f89b4057b0d5d32d3fbcf323
\ No newline at end of file
+341b703ce16361a64ed8bba64ff46792132c0b56
\ 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
+