mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Modify various routines inside btree.c to take a pointer to the return-code
as a parameter and to no-op if the return-code storage location already contains a non-zero code. (CVS 6911) FossilOrigin-Name: 7dcf2a78727ce448d9d26bd6e2e23b553456ec54
This commit is contained in:
12
manifest
12
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Use\san\sALWAYS()\son\sa\sconditional\sin\sbtmutex.c\sthat\sis\salways\strue.\s(CVS\s6910)
|
C Modify\svarious\sroutines\sinside\sbtree.c\sto\stake\sa\spointer\sto\sthe\sreturn-code\nas\sa\sparameter\sand\sto\sno-op\sif\sthe\sreturn-code\sstorage\slocation\salready\ncontains\sa\snon-zero\scode.\s(CVS\s6911)
|
||||||
D 2009-07-20T12:33:33
|
D 2009-07-20T17:11:50
|
||||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||||
F Makefile.in df9359da7a726ccb67a45db905c5447d5c00c6ef
|
F Makefile.in df9359da7a726ccb67a45db905c5447d5c00c6ef
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@@ -106,7 +106,7 @@ F src/auth.c 802a9439dfa0b8c208b10055cba400e82ef18025
|
|||||||
F src/backup.c 6f1c2d9862c8a3feb7739dfcca02c1f5352e37f3
|
F src/backup.c 6f1c2d9862c8a3feb7739dfcca02c1f5352e37f3
|
||||||
F src/bitvec.c cfbf6af5b0ababb4f06ed3e75c616dadaf47fcbd
|
F src/bitvec.c cfbf6af5b0ababb4f06ed3e75c616dadaf47fcbd
|
||||||
F src/btmutex.c 0f43a75bb5b8147b386e8e1c3e71ba734e3863b7
|
F src/btmutex.c 0f43a75bb5b8147b386e8e1c3e71ba734e3863b7
|
||||||
F src/btree.c 4d964398d7291fd536cd6361c70ccad9c8dc3b9a
|
F src/btree.c a597d1d9608c88d6ce06f89c396fb560d244f2bc
|
||||||
F src/btree.h e53a10fd31d16c60a86f03c9467a6f470aa3683b
|
F src/btree.h e53a10fd31d16c60a86f03c9467a6f470aa3683b
|
||||||
F src/btreeInt.h 1c86297e69380f6577e7ae67452597dd8d5c2705
|
F src/btreeInt.h 1c86297e69380f6577e7ae67452597dd8d5c2705
|
||||||
F src/build.c 867028ee9f63f7bc8eb8d4a720bb98cf9b9a12b4
|
F src/build.c 867028ee9f63f7bc8eb8d4a720bb98cf9b9a12b4
|
||||||
@@ -741,7 +741,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
|||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746
|
F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746
|
||||||
P 7572991bc2232f57d04c972d516a3e8f85f34f14
|
P 609022caff12c010575e704be550da6f52226d33
|
||||||
R 9782ac6fe60ba619daf4a6a17cc11b51
|
R f0dac37b25de3361940901b7ede7713d
|
||||||
U drh
|
U drh
|
||||||
Z d571a5e8243db19d230ca1d0fe109d34
|
Z 0886d43bf9f8d479825e913af0119cfa
|
||||||
|
@@ -1 +1 @@
|
|||||||
609022caff12c010575e704be550da6f52226d33
|
7dcf2a78727ce448d9d26bd6e2e23b553456ec54
|
156
src/btree.c
156
src/btree.c
@@ -9,7 +9,7 @@
|
|||||||
** May you share freely, never taking more than you give.
|
** May you share freely, never taking more than you give.
|
||||||
**
|
**
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
** $Id: btree.c,v 1.691 2009/07/16 18:21:18 drh Exp $
|
** $Id: btree.c,v 1.692 2009/07/20 17:11:50 drh Exp $
|
||||||
**
|
**
|
||||||
** This file implements a external (disk-based) database using BTrees.
|
** This file implements a external (disk-based) database using BTrees.
|
||||||
** See the header comment on "btreeInt.h" for additional information.
|
** See the header comment on "btreeInt.h" for additional information.
|
||||||
@@ -724,14 +724,19 @@ static Pgno ptrmapPageno(BtShared *pBt, Pgno pgno){
|
|||||||
**
|
**
|
||||||
** This routine updates the pointer map entry for page number 'key'
|
** This routine updates the pointer map entry for page number 'key'
|
||||||
** so that it maps to type 'eType' and parent page number 'pgno'.
|
** so that it maps to type 'eType' and parent page number 'pgno'.
|
||||||
** An error code is returned if something goes wrong, otherwise SQLITE_OK.
|
**
|
||||||
|
** If *pRC is initially non-zero (non-SQLITE_OK) then this routine is
|
||||||
|
** a no-op. If an error occurs, the appropriate error code is written
|
||||||
|
** into *pRC.
|
||||||
*/
|
*/
|
||||||
static int ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent){
|
static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){
|
||||||
DbPage *pDbPage; /* The pointer map page */
|
DbPage *pDbPage; /* The pointer map page */
|
||||||
u8 *pPtrmap; /* The pointer map data */
|
u8 *pPtrmap; /* The pointer map data */
|
||||||
Pgno iPtrmap; /* The pointer map page number */
|
Pgno iPtrmap; /* The pointer map page number */
|
||||||
int offset; /* Offset in pointer map page */
|
int offset; /* Offset in pointer map page */
|
||||||
int rc;
|
int rc; /* Return code from subfunctions */
|
||||||
|
|
||||||
|
if( *pRC ) return;
|
||||||
|
|
||||||
assert( sqlite3_mutex_held(pBt->mutex) );
|
assert( sqlite3_mutex_held(pBt->mutex) );
|
||||||
/* The master-journal page number must never be used as a pointer map page */
|
/* The master-journal page number must never be used as a pointer map page */
|
||||||
@@ -739,23 +744,25 @@ static int ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent){
|
|||||||
|
|
||||||
assert( pBt->autoVacuum );
|
assert( pBt->autoVacuum );
|
||||||
if( key==0 ){
|
if( key==0 ){
|
||||||
return SQLITE_CORRUPT_BKPT;
|
*pRC = SQLITE_CORRUPT_BKPT;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
iPtrmap = PTRMAP_PAGENO(pBt, key);
|
iPtrmap = PTRMAP_PAGENO(pBt, key);
|
||||||
rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage);
|
rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
return rc;
|
*pRC = rc;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
offset = PTRMAP_PTROFFSET(iPtrmap, key);
|
offset = PTRMAP_PTROFFSET(iPtrmap, key);
|
||||||
if( offset<0 ){
|
if( offset<0 ){
|
||||||
rc = SQLITE_CORRUPT_BKPT;
|
*pRC = SQLITE_CORRUPT_BKPT;
|
||||||
goto ptrmap_exit;
|
goto ptrmap_exit;
|
||||||
}
|
}
|
||||||
pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage);
|
pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage);
|
||||||
|
|
||||||
if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){
|
if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){
|
||||||
TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent));
|
TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent));
|
||||||
rc = sqlite3PagerWrite(pDbPage);
|
*pRC= rc = sqlite3PagerWrite(pDbPage);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
pPtrmap[offset] = eType;
|
pPtrmap[offset] = eType;
|
||||||
put4byte(&pPtrmap[offset+1], parent);
|
put4byte(&pPtrmap[offset+1], parent);
|
||||||
@@ -764,7 +771,6 @@ static int ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent){
|
|||||||
|
|
||||||
ptrmap_exit:
|
ptrmap_exit:
|
||||||
sqlite3PagerUnref(pDbPage);
|
sqlite3PagerUnref(pDbPage);
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -801,9 +807,9 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
|
|||||||
}
|
}
|
||||||
|
|
||||||
#else /* if defined SQLITE_OMIT_AUTOVACUUM */
|
#else /* if defined SQLITE_OMIT_AUTOVACUUM */
|
||||||
#define ptrmapPut(w,x,y,z) SQLITE_OK
|
#define ptrmapPut(w,x,y,z,rc)
|
||||||
#define ptrmapGet(w,x,y,z) SQLITE_OK
|
#define ptrmapGet(w,x,y,z) SQLITE_OK
|
||||||
#define ptrmapPutOvflPtr(x, y) SQLITE_OK
|
#define ptrmapPutOvflPtr(x, y, rc)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -998,16 +1004,16 @@ static u16 cellSize(MemPage *pPage, int iCell){
|
|||||||
** to an overflow page, insert an entry into the pointer-map
|
** to an overflow page, insert an entry into the pointer-map
|
||||||
** for the overflow page.
|
** for the overflow page.
|
||||||
*/
|
*/
|
||||||
static int ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell){
|
static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
|
||||||
CellInfo info;
|
CellInfo info;
|
||||||
|
if( *pRC ) return;
|
||||||
assert( pCell!=0 );
|
assert( pCell!=0 );
|
||||||
btreeParseCellPtr(pPage, pCell, &info);
|
btreeParseCellPtr(pPage, pCell, &info);
|
||||||
assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload );
|
assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload );
|
||||||
if( info.iOverflow ){
|
if( info.iOverflow ){
|
||||||
Pgno ovfl = get4byte(&pCell[info.iOverflow]);
|
Pgno ovfl = get4byte(&pCell[info.iOverflow]);
|
||||||
return ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno);
|
ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC);
|
||||||
}
|
}
|
||||||
return SQLITE_OK;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -2529,21 +2535,17 @@ static int setChildPtrmaps(MemPage *pPage){
|
|||||||
for(i=0; i<nCell; i++){
|
for(i=0; i<nCell; i++){
|
||||||
u8 *pCell = findCell(pPage, i);
|
u8 *pCell = findCell(pPage, i);
|
||||||
|
|
||||||
rc = ptrmapPutOvflPtr(pPage, pCell);
|
ptrmapPutOvflPtr(pPage, pCell, &rc);
|
||||||
if( rc!=SQLITE_OK ){
|
|
||||||
goto set_child_ptrmaps_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !pPage->leaf ){
|
if( !pPage->leaf ){
|
||||||
Pgno childPgno = get4byte(pCell);
|
Pgno childPgno = get4byte(pCell);
|
||||||
rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno);
|
ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno, &rc);
|
||||||
if( rc!=SQLITE_OK ) goto set_child_ptrmaps_out;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !pPage->leaf ){
|
if( !pPage->leaf ){
|
||||||
Pgno childPgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
|
Pgno childPgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
|
||||||
rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno);
|
ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno, &rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_child_ptrmaps_out:
|
set_child_ptrmaps_out:
|
||||||
@@ -2667,7 +2669,7 @@ static int relocatePage(
|
|||||||
}else{
|
}else{
|
||||||
Pgno nextOvfl = get4byte(pDbPage->aData);
|
Pgno nextOvfl = get4byte(pDbPage->aData);
|
||||||
if( nextOvfl!=0 ){
|
if( nextOvfl!=0 ){
|
||||||
rc = ptrmapPut(pBt, nextOvfl, PTRMAP_OVERFLOW2, iFreePage);
|
ptrmapPut(pBt, nextOvfl, PTRMAP_OVERFLOW2, iFreePage, &rc);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -2691,7 +2693,7 @@ static int relocatePage(
|
|||||||
rc = modifyPagePointer(pPtrPage, iDbPage, iFreePage, eType);
|
rc = modifyPagePointer(pPtrPage, iDbPage, iFreePage, eType);
|
||||||
releasePage(pPtrPage);
|
releasePage(pPtrPage);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
rc = ptrmapPut(pBt, iFreePage, eType, iPtrPage);
|
ptrmapPut(pBt, iFreePage, eType, iPtrPage, &rc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
@@ -4876,7 +4878,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
|
|||||||
** to indicate that the page is free.
|
** to indicate that the page is free.
|
||||||
*/
|
*/
|
||||||
if( ISAUTOVACUUM ){
|
if( ISAUTOVACUUM ){
|
||||||
rc = ptrmapPut(pBt, iPage, PTRMAP_FREEPAGE, 0);
|
ptrmapPut(pBt, iPage, PTRMAP_FREEPAGE, 0, &rc);
|
||||||
if( rc ) goto freepage_out;
|
if( rc ) goto freepage_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5107,7 +5109,7 @@ static int fillInCell(
|
|||||||
*/
|
*/
|
||||||
if( pBt->autoVacuum && rc==SQLITE_OK ){
|
if( pBt->autoVacuum && rc==SQLITE_OK ){
|
||||||
u8 eType = (pgnoPtrmap?PTRMAP_OVERFLOW2:PTRMAP_OVERFLOW1);
|
u8 eType = (pgnoPtrmap?PTRMAP_OVERFLOW2:PTRMAP_OVERFLOW1);
|
||||||
rc = ptrmapPut(pBt, pgnoOvfl, eType, pgnoPtrmap);
|
ptrmapPut(pBt, pgnoOvfl, eType, pgnoPtrmap, &rc);
|
||||||
if( rc ){
|
if( rc ){
|
||||||
releasePage(pOvfl);
|
releasePage(pOvfl);
|
||||||
}
|
}
|
||||||
@@ -5176,13 +5178,15 @@ static int fillInCell(
|
|||||||
**
|
**
|
||||||
** "sz" must be the number of bytes in the cell.
|
** "sz" must be the number of bytes in the cell.
|
||||||
*/
|
*/
|
||||||
static int dropCell(MemPage *pPage, int idx, int sz){
|
static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){
|
||||||
int i; /* Loop counter */
|
int i; /* Loop counter */
|
||||||
int pc; /* Offset to cell content of cell being deleted */
|
int pc; /* Offset to cell content of cell being deleted */
|
||||||
u8 *data; /* pPage->aData */
|
u8 *data; /* pPage->aData */
|
||||||
u8 *ptr; /* Used to move bytes around within data[] */
|
u8 *ptr; /* Used to move bytes around within data[] */
|
||||||
int rc; /* The return code */
|
int rc; /* The return code */
|
||||||
|
|
||||||
|
if( *pRC ) return;
|
||||||
|
|
||||||
assert( idx>=0 && idx<pPage->nCell );
|
assert( idx>=0 && idx<pPage->nCell );
|
||||||
assert( sz==cellSize(pPage, idx) );
|
assert( sz==cellSize(pPage, idx) );
|
||||||
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
|
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
|
||||||
@@ -5192,11 +5196,13 @@ static int dropCell(MemPage *pPage, int idx, int sz){
|
|||||||
pc = get2byte(ptr);
|
pc = get2byte(ptr);
|
||||||
if( (pc<pPage->hdrOffset+6+pPage->childPtrSize)
|
if( (pc<pPage->hdrOffset+6+pPage->childPtrSize)
|
||||||
|| (pc+sz>pPage->pBt->usableSize) ){
|
|| (pc+sz>pPage->pBt->usableSize) ){
|
||||||
return SQLITE_CORRUPT_BKPT;
|
*pRC = SQLITE_CORRUPT_BKPT;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
rc = freeSpace(pPage, pc, sz);
|
rc = freeSpace(pPage, pc, sz);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc ){
|
||||||
return rc;
|
*pRC = rc;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
for(i=idx+1; i<pPage->nCell; i++, ptr+=2){
|
for(i=idx+1; i<pPage->nCell; i++, ptr+=2){
|
||||||
ptr[0] = ptr[2];
|
ptr[0] = ptr[2];
|
||||||
@@ -5205,7 +5211,6 @@ static int dropCell(MemPage *pPage, int idx, int sz){
|
|||||||
pPage->nCell--;
|
pPage->nCell--;
|
||||||
put2byte(&data[pPage->hdrOffset+3], pPage->nCell);
|
put2byte(&data[pPage->hdrOffset+3], pPage->nCell);
|
||||||
pPage->nFree += 2;
|
pPage->nFree += 2;
|
||||||
return SQLITE_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -5225,13 +5230,14 @@ static int dropCell(MemPage *pPage, int idx, int sz){
|
|||||||
** nSkip is non-zero, then pCell may not point to an invalid memory location
|
** nSkip is non-zero, then pCell may not point to an invalid memory location
|
||||||
** (but pCell+nSkip is always valid).
|
** (but pCell+nSkip is always valid).
|
||||||
*/
|
*/
|
||||||
static int insertCell(
|
static void insertCell(
|
||||||
MemPage *pPage, /* Page into which we are copying */
|
MemPage *pPage, /* Page into which we are copying */
|
||||||
int i, /* New cell becomes the i-th cell of the page */
|
int i, /* New cell becomes the i-th cell of the page */
|
||||||
u8 *pCell, /* Content of the new cell */
|
u8 *pCell, /* Content of the new cell */
|
||||||
int sz, /* Bytes of content in pCell */
|
int sz, /* Bytes of content in pCell */
|
||||||
u8 *pTemp, /* Temp storage space for pCell, if needed */
|
u8 *pTemp, /* Temp storage space for pCell, if needed */
|
||||||
Pgno iChild /* If non-zero, replace first 4 bytes with this value */
|
Pgno iChild, /* If non-zero, replace first 4 bytes with this value */
|
||||||
|
int *pRC /* Read and write return code from here */
|
||||||
){
|
){
|
||||||
int idx; /* Where to write new cell content in data[] */
|
int idx; /* Where to write new cell content in data[] */
|
||||||
int j; /* Loop counter */
|
int j; /* Loop counter */
|
||||||
@@ -5243,6 +5249,8 @@ static int insertCell(
|
|||||||
|
|
||||||
int nSkip = (iChild ? 4 : 0);
|
int nSkip = (iChild ? 4 : 0);
|
||||||
|
|
||||||
|
if( *pRC ) return;
|
||||||
|
|
||||||
assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
|
assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
|
||||||
assert( pPage->nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=5460 );
|
assert( pPage->nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=5460 );
|
||||||
assert( pPage->nOverflow<=ArraySize(pPage->aOvfl) );
|
assert( pPage->nOverflow<=ArraySize(pPage->aOvfl) );
|
||||||
@@ -5263,7 +5271,8 @@ static int insertCell(
|
|||||||
}else{
|
}else{
|
||||||
int rc = sqlite3PagerWrite(pPage->pDbPage);
|
int rc = sqlite3PagerWrite(pPage->pDbPage);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
return rc;
|
*pRC = rc;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
|
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
|
||||||
data = pPage->aData;
|
data = pPage->aData;
|
||||||
@@ -5271,10 +5280,11 @@ static int insertCell(
|
|||||||
end = cellOffset + 2*pPage->nCell;
|
end = cellOffset + 2*pPage->nCell;
|
||||||
ins = cellOffset + 2*i;
|
ins = cellOffset + 2*i;
|
||||||
rc = allocateSpace(pPage, sz, &idx);
|
rc = allocateSpace(pPage, sz, &idx);
|
||||||
if( rc ) return rc;
|
if( rc ){ *pRC = rc; return; }
|
||||||
assert( idx>=end+2 );
|
assert( idx>=end+2 );
|
||||||
if( idx+sz > pPage->pBt->usableSize ){
|
if( idx+sz > pPage->pBt->usableSize ){
|
||||||
return SQLITE_CORRUPT_BKPT;
|
*pRC = SQLITE_CORRUPT_BKPT;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
pPage->nCell++;
|
pPage->nCell++;
|
||||||
pPage->nFree -= (u16)(2 + sz);
|
pPage->nFree -= (u16)(2 + sz);
|
||||||
@@ -5293,12 +5303,10 @@ static int insertCell(
|
|||||||
/* The cell may contain a pointer to an overflow page. If so, write
|
/* The cell may contain a pointer to an overflow page. If so, write
|
||||||
** the entry for the overflow page into the pointer map.
|
** the entry for the overflow page into the pointer map.
|
||||||
*/
|
*/
|
||||||
return ptrmapPutOvflPtr(pPage, pCell);
|
ptrmapPutOvflPtr(pPage, pCell, pRC);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return SQLITE_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -5421,9 +5429,9 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
|
|||||||
** rollback, undoing any changes made to the parent page.
|
** rollback, undoing any changes made to the parent page.
|
||||||
*/
|
*/
|
||||||
if( ISAUTOVACUUM ){
|
if( ISAUTOVACUUM ){
|
||||||
rc = ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno);
|
ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno, &rc);
|
||||||
if( szCell>pNew->minLocal && rc==SQLITE_OK ){
|
if( szCell>pNew->minLocal ){
|
||||||
rc = ptrmapPutOvflPtr(pNew, pCell);
|
ptrmapPutOvflPtr(pNew, pCell, &rc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5447,7 +5455,8 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
|
|||||||
while( ((*(pOut++) = *(pCell++))&0x80) && pCell<pStop );
|
while( ((*(pOut++) = *(pCell++))&0x80) && pCell<pStop );
|
||||||
|
|
||||||
/* Insert the new divider cell into pParent. */
|
/* Insert the new divider cell into pParent. */
|
||||||
insertCell(pParent,pParent->nCell,pSpace,(int)(pOut-pSpace),0,pPage->pgno);
|
insertCell(pParent, pParent->nCell, pSpace, (int)(pOut-pSpace),
|
||||||
|
0, pPage->pgno, &rc);
|
||||||
|
|
||||||
/* Set the right-child pointer of pParent to point to the new page. */
|
/* Set the right-child pointer of pParent to point to the new page. */
|
||||||
put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew);
|
put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew);
|
||||||
@@ -5711,7 +5720,7 @@ static int balance_nonroot(
|
|||||||
memcpy(&aOvflSpace[apDiv[i]-pParent->aData], apDiv[i], szNew[i]);
|
memcpy(&aOvflSpace[apDiv[i]-pParent->aData], apDiv[i], szNew[i]);
|
||||||
apDiv[i] = &aOvflSpace[apDiv[i]-pParent->aData];
|
apDiv[i] = &aOvflSpace[apDiv[i]-pParent->aData];
|
||||||
#endif
|
#endif
|
||||||
dropCell(pParent, i+nxDiv-pParent->nOverflow, szNew[i]);
|
dropCell(pParent, i+nxDiv-pParent->nOverflow, szNew[i], &rc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5905,7 +5914,7 @@ static int balance_nonroot(
|
|||||||
|
|
||||||
/* Set the pointer-map entry for the new sibling page. */
|
/* Set the pointer-map entry for the new sibling page. */
|
||||||
if( ISAUTOVACUUM ){
|
if( ISAUTOVACUUM ){
|
||||||
rc = ptrmapPut(pBt, pNew->pgno, PTRMAP_BTREE, pParent->pgno);
|
ptrmapPut(pBt, pNew->pgno, PTRMAP_BTREE, pParent->pgno, &rc);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
goto balance_cleanup;
|
goto balance_cleanup;
|
||||||
}
|
}
|
||||||
@@ -6029,7 +6038,7 @@ static int balance_nonroot(
|
|||||||
iOvflSpace += sz;
|
iOvflSpace += sz;
|
||||||
assert( sz<=pBt->pageSize/4 );
|
assert( sz<=pBt->pageSize/4 );
|
||||||
assert( iOvflSpace<=pBt->pageSize );
|
assert( iOvflSpace<=pBt->pageSize );
|
||||||
rc = insertCell(pParent, nxDiv, pCell, sz, pTemp, pNew->pgno);
|
insertCell(pParent, nxDiv, pCell, sz, pTemp, pNew->pgno, &rc);
|
||||||
if( rc!=SQLITE_OK ) goto balance_cleanup;
|
if( rc!=SQLITE_OK ) goto balance_cleanup;
|
||||||
assert( sqlite3PagerIswriteable(pParent->pDbPage) );
|
assert( sqlite3PagerIswriteable(pParent->pDbPage) );
|
||||||
|
|
||||||
@@ -6148,18 +6157,18 @@ static int balance_nonroot(
|
|||||||
** with any child or overflow pages need to be updated. */
|
** with any child or overflow pages need to be updated. */
|
||||||
if( isDivider || pOld->pgno!=pNew->pgno ){
|
if( isDivider || pOld->pgno!=pNew->pgno ){
|
||||||
if( !leafCorrection ){
|
if( !leafCorrection ){
|
||||||
rc = ptrmapPut(pBt, get4byte(apCell[i]), PTRMAP_BTREE, pNew->pgno);
|
ptrmapPut(pBt, get4byte(apCell[i]), PTRMAP_BTREE, pNew->pgno, &rc);
|
||||||
}
|
}
|
||||||
if( szCell[i]>pNew->minLocal && rc==SQLITE_OK ){
|
if( szCell[i]>pNew->minLocal ){
|
||||||
rc = ptrmapPutOvflPtr(pNew, apCell[i]);
|
ptrmapPutOvflPtr(pNew, apCell[i], &rc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !leafCorrection ){
|
if( !leafCorrection ){
|
||||||
for(i=0; rc==SQLITE_OK && i<nNew; i++){
|
for(i=0; i<nNew; i++){
|
||||||
rc = ptrmapPut(
|
u32 key = get4byte(&apNew[i]->aData[8]);
|
||||||
pBt, get4byte(&apNew[i]->aData[8]), PTRMAP_BTREE, apNew[i]->pgno);
|
ptrmapPut(pBt, key, PTRMAP_BTREE, apNew[i]->pgno, &rc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6225,12 +6234,17 @@ static int balance_deeper(MemPage *pRoot, MemPage **ppChild){
|
|||||||
** page that will become the new right-child of pPage. Copy the contents
|
** page that will become the new right-child of pPage. Copy the contents
|
||||||
** of the node stored on pRoot into the new child page.
|
** of the node stored on pRoot into the new child page.
|
||||||
*/
|
*/
|
||||||
if( SQLITE_OK!=(rc = sqlite3PagerWrite(pRoot->pDbPage))
|
rc = sqlite3PagerWrite(pRoot->pDbPage);
|
||||||
|| SQLITE_OK!=(rc = allocateBtreePage(pBt,&pChild,&pgnoChild,pRoot->pgno,0))
|
if( rc==SQLITE_OK ){
|
||||||
|| SQLITE_OK!=(rc = copyNodeContent(pRoot, pChild))
|
rc = allocateBtreePage(pBt,&pChild,&pgnoChild,pRoot->pgno,0);
|
||||||
|| (ISAUTOVACUUM &&
|
if( rc==SQLITE_OK ){
|
||||||
SQLITE_OK!=(rc = ptrmapPut(pBt, pgnoChild, PTRMAP_BTREE, pRoot->pgno)))
|
rc = copyNodeContent(pRoot, pChild);
|
||||||
){
|
if( ISAUTOVACUUM ){
|
||||||
|
ptrmapPut(pBt, pgnoChild, PTRMAP_BTREE, pRoot->pgno, &rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( rc ){
|
||||||
*ppChild = 0;
|
*ppChild = 0;
|
||||||
releasePage(pChild);
|
releasePage(pChild);
|
||||||
return rc;
|
return rc;
|
||||||
@@ -6414,6 +6428,11 @@ int sqlite3BtreeInsert(
|
|||||||
unsigned char *oldCell;
|
unsigned char *oldCell;
|
||||||
unsigned char *newCell = 0;
|
unsigned char *newCell = 0;
|
||||||
|
|
||||||
|
if( pCur->eState==CURSOR_FAULT ){
|
||||||
|
assert( pCur->skipNext!=SQLITE_OK );
|
||||||
|
return pCur->skipNext;
|
||||||
|
}
|
||||||
|
|
||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorHoldsMutex(pCur) );
|
||||||
assert( pCur->wrFlag && pBt->inTransaction==TRANS_WRITE && !pBt->readOnly );
|
assert( pCur->wrFlag && pBt->inTransaction==TRANS_WRITE && !pBt->readOnly );
|
||||||
assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
|
assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
|
||||||
@@ -6432,11 +6451,6 @@ int sqlite3BtreeInsert(
|
|||||||
invalidateIncrblobCursors(p, pCur->pgnoRoot, nKey, 0);
|
invalidateIncrblobCursors(p, pCur->pgnoRoot, nKey, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pCur->eState==CURSOR_FAULT ){
|
|
||||||
assert( pCur->skipNext!=SQLITE_OK );
|
|
||||||
return pCur->skipNext;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Save the positions of any other cursors open on this table.
|
/* Save the positions of any other cursors open on this table.
|
||||||
**
|
**
|
||||||
** In some cases, the call to btreeMoveto() below is a no-op. For
|
** In some cases, the call to btreeMoveto() below is a no-op. For
|
||||||
@@ -6485,18 +6499,15 @@ int sqlite3BtreeInsert(
|
|||||||
}
|
}
|
||||||
szOld = cellSizePtr(pPage, oldCell);
|
szOld = cellSizePtr(pPage, oldCell);
|
||||||
rc = clearCell(pPage, oldCell);
|
rc = clearCell(pPage, oldCell);
|
||||||
|
dropCell(pPage, idx, szOld, &rc);
|
||||||
if( rc ) goto end_insert;
|
if( rc ) goto end_insert;
|
||||||
rc = dropCell(pPage, idx, szOld);
|
|
||||||
if( rc!=SQLITE_OK ) {
|
|
||||||
goto end_insert;
|
|
||||||
}
|
|
||||||
}else if( loc<0 && pPage->nCell>0 ){
|
}else if( loc<0 && pPage->nCell>0 ){
|
||||||
assert( pPage->leaf );
|
assert( pPage->leaf );
|
||||||
idx = ++pCur->aiIdx[pCur->iPage];
|
idx = ++pCur->aiIdx[pCur->iPage];
|
||||||
}else{
|
}else{
|
||||||
assert( pPage->leaf );
|
assert( pPage->leaf );
|
||||||
}
|
}
|
||||||
rc = insertCell(pPage, idx, newCell, szNew, 0, 0);
|
insertCell(pPage, idx, newCell, szNew, 0, 0, &rc);
|
||||||
assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 );
|
assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 );
|
||||||
|
|
||||||
/* If no error has occured and pPage has an overflow cell, call balance()
|
/* If no error has occured and pPage has an overflow cell, call balance()
|
||||||
@@ -6597,8 +6608,7 @@ int sqlite3BtreeDelete(BtCursor *pCur){
|
|||||||
rc = sqlite3PagerWrite(pPage->pDbPage);
|
rc = sqlite3PagerWrite(pPage->pDbPage);
|
||||||
if( rc ) return rc;
|
if( rc ) return rc;
|
||||||
rc = clearCell(pPage, pCell);
|
rc = clearCell(pPage, pCell);
|
||||||
if( rc ) return rc;
|
dropCell(pPage, iCellIdx, cellSizePtr(pPage, pCell), &rc);
|
||||||
rc = dropCell(pPage, iCellIdx, cellSizePtr(pPage, pCell));
|
|
||||||
if( rc ) return rc;
|
if( rc ) return rc;
|
||||||
|
|
||||||
/* If the cell deleted was not located on a leaf page, then the cursor
|
/* If the cell deleted was not located on a leaf page, then the cursor
|
||||||
@@ -6620,10 +6630,8 @@ int sqlite3BtreeDelete(BtCursor *pCur){
|
|||||||
pTmp = pBt->pTmpSpace;
|
pTmp = pBt->pTmpSpace;
|
||||||
|
|
||||||
rc = sqlite3PagerWrite(pLeaf->pDbPage);
|
rc = sqlite3PagerWrite(pLeaf->pDbPage);
|
||||||
if( rc ) return rc;
|
insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc);
|
||||||
rc = insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n);
|
dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc);
|
||||||
if( rc ) return rc;
|
|
||||||
rc = dropCell(pLeaf, pLeaf->nCell-1, nCell);
|
|
||||||
if( rc ) return rc;
|
if( rc ) return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6767,7 +6775,7 @@ static int btreeCreateTable(Btree *p, int *piTable, int flags){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Update the pointer-map and meta-data with the new root-page number. */
|
/* Update the pointer-map and meta-data with the new root-page number. */
|
||||||
rc = ptrmapPut(pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0);
|
ptrmapPut(pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0, &rc);
|
||||||
if( rc ){
|
if( rc ){
|
||||||
releasePage(pRoot);
|
releasePage(pRoot);
|
||||||
return rc;
|
return rc;
|
||||||
|
Reference in New Issue
Block a user