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

FossilOrigin-Name: ca2ef8a86cf806cbbcc64db03251b1df5b2c5501

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

index fa810c3c2f248b677415fce348019273bcef2be1..998430d736d2d589a18c3b61f02a8133ee97aaab 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Limit\sthe\snumber\sof\sdigits\sshown\sin\sthe\s"prereq"\smask\sfor\s".wheretrace"\ndebugging\soutput.
-D 2016-04-09T14:36:07.399
+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-09T17:04:05.661
 F Makefile.in eba680121821b8a60940a81454316f47a341487a
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a
@@ -319,7 +319,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 556203aab543e91f4e20cc273a507ed712c8da26
+F src/btree.c 3ae6aea66cc4e13d30162ff0d0d43c7088e34abf
 F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9
 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5
 F src/build.c 1944d95f0250ec72dab939f8319a12e237aaad61
@@ -615,7 +615,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
@@ -1482,7 +1482,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 1dfa5234d3ee38c6af2d18a6294afa93232821e7
-R 8cb0faecb86a13a69a59d8a42b73cabb
+P 3686ed7413ae6cdbc8020c0023205e0455e87467
+R 4553ce3d8ac9552c77beb258f84ad711
 U drh
-Z ae55d26bb66b3417bd5295b83c3ebe20
+Z 3040395f9dd600c859bc208544af87b9
index 19da24946993e02926af275a395d3c6693c68739..d5324b3e294301fc29a29d09821085d3f5a02ac1 100644 (file)
@@ -1 +1 @@
-3686ed7413ae6cdbc8020c0023205e0455e87467
\ No newline at end of file
+ca2ef8a86cf806cbbcc64db03251b1df5b2c5501
\ No newline at end of file
index e5be8e0ef8159d3c5d232149b852a9142e262b53..0e30df7f47f25296ddc387eb9433df6342e456a6 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