Fix a recently introduced problem with deleting entries from index tables. (CVS 5754)
FossilOrigin-Name: 83c064cae481ca95b7107e22e98fc599fe85a2da
This commit is contained in:
parent
d94b0556f8
commit
2f78fc66b5
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
||||
C Misc\sclean\sup.\s\sWrapped\sa\sCE\sonly\svariable\sin\sif-defs.\sChanged\sto\sonly\sprovide\scache\shint\sfor\sCE\sbuilds\s(as\sthis\sprevents\sCE\sfrom\scompressing\sthe\sfile.)\sPerformance\stesting\son\sXP\sand\sVista\sshowed\scaching\shint\shad\slittle\seffect\swhen\sthe\sDB\ssize\swas\smuch\ssmaller\sthan\sthe\sO/S\sdisk\scache\ssize,\sand\sprovided\sonly\smarginal\sbenefit\swhen\sthe\sDB\ssize\swas\smuch\slarger\sthan\sthe\scache.\s\sOn\sVista,\soverall\ssystem\sperformance\swas\shurt\sfor\svery\slarge\sDBs.\s\sTicket\s#3387.\s(CVS\s5753)
|
||||
D 2008-09-30T04:20:08
|
||||
C Fix\sa\srecently\sintroduced\sproblem\swith\sdeleting\sentries\sfrom\sindex\stables.\s(CVS\s5754)
|
||||
D 2008-09-30T09:31:45
|
||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||
F Makefile.in e4ab842f9a64ef61d57093539a8aab76b12810db
|
||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||
@ -99,7 +99,7 @@ F src/attach.c db3f4a60538733c1e4dcb9d0217a6e0d6ccd615b
|
||||
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
|
||||
F src/bitvec.c 95c86bd18d8fedf0533f5af196192546e10a7e7d
|
||||
F src/btmutex.c 709cad2cdca0afd013f0f612363810e53f59ec53
|
||||
F src/btree.c df02edb06f8fcb53d607a338d77434c4a3bffe7a
|
||||
F src/btree.c 2e5cf91c3f342fa611bfd6f0250c31b432fbdd90
|
||||
F src/btree.h 6371c5e599fab391a150c96afbc10062b276d107
|
||||
F src/btreeInt.h 3e93c0a6f363bbf68fdd975620f4d3671b6cf7bc
|
||||
F src/build.c 160c71acca8f643f436ed6c1ee2f684c88df4dfe
|
||||
@ -637,7 +637,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
|
||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||
P 78d075ff38d96cc58659a7097dec0e49402aa960
|
||||
R 39be9f2940749141be589318f7d2a538
|
||||
U shane
|
||||
Z b381b1aa9c52e2148aadad6fea9866f7
|
||||
P 15dd0169a4c5e2ff9e3894eec10799cb89d462e5
|
||||
R 67ac196eea416fb3e08d66e37fb1b4f0
|
||||
U danielk1977
|
||||
Z 769068257f0c5361c027fdd2793aa895
|
||||
|
@ -1 +1 @@
|
||||
15dd0169a4c5e2ff9e3894eec10799cb89d462e5
|
||||
83c064cae481ca95b7107e22e98fc599fe85a2da
|
66
src/btree.c
66
src/btree.c
@ -9,7 +9,7 @@
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** $Id: btree.c,v 1.520 2008/09/29 16:41:32 danielk1977 Exp $
|
||||
** $Id: btree.c,v 1.521 2008/09/30 09:31:45 danielk1977 Exp $
|
||||
**
|
||||
** This file implements a external (disk-based) database using BTrees.
|
||||
** See the header comment on "btreeInt.h" for additional information.
|
||||
@ -5883,7 +5883,6 @@ int sqlite3BtreeDelete(BtCursor *pCur){
|
||||
*/
|
||||
BtCursor leafCur;
|
||||
MemPage *pLeafPage;
|
||||
int iLeafIdx;
|
||||
|
||||
unsigned char *pNext;
|
||||
int notUsed;
|
||||
@ -5892,16 +5891,17 @@ int sqlite3BtreeDelete(BtCursor *pCur){
|
||||
sqlite3BtreeGetTempCursor(pCur, &leafCur);
|
||||
rc = sqlite3BtreeNext(&leafCur, ¬Used);
|
||||
if( rc==SQLITE_OK ){
|
||||
assert( leafCur.aiIdx[leafCur.iPage]==0 );
|
||||
pLeafPage = leafCur.apPage[leafCur.iPage];
|
||||
iLeafIdx = leafCur.aiIdx[leafCur.iPage];
|
||||
rc = sqlite3PagerWrite(pLeafPage->pDbPage);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
int leafCursorInvalid = 0;
|
||||
u16 szNext;
|
||||
TRACE(("DELETE: table=%d delete internal from %d replace from leaf %d\n",
|
||||
pCur->pgnoRoot, pPage->pgno, pLeafPage->pgno));
|
||||
dropCell(pPage, idx, cellSizePtr(pPage, pCell));
|
||||
pNext = findCell(pLeafPage, iLeafIdx);
|
||||
pNext = findCell(pLeafPage, 0);
|
||||
szNext = cellSizePtr(pLeafPage, pNext);
|
||||
assert( MX_CELL_SIZE(pBt)>=szNext+4 );
|
||||
allocateTempSpace(pBt);
|
||||
@ -5912,12 +5912,66 @@ int sqlite3BtreeDelete(BtCursor *pCur){
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = insertCell(pPage, idx, pNext-4, szNext+4, tempCell, 0);
|
||||
}
|
||||
|
||||
if( (pPage->nOverflow>0 || (pPage->nFree > pBt->usableSize*2/3)) &&
|
||||
(pLeafPage->nFree+2+szNext > pBt->usableSize*2/3)
|
||||
){
|
||||
/* This branch is taken if the internal node is now either over or
|
||||
** underfull and the leaf node will be underfull after the just cell
|
||||
** copied to the internal node is deleted from it. This is a special
|
||||
** case because the call to balance() to correct the internal node
|
||||
** may change the tree structure and invalidate the contents of
|
||||
** the leafCur.apPage[] and leafCur.aiIdx[] arrays, which will be
|
||||
** used by the balance() required to correct the underfull leaf
|
||||
** node.
|
||||
**
|
||||
** The formula used in the expression above are based on facets of
|
||||
** the SQLite file-format that do not change over time.
|
||||
*/
|
||||
leafCursorInvalid = 1;
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
put4byte(findOverflowCell(pPage, idx), pgnoChild);
|
||||
rc = balance(pCur, 0);
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK && leafCursorInvalid ){
|
||||
/* The leaf-node is now underfull and so the tree needs to be
|
||||
** rebalanced. However, the balance() operation on the internal
|
||||
** node above may have modified the structure of the B-Tree and
|
||||
** so the current contents of leafCur.apPage[] and leafCur.aiIdx[]
|
||||
** may not be trusted.
|
||||
**
|
||||
** It is not possible to copy the ancestry from pCur, as the same
|
||||
** balance() call has invalidated the pCur->apPage[] and aiIdx[]
|
||||
** arrays.
|
||||
**
|
||||
** The call to saveCursorPosition() below internally saves the
|
||||
** key that leafCur is currently pointing to. Currently, there
|
||||
** are two copies of that key in the tree - one here on the leaf
|
||||
** page and one on some internal node in the tree. The copy on
|
||||
** the leaf node is always the next key in tree-order after the
|
||||
** copy on the internal node. So, the call to sqlite3BtreeNext()
|
||||
** calls restoreCursorPosition() to point the cursor to the copy
|
||||
** stored on the internal node, then advances to the next entry,
|
||||
** which happens to be the copy of the key on the internal node.
|
||||
** Net effect: leafCur is pointing back where
|
||||
*/
|
||||
#ifndef NDEBUG
|
||||
Pgno leafPgno = pLeafPage->pgno;
|
||||
#endif
|
||||
rc = saveCursorPosition(&leafCur);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3BtreeNext(&leafCur, ¬Used);
|
||||
}
|
||||
pLeafPage = leafCur.apPage[leafCur.iPage];
|
||||
assert( pLeafPage->pgno==leafPgno );
|
||||
assert( leafCur.aiIdx[leafCur.iPage]==0 );
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
dropCell(pLeafPage, iLeafIdx, szNext);
|
||||
dropCell(pLeafPage, 0, szNext);
|
||||
rc = balance(&leafCur, 0);
|
||||
}
|
||||
}
|
||||
@ -7026,7 +7080,7 @@ static int btreeCopyFile(Btree *pTo, Btree *pFrom){
|
||||
}
|
||||
|
||||
memcpy(zTo, zFrom, nCopy);
|
||||
sqlite3PagerUnref(pFromPage);
|
||||
sqlite3PagerUnref(pFromPage);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user