diff --git a/manifest b/manifest index 1bc55e3060..bcf51987e8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Bug\sfixes\sand\sspeed\simprovements.\sDelete\sis\sstill\sslow.\s(CVS\s244) -D 2001-09-14T16:42:12 +C Added\sa\sPRAGMA\sstatement.\s\sTook\sout\sthe\sspecial\scomment\sparsing.\s(CVS\s245) +D 2001-09-14T18:54:08 F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4 F Makefile.in 7ecb2370b5cb34d390af1fcb3118ea6d84a253ca F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958 @@ -13,9 +13,9 @@ F notes/notes2.txt 7e3fafd5e25906c1fe1e95f13b089aa398ca403e F notes/notes2b.txt 1c17a5b7f6b44a75cd3eb98ed2c24db1eefb06c3 F notes/notes3.txt 71e47be517e3d2578b3b9343a45b772d43b7ba16 F src/TODO f0ea267ab55c4d15127c1ac1667edbf781147438 -F src/btree.c 04cfedfd8c86401b2a5a61395589bb0c52cbeb15 -F src/btree.h 2427961c702dd0755ec70f529cf3db32707d689b -F src/build.c d639146a7d88045f1e69d6bb827a51c19c9ec825 +F src/btree.c 3adf545b8e072000923f7e0f7f91d33072a9f869 +F src/btree.h a3d9c20fa876e837680745ac60500be697026b7b +F src/build.c b5c682960b5889555cd059f3b5157668778b8834 F src/delete.c 62500a09606c0f714b651756475cd42979ef08e8 F src/ex/README b745b00acce2d892f60c40111dacdfc48e0c1c7a F src/ex/db.c f1419ae6c93e40b5ac6e39fe7efd95d868e6f9d7 @@ -29,22 +29,22 @@ F src/expr.c bcd91d0487c71cfa44413a46efe5e2c2244901b6 F src/insert.c edf098ecbbe00e3ecde6b5f22404a8230590c9fd F src/main.c a2c142626b46e3eb3e01436626df6c2d0a8f3ae6 F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c -F src/pager.c fc0d51b73e74fe7e8aec98c146fa2e714c7a8d52 -F src/pager.h 238aa88bafe33911bf9b0b365f35afd0a261cd46 -F src/parse.y 8fc096948994a7ffbf61ba13129cc589f794a9cb +F src/pager.c bb0891d49b9068711e4b8bab14db2959f56f5be9 +F src/pager.h bb9136e833de46bc84aafd8403713d3c46fcbfdf +F src/parse.y 8b30e072208c3dfabd97c7d06f0924f194919533 F src/printf.c b1e22a47be8cdf707815647239991e08e8cb69f9 F src/random.c b626726c4f0066610739e52e7431adae7ccd9651 F src/select.c f1673b4d06c24665097faf28d76c4533bce18b84 F src/shell.c 1fcdf8c4180098bcfdee12501e01b4c8eb21d726 F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e F src/sqlite.h.in 8faa2fed0513d188ced16e5f9094e57694594e70 -F src/sqliteInt.h 28d53b3690d730d5470a4a183531c7e4371669f1 +F src/sqliteInt.h 11d74bfd90777afafc529434b86c413fed44f0bf F src/table.c adcaf074f6c1075e86359174e68701fa2acfc4d6 F src/tclsqlite.c d328970848c028e13e61e173bef79adcc379568a F src/test1.c abb3cb427e735ae87e6533f5b3b7164b7da91bc4 F src/test2.c b3177e061fabd20d48e4b1b4bca610a0d2b28670 F src/test3.c 1fc103f198cbd0447d1a12c3ce48795755ec1a53 -F src/tokenize.c 00c8ab42ee731ff7466b048b449e1e838e9d638c +F src/tokenize.c 2d4d1534b321422384de0f311d417ffce14fedc6 F src/update.c ea8f2c0712cd4cd19314a26ef4766866013facda F src/util.c c77668fef860cfd2e4e682ef4f3ed8f9e68c551b F src/vdbe.c 244c86e406170c76b89ab07de4c7258f716c36ff @@ -107,7 +107,7 @@ F www/opcode.tcl cb3a1abf8b7b9be9f3a228d097d6bf8b742c2b6f F www/sqlite.tcl cb0d23d8f061a80543928755ec7775da6e4f362f F www/tclsqlite.tcl 06f81c401f79a04f2c5ebfb97e7c176225c0aef2 F www/vdbe.tcl 0c8aaa529dd216ccbf7daaabd80985e413d5f9ad -P e7b65e37fd88c4d69c89cfe73ab345b8b645ada6 -R ed181b52a40061f0079d6a386222bac2 +P 7da856cd94d2572070e40762e5bc477679e60042 +R 07caee6e3ed361d3efc95a7817451754 U drh -Z badce0ce49575ed2f4c401ae6458d977 +Z 4e11150d8699ec673e8745d72c606c4d diff --git a/manifest.uuid b/manifest.uuid index f38d1c9605..af847db2fc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7da856cd94d2572070e40762e5bc477679e60042 \ No newline at end of file +5e3724603e6f52bb74deb1c62e6e8f323d7b64b7 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 587103fdaa..3baa48733a 100644 --- a/src/btree.c +++ b/src/btree.c @@ -21,7 +21,7 @@ ** http://www.hwaci.com/drh/ ** ************************************************************************* -** $Id: btree.c,v 1.26 2001/09/14 16:42:12 drh Exp $ +** $Id: btree.c,v 1.27 2001/09/14 18:54:08 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -643,6 +643,14 @@ int sqliteBtreeClose(Btree *pBt){ return SQLITE_OK; } +/* +** Change the number of pages in the cache. +*/ +int sqliteBtreeSetCacheSize(Btree *pBt, int mxPage){ + sqlitepager_set_cachesize(pBt->pPager, mxPage); + return SQLITE_OK; +} + /* ** Get a reference to page1 of the database file. This will ** also acquire a readlock on that file. diff --git a/src/btree.h b/src/btree.h index 993b3d2d0b..e754427f70 100644 --- a/src/btree.h +++ b/src/btree.h @@ -24,7 +24,7 @@ ** This header file defines the interface that the sqlite B-Tree file ** subsystem. ** -** @(#) $Id: btree.h,v 1.12 2001/09/13 14:46:10 drh Exp $ +** @(#) $Id: btree.h,v 1.13 2001/09/14 18:54:08 drh Exp $ */ #ifndef _BTREE_H_ #define _BTREE_H_ @@ -34,6 +34,7 @@ typedef struct BtCursor BtCursor; int sqliteBtreeOpen(const char *zFilename, int mode, int nPg, Btree **ppBtree); int sqliteBtreeClose(Btree*); +int sqliteBtreeSetCacheSize(Btree*, int); int sqliteBtreeBeginTrans(Btree*); int sqliteBtreeCommit(Btree*); diff --git a/src/build.c b/src/build.c index 3ac86fc08f..9befe97cf9 100644 --- a/src/build.c +++ b/src/build.c @@ -33,9 +33,10 @@ ** COPY ** VACUUM ** -** $Id: build.c,v 1.33 2001/09/14 03:24:24 drh Exp $ +** $Id: build.c,v 1.34 2001/09/14 18:54:08 drh Exp $ */ #include "sqliteInt.h" +#include /* ** This routine is called after a single SQL statement has been @@ -1183,3 +1184,73 @@ void sqliteRollbackTransaction(Parse *pParse){ } db->flags &= ~SQLITE_InTrans; } + +/* +** Interpret the given string as a boolean value. +*/ +static int getBoolean(char *z){ + static char *azTrue[] = { "yes", "on", "true" }; + int i; + if( z[0]==0 ) return 0; + if( isdigit(z[0]) || (z[0]=='-' && isdigit(z[1])) ){ + return atoi(z); + } + for(i=0; idb; + + zLeft = sqliteStrNDup(pLeft->z, pLeft->n); + sqliteDequote(zLeft); + if( minusFlag ){ + zRight = 0; + sqliteSetNString(&zRight, "-", 1, pRight->z, pRight->n, 0); + }else{ + zRight = sqliteStrNDup(pRight->z, pRight->n); + sqliteDequote(zRight); + } + + if( sqliteStrICmp(zLeft,"cache_size")==0 ){ + int size = atoi(zRight); + sqliteBtreeSetCacheSize(db->pBe, size); + }else + + if( sqliteStrICmp(zLeft, "vdbe_trace")==0 ){ + if( getBoolean(zRight) ){ + db->flags |= SQLITE_VdbeTrace; + }else{ + db->flags &= ~SQLITE_VdbeTrace; + } + }else + +#ifndef NDEBUG + if( sqliteStrICmp(zLeft, "parser_trace")==0 ){ + extern void sqliteParserTrace(FILE*, char *); + if( getBoolean(zRight) ){ + sqliteParserTrace(stdout, "parser: "); + }else{ + sqliteParserTrace(0, 0); + } + }else +#endif + + if( zLeft ) sqliteFree(zLeft); + if( zRight ) sqliteFree(zRight); +} diff --git a/src/pager.c b/src/pager.c index 1428d8253d..8d4f9696d9 100644 --- a/src/pager.c +++ b/src/pager.c @@ -27,7 +27,7 @@ ** all writes in order to support rollback. Locking is used to limit ** access to one or more reader or to one writer. ** -** @(#) $Id: pager.c,v 1.17 2001/09/14 16:42:12 drh Exp $ +** @(#) $Id: pager.c,v 1.18 2001/09/14 18:54:09 drh Exp $ */ #include "sqliteInt.h" #include "pager.h" @@ -124,6 +124,7 @@ struct Pager { unsigned char errMask; /* One of several kinds of errors */ unsigned char tempFile; /* zFilename is a temporary file */ unsigned char readOnly; /* True for a read-only database */ + unsigned char needSync; /* True if an fsync() is needed on the journal */ unsigned char *aInJournal; /* One bit for each page in the database file */ PgHdr *pFirst, *pLast; /* List of free pages */ PgHdr *pAll; /* List of all pages */ @@ -483,6 +484,15 @@ static const char *findTempDir(void){ return 0; } +/* +** Change the maximum number of in-memory pages that are allowed. +*/ +void sqlitepager_set_cachesize(Pager *pPager, int mxPage){ + if( mxPage>10 ){ + pPager->mxPage = mxPage; + } +} + /* ** Create a new page cache and put a pointer to the page cache in *ppPager. ** The file to be cached need not exist. The file is not locked until @@ -549,6 +559,7 @@ int sqlitepager_open( pPager->errMask = 0; pPager->tempFile = tempFile; pPager->readOnly = readOnly; + pPager->needSync = 0; pPager->pFirst = 0; pPager->pLast = 0; pPager->nExtra = nExtra; @@ -780,7 +791,8 @@ int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage){ /* Recycle an older page. First locate the page to be recycled. ** Try to find one that is not dirty and is near the head of ** of the free list */ - int cnt = pPager->mxPage/2; + /* int cnt = pPager->mxPage/2; */ + int cnt = 10; pPg = pPager->pFirst; while( pPg->dirty && 0pNextFree ){ pPg = pPg->pNextFree; @@ -794,12 +806,15 @@ int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage){ int rc; assert( pPg->inJournal==1 ); assert( pPager->state==SQLITE_WRITELOCK ); - rc = fsync(pPager->jfd); - if( rc!=0 ){ - rc = sqlitepager_rollback(pPager); - *ppPage = 0; - if( rc==SQLITE_OK ) rc = SQLITE_IOERR; - return rc; + if( pPager->needSync ){ + rc = fsync(pPager->jfd); + if( rc!=0 ){ + rc = sqlitepager_rollback(pPager); + *ppPage = 0; + if( rc==SQLITE_OK ) rc = SQLITE_IOERR; + return rc; + } + pPager->needSync = 0; } pager_seek(pPager->fd, (pPg->pgno-1)*SQLITE_PAGE_SIZE); rc = pager_write(pPager->fd, PGHDR_TO_DATA(pPg), SQLITE_PAGE_SIZE); @@ -995,6 +1010,7 @@ int sqlitepager_write(void *pData){ if( pPager->jfd<0 ){ return SQLITE_CANTOPEN; } + pPager->needSync = 0; if( pager_lock(pPager->jfd, 1) ){ close(pPager->jfd); pPager->jfd = -1; @@ -1035,6 +1051,7 @@ int sqlitepager_write(void *pData){ } assert( pPager->aInJournal!=0 ); pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7); + pPager->needSync = 1; } pPg->inJournal = 1; if( pPager->dbSizepgno ){ @@ -1077,7 +1094,7 @@ int sqlitepager_commit(Pager *pPager){ return SQLITE_ERROR; } assert( pPager->jfd>=0 ); - if( fsync(pPager->jfd) ){ + if( pPager->needSync && fsync(pPager->jfd) ){ goto commit_abort; } for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){ diff --git a/src/pager.h b/src/pager.h index 1254af413a..8ae8b9ee6d 100644 --- a/src/pager.h +++ b/src/pager.h @@ -25,7 +25,7 @@ ** subsystem. The page cache subsystem reads and writes a file a page ** at a time and provides a journal for rollback. ** -** @(#) $Id: pager.h,v 1.8 2001/09/13 13:46:57 drh Exp $ +** @(#) $Id: pager.h,v 1.9 2001/09/14 18:54:09 drh Exp $ */ /* @@ -46,6 +46,7 @@ typedef struct Pager Pager; int sqlitepager_open(Pager **ppPager,const char *zFilename,int nPage,int nEx); void sqlitepager_set_destructor(Pager*, void(*)(void*)); +void sqlitepager_set_cachesize(Pager*, int); int sqlitepager_close(Pager *pPager); int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage); void *sqlitepager_lookup(Pager *pPager, Pgno pgno); diff --git a/src/parse.y b/src/parse.y index 1049150f6d..373497d350 100644 --- a/src/parse.y +++ b/src/parse.y @@ -26,10 +26,11 @@ ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** -** @(#) $Id: parse.y,v 1.28 2001/04/11 14:28:42 drh Exp $ +** @(#) $Id: parse.y,v 1.29 2001/09/14 18:54:09 drh Exp $ */ %token_prefix TK_ %token_type {Token} +%default_type {Token} %extra_argument {Parse *pParse} %syntax_error { sqliteSetString(&pParse->zErrMsg,"syntax error",0); @@ -100,6 +101,8 @@ id(A) ::= EXPLAIN(X). {A = X;} id(A) ::= VACUUM(X). {A = X;} id(A) ::= BEGIN(X). {A = X;} id(A) ::= END(X). {A = X;} +id(A) ::= PRAGMA(X). {A = X;} +id(A) ::= CLUSTER(X). {A = X;} id(A) ::= ID(X). {A = X;} // And "ids" is an identifer-or-string. @@ -478,3 +481,14 @@ cmd ::= COPY ids(X) FROM ids(Y). cmd ::= VACUUM. {sqliteVacuum(pParse,0);} cmd ::= VACUUM ids(X). {sqliteVacuum(pParse,&X);} + +cmd ::= PRAGMA ids(X) EQ ids(Y). {sqlitePragma(pParse,&X,&Y,0);} +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);} +plus_num(A) ::= plus_opt number(X). {A = X;} +minus_num(A) ::= MINUS number(X). {A = X;} +number(A) ::= INTEGER(X). {A = X;} +number(A) ::= FLOAT(X). {A = X;} +plus_opt ::= PLUS. +plus_opt ::= . diff --git a/src/sqliteInt.h b/src/sqliteInt.h index c99c6a9bfe..7a69341358 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -23,7 +23,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.46 2001/09/14 16:42:12 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.47 2001/09/14 18:54:09 drh Exp $ */ #include "sqlite.h" #include "vdbe.h" @@ -38,8 +38,8 @@ ** The maximum number of in-memory pages to use for the main database ** table and for temporary tables. */ -#define MAX_PAGES 150 -#define TEMP_PAGES 50 +#define MAX_PAGES 100 +#define TEMP_PAGES 25 /* ** The paging system deals with 32-bit integers. @@ -411,6 +411,7 @@ Expr *sqliteExprFunction(ExprList*, Token*); void sqliteExprDelete(Expr*); ExprList *sqliteExprListAppend(ExprList*,Expr*,Token*); void sqliteExprListDelete(ExprList*); +void sqlitePragma(Parse*,Token*,Token*,int); void sqliteCommitInternalChanges(sqlite*); void sqliteRollbackInternalChanges(sqlite*); void sqliteStartTable(Parse*,Token*,Token*); diff --git a/src/tokenize.c b/src/tokenize.c index b5865fdd53..8b7e82aece 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -27,7 +27,7 @@ ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** -** $Id: tokenize.c,v 1.20 2001/09/14 03:24:25 drh Exp $ +** $Id: tokenize.c,v 1.21 2001/09/14 18:54:09 drh Exp $ */ #include "sqliteInt.h" #include @@ -57,6 +57,7 @@ static Keyword aKeywordTable[] = { { "BETWEEN", 0, TK_BETWEEN, 0 }, { "BY", 0, TK_BY, 0 }, { "CHECK", 0, TK_CHECK, 0 }, + { "CLUSTER", 0, TK_CLUSTER, 0 }, { "COMMIT", 0, TK_COMMIT, 0 }, { "CONSTRAINT", 0, TK_CONSTRAINT, 0 }, { "COPY", 0, TK_COPY, 0 }, @@ -89,6 +90,7 @@ static Keyword aKeywordTable[] = { { "ON", 0, TK_ON, 0 }, { "OR", 0, TK_OR, 0 }, { "ORDER", 0, TK_ORDER, 0 }, + { "PRAGMA", 0, TK_PRAGMA, 0 }, { "PRIMARY", 0, TK_PRIMARY, 0 }, { "ROLLBACK", 0, TK_ROLLBACK, 0 }, { "SELECT", 0, TK_SELECT, 0 }, @@ -310,11 +312,9 @@ int sqliteRunParser(Parse *pParse, char *zSql, char **pzErrMsg){ int i; void *pEngine; int once = 1; - static FILE *trace = 0; extern void *sqliteParserAlloc(void*(*)(int)); extern void sqliteParserFree(void*, void(*)(void*)); extern int sqliteParser(void*, int, Token, Parse*); - extern void sqliteParserTrace(FILE*, char *); pParse->db->flags &= ~SQLITE_Interrupt; pParse->rc = SQLITE_OK; @@ -325,9 +325,6 @@ int sqliteRunParser(Parse *pParse, char *zSql, char **pzErrMsg){ sqliteSetString(pzErrMsg, "out of memory", 0); return 1; } -#ifndef NDEBUG - sqliteParserTrace(trace, "parser: "); -#endif while( sqlite_malloc_failed==0 && nErr==0 && i>=0 && zSql[i]!=0 ){ int tokenType; @@ -347,24 +344,6 @@ int sqliteRunParser(Parse *pParse, char *zSql, char **pzErrMsg){ case TK_SPACE: break; case TK_COMMENT: { - /* Various debugging modes can be turned on and off using - ** special SQL comments. Check for the special comments - ** here and take approriate action if found. - */ -#ifndef NDEBUG - char *z = pParse->sLastToken.z; - if( sqliteStrNICmp(z,"--parser-trace-on--",19)==0 ){ - trace = stdout; - sqliteParserTrace(trace, "parser: "); - }else if( sqliteStrNICmp(z,"--parser-trace-off--", 20)==0 ){ - trace = 0; - sqliteParserTrace(trace, "parser: "); - }else if( sqliteStrNICmp(z,"--vdbe-trace-on--",17)==0 ){ - pParse->db->flags |= SQLITE_VdbeTrace; - }else if( sqliteStrNICmp(z,"--vdbe-trace-off--", 18)==0 ){ - pParse->db->flags &= ~SQLITE_VdbeTrace; - } -#endif break; } case TK_ILLEGAL: