mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Changes to pragma integrity_check to check rowid order. Tests of same in corruptE.test.
FossilOrigin-Name: cae47c5b09cb122689bcb020a66ce14982cc4aa8
This commit is contained in:
63
src/btree.c
63
src/btree.c
@@ -7411,7 +7411,9 @@ static void checkList(
|
||||
static int checkTreePage(
|
||||
IntegrityCk *pCheck, /* Context for the sanity check */
|
||||
int iPage, /* Page number of the page to check */
|
||||
char *zParentContext /* Parent context */
|
||||
char *zParentContext, /* Parent context */
|
||||
i64 *pnParentMinKey,
|
||||
i64 *pnParentMaxKey
|
||||
){
|
||||
MemPage *pPage;
|
||||
int i, rc, depth, d2, pgno, cnt;
|
||||
@@ -7422,6 +7424,8 @@ static int checkTreePage(
|
||||
int usableSize;
|
||||
char zContext[100];
|
||||
char *hit = 0;
|
||||
i64 nMinKey = 0;
|
||||
i64 nMaxKey = 0;
|
||||
|
||||
sqlite3_snprintf(sizeof(zContext), zContext, "Page %d: ", iPage);
|
||||
|
||||
@@ -7464,6 +7468,16 @@ static int checkTreePage(
|
||||
btreeParseCellPtr(pPage, pCell, &info);
|
||||
sz = info.nData;
|
||||
if( !pPage->intKey ) sz += (int)info.nKey;
|
||||
/* For intKey pages, check that the keys are in order.
|
||||
*/
|
||||
else if( i==0 ) nMinKey = nMaxKey = info.nKey;
|
||||
else{
|
||||
if( info.nKey <= nMaxKey ){
|
||||
checkAppendMsg(pCheck, zContext,
|
||||
"Rowid %lld out of order (previous was %lld)", info.nKey, nMaxKey);
|
||||
}
|
||||
nMaxKey = info.nKey;
|
||||
}
|
||||
assert( sz==info.nPayload );
|
||||
if( (sz>info.nLocal)
|
||||
&& (&pCell[info.iOverflow]<=&pPage->aData[pBt->usableSize])
|
||||
@@ -7487,25 +7501,62 @@ static int checkTreePage(
|
||||
checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, zContext);
|
||||
}
|
||||
#endif
|
||||
d2 = checkTreePage(pCheck, pgno, zContext);
|
||||
d2 = checkTreePage(pCheck, pgno, zContext, &nMinKey, i==0 ? NULL : &nMaxKey);
|
||||
if( i>0 && d2!=depth ){
|
||||
checkAppendMsg(pCheck, zContext, "Child page depth differs");
|
||||
}
|
||||
depth = d2;
|
||||
}
|
||||
}
|
||||
|
||||
if( !pPage->leaf ){
|
||||
pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
|
||||
sqlite3_snprintf(sizeof(zContext), zContext,
|
||||
"On page %d at right child: ", iPage);
|
||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||
if( pBt->autoVacuum ){
|
||||
checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, 0);
|
||||
checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, zContext);
|
||||
}
|
||||
#endif
|
||||
checkTreePage(pCheck, pgno, zContext);
|
||||
checkTreePage(pCheck, pgno, zContext, NULL, !pPage->nCell ? NULL : &nMaxKey);
|
||||
}
|
||||
|
||||
/* For intKey leaf pages, check that the min/max keys are in order
|
||||
** with any left/parent/right pages.
|
||||
*/
|
||||
if( pPage->leaf && pPage->intKey ){
|
||||
/* if we are a left child page */
|
||||
if( pnParentMinKey ){
|
||||
/* if we are the left most child page */
|
||||
if( !pnParentMaxKey ){
|
||||
if( nMaxKey > *pnParentMinKey ){
|
||||
checkAppendMsg(pCheck, zContext,
|
||||
"Rowid %lld out of order (max larger than parent min of %lld)",
|
||||
nMaxKey, *pnParentMinKey);
|
||||
}
|
||||
}else{
|
||||
if( nMinKey <= *pnParentMinKey ){
|
||||
checkAppendMsg(pCheck, zContext,
|
||||
"Rowid %lld out of order (min less than parent min of %lld)",
|
||||
nMinKey, *pnParentMinKey);
|
||||
}
|
||||
if( nMaxKey > *pnParentMaxKey ){
|
||||
checkAppendMsg(pCheck, zContext,
|
||||
"Rowid %lld out of order (max larger than parent max of %lld)",
|
||||
nMaxKey, *pnParentMaxKey);
|
||||
}
|
||||
*pnParentMinKey = nMaxKey;
|
||||
}
|
||||
/* else if we're a right child page */
|
||||
} else if( pnParentMaxKey ){
|
||||
if( nMinKey <= *pnParentMaxKey ){
|
||||
checkAppendMsg(pCheck, zContext,
|
||||
"Rowid %lld out of order (min less than parent max of %lld)",
|
||||
nMinKey, *pnParentMaxKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for complete coverage of the page
|
||||
*/
|
||||
data = pPage->aData;
|
||||
@@ -7529,7 +7580,7 @@ static int checkTreePage(
|
||||
}
|
||||
if( (pc+size-1)>=usableSize ){
|
||||
checkAppendMsg(pCheck, 0,
|
||||
"Corruption detected in cell %d on page %d",i,iPage,0);
|
||||
"Corruption detected in cell %d on page %d",i,iPage);
|
||||
}else{
|
||||
for(j=pc+size-1; j>=pc; j--) hit[j]++;
|
||||
}
|
||||
@@ -7635,7 +7686,7 @@ char *sqlite3BtreeIntegrityCheck(
|
||||
checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0, 0);
|
||||
}
|
||||
#endif
|
||||
checkTreePage(&sCheck, aRoot[i], "List of tree roots: ");
|
||||
checkTreePage(&sCheck, aRoot[i], "List of tree roots: ", NULL, NULL);
|
||||
}
|
||||
|
||||
/* Make sure every page in the file is referenced
|
||||
|
Reference in New Issue
Block a user