diff options
author | drh <drh@noemail.net> | 2004-10-31 02:22:47 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2004-10-31 02:22:47 +0000 |
commit | b7f9164e98fa24ae6995c99dd792836b81ccc91d (patch) | |
tree | f55e787ff88094cfad5dd4abf2a6230ae5e5f4ee /src | |
parent | 27d258a3ec1cf88e2a9104650bb6221215ea4d76 (diff) | |
download | sqlite-b7f9164e98fa24ae6995c99dd792836b81ccc91d.tar.gz sqlite-b7f9164e98fa24ae6995c99dd792836b81ccc91d.zip |
Insert #ifdefs that can optionally remove features at compiletime resulting
in a database engine with a smaller footprint. (CVS 2034)
FossilOrigin-Name: be661acfa849bb0d5692797dd221f5a8a457f8ad
Diffstat (limited to 'src')
-rw-r--r-- | src/btree.c | 14 | ||||
-rw-r--r-- | src/build.c | 16 | ||||
-rw-r--r-- | src/delete.c | 18 | ||||
-rw-r--r-- | src/expr.c | 4 | ||||
-rw-r--r-- | src/insert.c | 29 | ||||
-rw-r--r-- | src/pager.c | 82 | ||||
-rw-r--r-- | src/parse.y | 26 | ||||
-rw-r--r-- | src/pragma.c | 7 | ||||
-rw-r--r-- | src/select.c | 16 | ||||
-rw-r--r-- | src/sqliteInt.h | 54 | ||||
-rw-r--r-- | src/test1.c | 34 | ||||
-rw-r--r-- | src/test3.c | 6 | ||||
-rw-r--r-- | src/tokenize.c | 103 | ||||
-rw-r--r-- | src/trigger.c | 2 | ||||
-rw-r--r-- | src/update.c | 22 | ||||
-rw-r--r-- | src/vdbe.c | 4 | ||||
-rw-r--r-- | src/vdbeapi.c | 5 | ||||
-rw-r--r-- | src/vdbeaux.c | 5 |
18 files changed, 333 insertions, 114 deletions
diff --git a/src/btree.c b/src/btree.c index 677e48c61..41c651995 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.193 2004/10/22 16:22:58 drh Exp $ +** $Id: btree.c,v 1.194 2004/10/31 02:22:49 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -4067,6 +4067,7 @@ struct IntegrityCk { char *zErrMsg; /* An error message. NULL of no errors seen. */ }; +#ifndef SQLITE_OMIT_INTEGRITY_CHECK /* ** Append a message to the error message string. */ @@ -4092,7 +4093,9 @@ static void checkAppendMsg( } sqliteFree(zMsg2); } +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ +#ifndef SQLITE_OMIT_INTEGRITY_CHECK /* ** 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. @@ -4113,7 +4116,9 @@ static int checkRef(IntegrityCk *pCheck, int iPage, char *zContext){ } return (pCheck->anRef[iPage]++)>1; } +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ +#ifndef SQLITE_OMIT_INTEGRITY_CHECK /* ** Check the integrity of the freelist or of an overflow page list. ** Verify that the number of pages on the list is N. @@ -4158,7 +4163,9 @@ static void checkList( sqlite3pager_unref(pOvfl); } } +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ +#ifndef SQLITE_OMIT_INTEGRITY_CHECK /* ** Do various sanity checks on a single page of a tree. Return ** the tree depth. Root pages return 0. Parents of root pages @@ -4296,7 +4303,9 @@ static int checkTreePage( releasePage(pPage); return depth+1; } +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ +#ifndef SQLITE_OMIT_INTEGRITY_CHECK /* ** 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 @@ -4366,6 +4375,7 @@ char *sqlite3BtreeIntegrityCheck(Btree *pBt, int *aRoot, int nRoot){ sqliteFree(sCheck.anRef); return sCheck.zErrMsg; } +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ /* ** Return the full pathname of the underlying database file. @@ -4393,6 +4403,7 @@ const char *sqlite3BtreeGetJournalname(Btree *pBt){ return sqlite3pager_journalname(pBt->pPager); } +#ifndef SQLITE_OMIT_VACUUM /* ** Copy the complete content of pBtFrom into pBtTo. A transaction ** must be active for both files. @@ -4434,6 +4445,7 @@ int sqlite3BtreeCopyFile(Btree *pBtTo, Btree *pBtFrom){ } return rc; } +#endif /* SQLITE_OMIT_VACUUM */ /* ** Return non-zero if a transaction is active. diff --git a/src/build.c b/src/build.c index 7ae1868af..250ca2833 100644 --- a/src/build.c +++ b/src/build.c @@ -23,7 +23,7 @@ ** ROLLBACK ** PRAGMA ** -** $Id: build.c,v 1.257 2004/10/06 15:41:16 drh Exp $ +** $Id: build.c,v 1.258 2004/10/31 02:22:49 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -1400,6 +1400,7 @@ void sqlite3EndTable(Parse *pParse, Token *pEnd, Select *pSelect){ } } +#ifndef SQLITE_OMIT_VIEW /* ** The parser calls this routine in order to create a new VIEW */ @@ -1461,7 +1462,9 @@ void sqlite3CreateView( sqlite3EndTable(pParse, &sEnd, 0); return; } +#endif /* SQLITE_OMIT_VIEW */ +#ifndef SQLITE_OMIT_VIEW /* ** The Table structure pTable is really a VIEW. Fill in the names of ** the columns of the view in the pTable structure. Return the number @@ -1530,7 +1533,9 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ pSel->pEList = pEList; return nErr; } +#endif /* SQLITE_OMIT_VIEW */ +#ifndef SQLITE_OMIT_VIEW /* ** Clear the column names from every VIEW in database idx. */ @@ -1545,6 +1550,9 @@ static void sqliteViewResetAll(sqlite3 *db, int idx){ } DbClearProperty(db, idx, DB_UnresetViews); } +#else +# define sqliteViewResetAll(A,B) +#endif /* SQLITE_OMIT_VIEW */ /* ** This routine is called to do the work of a DROP TABLE statement. @@ -1693,12 +1701,13 @@ void sqlite3CreateForeignKey( ExprList *pToCol, /* Columns in the other table */ int flags /* Conflict resolution algorithms. */ ){ + FKey *pFKey = 0; +#ifndef SQLITE_OMIT_FOREIGN_KEY Table *p = pParse->pNewTable; int nByte; int i; int nCol; char *z; - FKey *pFKey = 0; assert( pTo!=0 ); if( p==0 || pParse->nErr ) goto fk_end; @@ -1779,6 +1788,7 @@ void sqlite3CreateForeignKey( fk_end: sqliteFree(pFKey); +#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ sqlite3ExprListDelete(pFromCol); sqlite3ExprListDelete(pToCol); } @@ -1791,10 +1801,12 @@ fk_end: ** accordingly. */ void sqlite3DeferForeignKey(Parse *pParse, int isDeferred){ +#ifndef SQLITE_OMIT_FOREIGN_KEY Table *pTab; FKey *pFKey; if( (pTab = pParse->pNewTable)==0 || (pFKey = pTab->pFKey)==0 ) return; pFKey->isDeferred = isDeferred; +#endif } /* diff --git a/src/delete.c b/src/delete.c index d6d4cd733..e9b2bf707 100644 --- a/src/delete.c +++ b/src/delete.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle DELETE FROM statements. ** -** $Id: delete.c,v 1.83 2004/10/22 20:29:22 drh Exp $ +** $Id: delete.c,v 1.84 2004/10/31 02:22:49 drh Exp $ */ #include "sqliteInt.h" @@ -104,12 +104,28 @@ void sqlite3DeleteFrom( */ pTab = sqlite3SrcListLookup(pParse, pTabList); if( pTab==0 ) goto delete_from_cleanup; + + /* Figure out if we have any triggers and if the table being + ** deleted from is a view + */ +#ifndef SQLITE_OMIT_TRIGGER before_triggers = sqlite3TriggersExist(pParse, pTab->pTrigger, TK_DELETE, TK_BEFORE, TK_ROW, 0); after_triggers = sqlite3TriggersExist(pParse, pTab->pTrigger, TK_DELETE, TK_AFTER, TK_ROW, 0); row_triggers_exist = before_triggers || after_triggers; isView = pTab->pSelect!=0; +#else +# define before_triggers 0 +# define after_triggers 0 +# define row_triggers_exist 0 +# define isView 0 +#endif +#ifdef SQLITE_OMIT_VIEW +# undef isView +# define isView 0 +#endif + if( sqlite3IsReadOnly(pParse, pTab, before_triggers) ){ goto delete_from_cleanup; } diff --git a/src/expr.c b/src/expr.c index 75167579b..daf7dc492 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.166 2004/10/04 13:19:24 drh Exp $ +** $Id: expr.c,v 1.167 2004/10/31 02:22:49 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -700,6 +700,7 @@ static int lookupName( } } +#ifndef SQLITE_OMIT_TRIGGER /* If we have not already resolved the name, then maybe ** it is a new.* or old.* trigger argument reference */ @@ -733,6 +734,7 @@ static int lookupName( } } } +#endif /* !defined(SQLITE_OMIT_TRIGGER) */ /* ** Perhaps the name is a reference to the ROWID diff --git a/src/insert.c b/src/insert.c index 114942e8c..d7a202a5d 100644 --- a/src/insert.c +++ b/src/insert.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** -** $Id: insert.c,v 1.119 2004/10/05 02:41:42 drh Exp $ +** $Id: insert.c,v 1.120 2004/10/31 02:22:49 drh Exp $ */ #include "sqliteInt.h" @@ -213,16 +213,31 @@ void sqlite3Insert( goto insert_cleanup; } + /* Figure out if we have any triggers and if the table being + ** inserted into is a view + */ +#ifndef SQLITE_OMIT_TRIGGER + before_triggers = sqlite3TriggersExist(pParse, pTab->pTrigger, + TK_INSERT, TK_BEFORE, TK_ROW, 0); + after_triggers = sqlite3TriggersExist(pParse, pTab->pTrigger, + TK_INSERT, TK_AFTER, TK_ROW, 0); + row_triggers_exist = before_triggers || after_triggers; + isView = pTab->pSelect!=0; +#else +# define before_triggers 0 +# define after_triggers 0 +# define row_triggers_exist 0 +# define isView 0 +#endif +#ifdef SQLITE_OMIT_VIEW +# undef isView +# define isView 0 +#endif + /* Ensure that: * (a) the table is not read-only, * (b) that if it is a view then ON INSERT triggers exist */ - before_triggers = sqlite3TriggersExist(pParse, pTab->pTrigger, TK_INSERT, - TK_BEFORE, TK_ROW, 0); - after_triggers = sqlite3TriggersExist(pParse, pTab->pTrigger, TK_INSERT, - TK_AFTER, TK_ROW, 0); - row_triggers_exist = before_triggers || after_triggers; - isView = pTab->pSelect!=0; if( sqlite3IsReadOnly(pParse, pTab, before_triggers) ){ goto insert_cleanup; } diff --git a/src/pager.c b/src/pager.c index fe06e2a4b..2395649ad 100644 --- a/src/pager.c +++ b/src/pager.c @@ -18,7 +18,7 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.168 2004/10/22 16:22:59 drh Exp $ +** @(#) $Id: pager.c,v 1.169 2004/10/31 02:22:49 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -308,6 +308,21 @@ static const unsigned char aJournalMagic[] = { */ #define JOURNAL_HDR_SZ(pPager) (pPager->sectorSize) +/* +** The macro MEMDB is true if we are dealing with an in-memory database. +** We do this as a macro so that if the SQLITE_OMIT_MEMORYDB macro is set, +** the value of MEMDB will be a constant and the compiler will optimize +** out code that would never execute. +*/ +#ifdef SQLITE_OMIT_MEMORYDB +# define MEMDB 0 +#else +# define MEMDB pPager->memDb +#endif + +/* +** The default size of a disk sector +*/ #define PAGER_SECTOR_SIZE 512 /* @@ -779,7 +794,7 @@ static void pager_reset(Pager *pPager){ static int pager_unwritelock(Pager *pPager){ PgHdr *pPg; int rc; - assert( !pPager->memDb ); + assert( !MEMDB ); if( pPager->state<PAGER_RESERVED ){ return SQLITE_OK; } @@ -1454,11 +1469,14 @@ int sqlite3pager_open( return SQLITE_NOMEM; } if( zFilename && zFilename[0] ){ +#ifndef SQLITE_OMIT_MEMORYDB if( strcmp(zFilename,":memory:")==0 ){ memDb = 1; zFullPathname = sqliteStrDup(""); rc = SQLITE_OK; - }else{ + }else +#endif + { zFullPathname = sqlite3OsFullPathname(zFilename); if( zFullPathname ){ rc = sqlite3OsOpenReadWrite(zFullPathname, &fd, &readOnly); @@ -1581,7 +1599,7 @@ void sqlite3pager_set_pagesize(Pager *pPager, int pageSize){ */ void sqlite3pager_read_fileheader(Pager *pPager, int N, unsigned char *pDest){ memset(pDest, 0, N); - if( pPager->memDb==0 ){ + if( MEMDB==0 ){ sqlite3OsSeek(&pPager->fd, 0); sqlite3OsRead(&pPager->fd, pDest, N); } @@ -1602,7 +1620,7 @@ int sqlite3pager_pagecount(Pager *pPager){ return 0; } n /= pPager->pageSize; - if( !pPager->memDb && n==PENDING_BYTE/pPager->pageSize ){ + if( !MEMDB && n==PENDING_BYTE/pPager->pageSize ){ n++; } if( pPager->state!=PAGER_UNLOCK ){ @@ -1699,7 +1717,7 @@ int sqlite3pager_truncate(Pager *pPager, Pgno nPage){ if( nPage>=(unsigned)pPager->dbSize ){ return SQLITE_OK; } - if( pPager->memDb ){ + if( MEMDB ){ pPager->dbSize = nPage; memoryTruncate(pPager); return SQLITE_OK; @@ -1731,14 +1749,14 @@ int sqlite3pager_close(Pager *pPager){ case PAGER_SYNCED: case PAGER_EXCLUSIVE: { sqlite3pager_rollback(pPager); - if( !pPager->memDb ){ + if( !MEMDB ){ sqlite3OsUnlock(&pPager->fd, NO_LOCK); } assert( pPager->journalOpen==0 ); break; } case PAGER_SHARED: { - if( !pPager->memDb ){ + if( !MEMDB ){ sqlite3OsUnlock(&pPager->fd, NO_LOCK); } break; @@ -1750,7 +1768,7 @@ int sqlite3pager_close(Pager *pPager){ } for(pPg=pPager->pAll; pPg; pPg=pNext){ #ifndef NDEBUG - if( pPager->memDb ){ + if( MEMDB ){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); assert( !pPg->alwaysRollback ); assert( !pHist->pOrig ); @@ -2066,7 +2084,7 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ /* If this is the first page accessed, then get a SHARED lock ** on the database file. */ - if( pPager->nRef==0 && !pPager->memDb ){ + if( pPager->nRef==0 && !MEMDB ){ rc = pager_wait_on_lock(pPager, SHARED_LOCK); if( rc!=SQLITE_OK ){ return rc; @@ -2132,7 +2150,7 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ }else{ /* Search for page in cache */ pPg = pager_lookup(pPager, pgno); - if( pPager->memDb && pPager->state==PAGER_UNLOCK ){ + if( MEMDB && pPager->state==PAGER_UNLOCK ){ pPager->state = PAGER_SHARED; } } @@ -2140,20 +2158,20 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ /* The requested page is not in the page cache. */ int h; pPager->nMiss++; - if( pPager->nPage<pPager->mxPage || pPager->pFirst==0 || pPager->memDb ){ + if( pPager->nPage<pPager->mxPage || pPager->pFirst==0 || MEMDB ){ /* Create a new page */ pPg = sqliteMallocRaw( sizeof(*pPg) + pPager->psAligned + sizeof(u32) + pPager->nExtra - + pPager->memDb*sizeof(PgHistory) ); + + MEMDB*sizeof(PgHistory) ); if( pPg==0 ){ - if( !pPager->memDb ){ + if( !MEMDB ){ pager_unwritelock(pPager); } pPager->errMask |= PAGER_ERR_MEM; return SQLITE_NOMEM; } memset(pPg, 0, sizeof(*pPg)); - if( pPager->memDb ){ + if( MEMDB ){ memset(PGHDR_TO_HIST(pPg, pPager), 0, sizeof(PgHistory)); } pPg->pPager = pPager; @@ -2266,7 +2284,7 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize); }else{ int rc; - assert( pPager->memDb==0 ); + assert( MEMDB==0 ); sqlite3OsSeek(&pPager->fd, (pgno-1)*(i64)pPager->pageSize); rc = sqlite3OsRead(&pPager->fd, PGHDR_TO_DATA(pPg), pPager->pageSize); TRACE3("FETCH %d page %d\n", pPager->fd.h, pPg->pgno); @@ -2360,7 +2378,7 @@ int sqlite3pager_unref(void *pData){ */ pPager->nRef--; assert( pPager->nRef>=0 ); - if( pPager->nRef==0 && !pPager->memDb ){ + if( pPager->nRef==0 && !MEMDB ){ pager_reset(pPager); } } @@ -2376,7 +2394,7 @@ int sqlite3pager_unref(void *pData){ */ static int pager_open_journal(Pager *pPager){ int rc; - assert( !pPager->memDb ); + assert( !MEMDB ); assert( pPager->state>=PAGER_RESERVED ); assert( pPager->journalOpen==0 ); assert( pPager->useJournal ); @@ -2461,7 +2479,7 @@ int sqlite3pager_begin(void *pData, int exFlag){ assert( pPager->state!=PAGER_UNLOCK ); if( pPager->state==PAGER_SHARED ){ assert( pPager->aInJournal==0 ); - if( pPager->memDb ){ + if( MEMDB ){ pPager->state = PAGER_EXCLUSIVE; pPager->origDbSize = pPager->dbSize; }else{ @@ -2555,11 +2573,11 @@ int sqlite3pager_write(void *pData){ ** EXCLUSIVE lock on the main database file. Write the current page to ** the transaction journal if it is not there already. */ - if( !pPg->inJournal && (pPager->useJournal || pPager->memDb) ){ + if( !pPg->inJournal && (pPager->useJournal || MEMDB) ){ if( (int)pPg->pgno <= pPager->origDbSize ){ int szPg; u32 saved; - if( pPager->memDb ){ + if( MEMDB ){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); TRACE3("JOURNAL %d page %d\n", pPager->fd.h, pPg->pgno); assert( pHist->pOrig==0 ); @@ -2613,7 +2631,7 @@ int sqlite3pager_write(void *pData){ */ if( pPager->stmtInUse && !pPg->inStmt && (int)pPg->pgno<=pPager->stmtSize ){ assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize ); - if( pPager->memDb ){ + if( MEMDB ){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); assert( pHist->pStmt==0 ); pHist->pStmt = sqliteMallocRaw( pPager->pageSize ); @@ -2643,7 +2661,7 @@ int sqlite3pager_write(void *pData){ */ if( pPager->dbSize<(int)pPg->pgno ){ pPager->dbSize = pPg->pgno; - if( !pPager->memDb && pPager->dbSize==PENDING_BYTE/pPager->pageSize ){ + if( !MEMDB && pPager->dbSize==PENDING_BYTE/pPager->pageSize ){ pPager->dbSize++; } } @@ -2706,7 +2724,7 @@ int sqlite3pager_overwrite(Pager *pPager, Pgno pgno, void *pData){ void sqlite3pager_dont_write(Pager *pPager, Pgno pgno){ PgHdr *pPg; - if( pPager->memDb ) return; + if( MEMDB ) return; pPg = pager_lookup(pPager, pgno); pPg->alwaysRollback = 1; @@ -2738,7 +2756,7 @@ void sqlite3pager_dont_rollback(void *pData){ Pager *pPager = pPg->pPager; if( pPager->state!=PAGER_EXCLUSIVE || pPager->journalOpen==0 ) return; - if( pPg->alwaysRollback || pPager->alwaysRollback || pPager->memDb ) return; + if( pPg->alwaysRollback || pPager->alwaysRollback || MEMDB ) return; if( !pPg->inJournal && (int)pPg->pgno <= pPager->origDbSize ){ assert( pPager->aInJournal!=0 ); pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7); @@ -2794,7 +2812,7 @@ int sqlite3pager_commit(Pager *pPager){ return SQLITE_ERROR; } TRACE2("COMMIT %d\n", pPager->fd.h); - if( pPager->memDb ){ + if( MEMDB ){ pPg = pager_get_all_dirty_pages(pPager); while( pPg ){ clearHistory(PGHDR_TO_HIST(pPg, pPager)); @@ -2855,7 +2873,7 @@ commit_abort: int sqlite3pager_rollback(Pager *pPager){ int rc; TRACE2("ROLLBACK %d\n", pPager->fd.h); - if( pPager->memDb ){ + if( MEMDB ){ PgHdr *p; for(p=pPager->pAll; p; p=p->pNextAll){ PgHistory *pHist; @@ -2962,7 +2980,7 @@ int sqlite3pager_stmt_begin(Pager *pPager){ assert( !pPager->stmtInUse ); assert( pPager->dbSize>=0 ); TRACE2("STMT-BEGIN %d\n", pPager->fd.h); - if( pPager->memDb ){ + if( MEMDB ){ pPager->stmtInUse = 1; pPager->stmtSize = pPager->dbSize; return SQLITE_OK; @@ -3010,7 +3028,7 @@ int sqlite3pager_stmt_commit(Pager *pPager){ if( pPager->stmtInUse ){ PgHdr *pPg, *pNext; TRACE2("STMT-COMMIT %d\n", pPager->fd.h); - if( !pPager->memDb ){ + if( !MEMDB ){ sqlite3OsSeek(&pPager->stfd, 0); /* sqlite3OsTruncate(&pPager->stfd, 0); */ sqliteFree( pPager->aInStmt ); @@ -3021,7 +3039,7 @@ int sqlite3pager_stmt_commit(Pager *pPager){ assert( pPg->inStmt ); pPg->inStmt = 0; pPg->pPrevStmt = pPg->pNextStmt = 0; - if( pPager->memDb ){ + if( MEMDB ){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); sqliteFree(pHist->pStmt); pHist->pStmt = 0; @@ -3042,7 +3060,7 @@ int sqlite3pager_stmt_rollback(Pager *pPager){ int rc; if( pPager->stmtInUse ){ TRACE2("STMT-ROLLBACK %d\n", pPager->fd.h); - if( pPager->memDb ){ + if( MEMDB ){ PgHdr *pPg; for(pPg=pPager->pStmt; pPg; pPg=pPg->pNextStmt){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); @@ -3148,7 +3166,7 @@ int sqlite3pager_sync(Pager *pPager, const char *zMaster){ /* If this is an in-memory db, or no pages have been written to, or this ** function has already been called, it is a no-op. */ - if( pPager->state!=PAGER_SYNCED && !pPager->memDb && pPager->dirtyCache ){ + if( pPager->state!=PAGER_SYNCED && !MEMDB && pPager->dirtyCache ){ PgHdr *pPg; assert( pPager->journalOpen ); diff --git a/src/parse.y b/src/parse.y index e9f9fc336..8a4ee62e3 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.144 2004/10/07 03:06:29 drh Exp $ +** @(#) $Id: parse.y,v 1.145 2004/10/31 02:22:49 drh Exp $ */ %token_prefix TK_ %token_type {Token} @@ -81,11 +81,13 @@ struct AttachKey { int type; Token key; }; input ::= cmdlist. cmdlist ::= cmdlist ecmd. cmdlist ::= ecmd. -ecmd ::= explain cmdx SEMI. -ecmd ::= SEMI. cmdx ::= cmd. { sqlite3FinishCoding(pParse); } -explain ::= EXPLAIN. { sqlite3BeginParse(pParse, 1); } +ecmd ::= SEMI. +ecmd ::= explain cmdx SEMI. explain ::= . { sqlite3BeginParse(pParse, 0); } +%ifndef SQLITE_OMIT_EXPLAIN +explain ::= EXPLAIN. { sqlite3BeginParse(pParse, 1); } +%endif ///////////////////// Begin and end transactions. //////////////////////////// // @@ -144,7 +146,11 @@ id(A) ::= ID(X). {A = X;} DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR GLOB IGNORE IMMEDIATE INITIALLY INSTEAD LIKE MATCH KEY OF OFFSET PRAGMA RAISE REPLACE RESTRICT ROW STATEMENT - TEMP TRIGGER VACUUM VIEW. + TEMP TRIGGER VACUUM VIEW +%ifdef SQLITE_OMIT_COMPOUND_SELECT + EXCEPT INTERSECT UNION +%endif + . // Define operator precedence early so that this is the first occurance // of the operator tokens in the grammer. Keeping the operators together @@ -285,12 +291,14 @@ cmd ::= DROP TABLE fullname(X). { ///////////////////// The CREATE VIEW statement ///////////////////////////// // +%ifndef SQLITE_OMIT_VIEW cmd ::= CREATE(X) temp(T) VIEW nm(Y) dbnm(Z) AS select(S). { sqlite3CreateView(pParse, &X, &Y, &Z, S, T); } cmd ::= DROP VIEW fullname(X). { sqlite3DropTable(pParse, X, 1); } +%endif // SQLITE_OMIT_VIEW //////////////////////// The SELECT statement ///////////////////////////////// // @@ -305,6 +313,7 @@ cmd ::= select(X). { %destructor oneselect {sqlite3SelectDelete($$);} select(A) ::= oneselect(X). {A = X;} +%ifndef SQLITE_OMIT_COMPOUND_SELECT select(A) ::= select(X) multiselect_op(Y) oneselect(Z). { if( Z ){ Z->op = Y; @@ -317,6 +326,7 @@ multiselect_op(A) ::= UNION(OP). {A = @OP;} multiselect_op(A) ::= UNION ALL. {A = TK_ALL;} multiselect_op(A) ::= INTERSECT(OP). {A = @OP;} multiselect_op(A) ::= EXCEPT(OP). {A = @OP;} +%endif // SQLITE_OMIT_COMPOUND_SELECT oneselect(A) ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y) groupby_opt(P) having_opt(Q) orderby_opt(Z) limit_opt(L). { A = sqlite3SelectNew(W,X,Y,P,Q,Z,D,L.limit,L.offset); @@ -793,6 +803,8 @@ plus_opt ::= . //////////////////////////// The CREATE TRIGGER command ///////////////////// +%ifndef SQLITE_OMIT_TRIGGER + cmd ::= CREATE trigger_decl(A) BEGIN trigger_cmd_list(S) END(Z). { Token all; all.z = A.z; @@ -869,6 +881,8 @@ expr(A) ::= RAISE(X) LP raisetype(T) COMMA nm(Z) RP(Y). { A->iColumn = T; sqlite3ExprSpan(A, &X, &Y); } +%endif // !SQLITE_OMIT_TRIGGER + %type raisetype {int} raisetype(A) ::= ROLLBACK. {A = OE_Rollback;} raisetype(A) ::= ABORT. {A = OE_Abort;} @@ -876,9 +890,11 @@ raisetype(A) ::= FAIL. {A = OE_Fail;} //////////////////////// DROP TRIGGER statement ////////////////////////////// +%ifndef SQLITE_OMIT_TRIGGER cmd ::= DROP TRIGGER fullname(X). { sqlite3DropTrigger(pParse,X); } +%endif // !SQLITE_OMIT_TRIGGER //////////////////////// ATTACH DATABASE file AS name ///////////////////////// cmd ::= ATTACH database_kw_opt ids(F) AS nm(D) key_opt(K). { diff --git a/src/pragma.c b/src/pragma.c index d238d4264..4b10e1233 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** -** $Id: pragma.c,v 1.72 2004/10/25 20:33:44 drh Exp $ +** $Id: pragma.c,v 1.73 2004/10/31 02:22:49 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -444,6 +444,7 @@ void sqlite3Pragma( } }else +#ifndef SQLITE_OMIT_FOREIGN_KEY if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 && zRight ){ FKey *pFK; Table *pTab; @@ -477,6 +478,7 @@ void sqlite3Pragma( } } }else +#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ if( sqlite3StrICmp(zLeft, "database_list")==0 ){ int i; @@ -507,6 +509,7 @@ void sqlite3Pragma( }else #endif +#ifndef SQLITE_OMIT_INTEGRITY_CHECK if( sqlite3StrICmp(zLeft, "integrity_check")==0 ){ int i, j, addr; @@ -631,6 +634,8 @@ void sqlite3Pragma( addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode); sqlite3VdbeChangeP2(v, addr+2, addr+ArraySize(endCode)); }else +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + /* ** PRAGMA encoding ** PRAGMA encoding = "utf-8"|"utf-16"|"utf-16le"|"utf-16be" diff --git a/src/select.c b/src/select.c index 75ff2fbef..155ae9c0a 100644 --- a/src/select.c +++ b/src/select.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** -** $Id: select.c,v 1.212 2004/10/06 15:41:17 drh Exp $ +** $Id: select.c,v 1.213 2004/10/31 02:22:49 drh Exp $ */ #include "sqliteInt.h" @@ -1282,6 +1282,7 @@ static int openTempIndex(Parse *pParse, Select *p, int iTab, int keyAsData){ return addr; } +#ifndef SQLITE_OMIT_COMPOUND_SELECT /* ** Add the address "addr" to the set of all OpenTemp opcode addresses ** that are being accumulated in p->ppOpenTemp. @@ -1294,7 +1295,9 @@ static int multiSelectOpenTempAddr(Select *p, int addr){ pList->a[pList->nId-1].idx = addr; return SQLITE_OK; } +#endif /* SQLITE_OMIT_COMPOUND_SELECT */ +#ifndef SQLITE_OMIT_COMPOUND_SELECT /* ** Return the appropriate collating sequence for the iCol-th column of ** the result set for the compound-select statement "p". Return NULL if @@ -1315,7 +1318,9 @@ static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){ } return pRet; } +#endif /* SQLITE_OMIT_COMPOUND_SELECT */ +#ifndef SQLITE_OMIT_COMPOUND_SELECT /* ** This routine is called to process a query that is really the union ** or intersection of two or more separate queries. @@ -1704,7 +1709,9 @@ multi_select_end: p->ppOpenTemp = 0; return rc; } +#endif /* SQLITE_OMIT_COMPOUND_SELECT */ +#ifndef SQLITE_OMIT_VIEW /* ** Scan through the expression pExpr. Replace every reference to ** a column in table number iTable with a copy of the iColumn-th @@ -1757,7 +1764,9 @@ substExprList(ExprList *pList, int iTable, ExprList *pEList){ substExpr(pList->a[i].pExpr, iTable, pEList); } } +#endif /* !defined(SQLITE_OMIT_VIEW) */ +#ifndef SQLITE_OMIT_VIEW /* ** This routine attempts to flatten subqueries in order to speed ** execution. It returns 1 if it makes changes and 0 if no flattening @@ -2009,6 +2018,7 @@ static int flattenSubquery( sqlite3SelectDelete(pSub); return 1; } +#endif /* SQLITE_OMIT_VIEW */ /* ** Analyze the SELECT statement passed in as an argument to see if it @@ -2262,11 +2272,13 @@ int sqlite3Select( if( sqlite3_malloc_failed || pParse->nErr || p==0 ) return 1; if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; +#ifndef SQLITE_OMIT_COMPOUND_SELECT /* If there is are a sequence of queries, do the earlier ones first. */ if( p->pPrior ){ return multiSelect(pParse, p, eDest, iParm, aff); } +#endif /* Make local copies of the parameters for this query. */ @@ -2400,11 +2412,13 @@ int sqlite3Select( /* Check to see if this is a subquery that can be "flattened" into its parent. ** If flattening is a possiblity, do so and return immediately. */ +#ifndef SQLITE_OMIT_VIEW if( pParent && pParentAgg && flattenSubquery(pParse, pParent, parentTab, *pParentAgg, isAgg) ){ if( isAgg ) *pParentAgg = 1; return rc; } +#endif /* If there is an ORDER BY clause, resolve any collation sequences ** names that have been explicitly specified. diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 2380dc738..6e2bf5890 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.328 2004/10/22 20:29:22 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.329 2004/10/31 02:22:49 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -1259,8 +1259,14 @@ void sqlite3AddColumnType(Parse*,Token*,Token*); void sqlite3AddDefaultValue(Parse*,Token*,int); void sqlite3AddCollateType(Parse*, const char*, int); void sqlite3EndTable(Parse*,Token*,Select*); -void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int); -int sqlite3ViewGetColumnNames(Parse*,Table*); + +#ifndef SQLITE_OMIT_VIEW + void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int); + int sqlite3ViewGetColumnNames(Parse*,Table*); +#else +# define sqlite3ViewGetColumnNames(A,B) 0 +#endif + void sqlite3DropTable(Parse*, SrcList*, int); void sqlite3DeleteTable(sqlite3*, Table*); void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int); @@ -1297,7 +1303,6 @@ Table *sqlite3LocateTable(Parse*,const char*, const char*); Index *sqlite3FindIndex(sqlite3*,const char*, const char*); void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); -void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*); void sqlite3Vacuum(Parse*, Token*); int sqlite3RunVacuum(char**, sqlite3*); char *sqlite3NameFromToken(Token*); @@ -1337,21 +1342,32 @@ int sqlite3SafetyOn(sqlite3*); int sqlite3SafetyOff(sqlite3*); int sqlite3SafetyCheck(sqlite3*); void sqlite3ChangeCookie(sqlite3*, Vdbe*, int); -void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*, - int,Expr*,int); -void sqlite3FinishTrigger(Parse*, TriggerStep*, Token*); -void sqlite3DropTrigger(Parse*, SrcList*); -void sqlite3DropTriggerPtr(Parse*, Trigger*, int); -int sqlite3TriggersExist(Parse* , Trigger* , int , int , int, ExprList*); -int sqlite3CodeRowTrigger(Parse*, int, ExprList*, int, Table *, int, int, - int, int); -void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*); -void sqlite3DeleteTriggerStep(TriggerStep*); -TriggerStep *sqlite3TriggerSelectStep(Select*); -TriggerStep *sqlite3TriggerInsertStep(Token*, IdList*, ExprList*, Select*, int); -TriggerStep *sqlite3TriggerUpdateStep(Token*, ExprList*, Expr*, int); -TriggerStep *sqlite3TriggerDeleteStep(Token*, Expr*); -void sqlite3DeleteTrigger(Trigger*); + +#ifndef SQLITE_OMIT_TRIGGER + void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*, + int,Expr*,int); + void sqlite3FinishTrigger(Parse*, TriggerStep*, Token*); + void sqlite3DropTrigger(Parse*, SrcList*); + void sqlite3DropTriggerPtr(Parse*, Trigger*, int); + int sqlite3TriggersExist(Parse* , Trigger* , int , int , int, ExprList*); + int sqlite3CodeRowTrigger(Parse*, int, ExprList*, int, Table *, int, int, + int, int); + void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*); + void sqlite3DeleteTriggerStep(TriggerStep*); + TriggerStep *sqlite3TriggerSelectStep(Select*); + TriggerStep *sqlite3TriggerInsertStep(Token*, IdList*, ExprList*,Select*,int); + TriggerStep *sqlite3TriggerUpdateStep(Token*, ExprList*, Expr*, int); + TriggerStep *sqlite3TriggerDeleteStep(Token*, Expr*); + void sqlite3DeleteTrigger(Trigger*); + void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*); +#else +# define sqlite3TriggersExist(A,B,C,D,E,F) 0 +# define sqlite3DeleteTrigger(A) +# define sqlite3DropTriggerPtr(A,B,C) +# define sqlite3UnlinkAndDeleteTrigger(A,B,C) +# define sqlite3CodeRowTrigger(A,B,C,D,E,F,G,H,I) 0 +#endif + int sqlite3JoinType(Parse*, Token*, Token*, Token*); void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int); void sqlite3DeferForeignKey(Parse*, int); diff --git a/src/test1.c b/src/test1.c index 0c9d16d18..18458eff0 100644 --- a/src/test1.c +++ b/src/test1.c @@ -13,7 +13,7 @@ ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** -** $Id: test1.c,v 1.105 2004/10/30 20:23:09 drh Exp $ +** $Id: test1.c,v 1.106 2004/10/31 02:22:49 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" @@ -2491,7 +2491,7 @@ static void set_options(Tcl_Interp *interp){ #ifdef SQLITE_OMIT_DATETIME_FUNCS Tcl_SetVar2(interp, "sqlite_options", "datetime", "0", TCL_GLOBAL_ONLY); #else - Tcl_SetVar2(interp, "sqlite_options", "datatime", "1", TCL_GLOBAL_ONLY); + Tcl_SetVar2(interp, "sqlite_options", "datetime", "1", TCL_GLOBAL_ONLY); #endif #if defined(THREADSAFE) && THREADSAFE Tcl_SetVar2(interp, "sqlite_options", "threadsafe", "1", TCL_GLOBAL_ONLY); @@ -2528,6 +2528,36 @@ static void set_options(Tcl_Interp *interp){ #else Tcl_SetVar2(interp, "sqlite_options", "conflict", "1", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_OMIT_FLOATING_POINT + Tcl_SetVar2(interp, "sqlite_options", "floatingpoint", "0", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "floatingpoint", "1", TCL_GLOBAL_ONLY); +#endif +#ifdef SQLITE_OMIT_MEMORYDB + Tcl_SetVar2(interp, "sqlite_options", "memorydb", "0", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "memorydb", "1", TCL_GLOBAL_ONLY); +#endif +#ifdef SQLITE_OMIT_UTF16 + Tcl_SetVar2(interp, "sqlite_options", "utf16", "0", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "utf16", "1", TCL_GLOBAL_ONLY); +#endif +#ifdef SQLITE_OMIT_EXPLAIN + Tcl_SetVar2(interp, "sqlite_options", "explain", "0", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "explain", "1", TCL_GLOBAL_ONLY); +#endif +#ifdef SQLITE_OMIT_TCL_VARIABLE + Tcl_SetVar2(interp, "sqlite_options", "tclvar", "0", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "tclvar", "1", TCL_GLOBAL_ONLY); +#endif +#ifdef SQLITE_OMIT_BLOB_LITERAL + Tcl_SetVar2(interp, "sqlite_options", "bloblit", "0", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "bloblit", "1", TCL_GLOBAL_ONLY); +#endif } /* diff --git a/src/test3.c b/src/test3.c index b2974a77b..cc62b8c23 100644 --- a/src/test3.c +++ b/src/test3.c @@ -13,7 +13,7 @@ ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** -** $Id: test3.c,v 1.52 2004/09/17 19:39:24 drh Exp $ +** $Id: test3.c,v 1.53 2004/10/31 02:22:49 drh Exp $ */ #include "sqliteInt.h" #include "pager.h" @@ -578,7 +578,11 @@ static int btree_integrity_check( for(i=0; i<argc-2; i++){ if( Tcl_GetInt(interp, argv[i+2], &aRoot[i]) ) return TCL_ERROR; } +#ifndef SQLITE_OMIT_INTEGRITY_CHECK zResult = sqlite3BtreeIntegrityCheck(pBt, aRoot, nRoot); +#else + zResult = "ok"; +#endif if( zResult ){ Tcl_AppendResult(interp, zResult, 0); sqliteFree(zResult); diff --git a/src/tokenize.c b/src/tokenize.c index fee36dbf6..574077d67 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -15,7 +15,7 @@ ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** -** $Id: tokenize.c,v 1.92 2004/10/23 05:10:18 drh Exp $ +** $Id: tokenize.c,v 1.93 2004/10/31 02:22:49 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -287,6 +287,7 @@ static int sqliteGetToken(const unsigned char *z, int *tokenType){ case '5': case '6': case '7': case '8': case '9': { *tokenType = TK_INTEGER; for(i=1; isdigit(z[i]); i++){} +#ifndef SQLITE_OMIT_FLOATING_POINT if( z[i]=='.' && isdigit(z[i+1]) ){ i += 2; while( isdigit(z[i]) ){ i++; } @@ -301,6 +302,7 @@ static int sqliteGetToken(const unsigned char *z, int *tokenType){ while( isdigit(z[i]) ){ i++; } *tokenType = TK_FLOAT; } +#endif return i; } case '[': { @@ -318,6 +320,7 @@ static int sqliteGetToken(const unsigned char *z, int *tokenType){ *tokenType = i>1 ? TK_VARIABLE : TK_ILLEGAL; return i; } +#ifndef SQLITE_OMIT_TCL_VARIABLE case '$': { *tokenType = TK_VARIABLE; if( z[1]=='{' ){ @@ -354,7 +357,9 @@ static int sqliteGetToken(const unsigned char *z, int *tokenType){ if( n==0 ) *tokenType = TK_ILLEGAL; } return i; - } + } +#endif +#ifndef SQLITE_OMIT_BLOB_LITERAL case 'x': case 'X': { if( (c=z[1])=='\'' || c=='"' ){ int delim = c; @@ -374,6 +379,7 @@ static int sqliteGetToken(const unsigned char *z, int *tokenType){ } /* Otherwise fall through to the next case */ } +#endif default: { if( !IdChar(*z) ){ break; @@ -502,14 +508,14 @@ abort_parse: ** Token types used by the sqlite3_complete() routine. See the header ** comments on that procedure for additional information. */ -#define tkEXPLAIN 0 -#define tkCREATE 1 -#define tkTEMP 2 -#define tkTRIGGER 3 -#define tkEND 4 -#define tkSEMI 5 -#define tkWS 6 -#define tkOTHER 7 +#define tkSEMI 0 +#define tkWS 1 +#define tkOTHER 2 +#define tkEXPLAIN 3 +#define tkCREATE 4 +#define tkTEMP 5 +#define tkTRIGGER 6 +#define tkEND 7 /* ** Return TRUE if the given SQL string ends in a semicolon. @@ -524,16 +530,16 @@ abort_parse: ** returns 1 if it ends in the START state and 0 if it ends ** in any other state. ** -** (1) EXPLAIN The keyword EXPLAIN has been seen at the beginning of +** (1) NORMAL We are in the middle of statement which ends with a single +** semicolon. +** +** (2) EXPLAIN The keyword EXPLAIN has been seen at the beginning of ** a statement. ** -** (2) CREATE The keyword CREATE has been seen at the beginning of a +** (3) CREATE The keyword CREATE has been seen at the beginning of a ** statement, possibly preceeded by EXPLAIN and/or followed by ** TEMP or TEMPORARY ** -** (3) NORMAL We are in the middle of statement which ends with a single -** semicolon. -** ** (4) TRIGGER We are in the middle of a trigger definition that must be ** ended by a semicolon, the keyword END, and another semicolon. ** @@ -546,36 +552,51 @@ abort_parse: ** Transitions between states above are determined by tokens extracted ** from the input. The following tokens are significant: ** -** (0) tkEXPLAIN The "explain" keyword. -** (1) tkCREATE The "create" keyword. -** (2) tkTEMP The "temp" or "temporary" keyword. -** (3) tkTRIGGER The "trigger" keyword. -** (4) tkEND The "end" keyword. -** (5) tkSEMI A semicolon. -** (6) tkWS Whitespace -** (7) tkOTHER Any other SQL token. +** (0) tkSEMI A semicolon. +** (1) tkWS Whitespace +** (2) tkOTHER Any other SQL token. +** (3) tkEXPLAIN The "explain" keyword. +** (4) tkCREATE The "create" keyword. +** (5) tkTEMP The "temp" or "temporary" keyword. +** (6) tkTRIGGER The "trigger" keyword. +** (7) tkEND The "end" keyword. ** ** Whitespace never causes a state transition and is always ignored. +** +** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed +** to recognize the end of a trigger can be omitted. All we have to do +** is look for a semicolon that is not part of an string or comment. */ int sqlite3_complete(const char *zSql){ u8 state = 0; /* Current state, using numbers defined in header comment */ u8 token; /* Value of the next token */ - /* The following matrix defines the transition from one state to another - ** according to what token is seen. trans[state][token] returns the - ** next state. +#ifndef SQLITE_OMIT_TRIGGER + /* A complex statement machine used to detect the end of a CREATE TRIGGER + ** statement. This is the normal case. */ static const u8 trans[7][8] = { /* Token: */ - /* State: ** EXPLAIN CREATE TEMP TRIGGER END SEMI WS OTHER */ - /* 0 START: */ { 1, 2, 3, 3, 3, 0, 0, 3, }, - /* 1 EXPLAIN: */ { 3, 2, 3, 3, 3, 0, 1, 3, }, - /* 2 CREATE: */ { 3, 3, 2, 4, 3, 0, 2, 3, }, - /* 3 NORMAL: */ { 3, 3, 3, 3, 3, 0, 3, 3, }, - /* 4 TRIGGER: */ { 4, 4, 4, 4, 4, 5, 4, 4, }, - /* 5 SEMI: */ { 4, 4, 4, 4, 6, 5, 5, 4, }, - /* 6 END: */ { 4, 4, 4, 4, 4, 0, 6, 4, }, + /* State: ** SEMI WS OTHER EXPLAIN CREATE TEMP TRIGGER END */ + /* 0 START: */ { 0, 0, 1, 2, 3, 1, 1, 1, }, + /* 1 NORMAL: */ { 0, 1, 1, 1, 1, 1, 1, 1, }, + /* 2 EXPLAIN: */ { 0, 2, 1, 1, 3, 1, 1, 1, }, + /* 3 CREATE: */ { 0, 3, 1, 1, 1, 3, 4, 1, }, + /* 4 TRIGGER: */ { 5, 4, 4, 4, 4, 4, 4, 4, }, + /* 5 SEMI: */ { 5, 5, 4, 4, 4, 4, 4, 6, }, + /* 6 END: */ { 0, 6, 4, 4, 4, 4, 4, 4, }, + }; +#else + /* If triggers are not suppored by this compile then the statement machine + ** used to detect the end of a statement is much simplier + */ + static const u8 trans[2][3] = { + /* Token: */ + /* State: ** SEMI WS OTHER */ + /* 0 START: */ { 0, 0, 1, }, + /* 1 NORMAL: */ { 0, 1, 1, }, }; +#endif /* SQLITE_OMIT_TRIGGER */ while( *zSql ){ switch( *zSql ){ @@ -635,6 +656,9 @@ int sqlite3_complete(const char *zSql){ /* Keywords and unquoted identifiers */ int nId; for(nId=1; IdChar(zSql[nId]); nId++){} +#ifdef SQLITE_OMIT_TRIGGER + token = tkOTHER; +#else switch( *zSql ){ case 'c': case 'C': { if( nId==6 && sqlite3StrNICmp(zSql, "create", 6)==0 ){ @@ -659,9 +683,13 @@ int sqlite3_complete(const char *zSql){ case 'e': case 'E': { if( nId==3 && sqlite3StrNICmp(zSql, "end", 3)==0 ){ token = tkEND; - }else if( nId==7 && sqlite3StrNICmp(zSql, "explain", 7)==0 ){ + }else +#ifndef SQLITE_OMIT_EXPLAIN + if( nId==7 && sqlite3StrNICmp(zSql, "explain", 7)==0 ){ token = tkEXPLAIN; - }else{ + }else +#endif + { token = tkOTHER; } break; @@ -671,6 +699,7 @@ int sqlite3_complete(const char *zSql){ break; } } +#endif /* SQLITE_OMIT_TRIGGER */ zSql += nId-1; }else{ /* Operators and special symbols */ @@ -685,6 +714,7 @@ int sqlite3_complete(const char *zSql){ return state==0; } +#ifndef SQLITE_OMIT_UTF16 /* ** This routine is the same as the sqlite3_complete() routine described ** above, except that the parameter is required to be UTF-16 encoded, not @@ -704,3 +734,4 @@ int sqlite3_complete16(const void *zSql){ sqlite3ValueFree(pVal); return rc; } +#endif /* SQLITE_OMIT_UTF16 */ diff --git a/src/trigger.c b/src/trigger.c index bbb526f80..90b8b775e 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -12,6 +12,7 @@ */ #include "sqliteInt.h" +#ifndef SQLITE_OMIT_TRIGGER /* ** Delete a linked list of TriggerStep structures. */ @@ -802,3 +803,4 @@ int sqlite3CodeRowTrigger( } return 0; } +#endif /* !defined(SQLITE_OMIT_TRIGGER) */ diff --git a/src/update.c b/src/update.c index ca1500078..1905c3073 100644 --- a/src/update.c +++ b/src/update.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** -** $Id: update.c,v 1.90 2004/10/05 02:41:43 drh Exp $ +** $Id: update.c,v 1.91 2004/10/31 02:22:49 drh Exp $ */ #include "sqliteInt.h" @@ -67,12 +67,28 @@ void sqlite3Update( */ pTab = sqlite3SrcListLookup(pParse, pTabList); if( pTab==0 ) goto update_cleanup; + + /* Figure out if we have any triggers and if the table being + ** updated is a view + */ +#ifndef SQLITE_OMIT_TRIGGER before_triggers = sqlite3TriggersExist(pParse, pTab->pTrigger, - TK_UPDATE, TK_BEFORE, TK_ROW, pChanges); + TK_UPDATE, TK_BEFORE, TK_ROW, pChanges); after_triggers = sqlite3TriggersExist(pParse, pTab->pTrigger, - TK_UPDATE, TK_AFTER, TK_ROW, pChanges); + TK_UPDATE, TK_AFTER, TK_ROW, pChanges); row_triggers_exist = before_triggers || after_triggers; isView = pTab->pSelect!=0; +#else +# define before_triggers 0 +# define after_triggers 0 +# define row_triggers_exist 0 +# define isView 0 +#endif +#ifdef SQLITE_OMIT_VIEW +# undef isView +# define isView 0 +#endif + if( sqlite3IsReadOnly(pParse, pTab, before_triggers) ){ goto update_cleanup; } diff --git a/src/vdbe.c b/src/vdbe.c index 854a09577..bcf37f465 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -43,7 +43,7 @@ ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.419 2004/10/19 16:40:59 drh Exp $ +** $Id: vdbe.c,v 1.420 2004/10/31 02:22:50 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -3735,6 +3735,7 @@ case OP_DropTrigger: { } +#ifndef SQLITE_OMIT_INTEGRITY_CHECK /* Opcode: IntegrityCk * P2 * ** ** Do an analysis of the currently open database. Push onto the @@ -3786,6 +3787,7 @@ case OP_IntegrityCk: { sqliteFree(aRoot); break; } +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ /* Opcode: ListWrite * * * ** diff --git a/src/vdbeapi.c b/src/vdbeapi.c index f6047f6fb..bd39a539f 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -177,9 +177,12 @@ int sqlite3_step(sqlite3_stmt *pStmt){ db->activeVdbeCnt++; p->pc = 0; } +#ifndef SQLITE_OMIT_EXPLAIN if( p->explain ){ rc = sqlite3VdbeList(p); - }else{ + }else +#endif /* SQLITE_OMIT_EXPLAIN */ + { rc = sqlite3VdbeExec(p); } diff --git a/src/vdbeaux.c b/src/vdbeaux.c index fa9751daa..b2fad8e39 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -375,6 +375,8 @@ VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ return &p->aOp[addr]; } +#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \ + || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) /* ** Compute a string that describes the P3 parameter for an opcode. ** Use zTemp for any required temporary buffer space. @@ -444,6 +446,7 @@ static char *displayP3(Op *pOp, char *zTemp, int nTemp){ } return zP3; } +#endif #if !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) @@ -473,6 +476,7 @@ static void releaseMemArray(Mem *p, int N){ } } +#ifndef SQLITE_OMIT_EXPLAIN /* ** Give a listing of the program in the virtual machine. ** @@ -549,6 +553,7 @@ int sqlite3VdbeList( } return rc; } +#endif /* SQLITE_OMIT_EXPLAIN */ /* ** Print the SQL that was used to generate a VDBE program. |