]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix the sqlite3BtreeDelete() routine so that it preserves the correct
authordrh <drh@noemail.net>
Mon, 18 Apr 2016 16:06:03 +0000 (16:06 +0000)
committerdrh <drh@noemail.net>
Mon, 18 Apr 2016 16:06:03 +0000 (16:06 +0000)
key even when the row being deleted is not on a leaf page.
Fix for ticket [a306e56ff68b8fa56]

FossilOrigin-Name: 368e86c760477f2e646f71f6135b69d40eeb82e7

manifest
manifest.uuid
src/btree.c
test/delete4.test

index 239e5c27e577553412dd01ac64142eb87766de18..348b5c25e3bdceb72d57337aea1b79c7b6ac5a3f 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Increase\sthe\sversion\snumber\sto\s3.12.2.
-D 2016-04-18T15:59:16.905
+C Fix\sthe\ssqlite3BtreeDelete()\sroutine\sso\sthat\sit\spreserves\sthe\scorrect\nkey\seven\swhen\sthe\srow\sbeing\sdeleted\sis\snot\son\sa\sleaf\spage.\nFix\sfor\sticket\s[a306e56ff68b8fa56]
+D 2016-04-18T16:06:03.711
 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc b00bcf0ec7001857aea81ee39fae45d20f5f4e59
@@ -297,7 +297,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
 F src/backup.c f60f0aa55d25d853ffde53d0b0370a7bb7ee41ce
 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63
 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73
-F src/btree.c 577fb5674e2f0aa0a38246afc19e1885a0b8c9b0
+F src/btree.c c833d5ac4469a761435c211956315d000b246fdd
 F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9
 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5
 F src/build.c 16bbcb166a06b4909a4c645273c474645dbdce66
@@ -593,7 +593,7 @@ F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d
 F test/delete.test e1bcdf8926234e27aac24b346ad83d3329ec8b6f
 F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
 F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab
-F test/delete4.test 3ac0b8d23689ba764c2e8b78c1b56b8f1b942fa2
+F test/delete4.test 738044ee892ee0c84e0848e36ba92c55f907d52b
 F test/descidx1.test 6d03b44c8538fe0eb4924e19fba10cdd8f3c9240
 F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d
 F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2
@@ -1459,7 +1459,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P ab9d279f40f81e5a95de10f70324960cf091c368
-R 98297537d8f146517a1f23e21a9df1a6
+P 9c37e9ce07b42bdbaa0cecfdd2bc8181b1eded47
+Q +ca2ef8a86cf806cbbcc64db03251b1df5b2c5501
+R 4710e941720805c2cc7e949e21895ad6
 U drh
-Z c9af401b6ea9af28f45209d059fd0667
+Z e361cdd0aa73a2909e88537a2c8c4051
index 882c458269ff202a4dd3d8e4f9ad63ec4778e752..e879e4e2f6c861a9cbc4783a8c2c5c0185680640 100644 (file)
@@ -1 +1 @@
-9c37e9ce07b42bdbaa0cecfdd2bc8181b1eded47
\ No newline at end of file
+368e86c760477f2e646f71f6135b69d40eeb82e7
\ No newline at end of file
index bf995970951c0145599be741ec357fcc74c94e7a..496e09b690942858f9047d39fd74096fb614c37b 100644 (file)
@@ -8140,6 +8140,28 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
   pPage = pCur->apPage[iCellDepth];
   pCell = findCell(pPage, iCellIdx);
 
+  /* If the bPreserve flag is set to true, then the cursor position must
+  ** be preserved following this delete operation. If the current delete
+  ** will cause a b-tree rebalance, then this is done by saving the cursor
+  ** key and leaving the cursor in CURSOR_REQUIRESEEK state before 
+  ** returning. 
+  **
+  ** Or, if the current delete will not cause a rebalance, then the cursor
+  ** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately
+  ** before or after the deleted entry. In this case set bSkipnext to true.  */
+  if( bPreserve ){
+    if( !pPage->leaf 
+     || (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
+    ){
+      /* A b-tree rebalance will be required after deleting this entry.
+      ** Save the cursor key.  */
+      rc = saveCursorKey(pCur);
+      if( rc ) return rc;
+    }else{
+      bSkipnext = 1;
+    }
+  }
+
   /* If the page containing the entry to delete is not a leaf page, move
   ** the cursor to the largest entry in the tree that is smaller than
   ** the entry being deleted. This cell will replace the cell being deleted
@@ -8166,28 +8188,6 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
     invalidateIncrblobCursors(p, pCur->info.nKey, 0);
   }
 
-  /* If the bPreserve flag is set to true, then the cursor position must
-  ** be preserved following this delete operation. If the current delete
-  ** will cause a b-tree rebalance, then this is done by saving the cursor
-  ** key and leaving the cursor in CURSOR_REQUIRESEEK state before 
-  ** returning. 
-  **
-  ** Or, if the current delete will not cause a rebalance, then the cursor
-  ** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately
-  ** before or after the deleted entry. In this case set bSkipnext to true.  */
-  if( bPreserve ){
-    if( !pPage->leaf 
-     || (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
-    ){
-      /* A b-tree rebalance will be required after deleting this entry.
-      ** Save the cursor key.  */
-      rc = saveCursorKey(pCur);
-      if( rc ) return rc;
-    }else{
-      bSkipnext = 1;
-    }
-  }
-
   /* Make the page containing the entry to be deleted writable. Then free any
   ** overflow pages associated with the entry and finally remove the cell
   ** itself from within the page.  */
index f3598a9496bd8a4a972453c03219b4f4539619e8..7622b7525ee5d8f0e440e25778f93d3e3b6bbbc8 100644 (file)
@@ -139,7 +139,26 @@ do_execsql_test 4.12 {
   PRAGMA integrity_check;
 } {ok}
 
-
-
+# 2016-04-09
+# Ticket https://sqlite.org/src/info/a306e56ff68b8fa5
+# Failure to completely delete when reverse_unordered_selects is
+# engaged.
+#
+db close
+forcedelete test.db
+sqlite3 db test.db
+do_execsql_test 5.0 {
+  PRAGMA page_size=1024;
+  CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
+  CREATE INDEX x1 ON t1(b, c);
+  INSERT INTO t1(a,b,c) VALUES(1, 1, zeroblob(80));
+  INSERT INTO t1(a,b,c) SELECT a+1, 1, c FROM t1;
+  INSERT INTO t1(a,b,c) SELECT a+2, 1, c FROM t1;
+  INSERT INTO t1(a,b,c) SELECT a+10, 2, c FROM t1 WHERE b=1;
+  INSERT INTO t1(a,b,c) SELECT a+20, 3, c FROM t1 WHERE b=1;
+  PRAGMA reverse_unordered_selects = ON;
+  DELETE FROM t1 WHERE b=2;
+  SELECT a FROM t1 WHERE b=2;
+} {}
 
 finish_test