Implemented the sqliteBtreeSanityCheck() test function. (CVS 232)
FossilOrigin-Name: 42486880ed31318ef36a8831b959e9115b4fbac6
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
C More\sBTree\stests\sand\sa\sfew\sbug\sfixes.\s(CVS\s231)
|
||||
D 2001-06-28T11:50:22
|
||||
C Implemented\sthe\ssqliteBtreeSanityCheck()\stest\sfunction.\s(CVS\s232)
|
||||
D 2001-06-30T21:53:53
|
||||
F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
|
||||
F Makefile.in 63bc9a6a39b7160ce8d2392ae74eb4ca4ca84c6e
|
||||
F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
|
||||
@@ -12,8 +12,8 @@ F notes/notes1.txt b7c0812b704a022e88c621146ae50955c923d464
|
||||
F notes/notes2.txt 7e3fafd5e25906c1fe1e95f13b089aa398ca403e
|
||||
F notes/notes3.txt 985bf688b59f1f52bfe6e4b1f896efdeffac1432
|
||||
F src/TODO 38a68a489e56e9fd4a96263e0ff9404a47368ad4
|
||||
F src/btree.c 19c77416536851667983be43af62c631fb395a92
|
||||
F src/btree.h d327e9ad671d41d41aa2dd376c9230c8d2167c8e
|
||||
F src/btree.c 26f04c3fc1bb5bc9ba598c373cba09acaf82d6ce
|
||||
F src/btree.h 987d80658ae67f0e4d8b849539c113d4f9a7e835
|
||||
F src/build.c 4f6a2d551c56342cd4a0420654835be3ad179651
|
||||
F src/dbbe.c b18259f99d87240cbe751021cf14dd3aa83a48af
|
||||
F src/dbbe.h 7235b15c6c5d8be0c4da469cef9620cee70b1cc8
|
||||
@@ -45,7 +45,7 @@ F src/table.c adcaf074f6c1075e86359174e68701fa2acfc4d6
|
||||
F src/tclsqlite.c af29a45cb4c2244a6fd032568a22d26516472b2c
|
||||
F src/test1.c abb3cb427e735ae87e6533f5b3b7164b7da91bc4
|
||||
F src/test2.c 0183625225a860397b4fd3041aefb48f77e4630a
|
||||
F src/test3.c b55fd9d2af55b29e0a906851bb09de3006a28629
|
||||
F src/test3.c 6b5a099476ab96e7bca8bb6c48bc28700157a314
|
||||
F src/tokenize.c 0118b57702cb6550769316e8443b06760b067acf
|
||||
F src/update.c 0cf789656a936d4356668393267692fa4b03ffc6
|
||||
F src/util.c 1b396ac34e30dd6222d82e996c17b161bbc906bc
|
||||
@@ -53,7 +53,7 @@ F src/vdbe.c f93be4414ba892df9c5589815d2a57c1fb12c820
|
||||
F src/vdbe.h dc1205da434c6a9da03b5d6b089270bbc8e6d437
|
||||
F src/where.c 0c542fc44bd85152dfb8507862cfe2e60c629e9f
|
||||
F test/all.test 21d55a97e39e7ec5776751dc9dd8b1b51ef4a048
|
||||
F test/btree.test 6299ba795987b28fddd62e0869211c97ba311bcc
|
||||
F test/btree.test 2463425e01ef94ec123fdbfb0dcae33f5303d5b1
|
||||
F test/copy.test b77a1214bd7756f2849d5c4fa6e715c0ff0c34eb
|
||||
F test/dbbe.test a022fe2d983848f786e17ef1fc6809cfd37fb02c
|
||||
F test/delete.test 50b9b1f06c843d591741dba7869433a105360dbf
|
||||
@@ -108,7 +108,7 @@ F www/opcode.tcl cb3a1abf8b7b9be9f3a228d097d6bf8b742c2b6f
|
||||
F www/sqlite.tcl cb0d23d8f061a80543928755ec7775da6e4f362f
|
||||
F www/tclsqlite.tcl 06f81c401f79a04f2c5ebfb97e7c176225c0aef2
|
||||
F www/vdbe.tcl 0c8aaa529dd216ccbf7daaabd80985e413d5f9ad
|
||||
P 9cfeeb5896d2a17c8c7904136d346a6245c9e497
|
||||
R 143955071809794a38422b6ba77e94d9
|
||||
P 2c9127943cd5a541613924d2df773c4e8df4c1a6
|
||||
R 28adcf006d91ae47e28b3894b3bf7acf
|
||||
U drh
|
||||
Z c80cdc0e1cd9e727a881d0fcbcd59b2a
|
||||
Z a0a81713c9302268fb4ff7274344753c
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
2c9127943cd5a541613924d2df773c4e8df4c1a6
|
||||
42486880ed31318ef36a8831b959e9115b4fbac6
|
||||
+287
-7
@@ -21,7 +21,7 @@
|
||||
** http://www.hwaci.com/drh/
|
||||
**
|
||||
*************************************************************************
|
||||
** $Id: btree.c,v 1.17 2001/06/28 11:50:22 drh Exp $
|
||||
** $Id: btree.c,v 1.18 2001/06/30 21:53:53 drh Exp $
|
||||
**
|
||||
** This file implements a external (disk-based) database using BTrees.
|
||||
** For a detailed discussion of BTrees, refer to
|
||||
@@ -2142,7 +2142,15 @@ int sqliteBtreeUpdateMeta(Btree *pBt, int *aMeta){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
** The complete implementation of the BTree subsystem is above this line.
|
||||
** All the code the follows is for testing and troubleshooting the BTree
|
||||
** subsystem. None of the code that follows is used during normal operation.
|
||||
** All of the following code is omitted unless the library is compiled with
|
||||
** the -DSQLITE_TEST=1 compiler option.
|
||||
******************************************************************************/
|
||||
#ifdef SQLITE_TEST
|
||||
|
||||
/*
|
||||
** Print a disassembly of the given page on standard output. This routine
|
||||
** is used for debugging and testing only.
|
||||
@@ -2205,9 +2213,7 @@ int sqliteBtreePageDump(Btree *pBt, int pgno){
|
||||
sqlitepager_unref(pPage);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_TEST
|
||||
/*
|
||||
** Fill aResult[] with information about the entry and page that the
|
||||
** cursor is pointing to.
|
||||
@@ -2220,6 +2226,8 @@ int sqliteBtreePageDump(Btree *pBt, int pgno){
|
||||
** aResult[5] = Number of free blocks on the page
|
||||
** aResult[6] = Page number of the left child of this entry
|
||||
** aResult[7] = Page number of the right child for the whole page
|
||||
**
|
||||
** This routine is used for testing and debugging only.
|
||||
*/
|
||||
int sqliteBtreeCursorDump(BtCursor *pCur, int *aResult){
|
||||
int cnt, idx;
|
||||
@@ -2245,13 +2253,285 @@ int sqliteBtreeCursorDump(BtCursor *pCur, int *aResult){
|
||||
aResult[7] = pPage->u.hdr.rightChild;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_TEST
|
||||
/*
|
||||
** Return the pager associated with a BTree
|
||||
** Return the pager associated with a BTree. This routine is used for
|
||||
** testing and debugging only.
|
||||
*/
|
||||
Pager *sqliteBtreePager(Btree *pBt){
|
||||
return pBt->pPager;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** This structure is passed around through all the sanity checking routines
|
||||
** in order to keep track of some global state information.
|
||||
*/
|
||||
typedef struct SanityCheck SanityCheck;
|
||||
struct SanityCheck {
|
||||
Btree *pBt; // The tree being checked out
|
||||
Pager *pPager; // The associated pager. Also accessible by pBt->pPager
|
||||
int nPage; // Number of pages in the database
|
||||
int *anRef; // Number of times each page is referenced
|
||||
char *zErrMsg; // An error message. NULL of no errors seen.
|
||||
};
|
||||
|
||||
/*
|
||||
** Append a message to the error message string.
|
||||
*/
|
||||
static void checkAppendMsg(SanityCheck *pCheck, char *zMsg1, char *zMsg2){
|
||||
if( pCheck->zErrMsg ){
|
||||
char *zOld = pCheck->zErrMsg;
|
||||
pCheck->zErrMsg = 0;
|
||||
sqliteSetString(&pCheck->zErrMsg, zOld, "\n", zMsg1, zMsg2, 0);
|
||||
sqliteFree(zOld);
|
||||
}else{
|
||||
sqliteSetString(&pCheck->zErrMsg, zMsg1, zMsg2, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Add 1 to the reference count for page iPage. If this is the second
|
||||
** reference to the page, add an error message to pCheck->zErrMsg.
|
||||
** Return 1 if there are 2 ore more references to the page and 0 if
|
||||
** if this is the first reference to the page.
|
||||
**
|
||||
** Also check that the page number is in bounds.
|
||||
*/
|
||||
static int checkRef(SanityCheck *pCheck, int iPage, char *zContext){
|
||||
if( iPage==0 ) return 1;
|
||||
if( iPage>pCheck->nPage ){
|
||||
char zBuf[100];
|
||||
sprintf(zBuf, "invalid page number %d", iPage);
|
||||
checkAppendMsg(pCheck, zContext, zBuf);
|
||||
return 1;
|
||||
}
|
||||
if( pCheck->anRef[iPage]==1 ){
|
||||
char zBuf[100];
|
||||
sprintf(zBuf, "2nd reference to page %d", iPage);
|
||||
checkAppendMsg(pCheck, zContext, zBuf);
|
||||
return 1;
|
||||
}
|
||||
return (pCheck->anRef[iPage]++)>1;
|
||||
}
|
||||
|
||||
/*
|
||||
** Check the integrity of the freelist or of an overflow page list.
|
||||
** Verify that the number of pages on the list is N.
|
||||
*/
|
||||
static void checkList(SanityCheck *pCheck, int iPage, int N, char *zContext){
|
||||
char zMsg[100];
|
||||
while( N-- ){
|
||||
OverflowPage *pOvfl;
|
||||
if( iPage<1 ){
|
||||
sprintf(zMsg, "%d pages missing from overflow list", N+1);
|
||||
checkAppendMsg(pCheck, zContext, zMsg);
|
||||
break;
|
||||
}
|
||||
if( checkRef(pCheck, iPage, zContext) ) break;
|
||||
if( sqlitepager_get(pCheck->pPager, (Pgno)iPage, (void**)&pOvfl) ){
|
||||
sprintf(zMsg, "failed to get page %d", iPage);
|
||||
checkAppendMsg(pCheck, zContext, zMsg);
|
||||
break;
|
||||
}
|
||||
iPage = (int)pOvfl->iNext;
|
||||
sqlitepager_unref(pOvfl);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Do various sanity checks on a single page of a tree. Return
|
||||
** the tree depth. Root pages return 0. Parents of root pages
|
||||
** return 1, and so forth.
|
||||
**
|
||||
** These checks are done:
|
||||
**
|
||||
** 1. Make sure that cells and freeblocks do not overlap
|
||||
** but combine to completely cover the page.
|
||||
** 2. Make sure cell keys are in order.
|
||||
** 3. Make sure no key is less than or equal to zLowerBound.
|
||||
** 4. Make sure no key is greater than or equal to zUpperBound.
|
||||
** 5. Check the integrity of overflow pages.
|
||||
** 6. Recursively call checkTreePage on all children.
|
||||
** 7. Verify that the depth of all children is the same.
|
||||
** 8. Make sure this page is at least 50% full or else it is
|
||||
** the root of the tree.
|
||||
*/
|
||||
static int checkTreePage(
|
||||
SanityCheck *pCheck, /* Context for the sanity check */
|
||||
int iPage, /* Page number of the page to check */
|
||||
MemPage *pParent, /* Parent page */
|
||||
char *zParentContext, /* Parent context */
|
||||
char *zLowerBound, /* All keys should be greater than this, if not NULL */
|
||||
char *zUpperBound /* All keys should be less than this, if not NULL */
|
||||
){
|
||||
MemPage *pPage;
|
||||
int i, rc, depth, d2, pgno;
|
||||
char *zKey1, *zKey2;
|
||||
BtCursor cur;
|
||||
char zMsg[100];
|
||||
char zContext[100];
|
||||
char hit[SQLITE_PAGE_SIZE];
|
||||
|
||||
/* Check that the page exists
|
||||
*/
|
||||
if( iPage==0 ) return 0;
|
||||
if( checkRef(pCheck, iPage, zParentContext) ) return 0;
|
||||
sprintf(zContext, "On tree page %d: ", iPage);
|
||||
if( (rc = sqlitepager_get(pCheck->pPager, (Pgno)iPage, (void**)&pPage))!=0 ){
|
||||
sprintf(zMsg, "unable to get the page. error code=%d", rc);
|
||||
checkAppendMsg(pCheck, zContext, zMsg);
|
||||
return 0;
|
||||
}
|
||||
if( (rc = initPage(pPage, (Pgno)iPage, pParent))!=0 ){
|
||||
sprintf(zMsg, "initPage() returns error code %d", rc);
|
||||
checkAppendMsg(pCheck, zContext, zMsg);
|
||||
sqlitepager_unref(pPage);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check out all the cells.
|
||||
*/
|
||||
depth = 0;
|
||||
zKey1 = zLowerBound ? sqliteStrDup(zLowerBound) : 0;
|
||||
cur.pPage = pPage;
|
||||
cur.pBt = pCheck->pBt;
|
||||
for(i=0; i<pPage->nCell; i++){
|
||||
Cell *pCell = pPage->apCell[i];
|
||||
int sz;
|
||||
|
||||
/* Check payload overflow pages
|
||||
*/
|
||||
sz = pCell->h.nKey + pCell->h.nData;
|
||||
sprintf(zContext, "On page %d cell %d: ", iPage, i);
|
||||
if( sz>MX_LOCAL_PAYLOAD ){
|
||||
int nPage = (sz - MX_LOCAL_PAYLOAD + OVERFLOW_SIZE - 1)/OVERFLOW_SIZE;
|
||||
checkList(pCheck, pCell->ovfl, nPage, zContext);
|
||||
}
|
||||
|
||||
/* Check that keys are in the right order
|
||||
*/
|
||||
cur.idx = i;
|
||||
zKey2 = sqliteMalloc( pCell->h.nKey+1 );
|
||||
getPayload(&cur, 0, pCell->h.nKey, zKey2);
|
||||
if( zKey1 && strcmp(zKey1,zKey2)>=0 ){
|
||||
checkAppendMsg(pCheck, zContext, "Key is out of order");
|
||||
}
|
||||
|
||||
/* Check sanity of left child page.
|
||||
*/
|
||||
pgno = (int)pCell->h.leftChild;
|
||||
d2 = checkTreePage(pCheck, pgno, pPage, zContext, zKey1, zKey2);
|
||||
if( i>0 && d2!=depth ){
|
||||
checkAppendMsg(pCheck, zContext, "Child page depth differs");
|
||||
}
|
||||
depth = d2;
|
||||
sqliteFree(zKey1);
|
||||
zKey1 = zKey2;
|
||||
}
|
||||
pgno = pPage->u.hdr.rightChild;
|
||||
sprintf(zContext, "On page %d at right child: ", iPage);
|
||||
checkTreePage(pCheck, pgno, pPage, zContext, zKey1, zUpperBound);
|
||||
sqliteFree(zKey1);
|
||||
|
||||
/* Check for complete coverage of the page
|
||||
*/
|
||||
memset(hit, 0, sizeof(hit));
|
||||
memset(hit, 1, sizeof(PageHdr));
|
||||
for(i=pPage->u.hdr.firstCell; i>0 && i<SQLITE_PAGE_SIZE; ){
|
||||
Cell *pCell = (Cell*)&pPage->u.aDisk[i];
|
||||
int j;
|
||||
for(j=i+cellSize(pCell)-1; j>=i; j--) hit[j]++;
|
||||
i = pCell->h.iNext;
|
||||
}
|
||||
for(i=pPage->u.hdr.firstFree; i>0 && i<SQLITE_PAGE_SIZE; ){
|
||||
FreeBlk *pFBlk = (FreeBlk*)&pPage->u.aDisk[i];
|
||||
int j;
|
||||
for(j=i+pFBlk->iSize-1; j>=i; j--) hit[j]++;
|
||||
i = pFBlk->iNext;
|
||||
}
|
||||
for(i=0; i<SQLITE_PAGE_SIZE; i++){
|
||||
if( hit[i]==0 ){
|
||||
sprintf(zMsg, "Unused space at byte %d of page %d", i, iPage);
|
||||
checkAppendMsg(pCheck, zMsg, 0);
|
||||
break;
|
||||
}else if( hit[i]>1 ){
|
||||
sprintf(zMsg, "Multiple uses for byte %d of page %d", i, iPage);
|
||||
checkAppendMsg(pCheck, zMsg, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that free space is kept to a minimum
|
||||
*/
|
||||
if( pParent && pPage->nFree>SQLITE_PAGE_SIZE/3 ){
|
||||
sprintf(zMsg, "free space (%d) greater than max (%d)", pPage->nFree,
|
||||
SQLITE_PAGE_SIZE/3);
|
||||
checkAppendMsg(pCheck, zContext, zMsg);
|
||||
}
|
||||
|
||||
sqlitepager_unref(pPage);
|
||||
return depth;
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine does a complete check of the given BTree file. aRoot[] is
|
||||
** an array of pages numbers were each page number is the root page of
|
||||
** a table. nRoot is the number of entries in aRoot.
|
||||
**
|
||||
** If everything checks out, this routine returns NULL. If something is
|
||||
** amiss, an error message is written into memory obtained from malloc()
|
||||
** and a pointer to that error message is returned. The calling function
|
||||
** is responsible for freeing the error message when it is done.
|
||||
*/
|
||||
char *sqliteBtreeSanityCheck(Btree *pBt, int *aRoot, int nRoot){
|
||||
int i;
|
||||
int nRef;
|
||||
SanityCheck sCheck;
|
||||
|
||||
nRef = *sqlitepager_stats(pBt->pPager);
|
||||
sCheck.pBt = pBt;
|
||||
sCheck.pPager = pBt->pPager;
|
||||
sCheck.nPage = sqlitepager_pagecount(sCheck.pPager);
|
||||
sCheck.anRef = sqliteMalloc( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) );
|
||||
sCheck.anRef[1] = 1;
|
||||
for(i=2; i<=sCheck.nPage; i++){ sCheck.anRef[i] = 0; }
|
||||
sCheck.zErrMsg = 0;
|
||||
|
||||
/* Check the integrity of the freelist
|
||||
*/
|
||||
checkList(&sCheck, pBt->page1->freeList, pBt->page1->nFree,"Main freelist: ");
|
||||
|
||||
/* Check all the tables.
|
||||
*/
|
||||
for(i=0; i<nRoot; i++){
|
||||
checkTreePage(&sCheck, aRoot[i], 0, "List of tree roots: ", 0, 0);
|
||||
}
|
||||
|
||||
/* Make sure every page in the file is referenced
|
||||
*/
|
||||
for(i=1; i<=sCheck.nPage; i++){
|
||||
if( sCheck.anRef[i]==0 ){
|
||||
char zBuf[100];
|
||||
sprintf(zBuf, "Page %d is never used", i);
|
||||
checkAppendMsg(&sCheck, zBuf, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure this analysis did not leave any unref() pages
|
||||
*/
|
||||
if( nRef != *sqlitepager_stats(pBt->pPager) ){
|
||||
char zBuf[100];
|
||||
sprintf(zBuf,
|
||||
"Outstanding page count goes from %d to %d during this analysis",
|
||||
nRef, *sqlitepager_stats(pBt->pPager)
|
||||
);
|
||||
checkAppendMsg(&sCheck, zBuf, 0);
|
||||
}
|
||||
|
||||
/* Clean up and report errors.
|
||||
*/
|
||||
sqliteFree(sCheck.anRef);
|
||||
return sCheck.zErrMsg;
|
||||
}
|
||||
|
||||
#endif /* SQLITE_TEST */
|
||||
|
||||
+2
-1
@@ -24,7 +24,7 @@
|
||||
** This header file defines the interface that the sqlite B-Tree file
|
||||
** subsystem.
|
||||
**
|
||||
** @(#) $Id: btree.h,v 1.7 2001/06/28 01:54:49 drh Exp $
|
||||
** @(#) $Id: btree.h,v 1.8 2001/06/30 21:53:53 drh Exp $
|
||||
*/
|
||||
|
||||
typedef struct Btree Btree;
|
||||
@@ -61,4 +61,5 @@ int sqliteBtreeUpdateMeta(Btree*, int*);
|
||||
int sqliteBtreePageDump(Btree*, int);
|
||||
int sqliteBtreeCursorDump(BtCursor*, int*);
|
||||
Pager *sqliteBtreePager(Btree*);
|
||||
char *sqliteBtreeSanityCheck(Btree*, int*, int);
|
||||
#endif
|
||||
|
||||
+40
-1
@@ -25,7 +25,7 @@
|
||||
** is not included in the SQLite library. It is used for automated
|
||||
** testing of the SQLite library.
|
||||
**
|
||||
** $Id: test3.c,v 1.4 2001/06/28 01:54:49 drh Exp $
|
||||
** $Id: test3.c,v 1.5 2001/06/30 21:53:53 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "pager.h"
|
||||
@@ -413,6 +413,44 @@ static int btree_pager_ref_dump(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: btree_sanity_check ID ROOT ...
|
||||
**
|
||||
** Look through every page of the given BTree file to verify correct
|
||||
** formatting and linkage. Return a line of text for each problem found.
|
||||
** Return an empty string if everything worked.
|
||||
*/
|
||||
static int btree_sanity_check(
|
||||
void *NotUsed,
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int argc, /* Number of arguments */
|
||||
char **argv /* Text of each argument */
|
||||
){
|
||||
Btree *pBt;
|
||||
char *zResult;
|
||||
int nRoot;
|
||||
int *aRoot;
|
||||
int i;
|
||||
|
||||
if( argc<3 ){
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" ID ROOT ...\"", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
|
||||
nRoot = argc-2;
|
||||
aRoot = malloc( sizeof(int)*(argc-2) );
|
||||
for(i=0; i<argc-2; i++){
|
||||
if( Tcl_GetInt(interp, argv[i+2], &aRoot[i]) ) return TCL_ERROR;
|
||||
}
|
||||
zResult = sqliteBtreeSanityCheck(pBt, aRoot, nRoot);
|
||||
if( zResult ){
|
||||
Tcl_AppendResult(interp, zResult, 0);
|
||||
free(zResult);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: btree_cursor ID TABLENUM
|
||||
**
|
||||
@@ -738,6 +776,7 @@ int Sqlitetest3_Init(Tcl_Interp *interp){
|
||||
Tcl_CreateCommand(interp, "btree_key", btree_key, 0, 0);
|
||||
Tcl_CreateCommand(interp, "btree_data", btree_data, 0, 0);
|
||||
Tcl_CreateCommand(interp, "btree_cursor_dump", btree_cursor_dump, 0, 0);
|
||||
Tcl_CreateCommand(interp, "btree_sanity_check", btree_sanity_check, 0, 0);
|
||||
Tcl_LinkVar(interp, "pager_refinfo_enable", (char*)&pager_refinfo_enable,
|
||||
TCL_LINK_INT);
|
||||
return TCL_OK;
|
||||
|
||||
+4
-1
@@ -23,7 +23,7 @@
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script is btree database backend
|
||||
#
|
||||
# $Id: btree.test,v 1.4 2001/06/28 11:50:22 drh Exp $
|
||||
# $Id: btree.test,v 1.5 2001/06/30 21:53:53 drh Exp $
|
||||
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
@@ -990,6 +990,9 @@ do_test btree-12.12 {
|
||||
btree_next $::c1
|
||||
btree_key $::c1
|
||||
} {402}
|
||||
do_test btree-13.1 {
|
||||
btree_sanity_check $::b1 2 3
|
||||
} {}
|
||||
|
||||
# To Do:
|
||||
#
|
||||
|
||||
Reference in New Issue
Block a user