diff --git a/manifest b/manifest index f92100e482..4ae4cffcf7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sVACUUM\scommand\snow\sdoes\sa\sdatabase\ssanity\scheck.\s(CVS\s364) -D 2002-02-03T03:34:08 +C Put\sin\sPRAGMA\sSANITY_CHECK\sin\splace\sof\sVACUUM.\s(CVS\s365) +D 2002-02-03T17:37:36 F Makefile.in 9fa4277413bf1d9cf91365f07d4108d7d87ed2af F Makefile.template 3372d45f8853afdb70bd30cc6fb50a3cd9069834 F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0 @@ -19,9 +19,9 @@ F ltmain.sh e9ed72eb1d690f447c13945eaf69e28af531eda1 F publish.sh 5b59f4aff037aafa0e4a3b6fa599495dbd73f360 F sqlite.1 2e2bb0529ef468ade9e4322bd609d0695fb9ded9 F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6 -F src/btree.c ced7d25e7ed33df5ef177e839db3e137d3c6a361 -F src/btree.h a94bef69f5174461331b6b9ae45a2d84f05af6db -F src/build.c a8851852bd67821a06dc1a816291ca0edaf15a18 +F src/btree.c cbe62fae68290ae5b5e1015f6a0696479244bc5b +F src/btree.h 53476ad4f76537591dceded79fa484a2dc168888 +F src/build.c 29504057ac5e2f40c08f19cb1574bd0512353169 F src/delete.c f8ad71be53cf18656b6573de65395852fe817f0c F src/expr.c a2a87dbd411a508ff89dffa90505ad42dac2f920 F src/hash.c 8f7c740ef2eaaa8decfa8751f2be30680b123e46 @@ -33,7 +33,7 @@ F src/os.c 1953080d14098cd45e5bde88941567688efb72b1 F src/os.h a17596ecc7f38a228b83ecdb661fb03ce44726d6 F src/pager.c 4059bda97a7e10083b77b7d347fea45426b08589 F src/pager.h b28f004e2f5541dc60cc32db01bf80cf4d056283 -F src/parse.y f081d7d4ef17deb2e20511addd32d07e277edc25 +F src/parse.y 734ba1e0dce9882345e65de5a14d9fe02fb757c2 F src/printf.c 300a90554345751f26e1fc0c0333b90a66110a1d F src/random.c f6b36bec5ebd3edb3440224bf5bf811fe4ac9a1b F src/select.c fc11d5a8c2bae1b62d8028ffb111c773ad6bf161 @@ -122,7 +122,7 @@ F www/speed.tcl 83457b2bf6bb430900bd48ca3dd98264d9a916a5 F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279 F www/tclsqlite.tcl 829b393d1ab187fd7a5e978631b3429318885c49 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218 -P 0115518f8e4591123582e3d2bb67282111ebcf60 -R 3b844437150a914d910bcb945e186cae +P 95d1f8389dd5e168bdf0290169662296b6a0f6d9 +R 1674dac486d8e0c1072b57bc5cd4e3c0 U drh -Z 41bd35da914d3e147a09ab98b479c192 +Z 536d009bb8b29d6b3df6118f3f597eb5 diff --git a/manifest.uuid b/manifest.uuid index 8eaf5c4165..c741447554 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -95d1f8389dd5e168bdf0290169662296b6a0f6d9 \ No newline at end of file +7c65029e5bf26eb640aef529a7421cd0d6ffd1a9 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index bf52166325..5e8439cb36 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.49 2002/02/03 03:34:08 drh Exp $ +** $Id: btree.c,v 1.50 2002/02/03 17:37:36 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -2458,10 +2458,10 @@ int sqliteBtreeUpdateMeta(Btree *pBt, int *aMeta){ ** 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. +** All of the following code is omitted if the library is compiled with +** the -DNDEBUG=1 compiler option. ******************************************************************************/ -#if 1 +#ifndef NDEEBUG /* ** Print a disassembly of the given page on standard output. This routine @@ -2662,6 +2662,23 @@ static void checkList(SanityCheck *pCheck, int iPage, int N, char *zContext){ } } +/* +** Return negative if zKey1zKey2. +*/ +static int keyCompare( + const char *zKey1, int nKey1, + const char *zKey2, int nKey2 +){ + int min = nKey1>nKey2 ? nKey2 : nKey1; + int c = memcmp(zKey1, zKey2, min); + if( c==0 ){ + c = nKey1 - nKey2; + } + return c; +} + /* ** Do various sanity checks on a single page of a tree. Return ** the tree depth. Root pages return 0. Parents of root pages @@ -2686,11 +2703,14 @@ static int checkTreePage( 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 */ + int nLower, /* Number of characters in zLowerBound */ + char *zUpperBound, /* All keys should be less than this, if not NULL */ + int nUpper /* Number of characters in zUpperBound */ ){ MemPage *pPage; int i, rc, depth, d2, pgno; char *zKey1, *zKey2; + int nKey1, nKey2; BtCursor cur; char zMsg[100]; char zContext[100]; @@ -2716,7 +2736,14 @@ static int checkTreePage( /* Check out all the cells. */ depth = 0; - zKey1 = zLowerBound ? sqliteStrDup(zLowerBound) : 0; + if( zLowerBound ){ + zKey1 = sqliteMalloc( nLower+1 ); + memcpy(zKey1, zLowerBound, nLower); + zKey1[nLower] = 0; + }else{ + zKey1 = 0; + } + nKey1 = nLower; cur.pPage = pPage; cur.pBt = pCheck->pBt; for(i=0; inCell; i++){ @@ -2725,7 +2752,8 @@ static int checkTreePage( /* Check payload overflow pages */ - sz = NKEY(pCell->h) + NDATA(pCell->h); + nKey2 = NKEY(pCell->h); + sz = nKey2 + NDATA(pCell->h); 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; @@ -2735,26 +2763,27 @@ static int checkTreePage( /* Check that keys are in the right order */ cur.idx = i; - zKey2 = sqliteMalloc( NKEY(pCell->h)+1 ); - getPayload(&cur, 0, NKEY(pCell->h), zKey2); - if( zKey1 && strcmp(zKey1,zKey2)>0 ){ + zKey2 = sqliteMalloc( nKey2+1 ); + getPayload(&cur, 0, nKey2, zKey2); + if( zKey1 && keyCompare(zKey1, nKey1, zKey2, nKey2)>=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); + d2 = checkTreePage(pCheck, pgno, pPage, zContext, zKey1,nKey1,zKey2,nKey2); if( i>0 && d2!=depth ){ checkAppendMsg(pCheck, zContext, "Child page depth differs"); } depth = d2; sqliteFree(zKey1); zKey1 = zKey2; + nKey1 = nKey2; } pgno = pPage->u.hdr.rightChild; sprintf(zContext, "On page %d at right child: ", iPage); - checkTreePage(pCheck, pgno, pPage, zContext, zKey1, zUpperBound); + checkTreePage(pCheck, pgno, pPage, zContext, zKey1,nKey1,zUpperBound,nUpper); sqliteFree(zKey1); /* Check for complete coverage of the page @@ -2838,7 +2867,7 @@ char *sqliteBtreeSanityCheck(Btree *pBt, int *aRoot, int nRoot){ /* Check all the tables. */ for(i=0; i @@ -1398,33 +1398,13 @@ copy_cleanup: ** collapse free space, etc. It is modelled after the VACUUM command ** in PostgreSQL. ** -** In this implementation, no cleanup occurs. Instead, the B-tree that -** forms the database is checked for integrity. This is a no-op unless -** SQLite is compiled with the SQLITE_TEST macro. +** In version 1.0.x of SQLite, the VACUUM command would call +** gdbm_reorganize() on all the database tables. But beginning +** with 2.0.0, SQLite no longer uses GDBM so this command has +** become a no-op. */ void sqliteVacuum(Parse *pParse, Token *pTableName){ -#if 1 - static VdbeOp checkDb[] = { - { OP_SetInsert, 0, 0, "2"}, - { OP_Open, 0, 2, 0}, - { OP_Rewind, 0, 6, 0}, - { OP_Column, 0, 3, 0}, - { OP_SetInsert, 0, 0, 0}, - { OP_Next, 0, 3, 0}, - { OP_SanityCheck, 0, 0, 0}, - { OP_ColumnCount, 1, 0, 0}, - { OP_ColumnName, 0, 0, "sanity_check"}, - { OP_Callback, 1, 0, 0}, - }; - static - Vdbe *v; - - - v = sqliteGetVdbe(pParse); - if( v==0 ) return; - sqliteVdbeAddOpList(v, ArraySize(checkDb), checkDb); - return; -#endif + /* Do nothing */ } /* @@ -1717,6 +1697,26 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){ }else #endif +#ifndef NDEBUG + if( sqliteStrICmp(zLeft, "sanity_check")==0 ){ + static VdbeOp checkDb[] = { + { OP_SetInsert, 0, 0, "2"}, + { OP_Open, 0, 2, 0}, + { OP_Rewind, 0, 6, 0}, + { OP_Column, 0, 3, 0}, + { OP_SetInsert, 0, 0, 0}, + { OP_Next, 0, 3, 0}, + { OP_SanityCheck, 0, 0, 0}, + { OP_ColumnCount, 1, 0, 0}, + { OP_ColumnName, 0, 0, "sanity_check"}, + { OP_Callback, 1, 0, 0}, + }; + Vdbe *v = sqliteGetVdbe(pParse); + if( v==0 ) return; + sqliteVdbeAddOpList(v, ArraySize(checkDb), checkDb); + }else +#endif + {} sqliteFree(zLeft); sqliteFree(zRight); diff --git a/src/parse.y b/src/parse.y index 800853f1f9..7959e0b6fe 100644 --- a/src/parse.y +++ b/src/parse.y @@ -14,7 +14,7 @@ ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** -** @(#) $Id: parse.y,v 1.47 2002/02/03 00:56:10 drh Exp $ +** @(#) $Id: parse.y,v 1.48 2002/02/03 17:37:36 drh Exp $ */ %token_prefix TK_ %token_type {Token} @@ -573,6 +573,7 @@ cmd ::= PRAGMA ids(X) EQ ON(Y). {sqlitePragma(pParse,&X,&Y,0);} cmd ::= PRAGMA ids(X) EQ plus_num(Y). {sqlitePragma(pParse,&X,&Y,0);} cmd ::= PRAGMA ids(X) EQ minus_num(Y). {sqlitePragma(pParse,&X,&Y,1);} cmd ::= PRAGMA ids(X) LP ids(Y) RP. {sqlitePragma(pParse,&X,&Y,0);} +cmd ::= PRAGMA(Y) ids(X). {sqlitePragma(pParse,&X,&Y,0);} plus_num(A) ::= plus_opt number(X). {A = X;} minus_num(A) ::= MINUS number(X). {A = X;} number(A) ::= INTEGER(X). {A = X;}