-C Begin\sadding\sthe\sability\sto\sremove\sunused\sfeatures\sat\scompile-time\sand\sstill\nhave\sall\sthe\stests\spass.\s(CVS\s2033)
-D 2004-10-30T20:23:09
+C Insert\s#ifdefs\sthat\scan\soptionally\sremove\sfeatures\sat\scompiletime\sresulting\nin\sa\sdatabase\sengine\swith\sa\ssmaller\sfootprint.\s(CVS\s2034)
+D 2004-10-31T02:22:48
F Makefile.in 9e90c685d69f09039015a6b1f3b0a48e9738c9e5
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1
F ltmain.sh f6b283068efa69f06eb8aa1fe4bddfdbdeb35826
F main.mk c7c97f809e5e7897bc843db64f692c7ef9013a92
F mkdll.sh 468d4f41d3ea98221371df4825cfbffbaac4d7e4
-F mkopcodec.awk 80311cdeb16d78017cc62e4ad6c6d008e5fe0e17
+F mkopcodec.awk 14a794f7b206976afc416b30fe8e0fc97f3434e9
F mkopcodeh.awk 4090944e4de0a2ccb99aa0083290f73bce4db406
F mkso.sh 7b67da1d63070875ba948e749aee9ef50ce36e3d
F publish.sh 72bde067dda3fc2d33e92f20253b924e3b97da30
F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a
F src/attach.c e49d09dad9f5f9fb10b4b0c1be5a70ae4c45e689
F src/auth.c 3b81f2a42f48a62c2c9c9b0eda31a157c681edea
-F src/btree.c d8426846c0db61c97a0e3e11531781be7a96f1bc
+F src/btree.c 3764bdd9839075eb6dcc2369caca659b9b89d3f5
F src/btree.h 94dfec0a1722d33359b23e7e310f2b64ffedf029
-F src/build.c cb0232e0f239d7cea8598d982039b99259074f64
+F src/build.c bb896c5f85ab749d17ae5d730235134c12c08033
F src/date.c 34bdb0082db7ec2a83ef00063f7b44e61ee19dad
-F src/delete.c 531525eca2885afc1d9c63e110bc7aa568e170c3
-F src/expr.c 2f492bf532d700bd2c38e16caa49048535e8ed27
+F src/delete.c cf0efbef1f42d4eec385a3f59af2b37a5e232074
+F src/expr.c 3a43e508a3dc213703808bbcbb17633b88b57d17
F src/func.c 600e506bccf7648df8ad03efb417560d0f7ad4c1
F src/hash.c a97721a55440b7bea31ffe471bb2f6b4123cddd5
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
-F src/insert.c 7e8ce8834c3716a313694e5340dbf28ff828677a
+F src/insert.c 64a3716522cbc81d91176eac0d944cc14be6236c
F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b
F src/main.c ba1b26f03af4b7f8be3394748123dd671b9ea147
F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
F src/os_unix.h f3097815e041e82e24d92505e1ff61ba24172d13
F src/os_win.c 9482dfc92f289b68205bb2c9315757c7e3946bfb
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
-F src/pager.c cc2e7fb3d7913862d7b1170f923d2dcfdbac3bed
+F src/pager.c 6e19f9a64a9fae60bcf00140cecb5981765f3d95
F src/pager.h 774d1973acbda341827d21b0da0150575d69f7d9
-F src/parse.y 8d97a91cba7e35b5eaac064c9f6e597dc6442b29
-F src/pragma.c 263e20f7640df1e7937f1c71372fa286356aaf09
+F src/parse.y 08f4971f89e651f47b3f83fe7369c7edde254331
+F src/pragma.c 44e192eb5928157bdb015926f858a7c6e3ef6c98
F src/printf.c 7a92adc00b758cd5ce087dae80181a8bbdb70ed2
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
-F src/select.c de51ec24aef0d5370819dac6c2613460effac42c
+F src/select.c 156990c636102bb6b8de85e7ff3396a62568476b
F src/shell.c 55adda3cf3c1cc2f6c1919aac17b2318f9c2a96f
F src/sqlite.h.in 4f97b5907acfd2a5068cb0cec9d5178816734db7
-F src/sqliteInt.h 008c205896a1c531ec6249de20ecfe23c89ae243
+F src/sqliteInt.h 84d5ca7b02793697641a74fb125fcee3995ea2ff
F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9
F src/tclsqlite.c 0302e3f42f015d132d1291f3388c06e86c24a008
-F src/test1.c 23fd40832736c46b9c2d897fa13c7d913a3f1626
+F src/test1.c cc5bc94006d23584a966c12b0b9fa1db0d94af76
F src/test2.c b11fa244fff02190707dd0879987c37c75e61fc8
-F src/test3.c 5b5b0f3d11b097399c1054fff73d8f3711092301
+F src/test3.c f423597e220b3d446a65c9cc0c49cb4eb00c0215
F src/test4.c 7c6b9fc33dd1f3f93c7f1ee6e5e6d016afa6c1df
F src/test5.c b001fa7f1b9e2dc5c2331de62fc641b5ab2bd7a1
-F src/tokenize.c f073bbf85fe527e1a8a191a1fda88313c09710ad
-F src/trigger.c b51a120d53e8b85359be11bf5e50854e5725fe3d
-F src/update.c 174c3b593b8f4928e510a51ec309e8ce69d2371c
+F src/tokenize.c a0a999bf4800e7295ac66c8694f84414ceff1755
+F src/trigger.c f9a0a8d3a87238de1a934eeb7d0b6b1f13e6a55b
+F src/update.c ee15b7ba712c2292802eba2d465f039b5deada39
F src/utf.c f4f83acd73389090e32d6589d307fc55d794c7ed
F src/util.c f4ab796b9def353feed2191d7ce8e39a0f5059cd
F src/vacuum.c ecb4a2c6f1ac5cc9b394dc64d3bb14ca650c4f60
-F src/vdbe.c adbcdbc817ae2f411904cd12582f06fc1ca8be1e
+F src/vdbe.c 253beaae665f50a1320f0a068f9dda68e3c3df47
F src/vdbe.h 067ca8d6750ba4f69a50284765e5883dee860181
F src/vdbeInt.h 6017100adff362b8dfa37a69e3f1431f084bfa5b
-F src/vdbeapi.c 81ab9e84c55f5762f552904e6e5d309269b02017
-F src/vdbeaux.c 73928b98034cf3321afb6aa815723f08705bb135
+F src/vdbeapi.c 3965bf4678ae32c05f73550c1b5be3268f9f3006
+F src/vdbeaux.c 544ff66308d3184b519decc731abb65c5233bc2d
F src/vdbemem.c ef9ac7d32acfe4bce5c5b408b1294c8d9e0cdb56
F src/where.c 6e637a6b3e61fe3104adc4e5caa4738bf6570daa
F test/all.test 929bfa932b55e75c96fe2203f7650ba451c1862c
-F test/attach.test feb2ce54e78688df4c84553416d5aec3b2a0112e
+F test/attach.test 6ad560eb3e77751a4faecd77da09deac9e38cc41
F test/attach2.test f7795123d3051ace1672b6d23973da6435de3745
F test/attach3.test 6d060986ff004ebb89e1876a331d96c6bb62269e
F test/auth.test 1cc252d9e7b3bdc1314199cbf3a0d3c5ed026c21
F test/corrupt.test 0080ddcece23e8ba47c44608c4fb73fd4d1d8ce2
F test/crash.test a3f6d27f7cb7f7bd752461db1e14f7c781ecedc3
F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
-F test/date.test b4f8bb8e3e3ee6eb3efa1ccef47cfe206dafe4b8
+F test/date.test dda578ec1857837156bd8b32f8e09d81d7d7881c
F test/delete.test ec0b455f2dcc0e189d96ee438438ba026c4e51d8
F test/delete2.test 050a3a6e8ea0f83aed817d164b16af2a499fb452
F test/diskfull.test e2f6cfd868713ead06dc82b84a4938e868128fc0
F test/threadtest2.c 97a830d53c24c42290501fdfba4a6e5bdd34748b
F test/trace.test a54fa8df0d01cf827289a7659d78959e8fd2f955
F test/trans.test 29645b344d2b9b6792793562b12340177ddd8f96
-F test/trigger1.test dc015c410161f1a6109fd52638dfac852e2a34de
-F test/trigger2.test a5d06e6e8e1e773cfcb5aaa75ab381b2ff35de63
-F test/trigger3.test 70931be83fa3f563f7a5ca9e88b86f476af73948
-F test/trigger4.test 97c11d3cf43d752b172809bb82536372ee5e399c
-F test/trigger5.test 25ba4d352282cd05753496a50f0bd23162cc97b9
+F test/trigger1.test 63a74ae12bccac86036f1c4f8f952fb0cf80703f
+F test/trigger2.test fec8f9091ff1248eafb5a33690ad4ff7615f5215
+F test/trigger3.test f1c0cc1365f00b21a8cd41c189edca139c2d6cc6
+F test/trigger4.test ce5c97aba6a8a11be5820e694659438c3e982ada
+F test/trigger5.test 619391a3e9fc194081d22cefd830d811e7badf83
F test/types.test 1f5f0670cf07e44c0a5b03a31e31ec5ed39a482e
F test/types2.test f23c147a2ab3e51d5dbcfa9987200db5acba7aa7
F test/unique.test 0e38d4cc7affeef2527720d1dafd1f6870f02f2b
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
F www/whentouse.tcl fdacb0ba2d39831e8a6240d05a490026ad4c4e4c
-P 87a3c668f0dcd43f5d9b38d92a75a4ac38d49057
-R 7ce19f5cec69820ac47d8f047cf87ee1
+P 2aa506ccb003a25555b414772002d0130db93052
+R a7fa315527f5cd6a01abf8ab34756c15
U drh
-Z 49adbf5abf742ee3280084694fca0270
+Z ec22b5e4f08c77bf263552544e24fca1
-2aa506ccb003a25555b414772002d0130db93052
\ No newline at end of file
+be661acfa849bb0d5692797dd221f5a8a457f8ad
\ No newline at end of file
BEGIN {
print "/* Automatically generated. Do not edit */"
print "/* See the mkopcodec.h script for details. */"
+ printf "#if !defined(SQLITE_OMIT_EXPLAIN)"
+ printf " || !defined(NDEBUG)"
+ printf " || defined(VDBE_PROFILE)"
+ print " || defined(SQLITE_DEBUG)"
print "const char *const sqlite3OpcodeNames[] = { \"?\","
}
/^#define OP_/ {
}
END {
print "};"
+ print "#endif"
}
** 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
char *zErrMsg; /* An error message. NULL of no errors seen. */
};
+#ifndef SQLITE_OMIT_INTEGRITY_CHECK
/*
** Append a message to the error message string.
*/
}
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.
}
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.
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
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
sqliteFree(sCheck.anRef);
return sCheck.zErrMsg;
}
+#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
/*
** Return the full pathname of the underlying database file.
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.
}
return rc;
}
+#endif /* SQLITE_OMIT_VACUUM */
/*
** Return non-zero if a transaction is active.
** 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>
}
}
+#ifndef SQLITE_OMIT_VIEW
/*
** The parser calls this routine in order to create a new VIEW
*/
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
pSel->pEList = pEList;
return nErr;
}
+#endif /* SQLITE_OMIT_VIEW */
+#ifndef SQLITE_OMIT_VIEW
/*
** Clear the column names from every VIEW in database 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.
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;
fk_end:
sqliteFree(pFKey);
+#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
sqlite3ExprListDelete(pFromCol);
sqlite3ExprListDelete(pToCol);
}
** 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
}
/*
** 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"
*/
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;
}
** 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>
}
}
+#ifndef SQLITE_OMIT_TRIGGER
/* If we have not already resolved the name, then maybe
** it is a new.* or old.* trigger argument reference
*/
}
}
}
+#endif /* !defined(SQLITE_OMIT_TRIGGER) */
/*
** Perhaps the name is a reference to the ROWID
** 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"
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;
}
** 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"
*/
#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
/*
static int pager_unwritelock(Pager *pPager){
PgHdr *pPg;
int rc;
- assert( !pPager->memDb );
+ assert( !MEMDB );
if( pPager->state<PAGER_RESERVED ){
return SQLITE_OK;
}
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);
*/
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);
}
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 ){
if( nPage>=(unsigned)pPager->dbSize ){
return SQLITE_OK;
}
- if( pPager->memDb ){
+ if( MEMDB ){
pPager->dbSize = nPage;
memoryTruncate(pPager);
return SQLITE_OK;
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;
}
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 );
/* 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;
}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;
}
}
/* 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;
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);
*/
pPager->nRef--;
assert( pPager->nRef>=0 );
- if( pPager->nRef==0 && !pPager->memDb ){
+ if( pPager->nRef==0 && !MEMDB ){
pager_reset(pPager);
}
}
*/
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 );
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{
** 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 );
*/
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 );
*/
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++;
}
}
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;
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);
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));
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;
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;
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 );
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;
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);
/* 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 );
** 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}
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. ////////////////////////////
//
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
///////////////////// 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 /////////////////////////////////
//
%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;
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);
//////////////////////////// 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;
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;}
//////////////////////// 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). {
*************************************************************************
** 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>
}
}else
+#ifndef SQLITE_OMIT_FOREIGN_KEY
if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 && zRight ){
FKey *pFK;
Table *pTab;
}
}
}else
+#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
if( sqlite3StrICmp(zLeft, "database_list")==0 ){
int i;
}else
#endif
+#ifndef SQLITE_OMIT_INTEGRITY_CHECK
if( sqlite3StrICmp(zLeft, "integrity_check")==0 ){
int i, j, addr;
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"
** 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"
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.
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
}
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.
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
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
sqlite3SelectDelete(pSub);
return 1;
}
+#endif /* SQLITE_OMIT_VIEW */
/*
** Analyze the SELECT statement passed in as an argument to see if it
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.
*/
/* 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.
*************************************************************************
** 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_
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);
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*);
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);
** 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"
#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);
#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
}
/*
** 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"
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);
** 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"
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++; }
while( isdigit(z[i]) ){ i++; }
*tokenType = TK_FLOAT;
}
+#endif
return i;
}
case '[': {
*tokenType = i>1 ? TK_VARIABLE : TK_ILLEGAL;
return i;
}
+#ifndef SQLITE_OMIT_TCL_VARIABLE
case '$': {
*tokenType = TK_VARIABLE;
if( z[1]=='{' ){
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;
}
/* Otherwise fall through to the next case */
}
+#endif
default: {
if( !IdChar(*z) ){
break;
** 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.
** 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.
**
** 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 ){
/* 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 ){
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;
break;
}
}
+#endif /* SQLITE_OMIT_TRIGGER */
zSql += nId-1;
}else{
/* Operators and special symbols */
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
sqlite3ValueFree(pVal);
return rc;
}
+#endif /* SQLITE_OMIT_UTF16 */
*/
#include "sqliteInt.h"
+#ifndef SQLITE_OMIT_TRIGGER
/*
** Delete a linked list of TriggerStep structures.
*/
}
return 0;
}
+#endif /* !defined(SQLITE_OMIT_TRIGGER) */
** 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"
*/
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;
}
** 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"
}
+#ifndef SQLITE_OMIT_INTEGRITY_CHECK
/* Opcode: IntegrityCk * P2 *
**
** Do an analysis of the currently open database. Push onto the
sqliteFree(aRoot);
break;
}
+#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
/* Opcode: ListWrite * * *
**
db->activeVdbeCnt++;
p->pc = 0;
}
+#ifndef SQLITE_OMIT_EXPLAIN
if( p->explain ){
rc = sqlite3VdbeList(p);
- }else{
+ }else
+#endif /* SQLITE_OMIT_EXPLAIN */
+ {
rc = sqlite3VdbeExec(p);
}
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.
}
return zP3;
}
+#endif
#if !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
}
}
+#ifndef SQLITE_OMIT_EXPLAIN
/*
** Give a listing of the program in the virtual machine.
**
}
return rc;
}
+#endif /* SQLITE_OMIT_EXPLAIN */
/*
** Print the SQL that was used to generate a VDBE program.
# focus of this script is testing the ATTACH and DETACH commands
# and related functionality.
#
-# $Id: attach.test,v 1.26 2004/08/18 15:58:24 drh Exp $
+# $Id: attach.test,v 1.27 2004/10/31 02:22:50 drh Exp $
#
set testdir [file dirname $argv0]
db_list db
} {0 main 1 temp}
+ifcapable {trigger} { # Only do the following tests if triggers are enabled
do_test attach-2.1 {
execsql {
CREATE TABLE tx(x1,x2,y1,y2);
SELECT type, name, tbl_name FROM db2.sqlite_master;
}
} {table t2 t2 table tx tx trigger r1 t2 index i2 t2}
+} ;# End of ifcapable {trigger}
do_test attach-3.1 {
db close
SELECT * FROM t1
}
} {1 2 3 4}
+
+# If we are testing a version of the code that lacks trigger support,
+# adjust the database contents so that they are the same if triggers
+# had been enabled.
+ifcapable {!trigger} {
+ db2 eval {
+ DELETE FROM t2;
+ INSERT INTO t2 VALUES(21, 'x');
+ INSERT INTO t2 VALUES(22, 'y');
+ CREATE TABLE tx(x1,x2,y1,y2);
+ INSERT INTO tx VALUES(1, 11, 'x', 'x');
+ INSERT INTO tx VALUES(2, 12, 'y', 'y');
+ INSERT INTO tx VALUES(11, 21, 'x', 'x');
+ INSERT INTO tx VALUES(12, 22, 'y', 'y');
+ CREATE INDEX i2 ON t2(x);
+ }
+}
+
do_test attach-3.2 {
catchsql {
SELECT * FROM t2
SELECT * FROM db2.t3;
}
} {1 2 9 10}
-do_test attach-4.6 {
- execsql {
- DETACH db2;
- }
- execsql {
- CREATE TABLE t4(x);
- CREATE TRIGGER t3r3 AFTER INSERT ON t3 BEGIN
- INSERT INTO t4 VALUES('db2.' || NEW.x);
- END;
- INSERT INTO t3 VALUES(6,7);
- SELECT * FROM t4;
- } db2
-} {db2.6}
-do_test attach-4.7 {
- execsql {
- CREATE TABLE t4(y);
- CREATE TRIGGER t3r3 AFTER INSERT ON t3 BEGIN
- INSERT INTO t4 VALUES('main.' || NEW.a);
- END;
- INSERT INTO main.t3 VALUES(11,12);
- SELECT * FROM main.t4;
- }
-} {main.11}
+ifcapable {trigger} {
+ do_test attach-4.6 {
+ execsql {
+ DETACH db2;
+ }
+ execsql {
+ CREATE TABLE t4(x);
+ CREATE TRIGGER t3r3 AFTER INSERT ON t3 BEGIN
+ INSERT INTO t4 VALUES('db2.' || NEW.x);
+ END;
+ INSERT INTO t3 VALUES(6,7);
+ SELECT * FROM t4;
+ } db2
+ } {db2.6}
+ do_test attach-4.7 {
+ execsql {
+ CREATE TABLE t4(y);
+ CREATE TRIGGER t3r3 AFTER INSERT ON t3 BEGIN
+ INSERT INTO t4 VALUES('main.' || NEW.a);
+ END;
+ INSERT INTO main.t3 VALUES(11,12);
+ SELECT * FROM main.t4;
+ }
+ } {main.11}
+}
# This one is tricky. On the UNION ALL select, we have to make sure
# the schema for both main and db2 is valid before starting to execute
# This file implements regression tests for SQLite library. The
# focus of this file is testing date and time functions.
#
-# $Id: date.test,v 1.10 2004/10/30 20:23:10 drh Exp $
+# $Id: date.test,v 1.11 2004/10/31 02:22:50 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# Skip this whole file if date and time functions are omitted
# at compile-time
#
-if {!$sqlite_options(datetime)} {
+ifcapable {!datetime} {
finish_test
return
}
set testdir [file dirname $argv0]
source $testdir/tester.tcl
+ifcapable {!trigger} {
+ finish_test
+ return
+}
-do_test trigger1-1.1.2 {
+do_test trigger1-1.1.1 {
catchsql {
CREATE TRIGGER trig UPDATE ON no_such_table BEGIN
SELECT * from sqlite_master;
set testdir [file dirname $argv0]
source $testdir/tester.tcl
+ifcapable {!trigger} {
+ finish_test
+ return
+}
# 1.
set ii 0
set testdir [file dirname $argv0]
source $testdir/tester.tcl
+ifcapable {!trigger} {
+ finish_test
+ return
+}
# Test that we can cause ROLLBACK, FAIL and ABORT correctly
# catchsql { DROP TABLE tbl; }
set testdir [file dirname $argv0]
source $testdir/tester.tcl
+ifcapable {!trigger} {
+ finish_test
+ return
+}
do_test trigger4-1.1 {
execsql {
set testdir [file dirname $argv0]
source $testdir/tester.tcl
+ifcapable {!trigger} {
+ finish_test
+ return
+}
# Ticket #844
#