Fix the sqlite3BtreeDelete() routine so that it preserves the correct
key even when the row being deleted is not on a leaf page. Fix for ticket [a306e56ff68b8fa56] FossilOrigin-Name: ca2ef8a86cf806cbbcc64db03251b1df5b2c5501
This commit is contained in:
parent
53801efcdf
commit
bfc7a8bb01
14
manifest
14
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
|
||||
|
@ -1 +1 @@
|
||||
3686ed7413ae6cdbc8020c0023205e0455e87467
|
||||
ca2ef8a86cf806cbbcc64db03251b1df5b2c5501
|
44
src/btree.c
44
src/btree.c
@ -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. */
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user