From a004e906ddb5e5796bcb04669ab1606254f2e9a9 Mon Sep 17 00:00:00 2001 From: Scott Ehlert Date: Wed, 21 Mar 2007 20:19:37 +0000 Subject: [PATCH] Updated SQLite to 3.3.13 - why? I have no idea --- dlls/sqlite/Makefile | 17 +- dlls/sqlite/msvc7/sqlite.vcproj | 9 + dlls/sqlite/msvc8/sqlite.vcproj | 12 + dlls/sqlite/sqlite-source/alter.c | 19 +- dlls/sqlite/sqlite-source/attach.c | 24 +- dlls/sqlite/sqlite-source/auth.c | 6 +- dlls/sqlite/sqlite-source/btree.c | 502 ++- dlls/sqlite/sqlite-source/btree.h | 3 +- dlls/sqlite/sqlite-source/build.c | 219 +- dlls/sqlite/sqlite-source/callback.c | 6 + dlls/sqlite/sqlite-source/date.c | 74 +- dlls/sqlite/sqlite-source/delete.c | 46 +- dlls/sqlite/sqlite-source/expr.c | 159 +- dlls/sqlite/sqlite-source/func.c | 114 +- dlls/sqlite/sqlite-source/insert.c | 49 +- dlls/sqlite/sqlite-source/keywordhash.h | 24 +- dlls/sqlite/sqlite-source/legacy.c | 3 +- dlls/sqlite/sqlite-source/loadext.c | 422 +++ dlls/sqlite/sqlite-source/main.c | 140 +- dlls/sqlite/sqlite-source/opcodes.c | 276 +- dlls/sqlite/sqlite-source/opcodes.h | 292 +- dlls/sqlite/sqlite-source/os.h | 85 +- dlls/sqlite/sqlite-source/os_common.h | 10 +- dlls/sqlite/sqlite-source/os_unix.c | 1119 ++++++- dlls/sqlite/sqlite-source/os_win.c | 412 ++- dlls/sqlite/sqlite-source/pager.c | 426 ++- dlls/sqlite/sqlite-source/pager.h | 3 +- dlls/sqlite/sqlite-source/parse.c | 3772 ++++++++++++----------- dlls/sqlite/sqlite-source/parse.h | 194 +- dlls/sqlite/sqlite-source/pragma.c | 79 +- dlls/sqlite/sqlite-source/prepare.c | 151 +- dlls/sqlite/sqlite-source/printf.c | 35 +- dlls/sqlite/sqlite-source/random.c | 2 +- dlls/sqlite/sqlite-source/select.c | 327 +- dlls/sqlite/sqlite-source/shell.c | 360 ++- dlls/sqlite/sqlite-source/sqlite3.def | 101 - dlls/sqlite/sqlite-source/sqlite3.h | 410 ++- dlls/sqlite/sqlite-source/sqlite3ext.h | 282 ++ dlls/sqlite/sqlite-source/sqliteInt.h | 189 +- dlls/sqlite/sqlite-source/table.c | 32 +- dlls/sqlite/sqlite-source/tclsqlite.c | 134 +- dlls/sqlite/sqlite-source/tokenize.c | 26 +- dlls/sqlite/sqlite-source/trigger.c | 32 +- dlls/sqlite/sqlite-source/update.c | 153 +- dlls/sqlite/sqlite-source/utf.c | 65 +- dlls/sqlite/sqlite-source/util.c | 19 +- dlls/sqlite/sqlite-source/vacuum.c | 113 +- dlls/sqlite/sqlite-source/vdbe.c | 525 +++- dlls/sqlite/sqlite-source/vdbe.h | 8 +- dlls/sqlite/sqlite-source/vdbeInt.h | 19 +- dlls/sqlite/sqlite-source/vdbeapi.c | 93 +- dlls/sqlite/sqlite-source/vdbeaux.c | 257 +- dlls/sqlite/sqlite-source/vdbemem.c | 34 +- dlls/sqlite/sqlite-source/vtab.c | 693 +++++ dlls/sqlite/sqlite-source/where.c | 723 ++++- 55 files changed, 9336 insertions(+), 3963 deletions(-) create mode 100644 dlls/sqlite/sqlite-source/loadext.c delete mode 100644 dlls/sqlite/sqlite-source/sqlite3.def create mode 100644 dlls/sqlite/sqlite-source/sqlite3ext.h create mode 100644 dlls/sqlite/sqlite-source/vtab.c diff --git a/dlls/sqlite/Makefile b/dlls/sqlite/Makefile index e8262309..57d14c51 100755 --- a/dlls/sqlite/Makefile +++ b/dlls/sqlite/Makefile @@ -20,16 +20,13 @@ CPP_OBJECTS = basic_sql.cpp handles.cpp module.cpp threading.cpp sdk/amxxmodule. CPP_OBJECTS += thread/BaseWorker.cpp thread/ThreadWorker.cpp thread/PosixThreads.cpp CPP_OBJECTS += sqlitepp/SqliteQuery.cpp sqlitepp/SqliteResultSet.cpp sqlitepp/SqliteDatabase.cpp sqlitepp/SqliteDriver.cpp -C_OBJECTS = $(SQL)/attach.c $(SQL)/auth.c $(SQL)/btree.c $(SQL)/build.c \ - $(SQL)/date.c $(SQL)/delete.c $(SQL)/func.c $(SQL)/hash.c \ - $(SQL)/insert.c $(SQL)/legacy.c $(SQL)/main.c $(SQL)/opcodes.c \ - $(SQL)/os.c $(SQL)/os_unix.c $(SQL)/pager.c $(SQL)/parse.c \ - $(SQL)/pragma.c $(SQL)/printf.c $(SQL)/random.c $(SQL)/select.c \ - $(SQL)/table.c $(SQL)/tokenize.c $(SQL)/trigger.c $(SQL)/update.c \ - $(SQL)/utf.c $(SQL)/util.c $(SQL)/vacuum.c $(SQL)/vdbe.c \ - $(SQL)/vdbeapi.c $(SQL)/vdbeaux.c $(SQL)/vdbemem.c $(SQL)/where.c \ - $(SQL)/prepare.c $(SQL)/expr.c $(SQL)/callback.c $(SQL)/alter.c \ - $(SQL)/vdbefifo.c $(SQL)/complete.c $(SQL)/analyze.c +C_OBJECTS = $(SQL)/alter.c $(SQL)/analyze.c $(SQL)/attach.c $(SQL)/auth.c $(SQL)/btree.c $(SQL)/build.c \ + $(SQL)/callback.c $(SQL)/complete.c $(SQL)/date.c $(SQL)/delete.c $(SQL)/expr.c $(SQL)/func.c \ + $(SQL)/hash.c $(SQL)/insert.c $(SQL)/legacy.c $(SQL)/loadext.c $(SQL)/main.c $(SQL)/opcodes.c \ + $(SQL)/os.c $(SQL)/os_unix.c $(SQL)/pager.c $(SQL)/parse.c $(SQL)/pragma.c $(SQL)/prepare.c \ + $(SQL)/printf.c $(SQL)/random.c $(SQL)/select.c $(SQL)/table.c $(SQL)/tokenize.c $(SQL)/trigger.c \ + $(SQL)/update.c $(SQL)/utf.c $(SQL)/util.c $(SQL)/vacuum.c $(SQL)/vdbe.c $(SQL)/vdbeapi.c \ + $(SQL)/vdbeaux.c $(SQL)/vdbefifo.c $(SQL)/vdbemem.c $(SQL)/vtab.c $(SQL)/where.c \ CFLAGS = -Wall -Werror CPPFLAGS = -Wall -Wno-non-virtual-dtor -Werror diff --git a/dlls/sqlite/msvc7/sqlite.vcproj b/dlls/sqlite/msvc7/sqlite.vcproj index 1a9bfdb6..e0ee8bf4 100644 --- a/dlls/sqlite/msvc7/sqlite.vcproj +++ b/dlls/sqlite/msvc7/sqlite.vcproj @@ -294,6 +294,9 @@ + + @@ -345,6 +348,9 @@ + + @@ -390,6 +396,9 @@ + + diff --git a/dlls/sqlite/msvc8/sqlite.vcproj b/dlls/sqlite/msvc8/sqlite.vcproj index 683c8c81..8224fdd8 100644 --- a/dlls/sqlite/msvc8/sqlite.vcproj +++ b/dlls/sqlite/msvc8/sqlite.vcproj @@ -407,6 +407,10 @@ RelativePath="..\sqlite-source\legacy.c" > + + @@ -475,6 +479,10 @@ RelativePath="..\sqlite-source\sqlite3.h" > + + @@ -535,6 +543,10 @@ RelativePath="..\sqlite-source\vdbemem.c" > + + diff --git a/dlls/sqlite/sqlite-source/alter.c b/dlls/sqlite/sqlite-source/alter.c index 2b48157d..81c53ffb 100644 --- a/dlls/sqlite/sqlite-source/alter.c +++ b/dlls/sqlite/sqlite-source/alter.c @@ -28,7 +28,7 @@ ** This function is used by SQL generated to implement the ** ALTER TABLE command. The first argument is the text of a CREATE TABLE or ** CREATE INDEX command. The second is a table name. The table name in -** the CREATE TABLE or CREATE INDEX statement is replaced with the second +** the CREATE TABLE or CREATE INDEX statement is replaced with the third ** argument and the result returned. Examples: ** ** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def') @@ -78,10 +78,10 @@ static void renameTableFunc( } #ifndef SQLITE_OMIT_TRIGGER -/* This function is used by SQL generated to implement the ALTER TABLE +/* This function is used by SQL generated to implement the ** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER ** statement. The second is a table name. The table name in the CREATE -** TRIGGER statement is replaced with the second argument and the result +** TRIGGER statement is replaced with the third argument and the result ** returned. This is analagous to renameTableFunc() above, except for CREATE ** TRIGGER, not CREATE INDEX and CREATE TABLE. */ @@ -272,6 +272,12 @@ void sqlite3AlterRenameTable( pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase); if( !pTab ) goto exit_rename_table; +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + sqlite3ErrorMsg(pParse, "virtual tables may not be altered"); + goto exit_rename_table; + } +#endif iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); zDb = db->aDb[iDb].zName; @@ -512,6 +518,13 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase); if( !pTab ) goto exit_begin_add_column; +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + sqlite3ErrorMsg(pParse, "virtual tables may not be altered"); + goto exit_begin_add_column; + } +#endif + /* Make sure this is not an attempt to ALTER a view. */ if( pTab->pSelect ){ sqlite3ErrorMsg(pParse, "Cannot add a column to a view"); diff --git a/dlls/sqlite/sqlite-source/attach.c b/dlls/sqlite/sqlite-source/attach.c index 5bd46ad6..10abc490 100644 --- a/dlls/sqlite/sqlite-source/attach.c +++ b/dlls/sqlite/sqlite-source/attach.c @@ -73,6 +73,8 @@ static void attachFunc( zFile = (const char *)sqlite3_value_text(argv[0]); zName = (const char *)sqlite3_value_text(argv[1]); + if( zFile==0 ) zFile = ""; + if( zName==0 ) zName = ""; /* Check for the following errors: ** @@ -82,7 +84,7 @@ static void attachFunc( */ if( db->nDb>=MAX_ATTACHED+2 ){ sqlite3_snprintf( - 127, zErr, "too many attached databases - max %d", MAX_ATTACHED + sizeof(zErr), zErr, "too many attached databases - max %d", MAX_ATTACHED ); goto attach_error; } @@ -92,8 +94,8 @@ static void attachFunc( } for(i=0; inDb; i++){ char *z = db->aDb[i].zName; - if( z && sqlite3StrICmp(z, zName)==0 ){ - sqlite3_snprintf(127, zErr, "database %s is already in use", zName); + if( z && zName && sqlite3StrICmp(z, zName)==0 ){ + sqlite3_snprintf(sizeof(zErr), zErr, "database %s is already in use", zName); goto attach_error; } } @@ -186,10 +188,10 @@ static void attachFunc( sqlite3ResetInternalSchema(db, 0); db->nDb = iDb; if( rc==SQLITE_NOMEM ){ - sqlite3MallocFailed(); - sqlite3_snprintf(127, zErr, "out of memory"); + if( !sqlite3MallocFailed() ) sqlite3FailedMalloc(); + sqlite3_snprintf(sizeof(zErr),zErr, "out of memory"); }else{ - sqlite3_snprintf(127, zErr, "unable to open database: %s", zFile); + sqlite3_snprintf(sizeof(zErr),zErr, "unable to open database: %s", zFile); } goto attach_error; } @@ -226,7 +228,7 @@ static void detachFunc( Db *pDb = 0; char zErr[128]; - assert(zName); + if( zName==0 ) zName = ""; for(i=0; inDb; i++){ pDb = &db->aDb[i]; if( pDb->pBt==0 ) continue; @@ -234,17 +236,21 @@ static void detachFunc( } if( i>=db->nDb ){ - sqlite3_snprintf(sizeof(zErr), zErr, "no such database: %s", zName); + sqlite3_snprintf(sizeof(zErr),zErr, "no such database: %s", zName); goto detach_error; } if( i<2 ){ - sqlite3_snprintf(sizeof(zErr), zErr, "cannot detach database %s", zName); + sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName); goto detach_error; } if( !db->autoCommit ){ strcpy(zErr, "cannot DETACH database within transaction"); goto detach_error; } + if( sqlite3BtreeIsInReadTrans(pDb->pBt) ){ + sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName); + goto detach_error; + } sqlite3BtreeClose(pDb->pBt); pDb->pBt = 0; diff --git a/dlls/sqlite/sqlite-source/auth.c b/dlls/sqlite/sqlite-source/auth.c index dbed6a52..3983c1bc 100644 --- a/dlls/sqlite/sqlite-source/auth.c +++ b/dlls/sqlite/sqlite-source/auth.c @@ -182,8 +182,10 @@ int sqlite3AuthCheck( sqlite3 *db = pParse->db; int rc; - /* Don't do any authorization checks if the database is initialising. */ - if( db->init.busy ){ + /* Don't do any authorization checks if the database is initialising + ** or if the parser is being invoked from within sqlite3_declare_vtab. + */ + if( db->init.busy || IN_DECLARE_VTAB ){ return SQLITE_OK; } diff --git a/dlls/sqlite/sqlite-source/btree.c b/dlls/sqlite/sqlite-source/btree.c index 5c84c5bf..91bdac8a 100644 --- a/dlls/sqlite/sqlite-source/btree.c +++ b/dlls/sqlite/sqlite-source/btree.c @@ -387,17 +387,13 @@ struct BtCursor { CellInfo info; /* A parse of the cell we are pointing at */ u8 wrFlag; /* True if writable */ u8 eState; /* One of the CURSOR_XXX constants (see below) */ -#ifndef SQLITE_OMIT_SHARED_CACHE void *pKey; /* Saved key that was cursor's last known position */ i64 nKey; /* Size of pKey, or last integer key */ int skip; /* (skip<0) -> Prev() is a no-op. (skip>0) -> Next() is */ -#endif }; /* -** Potential values for BtCursor.eState. The first two values (VALID and -** INVALID) may occur in any build. The third (REQUIRESEEK) may only occur -** if sqlite was compiled without the OMIT_SHARED_CACHE symbol defined. +** Potential values for BtCursor.eState. ** ** CURSOR_VALID: ** Cursor points to a valid entry. getPayload() etc. may be called. @@ -425,16 +421,17 @@ struct BtCursor { */ #if SQLITE_TEST # define TRACE(X) if( sqlite3_btree_trace )\ - { sqlite3DebugPrintf X; fflush(stdout); } +/* { sqlite3DebugPrintf X; fflush(stdout); } */ \ +{ printf X; fflush(stdout); } +int sqlite3_btree_trace=0; /* True to enable tracing */ #else # define TRACE(X) #endif -int sqlite3_btree_trace=0; /* True to enable tracing */ /* ** Forward declaration */ -static int checkReadLocks(BtShared*,Pgno,BtCursor*); +static int checkReadLocks(Btree*,Pgno,BtCursor*); /* ** Read or write a two- and four-byte big-endian integer values. @@ -509,105 +506,8 @@ struct BtLock { #define queryTableLock(a,b,c) SQLITE_OK #define lockTable(a,b,c) SQLITE_OK #define unlockAllTables(a) - #define restoreOrClearCursorPosition(a,b) SQLITE_OK - #define saveAllCursors(a,b,c) SQLITE_OK - #else -static void releasePage(MemPage *pPage); - -/* -** Save the current cursor position in the variables BtCursor.nKey -** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK. -*/ -static int saveCursorPosition(BtCursor *pCur){ - int rc; - - assert( CURSOR_VALID==pCur->eState ); - assert( 0==pCur->pKey ); - - rc = sqlite3BtreeKeySize(pCur, &pCur->nKey); - - /* If this is an intKey table, then the above call to BtreeKeySize() - ** stores the integer key in pCur->nKey. In this case this value is - ** all that is required. Otherwise, if pCur is not open on an intKey - ** table, then malloc space for and store the pCur->nKey bytes of key - ** data. - */ - if( rc==SQLITE_OK && 0==pCur->pPage->intKey){ - void *pKey = sqliteMalloc((int)pCur->nKey); - if( pKey ){ - rc = sqlite3BtreeKey(pCur, 0, (u32)pCur->nKey, pKey); - if( rc==SQLITE_OK ){ - pCur->pKey = pKey; - }else{ - sqliteFree(pKey); - } - }else{ - rc = SQLITE_NOMEM; - } - } - assert( !pCur->pPage->intKey || !pCur->pKey ); - - if( rc==SQLITE_OK ){ - releasePage(pCur->pPage); - pCur->pPage = 0; - pCur->eState = CURSOR_REQUIRESEEK; - } - - return rc; -} - -/* -** Save the positions of all cursors except pExcept open on the table -** with root-page iRoot. Usually, this is called just before cursor -** pExcept is used to modify the table (BtreeDelete() or BtreeInsert()). -*/ -static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){ - BtCursor *p; - if( sqlite3ThreadDataReadOnly()->useSharedData ){ - for(p=pBt->pCursor; p; p=p->pNext){ - if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) && - p->eState==CURSOR_VALID ){ - int rc = saveCursorPosition(p); - if( SQLITE_OK!=rc ){ - return rc; - } - } - } - } - return SQLITE_OK; -} - -/* -** Restore the cursor to the position it was in (or as close to as possible) -** when saveCursorPosition() was called. Note that this call deletes the -** saved position info stored by saveCursorPosition(), so there can be -** at most one effective restoreOrClearCursorPosition() call after each -** saveCursorPosition(). -** -** If the second argument argument - doSeek - is false, then instead of -** returning the cursor to it's saved position, any saved position is deleted -** and the cursor state set to CURSOR_INVALID. -*/ -static int restoreOrClearCursorPositionX(BtCursor *pCur, int doSeek){ - int rc = SQLITE_OK; - assert( sqlite3ThreadDataReadOnly()->useSharedData ); - assert( pCur->eState==CURSOR_REQUIRESEEK ); - pCur->eState = CURSOR_INVALID; - if( doSeek ){ - rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, &pCur->skip); - } - if( rc==SQLITE_OK ){ - sqliteFree(pCur->pKey); - pCur->pKey = 0; - assert( CURSOR_VALID==pCur->eState || CURSOR_INVALID==pCur->eState ); - } - return rc; -} - -#define restoreOrClearCursorPosition(p,x) \ - (p->eState==CURSOR_REQUIRESEEK?restoreOrClearCursorPositionX(p,x):SQLITE_OK) /* ** Query to see if btree handle p may obtain a lock of type eLock @@ -747,6 +647,98 @@ static void unlockAllTables(Btree *p){ } #endif /* SQLITE_OMIT_SHARED_CACHE */ +static void releasePage(MemPage *pPage); /* Forward reference */ + +/* +** Save the current cursor position in the variables BtCursor.nKey +** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK. +*/ +static int saveCursorPosition(BtCursor *pCur){ + int rc; + + assert( CURSOR_VALID==pCur->eState ); + assert( 0==pCur->pKey ); + + rc = sqlite3BtreeKeySize(pCur, &pCur->nKey); + + /* If this is an intKey table, then the above call to BtreeKeySize() + ** stores the integer key in pCur->nKey. In this case this value is + ** all that is required. Otherwise, if pCur is not open on an intKey + ** table, then malloc space for and store the pCur->nKey bytes of key + ** data. + */ + if( rc==SQLITE_OK && 0==pCur->pPage->intKey){ + void *pKey = sqliteMalloc((int)pCur->nKey); + if( pKey ){ + rc = sqlite3BtreeKey(pCur, 0, (u32)pCur->nKey, pKey); + if( rc==SQLITE_OK ){ + pCur->pKey = pKey; + }else{ + sqliteFree(pKey); + } + }else{ + rc = SQLITE_NOMEM; + } + } + assert( !pCur->pPage->intKey || !pCur->pKey ); + + if( rc==SQLITE_OK ){ + releasePage(pCur->pPage); + pCur->pPage = 0; + pCur->eState = CURSOR_REQUIRESEEK; + } + + return rc; +} + +/* +** Save the positions of all cursors except pExcept open on the table +** with root-page iRoot. Usually, this is called just before cursor +** pExcept is used to modify the table (BtreeDelete() or BtreeInsert()). +*/ +static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){ + BtCursor *p; + for(p=pBt->pCursor; p; p=p->pNext){ + if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) && + p->eState==CURSOR_VALID ){ + int rc = saveCursorPosition(p); + if( SQLITE_OK!=rc ){ + return rc; + } + } + } + return SQLITE_OK; +} + +/* +** Restore the cursor to the position it was in (or as close to as possible) +** when saveCursorPosition() was called. Note that this call deletes the +** saved position info stored by saveCursorPosition(), so there can be +** at most one effective restoreOrClearCursorPosition() call after each +** saveCursorPosition(). +** +** If the second argument argument - doSeek - is false, then instead of +** returning the cursor to it's saved position, any saved position is deleted +** and the cursor state set to CURSOR_INVALID. +*/ +static int restoreOrClearCursorPositionX(BtCursor *pCur, int doSeek){ + int rc = SQLITE_OK; + assert( pCur->eState==CURSOR_REQUIRESEEK ); + pCur->eState = CURSOR_INVALID; + if( doSeek ){ + rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, &pCur->skip); + } + if( rc==SQLITE_OK ){ + sqliteFree(pCur->pKey); + pCur->pKey = 0; + assert( CURSOR_VALID==pCur->eState || CURSOR_INVALID==pCur->eState ); + } + return rc; +} + +#define restoreOrClearCursorPosition(p,x) \ + (p->eState==CURSOR_REQUIRESEEK?restoreOrClearCursorPositionX(p,x):SQLITE_OK) + #ifndef SQLITE_OMIT_AUTOVACUUM /* ** These macros define the location of the pointer-map entry for a @@ -1048,91 +1040,6 @@ static int ptrmapPutOvfl(MemPage *pPage, int iCell){ #endif -/* -** Do sanity checking on a page. Throw an exception if anything is -** not right. -** -** This routine is used for internal error checking only. It is omitted -** from most builds. -*/ -#if defined(BTREE_DEBUG) && !defined(NDEBUG) && 0 -static void _pageIntegrity(MemPage *pPage){ - int usableSize; - u8 *data; - int i, j, idx, c, pc, hdr, nFree; - int cellOffset; - int nCell, cellLimit; - u8 *used; - - used = sqliteMallocRaw( pPage->pBt->pageSize ); - if( used==0 ) return; - usableSize = pPage->pBt->usableSize; - assert( pPage->aData==&((unsigned char*)pPage)[-pPage->pBt->pageSize] ); - hdr = pPage->hdrOffset; - assert( hdr==(pPage->pgno==1 ? 100 : 0) ); - assert( pPage->pgno==sqlite3pager_pagenumber(pPage->aData) ); - c = pPage->aData[hdr]; - if( pPage->isInit ){ - assert( pPage->leaf == ((c & PTF_LEAF)!=0) ); - assert( pPage->zeroData == ((c & PTF_ZERODATA)!=0) ); - assert( pPage->leafData == ((c & PTF_LEAFDATA)!=0) ); - assert( pPage->intKey == ((c & (PTF_INTKEY|PTF_LEAFDATA))!=0) ); - assert( pPage->hasData == - !(pPage->zeroData || (!pPage->leaf && pPage->leafData)) ); - assert( pPage->cellOffset==pPage->hdrOffset+12-4*pPage->leaf ); - assert( pPage->nCell = get2byte(&pPage->aData[hdr+3]) ); - } - data = pPage->aData; - memset(used, 0, usableSize); - for(i=0; ileaf*4; i++) used[i] = 1; - nFree = 0; - pc = get2byte(&data[hdr+1]); - while( pc ){ - int size; - assert( pc>0 && pcisInit==0 - || pPage->nFree==nFree+data[hdr+7]+cellLimit-(cellOffset+2*nCell) ); - cellOffset = pPage->cellOffset; - for(i=0; i0 && pcisInit = 1; - pageIntegrity(pPage); return SQLITE_OK; } @@ -1470,7 +1376,6 @@ static void zeroPage(MemPage *pPage, int flags){ pPage->idxShift = 0; pPage->nCell = 0; pPage->isInit = 1; - pageIntegrity(pPage); } /* @@ -1591,9 +1496,9 @@ int sqlite3BtreeOpen( */ #if !defined(SQLITE_OMIT_SHARED_CACHE) || !defined(SQLITE_OMIT_AUTOVACUUM) #ifdef SQLITE_OMIT_MEMORYDB - const int isMemdb = !zFilename; + const int isMemdb = 0; #else - const int isMemdb = !zFilename || (strcmp(zFilename, ":memory:")?0:1); + const int isMemdb = zFilename && !strcmp(zFilename, ":memory:"); #endif #endif @@ -1645,8 +1550,13 @@ int sqlite3BtreeOpen( return SQLITE_NOMEM; } rc = sqlite3pager_open(&pBt->pPager, zFilename, EXTRA_SIZE, flags); + if( rc==SQLITE_OK ){ + rc = sqlite3pager_read_fileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader); + } if( rc!=SQLITE_OK ){ - if( pBt->pPager ) sqlite3pager_close(pBt->pPager); + if( pBt->pPager ){ + sqlite3pager_close(pBt->pPager); + } sqliteFree(pBt); sqliteFree(p); *ppBtree = 0; @@ -1659,7 +1569,6 @@ int sqlite3BtreeOpen( pBt->pCursor = 0; pBt->pPage1 = 0; pBt->readOnly = sqlite3pager_isreadonly(pBt->pPager); - sqlite3pager_read_fileheader(pBt->pPager, sizeof(zDbHeader), zDbHeader); pBt->pageSize = get2byte(&zDbHeader[16]); if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){ @@ -2022,13 +1931,15 @@ static int lockBtreeWithRetry(Btree *pRef){ */ static void unlockBtreeIfUnused(BtShared *pBt){ if( pBt->inTransaction==TRANS_NONE && pBt->pCursor==0 && pBt->pPage1!=0 ){ - if( pBt->pPage1->aData==0 ){ - MemPage *pPage = pBt->pPage1; - pPage->aData = &((u8*)pPage)[-pBt->pageSize]; - pPage->pBt = pBt; - pPage->pgno = 1; + if( sqlite3pager_refcount(pBt->pPager)>=1 ){ + if( pBt->pPage1->aData==0 ){ + MemPage *pPage = pBt->pPage1; + pPage->aData = &((u8*)pPage)[-pBt->pageSize]; + pPage->pBt = pBt; + pPage->pgno = 1; + } + releasePage(pBt->pPage1); } - releasePage(pBt->pPage1); pBt->pPage1 = 0; pBt->inStmt = 0; } @@ -2367,7 +2278,7 @@ static int autoVacuumCommit(BtShared *pBt, Pgno *nTrunc){ MemPage *pFreeMemPage = 0; /* "" */ #ifndef NDEBUG - int nRef = *sqlite3pager_stats(pPager); + int nRef = sqlite3pager_refcount(pPager); #endif assert( pBt->autoVacuum ); @@ -2475,7 +2386,7 @@ static int autoVacuumCommit(BtShared *pBt, Pgno *nTrunc){ assert( finSize!=PENDING_BYTE_PAGE(pBt) ); autovacuum_out: - assert( nRef==*sqlite3pager_stats(pPager) ); + assert( nRef==sqlite3pager_refcount(pPager) ); if( rc!=SQLITE_OK ){ sqlite3pager_rollback(pPager); } @@ -2548,7 +2459,7 @@ static int countWriteCursors(BtShared *pBt){ } #endif -#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) +#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) /* ** Print debugging information about all cursors to standard output. */ @@ -2778,7 +2689,7 @@ int sqlite3BtreeCursor( if( pBt->readOnly ){ return SQLITE_READONLY; } - if( checkReadLocks(pBt, iTable, 0) ){ + if( checkReadLocks(p, iTable, 0) ){ return SQLITE_LOCKED; } } @@ -2980,7 +2891,6 @@ static int getPayload( assert( pCur->eState==CURSOR_VALID ); pBt = pCur->pBtree->pBt; pPage = pCur->pPage; - pageIntegrity(pPage); assert( pCur->idx>=0 && pCur->idxnCell ); getCellInfo(pCur); aPayload = pCur->info.pCell + pCur->info.nHeader; @@ -3118,7 +3028,6 @@ static const unsigned char *fetchPayload( assert( pCur!=0 && pCur->pPage!=0 ); assert( pCur->eState==CURSOR_VALID ); pPage = pCur->pPage; - pageIntegrity(pPage); assert( pCur->idx>=0 && pCur->idxnCell ); getCellInfo(pCur); aPayload = pCur->info.pCell; @@ -3180,7 +3089,6 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){ assert( pCur->eState==CURSOR_VALID ); rc = getAndInitPage(pBt, newPgno, &pNewPage, pCur->pPage); if( rc ) return rc; - pageIntegrity(pNewPage); pNewPage->idxParent = pCur->idx; pOldPage = pCur->pPage; pOldPage->idxShift = 0; @@ -3228,10 +3136,8 @@ static void moveToParent(BtCursor *pCur){ pPage = pCur->pPage; assert( pPage!=0 ); assert( !isRootPage(pPage) ); - pageIntegrity(pPage); pParent = pPage->pParent; assert( pParent!=0 ); - pageIntegrity(pParent); idxParent = pPage->idxParent; sqlite3pager_ref(pParent->aData); releasePage(pPage); @@ -3261,7 +3167,6 @@ static int moveToRoot(BtCursor *pCur){ return rc; } releasePage(pCur->pPage); - pageIntegrity(pRoot); pCur->pPage = pRoot; } pCur->idx = 0; @@ -3405,7 +3310,7 @@ int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){ assert( pCur->pPage->nCell==0 ); return SQLITE_OK; } - for(;;){ + for(;;){ int lwr, upr; Pgno chldPg; MemPage *pPage = pCur->pPage; @@ -3415,7 +3320,6 @@ int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){ if( !pPage->intKey && pKey==0 ){ return SQLITE_CORRUPT_BKPT; } - pageIntegrity(pPage); while( lwr<=upr ){ void *pCellKey; i64 nCellKey; @@ -3668,14 +3572,14 @@ static int allocatePage( int rc; int n; /* Number of pages on the freelist */ int k; /* Number of leaves on the trunk of the freelist */ + MemPage *pTrunk = 0; + MemPage *pPrevTrunk = 0; pPage1 = pBt->pPage1; n = get4byte(&pPage1->aData[36]); if( n>0 ){ /* There are pages on the freelist. Reuse one of those pages. */ - MemPage *pTrunk = 0; Pgno iTrunk; - MemPage *pPrevTrunk = 0; u8 searchList = 0; /* If the free-list must be searched for 'nearby' */ /* If the 'exact' parameter was true and a query of the pointer-map @@ -3716,16 +3620,8 @@ static int allocatePage( } rc = getPage(pBt, iTrunk, &pTrunk); if( rc ){ - releasePage(pPrevTrunk); - return rc; - } - - /* TODO: This should move to after the loop? */ - rc = sqlite3pager_write(pTrunk->aData); - if( rc ){ - releasePage(pTrunk); - releasePage(pPrevTrunk); - return rc; + pTrunk = 0; + goto end_allocate_page; } k = get4byte(&pTrunk->aData[4]); @@ -3734,6 +3630,10 @@ static int allocatePage( ** So extract the trunk page itself and use it as the newly ** allocated page */ assert( pPrevTrunk==0 ); + rc = sqlite3pager_write(pTrunk->aData); + if( rc ){ + goto end_allocate_page; + } *pPgno = iTrunk; memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); *ppPage = pTrunk; @@ -3741,7 +3641,8 @@ static int allocatePage( TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); }else if( k>pBt->usableSize/4 - 8 ){ /* Value of k is out of range. Database corruption */ - return SQLITE_CORRUPT_BKPT; + rc = SQLITE_CORRUPT_BKPT; + goto end_allocate_page; #ifndef SQLITE_OMIT_AUTOVACUUM }else if( searchList && nearby==iTrunk ){ /* The list is being searched and this trunk page is the page @@ -3750,6 +3651,10 @@ static int allocatePage( assert( *pPgno==iTrunk ); *ppPage = pTrunk; searchList = 0; + rc = sqlite3pager_write(pTrunk->aData); + if( rc ){ + goto end_allocate_page; + } if( k==0 ){ if( !pPrevTrunk ){ memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); @@ -3765,26 +3670,26 @@ static int allocatePage( Pgno iNewTrunk = get4byte(&pTrunk->aData[8]); rc = getPage(pBt, iNewTrunk, &pNewTrunk); if( rc!=SQLITE_OK ){ - releasePage(pTrunk); - releasePage(pPrevTrunk); - return rc; + goto end_allocate_page; } rc = sqlite3pager_write(pNewTrunk->aData); if( rc!=SQLITE_OK ){ releasePage(pNewTrunk); - releasePage(pTrunk); - releasePage(pPrevTrunk); - return rc; + goto end_allocate_page; } memcpy(&pNewTrunk->aData[0], &pTrunk->aData[0], 4); put4byte(&pNewTrunk->aData[4], k-1); memcpy(&pNewTrunk->aData[8], &pTrunk->aData[12], (k-1)*4); + releasePage(pNewTrunk); if( !pPrevTrunk ){ put4byte(&pPage1->aData[32], iNewTrunk); }else{ + rc = sqlite3pager_write(pPrevTrunk->aData); + if( rc ){ + goto end_allocate_page; + } put4byte(&pPrevTrunk->aData[0], iNewTrunk); } - releasePage(pNewTrunk); } pTrunk = 0; TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); @@ -3794,6 +3699,10 @@ static int allocatePage( int closest; Pgno iPage; unsigned char *aData = pTrunk->aData; + rc = sqlite3pager_write(aData); + if( rc ){ + goto end_allocate_page; + } if( nearby>0 ){ int i, dist; closest = 0; @@ -3837,8 +3746,8 @@ static int allocatePage( } } releasePage(pPrevTrunk); + pPrevTrunk = 0; }while( searchList ); - releasePage(pTrunk); }else{ /* There are no pages on the freelist, so create a new page at the ** end of the file */ @@ -3867,6 +3776,10 @@ static int allocatePage( } assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); + +end_allocate_page: + releasePage(pTrunk); + releasePage(pPrevTrunk); return rc; } @@ -4267,7 +4180,6 @@ static int insertCell( put2byte(&data[ins], idx); put2byte(&data[hdr+3], pPage->nCell); pPage->idxShift = 1; - pageIntegrity(pPage); #ifndef SQLITE_OMIT_AUTOVACUUM if( pPage->pBt->autoVacuum ){ /* The cell may contain a pointer to an overflow page. If so, write @@ -5007,8 +4919,6 @@ static int balance_nonroot(MemPage *pPage){ ** But the parent page will always be initialized. */ assert( pParent->isInit ); - /* assert( pPage->isInit ); // No! pPage might have been added to freelist */ - /* pageIntegrity(pPage); // No! pPage might have been added to freelist */ rc = balance(pParent, 0); /* @@ -5215,27 +5125,35 @@ static int balance(MemPage *pPage, int insert){ /* ** This routine checks all cursors that point to table pgnoRoot. -** If any of those cursors other than pExclude were opened with -** wrFlag==0 then this routine returns SQLITE_LOCKED. If all -** cursors that point to pgnoRoot were opened with wrFlag==1 -** then this routine returns SQLITE_OK. +** If any of those cursors were opened with wrFlag==0 in a different +** database connection (a database connection that shares the pager +** cache with the current connection) and that other connection +** is not in the ReadUncommmitted state, then this routine returns +** SQLITE_LOCKED. ** ** In addition to checking for read-locks (where a read-lock ** means a cursor opened with wrFlag==0) this routine also moves -** all cursors other than pExclude so that they are pointing to the -** first Cell on root page. This is necessary because an insert +** all cursors write cursors so that they are pointing to the +** first Cell on the root page. This is necessary because an insert ** or delete might change the number of cells on a page or delete ** a page entirely and we do not want to leave any cursors ** pointing to non-existant pages or cells. */ -static int checkReadLocks(BtShared *pBt, Pgno pgnoRoot, BtCursor *pExclude){ +static int checkReadLocks(Btree *pBtree, Pgno pgnoRoot, BtCursor *pExclude){ BtCursor *p; + BtShared *pBt = pBtree->pBt; + sqlite3 *db = pBtree->pSqlite; for(p=pBt->pCursor; p; p=p->pNext){ - u32 flags = (p->pBtree->pSqlite ? p->pBtree->pSqlite->flags : 0); - if( p->pgnoRoot!=pgnoRoot || p==pExclude ) continue; - if( p->wrFlag==0 && flags&SQLITE_ReadUncommitted ) continue; - if( p->wrFlag==0 ) return SQLITE_LOCKED; - if( p->pPage->pgno!=p->pgnoRoot ){ + if( p==pExclude ) continue; + if( p->eState!=CURSOR_VALID ) continue; + if( p->pgnoRoot!=pgnoRoot ) continue; + if( p->wrFlag==0 ){ + sqlite3 *dbOther = p->pBtree->pSqlite; + if( dbOther==0 || + (dbOther!=db && (dbOther->flags & SQLITE_ReadUncommitted)==0) ){ + return SQLITE_LOCKED; + } + }else if( p->pPage->pgno!=p->pgnoRoot ){ moveToRoot(p); } } @@ -5272,7 +5190,7 @@ int sqlite3BtreeInsert( if( !pCur->wrFlag ){ return SQLITE_PERM; /* Cursor not open for writing */ } - if( checkReadLocks(pBt, pCur->pgnoRoot, pCur) ){ + if( checkReadLocks(pCur->pBtree, pCur->pgnoRoot, pCur) ){ return SQLITE_LOCKED; /* The table pCur points to has a read lock */ } @@ -5354,7 +5272,7 @@ int sqlite3BtreeDelete(BtCursor *pCur){ if( !pCur->wrFlag ){ return SQLITE_PERM; /* Did not open this cursor for writing */ } - if( checkReadLocks(pBt, pCur->pgnoRoot, pCur) ){ + if( checkReadLocks(pCur->pBtree, pCur->pgnoRoot, pCur) ){ return SQLITE_LOCKED; /* The table pCur points to has a read lock */ } @@ -5393,8 +5311,8 @@ int sqlite3BtreeDelete(BtCursor *pCur){ BtCursor leafCur; unsigned char *pNext; int szNext = 0; /* The compiler warning is wrong: szNext is always - ** initialized before use. Adding an extra initialization - ** to silence the compiler slows down the code. */ + ** initialized before use. Adding an extra initialization + ** to silence the compiler slows down the code. */ int notUsed; unsigned char *tempCell = 0; assert( !pPage->leafData ); @@ -5631,25 +5549,13 @@ cleardatabasepage_out: */ int sqlite3BtreeClearTable(Btree *p, int iTable){ int rc; - BtCursor *pCur; BtShared *pBt = p->pBt; - sqlite3 *db = p->pSqlite; if( p->inTrans!=TRANS_WRITE ){ return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR; } - - /* If this connection is not in read-uncommitted mode and currently has - ** a read-cursor open on the table being cleared, return SQLITE_LOCKED. - */ - if( 0==db || 0==(db->flags&SQLITE_ReadUncommitted) ){ - for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ - if( pCur->pBtree==p && pCur->pgnoRoot==(Pgno)iTable ){ - if( 0==pCur->wrFlag ){ - return SQLITE_LOCKED; - } - moveToRoot(pCur); - } - } + rc = checkReadLocks(p, iTable, 0); + if( rc ){ + return rc; } /* Save the position of all cursors open on this table */ @@ -5969,7 +5875,7 @@ int sqlite3BtreePageDump(Btree *p, int pgno, int recursive){ } #endif -#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) +#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) /* ** Fill aResult[] with information about the entry and page that the ** cursor is pointing to. @@ -5984,6 +5890,7 @@ int sqlite3BtreePageDump(Btree *p, int pgno, int recursive){ ** aResult[7] = Header size in bytes ** aResult[8] = Local payload size ** aResult[9] = Parent page number +** aResult[10]= Page number of the first overflow page ** ** This routine is used for testing and debugging only. */ @@ -5997,14 +5904,12 @@ int sqlite3BtreeCursorInfo(BtCursor *pCur, int *aResult, int upCnt){ return rc; } - pageIntegrity(pPage); assert( pPage->isInit ); getTempCursor(pCur, &tmpCur); while( upCnt-- ){ moveToParent(&tmpCur); } pPage = tmpCur.pPage; - pageIntegrity(pPage); aResult[0] = sqlite3pager_pagenumber(pPage->aData); assert( aResult[0]==pPage->pgno ); aResult[1] = tmpCur.idx; @@ -6034,6 +5939,11 @@ int sqlite3BtreeCursorInfo(BtCursor *pCur, int *aResult, int upCnt){ }else{ aResult[9] = pPage->pParent->pgno; } + if( tmpCur.info.iOverflow ){ + aResult[10] = get4byte(&tmpCur.info.pCell[tmpCur.info.iOverflow]); + }else{ + aResult[10] = 0; + } releaseTempCursor(&tmpCur); return SQLITE_OK; } @@ -6054,10 +5964,12 @@ Pager *sqlite3BtreePager(Btree *p){ typedef struct IntegrityCk IntegrityCk; struct IntegrityCk { BtShared *pBt; /* The tree being checked out */ - Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */ - int nPage; /* Number of pages in the database */ - int *anRef; /* Number of times each page is referenced */ - char *zErrMsg; /* An error message. NULL of no errors seen. */ + Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */ + int nPage; /* Number of pages in the database */ + int *anRef; /* Number of times each page is referenced */ + int mxErr; /* Stop accumulating errors when this reaches zero */ + char *zErrMsg; /* An error message. NULL if no errors seen. */ + int nErr; /* Number of messages written to zErrMsg so far */ }; #ifndef SQLITE_OMIT_INTEGRITY_CHECK @@ -6072,6 +5984,9 @@ static void checkAppendMsg( ){ va_list ap; char *zMsg2; + if( !pCheck->mxErr ) return; + pCheck->mxErr--; + pCheck->nErr++; va_start(ap, zFormat); zMsg2 = sqlite3VMPrintf(zFormat, ap); va_end(ap); @@ -6155,7 +6070,7 @@ static void checkList( int i; int expected = N; int iFirst = iPage; - while( N-- > 0 ){ + while( N-- > 0 && pCheck->mxErr ){ unsigned char *pOvfl; if( iPage<1 ){ checkAppendMsg(pCheck, zContext, @@ -6267,7 +6182,7 @@ static int checkTreePage( /* Check out all the cells. */ depth = 0; - for(i=0; inCell; i++){ + for(i=0; inCell && pCheck->mxErr; i++){ u8 *pCell; int sz; CellInfo info; @@ -6382,19 +6297,28 @@ static int checkTreePage( ** and a pointer to that error message is returned. The calling function ** is responsible for freeing the error message when it is done. */ -char *sqlite3BtreeIntegrityCheck(Btree *p, int *aRoot, int nRoot){ +char *sqlite3BtreeIntegrityCheck( + Btree *p, /* The btree to be checked */ + int *aRoot, /* An array of root pages numbers for individual trees */ + int nRoot, /* Number of entries in aRoot[] */ + int mxErr, /* Stop reporting errors after this many */ + int *pnErr /* Write number of errors seen to this variable */ +){ int i; int nRef; IntegrityCk sCheck; BtShared *pBt = p->pBt; - nRef = *sqlite3pager_stats(pBt->pPager); + nRef = sqlite3pager_refcount(pBt->pPager); if( lockBtreeWithRetry(p)!=SQLITE_OK ){ return sqliteStrDup("Unable to acquire a read lock on the database"); } sCheck.pBt = pBt; sCheck.pPager = pBt->pPager; sCheck.nPage = sqlite3pager_pagecount(sCheck.pPager); + sCheck.mxErr = mxErr; + sCheck.nErr = 0; + *pnErr = 0; if( sCheck.nPage==0 ){ unlockBtreeIfUnused(pBt); return 0; @@ -6402,6 +6326,7 @@ char *sqlite3BtreeIntegrityCheck(Btree *p, int *aRoot, int nRoot){ sCheck.anRef = sqliteMallocRaw( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) ); if( !sCheck.anRef ){ unlockBtreeIfUnused(pBt); + *pnErr = 1; return sqlite3MPrintf("Unable to malloc %d bytes", (sCheck.nPage+1)*sizeof(sCheck.anRef[0])); } @@ -6419,7 +6344,7 @@ char *sqlite3BtreeIntegrityCheck(Btree *p, int *aRoot, int nRoot){ /* Check all the tables. */ - for(i=0; iautoVacuum && aRoot[i]>1 ){ @@ -6431,7 +6356,7 @@ char *sqlite3BtreeIntegrityCheck(Btree *p, int *aRoot, int nRoot){ /* Make sure every page in the file is referenced */ - for(i=1; i<=sCheck.nPage; i++){ + for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){ #ifdef SQLITE_OMIT_AUTOVACUUM if( sCheck.anRef[i]==0 ){ checkAppendMsg(&sCheck, 0, "Page %d is never used", i); @@ -6454,16 +6379,17 @@ char *sqlite3BtreeIntegrityCheck(Btree *p, int *aRoot, int nRoot){ /* Make sure this analysis did not leave any unref() pages */ unlockBtreeIfUnused(pBt); - if( nRef != *sqlite3pager_stats(pBt->pPager) ){ + if( nRef != sqlite3pager_refcount(pBt->pPager) ){ checkAppendMsg(&sCheck, 0, "Outstanding page count goes from %d to %d during this analysis", - nRef, *sqlite3pager_stats(pBt->pPager) + nRef, sqlite3pager_refcount(pBt->pPager) ); } /* Clean up and report errors. */ sqliteFree(sCheck.anRef); + *pnErr = sCheck.nErr; return sCheck.zErrMsg; } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ @@ -6522,7 +6448,6 @@ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ rc = sqlite3pager_get(pBtFrom->pPager, i, &pPage); if( rc ) break; rc = sqlite3pager_overwrite(pBtTo->pPager, i, pPage); - if( rc ) break; sqlite3pager_unref(pPage); } for(i=nPage+1; rc==SQLITE_OK && i<=nToPage; i++){ @@ -6558,6 +6483,13 @@ int sqlite3BtreeIsInStmt(Btree *p){ return (p->pBt && p->pBt->inStmt); } +/* +** Return non-zero if a read (or write) transaction is active. +*/ +int sqlite3BtreeIsInReadTrans(Btree *p){ + return (p && (p->inTrans!=TRANS_NONE)); +} + /* ** This call is a no-op if no write-transaction is currently active on pBt. ** diff --git a/dlls/sqlite/sqlite-source/btree.h b/dlls/sqlite/sqlite-source/btree.h index 4faf23ef..2f573e27 100644 --- a/dlls/sqlite/sqlite-source/btree.h +++ b/dlls/sqlite/sqlite-source/btree.h @@ -75,6 +75,7 @@ int sqlite3BtreeRollbackStmt(Btree*); int sqlite3BtreeCreateTable(Btree*, int*, int flags); int sqlite3BtreeIsInTrans(Btree*); int sqlite3BtreeIsInStmt(Btree*); +int sqlite3BtreeIsInReadTrans(Btree*); int sqlite3BtreeSync(Btree*, const char *zMaster); void *sqlite3BtreeSchema(Btree *, int, void(*)(void *)); int sqlite3BtreeSchemaLocked(Btree *); @@ -130,7 +131,7 @@ const void *sqlite3BtreeDataFetch(BtCursor*, int *pAmt); int sqlite3BtreeDataSize(BtCursor*, u32 *pSize); int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*); -char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot); +char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*); struct Pager *sqlite3BtreePager(Btree*); diff --git a/dlls/sqlite/sqlite-source/build.c b/dlls/sqlite/sqlite-source/build.c index 1fc80eeb..b2da7fb5 100644 --- a/dlls/sqlite/sqlite-source/build.c +++ b/dlls/sqlite/sqlite-source/build.c @@ -164,6 +164,12 @@ void sqlite3FinishCoding(Parse *pParse){ sqlite3VdbeAddOp(v, OP_Transaction, iDb, (mask & pParse->writeMask)!=0); sqlite3VdbeAddOp(v, OP_VerifyCookie, iDb, pParse->cookieValue[iDb]); } +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( pParse->pVirtualLock ){ + char *vtab = (char *)pParse->pVirtualLock->pVtab; + sqlite3VdbeOp3(v, OP_VBegin, 0, 0, vtab, P3_VTAB); + } +#endif /* Once all the cookies have been verified and transactions opened, ** obtain the required table-locks. This is a no-op unless the @@ -533,6 +539,7 @@ void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ #ifndef SQLITE_OMIT_CHECK sqlite3ExprDelete(pTable->pCheck); #endif + sqlite3VtabClear(pTable); sqliteFree(pTable); } @@ -710,6 +717,7 @@ void sqlite3StartTable( Token *pName2, /* Second part of the name of the table or view */ int isTemp, /* True if this is a TEMP table */ int isView, /* True if this is a VIEW */ + int isVirtual, /* True if this is a VIRTUAL table */ int noErr /* Do nothing if table already exists */ ){ Table *pTable; @@ -773,7 +781,7 @@ void sqlite3StartTable( code = SQLITE_CREATE_TABLE; } } - if( sqlite3AuthCheck(pParse, code, zName, 0, zDb) ){ + if( !isVirtual && sqlite3AuthCheck(pParse, code, zName, 0, zDb) ){ goto begin_table_error; } } @@ -781,22 +789,28 @@ void sqlite3StartTable( /* Make sure the new table name does not collide with an existing ** index or table name in the same database. Issue an error message if - ** it does. + ** it does. The exception is if the statement being parsed was passed + ** to an sqlite3_declare_vtab() call. In that case only the column names + ** and types will be used, so there is no need to test for namespace + ** collisions. */ - if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ - goto begin_table_error; - } - pTable = sqlite3FindTable(db, zName, db->aDb[iDb].zName); - if( pTable ){ - if( !noErr ){ - sqlite3ErrorMsg(pParse, "table %T already exists", pName); + if( !IN_DECLARE_VTAB ){ + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + goto begin_table_error; + } + pTable = sqlite3FindTable(db, zName, db->aDb[iDb].zName); + if( pTable ){ + if( !noErr ){ + sqlite3ErrorMsg(pParse, "table %T already exists", pName); + } + goto begin_table_error; + } + if( sqlite3FindIndex(db, zName, 0)!=0 && (iDb==0 || !db->init.busy) ){ + sqlite3ErrorMsg(pParse, "there is already an index named %s", zName); + goto begin_table_error; } - goto begin_table_error; - } - if( sqlite3FindIndex(db, zName, 0)!=0 && (iDb==0 || !db->init.busy) ){ - sqlite3ErrorMsg(pParse, "there is already an index named %s", zName); - goto begin_table_error; } + pTable = sqliteMalloc( sizeof(Table) ); if( pTable==0 ){ pParse->rc = SQLITE_NOMEM; @@ -804,10 +818,7 @@ void sqlite3StartTable( goto begin_table_error; } pTable->zName = zName; - pTable->nCol = 0; - pTable->aCol = 0; pTable->iPKey = -1; - pTable->pIndex = 0; pTable->pSchema = db->aDb[iDb].pSchema; pTable->nRef = 1; if( pParse->pNewTable ) sqlite3DeleteTable(db, pParse->pNewTable); @@ -836,6 +847,12 @@ void sqlite3StartTable( int fileFormat; sqlite3BeginWriteOperation(pParse, 0, iDb); +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( isVirtual ){ + sqlite3VdbeAddOp(v, OP_VBegin, 0, 0); + } +#endif + /* If the file format and encoding in the database have not been set, ** set them now. */ @@ -843,7 +860,7 @@ void sqlite3StartTable( lbl = sqlite3VdbeMakeLabel(v); sqlite3VdbeAddOp(v, OP_If, 0, lbl); fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ? - 1 : SQLITE_DEFAULT_FILE_FORMAT; + 1 : SQLITE_MAX_FILE_FORMAT; sqlite3VdbeAddOp(v, OP_Integer, fileFormat, 0); sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1); sqlite3VdbeAddOp(v, OP_Integer, ENC(db), 0); @@ -858,8 +875,8 @@ void sqlite3StartTable( ** The rowid value is needed by the code that sqlite3EndTable will ** generate. */ -#ifndef SQLITE_OMIT_VIEW - if( isView ){ +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) + if( isView || isVirtual ){ sqlite3VdbeAddOp(v, OP_Integer, 0, 0); }else #endif @@ -1060,8 +1077,12 @@ void sqlite3AddDefaultValue(Parse *pParse, Expr *pExpr){ sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant", pCol->zName); }else{ + Expr *pCopy; sqlite3ExprDelete(pCol->pDflt); - pCol->pDflt = sqlite3ExprDup(pExpr); + pCol->pDflt = pCopy = sqlite3ExprDup(pExpr); + if( pCopy ){ + sqlite3TokenCopy(&pCopy->span, &pExpr->span); + } } } sqlite3ExprDelete(pExpr); @@ -1095,7 +1116,7 @@ void sqlite3AddPrimaryKey( Table *pTab = pParse->pNewTable; char *zType = 0; int iCol = -1, i; - if( pTab==0 ) goto primary_key_exit; + if( pTab==0 || IN_DECLARE_VTAB ) goto primary_key_exit; if( pTab->hasPrimKey ){ sqlite3ErrorMsg(pParse, "table \"%s\" has more than one primary key", pTab->zName); @@ -1150,7 +1171,7 @@ void sqlite3AddCheckConstraint( ){ #ifndef SQLITE_OMIT_CHECK Table *pTab = pParse->pNewTable; - if( pTab ){ + if( pTab && !IN_DECLARE_VTAB ){ /* The CHECK expression must be duplicated so that tokens refer ** to malloced space and not the (ephemeral) text of the CREATE TABLE ** statement */ @@ -1201,6 +1222,10 @@ void sqlite3AddCollateType(Parse *pParse, const char *zType, int nType){ ** If no versions of the requested collations sequence are available, or ** another error occurs, NULL is returned and an error message written into ** pParse. +** +** This routine is a wrapper around sqlite3FindCollSeq(). This routine +** invokes the collation factory if the named collation cannot be found +** and generates an error message. */ CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName){ sqlite3 *db = pParse->db; @@ -1372,7 +1397,7 @@ void sqlite3EndTable( assert( !db->init.busy || !pSelect ); - iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema); + iDb = sqlite3SchemaToIndex(db, p->pSchema); #ifndef SQLITE_OMIT_CHECK /* Resolve names in all CHECK constraint expressions. @@ -1569,7 +1594,8 @@ void sqlite3CreateView( Token *pName1, /* The token that holds the name of the view */ Token *pName2, /* The token that holds the name of the view */ Select *pSelect, /* A SELECT statement that will become the new view */ - int isTemp /* TRUE for a TEMPORARY view */ + int isTemp, /* TRUE for a TEMPORARY view */ + int noErr /* Suppress error messages if VIEW already exists */ ){ Table *p; int n; @@ -1584,7 +1610,7 @@ void sqlite3CreateView( sqlite3SelectDelete(pSelect); return; } - sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0); + sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr); p = pParse->pNewTable; if( p==0 || pParse->nErr ){ sqlite3SelectDelete(pSelect); @@ -1633,7 +1659,7 @@ void sqlite3CreateView( } #endif /* SQLITE_OMIT_VIEW */ -#ifndef SQLITE_OMIT_VIEW +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) /* ** 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 @@ -1647,6 +1673,14 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ assert( pTable ); +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( sqlite3VtabCallConnect(pParse, pTable) ){ + return SQLITE_ERROR; + } + if( IsVirtual(pTable) ) return 0; +#endif + +#ifndef SQLITE_OMIT_VIEW /* A positive nCol means the columns names for this view are ** already known. */ @@ -1699,9 +1733,10 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ } else { nErr++; } +#endif /* SQLITE_OMIT_VIEW */ return nErr; } -#endif /* SQLITE_OMIT_VIEW */ +#endif /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */ #ifndef SQLITE_OMIT_VIEW /* @@ -1873,6 +1908,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ int code; const char *zTab = SCHEMA_TABLE(iDb); const char *zDb = db->aDb[iDb].zName; + const char *zArg2 = 0; if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){ goto exit_drop_table; } @@ -1882,6 +1918,14 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ }else{ code = SQLITE_DROP_VIEW; } +#ifndef SQLITE_OMIT_VIRTUALTABLE + }else if( IsVirtual(pTab) ){ + if( sqlite3ViewGetColumnNames(pParse, pTab) ){ + goto exit_drop_table; + } + code = SQLITE_DROP_VTABLE; + zArg2 = pTab->pMod->zName; +#endif }else{ if( !OMIT_TEMPDB && iDb==1 ){ code = SQLITE_DROP_TEMP_TABLE; @@ -1889,7 +1933,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ code = SQLITE_DROP_TABLE; } } - if( sqlite3AuthCheck(pParse, code, pTab->zName, 0, zDb) ){ + if( sqlite3AuthCheck(pParse, code, pTab->zName, zArg2, zDb) ){ goto exit_drop_table; } if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){ @@ -1925,6 +1969,15 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ Db *pDb = &db->aDb[iDb]; sqlite3BeginWriteOperation(pParse, 0, iDb); +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + Vdbe *v = sqlite3GetVdbe(pParse); + if( v ){ + sqlite3VdbeAddOp(v, OP_VBegin, 0, 0); + } + } +#endif + /* Drop all triggers associated with the table being dropped. Code ** is generated to remove entries from sqlite_master and/or ** sqlite_temp_master if required. @@ -1961,13 +2014,16 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'", pDb->zName, SCHEMA_TABLE(iDb), pTab->zName); - if( !isView ){ + if( !isView && !IsVirtual(pTab) ){ destroyTable(pParse, pTab); } /* Remove the table entry from SQLite's internal schema and modify ** the schema cookie. */ + if( IsVirtual(pTab) ){ + sqlite3VdbeOp3(v, OP_VDestroy, iDb, 0, pTab->zName, 0); + } sqlite3VdbeOp3(v, OP_DropTable, iDb, 0, pTab->zName, 0); sqlite3ChangeCookie(db, v, iDb); } @@ -2011,7 +2067,7 @@ void sqlite3CreateForeignKey( char *z; assert( pTo!=0 ); - if( p==0 || pParse->nErr ) goto fk_end; + if( p==0 || pParse->nErr || IN_DECLARE_VTAB ) goto fk_end; if( pFromCol==0 ){ int iCol = p->nCol-1; if( iCol<0 ) goto fk_end; @@ -2215,7 +2271,7 @@ void sqlite3CreateIndex( int nExtra = 0; char *zExtra; - if( pParse->nErr || sqlite3MallocFailed() ){ + if( pParse->nErr || sqlite3MallocFailed() || IN_DECLARE_VTAB ){ goto exit_create_index; } @@ -2272,6 +2328,12 @@ void sqlite3CreateIndex( goto exit_create_index; } #endif +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + sqlite3ErrorMsg(pParse, "virtual tables may not be indexed"); + goto exit_create_index; + } +#endif /* ** Find the name of the index. Make sure there is not already another @@ -2399,7 +2461,7 @@ void sqlite3CreateIndex( const char *zColName = pListItem->zName; Column *pTabCol; int requestedSortOrder; - char *zColl; /* Collation sequence */ + char *zColl; /* Collation sequence name */ for(j=0, pTabCol=pTab->aCol; jnCol; j++, pTabCol++){ if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break; @@ -2409,6 +2471,12 @@ void sqlite3CreateIndex( pTab->zName, zColName); goto exit_create_index; } + /* TODO: Add a test to make sure that the same column is not named + ** more than once within the same index. Only the first instance of + ** the column will ever be used by the optimizer. Note that using the + ** same column more than once cannot be an error because that would + ** break backwards compatibility - it needs to be a warning. + */ pIndex->aiColumn[i] = j; if( pListItem->pExpr ){ assert( pListItem->pExpr->pColl ); @@ -2638,8 +2706,12 @@ void sqlite3DefaultRowEst(Index *pIdx){ int i; assert( a!=0 ); a[0] = 1000000; - for(i=pIdx->nColumn; i>=1; i--){ - a[i] = 10; + for(i=pIdx->nColumn; i>=5; i--){ + a[i] = 5; + } + while( i>=1 ){ + a[i] = 11 - i; + i--; } if( pIdx->onError!=OE_None ){ a[pIdx->nColumn] = 1; @@ -2878,15 +2950,6 @@ void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ } } -/* -** Add an alias to the last identifier on the given identifier list. -*/ -void sqlite3SrcListAddAlias(SrcList *pList, Token *pToken){ - if( pList && pList->nSrc>0 ){ - pList->a[pList->nSrc-1].zAlias = sqlite3NameFromToken(pToken); - } -} - /* ** Delete an entire SrcList including all its substructure. */ @@ -2906,6 +2969,74 @@ void sqlite3SrcListDelete(SrcList *pList){ sqliteFree(pList); } +/* +** This routine is called by the parser to add a new term to the +** end of a growing FROM clause. The "p" parameter is the part of +** the FROM clause that has already been constructed. "p" is NULL +** if this is the first term of the FROM clause. pTable and pDatabase +** are the name of the table and database named in the FROM clause term. +** pDatabase is NULL if the database name qualifier is missing - the +** usual case. If the term has a alias, then pAlias points to the +** alias token. If the term is a subquery, then pSubquery is the +** SELECT statement that the subquery encodes. The pTable and +** pDatabase parameters are NULL for subqueries. The pOn and pUsing +** parameters are the content of the ON and USING clauses. +** +** Return a new SrcList which encodes is the FROM with the new +** term added. +*/ +SrcList *sqlite3SrcListAppendFromTerm( + SrcList *p, /* The left part of the FROM clause already seen */ + Token *pTable, /* Name of the table to add to the FROM clause */ + Token *pDatabase, /* Name of the database containing pTable */ + Token *pAlias, /* The right-hand side of the AS subexpression */ + Select *pSubquery, /* A subquery used in place of a table name */ + Expr *pOn, /* The ON clause of a join */ + IdList *pUsing /* The USING clause of a join */ +){ + struct SrcList_item *pItem; + p = sqlite3SrcListAppend(p, pTable, pDatabase); + if( p==0 || p->nSrc==0 ){ + sqlite3ExprDelete(pOn); + sqlite3IdListDelete(pUsing); + sqlite3SelectDelete(pSubquery); + return p; + } + pItem = &p->a[p->nSrc-1]; + if( pAlias && pAlias->n ){ + pItem->zAlias = sqlite3NameFromToken(pAlias); + } + pItem->pSelect = pSubquery; + pItem->pOn = pOn; + pItem->pUsing = pUsing; + return p; +} + +/* +** When building up a FROM clause in the parser, the join operator +** is initially attached to the left operand. But the code generator +** expects the join operator to be on the right operand. This routine +** Shifts all join operators from left to right for an entire FROM +** clause. +** +** Example: Suppose the join is like this: +** +** A natural cross join B +** +** The operator is "natural cross join". The A and B operands are stored +** in p->a[0] and p->a[1], respectively. The parser initially stores the +** operator with A. This routine shifts that operator over to B. +*/ +void sqlite3SrcListShiftJoinType(SrcList *p){ + if( p && p->a ){ + int i; + for(i=p->nSrc-1; i>0; i--){ + p->a[i].jointype = p->a[i-1].jointype; + } + p->a[0].jointype = 0; + } +} + /* ** Begin a transaction */ diff --git a/dlls/sqlite/sqlite-source/callback.c b/dlls/sqlite/sqlite-source/callback.c index c59df06a..788b6221 100644 --- a/dlls/sqlite/sqlite-source/callback.c +++ b/dlls/sqlite/sqlite-source/callback.c @@ -195,6 +195,11 @@ static CollSeq *findCollSeqEntry( ** ** If the entry specified is not found and 'create' is true, then create a ** new entry. Otherwise return NULL. +** +** A separate function sqlite3LocateCollSeq() is a wrapper around +** this routine. sqlite3LocateCollSeq() invokes the collation factory +** if necessary and generates an error message if the collating sequence +** cannot be found. */ CollSeq *sqlite3FindCollSeq( sqlite3 *db, @@ -362,6 +367,7 @@ Schema *sqlite3SchemaGet(Btree *pBt){ sqlite3HashInit(&p->idxHash, SQLITE_HASH_STRING, 0); sqlite3HashInit(&p->trigHash, SQLITE_HASH_STRING, 0); sqlite3HashInit(&p->aFKey, SQLITE_HASH_STRING, 1); + p->enc = SQLITE_UTF8; } return p; } diff --git a/dlls/sqlite/sqlite-source/date.c b/dlls/sqlite/sqlite-source/date.c index da7c7d70..5298aab9 100644 --- a/dlls/sqlite/sqlite-source/date.c +++ b/dlls/sqlite/sqlite-source/date.c @@ -23,7 +23,7 @@ ** SQLite processes all times and dates as Julian Day numbers. The ** dates and times are stored as the number of days since noon ** in Greenwich on November 24, 4714 B.C. according to the Gregorian -** calendar system. +** calendar system. ** ** 1970-01-01 00:00:00 is JD 2440587.5 ** 2000-01-01 00:00:00 is JD 2451544.5 @@ -231,14 +231,14 @@ static void computeJD(DateTime *p){ A = Y/100; B = 2 - A + (A/4); X1 = (int)(365.25*(Y+4716)); - X2 = (int)30.6001*(M+1); + X2 = (int)(30.6001*(M+1)); p->rJD = X1 + X2 + D + B - 1524.5; p->validJD = 1; - p->validYMD = 0; if( p->validHMS ){ p->rJD += (p->h*3600.0 + p->m*60.0 + p->s)/86400.0; if( p->validTZ ){ p->rJD -= p->tz*60/86400.0; + p->validYMD = 0; p->validHMS = 0; p->validTZ = 0; } @@ -357,10 +357,11 @@ static void computeYMD(DateTime *p){ static void computeHMS(DateTime *p){ int Z, s; if( p->validHMS ) return; + computeJD(p); Z = (int)(p->rJD + 0.5); s = (int)((p->rJD + 0.5 - Z)*86400000.0 + 0.5); p->s = 0.001*s; - s = (int)(p->s); + s = (int)p->s; p->s -= s; p->h = s/3600; s -= p->h*3600; @@ -393,7 +394,6 @@ static void clearYMD_HMS_TZ(DateTime *p){ static double localtimeOffset(DateTime *p){ DateTime x, y; time_t t; - struct tm *pTm; x = *p; computeYMD_HMS(&x); if( x.Y<1971 || x.Y>=2038 ){ @@ -411,15 +411,31 @@ static double localtimeOffset(DateTime *p){ x.validJD = 0; computeJD(&x); t = (time_t)((x.rJD-2440587.5)*86400.0 + 0.5); - sqlite3OsEnterMutex(); - pTm = localtime(&t); - y.Y = pTm->tm_year + 1900; - y.M = pTm->tm_mon + 1; - y.D = pTm->tm_mday; - y.h = pTm->tm_hour; - y.m = pTm->tm_min; - y.s = pTm->tm_sec; - sqlite3OsLeaveMutex(); +#ifdef HAVE_LOCALTIME_R + { + struct tm sLocal; + localtime_r(&t, &sLocal); + y.Y = sLocal.tm_year + 1900; + y.M = sLocal.tm_mon + 1; + y.D = sLocal.tm_mday; + y.h = sLocal.tm_hour; + y.m = sLocal.tm_min; + y.s = sLocal.tm_sec; + } +#else + { + struct tm *pTm; + sqlite3OsEnterMutex(); + pTm = localtime(&t); + y.Y = pTm->tm_year + 1900; + y.M = pTm->tm_mon + 1; + y.D = pTm->tm_mday; + y.h = pTm->tm_hour; + y.m = pTm->tm_min; + y.s = pTm->tm_sec; + sqlite3OsLeaveMutex(); + } +#endif y.validYMD = 1; y.validHMS = 1; y.validJD = 0; @@ -581,7 +597,7 @@ static int parseModifier(const char *zMod, DateTime *p){ if( z[0]=='-' ) tx.rJD = -tx.rJD; computeJD(p); clearYMD_HMS_TZ(p); - p->rJD += tx.rJD; + p->rJD += tx.rJD; rc = 0; break; } @@ -809,9 +825,9 @@ static void strftimeFunc( switch( zFmt[i] ){ case 'd': sprintf(&z[j],"%02d",x.D); j+=2; break; case 'f': { - int s = (int)x.s; - int ms = (int)((x.s - s)*1000.0); - sprintf(&z[j],"%02d.%03d",s,ms); + double s = x.s; + if( s>59.999 ) s = 59.999; + sqlite3_snprintf(7, &z[j],"%02.3f", s); j += strlen(&z[j]); break; } @@ -824,7 +840,7 @@ static void strftimeFunc( y.M = 1; y.D = 1; computeJD(&y); - nDay = (int)(x.rJD - y.rJD); + nDay = (int)(x.rJD - y.rJD + 0.5); if( zFmt[i]=='W' ){ int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */ wd = ((int)(x.rJD+0.5)) % 7; @@ -844,7 +860,7 @@ static void strftimeFunc( j += strlen(&z[j]); break; } - case 'S': sprintf(&z[j],"%02d",(int)(x.s+0.5)); j+=2; break; + case 'S': sprintf(&z[j],"%02d",(int)x.s); j+=2; break; case 'w': z[j++] = (((int)(x.rJD+1.5)) % 7) + '0'; break; case 'Y': sprintf(&z[j],"%04d",x.Y); j+=strlen(&z[j]); break; case '%': z[j++] = '%'; break; @@ -944,9 +960,21 @@ static void currentTimeFunc( } #endif - sqlite3OsEnterMutex(); - strftime(zBuf, 20, zFormat, gmtime(&t)); - sqlite3OsLeaveMutex(); +#ifdef HAVE_GMTIME_R + { + struct tm sNow; + gmtime_r(&t, &sNow); + strftime(zBuf, 20, zFormat, &sNow); + } +#else + { + struct tm *pTm; + sqlite3OsEnterMutex(); + pTm = gmtime(&t); + strftime(zBuf, 20, zFormat, pTm); + sqlite3OsLeaveMutex(); + } +#endif sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); } diff --git a/dlls/sqlite/sqlite-source/delete.c b/dlls/sqlite/sqlite-source/delete.c index 275c52ae..ea9e99b8 100644 --- a/dlls/sqlite/sqlite-source/delete.c +++ b/dlls/sqlite/sqlite-source/delete.c @@ -42,8 +42,12 @@ Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ ** writable return 0; */ int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){ - if( pTab->readOnly && (pParse->db->flags & SQLITE_WriteSchema)==0 - && pParse->nested==0 ){ + if( (pTab->readOnly && (pParse->db->flags & SQLITE_WriteSchema)==0 + && pParse->nested==0) +#ifndef SQLITE_OMIT_VIRTUALTABLE + || (pTab->pMod && pTab->pMod->pModule->xUpdate==0) +#endif + ){ sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName); return 1; } @@ -66,7 +70,9 @@ void sqlite3OpenTable( Table *pTab, /* The table to be opened */ int opcode /* OP_OpenRead or OP_OpenWrite */ ){ - Vdbe *v = sqlite3GetVdbe(p); + Vdbe *v; + if( IsVirtual(pTab) ) return; + v = sqlite3GetVdbe(p); assert( opcode==OP_OpenWrite || opcode==OP_OpenRead ); sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite), pTab->zName); sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); @@ -100,7 +106,8 @@ void sqlite3DeleteFrom( AuthContext sContext; /* Authorization context */ int oldIdx = -1; /* Cursor for the OLD table of AFTER triggers */ NameContext sNC; /* Name context to resolve expressions in */ - int iDb; + int iDb; /* Database number */ + int memCnt = 0; /* Memory cell used for change counting */ #ifndef SQLITE_OMIT_TRIGGER int isView; /* True if attempting to delete from a view */ @@ -149,7 +156,7 @@ void sqlite3DeleteFrom( /* If pTab is really a view, make sure it has been initialized. */ - if( isView && sqlite3ViewGetColumnNames(pParse, pTab) ){ + if( sqlite3ViewGetColumnNames(pParse, pTab) ){ goto delete_from_cleanup; } @@ -190,7 +197,7 @@ void sqlite3DeleteFrom( */ if( isView ){ Select *pView = sqlite3SelectDup(pTab->pSelect); - sqlite3Select(pParse, pView, SRT_VirtualTab, iCur, 0, 0, 0, 0); + sqlite3Select(pParse, pView, SRT_EphemTab, iCur, 0, 0, 0, 0); sqlite3SelectDelete(pView); } @@ -198,14 +205,15 @@ void sqlite3DeleteFrom( ** we are counting rows. */ if( db->flags & SQLITE_CountRows ){ - sqlite3VdbeAddOp(v, OP_Integer, 0, 0); + memCnt = pParse->nMem++; + sqlite3VdbeAddOp(v, OP_MemInt, 0, memCnt); } /* Special case: A DELETE without a WHERE clause deletes everything. ** It is easier just to erase the whole table. Note, however, that ** this means that the row change count will be incorrect. */ - if( pWhere==0 && !triggers_exist ){ + if( pWhere==0 && !triggers_exist && !IsVirtual(pTab) ){ if( db->flags & SQLITE_CountRows ){ /* If counting rows deleted, just count the total number of ** entries in the table. */ @@ -215,7 +223,7 @@ void sqlite3DeleteFrom( sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead); } sqlite3VdbeAddOp(v, OP_Rewind, iCur, sqlite3VdbeCurrentAddr(v)+2); - addr2 = sqlite3VdbeAddOp(v, OP_AddImm, 1, 0); + addr2 = sqlite3VdbeAddOp(v, OP_MemIncr, 1, memCnt); sqlite3VdbeAddOp(v, OP_Next, iCur, addr2); sqlite3VdbeResolveLabel(v, endOfLoop); sqlite3VdbeAddOp(v, OP_Close, iCur, 0); @@ -230,8 +238,7 @@ void sqlite3DeleteFrom( sqlite3VdbeAddOp(v, OP_Clear, pIdx->tnum, iDb); } } - } - + } /* The usual case: There is a WHERE clause so we have to scan through ** the table and pick which records to delete. */ @@ -243,10 +250,10 @@ void sqlite3DeleteFrom( /* Remember the rowid of every item to be deleted. */ - sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0); + sqlite3VdbeAddOp(v, IsVirtual(pTab) ? OP_VRowid : OP_Rowid, iCur, 0); sqlite3VdbeAddOp(v, OP_FifoWrite, 0, 0); if( db->flags & SQLITE_CountRows ){ - sqlite3VdbeAddOp(v, OP_AddImm, 1, 0); + sqlite3VdbeAddOp(v, OP_MemIncr, 1, memCnt); } /* End the database scan loop. @@ -304,7 +311,15 @@ void sqlite3DeleteFrom( } /* Delete the row */ - sqlite3GenerateRowDelete(db, v, pTab, iCur, pParse->nested==0); +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + pParse->pVirtualLock = pTab; + sqlite3VdbeOp3(v, OP_VUpdate, 0, 1, (const char*)pTab->pVtab, P3_VTAB); + }else +#endif + { + sqlite3GenerateRowDelete(db, v, pTab, iCur, pParse->nested==0); + } } /* If there are row triggers, close all cursors then invoke @@ -327,7 +342,7 @@ void sqlite3DeleteFrom( sqlite3VdbeResolveLabel(v, end); /* Close the cursors after the loop if there are no row triggers */ - if( !triggers_exist ){ + if( !triggers_exist && !IsVirtual(pTab) ){ for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum); } @@ -341,6 +356,7 @@ void sqlite3DeleteFrom( ** invoke the callback function. */ if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){ + sqlite3VdbeAddOp(v, OP_MemLoad, memCnt, 0); sqlite3VdbeAddOp(v, OP_Callback, 1, 0); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", P3_STATIC); diff --git a/dlls/sqlite/sqlite-source/expr.c b/dlls/sqlite/sqlite-source/expr.c index fde7db45..6d21918c 100644 --- a/dlls/sqlite/sqlite-source/expr.c +++ b/dlls/sqlite/sqlite-source/expr.c @@ -49,6 +49,24 @@ char sqlite3ExprAffinity(Expr *pExpr){ return pExpr->affinity; } +/* +** Set the collating sequence for expression pExpr to be the collating +** sequence named by pToken. Return a pointer to the revised expression. +** The collating sequence is marked as "explicit" using the EP_ExpCollate +** flag. An explicit collating sequence will override implicit +** collating sequences. +*/ +Expr *sqlite3ExprSetColl(Parse *pParse, Expr *pExpr, Token *pName){ + CollSeq *pColl; + if( pExpr==0 ) return 0; + pColl = sqlite3LocateCollSeq(pParse, (char*)pName->z, pName->n); + if( pColl ){ + pExpr->pColl = pColl; + pExpr->flags |= EP_ExpCollate; + } + return pExpr; +} + /* ** Return the default collation sequence for the expression pExpr. If ** there is no default collation type, return 0. @@ -158,9 +176,20 @@ static int binaryCompareP1(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){ ** type. */ static CollSeq* binaryCompareCollSeq(Parse *pParse, Expr *pLeft, Expr *pRight){ - CollSeq *pColl = sqlite3ExprCollSeq(pParse, pLeft); - if( !pColl ){ - pColl = sqlite3ExprCollSeq(pParse, pRight); + CollSeq *pColl; + assert( pLeft ); + assert( pRight ); + if( pLeft->flags & EP_ExpCollate ){ + assert( pLeft->pColl ); + pColl = pLeft->pColl; + }else if( pRight->flags & EP_ExpCollate ){ + assert( pRight->pColl ); + pColl = pRight->pColl; + }else{ + pColl = sqlite3ExprCollSeq(pParse, pLeft); + if( !pColl ){ + pColl = sqlite3ExprCollSeq(pParse, pRight); + } } return pColl; } @@ -205,8 +234,31 @@ Expr *sqlite3Expr(int op, Expr *pLeft, Expr *pRight, const Token *pToken){ if( pToken ){ assert( pToken->dyn==0 ); pNew->span = pNew->token = *pToken; - }else if( pLeft && pRight ){ - sqlite3ExprSpan(pNew, &pLeft->span, &pRight->span); + }else if( pLeft ){ + if( pRight ){ + sqlite3ExprSpan(pNew, &pLeft->span, &pRight->span); + if( pRight->flags && EP_ExpCollate ){ + pNew->flags |= EP_ExpCollate; + pNew->pColl = pRight->pColl; + } + } + if( pLeft->flags && EP_ExpCollate ){ + pNew->flags |= EP_ExpCollate; + pNew->pColl = pLeft->pColl; + } + } + return pNew; +} + +/* +** Works like sqlite3Expr() but frees its pLeft and pRight arguments +** if it fails due to a malloc problem. +*/ +Expr *sqlite3ExprOrFree(int op, Expr *pLeft, Expr *pRight, const Token *pToken){ + Expr *pNew = sqlite3Expr(op, pLeft, pRight, pToken); + if( pNew==0 ){ + sqlite3ExprDelete(pLeft); + sqlite3ExprDelete(pRight); } return pNew; } @@ -547,12 +599,12 @@ Select *sqlite3SelectDup(Select *p){ pNew->iOffset = -1; pNew->isResolved = p->isResolved; pNew->isAgg = p->isAgg; - pNew->usesVirt = 0; + pNew->usesEphm = 0; pNew->disallowOrderBy = 0; pNew->pRightmost = 0; - pNew->addrOpenVirt[0] = -1; - pNew->addrOpenVirt[1] = -1; - pNew->addrOpenVirt[2] = -1; + pNew->addrOpenEphm[0] = -1; + pNew->addrOpenEphm[1] = -1; + pNew->addrOpenEphm[2] = -1; return pNew; } #else @@ -877,23 +929,26 @@ static int lookupName( /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ pExpr->iColumn = j==pTab->iPKey ? -1 : j; pExpr->affinity = pTab->aCol[j].affinity; - pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0); - if( pItem->jointype & JT_NATURAL ){ - /* If this match occurred in the left table of a natural join, - ** then skip the right table to avoid a duplicate match */ - pItem++; - i++; + if( (pExpr->flags & EP_ExpCollate)==0 ){ + pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0); } - if( (pUsing = pItem->pUsing)!=0 ){ - /* If this match occurs on a column that is in the USING clause - ** of a join, skip the search of the right table of the join - ** to avoid a duplicate match there. */ - int k; - for(k=0; knId; k++){ - if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ){ - pItem++; - i++; - break; + if( inSrc-1 ){ + if( pItem[1].jointype & JT_NATURAL ){ + /* If this match occurred in the left table of a natural join, + ** then skip the right table to avoid a duplicate match */ + pItem++; + i++; + }else if( (pUsing = pItem[1].pUsing)!=0 ){ + /* If this match occurs on a column that is in the USING clause + ** of a join, skip the search of the right table of the join + ** to avoid a duplicate match there. */ + int k; + for(k=0; knId; k++){ + if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ){ + pItem++; + i++; + break; + } } } } @@ -932,7 +987,9 @@ static int lookupName( cnt++; pExpr->iColumn = iCol==pTab->iPKey ? -1 : iCol; pExpr->affinity = pTab->aCol[iCol].affinity; - pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0); + if( (pExpr->flags & EP_ExpCollate)==0 ){ + pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0); + } pExpr->pTab = pTab; break; } @@ -1032,7 +1089,7 @@ static int lookupName( n = sizeof(Bitmask)*8-1; } assert( pMatch->iCursor==pExpr->iTable ); - pMatch->colUsed |= 1<colUsed |= ((Bitmask)1)<xFunc==0; } +#ifndef SQLITE_OMIT_AUTHORIZATION + if( pDef ){ + auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0); + if( auth!=SQLITE_OK ){ + if( auth==SQLITE_DENY ){ + sqlite3ErrorMsg(pParse, "not authorized to use function: %s", + pDef->zName); + pNC->nErr++; + } + pExpr->op = TK_NULL; + return 1; + } + } +#endif if( is_agg && !pNC->allowAgg ){ sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId); pNC->nErr++; @@ -1316,7 +1388,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ case TK_IN: { char affinity; KeyInfo keyInfo; - int addr; /* Address of OP_OpenVirtual instruction */ + int addr; /* Address of OP_OpenEphemeral instruction */ affinity = sqlite3ExprAffinity(pExpr->pLeft); @@ -1334,7 +1406,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ ** is used. */ pExpr->iTable = pParse->nTab++; - addr = sqlite3VdbeAddOp(v, OP_OpenVirtual, pExpr->iTable, 0); + addr = sqlite3VdbeAddOp(v, OP_OpenEphemeral, pExpr->iTable, 0); memset(&keyInfo, 0, sizeof(keyInfo)); keyInfo.nField = 1; sqlite3VdbeAddOp(v, OP_SetNumColumns, pExpr->iTable, 1); @@ -1367,7 +1439,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ struct ExprList_item *pItem; if( !affinity ){ - affinity = SQLITE_AFF_NUMERIC; + affinity = SQLITE_AFF_NONE; } keyInfo.aColl[0] = pExpr->pLeft->pColl; @@ -1489,7 +1561,8 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ }else if( pExpr->iColumn>=0 ){ Table *pTab = pExpr->pTab; int iCol = pExpr->iColumn; - sqlite3VdbeAddOp(v, OP_Column, pExpr->iTable, iCol); + int op = (pTab && IsVirtual(pTab)) ? OP_VColumn : OP_Column; + sqlite3VdbeAddOp(v, op, pExpr->iTable, iCol); sqlite3ColumnDefault(v, pTab, iCol); #ifndef SQLITE_OMIT_FLOATING_POINT if( pTab && pTab->aCol[iCol].affinity==SQLITE_AFF_REAL ){ @@ -1497,7 +1570,9 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ } #endif }else{ - sqlite3VdbeAddOp(v, OP_Rowid, pExpr->iTable, 0); + Table *pTab = pExpr->pTab; + int op = (pTab && IsVirtual(pTab)) ? OP_VRowid : OP_Rowid; + sqlite3VdbeAddOp(v, op, pExpr->iTable, 0); } break; } @@ -1671,6 +1746,25 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0); assert( pDef!=0 ); nExpr = sqlite3ExprCodeExprList(pParse, pList); +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* Possibly overload the function if the first argument is + ** a virtual table column. + ** + ** For infix functions (LIKE, GLOB, REGEXP, and MATCH) use the + ** second argument, not the first, as the argument to test to + ** see if it is a column in a virtual table. This is done because + ** the left operand of infix functions (the operand we want to + ** control overloading) ends up as the second argument to the + ** function. The expression "A glob B" is equivalent to + ** "glob(B,A). We want to use the A in "A glob B" to test + ** for function overloading. But we use the B term in "glob(B,A)". + */ + if( nExpr>=2 && (pExpr->flags & EP_InfixFunc) ){ + pDef = sqlite3VtabOverloadFunction(pDef, nExpr, pList->a[1].pExpr); + }else if( nExpr>0 ){ + pDef = sqlite3VtabOverloadFunction(pDef, nExpr, pList->a[0].pExpr); + } +#endif for(i=0; ia[i].pExpr) ){ constMask |= (1<op ){ + case TK_AGG_COLUMN: case TK_COLUMN: { /* Check to see if the column is in one of the tables in the FROM ** clause of the aggregate query */ diff --git a/dlls/sqlite/sqlite-source/func.c b/dlls/sqlite/sqlite-source/func.c index 7668c412..eb0ca8b2 100644 --- a/dlls/sqlite/sqlite-source/func.c +++ b/dlls/sqlite/sqlite-source/func.c @@ -204,7 +204,8 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; r = sqlite3_value_double(argv[0]); sqlite3_snprintf(sizeof(zBuf),zBuf,"%.*f",n,r); - sqlite3_result_double(context, atof(zBuf)); + sqlite3AtoF(zBuf, &r); + sqlite3_result_double(context, r); } /* @@ -271,6 +272,25 @@ static void randomFunc( sqlite3_result_int64(context, r); } +/* +** Implementation of randomblob(N). Return a random blob +** that is N bytes long. +*/ +static void randomBlob( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int n; + unsigned char *p; + assert( argc==1 ); + n = sqlite3_value_int(argv[0]); + if( n<1 ) n = 1; + p = sqlite3_malloc(n); + sqlite3Randomness(n, p); + sqlite3_result_blob(context, (char*)p, n, sqlite3_free); +} + /* ** Implementation of the last_insert_rowid() SQL function. The return ** value is the same as the sqlite3_last_insert_rowid() API function. @@ -547,6 +567,12 @@ static void versionFunc( sqlite3_result_text(context, sqlite3_version, -1, SQLITE_STATIC); } +/* Array for converting from half-bytes (nybbles) into ASCII hex +** digits. */ +static const char hexdigits[] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' +}; /* ** EXPERIMENTAL - This is not an official function. The interface may @@ -572,10 +598,6 @@ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ break; } case SQLITE_BLOB: { - static const char hexdigits[] = { - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' - }; char *zText = 0; int nBlob = sqlite3_value_bytes(argv[0]); char const *zBlob = sqlite3_value_blob(argv[0]); @@ -621,11 +643,41 @@ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ } } +/* +** The hex() function. Interpret the argument as a blob. Return +** a hexadecimal rendering as text. +*/ +static void hexFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int i, n; + const unsigned char *pBlob; + char *zHex, *z; + assert( argc==1 ); + pBlob = sqlite3_value_blob(argv[0]); + n = sqlite3_value_bytes(argv[0]); + z = zHex = sqlite3_malloc(n*2 + 1); + if( zHex==0 ) return; + for(i=0; i>4)&0xf]; + *(z++) = hexdigits[c&0xf]; + } + *z = 0; + sqlite3_result_text(context, zHex, n*2, sqlite3_free); +} + #ifdef SQLITE_SOUNDEX /* ** Compute the soundex encoding of a word. */ -static void soundexFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ +static void soundexFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ char zResult[8]; const u8 *zIn; int i, j; @@ -641,13 +693,20 @@ static void soundexFunc(sqlite3_context *context, int argc, sqlite3_value **argv }; assert( argc==1 ); zIn = (u8*)sqlite3_value_text(argv[0]); + if( zIn==0 ) zIn = (u8*)""; for(i=0; zIn[i] && !isalpha(zIn[i]); i++){} if( zIn[i] ){ + u8 prevcode = iCode[zIn[i]&0x7f]; zResult[0] = toupper(zIn[i]); for(j=1; j<4 && zIn[i]; i++){ int code = iCode[zIn[i]&0x7f]; if( code>0 ){ - zResult[j++] = code + '0'; + if( code!=prevcode ){ + prevcode = code; + zResult[j++] = code + '0'; + } + }else{ + prevcode = 0; } } while( j<4 ){ @@ -661,6 +720,26 @@ static void soundexFunc(sqlite3_context *context, int argc, sqlite3_value **argv } #endif +#ifndef SQLITE_OMIT_LOAD_EXTENSION +/* +** A function that loads a shared-library extension then returns NULL. +*/ +static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){ + const char *zFile = (const char *)sqlite3_value_text(argv[0]); + const char *zProc = 0; + sqlite3 *db = sqlite3_user_data(context); + char *zErrMsg = 0; + + if( argc==2 ){ + zProc = (const char *)sqlite3_value_text(argv[1]); + } + if( sqlite3_load_extension(db, zFile, zProc, &zErrMsg) ){ + sqlite3_result_error(context, zErrMsg, -1); + sqlite3_free(zErrMsg); + } +} +#endif + #ifdef SQLITE_TEST /* ** This function generates a string of random characters. Used for @@ -839,16 +918,8 @@ struct SumCtx { ** that it returns NULL if it sums over no inputs. TOTAL returns ** 0.0 in that case. In addition, TOTAL always returns a float where ** SUM might return an integer if it never encounters a floating point -** value. -** -** I am told that SUM() should raise an exception if it encounters -** a integer overflow. But after pondering this, I decided that -** behavior leads to brittle programs. So instead, I have coded -** SUM() to revert to using floating point if it encounters an -** integer overflow. The answer may not be exact, but it will be -** close. If the SUM() function returns an integer, the value is -** exact. If SUM() returns a floating point value, it means the -** value might be approximated. +** value. TOTAL never fails, but SUM might through an exception if +** it overflows an integer. */ static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){ SumCtx *p; @@ -864,7 +935,7 @@ static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){ if( (p->approx|p->overflow)==0 ){ i64 iNewSum = p->iSum + v; int s1 = (int)(p->iSum >> (sizeof(i64)*8-1)); - int s2 = (int)(v >> (sizeof(i64)*8-1)); + int s2 = (int)(v >> (sizeof(i64)*8-1)); int s3 = (int)(iNewSum >> (sizeof(i64)*8-1)); p->overflow = (s1&s2&~s3) | (~s1&~s2&s3); p->iSum = iNewSum; @@ -1002,8 +1073,10 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ { "coalesce", -1, 0, SQLITE_UTF8, 0, ifnullFunc }, { "coalesce", 0, 0, SQLITE_UTF8, 0, 0 }, { "coalesce", 1, 0, SQLITE_UTF8, 0, 0 }, + { "hex", 1, 0, SQLITE_UTF8, 0, hexFunc }, { "ifnull", 2, 0, SQLITE_UTF8, 1, ifnullFunc }, { "random", -1, 0, SQLITE_UTF8, 0, randomFunc }, + { "randomblob", 1, 0, SQLITE_UTF8, 0, randomBlob }, { "nullif", 2, 0, SQLITE_UTF8, 1, nullifFunc }, { "sqlite_version", 0, 0, SQLITE_UTF8, 0, versionFunc}, { "quote", 1, 0, SQLITE_UTF8, 0, quoteFunc }, @@ -1013,6 +1086,10 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ #ifdef SQLITE_SOUNDEX { "soundex", 1, 0, SQLITE_UTF8, 0, soundexFunc}, #endif +#ifndef SQLITE_OMIT_LOAD_EXTENSION + { "load_extension", 1, 1, SQLITE_UTF8, 0, loadExt }, + { "load_extension", 2, 1, SQLITE_UTF8, 0, loadExt }, +#endif #ifdef SQLITE_TEST { "randstr", 2, 0, SQLITE_UTF8, 0, randStr }, { "test_destructor", 1, 1, SQLITE_UTF8, 0, test_destructor}, @@ -1078,6 +1155,7 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ } } sqlite3RegisterDateTimeFunctions(db); + sqlite3_overload_function(db, "MATCH", 2); #ifdef SQLITE_SSE (void)sqlite3SseFunctions(db); #endif diff --git a/dlls/sqlite/sqlite-source/insert.c b/dlls/sqlite/sqlite-source/insert.c index c3f1387d..adcc37a4 100644 --- a/dlls/sqlite/sqlite-source/insert.c +++ b/dlls/sqlite/sqlite-source/insert.c @@ -272,8 +272,10 @@ void sqlite3Insert( assert( pTab!=0 ); /* If pTab is really a view, make sure it has been initialized. + ** ViewGetColumnNames() is a no-op if pTab is not a view (or virtual + ** module table). */ - if( isView && sqlite3ViewGetColumnNames(pParse, pTab) ){ + if( sqlite3ViewGetColumnNames(pParse, pTab) ){ goto insert_cleanup; } @@ -371,7 +373,7 @@ void sqlite3Insert( ** back up and execute the SELECT code above. */ sqlite3VdbeJumpHere(v, iInitCode); - sqlite3VdbeAddOp(v, OP_OpenVirtual, srcTab, 0); + sqlite3VdbeAddOp(v, OP_OpenEphemeral, srcTab, 0); sqlite3VdbeAddOp(v, OP_SetNumColumns, srcTab, nColumn); sqlite3VdbeAddOp(v, OP_Goto, 0, iSelectLoop); sqlite3VdbeResolveLabel(v, iCleanup); @@ -385,11 +387,9 @@ void sqlite3Insert( NameContext sNC; memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; - assert( pList!=0 ); srcTab = -1; useTempTable = 0; - assert( pList ); - nColumn = pList->nExpr; + nColumn = pList ? pList->nExpr : 0; for(i=0; ia[i].pExpr) ){ goto insert_cleanup; @@ -400,7 +400,7 @@ void sqlite3Insert( /* Make sure the number of columns in the source data matches the number ** of columns to be inserted into the table. */ - if( pColumn==0 && nColumn!=pTab->nCol ){ + if( pColumn==0 && nColumn && nColumn!=pTab->nCol ){ sqlite3ErrorMsg(pParse, "table %S has %d columns but %d values were supplied", pTabList, 0, pTab->nCol, nColumn); @@ -453,7 +453,7 @@ void sqlite3Insert( ** key, the set the keyColumn variable to the primary key column index ** in the original table definition. */ - if( pColumn==0 ){ + if( pColumn==0 && nColumn>0 ){ keyColumn = pTab->iPKey; } @@ -567,6 +567,10 @@ void sqlite3Insert( ** case the record number is the same as that column. */ if( !isView ){ + if( IsVirtual(pTab) ){ + /* The row that the VUpdate opcode will delete: none */ + sqlite3VdbeAddOp(v, OP_Null, 0, 0); + } if( keyColumn>=0 ){ if( useTempTable ){ sqlite3VdbeAddOp(v, OP_Column, srcTab, keyColumn); @@ -582,6 +586,8 @@ void sqlite3Insert( sqlite3VdbeAddOp(v, OP_Pop, 1, 0); sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem); sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0); + }else if( IsVirtual(pTab) ){ + sqlite3VdbeAddOp(v, OP_Null, 0, 0); }else{ sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem); } @@ -610,12 +616,12 @@ void sqlite3Insert( if( pColumn->a[j].idx==i ) break; } } - if( pColumn && j>=pColumn->nId ){ + if( nColumn==0 || (pColumn && j>=pColumn->nId) ){ sqlite3ExprCode(pParse, pTab->aCol[i].pDflt); }else if( useTempTable ){ sqlite3VdbeAddOp(v, OP_Column, srcTab, j); }else if( pSelect ){ - sqlite3VdbeAddOp(v, OP_Dup, i+nColumn-j, 1); + sqlite3VdbeAddOp(v, OP_Dup, i+nColumn-j+IsVirtual(pTab), 1); }else{ sqlite3ExprCode(pParse, pList->a[j].pExpr); } @@ -624,10 +630,19 @@ void sqlite3Insert( /* Generate code to check constraints and generate index keys and ** do the insertion. */ - sqlite3GenerateConstraintChecks(pParse, pTab, base, 0, keyColumn>=0, - 0, onError, endOfLoop); - sqlite3CompleteInsertion(pParse, pTab, base, 0,0,0, +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + pParse->pVirtualLock = pTab; + sqlite3VdbeOp3(v, OP_VUpdate, 1, pTab->nCol+2, + (const char*)pTab->pVtab, P3_VTAB); + }else +#endif + { + sqlite3GenerateConstraintChecks(pParse, pTab, base, 0, keyColumn>=0, + 0, onError, endOfLoop); + sqlite3CompleteInsertion(pParse, pTab, base, 0,0,0, (triggers_exist & TRIGGER_AFTER)!=0 ? newIdx : -1); + } } /* Update the count of rows that are inserted @@ -665,7 +680,7 @@ void sqlite3Insert( sqlite3VdbeResolveLabel(v, iCleanup); } - if( !triggers_exist ){ + if( !triggers_exist && !IsVirtual(pTab) ){ /* Close all tables opened */ sqlite3VdbeAddOp(v, OP_Close, base, 0); for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){ @@ -1105,9 +1120,13 @@ void sqlite3OpenTableAndIndices( int op /* OP_OpenRead or OP_OpenWrite */ ){ int i; - int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + int iDb; Index *pIdx; - Vdbe *v = sqlite3GetVdbe(pParse); + Vdbe *v; + + if( IsVirtual(pTab) ) return; + iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + v = sqlite3GetVdbe(pParse); assert( v!=0 ); sqlite3OpenTable(pParse, base, iDb, pTab, op); for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ diff --git a/dlls/sqlite/sqlite-source/keywordhash.h b/dlls/sqlite/sqlite-source/keywordhash.h index 53a4bf19..bc0898f3 100644 --- a/dlls/sqlite/sqlite-source/keywordhash.h +++ b/dlls/sqlite/sqlite-source/keywordhash.h @@ -1,6 +1,6 @@ -/* Hash score: 159 */ +/* Hash score: 167 */ static int keywordCode(const char *z, int n){ - static const char zText[537] = + static const char zText[544] = "ABORTABLEFTEMPORARYADDATABASELECTHENDEFAULTRANSACTIONATURALTER" "AISEACHECKEYAFTEREFERENCESCAPELSEXCEPTRIGGEREGEXPLAINITIALLYANALYZE" "XCLUSIVEXISTSTATEMENTANDEFERRABLEATTACHAVINGLOBEFOREIGNOREINDEX" @@ -9,11 +9,11 @@ static int keywordCode(const char *z, int n){ "CURRENT_DATECURRENT_TIMESTAMPLANDESCDETACHDISTINCTDROPRAGMATCH" "FAILIMITFROMFULLGROUPDATEIFIMMEDIATEINSERTINSTEADINTOFFSETISNULL" "JOINORDEREPLACEOUTERESTRICTPRIMARYQUERYRIGHTROLLBACKROWHENUNION" - "UNIQUEUSINGVACUUMVALUESVIEWHERE"; + "UNIQUEUSINGVACUUMVALUESVIEWHEREVIRTUAL"; static const unsigned char aHash[127] = { 92, 80, 107, 91, 0, 4, 0, 0, 114, 0, 83, 0, 0, 95, 44, 76, 93, 0, 106, 109, 97, 90, 0, 10, 0, 0, - 113, 0, 110, 103, 0, 28, 48, 0, 41, 0, 0, 65, 71, + 113, 0, 117, 103, 0, 28, 48, 0, 41, 0, 0, 65, 71, 0, 63, 19, 0, 105, 36, 104, 0, 108, 74, 0, 0, 33, 0, 61, 37, 0, 8, 0, 115, 38, 12, 0, 77, 40, 25, 66, 0, 0, 31, 81, 53, 30, 50, 20, 88, 0, 34, 0, @@ -22,7 +22,7 @@ static int keywordCode(const char *z, int n){ 54, 6, 85, 0, 0, 49, 94, 0, 102, 0, 70, 0, 0, 15, 0, 116, 51, 56, 0, 2, 55, 0, 111, }; - static const unsigned char aNext[116] = { + static const unsigned char aNext[117] = { 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 5, 13, 0, 7, 0, 0, 0, @@ -31,9 +31,9 @@ static int keywordCode(const char *z, int n){ 0, 0, 0, 0, 0, 0, 0, 0, 73, 42, 0, 24, 60, 21, 0, 79, 0, 0, 68, 0, 0, 84, 46, 0, 0, 0, 0, 0, 0, 0, 0, 39, 96, 98, 0, 0, 100, 0, 32, - 0, 14, 27, 78, 0, 57, 89, 0, 35, 0, 62, 0, + 0, 14, 27, 78, 0, 57, 89, 0, 35, 0, 62, 0, 110, }; - static const unsigned char aLen[116] = { + static const unsigned char aLen[117] = { 5, 5, 4, 4, 9, 2, 3, 8, 2, 6, 4, 3, 7, 11, 2, 7, 5, 5, 4, 5, 3, 5, 10, 6, 4, 6, 7, 6, 7, 9, 3, 7, 9, 6, 9, 3, 10, 6, 6, @@ -42,9 +42,9 @@ static int keywordCode(const char *z, int n){ 6, 6, 8, 10, 9, 6, 5, 12, 12, 17, 4, 4, 6, 8, 2, 4, 6, 5, 4, 5, 4, 4, 5, 6, 2, 9, 6, 7, 4, 2, 6, 3, 6, 4, 5, 7, 5, 8, 7, - 5, 5, 8, 3, 4, 5, 6, 5, 6, 6, 4, 5, + 5, 5, 8, 3, 4, 5, 6, 5, 6, 6, 4, 5, 7, }; - static const unsigned short int aOffset[116] = { + static const unsigned short int aOffset[117] = { 0, 4, 7, 10, 10, 14, 19, 21, 26, 27, 32, 34, 36, 42, 51, 52, 57, 61, 65, 67, 71, 74, 78, 86, 91, 94, 99, 105, 108, 113, 118, 122, 128, 136, 141, 150, 152, 162, 167, @@ -53,9 +53,9 @@ static int keywordCode(const char *z, int n){ 269, 275, 281, 289, 296, 305, 311, 316, 328, 328, 344, 348, 352, 358, 359, 366, 369, 373, 378, 381, 386, 390, 394, 397, 403, 405, 414, 420, 427, 430, 430, 433, 436, 442, 446, 450, 457, 461, 469, - 476, 481, 486, 494, 496, 500, 505, 511, 516, 522, 528, 531, + 476, 481, 486, 494, 496, 500, 505, 511, 516, 522, 528, 531, 536, }; - static const unsigned char aCode[116] = { + static const unsigned char aCode[117] = { TK_ABORT, TK_TABLE, TK_JOIN_KW, TK_TEMP, TK_TEMP, TK_OR, TK_ADD, TK_DATABASE, TK_AS, TK_SELECT, TK_THEN, TK_END, TK_DEFAULT, TK_TRANSACTION,TK_ON, @@ -79,7 +79,7 @@ static int keywordCode(const char *z, int n){ TK_REPLACE, TK_JOIN_KW, TK_RESTRICT, TK_PRIMARY, TK_QUERY, TK_JOIN_KW, TK_ROLLBACK, TK_ROW, TK_WHEN, TK_UNION, TK_UNIQUE, TK_USING, TK_VACUUM, TK_VALUES, TK_VIEW, - TK_WHERE, + TK_WHERE, TK_VIRTUAL, }; int h, i; if( n<2 ) return TK_ID; diff --git a/dlls/sqlite/sqlite-source/legacy.c b/dlls/sqlite/sqlite-source/legacy.c index 72e354f0..00c0f9ee 100644 --- a/dlls/sqlite/sqlite-source/legacy.c +++ b/dlls/sqlite/sqlite-source/legacy.c @@ -123,7 +123,7 @@ exec_out: rc = sqlite3ApiExit(0, rc); if( rc!=SQLITE_OK && rc==sqlite3_errcode(db) && pzErrMsg ){ - *pzErrMsg = malloc(1+strlen(sqlite3_errmsg(db))); + *pzErrMsg = sqlite3_malloc(1+strlen(sqlite3_errmsg(db))); if( *pzErrMsg ){ strcpy(*pzErrMsg, sqlite3_errmsg(db)); } @@ -131,5 +131,6 @@ exec_out: *pzErrMsg = 0; } + assert( (rc&db->errMask)==rc ); return rc; } diff --git a/dlls/sqlite/sqlite-source/loadext.c b/dlls/sqlite/sqlite-source/loadext.c new file mode 100644 index 00000000..6af99a64 --- /dev/null +++ b/dlls/sqlite/sqlite-source/loadext.c @@ -0,0 +1,422 @@ +/* +** 2006 June 7 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code used to dynamically load extensions into +** the SQLite library. +*/ +#ifndef SQLITE_OMIT_LOAD_EXTENSION + +#define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */ +#include "sqlite3ext.h" +#include "sqliteInt.h" +#include "os.h" +#include +#include + +/* +** Some API routines are omitted when various features are +** excluded from a build of SQLite. Substitute a NULL pointer +** for any missing APIs. +*/ +#ifndef SQLITE_ENABLE_COLUMN_METADATA +# define sqlite3_column_database_name 0 +# define sqlite3_column_database_name16 0 +# define sqlite3_column_table_name 0 +# define sqlite3_column_table_name16 0 +# define sqlite3_column_origin_name 0 +# define sqlite3_column_origin_name16 0 +# define sqlite3_table_column_metadata 0 +#endif + +#ifdef SQLITE_OMIT_AUTHORIZATION +# define sqlite3_set_authorizer 0 +#endif + +#ifdef SQLITE_OMIT_UTF16 +# define sqlite3_bind_text16 0 +# define sqlite3_collation_needed16 0 +# define sqlite3_column_decltype16 0 +# define sqlite3_column_name16 0 +# define sqlite3_column_text16 0 +# define sqlite3_complete16 0 +# define sqlite3_create_collation16 0 +# define sqlite3_create_function16 0 +# define sqlite3_errmsg16 0 +# define sqlite3_open16 0 +# define sqlite3_prepare16 0 +# define sqlite3_result_error16 0 +# define sqlite3_result_text16 0 +# define sqlite3_result_text16be 0 +# define sqlite3_result_text16le 0 +# define sqlite3_value_text16 0 +# define sqlite3_value_text16be 0 +# define sqlite3_value_text16le 0 +#endif + +#ifdef SQLITE_OMIT_COMPLETE +# define sqlite3_complete 0 +# define sqlite3_complete16 0 +#endif + +#ifdef SQLITE_OMIT_PROGRESS_CALLBACK +# define sqlite3_progress_handler 0 +#endif + +#ifdef SQLITE_OMIT_VIRTUALTABLE +# define sqlite3_create_module 0 +# define sqlite3_declare_vtab 0 +#endif + +#ifdef SQLITE_OMIT_SHARED_CACHE +# define sqlite3_enable_shared_cache 0 +#endif + +#ifdef SQLITE_OMIT_TRACE +# define sqlite3_profile 0 +# define sqlite3_trace 0 +#endif + +#ifdef SQLITE_OMIT_GET_TABLE +# define sqlite3_free_table 0 +# define sqlite3_get_table 0 +#endif + +/* +** The following structure contains pointers to all SQLite API routines. +** A pointer to this structure is passed into extensions when they are +** loaded so that the extension can make calls back into the SQLite +** library. +** +** When adding new APIs, add them to the bottom of this structure +** in order to preserve backwards compatibility. +** +** Extensions that use newer APIs should first call the +** sqlite3_libversion_number() to make sure that the API they +** intend to use is supported by the library. Extensions should +** also check to make sure that the pointer to the function is +** not NULL before calling it. +*/ +const sqlite3_api_routines sqlite3_apis = { + sqlite3_aggregate_context, + sqlite3_aggregate_count, + sqlite3_bind_blob, + sqlite3_bind_double, + sqlite3_bind_int, + sqlite3_bind_int64, + sqlite3_bind_null, + sqlite3_bind_parameter_count, + sqlite3_bind_parameter_index, + sqlite3_bind_parameter_name, + sqlite3_bind_text, + sqlite3_bind_text16, + sqlite3_bind_value, + sqlite3_busy_handler, + sqlite3_busy_timeout, + sqlite3_changes, + sqlite3_close, + sqlite3_collation_needed, + sqlite3_collation_needed16, + sqlite3_column_blob, + sqlite3_column_bytes, + sqlite3_column_bytes16, + sqlite3_column_count, + sqlite3_column_database_name, + sqlite3_column_database_name16, + sqlite3_column_decltype, + sqlite3_column_decltype16, + sqlite3_column_double, + sqlite3_column_int, + sqlite3_column_int64, + sqlite3_column_name, + sqlite3_column_name16, + sqlite3_column_origin_name, + sqlite3_column_origin_name16, + sqlite3_column_table_name, + sqlite3_column_table_name16, + sqlite3_column_text, + sqlite3_column_text16, + sqlite3_column_type, + sqlite3_column_value, + sqlite3_commit_hook, + sqlite3_complete, + sqlite3_complete16, + sqlite3_create_collation, + sqlite3_create_collation16, + sqlite3_create_function, + sqlite3_create_function16, + sqlite3_create_module, + sqlite3_data_count, + sqlite3_db_handle, + sqlite3_declare_vtab, + sqlite3_enable_shared_cache, + sqlite3_errcode, + sqlite3_errmsg, + sqlite3_errmsg16, + sqlite3_exec, + sqlite3_expired, + sqlite3_finalize, + sqlite3_free, + sqlite3_free_table, + sqlite3_get_autocommit, + sqlite3_get_auxdata, + sqlite3_get_table, + 0, /* Was sqlite3_global_recover(), but that function is deprecated */ + sqlite3_interrupt, + sqlite3_last_insert_rowid, + sqlite3_libversion, + sqlite3_libversion_number, + sqlite3_malloc, + sqlite3_mprintf, + sqlite3_open, + sqlite3_open16, + sqlite3_prepare, + sqlite3_prepare16, + sqlite3_profile, + sqlite3_progress_handler, + sqlite3_realloc, + sqlite3_reset, + sqlite3_result_blob, + sqlite3_result_double, + sqlite3_result_error, + sqlite3_result_error16, + sqlite3_result_int, + sqlite3_result_int64, + sqlite3_result_null, + sqlite3_result_text, + sqlite3_result_text16, + sqlite3_result_text16be, + sqlite3_result_text16le, + sqlite3_result_value, + sqlite3_rollback_hook, + sqlite3_set_authorizer, + sqlite3_set_auxdata, + sqlite3_snprintf, + sqlite3_step, + sqlite3_table_column_metadata, + sqlite3_thread_cleanup, + sqlite3_total_changes, + sqlite3_trace, + sqlite3_transfer_bindings, + sqlite3_update_hook, + sqlite3_user_data, + sqlite3_value_blob, + sqlite3_value_bytes, + sqlite3_value_bytes16, + sqlite3_value_double, + sqlite3_value_int, + sqlite3_value_int64, + sqlite3_value_numeric_type, + sqlite3_value_text, + sqlite3_value_text16, + sqlite3_value_text16be, + sqlite3_value_text16le, + sqlite3_value_type, + sqlite3_vmprintf, + /* + ** The original API set ends here. All extensions can call any + ** of the APIs above provided that the pointer is not NULL. But + ** before calling APIs that follow, extension should check the + ** sqlite3_libversion_number() to make sure they are dealing with + ** a library that is new enough to support that API. + ************************************************************************* + */ + sqlite3_overload_function, +}; + +/* +** Attempt to load an SQLite extension library contained in the file +** zFile. The entry point is zProc. zProc may be 0 in which case a +** default entry point name (sqlite3_extension_init) is used. Use +** of the default name is recommended. +** +** Return SQLITE_OK on success and SQLITE_ERROR if something goes wrong. +** +** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with +** error message text. The calling function should free this memory +** by calling sqlite3_free(). +*/ +int sqlite3_load_extension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +){ + void *handle; + int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*); + char *zErrmsg = 0; + void **aHandle; + + /* Ticket #1863. To avoid a creating security problems for older + ** applications that relink against newer versions of SQLite, the + ** ability to run load_extension is turned off by default. One + ** must call sqlite3_enable_load_extension() to turn on extension + ** loading. Otherwise you get the following error. + */ + if( (db->flags & SQLITE_LoadExtension)==0 ){ + if( pzErrMsg ){ + *pzErrMsg = sqlite3_mprintf("not authorized"); + } + return SQLITE_ERROR; + } + + if( zProc==0 ){ + zProc = "sqlite3_extension_init"; + } + + handle = sqlite3OsDlopen(zFile); + if( handle==0 ){ + if( pzErrMsg ){ + *pzErrMsg = sqlite3_mprintf("unable to open shared library [%s]", zFile); + } + return SQLITE_ERROR; + } + xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*)) + sqlite3OsDlsym(handle, zProc); + if( xInit==0 ){ + if( pzErrMsg ){ + *pzErrMsg = sqlite3_mprintf("no entry point [%s] in shared library [%s]", + zProc, zFile); + } + sqlite3OsDlclose(handle); + return SQLITE_ERROR; + }else if( xInit(db, &zErrmsg, &sqlite3_apis) ){ + if( pzErrMsg ){ + *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg); + } + sqlite3_free(zErrmsg); + sqlite3OsDlclose(handle); + return SQLITE_ERROR; + } + + /* Append the new shared library handle to the db->aExtension array. */ + db->nExtension++; + aHandle = sqliteMalloc(sizeof(handle)*db->nExtension); + if( aHandle==0 ){ + return SQLITE_NOMEM; + } + if( db->nExtension>0 ){ + memcpy(aHandle, db->aExtension, sizeof(handle)*(db->nExtension-1)); + } + sqliteFree(db->aExtension); + db->aExtension = aHandle; + + db->aExtension[db->nExtension-1] = handle; + return SQLITE_OK; +} + +/* +** Call this routine when the database connection is closing in order +** to clean up loaded extensions +*/ +void sqlite3CloseExtensions(sqlite3 *db){ + int i; + for(i=0; inExtension; i++){ + sqlite3OsDlclose(db->aExtension[i]); + } + sqliteFree(db->aExtension); +} + +/* +** Enable or disable extension loading. Extension loading is disabled by +** default so as not to open security holes in older applications. +*/ +int sqlite3_enable_load_extension(sqlite3 *db, int onoff){ + if( onoff ){ + db->flags |= SQLITE_LoadExtension; + }else{ + db->flags &= ~SQLITE_LoadExtension; + } + return SQLITE_OK; +} + +/* +** A list of automatically loaded extensions. +** +** This list is shared across threads, so be sure to hold the +** mutex while accessing or changing it. +*/ +static int nAutoExtension = 0; +static void **aAutoExtension = 0; + + +/* +** Register a statically linked extension that is automatically +** loaded by every new database connection. +*/ +int sqlite3_auto_extension(void *xInit){ + int i; + int rc = SQLITE_OK; + sqlite3OsEnterMutex(); + for(i=0; i=nAutoExtension ){ + xInit = 0; + go = 0; + }else{ + xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*)) + aAutoExtension[i]; + } + sqlite3OsLeaveMutex(); + if( xInit && xInit(db, &zErrmsg, &sqlite3_apis) ){ + sqlite3Error(db, SQLITE_ERROR, + "automatic extension loading failed: %s", zErrmsg); + go = 0; + rc = SQLITE_ERROR; + } + } + return rc; +} + +#endif /* SQLITE_OMIT_LOAD_EXTENSION */ diff --git a/dlls/sqlite/sqlite-source/main.c b/dlls/sqlite/sqlite-source/main.c index 4ca733e7..c1f8f9ed 100644 --- a/dlls/sqlite/sqlite-source/main.c +++ b/dlls/sqlite/sqlite-source/main.c @@ -116,6 +116,7 @@ int sqlite3_close(sqlite3 *db){ #endif /* If there are any outstanding VMs, return SQLITE_BUSY. */ + sqlite3ResetInternalSchema(db, 0); if( db->pVdbe ){ sqlite3Error(db, SQLITE_BUSY, "Unable to close due to unfinalised statements"); @@ -133,6 +134,8 @@ int sqlite3_close(sqlite3 *db){ return SQLITE_ERROR; } + sqlite3VtabRollback(db); + for(j=0; jnDb; j++){ struct Db *pDb = &db->aDb[j]; if( pDb->pBt ){ @@ -159,12 +162,20 @@ int sqlite3_close(sqlite3 *db){ sqliteFree(pColl); } sqlite3HashClear(&db->aCollSeq); +#ifndef SQLITE_OMIT_VIRTUALTABLE + for(i=sqliteHashFirst(&db->aModule); i; i=sqliteHashNext(i)){ + Module *pMod = (Module *)sqliteHashData(i); + sqliteFree(pMod); + } + sqlite3HashClear(&db->aModule); +#endif sqlite3HashClear(&db->aFunc); sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */ if( db->pErr ){ sqlite3ValueFree(db->pErr); } + sqlite3CloseExtensions(db); db->magic = SQLITE_MAGIC_ERROR; @@ -195,6 +206,7 @@ void sqlite3RollbackAll(sqlite3 *db){ db->aDb[i].inTrans = 0; } } + sqlite3VtabRollback(db); if( db->flags&SQLITE_InternChanges ){ sqlite3ResetInternalSchema(db, 0); } @@ -211,7 +223,7 @@ void sqlite3RollbackAll(sqlite3 *db){ */ const char *sqlite3ErrStr(int rc){ const char *z; - switch( rc ){ + switch( rc & 0xff ){ case SQLITE_ROW: case SQLITE_DONE: case SQLITE_OK: z = "not an error"; break; @@ -355,6 +367,9 @@ void sqlite3_progress_handler( ** specified number of milliseconds before returning 0. */ int sqlite3_busy_timeout(sqlite3 *db, int ms){ + if( sqlite3SafetyCheck(db) ){ + return SQLITE_MISUSE; + } if( ms>0 ){ db->busyTimeout = ms; sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db); @@ -368,20 +383,35 @@ int sqlite3_busy_timeout(sqlite3 *db, int ms){ ** Cause any pending operation to stop at its earliest opportunity. */ void sqlite3_interrupt(sqlite3 *db){ - if( !sqlite3SafetyCheck(db) ){ - db->flags |= SQLITE_Interrupt; + if( db && (db->magic==SQLITE_MAGIC_OPEN || db->magic==SQLITE_MAGIC_BUSY) ){ + db->u1.isInterrupted = 1; } } /* -** Windows systems should call this routine to free memory that -** is returned in the in the errmsg parameter of sqlite3_open() when -** SQLite is a DLL. For some reason, it does not work to call free() -** directly. +** Memory allocation routines that use SQLites internal memory +** memory allocator. Depending on how SQLite is compiled, the +** internal memory allocator might be just an alias for the +** system default malloc/realloc/free. Or the built-in allocator +** might do extra stuff like put sentinals around buffers to +** check for overruns or look for memory leaks. ** -** Note that we need to call free() not sqliteFree() here. +** Use sqlite3_free() to free memory returned by sqlite3_mprintf(). */ -void sqlite3_free(char *p){ free(p); } +void sqlite3_free(void *p){ if( p ) sqlite3OsFree(p); } +void *sqlite3_malloc(int nByte){ return nByte>0 ? sqlite3OsMalloc(nByte) : 0; } +void *sqlite3_realloc(void *pOld, int nByte){ + if( pOld ){ + if( nByte>0 ){ + return sqlite3OsRealloc(pOld, nByte); + }else{ + sqlite3OsFree(pOld); + return 0; + } + }else{ + return sqlite3_malloc(nByte); + } +} /* ** This function is exactly the same as sqlite3_create_function(), except @@ -411,6 +441,7 @@ int sqlite3CreateFunc( (!xFunc && (!xFinal && xStep)) || (nArg<-1 || nArg>127) || (255<(nName = strlen(zFunctionName))) ){ + sqlite3Error(db, SQLITE_ERROR, "bad parameters"); return SQLITE_ERROR; } @@ -462,6 +493,7 @@ int sqlite3CreateFunc( p->xStep = xStep; p->xFinalize = xFinal; p->pUserData = pUserData; + p->nArg = nArg; } return SQLITE_OK; } @@ -509,6 +541,32 @@ int sqlite3_create_function16( } #endif + +/* +** Declare that a function has been overloaded by a virtual table. +** +** If the function already exists as a regular global function, then +** this routine is a no-op. If the function does not exist, then create +** a new one that always throws a run-time error. +** +** When virtual tables intend to provide an overloaded function, they +** should call this routine to make sure the global function exists. +** A global function must exist in order for name resolution to work +** properly. +*/ +int sqlite3_overload_function( + sqlite3 *db, + const char *zName, + int nArg +){ + int nName = strlen(zName); + if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){ + sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8, + 0, sqlite3InvalidFunction, 0, 0); + } + return sqlite3ApiExit(db, SQLITE_OK); +} + #ifndef SQLITE_OMIT_TRACE /* ** Register a trace function. The pArg from the previously registered trace @@ -731,7 +789,7 @@ int sqlite3_errcode(sqlite3 *db){ if( sqlite3SafetyCheck(db) ){ return SQLITE_MISUSE; } - return db->errCode; + return db->errCode & db->errMask; } /* @@ -809,14 +867,22 @@ static int openDatabase( /* Allocate the sqlite data structure */ db = sqliteMalloc( sizeof(sqlite3) ); if( db==0 ) goto opendb_out; + db->errMask = 0xff; db->priorNewRowid = 0; db->magic = SQLITE_MAGIC_BUSY; db->nDb = 2; db->aDb = db->aDbStatic; db->autoCommit = 1; - db->flags |= SQLITE_ShortColNames; + db->flags |= SQLITE_ShortColNames +#if SQLITE_DEFAULT_FILE_FORMAT<4 + | SQLITE_LegacyFileFmt +#endif + ; sqlite3HashInit(&db->aFunc, SQLITE_HASH_STRING, 0); sqlite3HashInit(&db->aCollSeq, SQLITE_HASH_STRING, 0); +#ifndef SQLITE_OMIT_VIRTUALTABLE + sqlite3HashInit(&db->aModule, SQLITE_HASH_STRING, 0); +#endif /* Add the default collation sequence BINARY. BINARY works for both UTF-8 ** and UTF-16, so add a version for each to avoid any unnecessary @@ -851,9 +917,6 @@ static int openDatabase( } db->aDb[0].pSchema = sqlite3SchemaGet(db->aDb[0].pBt); db->aDb[1].pSchema = sqlite3SchemaGet(0); - if( db->aDb[0].pSchema ){ - ENC(db) = SQLITE_UTF8; - } /* The default safety_level for the main database is 'full'; for the temp @@ -871,11 +934,30 @@ static int openDatabase( ** is accessed. */ if( !sqlite3MallocFailed() ){ - sqlite3RegisterBuiltinFunctions(db); sqlite3Error(db, SQLITE_OK, 0); + sqlite3RegisterBuiltinFunctions(db); } db->magic = SQLITE_MAGIC_OPEN; + /* Load automatic extensions - extensions that have been registered + ** using the sqlite3_automatic_extension() API. + */ + (void)sqlite3AutoLoadExtensions(db); + +#ifdef SQLITE_ENABLE_FTS1 + { + extern int sqlite3Fts1Init(sqlite3*); + sqlite3Fts1Init(db); + } +#endif + +#ifdef SQLITE_ENABLE_FTS2 + { + extern int sqlite3Fts2Init(sqlite3*); + sqlite3Fts2Init(db); + } +#endif + opendb_out: if( SQLITE_NOMEM==(rc = sqlite3_errcode(db)) ){ sqlite3_close(db); @@ -963,6 +1045,7 @@ int sqlite3_reset(sqlite3_stmt *pStmt){ }else{ rc = sqlite3VdbeReset((Vdbe*)pStmt); sqlite3VdbeMakeReady((Vdbe*)pStmt, -1, 0, 0, 0); + assert( (rc & (sqlite3_db_handle(pStmt)->errMask))==rc ); } return rc; } @@ -1230,3 +1313,30 @@ error_out: return sqlite3ApiExit(db, rc); } #endif + +/* +** Set all the parameters in the compiled SQL statement to NULL. +*/ +int sqlite3_clear_bindings(sqlite3_stmt *pStmt){ + int i; + int rc = SQLITE_OK; + for(i=1; rc==SQLITE_OK && i<=sqlite3_bind_parameter_count(pStmt); i++){ + rc = sqlite3_bind_null(pStmt, i); + } + return rc; +} + +/* +** Sleep for a little while. Return the amount of time slept. +*/ +int sqlite3_sleep(int ms){ + return sqlite3OsSleep(ms); +} + +/* +** Enable or disable the extended result codes. +*/ +int sqlite3_extended_result_codes(sqlite3 *db, int onoff){ + db->errMask = onoff ? 0xffffffff : 0xff; + return SQLITE_OK; +} diff --git a/dlls/sqlite/sqlite-source/opcodes.c b/dlls/sqlite/sqlite-source/opcodes.c index 9f1bdbaa..4f796476 100644 --- a/dlls/sqlite/sqlite-source/opcodes.c +++ b/dlls/sqlite/sqlite-source/opcodes.c @@ -3,145 +3,147 @@ #if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) const char *const sqlite3OpcodeNames[] = { "?", /* 1 */ "MemLoad", - /* 2 */ "Column", - /* 3 */ "SetCookie", - /* 4 */ "IfMemPos", - /* 5 */ "Sequence", - /* 6 */ "MoveGt", - /* 7 */ "RowKey", - /* 8 */ "OpenWrite", - /* 9 */ "If", - /* 10 */ "Pop", - /* 11 */ "CollSeq", - /* 12 */ "OpenRead", - /* 13 */ "Expire", - /* 14 */ "AutoCommit", - /* 15 */ "IntegrityCk", + /* 2 */ "VNext", + /* 3 */ "Column", + /* 4 */ "SetCookie", + /* 5 */ "IfMemPos", + /* 6 */ "Sequence", + /* 7 */ "MoveGt", + /* 8 */ "RowKey", + /* 9 */ "OpenWrite", + /* 10 */ "If", + /* 11 */ "Pop", + /* 12 */ "VRowid", + /* 13 */ "CollSeq", + /* 14 */ "OpenRead", + /* 15 */ "Expire", /* 16 */ "Not", - /* 17 */ "Sort", - /* 18 */ "Function", - /* 19 */ "Noop", - /* 20 */ "Return", - /* 21 */ "NewRowid", - /* 22 */ "IfMemNeg", - /* 23 */ "Variable", - /* 24 */ "String", - /* 25 */ "RealAffinity", - /* 26 */ "ParseSchema", - /* 27 */ "Close", - /* 28 */ "CreateIndex", - /* 29 */ "IsUnique", - /* 30 */ "IdxIsNull", - /* 31 */ "NotFound", - /* 32 */ "Int64", - /* 33 */ "MustBeInt", - /* 34 */ "Halt", - /* 35 */ "Rowid", - /* 36 */ "IdxLT", - /* 37 */ "AddImm", - /* 38 */ "Statement", - /* 39 */ "RowData", - /* 40 */ "MemMax", - /* 41 */ "Push", - /* 42 */ "NotExists", - /* 43 */ "MemIncr", - /* 44 */ "Gosub", - /* 45 */ "Integer", - /* 46 */ "MemInt", - /* 47 */ "Prev", - /* 48 */ "CreateTable", - /* 49 */ "Last", - /* 50 */ "IdxRowid", - /* 51 */ "MakeIdxRec", - /* 52 */ "ResetCount", - /* 53 */ "FifoWrite", - /* 54 */ "Callback", - /* 55 */ "ContextPush", - /* 56 */ "DropTrigger", - /* 57 */ "DropIndex", - /* 58 */ "IdxGE", - /* 59 */ "Or", - /* 60 */ "And", - /* 61 */ "IdxDelete", - /* 62 */ "Vacuum", - /* 63 */ "MoveLe", - /* 64 */ "IsNull", - /* 65 */ "NotNull", - /* 66 */ "Ne", - /* 67 */ "Eq", - /* 68 */ "Gt", - /* 69 */ "Le", - /* 70 */ "Lt", - /* 71 */ "Ge", - /* 72 */ "IfNot", - /* 73 */ "BitAnd", - /* 74 */ "BitOr", - /* 75 */ "ShiftLeft", - /* 76 */ "ShiftRight", - /* 77 */ "Add", - /* 78 */ "Subtract", - /* 79 */ "Multiply", - /* 80 */ "Divide", - /* 81 */ "Remainder", - /* 82 */ "Concat", - /* 83 */ "Negative", - /* 84 */ "DropTable", - /* 85 */ "BitNot", - /* 86 */ "String8", - /* 87 */ "MakeRecord", - /* 88 */ "Delete", - /* 89 */ "AggFinal", - /* 90 */ "Dup", - /* 91 */ "Goto", - /* 92 */ "TableLock", - /* 93 */ "FifoRead", - /* 94 */ "Clear", - /* 95 */ "IdxGT", - /* 96 */ "MoveLt", - /* 97 */ "VerifyCookie", - /* 98 */ "AggStep", - /* 99 */ "Pull", - /* 100 */ "SetNumColumns", - /* 101 */ "AbsValue", - /* 102 */ "Transaction", - /* 103 */ "ContextPop", - /* 104 */ "Next", - /* 105 */ "IdxInsert", - /* 106 */ "Distinct", - /* 107 */ "Insert", - /* 108 */ "Destroy", - /* 109 */ "ReadCookie", - /* 110 */ "ForceInt", - /* 111 */ "LoadAnalysis", - /* 112 */ "OpenVirtual", - /* 113 */ "Explain", - /* 114 */ "IfMemZero", - /* 115 */ "OpenPseudo", - /* 116 */ "Null", - /* 117 */ "Blob", - /* 118 */ "MemStore", - /* 119 */ "Rewind", - /* 120 */ "MoveGe", - /* 121 */ "MemMove", - /* 122 */ "MemNull", - /* 123 */ "Found", - /* 124 */ "Real", - /* 125 */ "HexBlob", - /* 126 */ "NullRow", - /* 127 */ "NotUsed_127", - /* 128 */ "NotUsed_128", - /* 129 */ "NotUsed_129", - /* 130 */ "NotUsed_130", - /* 131 */ "NotUsed_131", - /* 132 */ "NotUsed_132", - /* 133 */ "NotUsed_133", - /* 134 */ "NotUsed_134", + /* 17 */ "AutoCommit", + /* 18 */ "IntegrityCk", + /* 19 */ "Sort", + /* 20 */ "Function", + /* 21 */ "Noop", + /* 22 */ "Return", + /* 23 */ "NewRowid", + /* 24 */ "IfMemNeg", + /* 25 */ "Variable", + /* 26 */ "String", + /* 27 */ "RealAffinity", + /* 28 */ "ParseSchema", + /* 29 */ "VOpen", + /* 30 */ "Close", + /* 31 */ "CreateIndex", + /* 32 */ "IsUnique", + /* 33 */ "NotFound", + /* 34 */ "Int64", + /* 35 */ "MustBeInt", + /* 36 */ "Halt", + /* 37 */ "Rowid", + /* 38 */ "IdxLT", + /* 39 */ "AddImm", + /* 40 */ "Statement", + /* 41 */ "RowData", + /* 42 */ "MemMax", + /* 43 */ "Push", + /* 44 */ "NotExists", + /* 45 */ "MemIncr", + /* 46 */ "Gosub", + /* 47 */ "Integer", + /* 48 */ "MemInt", + /* 49 */ "Prev", + /* 50 */ "VColumn", + /* 51 */ "CreateTable", + /* 52 */ "Last", + /* 53 */ "IdxRowid", + /* 54 */ "MakeIdxRec", + /* 55 */ "ResetCount", + /* 56 */ "FifoWrite", + /* 57 */ "Callback", + /* 58 */ "ContextPush", + /* 59 */ "DropTrigger", + /* 60 */ "DropIndex", + /* 61 */ "Or", + /* 62 */ "And", + /* 63 */ "IdxGE", + /* 64 */ "IdxDelete", + /* 65 */ "Vacuum", + /* 66 */ "IsNull", + /* 67 */ "NotNull", + /* 68 */ "Ne", + /* 69 */ "Eq", + /* 70 */ "Gt", + /* 71 */ "Le", + /* 72 */ "Lt", + /* 73 */ "Ge", + /* 74 */ "MoveLe", + /* 75 */ "BitAnd", + /* 76 */ "BitOr", + /* 77 */ "ShiftLeft", + /* 78 */ "ShiftRight", + /* 79 */ "Add", + /* 80 */ "Subtract", + /* 81 */ "Multiply", + /* 82 */ "Divide", + /* 83 */ "Remainder", + /* 84 */ "Concat", + /* 85 */ "IfNot", + /* 86 */ "Negative", + /* 87 */ "DropTable", + /* 88 */ "BitNot", + /* 89 */ "String8", + /* 90 */ "MakeRecord", + /* 91 */ "Delete", + /* 92 */ "AggFinal", + /* 93 */ "Dup", + /* 94 */ "Goto", + /* 95 */ "TableLock", + /* 96 */ "FifoRead", + /* 97 */ "Clear", + /* 98 */ "IdxGT", + /* 99 */ "MoveLt", + /* 100 */ "VerifyCookie", + /* 101 */ "AggStep", + /* 102 */ "Pull", + /* 103 */ "SetNumColumns", + /* 104 */ "AbsValue", + /* 105 */ "Transaction", + /* 106 */ "VFilter", + /* 107 */ "VDestroy", + /* 108 */ "ContextPop", + /* 109 */ "Next", + /* 110 */ "IdxInsert", + /* 111 */ "Distinct", + /* 112 */ "Insert", + /* 113 */ "Destroy", + /* 114 */ "ReadCookie", + /* 115 */ "ForceInt", + /* 116 */ "LoadAnalysis", + /* 117 */ "Explain", + /* 118 */ "IfMemZero", + /* 119 */ "OpenPseudo", + /* 120 */ "OpenEphemeral", + /* 121 */ "Null", + /* 122 */ "Blob", + /* 123 */ "MemStore", + /* 124 */ "Rewind", + /* 125 */ "MoveGe", + /* 126 */ "Real", + /* 127 */ "HexBlob", + /* 128 */ "VBegin", + /* 129 */ "VUpdate", + /* 130 */ "VCreate", + /* 131 */ "MemMove", + /* 132 */ "MemNull", + /* 133 */ "Found", + /* 134 */ "NullRow", /* 135 */ "NotUsed_135", /* 136 */ "NotUsed_136", - /* 137 */ "ToText", - /* 138 */ "ToBlob", - /* 139 */ "ToNumeric", - /* 140 */ "ToInt", - /* 141 */ "ToReal", + /* 137 */ "NotUsed_137", + /* 138 */ "NotUsed_138", + /* 139 */ "ToText", + /* 140 */ "ToBlob", + /* 141 */ "ToNumeric", + /* 142 */ "ToInt", + /* 143 */ "ToReal", }; #endif diff --git a/dlls/sqlite/sqlite-source/opcodes.h b/dlls/sqlite/sqlite-source/opcodes.h index e768d603..69ffced3 100644 --- a/dlls/sqlite/sqlite-source/opcodes.h +++ b/dlls/sqlite/sqlite-source/opcodes.h @@ -1,159 +1,161 @@ /* Automatically generated. Do not edit */ /* See the mkopcodeh.awk script for details */ #define OP_MemLoad 1 -#define OP_HexBlob 125 /* same as TK_BLOB */ -#define OP_Column 2 -#define OP_SetCookie 3 -#define OP_IfMemPos 4 -#define OP_Real 124 /* same as TK_FLOAT */ -#define OP_Sequence 5 -#define OP_MoveGt 6 -#define OP_Ge 71 /* same as TK_GE */ -#define OP_RowKey 7 -#define OP_Eq 67 /* same as TK_EQ */ -#define OP_OpenWrite 8 -#define OP_NotNull 65 /* same as TK_NOTNULL */ -#define OP_If 9 -#define OP_ToInt 140 /* same as TK_TO_INT */ -#define OP_String8 86 /* same as TK_STRING */ -#define OP_Pop 10 -#define OP_CollSeq 11 -#define OP_OpenRead 12 -#define OP_Expire 13 -#define OP_AutoCommit 14 -#define OP_Gt 68 /* same as TK_GT */ -#define OP_IntegrityCk 15 -#define OP_Sort 17 -#define OP_Function 18 -#define OP_And 60 /* same as TK_AND */ -#define OP_Subtract 78 /* same as TK_MINUS */ -#define OP_Noop 19 -#define OP_Return 20 -#define OP_Remainder 81 /* same as TK_REM */ -#define OP_NewRowid 21 -#define OP_Multiply 79 /* same as TK_STAR */ -#define OP_IfMemNeg 22 -#define OP_Variable 23 -#define OP_String 24 -#define OP_RealAffinity 25 -#define OP_ParseSchema 26 -#define OP_Close 27 -#define OP_CreateIndex 28 -#define OP_IsUnique 29 -#define OP_IdxIsNull 30 -#define OP_NotFound 31 -#define OP_Int64 32 -#define OP_MustBeInt 33 -#define OP_Halt 34 -#define OP_Rowid 35 -#define OP_IdxLT 36 -#define OP_AddImm 37 -#define OP_Statement 38 -#define OP_RowData 39 -#define OP_MemMax 40 -#define OP_Push 41 -#define OP_Or 59 /* same as TK_OR */ -#define OP_NotExists 42 -#define OP_MemIncr 43 -#define OP_Gosub 44 -#define OP_Divide 80 /* same as TK_SLASH */ -#define OP_Integer 45 -#define OP_ToNumeric 139 /* same as TK_TO_NUMERIC*/ -#define OP_MemInt 46 -#define OP_Prev 47 -#define OP_Concat 82 /* same as TK_CONCAT */ -#define OP_BitAnd 73 /* same as TK_BITAND */ -#define OP_CreateTable 48 -#define OP_Last 49 -#define OP_IsNull 64 /* same as TK_ISNULL */ -#define OP_IdxRowid 50 -#define OP_MakeIdxRec 51 -#define OP_ShiftRight 76 /* same as TK_RSHIFT */ -#define OP_ResetCount 52 -#define OP_FifoWrite 53 -#define OP_Callback 54 -#define OP_ContextPush 55 -#define OP_DropTrigger 56 -#define OP_DropIndex 57 -#define OP_IdxGE 58 -#define OP_IdxDelete 61 -#define OP_Vacuum 62 -#define OP_MoveLe 63 -#define OP_IfNot 72 -#define OP_DropTable 84 -#define OP_MakeRecord 87 -#define OP_ToBlob 138 /* same as TK_TO_BLOB */ -#define OP_Delete 88 -#define OP_AggFinal 89 -#define OP_ShiftLeft 75 /* same as TK_LSHIFT */ -#define OP_Dup 90 -#define OP_Goto 91 -#define OP_TableLock 92 -#define OP_FifoRead 93 -#define OP_Clear 94 -#define OP_IdxGT 95 -#define OP_MoveLt 96 -#define OP_Le 69 /* same as TK_LE */ -#define OP_VerifyCookie 97 -#define OP_AggStep 98 -#define OP_Pull 99 -#define OP_ToText 137 /* same as TK_TO_TEXT */ +#define OP_VNext 2 +#define OP_HexBlob 127 /* same as TK_BLOB */ +#define OP_Column 3 +#define OP_SetCookie 4 +#define OP_IfMemPos 5 +#define OP_Real 126 /* same as TK_FLOAT */ +#define OP_Sequence 6 +#define OP_MoveGt 7 +#define OP_Ge 73 /* same as TK_GE */ +#define OP_RowKey 8 +#define OP_Eq 69 /* same as TK_EQ */ +#define OP_OpenWrite 9 +#define OP_NotNull 67 /* same as TK_NOTNULL */ +#define OP_If 10 +#define OP_ToInt 142 /* same as TK_TO_INT */ +#define OP_String8 89 /* same as TK_STRING */ +#define OP_Pop 11 +#define OP_VRowid 12 +#define OP_CollSeq 13 +#define OP_OpenRead 14 +#define OP_Expire 15 +#define OP_AutoCommit 17 +#define OP_Gt 70 /* same as TK_GT */ +#define OP_IntegrityCk 18 +#define OP_Sort 19 +#define OP_Function 20 +#define OP_And 62 /* same as TK_AND */ +#define OP_Subtract 80 /* same as TK_MINUS */ +#define OP_Noop 21 +#define OP_Return 22 +#define OP_Remainder 83 /* same as TK_REM */ +#define OP_NewRowid 23 +#define OP_Multiply 81 /* same as TK_STAR */ +#define OP_IfMemNeg 24 +#define OP_Variable 25 +#define OP_String 26 +#define OP_RealAffinity 27 +#define OP_ParseSchema 28 +#define OP_VOpen 29 +#define OP_Close 30 +#define OP_CreateIndex 31 +#define OP_IsUnique 32 +#define OP_NotFound 33 +#define OP_Int64 34 +#define OP_MustBeInt 35 +#define OP_Halt 36 +#define OP_Rowid 37 +#define OP_IdxLT 38 +#define OP_AddImm 39 +#define OP_Statement 40 +#define OP_RowData 41 +#define OP_MemMax 42 +#define OP_Push 43 +#define OP_Or 61 /* same as TK_OR */ +#define OP_NotExists 44 +#define OP_MemIncr 45 +#define OP_Gosub 46 +#define OP_Divide 82 /* same as TK_SLASH */ +#define OP_Integer 47 +#define OP_ToNumeric 141 /* same as TK_TO_NUMERIC*/ +#define OP_MemInt 48 +#define OP_Prev 49 +#define OP_Concat 84 /* same as TK_CONCAT */ +#define OP_BitAnd 75 /* same as TK_BITAND */ +#define OP_VColumn 50 +#define OP_CreateTable 51 +#define OP_Last 52 +#define OP_IsNull 66 /* same as TK_ISNULL */ +#define OP_IdxRowid 53 +#define OP_MakeIdxRec 54 +#define OP_ShiftRight 78 /* same as TK_RSHIFT */ +#define OP_ResetCount 55 +#define OP_FifoWrite 56 +#define OP_Callback 57 +#define OP_ContextPush 58 +#define OP_DropTrigger 59 +#define OP_DropIndex 60 +#define OP_IdxGE 63 +#define OP_IdxDelete 64 +#define OP_Vacuum 65 +#define OP_MoveLe 74 +#define OP_IfNot 85 +#define OP_DropTable 87 +#define OP_MakeRecord 90 +#define OP_ToBlob 140 /* same as TK_TO_BLOB */ +#define OP_Delete 91 +#define OP_AggFinal 92 +#define OP_ShiftLeft 77 /* same as TK_LSHIFT */ +#define OP_Dup 93 +#define OP_Goto 94 +#define OP_TableLock 95 +#define OP_FifoRead 96 +#define OP_Clear 97 +#define OP_IdxGT 98 +#define OP_MoveLt 99 +#define OP_Le 71 /* same as TK_LE */ +#define OP_VerifyCookie 100 +#define OP_AggStep 101 +#define OP_Pull 102 +#define OP_ToText 139 /* same as TK_TO_TEXT */ #define OP_Not 16 /* same as TK_NOT */ -#define OP_ToReal 141 /* same as TK_TO_REAL */ -#define OP_SetNumColumns 100 -#define OP_AbsValue 101 -#define OP_Transaction 102 -#define OP_Negative 83 /* same as TK_UMINUS */ -#define OP_Ne 66 /* same as TK_NE */ -#define OP_ContextPop 103 -#define OP_BitOr 74 /* same as TK_BITOR */ -#define OP_Next 104 -#define OP_IdxInsert 105 -#define OP_Distinct 106 -#define OP_Lt 70 /* same as TK_LT */ -#define OP_Insert 107 -#define OP_Destroy 108 -#define OP_ReadCookie 109 -#define OP_ForceInt 110 -#define OP_LoadAnalysis 111 -#define OP_OpenVirtual 112 -#define OP_Explain 113 -#define OP_IfMemZero 114 -#define OP_OpenPseudo 115 -#define OP_Null 116 -#define OP_Blob 117 -#define OP_Add 77 /* same as TK_PLUS */ -#define OP_MemStore 118 -#define OP_Rewind 119 -#define OP_MoveGe 120 -#define OP_BitNot 85 /* same as TK_BITNOT */ -#define OP_MemMove 121 -#define OP_MemNull 122 -#define OP_Found 123 -#define OP_NullRow 126 +#define OP_ToReal 143 /* same as TK_TO_REAL */ +#define OP_SetNumColumns 103 +#define OP_AbsValue 104 +#define OP_Transaction 105 +#define OP_VFilter 106 +#define OP_Negative 86 /* same as TK_UMINUS */ +#define OP_Ne 68 /* same as TK_NE */ +#define OP_VDestroy 107 +#define OP_ContextPop 108 +#define OP_BitOr 76 /* same as TK_BITOR */ +#define OP_Next 109 +#define OP_IdxInsert 110 +#define OP_Distinct 111 +#define OP_Lt 72 /* same as TK_LT */ +#define OP_Insert 112 +#define OP_Destroy 113 +#define OP_ReadCookie 114 +#define OP_ForceInt 115 +#define OP_LoadAnalysis 116 +#define OP_Explain 117 +#define OP_IfMemZero 118 +#define OP_OpenPseudo 119 +#define OP_OpenEphemeral 120 +#define OP_Null 121 +#define OP_Blob 122 +#define OP_Add 79 /* same as TK_PLUS */ +#define OP_MemStore 123 +#define OP_Rewind 124 +#define OP_MoveGe 125 +#define OP_VBegin 128 +#define OP_VUpdate 129 +#define OP_BitNot 88 /* same as TK_BITNOT */ +#define OP_VCreate 130 +#define OP_MemMove 131 +#define OP_MemNull 132 +#define OP_Found 133 +#define OP_NullRow 134 /* The following opcode values are never used */ -#define OP_NotUsed_127 127 -#define OP_NotUsed_128 128 -#define OP_NotUsed_129 129 -#define OP_NotUsed_130 130 -#define OP_NotUsed_131 131 -#define OP_NotUsed_132 132 -#define OP_NotUsed_133 133 -#define OP_NotUsed_134 134 #define OP_NotUsed_135 135 #define OP_NotUsed_136 136 +#define OP_NotUsed_137 137 +#define OP_NotUsed_138 138 /* Opcodes that are guaranteed to never push a value onto the stack ** contain a 1 their corresponding position of the following mask ** set. See the opcodeNoPush() function in vdbeaux.c */ -#define NOPUSH_MASK_0 0x7f58 -#define NOPUSH_MASK_1 0xee5b -#define NOPUSH_MASK_2 0x9f76 -#define NOPUSH_MASK_3 0xfff2 +#define NOPUSH_MASK_0 0xeeb4 +#define NOPUSH_MASK_1 0x796b +#define NOPUSH_MASK_2 0x7ddb +#define NOPUSH_MASK_3 0xff92 #define NOPUSH_MASK_4 0xffff -#define NOPUSH_MASK_5 0xdb3b -#define NOPUSH_MASK_6 0xcfdf -#define NOPUSH_MASK_7 0x49cd -#define NOPUSH_MASK_8 0x3e00 +#define NOPUSH_MASK_5 0xd9ef +#define NOPUSH_MASK_6 0xfefe +#define NOPUSH_MASK_7 0x39d9 +#define NOPUSH_MASK_8 0xf867 #define NOPUSH_MASK_9 0x0000 diff --git a/dlls/sqlite/sqlite-source/os.h b/dlls/sqlite/sqlite-source/os.h index b294346b..0fe7b156 100644 --- a/dlls/sqlite/sqlite-source/os.h +++ b/dlls/sqlite/sqlite-source/os.h @@ -27,12 +27,19 @@ # if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__) # define OS_WIN 1 # define OS_UNIX 0 +# define OS_OS2 0 +# elif defined(_EMX_) || defined(_OS2) || defined(OS2) || defined(_OS2_) || defined(__OS2__) +# define OS_WIN 0 +# define OS_UNIX 0 +# define OS_OS2 1 # else # define OS_WIN 0 # define OS_UNIX 1 +# define OS_OS2 0 # endif # else # define OS_UNIX 0 +# define OS_OS2 0 # endif #else # ifndef OS_WIN @@ -47,6 +54,14 @@ #if OS_WIN # include # define SQLITE_TEMPNAME_SIZE (MAX_PATH+50) +#elif OS_OS2 +# define INCL_DOSDATETIME +# define INCL_DOSFILEMGR +# define INCL_DOSERRORS +# define INCL_DOSMISC +# define INCL_DOSPROCESS +# include +# define SQLITE_TEMPNAME_SIZE (CCHMAXPATHCOMP) #else # define SQLITE_TEMPNAME_SIZE 200 #endif @@ -66,13 +81,25 @@ ** prefix to reflect your program's name, so that if your program exits ** prematurely, old temporary files can be easily identified. This can be done ** using -DTEMP_FILE_PREFIX=myprefix_ on the compiler command line. +** +** 2006-10-31: The default prefix used to be "sqlite_". But then +** Mcafee started using SQLite in their anti-virus product and it +** started putting files with the "sqlite" name in the c:/temp folder. +** This annoyed many windows users. Those users would then do a +** Google search for "sqlite", find the telephone numbers of the +** developers and call to wake them up at night and complain. +** For this reason, the default name prefix is changed to be "sqlite" +** spelled backwards. So the temp files are still identified, but +** anybody smart enough to figure out the code is also likely smart +** enough to know that calling the developer will not help get rid +** of the file. */ #ifndef TEMP_FILE_PREFIX -# define TEMP_FILE_PREFIX "sqlite_" +# define TEMP_FILE_PREFIX "etilqs_" #endif /* -** Define the interfaces for Unix and for Windows. +** Define the interfaces for Unix, Windows, and OS/2. */ #if OS_UNIX #define sqlite3OsOpenReadWrite sqlite3UnixOpenReadWrite @@ -95,6 +122,9 @@ #define sqlite3OsRealloc sqlite3GenericRealloc #define sqlite3OsFree sqlite3GenericFree #define sqlite3OsAllocationSize sqlite3GenericAllocationSize +#define sqlite3OsDlopen sqlite3UnixDlopen +#define sqlite3OsDlsym sqlite3UnixDlsym +#define sqlite3OsDlclose sqlite3UnixDlclose #endif #if OS_WIN #define sqlite3OsOpenReadWrite sqlite3WinOpenReadWrite @@ -117,7 +147,38 @@ #define sqlite3OsRealloc sqlite3GenericRealloc #define sqlite3OsFree sqlite3GenericFree #define sqlite3OsAllocationSize sqlite3GenericAllocationSize +#define sqlite3OsDlopen sqlite3WinDlopen +#define sqlite3OsDlsym sqlite3WinDlsym +#define sqlite3OsDlclose sqlite3WinDlclose #endif +#if OS_OS2 +#define sqlite3OsOpenReadWrite sqlite3Os2OpenReadWrite +#define sqlite3OsOpenExclusive sqlite3Os2OpenExclusive +#define sqlite3OsOpenReadOnly sqlite3Os2OpenReadOnly +#define sqlite3OsDelete sqlite3Os2Delete +#define sqlite3OsFileExists sqlite3Os2FileExists +#define sqlite3OsFullPathname sqlite3Os2FullPathname +#define sqlite3OsIsDirWritable sqlite3Os2IsDirWritable +#define sqlite3OsSyncDirectory sqlite3Os2SyncDirectory +#define sqlite3OsTempFileName sqlite3Os2TempFileName +#define sqlite3OsRandomSeed sqlite3Os2RandomSeed +#define sqlite3OsSleep sqlite3Os2Sleep +#define sqlite3OsCurrentTime sqlite3Os2CurrentTime +#define sqlite3OsEnterMutex sqlite3Os2EnterMutex +#define sqlite3OsLeaveMutex sqlite3Os2LeaveMutex +#define sqlite3OsInMutex sqlite3Os2InMutex +#define sqlite3OsThreadSpecificData sqlite3Os2ThreadSpecificData +#define sqlite3OsMalloc sqlite3GenericMalloc +#define sqlite3OsRealloc sqlite3GenericRealloc +#define sqlite3OsFree sqlite3GenericFree +#define sqlite3OsAllocationSize sqlite3GenericAllocationSize +#define sqlite3OsDlopen sqlite3Os2Dlopen +#define sqlite3OsDlsym sqlite3Os2Dlsym +#define sqlite3OsDlclose sqlite3Os2Dlclose +#endif + + + /* ** If using an alternative OS interface, then we must have an "os_other.h" @@ -297,6 +358,9 @@ void *sqlite3OsMalloc(int); void *sqlite3OsRealloc(void *, int); void sqlite3OsFree(void *); int sqlite3OsAllocationSize(void *); +void *sqlite3OsDlopen(const char*); +void *sqlite3OsDlsym(void*, const char*); +int sqlite3OsDlclose(void*); /* ** If the SQLITE_ENABLE_REDEF_IO macro is defined, then the OS-layer @@ -341,16 +405,26 @@ struct sqlite3OsVtbl { void *(*xRealloc)(void *, int); void (*xFree)(void *); int (*xAllocationSize)(void *); + + void *(*xDlopen)(const char*); + void *(*xDlsym)(void*, const char*); + int (*xDlclose)(void*); }; /* Macro used to comment out routines that do not exists when there is -** no disk I/O +** no disk I/O or extension loading */ #ifdef SQLITE_OMIT_DISKIO # define IF_DISKIO(X) 0 #else # define IF_DISKIO(X) X #endif +#ifdef SQLITE_OMIT_LOAD_EXTENSION +# define IF_DLOPEN(X) 0 +#else +# define IF_DLOPEN(X) X +#endif + #ifdef _SQLITE_OS_C_ /* @@ -376,7 +450,10 @@ struct sqlite3OsVtbl { sqlite3OsMalloc, sqlite3OsRealloc, sqlite3OsFree, - sqlite3OsAllocationSize + sqlite3OsAllocationSize, + IF_DLOPEN( sqlite3OsDlopen ), + IF_DLOPEN( sqlite3OsDlsym ), + IF_DLOPEN( sqlite3OsDlclose ), }; #else /* diff --git a/dlls/sqlite/sqlite-source/os_common.h b/dlls/sqlite/sqlite-source/os_common.h index d65c352d..863e3cde 100644 --- a/dlls/sqlite/sqlite-source/os_common.h +++ b/dlls/sqlite/sqlite-source/os_common.h @@ -92,25 +92,25 @@ int sqlite3_io_error_hit = 0; int sqlite3_io_error_pending = 0; int sqlite3_diskfull_pending = 0; int sqlite3_diskfull = 0; -#define SimulateIOError(A) \ +#define SimulateIOError(CODE) \ if( sqlite3_io_error_pending ) \ - if( sqlite3_io_error_pending-- == 1 ){ local_ioerr(); return A; } + if( sqlite3_io_error_pending-- == 1 ){ local_ioerr(); CODE; } static void local_ioerr(){ sqlite3_io_error_hit = 1; /* Really just a place to set a breakpoint */ } -#define SimulateDiskfullError \ +#define SimulateDiskfullError(CODE) \ if( sqlite3_diskfull_pending ){ \ if( sqlite3_diskfull_pending == 1 ){ \ local_ioerr(); \ sqlite3_diskfull = 1; \ - return SQLITE_FULL; \ + CODE; \ }else{ \ sqlite3_diskfull_pending--; \ } \ } #else #define SimulateIOError(A) -#define SimulateDiskfullError +#define SimulateDiskfullError(A) #endif /* diff --git a/dlls/sqlite/sqlite-source/os_unix.c b/dlls/sqlite/sqlite-source/os_unix.c index 6dcc43eb..0bb8a90e 100644 --- a/dlls/sqlite/sqlite-source/os_unix.c +++ b/dlls/sqlite/sqlite-source/os_unix.c @@ -16,6 +16,8 @@ #include "os.h" #if OS_UNIX /* This file is used on unix only */ +/* #define SQLITE_ENABLE_LOCKING_STYLE 0 */ + /* ** These #defines should enable >2GB file support on Posix if the ** underlying operating system supports it. If the OS lacks @@ -47,6 +49,11 @@ #include #include #include +#ifdef SQLITE_ENABLE_LOCKING_STYLE +#include +#include +#include +#endif /* SQLITE_ENABLE_LOCKING_STYLE */ /* ** If we are to be thread-safe, include the pthreads header and define @@ -75,6 +82,9 @@ struct unixFile { IoMethod const *pMethod; /* Always the first entry */ struct openCnt *pOpen; /* Info about all open fd's on this inode */ struct lockInfo *pLock; /* Info about locks on this inode */ +#ifdef SQLITE_ENABLE_LOCKING_STYLE + void *lockingContext; /* Locking style specific state */ +#endif /* SQLITE_ENABLE_LOCKING_STYLE */ int h; /* The file descriptor */ unsigned char locktype; /* The type of lock held on this fd */ unsigned char isOpen; /* True if needs to be closed */ @@ -346,6 +356,32 @@ static Hash lockHash = {SQLITE_HASH_BINARY, 0, 0, 0, static Hash openHash = {SQLITE_HASH_BINARY, 0, 0, 0, sqlite3ThreadSafeMalloc, sqlite3ThreadSafeFree, 0, 0}; +#ifdef SQLITE_ENABLE_LOCKING_STYLE +/* +** The locking styles are associated with the different file locking +** capabilities supported by different file systems. +** +** POSIX locking style fully supports shared and exclusive byte-range locks +** ADP locking only supports exclusive byte-range locks +** FLOCK only supports a single file-global exclusive lock +** DOTLOCK isn't a true locking style, it refers to the use of a special +** file named the same as the database file with a '.lock' extension, this +** can be used on file systems that do not offer any reliable file locking +** NO locking means that no locking will be attempted, this is only used for +** read-only file systems currently +** UNSUPPORTED means that no locking will be attempted, this is only used for +** file systems that are known to be unsupported +*/ +typedef enum { + posixLockingStyle = 0, /* standard posix-advisory locks */ + afpLockingStyle, /* use afp locks */ + flockLockingStyle, /* use flock() */ + dotlockLockingStyle, /* use .lock files */ + noLockingStyle, /* useful for read-only file system */ + unsupportedLockingStyle /* indicates unsupported file system */ +} sqlite3LockingStyle; +#endif /* SQLITE_ENABLE_LOCKING_STYLE */ + #ifdef SQLITE_UNIX_THREADS /* ** This variable records whether or not threads can override each others @@ -490,6 +526,8 @@ static void testThreadLockingBehavior(int fd_orig){ */ static void releaseLockInfo(struct lockInfo *pLock){ assert( sqlite3OsInMutex(1) ); + if (pLock == NULL) + return; pLock->nRef--; if( pLock->nRef==0 ){ sqlite3HashInsert(&lockHash, &pLock->key, sizeof(pLock->key), 0); @@ -502,6 +540,8 @@ static void releaseLockInfo(struct lockInfo *pLock){ */ static void releaseOpenCnt(struct openCnt *pOpen){ assert( sqlite3OsInMutex(1) ); + if (pOpen == NULL) + return; pOpen->nRef--; if( pOpen->nRef==0 ){ sqlite3HashInsert(&openHash, &pOpen->key, sizeof(pOpen->key), 0); @@ -510,6 +550,77 @@ static void releaseOpenCnt(struct openCnt *pOpen){ } } +#ifdef SQLITE_ENABLE_LOCKING_STYLE +/* +** Tests a byte-range locking query to see if byte range locks are +** supported, if not we fall back to dotlockLockingStyle. +*/ +static sqlite3LockingStyle sqlite3TestLockingStyle(const char *filePath, + int fd) { + /* test byte-range lock using fcntl */ + struct flock lockInfo; + + lockInfo.l_len = 1; + lockInfo.l_start = 0; + lockInfo.l_whence = SEEK_SET; + lockInfo.l_type = F_RDLCK; + + if (fcntl(fd, F_GETLK, &lockInfo) != -1) { + return posixLockingStyle; + } + + /* testing for flock can give false positives. So if if the above test + ** fails, then we fall back to using dot-lock style locking. + */ + return dotlockLockingStyle; +} + +/* +** Examines the f_fstypename entry in the statfs structure as returned by +** stat() for the file system hosting the database file, assigns the +** appropriate locking style based on it's value. These values and +** assignments are based on Darwin/OSX behavior and have not been tested on +** other systems. +*/ +static sqlite3LockingStyle sqlite3DetectLockingStyle(const char *filePath, + int fd) { + +#ifdef SQLITE_FIXED_LOCKING_STYLE + return (sqlite3LockingStyle)SQLITE_FIXED_LOCKING_STYLE; +#else + struct statfs fsInfo; + + if (statfs(filePath, &fsInfo) == -1) + return sqlite3TestLockingStyle(filePath, fd); + + if (fsInfo.f_flags & MNT_RDONLY) + return noLockingStyle; + + if( (!strcmp(fsInfo.f_fstypename, "hfs")) || + (!strcmp(fsInfo.f_fstypename, "ufs")) ) + return posixLockingStyle; + + if(!strcmp(fsInfo.f_fstypename, "afpfs")) + return afpLockingStyle; + + if(!strcmp(fsInfo.f_fstypename, "nfs")) + return sqlite3TestLockingStyle(filePath, fd); + + if(!strcmp(fsInfo.f_fstypename, "smbfs")) + return flockLockingStyle; + + if(!strcmp(fsInfo.f_fstypename, "msdos")) + return dotlockLockingStyle; + + if(!strcmp(fsInfo.f_fstypename, "webdav")) + return unsupportedLockingStyle; + + return sqlite3TestLockingStyle(filePath, fd); +#endif // SQLITE_FIXED_LOCKING_STYLE +} + +#endif /* SQLITE_ENABLE_LOCKING_STYLE */ + /* ** Given a file descriptor, locate lockInfo and openCnt structures that ** describes that file descriptor. Create new ones if necessary. The @@ -651,12 +762,16 @@ static int transferOwnership(unixFile *pFile){ } TRACE4("Transfer ownership of %d from %d to %d\n", pFile->h,pFile->tid,hSelf); pFile->tid = hSelf; - releaseLockInfo(pFile->pLock); - rc = findLockInfo(pFile->h, &pFile->pLock, 0); - TRACE5("LOCK %d is now %s(%s,%d)\n", pFile->h, - locktypeName(pFile->locktype), - locktypeName(pFile->pLock->locktype), pFile->pLock->cnt); - return rc; + if (pFile->pLock != NULL) { + releaseLockInfo(pFile->pLock); + rc = findLockInfo(pFile->h, &pFile->pLock, 0); + TRACE5("LOCK %d is now %s(%s,%d)\n", pFile->h, + locktypeName(pFile->locktype), + locktypeName(pFile->pLock->locktype), pFile->pLock->cnt); + return rc; + } else { + return SQLITE_OK; + } } #else /* On single-threaded builds, ownership transfer is a no-op */ @@ -679,7 +794,12 @@ int sqlite3UnixFileExists(const char *zFilename){ } /* Forward declaration */ -static int allocateUnixFile(unixFile *pInit, OsFile **pId); +static int allocateUnixFile( + int h, /* File descriptor of the open file */ + OsFile **pId, /* Write the real file descriptor here */ + const char *zFilename, /* Name of the file being opened */ + int delFlag /* If true, make sure the file deletes on close */ +); /* ** Attempt to open a file for both reading and writing. If that @@ -699,36 +819,27 @@ int sqlite3UnixOpenReadWrite( OsFile **pId, int *pReadonly ){ - int rc; - unixFile f; - + int h; + CRASH_TEST_OVERRIDE(sqlite3CrashOpenReadWrite, zFilename, pId, pReadonly); assert( 0==*pId ); - f.h = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY, - SQLITE_DEFAULT_FILE_PERMISSIONS); - if( f.h<0 ){ + h = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY, + SQLITE_DEFAULT_FILE_PERMISSIONS); + if( h<0 ){ #ifdef EISDIR if( errno==EISDIR ){ return SQLITE_CANTOPEN; } #endif - f.h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY); - if( f.h<0 ){ + h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY); + if( h<0 ){ return SQLITE_CANTOPEN; } *pReadonly = 1; }else{ *pReadonly = 0; } - sqlite3OsEnterMutex(); - rc = findLockInfo(f.h, &f.pLock, &f.pOpen); - sqlite3OsLeaveMutex(); - if( rc ){ - close(f.h); - return SQLITE_NOMEM; - } - TRACE3("OPEN %-3d %s\n", f.h, zFilename); - return allocateUnixFile(&f, pId); + return allocateUnixFile(h, pId, zFilename, 0); } @@ -747,33 +858,17 @@ int sqlite3UnixOpenReadWrite( ** On failure, return SQLITE_CANTOPEN. */ int sqlite3UnixOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){ - int rc; - unixFile f; + int h; CRASH_TEST_OVERRIDE(sqlite3CrashOpenExclusive, zFilename, pId, delFlag); assert( 0==*pId ); - if( access(zFilename, 0)==0 ){ - return SQLITE_CANTOPEN; - } - f.h = open(zFilename, + h = open(zFilename, O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_LARGEFILE|O_BINARY, SQLITE_DEFAULT_FILE_PERMISSIONS); - if( f.h<0 ){ + if( h<0 ){ return SQLITE_CANTOPEN; } - sqlite3OsEnterMutex(); - rc = findLockInfo(f.h, &f.pLock, &f.pOpen); - sqlite3OsLeaveMutex(); - if( rc ){ - close(f.h); - unlink(zFilename); - return SQLITE_NOMEM; - } - if( delFlag ){ - unlink(zFilename); - } - TRACE3("OPEN-EX %-3d %s\n", f.h, zFilename); - return allocateUnixFile(&f, pId); + return allocateUnixFile(h, pId, zFilename, delFlag); } /* @@ -784,24 +879,15 @@ int sqlite3UnixOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){ ** On failure, return SQLITE_CANTOPEN. */ int sqlite3UnixOpenReadOnly(const char *zFilename, OsFile **pId){ - int rc; - unixFile f; - + int h; + CRASH_TEST_OVERRIDE(sqlite3CrashOpenReadOnly, zFilename, pId, 0); assert( 0==*pId ); - f.h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY); - if( f.h<0 ){ + h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY); + if( h<0 ){ return SQLITE_CANTOPEN; } - sqlite3OsEnterMutex(); - rc = findLockInfo(f.h, &f.pLock, &f.pOpen); - sqlite3OsLeaveMutex(); - if( rc ){ - close(f.h); - return SQLITE_NOMEM; - } - TRACE3("OPEN-RO %-3d %s\n", f.h, zFilename); - return allocateUnixFile(&f, pId); + return allocateUnixFile(h, pId, zFilename, 0); } /* @@ -813,6 +899,9 @@ int sqlite3UnixOpenReadOnly(const char *zFilename, OsFile **pId){ ** This routine is only meaningful for Unix. It is a no-op under ** windows since windows does not support hard links. ** +** If FULL_FSYNC is enabled, this function is not longer useful, +** a FULL_FSYNC sync applies to all pending disk operations. +** ** On success, a handle for a previously open file at *id is ** updated with the new directory file descriptor and SQLITE_OK is ** returned. @@ -911,10 +1000,14 @@ int sqlite3UnixIsDirWritable(char *zBuf){ */ static int seekAndRead(unixFile *id, void *pBuf, int cnt){ int got; + i64 newOffset; #ifdef USE_PREAD got = pread(id->h, pBuf, cnt, id->offset); #else - lseek(id->h, id->offset, SEEK_SET); + newOffset = lseek(id->h, id->offset, SEEK_SET); + if( newOffset!=id->offset ){ + return -1; + } got = read(id->h, pBuf, cnt); #endif if( got>0 ){ @@ -931,18 +1024,20 @@ static int seekAndRead(unixFile *id, void *pBuf, int cnt){ static int unixRead(OsFile *id, void *pBuf, int amt){ int got; assert( id ); - SimulateIOError(SQLITE_IOERR); TIMER_START; got = seekAndRead((unixFile*)id, pBuf, amt); TIMER_END; TRACE5("READ %-3d %5d %7d %d\n", ((unixFile*)id)->h, got, last_page, TIMER_ELAPSED); SEEK(0); - /* if( got<0 ) got = 0; */ + SimulateIOError( got = -1 ); if( got==amt ){ return SQLITE_OK; + }else if( got<0 ){ + return SQLITE_IOERR_READ; }else{ - return SQLITE_IOERR; + memset(&((char*)pBuf)[got], 0, amt-got); + return SQLITE_IOERR_SHORT_READ; } } @@ -952,10 +1047,14 @@ static int unixRead(OsFile *id, void *pBuf, int amt){ */ static int seekAndWrite(unixFile *id, const void *pBuf, int cnt){ int got; + i64 newOffset; #ifdef USE_PREAD got = pwrite(id->h, pBuf, cnt, id->offset); #else - lseek(id->h, id->offset, SEEK_SET); + newOffset = lseek(id->h, id->offset, SEEK_SET); + if( newOffset!=id->offset ){ + return -1; + } got = write(id->h, pBuf, cnt); #endif if( got>0 ){ @@ -973,8 +1072,6 @@ static int unixWrite(OsFile *id, const void *pBuf, int amt){ int wrote = 0; assert( id ); assert( amt>0 ); - SimulateIOError(SQLITE_IOERR); - SimulateDiskfullError; TIMER_START; while( amt>0 && (wrote = seekAndWrite((unixFile*)id, pBuf, amt))>0 ){ amt -= wrote; @@ -984,8 +1081,14 @@ static int unixWrite(OsFile *id, const void *pBuf, int amt){ TRACE5("WRITE %-3d %5d %7d %d\n", ((unixFile*)id)->h, wrote, last_page, TIMER_ELAPSED); SEEK(0); + SimulateIOError(( wrote=(-1), amt=1 )); + SimulateDiskfullError(( wrote=0, amt=1 )); if( amt>0 ){ - return SQLITE_FULL; + if( wrote<0 ){ + return SQLITE_IOERR_WRITE; + }else{ + return SQLITE_FULL; + } } return SQLITE_OK; } @@ -997,7 +1100,7 @@ static int unixSeek(OsFile *id, i64 offset){ assert( id ); SEEK(offset/1024 + 1); #ifdef SQLITE_TEST - if( offset ) SimulateDiskfullError + if( offset ) SimulateDiskfullError(return SQLITE_FULL); #endif ((unixFile*)id)->offset = offset; return SQLITE_OK; @@ -1068,16 +1171,23 @@ static int full_fsync(int fd, int fullSync, int dataOnly){ }else{ rc = 1; } - /* If the FULLSYNC failed, try to do a normal fsync() */ + /* If the FULLFSYNC failed, fall back to attempting an fsync(). + * It shouldn't be possible for fullfsync to fail on the local + * file system (on OSX), so failure indicates that FULLFSYNC + * isn't supported for this file system. So, attempt an fsync + * and (for now) ignore the overhead of a superfluous fcntl call. + * It'd be better to detect fullfsync support once and avoid + * the fcntl call every time sync is called. + */ if( rc ) rc = fsync(fd); -#else /* if !defined(F_FULLSYNC) */ +#else if( dataOnly ){ rc = fdatasync(fd); }else{ rc = fsync(fd); } -#endif /* defined(F_FULLFSYNC) */ +#endif /* HAVE_FULLFSYNC */ #endif /* defined(SQLITE_NO_SYNC) */ return rc; @@ -1099,12 +1209,14 @@ static int full_fsync(int fd, int fullSync, int dataOnly){ ** will not roll back - possibly leading to database corruption. */ static int unixSync(OsFile *id, int dataOnly){ + int rc; unixFile *pFile = (unixFile*)id; assert( pFile ); - SimulateIOError(SQLITE_IOERR); TRACE2("SYNC %-3d\n", pFile->h); - if( full_fsync(pFile->h, pFile->fullSync, dataOnly) ){ - return SQLITE_IOERR; + rc = full_fsync(pFile->h, pFile->fullSync, dataOnly); + SimulateIOError( rc=1 ); + if( rc ){ + return SQLITE_IOERR_FSYNC; } if( pFile->dirfd>=0 ){ TRACE4("DIRSYNC %-3d (have_fullfsync=%d fullsync=%d)\n", pFile->dirfd, @@ -1144,7 +1256,6 @@ int sqlite3UnixSyncDirectory(const char *zDirname){ #else int fd; int r; - SimulateIOError(SQLITE_IOERR); fd = open(zDirname, O_RDONLY|O_BINARY, 0); TRACE3("DIRSYNC %-3d (%s)\n", fd, zDirname); if( fd<0 ){ @@ -1152,7 +1263,12 @@ int sqlite3UnixSyncDirectory(const char *zDirname){ } r = fsync(fd); close(fd); - return ((r==0)?SQLITE_OK:SQLITE_IOERR); + SimulateIOError( r=1 ); + if( r ){ + return SQLITE_IOERR_DIR_FSYNC; + }else{ + return SQLITE_OK; + } #endif } @@ -1160,20 +1276,28 @@ int sqlite3UnixSyncDirectory(const char *zDirname){ ** Truncate an open file to a specified size */ static int unixTruncate(OsFile *id, i64 nByte){ + int rc; assert( id ); - SimulateIOError(SQLITE_IOERR); - return ftruncate(((unixFile*)id)->h, nByte)==0 ? SQLITE_OK : SQLITE_IOERR; + rc = ftruncate(((unixFile*)id)->h, nByte); + SimulateIOError( rc=1 ); + if( rc ){ + return SQLITE_IOERR_TRUNCATE; + }else{ + return SQLITE_OK; + } } /* ** Determine the current size of a file in bytes */ static int unixFileSize(OsFile *id, i64 *pSize){ + int rc; struct stat buf; assert( id ); - SimulateIOError(SQLITE_IOERR); - if( fstat(((unixFile*)id)->h, &buf)!=0 ){ - return SQLITE_IOERR; + rc = fstat(((unixFile*)id)->h, &buf); + SimulateIOError( rc=1 ); + if( rc!=0 ){ + return SQLITE_IOERR_FSTAT; } *pSize = buf.st_size; return SQLITE_OK; @@ -1383,7 +1507,7 @@ static int unixLock(OsFile *id, int locktype){ lock.l_len = 1L; lock.l_type = F_UNLCK; if( fcntl(pFile->h, F_SETLK, &lock)!=0 ){ - rc = SQLITE_IOERR; /* This should never happen */ + rc = SQLITE_IOERR_UNLOCK; /* This should never happen */ goto end_lock; } if( s ){ @@ -1472,7 +1596,7 @@ static int unixUnlock(OsFile *id, int locktype){ lock.l_len = SHARED_SIZE; if( fcntl(pFile->h, F_SETLK, &lock)!=0 ){ /* This should never happen */ - rc = SQLITE_IOERR; + rc = SQLITE_IOERR_RDLOCK; } } lock.l_type = F_UNLCK; @@ -1482,7 +1606,7 @@ static int unixUnlock(OsFile *id, int locktype){ if( fcntl(pFile->h, F_SETLK, &lock)==0 ){ pLock->locktype = SHARED_LOCK; }else{ - rc = SQLITE_IOERR; /* This should never happen */ + rc = SQLITE_IOERR_UNLOCK; /* This should never happen */ } } if( locktype==NO_LOCK ){ @@ -1500,7 +1624,7 @@ static int unixUnlock(OsFile *id, int locktype){ if( fcntl(pFile->h, F_SETLK, &lock)==0 ){ pLock->locktype = NO_LOCK; }else{ - rc = SQLITE_IOERR; /* This should never happen */ + rc = SQLITE_IOERR_UNLOCK; /* This should never happen */ } } @@ -1570,6 +1694,581 @@ static int unixClose(OsFile **pId){ return SQLITE_OK; } + +#ifdef SQLITE_ENABLE_LOCKING_STYLE +#pragma mark AFP Support + +/* + ** The afpLockingContext structure contains all afp lock specific state + */ +typedef struct afpLockingContext afpLockingContext; +struct afpLockingContext { + unsigned long long sharedLockByte; + char *filePath; +}; + +struct ByteRangeLockPB2 +{ + unsigned long long offset; /* offset to first byte to lock */ + unsigned long long length; /* nbr of bytes to lock */ + unsigned long long retRangeStart; /* nbr of 1st byte locked if successful */ + unsigned char unLockFlag; /* 1 = unlock, 0 = lock */ + unsigned char startEndFlag; /* 1=rel to end of fork, 0=rel to start */ + int fd; /* file desc to assoc this lock with */ +}; + +#define afpfsByteRangeLock2FSCTL _IOWR('z', 23, struct ByteRangeLockPB2) + +/* return 0 on success, 1 on failure. To match the behavior of the + normal posix file locking (used in unixLock for example), we should + provide 'richer' return codes - specifically to differentiate between + 'file busy' and 'file system error' results */ +static int _AFPFSSetLock(const char *path, int fd, unsigned long long offset, + unsigned long long length, int setLockFlag) +{ + struct ByteRangeLockPB2 pb; + int err; + + pb.unLockFlag = setLockFlag ? 0 : 1; + pb.startEndFlag = 0; + pb.offset = offset; + pb.length = length; + pb.fd = fd; + TRACE5("AFPLOCK setting lock %s for %d in range %llx:%llx\n", + (setLockFlag?"ON":"OFF"), fd, offset, length); + err = fsctl(path, afpfsByteRangeLock2FSCTL, &pb, 0); + if ( err==-1 ) { + TRACE4("AFPLOCK failed to fsctl() '%s' %d %s\n", path, errno, + strerror(errno)); + return 1; // error + } else { + return 0; + } +} + +/* + ** This routine checks if there is a RESERVED lock held on the specified + ** file by this or any other process. If such a lock is held, return + ** non-zero. If the file is unlocked or holds only SHARED locks, then + ** return zero. + */ +static int afpUnixCheckReservedLock(OsFile *id){ + int r = 0; + unixFile *pFile = (unixFile*)id; + + assert( pFile ); + afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; + + /* Check if a thread in this process holds such a lock */ + if( pFile->locktype>SHARED_LOCK ){ + r = 1; + } + + /* Otherwise see if some other process holds it. + */ + if ( !r ) { + // lock the byte + int failed = _AFPFSSetLock(context->filePath, pFile->h, RESERVED_BYTE, 1,1); + if (failed) { + /* if we failed to get the lock then someone else must have it */ + r = 1; + } else { + /* if we succeeded in taking the reserved lock, unlock it to restore + ** the original state */ + _AFPFSSetLock(context->filePath, pFile->h, RESERVED_BYTE, 1, 0); + } + } + TRACE3("TEST WR-LOCK %d %d\n", pFile->h, r); + + return r; +} + +/* AFP-style locking following the behavior of unixLock, see the unixLock +** function comments for details of lock management. */ +static int afpUnixLock(OsFile *id, int locktype) +{ + int rc = SQLITE_OK; + unixFile *pFile = (unixFile*)id; + afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; + int gotPendingLock = 0; + + assert( pFile ); + TRACE5("LOCK %d %s was %s pid=%d\n", pFile->h, + locktypeName(locktype), locktypeName(pFile->locktype), getpid()); + /* If there is already a lock of this type or more restrictive on the + ** OsFile, do nothing. Don't use the afp_end_lock: exit path, as + ** sqlite3OsEnterMutex() hasn't been called yet. + */ + if( pFile->locktype>=locktype ){ + TRACE3("LOCK %d %s ok (already held)\n", pFile->h, + locktypeName(locktype)); + return SQLITE_OK; + } + + /* Make sure the locking sequence is correct + */ + assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); + assert( locktype!=PENDING_LOCK ); + assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK ); + + /* This mutex is needed because pFile->pLock is shared across threads + */ + sqlite3OsEnterMutex(); + + /* Make sure the current thread owns the pFile. + */ + rc = transferOwnership(pFile); + if( rc!=SQLITE_OK ){ + sqlite3OsLeaveMutex(); + return rc; + } + + /* A PENDING lock is needed before acquiring a SHARED lock and before + ** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will + ** be released. + */ + if( locktype==SHARED_LOCK + || (locktype==EXCLUSIVE_LOCK && pFile->locktypefilePath, pFile->h, + PENDING_BYTE, 1, 1); + if (failed) { + rc = SQLITE_BUSY; + goto afp_end_lock; + } + } + + /* If control gets to this point, then actually go ahead and make + ** operating system calls for the specified lock. + */ + if( locktype==SHARED_LOCK ){ + int lk, failed; + int tries = 0; + + /* Now get the read-lock */ + /* note that the quality of the randomness doesn't matter that much */ + lk = random(); + context->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1); + failed = _AFPFSSetLock(context->filePath, pFile->h, + SHARED_FIRST+context->sharedLockByte, 1, 1); + + /* Drop the temporary PENDING lock */ + if (_AFPFSSetLock(context->filePath, pFile->h, PENDING_BYTE, 1, 0)) { + rc = SQLITE_IOERR_UNLOCK; /* This should never happen */ + goto afp_end_lock; + } + + if( failed ){ + rc = SQLITE_BUSY; + } else { + pFile->locktype = SHARED_LOCK; + } + }else{ + /* The request was for a RESERVED or EXCLUSIVE lock. It is + ** assumed that there is a SHARED or greater lock on the file + ** already. + */ + int failed = 0; + assert( 0!=pFile->locktype ); + if (locktype >= RESERVED_LOCK && pFile->locktype < RESERVED_LOCK) { + /* Acquire a RESERVED lock */ + failed = _AFPFSSetLock(context->filePath, pFile->h, RESERVED_BYTE, 1,1); + } + if (!failed && locktype == EXCLUSIVE_LOCK) { + /* Acquire an EXCLUSIVE lock */ + + /* Remove the shared lock before trying the range. we'll need to + ** reestablish the shared lock if we can't get the afpUnixUnlock + */ + if (!_AFPFSSetLock(context->filePath, pFile->h, SHARED_FIRST + + context->sharedLockByte, 1, 0)) { + /* now attemmpt to get the exclusive lock range */ + failed = _AFPFSSetLock(context->filePath, pFile->h, SHARED_FIRST, + SHARED_SIZE, 1); + if (failed && _AFPFSSetLock(context->filePath, pFile->h, SHARED_FIRST + + context->sharedLockByte, 1, 1)) { + rc = SQLITE_IOERR_RDLOCK; /* this should never happen */ + } + } else { + /* */ + rc = SQLITE_IOERR_UNLOCK; /* this should never happen */ + } + } + if( failed && rc == SQLITE_OK){ + rc = SQLITE_BUSY; + } + } + + if( rc==SQLITE_OK ){ + pFile->locktype = locktype; + }else if( locktype==EXCLUSIVE_LOCK ){ + pFile->locktype = PENDING_LOCK; + } + +afp_end_lock: + sqlite3OsLeaveMutex(); + TRACE4("LOCK %d %s %s\n", pFile->h, locktypeName(locktype), + rc==SQLITE_OK ? "ok" : "failed"); + return rc; +} + +/* + ** Lower the locking level on file descriptor pFile to locktype. locktype + ** must be either NO_LOCK or SHARED_LOCK. + ** + ** If the locking level of the file descriptor is already at or below + ** the requested locking level, this routine is a no-op. + */ +static int afpUnixUnlock(OsFile *id, int locktype) { + struct flock lock; + int rc = SQLITE_OK; + unixFile *pFile = (unixFile*)id; + afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; + + assert( pFile ); + TRACE5("UNLOCK %d %d was %d pid=%d\n", pFile->h, locktype, + pFile->locktype, getpid()); + + assert( locktype<=SHARED_LOCK ); + if( pFile->locktype<=locktype ){ + return SQLITE_OK; + } + if( CHECK_THREADID(pFile) ){ + return SQLITE_MISUSE; + } + sqlite3OsEnterMutex(); + if( pFile->locktype>SHARED_LOCK ){ + if( locktype==SHARED_LOCK ){ + int failed = 0; + + /* unlock the exclusive range - then re-establish the shared lock */ + if (pFile->locktype==EXCLUSIVE_LOCK) { + failed = _AFPFSSetLock(context->filePath, pFile->h, SHARED_FIRST, + SHARED_SIZE, 0); + if (!failed) { + /* successfully removed the exclusive lock */ + if (_AFPFSSetLock(context->filePath, pFile->h, SHARED_FIRST+ + context->sharedLockByte, 1, 1)) { + /* failed to re-establish our shared lock */ + rc = SQLITE_IOERR_RDLOCK; /* This should never happen */ + } + } else { + /* This should never happen - failed to unlock the exclusive range */ + rc = SQLITE_IOERR_UNLOCK; + } + } + } + if (rc == SQLITE_OK && pFile->locktype>=PENDING_LOCK) { + if (_AFPFSSetLock(context->filePath, pFile->h, PENDING_BYTE, 1, 0)){ + /* failed to release the pending lock */ + rc = SQLITE_IOERR_UNLOCK; /* This should never happen */ + } + } + if (rc == SQLITE_OK && pFile->locktype>=RESERVED_LOCK) { + if (_AFPFSSetLock(context->filePath, pFile->h, RESERVED_BYTE, 1, 0)) { + /* failed to release the reserved lock */ + rc = SQLITE_IOERR_UNLOCK; /* This should never happen */ + } + } + } + if( locktype==NO_LOCK ){ + int failed = _AFPFSSetLock(context->filePath, pFile->h, + SHARED_FIRST + context->sharedLockByte, 1, 0); + if (failed) { + rc = SQLITE_IOERR_UNLOCK; /* This should never happen */ + } + } + if (rc == SQLITE_OK) + pFile->locktype = locktype; + sqlite3OsLeaveMutex(); + return rc; +} + +/* + ** Close a file & cleanup AFP specific locking context + */ +static int afpUnixClose(OsFile **pId) { + unixFile *id = (unixFile*)*pId; + + if( !id ) return SQLITE_OK; + afpUnixUnlock(*pId, NO_LOCK); + /* free the AFP locking structure */ + if (id->lockingContext != NULL) { + if (((afpLockingContext *)id->lockingContext)->filePath != NULL) + sqlite3ThreadSafeFree(((afpLockingContext*)id->lockingContext)->filePath); + sqlite3ThreadSafeFree(id->lockingContext); + } + + if( id->dirfd>=0 ) close(id->dirfd); + id->dirfd = -1; + close(id->h); + id->isOpen = 0; + TRACE2("CLOSE %-3d\n", id->h); + OpenCounter(-1); + sqlite3ThreadSafeFree(id); + *pId = 0; + return SQLITE_OK; +} + + +#pragma mark flock() style locking + +/* + ** The flockLockingContext is not used + */ +typedef void flockLockingContext; + +static int flockUnixCheckReservedLock(OsFile *id) { + unixFile *pFile = (unixFile*)id; + + if (pFile->locktype == RESERVED_LOCK) { + return 1; // already have a reserved lock + } else { + // attempt to get the lock + int rc = flock(pFile->h, LOCK_EX | LOCK_NB); + if (!rc) { + // got the lock, unlock it + flock(pFile->h, LOCK_UN); + return 0; // no one has it reserved + } + return 1; // someone else might have it reserved + } +} + +static int flockUnixLock(OsFile *id, int locktype) { + unixFile *pFile = (unixFile*)id; + + // if we already have a lock, it is exclusive. + // Just adjust level and punt on outta here. + if (pFile->locktype > NO_LOCK) { + pFile->locktype = locktype; + return SQLITE_OK; + } + + // grab an exclusive lock + int rc = flock(pFile->h, LOCK_EX | LOCK_NB); + if (rc) { + // didn't get, must be busy + return SQLITE_BUSY; + } else { + // got it, set the type and return ok + pFile->locktype = locktype; + return SQLITE_OK; + } +} + +static int flockUnixUnlock(OsFile *id, int locktype) { + unixFile *pFile = (unixFile*)id; + + assert( locktype<=SHARED_LOCK ); + + // no-op if possible + if( pFile->locktype==locktype ){ + return SQLITE_OK; + } + + // shared can just be set because we always have an exclusive + if (locktype==SHARED_LOCK) { + pFile->locktype = locktype; + return SQLITE_OK; + } + + // no, really, unlock. + int rc = flock(pFile->h, LOCK_UN); + if (rc) + return SQLITE_IOERR_UNLOCK; + else { + pFile->locktype = NO_LOCK; + return SQLITE_OK; + } +} + +/* + ** Close a file. + */ +static int flockUnixClose(OsFile **pId) { + unixFile *id = (unixFile*)*pId; + + if( !id ) return SQLITE_OK; + flockUnixUnlock(*pId, NO_LOCK); + + if( id->dirfd>=0 ) close(id->dirfd); + id->dirfd = -1; + sqlite3OsEnterMutex(); + + close(id->h); + sqlite3OsLeaveMutex(); + id->isOpen = 0; + TRACE2("CLOSE %-3d\n", id->h); + OpenCounter(-1); + sqlite3ThreadSafeFree(id); + *pId = 0; + return SQLITE_OK; +} + +#pragma mark Old-School .lock file based locking + +/* + ** The dotlockLockingContext structure contains all dotlock (.lock) lock + ** specific state + */ +typedef struct dotlockLockingContext dotlockLockingContext; +struct dotlockLockingContext { + char *lockPath; +}; + + +static int dotlockUnixCheckReservedLock(OsFile *id) { + unixFile *pFile = (unixFile*)id; + dotlockLockingContext *context = + (dotlockLockingContext *) pFile->lockingContext; + + if (pFile->locktype == RESERVED_LOCK) { + return 1; // already have a reserved lock + } else { + struct stat statBuf; + if (lstat(context->lockPath,&statBuf) == 0) + // file exists, someone else has the lock + return 1; + else + // file does not exist, we could have it if we want it + return 0; + } +} + +static int dotlockUnixLock(OsFile *id, int locktype) { + unixFile *pFile = (unixFile*)id; + dotlockLockingContext *context = + (dotlockLockingContext *) pFile->lockingContext; + + // if we already have a lock, it is exclusive. + // Just adjust level and punt on outta here. + if (pFile->locktype > NO_LOCK) { + pFile->locktype = locktype; + + /* Always update the timestamp on the old file */ + utimes(context->lockPath,NULL); + return SQLITE_OK; + } + + // check to see if lock file already exists + struct stat statBuf; + if (lstat(context->lockPath,&statBuf) == 0){ + return SQLITE_BUSY; // it does, busy + } + + // grab an exclusive lock + int fd = open(context->lockPath,O_RDONLY|O_CREAT|O_EXCL,0600); + if (fd < 0) { + // failed to open/create the file, someone else may have stolen the lock + return SQLITE_BUSY; + } + close(fd); + + // got it, set the type and return ok + pFile->locktype = locktype; + return SQLITE_OK; +} + +static int dotlockUnixUnlock(OsFile *id, int locktype) { + unixFile *pFile = (unixFile*)id; + dotlockLockingContext *context = + (dotlockLockingContext *) pFile->lockingContext; + + assert( locktype<=SHARED_LOCK ); + + // no-op if possible + if( pFile->locktype==locktype ){ + return SQLITE_OK; + } + + // shared can just be set because we always have an exclusive + if (locktype==SHARED_LOCK) { + pFile->locktype = locktype; + return SQLITE_OK; + } + + // no, really, unlock. + unlink(context->lockPath); + pFile->locktype = NO_LOCK; + return SQLITE_OK; +} + +/* + ** Close a file. + */ +static int dotlockUnixClose(OsFile **pId) { + unixFile *id = (unixFile*)*pId; + + if( !id ) return SQLITE_OK; + dotlockUnixUnlock(*pId, NO_LOCK); + /* free the dotlock locking structure */ + if (id->lockingContext != NULL) { + if (((dotlockLockingContext *)id->lockingContext)->lockPath != NULL) + sqlite3ThreadSafeFree( ( (dotlockLockingContext *) + id->lockingContext)->lockPath); + sqlite3ThreadSafeFree(id->lockingContext); + } + + if( id->dirfd>=0 ) close(id->dirfd); + id->dirfd = -1; + sqlite3OsEnterMutex(); + + close(id->h); + + sqlite3OsLeaveMutex(); + id->isOpen = 0; + TRACE2("CLOSE %-3d\n", id->h); + OpenCounter(-1); + sqlite3ThreadSafeFree(id); + *pId = 0; + return SQLITE_OK; +} + + +#pragma mark No locking + +/* + ** The nolockLockingContext is void + */ +typedef void nolockLockingContext; + +static int nolockUnixCheckReservedLock(OsFile *id) { + return 0; +} + +static int nolockUnixLock(OsFile *id, int locktype) { + return SQLITE_OK; +} + +static int nolockUnixUnlock(OsFile *id, int locktype) { + return SQLITE_OK; +} + +/* + ** Close a file. + */ +static int nolockUnixClose(OsFile **pId) { + unixFile *id = (unixFile*)*pId; + + if( !id ) return SQLITE_OK; + if( id->dirfd>=0 ) close(id->dirfd); + id->dirfd = -1; + sqlite3OsEnterMutex(); + + close(id->h); + + sqlite3OsLeaveMutex(); + id->isOpen = 0; + TRACE2("CLOSE %-3d\n", id->h); + OpenCounter(-1); + sqlite3ThreadSafeFree(id); + *pId = 0; + return SQLITE_OK; +} + +#endif /* SQLITE_ENABLE_LOCKING_STYLE */ + /* ** Turn a relative pathname into a full pathname. Return a pointer ** to the full pathname stored in space obtained from sqliteMalloc(). @@ -1663,36 +2362,243 @@ static const IoMethod sqlite3UnixIoMethod = { unixCheckReservedLock, }; +#ifdef SQLITE_ENABLE_LOCKING_STYLE /* -** Allocate memory for a unixFile. Initialize the new unixFile -** to the value given in pInit and return a pointer to the new -** OsFile. If we run out of memory, close the file and return NULL. + ** This vector defines all the methods that can operate on an OsFile + ** for unix with AFP style file locking. + */ +static const IoMethod sqlite3AFPLockingUnixIoMethod = { + afpUnixClose, + unixOpenDirectory, + unixRead, + unixWrite, + unixSeek, + unixTruncate, + unixSync, + unixSetFullSync, + unixFileHandle, + unixFileSize, + afpUnixLock, + afpUnixUnlock, + unixLockState, + afpUnixCheckReservedLock, +}; + +/* + ** This vector defines all the methods that can operate on an OsFile + ** for unix with flock() style file locking. + */ +static const IoMethod sqlite3FlockLockingUnixIoMethod = { + flockUnixClose, + unixOpenDirectory, + unixRead, + unixWrite, + unixSeek, + unixTruncate, + unixSync, + unixSetFullSync, + unixFileHandle, + unixFileSize, + flockUnixLock, + flockUnixUnlock, + unixLockState, + flockUnixCheckReservedLock, +}; + +/* + ** This vector defines all the methods that can operate on an OsFile + ** for unix with dotlock style file locking. + */ +static const IoMethod sqlite3DotlockLockingUnixIoMethod = { + dotlockUnixClose, + unixOpenDirectory, + unixRead, + unixWrite, + unixSeek, + unixTruncate, + unixSync, + unixSetFullSync, + unixFileHandle, + unixFileSize, + dotlockUnixLock, + dotlockUnixUnlock, + unixLockState, + dotlockUnixCheckReservedLock, +}; + +/* + ** This vector defines all the methods that can operate on an OsFile + ** for unix with dotlock style file locking. + */ +static const IoMethod sqlite3NolockLockingUnixIoMethod = { + nolockUnixClose, + unixOpenDirectory, + unixRead, + unixWrite, + unixSeek, + unixTruncate, + unixSync, + unixSetFullSync, + unixFileHandle, + unixFileSize, + nolockUnixLock, + nolockUnixUnlock, + unixLockState, + nolockUnixCheckReservedLock, +}; + +#endif /* SQLITE_ENABLE_LOCKING_STYLE */ + +/* +** Allocate memory for a new unixFile and initialize that unixFile. +** Write a pointer to the new unixFile into *pId. +** If we run out of memory, close the file and return an error. */ -static int allocateUnixFile(unixFile *pInit, OsFile **pId){ +#ifdef SQLITE_ENABLE_LOCKING_STYLE +/* + ** When locking extensions are enabled, the filepath and locking style + ** are needed to determine the unixFile pMethod to use for locking operations. + ** The locking-style specific lockingContext data structure is created + ** and assigned here also. + */ +static int allocateUnixFile( + int h, /* Open file descriptor of file being opened */ + OsFile **pId, /* Write completed initialization here */ + const char *zFilename, /* Name of the file being opened */ + int delFlag /* Delete-on-or-before-close flag */ +){ + sqlite3LockingStyle lockingStyle; unixFile *pNew; - pInit->dirfd = -1; - pInit->fullSync = 0; - pInit->locktype = 0; - pInit->offset = 0; - SET_THREADID(pInit); + unixFile f; + int rc; + + lockingStyle = sqlite3DetectLockingStyle(zFilename, h); + if ( lockingStyle == posixLockingStyle ) { + sqlite3OsEnterMutex(); + rc = findLockInfo(h, &f.pLock, &f.pOpen); + sqlite3OsLeaveMutex(); + if( rc ){ + close(h); + unlink(zFilename); + return SQLITE_NOMEM; + } + } else { + // pLock and pOpen are only used for posix advisory locking + f.pLock = NULL; + f.pOpen = NULL; + } + if( delFlag ){ + unlink(zFilename); + } + f.dirfd = -1; + f.fullSync = 0; + f.locktype = 0; + f.offset = 0; + f.h = h; + SET_THREADID(&f); pNew = sqlite3ThreadSafeMalloc( sizeof(unixFile) ); if( pNew==0 ){ - close(pInit->h); + close(h); sqlite3OsEnterMutex(); - releaseLockInfo(pInit->pLock); - releaseOpenCnt(pInit->pOpen); + releaseLockInfo(f.pLock); + releaseOpenCnt(f.pOpen); sqlite3OsLeaveMutex(); *pId = 0; return SQLITE_NOMEM; }else{ - *pNew = *pInit; + *pNew = f; + switch(lockingStyle) { + case afpLockingStyle: + /* afp locking uses the file path so it needs to be included in + ** the afpLockingContext */ + pNew->pMethod = &sqlite3AFPLockingUnixIoMethod; + pNew->lockingContext = + sqlite3ThreadSafeMalloc(sizeof(afpLockingContext)); + ((afpLockingContext *)pNew->lockingContext)->filePath = + sqlite3ThreadSafeMalloc(strlen(zFilename) + 1); + strcpy(((afpLockingContext *)pNew->lockingContext)->filePath, + zFilename); + srandomdev(); + break; + case flockLockingStyle: + /* flock locking doesn't need additional lockingContext information */ + pNew->pMethod = &sqlite3FlockLockingUnixIoMethod; + break; + case dotlockLockingStyle: + /* dotlock locking uses the file path so it needs to be included in + ** the dotlockLockingContext */ + pNew->pMethod = &sqlite3DotlockLockingUnixIoMethod; + pNew->lockingContext = sqlite3ThreadSafeMalloc( + sizeof(dotlockLockingContext)); + ((dotlockLockingContext *)pNew->lockingContext)->lockPath = + sqlite3ThreadSafeMalloc(strlen(zFilename) + strlen(".lock") + 1); + sprintf(((dotlockLockingContext *)pNew->lockingContext)->lockPath, + "%s.lock", zFilename); + break; + case posixLockingStyle: + /* posix locking doesn't need additional lockingContext information */ + pNew->pMethod = &sqlite3UnixIoMethod; + break; + case noLockingStyle: + case unsupportedLockingStyle: + default: + pNew->pMethod = &sqlite3NolockLockingUnixIoMethod; + } + *pId = (OsFile*)pNew; + OpenCounter(+1); + return SQLITE_OK; + } +} +#else /* SQLITE_ENABLE_LOCKING_STYLE */ +static int allocateUnixFile( + int h, /* Open file descriptor on file being opened */ + OsFile **pId, /* Write the resul unixFile structure here */ + const char *zFilename, /* Name of the file being opened */ + int delFlag /* If true, delete the file on or before closing */ +){ + unixFile *pNew; + unixFile f; + f.pLock = NULL; + f.pOpen = NULL; + f.pMethod = NULL; + f.isOpen = 0; + int rc; + + sqlite3OsEnterMutex(); + rc = findLockInfo(h, &f.pLock, &f.pOpen); + sqlite3OsLeaveMutex(); + if( delFlag ){ + unlink(zFilename); + } + if( rc ){ + close(h); + return SQLITE_NOMEM; + } + TRACE3("OPEN %-3d %s\n", h, zFilename); + f.dirfd = -1; + f.fullSync = 0; + f.locktype = 0; + f.offset = 0; + f.h = h; + SET_THREADID(&f); + pNew = sqlite3ThreadSafeMalloc( sizeof(unixFile) ); + if( pNew==0 ){ + close(h); + sqlite3OsEnterMutex(); + releaseLockInfo(f.pLock); + releaseOpenCnt(f.pOpen); + sqlite3OsLeaveMutex(); + *pId = 0; + return SQLITE_NOMEM; + }else{ + *pNew = f; pNew->pMethod = &sqlite3UnixIoMethod; *pId = (OsFile*)pNew; OpenCounter(+1); return SQLITE_OK; } } - +#endif /* SQLITE_ENABLE_LOCKING_STYLE */ #endif /* SQLITE_OMIT_DISKIO */ /*************************************************************************** @@ -1701,6 +2607,23 @@ static int allocateUnixFile(unixFile *pInit, OsFile **pId){ ****************************************************************************/ +#ifndef SQLITE_OMIT_LOAD_EXTENSION +/* +** Interfaces for opening a shared library, finding entry points +** within the shared library, and closing the shared library. +*/ +#include +void *sqlite3UnixDlopen(const char *zFilename){ + return dlopen(zFilename, RTLD_NOW | RTLD_GLOBAL); +} +void *sqlite3UnixDlsym(void *pHandle, const char *zSymbol){ + return dlsym(pHandle, zSymbol); +} +int sqlite3UnixDlclose(void *pHandle){ + return dlclose(pHandle); +} +#endif /* SQLITE_OMIT_LOAD_EXTENSION */ + /* ** Get information to seed the random number generator. The seed ** is written into the buffer zBuf[256]. The calling function must diff --git a/dlls/sqlite/sqlite-source/os_win.c b/dlls/sqlite/sqlite-source/os_win.c index d6b6310e..b3c4771b 100644 --- a/dlls/sqlite/sqlite-source/os_win.c +++ b/dlls/sqlite/sqlite-source/os_win.c @@ -40,6 +40,7 @@ */ #if defined(_WIN32_WCE) # define OS_WINCE 1 +# define AreFileApisANSI() 1 #else # define OS_WINCE 0 #endif @@ -124,16 +125,14 @@ int sqlite3_os_type = 0; #endif /* OS_WINCE */ /* -** Convert a UTF-8 string to UTF-32. Space to hold the returned string -** is obtained from sqliteMalloc. +** Convert a UTF-8 string to microsoft unicode (UTF-16?). +** +** Space to hold the returned string is obtained from sqliteMalloc. */ static WCHAR *utf8ToUnicode(const char *zFilename){ int nChar; WCHAR *zWideFilename; - if( !isNT() ){ - return 0; - } nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); zWideFilename = sqliteMalloc( nChar*sizeof(zWideFilename[0]) ); if( zWideFilename==0 ){ @@ -148,7 +147,7 @@ static WCHAR *utf8ToUnicode(const char *zFilename){ } /* -** Convert UTF-32 to UTF-8. Space to hold the returned string is +** Convert microsoft unicode to UTF-8. Space to hold the returned string is ** obtained from sqliteMalloc(). */ static char *unicodeToUtf8(const WCHAR *zWideFilename){ @@ -169,6 +168,91 @@ static char *unicodeToUtf8(const WCHAR *zWideFilename){ return zFilename; } +/* +** Convert an ansi string to microsoft unicode, based on the +** current codepage settings for file apis. +** +** Space to hold the returned string is obtained +** from sqliteMalloc. +*/ +static WCHAR *mbcsToUnicode(const char *zFilename){ + int nByte; + WCHAR *zMbcsFilename; + int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; + + nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, NULL,0)*sizeof(WCHAR); + zMbcsFilename = sqliteMalloc( nByte*sizeof(zMbcsFilename[0]) ); + if( zMbcsFilename==0 ){ + return 0; + } + nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, nByte); + if( nByte==0 ){ + sqliteFree(zMbcsFilename); + zMbcsFilename = 0; + } + return zMbcsFilename; +} + +/* +** Convert microsoft unicode to multibyte character string, based on the +** user's Ansi codepage. +** +** Space to hold the returned string is obtained from +** sqliteMalloc(). +*/ +static char *unicodeToMbcs(const WCHAR *zWideFilename){ + int nByte; + char *zFilename; + int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; + + nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0); + zFilename = sqliteMalloc( nByte ); + if( zFilename==0 ){ + return 0; + } + nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, nByte, + 0, 0); + if( nByte == 0 ){ + sqliteFree(zFilename); + zFilename = 0; + } + return zFilename; +} + +/* +** Convert multibyte character string to UTF-8. Space to hold the +** returned string is obtained from sqliteMalloc(). +*/ +static char *mbcsToUtf8(const char *zFilename){ + char *zFilenameUtf8; + WCHAR *zTmpWide; + + zTmpWide = mbcsToUnicode(zFilename); + if( zTmpWide==0 ){ + return 0; + } + zFilenameUtf8 = unicodeToUtf8(zTmpWide); + sqliteFree(zTmpWide); + return zFilenameUtf8; +} + +/* +** Convert UTF-8 to multibyte character string. Space to hold the +** returned string is obtained from sqliteMalloc(). +*/ +static char *utf8ToMbcs(const char *zFilename){ + char *zFilenameMbcs; + WCHAR *zTmpWide; + + zTmpWide = utf8ToUnicode(zFilename); + if( zTmpWide==0 ){ + return 0; + } + zFilenameMbcs = unicodeToMbcs(zTmpWide); + sqliteFree(zTmpWide); + return zFilenameMbcs; +} + #if OS_WINCE /************************************************************************* ** This section contains code for WinCE only. @@ -476,22 +560,60 @@ static BOOL winceLockFileEx( #endif /* OS_WINCE */ /* -** Delete the named file +** Convert a UTF-8 filename into whatever form the underlying +** operating system wants filenames in. Space to hold the result +** is obtained from sqliteMalloc and must be freed by the calling +** function. */ +static void *convertUtf8Filename(const char *zFilename){ + void *zConverted = 0; + if( isNT() ){ + zConverted = utf8ToUnicode(zFilename); + }else{ + zConverted = utf8ToMbcs(zFilename); + } + /* caller will handle out of memory */ + return zConverted; +} + +/* +** Delete the named file. +** +** Note that windows does not allow a file to be deleted if some other +** process has it open. Sometimes a virus scanner or indexing program +** will open a journal file shortly after it is created in order to do +** whatever it is it does. While this other process is holding the +** file open, we will be unable to delete it. To work around this +** problem, we delay 100 milliseconds and try to delete again. Up +** to MX_DELETION_ATTEMPTs deletion attempts are run before giving +** up and returning an error. +*/ +#define MX_DELETION_ATTEMPTS 3 int sqlite3WinDelete(const char *zFilename){ - WCHAR *zWide = utf8ToUnicode(zFilename); - if( zWide ){ - DeleteFileW(zWide); - sqliteFree(zWide); + int cnt = 0; + int rc; + void *zConverted = convertUtf8Filename(zFilename); + if( zConverted==0 ){ + return SQLITE_NOMEM; + } + if( isNT() ){ + do{ + rc = DeleteFileW(zConverted); + }while( rc==0 && GetFileAttributesW(zConverted)!=0xffffffff + && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) ); }else{ #if OS_WINCE return SQLITE_NOMEM; #else - DeleteFileA(zFilename); + do{ + rc = DeleteFileA(zConverted); + }while( rc==0 && GetFileAttributesA(zConverted)!=0xffffffff + && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) ); #endif } + sqliteFree(zConverted); TRACE2("DELETE \"%s\"\n", zFilename); - return SQLITE_OK; + return rc!=0 ? SQLITE_OK : SQLITE_IOERR; } /* @@ -499,17 +621,20 @@ int sqlite3WinDelete(const char *zFilename){ */ int sqlite3WinFileExists(const char *zFilename){ int exists = 0; - WCHAR *zWide = utf8ToUnicode(zFilename); - if( zWide ){ - exists = GetFileAttributesW(zWide) != 0xffffffff; - sqliteFree(zWide); + void *zConverted = convertUtf8Filename(zFilename); + if( zConverted==0 ){ + return SQLITE_NOMEM; + } + if( isNT() ){ + exists = GetFileAttributesW((WCHAR*)zConverted) != 0xffffffff; }else{ #if OS_WINCE return SQLITE_NOMEM; #else - exists = GetFileAttributesA(zFilename) != 0xffffffff; + exists = GetFileAttributesA((char*)zConverted) != 0xffffffff; #endif } + sqliteFree(zConverted); return exists; } @@ -536,10 +661,14 @@ int sqlite3WinOpenReadWrite( ){ winFile f; HANDLE h; - WCHAR *zWide = utf8ToUnicode(zFilename); + void *zConverted = convertUtf8Filename(zFilename); + if( zConverted==0 ){ + return SQLITE_NOMEM; + } assert( *pId==0 ); - if( zWide ){ - h = CreateFileW(zWide, + + if( isNT() ){ + h = CreateFileW((WCHAR*)zConverted, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, @@ -548,16 +677,16 @@ int sqlite3WinOpenReadWrite( NULL ); if( h==INVALID_HANDLE_VALUE ){ - h = CreateFileW(zWide, + h = CreateFileW((WCHAR*)zConverted, GENERIC_READ, - FILE_SHARE_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL ); if( h==INVALID_HANDLE_VALUE ){ - sqliteFree(zWide); + sqliteFree(zConverted); return SQLITE_CANTOPEN; } *pReadonly = 1; @@ -567,16 +696,15 @@ int sqlite3WinOpenReadWrite( #if OS_WINCE if (!winceCreateLock(zFilename, &f)){ CloseHandle(h); - sqliteFree(zWide); + sqliteFree(zConverted); return SQLITE_CANTOPEN; } #endif - sqliteFree(zWide); }else{ #if OS_WINCE return SQLITE_NOMEM; #else - h = CreateFileA(zFilename, + h = CreateFileA((char*)zConverted, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, @@ -585,15 +713,16 @@ int sqlite3WinOpenReadWrite( NULL ); if( h==INVALID_HANDLE_VALUE ){ - h = CreateFileA(zFilename, + h = CreateFileA((char*)zConverted, GENERIC_READ, - FILE_SHARE_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL ); if( h==INVALID_HANDLE_VALUE ){ + sqliteFree(zConverted); return SQLITE_CANTOPEN; } *pReadonly = 1; @@ -602,6 +731,9 @@ int sqlite3WinOpenReadWrite( } #endif /* OS_WINCE */ } + + sqliteFree(zConverted); + f.h = h; #if OS_WINCE f.zDeleteOnClose = 0; @@ -624,12 +756,21 @@ int sqlite3WinOpenReadWrite( ** On success, write the file handle into *id and return SQLITE_OK. ** ** On failure, return SQLITE_CANTOPEN. +** +** Sometimes if we have just deleted a prior journal file, windows +** will fail to open a new one because there is a "pending delete". +** To work around this bug, we pause for 100 milliseconds and attempt +** a second open after the first one fails. The whole operation only +** fails if both open attempts are unsuccessful. */ int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){ winFile f; HANDLE h; - int fileflags; - WCHAR *zWide = utf8ToUnicode(zFilename); + DWORD fileflags; + void *zConverted = convertUtf8Filename(zFilename); + if( zConverted==0 ){ + return SQLITE_NOMEM; + } assert( *pId == 0 ); fileflags = FILE_FLAG_RANDOM_ACCESS; #if !OS_WINCE @@ -637,38 +778,47 @@ int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){ fileflags |= FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE; } #endif - if( zWide ){ - h = CreateFileW(zWide, - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - CREATE_ALWAYS, - fileflags, - NULL - ); - sqliteFree(zWide); + if( isNT() ){ + int cnt = 0; + do{ + h = CreateFileW((WCHAR*)zConverted, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + fileflags, + NULL + ); + }while( h==INVALID_HANDLE_VALUE && cnt++ < 2 && (Sleep(100), 1) ); }else{ #if OS_WINCE return SQLITE_NOMEM; #else - h = CreateFileA(zFilename, - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - CREATE_ALWAYS, - fileflags, - NULL - ); + int cnt = 0; + do{ + h = CreateFileA((char*)zConverted, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + fileflags, + NULL + ); + }while( h==INVALID_HANDLE_VALUE && cnt++ < 2 && (Sleep(100), 1) ); #endif /* OS_WINCE */ } +#if OS_WINCE + if( delFlag && h!=INVALID_HANDLE_VALUE ){ + f.zDeleteOnClose = zConverted; + zConverted = 0; + } + f.hMutex = NULL; +#endif + sqliteFree(zConverted); if( h==INVALID_HANDLE_VALUE ){ return SQLITE_CANTOPEN; } f.h = h; -#if OS_WINCE - f.zDeleteOnClose = delFlag ? utf8ToUnicode(zFilename) : 0; - f.hMutex = NULL; -#endif TRACE3("OPEN EX %d \"%s\"\n", h, zFilename); return allocateWinFile(&f, pId); } @@ -683,10 +833,13 @@ int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){ int sqlite3WinOpenReadOnly(const char *zFilename, OsFile **pId){ winFile f; HANDLE h; - WCHAR *zWide = utf8ToUnicode(zFilename); + void *zConverted = convertUtf8Filename(zFilename); + if( zConverted==0 ){ + return SQLITE_NOMEM; + } assert( *pId==0 ); - if( zWide ){ - h = CreateFileW(zWide, + if( isNT() ){ + h = CreateFileW((WCHAR*)zConverted, GENERIC_READ, 0, NULL, @@ -694,12 +847,11 @@ int sqlite3WinOpenReadOnly(const char *zFilename, OsFile **pId){ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL ); - sqliteFree(zWide); }else{ #if OS_WINCE return SQLITE_NOMEM; #else - h = CreateFileA(zFilename, + h = CreateFileA((char*)zConverted, GENERIC_READ, 0, NULL, @@ -709,6 +861,7 @@ int sqlite3WinOpenReadOnly(const char *zFilename, OsFile **pId){ ); #endif } + sqliteFree(zConverted); if( h==INVALID_HANDLE_VALUE ){ return SQLITE_CANTOPEN; } @@ -774,9 +927,21 @@ int sqlite3WinTempFileName(char *zBuf){ strncpy(zTempPath, zMulti, SQLITE_TEMPNAME_SIZE-30); zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0; sqliteFree(zMulti); + }else{ + return SQLITE_NOMEM; } }else{ - GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zTempPath); + char *zUtf8; + char zMbcsPath[SQLITE_TEMPNAME_SIZE]; + GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zMbcsPath); + zUtf8 = mbcsToUtf8(zMbcsPath); + if( zUtf8 ){ + strncpy(zTempPath, zUtf8, SQLITE_TEMPNAME_SIZE-30); + zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0; + sqliteFree(zUtf8); + }else{ + return SQLITE_NOMEM; + } } for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){} zTempPath[i] = 0; @@ -796,12 +961,24 @@ int sqlite3WinTempFileName(char *zBuf){ /* ** Close a file. +** +** It is reported that an attempt to close a handle might sometimes +** fail. This is a very unreasonable result, but windows is notorious +** for being unreasonable so I do not doubt that it might happen. If +** the close fails, we pause for 100 milliseconds and try again. As +** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before +** giving up and returning an error. */ +#define MX_CLOSE_ATTEMPT 3 static int winClose(OsFile **pId){ winFile *pFile; + int rc = 1; if( pId && (pFile = (winFile*)*pId)!=0 ){ + int rc, cnt = 0; TRACE2("CLOSE %d\n", pFile->h); - CloseHandle(pFile->h); + do{ + rc = CloseHandle(pFile->h); + }while( rc==0 && cnt++ < MX_CLOSE_ATTEMPT && (Sleep(100), 1) ); #if OS_WINCE winceDestroyLock(pFile); if( pFile->zDeleteOnClose ){ @@ -813,7 +990,7 @@ static int winClose(OsFile **pId){ sqliteFree(pFile); *pId = 0; } - return SQLITE_OK; + return rc ? SQLITE_OK : SQLITE_IOERR; } /* @@ -824,15 +1001,16 @@ static int winClose(OsFile **pId){ static int winRead(OsFile *id, void *pBuf, int amt){ DWORD got; assert( id!=0 ); - SimulateIOError(SQLITE_IOERR); + SimulateIOError(return SQLITE_IOERR_READ); TRACE3("READ %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype); if( !ReadFile(((winFile*)id)->h, pBuf, amt, &got, 0) ){ - got = 0; + return SQLITE_IOERR_READ; } if( got==(DWORD)amt ){ return SQLITE_OK; }else{ - return SQLITE_IOERR; + memset(&((char*)pBuf)[got], 0, amt-got); + return SQLITE_IOERR_SHORT_READ; } } @@ -844,8 +1022,8 @@ static int winWrite(OsFile *id, const void *pBuf, int amt){ int rc = 0; DWORD wrote; assert( id!=0 ); - SimulateIOError(SQLITE_IOERR); - SimulateDiskfullError; + SimulateIOError(return SQLITE_IOERR_READ); + SimulateDiskfullError(return SQLITE_FULL); TRACE3("WRITE %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype); assert( amt>0 ); while( amt>0 && (rc = WriteFile(((winFile*)id)->h, pBuf, amt, &wrote, 0))!=0 @@ -871,11 +1049,11 @@ static int winWrite(OsFile *id, const void *pBuf, int amt){ */ static int winSeek(OsFile *id, i64 offset){ LONG upperBits = (LONG)(offset>>32); - LONG lowerBits = (LONG)(offset) & 0xffffffff; + LONG lowerBits = (LONG)(offset & 0xffffffff); DWORD rc; assert( id!=0 ); #ifdef SQLITE_TEST - if( offset ) SimulateDiskfullError + if( offset ) SimulateDiskfullError(return SQLITE_FULL); #endif SEEK(offset/1024 + 1); rc = SetFilePointer(((winFile*)id)->h, lowerBits, &upperBits, FILE_BEGIN); @@ -904,7 +1082,7 @@ static int winSync(OsFile *id, int dataOnly){ ** than UNIX. */ int sqlite3WinSyncDirectory(const char *zDirname){ - SimulateIOError(SQLITE_IOERR); + SimulateIOError(return SQLITE_IOERR_READ); return SQLITE_OK; } @@ -915,7 +1093,7 @@ static int winTruncate(OsFile *id, i64 nByte){ LONG upperBits = (LONG)(nByte>>32); assert( id!=0 ); TRACE3("TRUNCATE %d %lld\n", ((winFile*)id)->h, nByte); - SimulateIOError(SQLITE_IOERR); + SimulateIOError(return SQLITE_IOERR_TRUNCATE); SetFilePointer(((winFile*)id)->h, (LONG)nByte, &upperBits, FILE_BEGIN); SetEndOfFile(((winFile*)id)->h); return SQLITE_OK; @@ -927,7 +1105,7 @@ static int winTruncate(OsFile *id, i64 nByte){ static int winFileSize(OsFile *id, i64 *pSize){ DWORD upperBits, lowerBits; assert( id!=0 ); - SimulateIOError(SQLITE_IOERR); + SimulateIOError(return SQLITE_IOERR_FSTAT); lowerBits = GetFileSize(((winFile*)id)->h, &upperBits); *pSize = (((i64)upperBits)<<32) + lowerBits; return SQLITE_OK; @@ -982,20 +1160,24 @@ static int unlockReadLock(winFile *pFile){ */ int sqlite3WinIsDirWritable(char *zDirname){ int fileAttr; - WCHAR *zWide; + void *zConverted; if( zDirname==0 ) return 0; if( !isNT() && strlen(zDirname)>MAX_PATH ) return 0; - zWide = utf8ToUnicode(zDirname); - if( zWide ){ - fileAttr = GetFileAttributesW(zWide); - sqliteFree(zWide); + + zConverted = convertUtf8Filename(zDirname); + if( zConverted==0 ){ + return SQLITE_NOMEM; + } + if( isNT() ){ + fileAttr = GetFileAttributesW((WCHAR*)zConverted); }else{ #if OS_WINCE return 0; #else - fileAttr = GetFileAttributesA(zDirname); + fileAttr = GetFileAttributesA((char*)zConverted); #endif } + sqliteFree(zConverted); if( fileAttr == 0xffffffff ) return 0; if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ){ return 0; @@ -1184,7 +1366,7 @@ static int winUnlock(OsFile *id, int locktype){ if( locktype==SHARED_LOCK && !getReadLock(pFile) ){ /* This should never happen. We should always be able to ** reacquire the read lock */ - rc = SQLITE_IOERR; + rc = SQLITE_IOERR_UNLOCK; } } if( type>=RESERVED_LOCK ){ @@ -1218,24 +1400,33 @@ char *sqlite3WinFullPathname(const char *zRelative){ /* WinCE has no concept of a relative pathname, or so I am told. */ zFull = sqliteStrDup(zRelative); #else - char *zNotUsed; - WCHAR *zWide; int nByte; - zWide = utf8ToUnicode(zRelative); - if( zWide ){ - WCHAR *zTemp, *zNotUsedW; - nByte = GetFullPathNameW(zWide, 0, 0, &zNotUsedW) + 1; + void *zConverted; + zConverted = convertUtf8Filename(zRelative); + if( isNT() ){ + WCHAR *zTemp; + nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3; zTemp = sqliteMalloc( nByte*sizeof(zTemp[0]) ); - if( zTemp==0 ) return 0; - GetFullPathNameW(zWide, nByte, zTemp, &zNotUsedW); - sqliteFree(zWide); + if( zTemp==0 ){ + sqliteFree(zConverted); + return 0; + } + GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, 0); + sqliteFree(zConverted); zFull = unicodeToUtf8(zTemp); sqliteFree(zTemp); }else{ - nByte = GetFullPathNameA(zRelative, 0, 0, &zNotUsed) + 1; - zFull = sqliteMalloc( nByte*sizeof(zFull[0]) ); - if( zFull==0 ) return 0; - GetFullPathNameA(zRelative, nByte, zFull, &zNotUsed); + char *zTemp; + nByte = GetFullPathNameA((char*)zConverted, 0, 0, 0) + 3; + zTemp = sqliteMalloc( nByte*sizeof(zTemp[0]) ); + if( zTemp==0 ){ + sqliteFree(zConverted); + return 0; + } + GetFullPathNameA((char*)zConverted, nByte, zTemp, 0); + sqliteFree(zConverted); + zFull = mbcsToUtf8(zTemp); + sqliteFree(zTemp); } #endif return zFull; @@ -1317,6 +1508,45 @@ static int allocateWinFile(winFile *pInit, OsFile **pId){ ** with other miscellanous aspects of the operating system interface ****************************************************************************/ +#if !defined(SQLITE_OMIT_LOAD_EXTENSION) +/* +** Interfaces for opening a shared library, finding entry points +** within the shared library, and closing the shared library. +*/ +void *sqlite3WinDlopen(const char *zFilename){ + HANDLE h; + void *zConverted = convertUtf8Filename(zFilename); + if( zConverted==0 ){ + return 0; + } + if( isNT() ){ + h = LoadLibraryW((WCHAR*)zConverted); + }else{ +#if OS_WINCE + return 0; +#else + h = LoadLibraryA((char*)zConverted); +#endif + } + sqliteFree(zConverted); + return (void*)h; + +} +void *sqlite3WinDlsym(void *pHandle, const char *zSymbol){ +#if OS_WINCE + /* The GetProcAddressA() routine is only available on wince. */ + return GetProcAddressA((HANDLE)pHandle, zSymbol); +#else + /* All other windows platforms expect GetProcAddress() to take + ** an Ansi string regardless of the _UNICODE setting */ + return GetProcAddress((HANDLE)pHandle, zSymbol); +#endif +} +int sqlite3WinDlclose(void *pHandle){ + return FreeLibrary((HANDLE)pHandle); +} +#endif /* !SQLITE_OMIT_LOAD_EXTENSION */ + /* ** Get information to seed the random number generator. The seed ** is written into the buffer zBuf[256]. The calling function must diff --git a/dlls/sqlite/sqlite-source/pager.c b/dlls/sqlite/sqlite-source/pager.c index 8ccbb587..8e47694f 100644 --- a/dlls/sqlite/sqlite-source/pager.c +++ b/dlls/sqlite/sqlite-source/pager.c @@ -31,6 +31,7 @@ ** Macros for troubleshooting. Normally turned off */ #if 0 +#define sqlite3DebugPrintf printf #define TRACE1(X) sqlite3DebugPrintf(X) #define TRACE2(X,Y) sqlite3DebugPrintf(X,Y) #define TRACE3(X,Y,Z) sqlite3DebugPrintf(X,Y,Z) @@ -161,7 +162,8 @@ struct PgHdr { u8 needSync; /* Sync journal before writing this page */ u8 alwaysRollback; /* Disable dont_rollback() for this page */ short int nRef; /* Number of users of this page */ - PgHdr *pDirty; /* Dirty pages sorted by PgHdr.pgno */ + PgHdr *pDirty, *pPrevDirty; /* Dirty pages */ + u32 notUsed; /* Buffer space */ #ifdef SQLITE_CHECK_PAGES u32 pageHash; #endif @@ -207,24 +209,6 @@ struct PgHistory { #define PGHDR_TO_HIST(P,PGR) \ ((PgHistory*)&((char*)(&(P)[1]))[(PGR)->pageSize+(PGR)->nExtra]) -/* -** How big to make the hash table used for locating in-memory pages -** by page number. This macro looks a little silly, but is evaluated -** at compile-time, not run-time (at least for gcc this is true). -*/ -#define N_PG_HASH (\ - (MAX_PAGES>1024)?2048: \ - (MAX_PAGES>512)?1024: \ - (MAX_PAGES>256)?512: \ - (MAX_PAGES>128)?256: \ - (MAX_PAGES>64)?128:64 \ -) - -/* -** Hash a page number -*/ -#define pager_hash(PN) ((PN)&(N_PG_HASH-1)) - /* ** A open page cache is an instance of the following structure. ** @@ -248,7 +232,6 @@ struct Pager { u8 fullSync; /* Do extra syncs of the journal for robustness */ u8 full_fsync; /* Use F_FULLFSYNC when available */ u8 state; /* PAGER_UNLOCK, _SHARED, _RESERVED, etc. */ - u8 errCode; /* One of several kinds of errors */ u8 tempFile; /* zFilename is a temporary file */ u8 readOnly; /* True for a read-only database */ u8 needSync; /* True if an fsync() is needed on the journal */ @@ -256,6 +239,7 @@ struct Pager { u8 alwaysRollback; /* Disable dont_rollback() for all pages */ u8 memDb; /* True to inhibit all file I/O */ u8 setMaster; /* True if a m-j name has been written to jrnl */ + int errCode; /* One of several kinds of errors */ int dbSize; /* Number of pages in the file */ int origDbSize; /* dbSize before the current change */ int stmtSize; /* Size of database (in pages) at stmt_begin() */ @@ -280,6 +264,7 @@ struct Pager { PgHdr *pFirstSynced; /* First free page with PgHdr.needSync==0 */ PgHdr *pAll; /* List of all pages */ PgHdr *pStmt; /* List of pages in the statement subjournal */ + PgHdr *pDirty; /* List of all dirty pages */ i64 journalOff; /* Current byte offset in the journal file */ i64 journalHdr; /* Byte offset to previous journal header */ i64 stmtHdrOff; /* First journal header written this statement */ @@ -294,7 +279,8 @@ struct Pager { void (*xReiniter)(void*,int); /* Call this routine when reloading pages */ void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */ void *pCodecArg; /* First argument to xCodec() */ - PgHdr *aHash[N_PG_HASH]; /* Hash table to map page number to PgHdr */ + int nHash; /* Size of the pager hash table */ + PgHdr **aHash; /* Hash table to map page number to PgHdr */ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT Pager *pNext; /* Linked list of pagers in this thread */ #endif @@ -365,7 +351,9 @@ static const unsigned char aJournalMagic[] = { /* ** The default size of a disk sector */ -#define PAGER_SECTOR_SIZE 512 +#ifndef PAGER_SECTOR_SIZE +# define PAGER_SECTOR_SIZE 512 +#endif /* ** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is @@ -385,14 +373,14 @@ static const unsigned char aJournalMagic[] = { /* ** Enable reference count tracking (for debugging) here: */ -#ifdef SQLITE_DEBUG +#ifdef SQLITE_TEST int pager3_refinfo_enable = 0; static void pager_refinfo(PgHdr *p){ static int cnt = 0; if( !pager3_refinfo_enable ) return; sqlite3DebugPrintf( - "REFCNT: %4d addr=%p nRef=%d\n", - p->pgno, PGHDR_TO_DATA(p), p->nRef + "REFCNT: %4d addr=%p nRef=%-3d total=%d\n", + p->pgno, PGHDR_TO_DATA(p), p->nRef, p->pPager->nRef ); cnt++; /* Something to set a breakpoint on */ } @@ -401,6 +389,38 @@ static const unsigned char aJournalMagic[] = { # define REFINFO(X) #endif + +/* +** Change the size of the pager hash table to N. N must be a power +** of two. +*/ +static void pager_resize_hash_table(Pager *pPager, int N){ + PgHdr **aHash, *pPg; + assert( N>0 && (N&(N-1))==0 ); + aHash = sqliteMalloc( sizeof(aHash[0])*N ); + if( aHash==0 ){ + /* Failure to rehash is not an error. It is only a performance hit. */ + return; + } + sqliteFree(pPager->aHash); + pPager->nHash = N; + pPager->aHash = aHash; + for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){ + int h; + if( pPg->pgno==0 ){ + assert( pPg->pNextHash==0 && pPg->pPrevHash==0 ); + continue; + } + h = pPg->pgno & (N-1); + pPg->pNextHash = aHash[h]; + if( aHash[h] ){ + aHash[h]->pPrevHash = pPg; + } + aHash[h] = pPg; + pPg->pPrevHash = 0; + } +} + /* ** Read a 32-bit integer from the given file descriptor. Store the integer ** that is read in *pRes. Return SQLITE_OK if everything worked, or an @@ -459,12 +479,13 @@ static u32 retrieve32bits(PgHdr *p, int offset){ ** will immediately return the same error code. */ static int pager_error(Pager *pPager, int rc){ + int rc2 = rc & 0xff; assert( pPager->errCode==SQLITE_FULL || pPager->errCode==SQLITE_OK ); if( - rc==SQLITE_FULL || - rc==SQLITE_IOERR || - rc==SQLITE_CORRUPT || - rc==SQLITE_PROTOCOL + rc2==SQLITE_FULL || + rc2==SQLITE_IOERR || + rc2==SQLITE_CORRUPT || + rc2==SQLITE_PROTOCOL ){ pPager->errCode = rc; } @@ -820,13 +841,32 @@ static void page_remove_from_stmt_list(PgHdr *pPg){ ** a pointer to the page or NULL if not found. */ static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){ - PgHdr *p = pPager->aHash[pager_hash(pgno)]; + PgHdr *p; + if( pPager->aHash==0 ) return 0; + p = pPager->aHash[pgno & (pPager->nHash-1)]; while( p && p->pgno!=pgno ){ p = p->pNextHash; } return p; } +/* +** Unlock the database file. +** +** Once all locks have been removed from the database file, other +** processes or threads might change the file. So make sure all of +** our internal cache is invalidated. +*/ +static void pager_unlock(Pager *pPager){ + if( !MEMDB ){ + sqlite3OsUnlock(pPager->fd, NO_LOCK); + pPager->dbSize = -1; + } + pPager->state = PAGER_UNLOCK; + assert( pPager->pAll==0 ); +} + + /* ** Unlock the database and clear the in-memory cache. This routine ** sets the state of the pager back to what it was when it was first @@ -844,16 +884,16 @@ static void pager_reset(Pager *pPager){ pPager->pFirstSynced = 0; pPager->pLast = 0; pPager->pAll = 0; - memset(pPager->aHash, 0, sizeof(pPager->aHash)); + pPager->nHash = 0; + sqliteFree(pPager->aHash); pPager->nPage = 0; + pPager->aHash = 0; if( pPager->state>=PAGER_RESERVED ){ sqlite3pager_rollback(pPager); } - sqlite3OsUnlock(pPager->fd, NO_LOCK); - pPager->state = PAGER_UNLOCK; - pPager->dbSize = -1; + pager_unlock(pPager); pPager->nRef = 0; - assert( pPager->journalOpen==0 ); + assert( pPager->errCode || (pPager->journalOpen==0 && pPager->stmtOpen==0) ); } /* @@ -892,6 +932,7 @@ static int pager_unwritelock(Pager *pPager){ pPg->pageHash = pager_pagehash(pPg); #endif } + pPager->pDirty = 0; pPager->dirtyCache = 0; pPager->nRec = 0; }else{ @@ -904,6 +945,7 @@ static int pager_unwritelock(Pager *pPager){ pPager->setMaster = 0; pPager->needSync = 0; pPager->pFirstSynced = pPager->pFirst; + pPager->dbSize = -1; return rc; } @@ -937,6 +979,9 @@ static u32 pager_cksum(Pager *pPager, const u8 *aData){ return cksum; } +/* Forward declaration */ +static void makeClean(PgHdr*); + /* ** Read a single page from the journal file opened on file descriptor ** jfd. Playback this one page. @@ -1014,7 +1059,9 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){ if( rc==SQLITE_OK ){ rc = sqlite3OsWrite(pPager->fd, aData, pPager->pageSize); } - if( pPg ) pPg->dirty = 0; + if( pPg ){ + makeClean(pPg); + } } if( pPg ){ /* No page should ever be explicitly rolled back that is in use, except @@ -1164,6 +1211,7 @@ static int pager_reload_cache(Pager *pPager){ pPg->pageHash = pager_pagehash(pPg); #endif } + pPager->pDirty = 0; return rc; } @@ -1312,6 +1360,10 @@ static int pager_playback(Pager *pPager){ pPager->journalOff = szJ; break; }else{ + /* If we are unable to rollback a hot journal, then the database + ** is probably not recoverable. Return CORRUPT. + */ + rc = SQLITE_CORRUPT; goto end_playback; } } @@ -1388,6 +1440,7 @@ static int pager_stmt_playback(Pager *pPager){ if( pPager->state>=PAGER_EXCLUSIVE ){ rc = pager_truncate(pPager, pPager->stmtSize); } + assert( pPager->state>=PAGER_SHARED ); pPager->dbSize = pPager->stmtSize; /* Figure out how many records are in the statement journal. @@ -1507,7 +1560,9 @@ void sqlite3pager_set_safety_level(Pager *pPager, int level, int full_fsync){ ** attempts to open a temporary file. This information is used for ** testing and analysis only. */ +#ifdef SQLITE_TEST int sqlite3_opentemp_count = 0; +#endif /* ** Open a temporary file. Write the name of the file into zFile @@ -1521,7 +1576,9 @@ int sqlite3_opentemp_count = 0; static int sqlite3pager_opentemp(char *zFile, OsFile **pFd){ int cnt = 8; int rc; +#ifdef SQLITE_TEST sqlite3_opentemp_count++; /* Used for testing and analysis only */ +#endif do{ cnt--; sqlite3OsTempFileName(zFile); @@ -1552,7 +1609,7 @@ int sqlite3pager_open( ){ Pager *pPager = 0; char *zFullPathname = 0; - int nameLen = 0; /* Compiler is wrong. This is always initialized before use */ + int nameLen; /* Compiler is wrong. This is always initialized before use */ OsFile *fd; int rc = SQLITE_OK; int i; @@ -1761,14 +1818,19 @@ void enable_simulated_io_errors(void){ ** response is to zero the memory at pDest and continue. A real IO error ** will presumably recur and be picked up later (Todo: Think about this). */ -void sqlite3pager_read_fileheader(Pager *pPager, int N, unsigned char *pDest){ +int sqlite3pager_read_fileheader(Pager *pPager, int N, unsigned char *pDest){ + int rc = SQLITE_OK; memset(pDest, 0, N); if( MEMDB==0 ){ disable_simulated_io_errors(); sqlite3OsSeek(pPager->fd, 0); - sqlite3OsRead(pPager->fd, pDest, N); enable_simulated_io_errors(); + rc = sqlite3OsRead(pPager->fd, pDest, N); + if( rc==SQLITE_IOERR_SHORT_READ ){ + rc = SQLITE_OK; + } } + return rc; } /* @@ -1782,12 +1844,13 @@ void sqlite3pager_read_fileheader(Pager *pPager, int N, unsigned char *pDest){ */ int sqlite3pager_pagecount(Pager *pPager){ i64 n; + int rc; assert( pPager!=0 ); if( pPager->dbSize>=0 ){ n = pPager->dbSize; } else { - if( sqlite3OsFileSize(pPager->fd, &n)!=SQLITE_OK ){ - pager_error(pPager, SQLITE_IOERR); + if( (rc = sqlite3OsFileSize(pPager->fd, &n))!=SQLITE_OK ){ + pager_error(pPager, rc); return 0; } if( n>0 && npageSize ){ @@ -1805,12 +1868,25 @@ int sqlite3pager_pagecount(Pager *pPager){ return (int)n; } + +#ifndef SQLITE_OMIT_MEMORYDB +/* +** Clear a PgHistory block +*/ +static void clearHistory(PgHistory *pHist){ + sqliteFree(pHist->pOrig); + sqliteFree(pHist->pStmt); + pHist->pOrig = 0; + pHist->pStmt = 0; +} +#else +#define clearHistory(x) +#endif + /* ** Forward declaration */ static int syncJournal(Pager*); -static void clearHistory(PgHistory*); - /* ** Unlink pPg from it's hash chain. Also set the page number to 0 to indicate @@ -1820,18 +1896,17 @@ static void clearHistory(PgHistory*); */ static void unlinkHashChain(Pager *pPager, PgHdr *pPg){ if( pPg->pgno==0 ){ - /* If the page number is zero, then this page is not in any hash chain. */ + assert( pPg->pNextHash==0 && pPg->pPrevHash==0 ); return; } if( pPg->pNextHash ){ pPg->pNextHash->pPrevHash = pPg->pPrevHash; } if( pPg->pPrevHash ){ - assert( pPager->aHash[pager_hash(pPg->pgno)]!=pPg ); + assert( pPager->aHash[pPg->pgno & (pPager->nHash-1)]!=pPg ); pPg->pPrevHash->pNextHash = pPg->pNextHash; }else{ - int h = pager_hash(pPg->pgno); - assert( pPager->aHash[h]==pPg ); + int h = pPg->pgno & (pPager->nHash-1); pPager->aHash[h] = pPg->pNextHash; } if( MEMDB ){ @@ -1895,6 +1970,7 @@ static void memoryTruncate(Pager *pPager){ }else{ *ppPg = pPg->pNextAll; unlinkPage(pPg); + makeClean(pPg); sqliteFree(pPg); pPager->nPage--; } @@ -1914,9 +1990,15 @@ static void memoryTruncate(Pager *pPager){ */ static int pager_wait_on_lock(Pager *pPager, int locktype){ int rc; + + /* The OS lock values must be the same as the Pager lock values */ assert( PAGER_SHARED==SHARED_LOCK ); assert( PAGER_RESERVED==RESERVED_LOCK ); assert( PAGER_EXCLUSIVE==EXCLUSIVE_LOCK ); + + /* If the file is currently unlocked then the size must be unknown */ + assert( pPager->state>=PAGER_SHARED || pPager->dbSize<0 || MEMDB ); + if( pPager->state>=locktype ){ rc = SQLITE_OK; }else{ @@ -1935,6 +2017,7 @@ static int pager_wait_on_lock(Pager *pPager, int locktype){ */ int sqlite3pager_truncate(Pager *pPager, Pgno nPage){ int rc; + assert( pPager->state>=PAGER_SHARED || MEMDB ); sqlite3pager_pagecount(pPager); if( pPager->errCode ){ rc = pPager->errCode; @@ -1981,7 +2064,6 @@ int sqlite3pager_truncate(Pager *pPager, Pgno nPage){ ** to the caller. */ int sqlite3pager_close(Pager *pPager){ - PgHdr *pPg, *pNext; #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT /* A malloc() cannot fail in sqlite3ThreadData() as one or more calls to ** malloc() must have already been made by this thread before it gets @@ -1993,46 +2075,10 @@ int sqlite3pager_close(Pager *pPager){ assert( pTsd && pTsd->nAlloc ); #endif - switch( pPager->state ){ - case PAGER_RESERVED: - case PAGER_SYNCED: - case PAGER_EXCLUSIVE: { - /* We ignore any IO errors that occur during the rollback - ** operation. So disable IO error simulation so that testing - ** works more easily. - */ - disable_simulated_io_errors(); - sqlite3pager_rollback(pPager); - enable_simulated_io_errors(); - if( !MEMDB ){ - sqlite3OsUnlock(pPager->fd, NO_LOCK); - } - assert( pPager->errCode || pPager->journalOpen==0 ); - break; - } - case PAGER_SHARED: { - if( !MEMDB ){ - sqlite3OsUnlock(pPager->fd, NO_LOCK); - } - break; - } - default: { - /* Do nothing */ - break; - } - } - for(pPg=pPager->pAll; pPg; pPg=pNext){ -#ifndef NDEBUG - if( MEMDB ){ - PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); - assert( !pPg->alwaysRollback ); - assert( !pHist->pOrig ); - assert( !pHist->pStmt ); - } -#endif - pNext = pPg->pNextAll; - sqliteFree(pPg); - } + disable_simulated_io_errors(); + pPager->errCode = 0; + pager_reset(pPager); + enable_simulated_io_errors(); TRACE2("CLOSE %d\n", PAGERID(pPager)); assert( pPager->errCode || (pPager->journalOpen==0 && pPager->stmtOpen==0) ); if( pPager->journalOpen ){ @@ -2061,7 +2107,7 @@ int sqlite3pager_close(Pager *pPager){ pTmp->pNext = pPager->pNext; } #endif - + sqliteFree(pPager->aHash); sqliteFree(pPager); return SQLITE_OK; } @@ -2223,6 +2269,68 @@ static int syncJournal(Pager *pPager){ return rc; } +/* +** Merge two lists of pages connected by pDirty and in pgno order. +** Do not both fixing the pPrevDirty pointers. +*/ +static PgHdr *merge_pagelist(PgHdr *pA, PgHdr *pB){ + PgHdr result, *pTail; + pTail = &result; + while( pA && pB ){ + if( pA->pgnopgno ){ + pTail->pDirty = pA; + pTail = pA; + pA = pA->pDirty; + }else{ + pTail->pDirty = pB; + pTail = pB; + pB = pB->pDirty; + } + } + if( pA ){ + pTail->pDirty = pA; + }else if( pB ){ + pTail->pDirty = pB; + }else{ + pTail->pDirty = 0; + } + return result.pDirty; +} + +/* +** Sort the list of pages in accending order by pgno. Pages are +** connected by pDirty pointers. The pPrevDirty pointers are +** corrupted by this sort. +*/ +#define N_SORT_BUCKET 25 +static PgHdr *sort_pagelist(PgHdr *pIn){ + PgHdr *a[N_SORT_BUCKET], *p; + int i; + memset(a, 0, sizeof(a)); + while( pIn ){ + p = pIn; + pIn = p->pDirty; + p->pDirty = 0; + for(i=0; idirty ); rc = sqlite3OsSeek(pPager->fd, (pList->pgno-1)*(i64)pPager->pageSize); @@ -2292,15 +2401,7 @@ static int pager_write_pagelist(PgHdr *pList){ ** collected even if they are still in use. */ static PgHdr *pager_get_all_dirty_pages(Pager *pPager){ - PgHdr *p, *pList; - pList = 0; - for(p=pPager->pAll; p; p=p->pNextAll){ - if( p->dirty ){ - p->pDirty = pList; - pList = p; - } - } - return pList; + return pPager->pDirty; } /* @@ -2375,6 +2476,8 @@ static int pager_recycle(Pager *pPager, int syncOk, PgHdr **ppPg){ if( pPg->dirty ){ int rc; assert( pPg->needSync==0 ); + makeClean(pPg); + pPg->dirty = 1; pPg->pDirty = 0; rc = pager_write_pagelist( pPg ); if( rc!=SQLITE_OK ){ @@ -2476,7 +2579,7 @@ int sqlite3pager_release_memory(int nReq){ ** The error will be returned to the user (or users, in the case ** of a shared pager cache) of the pager for which the error occured. */ - assert( rc==SQLITE_IOERR || rc==SQLITE_FULL ); + assert( (rc&0xff)==SQLITE_IOERR || rc==SQLITE_FULL ); assert( p->state>=PAGER_RESERVED ); pager_error(p, rc); } @@ -2557,8 +2660,7 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ */ rc = sqlite3OsLock(pPager->fd, EXCLUSIVE_LOCK); if( rc!=SQLITE_OK ){ - sqlite3OsUnlock(pPager->fd, NO_LOCK); - pPager->state = PAGER_UNLOCK; + pager_unlock(pPager); return pager_error(pPager, rc); } pPager->state = PAGER_EXCLUSIVE; @@ -2573,8 +2675,7 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ */ rc = sqlite3OsOpenReadOnly(pPager->zJournal, &pPager->jfd); if( rc!=SQLITE_OK ){ - sqlite3OsUnlock(pPager->fd, NO_LOCK); - pPager->state = PAGER_UNLOCK; + pager_unlock(pPager); return SQLITE_BUSY; } pPager->journalOpen = 1; @@ -2605,6 +2706,13 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ TEST_INCR(pPager->nMiss); if( pPager->nPagemxPage || pPager->pFirst==0 || MEMDB ){ /* Create a new page */ + if( pPager->nPage>=pPager->nHash ){ + pager_resize_hash_table(pPager, + pPager->nHash<256 ? 256 : pPager->nHash*2); + if( pPager->nHash==0 ){ + return SQLITE_NOMEM; + } + } pPg = sqliteMallocRaw( sizeof(*pPg) + pPager->pageSize + sizeof(u32) + pPager->nExtra + MEMDB*sizeof(PgHistory) ); @@ -2646,7 +2754,7 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ }else{ page_remove_from_stmt_list(pPg); } - pPg->dirty = 0; + makeClean(pPg); pPg->nRef = 1; REFINFO(pPg); @@ -2674,26 +2782,18 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ } TRACE3("FETCH %d page %d\n", PAGERID(pPager), pPg->pgno); CODEC1(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3); - if( rc!=SQLITE_OK ){ - i64 fileSize; - int rc2 = sqlite3OsFileSize(pPager->fd, &fileSize); - if( rc2!=SQLITE_OK || fileSize>=pgno*pPager->pageSize ){ - /* An IO error occured in one of the the sqlite3OsSeek() or - ** sqlite3OsRead() calls above. */ - pPg->pgno = 0; - sqlite3pager_unref(PGHDR_TO_DATA(pPg)); - return rc; - }else{ - clear_simulated_io_error(); - memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize); - } + if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){ + pPg->pgno = 0; + sqlite3pager_unref(PGHDR_TO_DATA(pPg)); + return rc; }else{ TEST_INCR(pPager->nRead); } } /* Link the page into the page hash table */ - h = pager_hash(pgno); + h = pgno & (pPager->nHash-1); + assert( pgno!=0 ); pPg->pNextHash = pPager->aHash[h]; pPager->aHash[h] = pPg; if( pPg->pNextHash ){ @@ -2857,8 +2957,7 @@ failed_to_open_journal: */ sqlite3OsDelete(pPager->zJournal); }else{ - sqlite3OsUnlock(pPager->fd, NO_LOCK); - pPager->state = PAGER_UNLOCK; + pager_reset(pPager); } return rc; } @@ -2922,6 +3021,42 @@ int sqlite3pager_begin(void *pData, int exFlag){ return rc; } +/* +** Make a page dirty. Set its dirty flag and add it to the dirty +** page list. +*/ +static void makeDirty(PgHdr *pPg){ + if( pPg->dirty==0 ){ + Pager *pPager = pPg->pPager; + pPg->dirty = 1; + pPg->pDirty = pPager->pDirty; + if( pPager->pDirty ){ + pPager->pDirty->pPrevDirty = pPg; + } + pPg->pPrevDirty = 0; + pPager->pDirty = pPg; + } +} + +/* +** Make a page clean. Clear its dirty bit and remove it from the +** dirty page list. +*/ +static void makeClean(PgHdr *pPg){ + if( pPg->dirty ){ + pPg->dirty = 0; + if( pPg->pDirty ){ + pPg->pDirty->pPrevDirty = pPg->pPrevDirty; + } + if( pPg->pPrevDirty ){ + pPg->pPrevDirty->pDirty = pPg->pDirty; + }else{ + pPg->pPager->pDirty = pPg->pDirty; + } + } +} + + /* ** Mark a data page as writeable. The page is written into the journal ** if it is not there already. This routine must be called before making @@ -2960,7 +3095,7 @@ int sqlite3pager_write(void *pData){ /* Mark the page as dirty. If the page has already been written ** to the journal then we can return right away. */ - pPg->dirty = 1; + makeDirty(pPg); if( pPg->inJournal && (pPg->inStmt || pPager->stmtInUse==0) ){ pPager->dirtyCache = 1; }else{ @@ -3081,6 +3216,7 @@ int sqlite3pager_write(void *pData){ /* Update the database size and return. */ + assert( pPager->state>=PAGER_SHARED ); if( pPager->dbSize<(int)pPg->pgno ){ pPager->dbSize = pPg->pgno; if( !MEMDB && pPager->dbSize==PENDING_BYTE/pPager->pageSize ){ @@ -3156,6 +3292,7 @@ void sqlite3pager_dont_write(Pager *pPager, Pgno pgno){ assert( pPg!=0 ); /* We never call _dont_write unless the page is in mem */ pPg->alwaysRollback = 1; if( pPg->dirty && !pPager->stmtInUse ){ + assert( pPager->state>=PAGER_SHARED ); if( pPager->dbSize==(int)pPg->pgno && pPager->origDbSizedbSize ){ /* If this pages is the last page in the file and the file has grown ** during the current transaction, then do NOT mark the page as clean. @@ -3167,7 +3304,7 @@ void sqlite3pager_dont_write(Pager *pPager, Pgno pgno){ */ }else{ TRACE3("DONT_WRITE page %d of %d\n", pgno, PAGERID(pPager)); - pPg->dirty = 0; + makeClean(pPg); #ifdef SQLITE_CHECK_PAGES pPg->pageHash = pager_pagehash(pPg); #endif @@ -3185,7 +3322,8 @@ void sqlite3pager_dont_rollback(void *pData){ PgHdr *pPg = DATA_TO_PGHDR(pData); Pager *pPager = pPg->pPager; - if( pPager->state!=PAGER_EXCLUSIVE || pPager->journalOpen==0 ) return; + assert( pPager->state>=PAGER_RESERVED ); + if( pPager->journalOpen==0 ) return; if( pPg->alwaysRollback || pPager->alwaysRollback || MEMDB ) return; if( !pPg->inJournal && (int)pPg->pgno <= pPager->origDbSize ){ assert( pPager->aInJournal!=0 ); @@ -3206,20 +3344,6 @@ void sqlite3pager_dont_rollback(void *pData){ } -#ifndef SQLITE_OMIT_MEMORYDB -/* -** Clear a PgHistory block -*/ -static void clearHistory(PgHistory *pHist){ - sqliteFree(pHist->pOrig); - sqliteFree(pHist->pStmt); - pHist->pOrig = 0; - pHist->pStmt = 0; -} -#else -#define clearHistory(x) -#endif - /* ** Commit all changes to the database and release the write lock. ** @@ -3249,6 +3373,7 @@ int sqlite3pager_commit(Pager *pPager){ pPg->pPrevStmt = pPg->pNextStmt = 0; pPg = pPg->pDirty; } + pPager->pDirty = 0; #ifndef NDEBUG for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); @@ -3266,14 +3391,12 @@ int sqlite3pager_commit(Pager *pPager){ ** if there have been no changes to the database file. */ assert( pPager->needSync==0 ); rc = pager_unwritelock(pPager); - pPager->dbSize = -1; return rc; } assert( pPager->journalOpen ); rc = sqlite3pager_sync(pPager, 0, 0); if( rc==SQLITE_OK ){ rc = pager_unwritelock(pPager); - pPager->dbSize = -1; } return rc; } @@ -3316,12 +3439,11 @@ int sqlite3pager_rollback(Pager *pPager){ p->inJournal = 0; p->inStmt = 0; p->pPrevStmt = p->pNextStmt = 0; - if( pPager->xReiniter ){ pPager->xReiniter(PGHDR_TO_DATA(p), pPager->pageSize); } - } + pPager->pDirty = 0; pPager->pStmt = 0; pPager->dbSize = pPager->origDbSize; memoryTruncate(pPager); @@ -3332,7 +3454,6 @@ int sqlite3pager_rollback(Pager *pPager){ if( !pPager->dirtyCache || !pPager->journalOpen ){ rc = pager_unwritelock(pPager); - pPager->dbSize = -1; return rc; } @@ -3369,6 +3490,14 @@ int sqlite3pager_isreadonly(Pager *pPager){ return pPager->readOnly; } +/* +** Return the number of references to the pager. +*/ +int sqlite3pager_refcount(Pager *pPager){ + return pPager->nRef; +} + +#ifdef SQLITE_TEST /* ** This routine is used for testing and analysis only. */ @@ -3380,15 +3509,14 @@ int *sqlite3pager_stats(Pager *pPager){ a[3] = pPager->dbSize; a[4] = pPager->state; a[5] = pPager->errCode; -#ifdef SQLITE_TEST a[6] = pPager->nHit; a[7] = pPager->nMiss; a[8] = pPager->nOvfl; a[9] = pPager->nRead; a[10] = pPager->nWrite; -#endif return a; } +#endif /* ** Set the statement rollback point. @@ -3401,6 +3529,7 @@ int sqlite3pager_stmt_begin(Pager *pPager){ int rc; char zTemp[SQLITE_TEMPNAME_SIZE]; assert( !pPager->stmtInUse ); + assert( pPager->state>=PAGER_SHARED ); assert( pPager->dbSize>=0 ); TRACE2("STMT-BEGIN %d\n", PAGERID(pPager)); if( MEMDB ){ @@ -3716,7 +3845,7 @@ int sqlite3pager_movepage(Pager *pPager, void *pData, Pgno pgno){ if( pPgOld ){ assert( pPgOld->nRef==0 ); unlinkHashChain(pPager, pPgOld); - pPgOld->dirty = 0; + makeClean(pPgOld); if( pPgOld->needSync ){ assert( pPgOld->inJournal ); pPg->inJournal = 1; @@ -3726,8 +3855,9 @@ int sqlite3pager_movepage(Pager *pPager, void *pData, Pgno pgno){ } /* Change the page number for pPg and insert it into the new hash-chain. */ + assert( pgno!=0 ); pPg->pgno = pgno; - h = pager_hash(pgno); + h = pgno & (pPager->nHash-1); if( pPager->aHash[h] ){ assert( pPager->aHash[h]->pPrevHash==0 ); pPager->aHash[h]->pPrevHash = pPg; @@ -3736,7 +3866,7 @@ int sqlite3pager_movepage(Pager *pPager, void *pData, Pgno pgno){ pPager->aHash[h] = pPg; pPg->pPrevHash = 0; - pPg->dirty = 1; + makeDirty(pPg); pPager->dirtyCache = 1; if( needSyncPgno ){ @@ -3757,7 +3887,7 @@ int sqlite3pager_movepage(Pager *pPager, void *pData, Pgno pgno){ pPager->needSync = 1; DATA_TO_PGHDR(pNeedSync)->needSync = 1; DATA_TO_PGHDR(pNeedSync)->inJournal = 1; - DATA_TO_PGHDR(pNeedSync)->dirty = 1; + makeDirty(DATA_TO_PGHDR(pNeedSync)); sqlite3pager_unref(pNeedSync); } diff --git a/dlls/sqlite/sqlite-source/pager.h b/dlls/sqlite/sqlite-source/pager.h index b1775c6b..7626ff6b 100644 --- a/dlls/sqlite/sqlite-source/pager.h +++ b/dlls/sqlite/sqlite-source/pager.h @@ -75,7 +75,7 @@ void sqlite3pager_set_busyhandler(Pager*, BusyHandler *pBusyHandler); void sqlite3pager_set_destructor(Pager*, void(*)(void*,int)); void sqlite3pager_set_reiniter(Pager*, void(*)(void*,int)); int sqlite3pager_set_pagesize(Pager*, int); -void sqlite3pager_read_fileheader(Pager*, int, unsigned char*); +int sqlite3pager_read_fileheader(Pager*, int, unsigned char*); void sqlite3pager_set_cachesize(Pager*, int); int sqlite3pager_close(Pager *pPager); int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage); @@ -98,6 +98,7 @@ int sqlite3pager_stmt_commit(Pager*); int sqlite3pager_stmt_rollback(Pager*); void sqlite3pager_dont_rollback(void*); void sqlite3pager_dont_write(Pager*, Pgno); +int sqlite3pager_refcount(Pager*); int *sqlite3pager_stats(Pager*); void sqlite3pager_set_safety_level(Pager*,int,int); const char *sqlite3pager_filename(Pager*); diff --git a/dlls/sqlite/sqlite-source/parse.c b/dlls/sqlite/sqlite-source/parse.c index 9b07d8cd..52480394 100644 --- a/dlls/sqlite/sqlite-source/parse.c +++ b/dlls/sqlite/sqlite-source/parse.c @@ -4,7 +4,7 @@ /* First off, code is include which follows the "include" declaration ** in the input file. */ #include -#line 54 "parse.y" +#line 56 "parse.y" #include "sqliteInt.h" #include "parse.h" @@ -93,35 +93,36 @@ struct AttachKey { int type; Token key; }; ** defined, then do no error processing. */ #define YYCODETYPE unsigned char -#define YYNOCODE 240 +#define YYNOCODE 249 #define YYACTIONTYPE unsigned short int +#define YYWILDCARD 60 #define sqlite3ParserTOKENTYPE Token typedef union { sqlite3ParserTOKENTYPE yy0; - struct {int value; int mask;} yy13; - struct TrigEvent yy132; - IdList* yy160; - Expr* yy178; - int yy230; - Select* yy239; - TriggerStep* yy247; - struct LimitVal yy270; - SrcList* yy285; - Expr * yy292; - Token yy384; - struct LikeOp yy440; - ExprList* yy462; - int yy479; + Select* yy43; + TriggerStep* yy75; + struct LimitVal yy84; + struct LikeOp yy86; + Expr * yy158; + Token yy178; + struct {int value; int mask;} yy207; + ExprList* yy242; + int yy316; + IdList* yy352; + struct TrigEvent yy354; + SrcList* yy419; + Expr* yy450; + int yy497; } YYMINORTYPE; #define YYSTACKDEPTH 100 #define sqlite3ParserARG_SDECL Parse *pParse; #define sqlite3ParserARG_PDECL ,Parse *pParse #define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse #define sqlite3ParserARG_STORE yypParser->pParse = pParse -#define YYNSTATE 559 -#define YYNRULE 295 -#define YYERRORSYMBOL 137 -#define YYERRSYMDT yy479 +#define YYNSTATE 587 +#define YYNRULE 312 +#define YYERRORSYMBOL 139 +#define YYERRSYMDT yy497 #define YYFALLBACK 1 #define YY_NO_ACTION (YYNSTATE+YYNRULE+2) #define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) @@ -175,397 +176,417 @@ typedef union { ** yy_default[] Default action for each state. */ static const YYACTIONTYPE yy_action[] = { - /* 0 */ 279, 67, 283, 69, 147, 165, 545, 418, 61, 61, - /* 10 */ 61, 61, 201, 63, 63, 63, 63, 64, 64, 65, - /* 20 */ 65, 65, 66, 66, 547, 548, 431, 68, 63, 63, - /* 30 */ 63, 63, 64, 64, 65, 65, 65, 66, 67, 453, - /* 40 */ 69, 147, 498, 60, 58, 287, 439, 440, 436, 436, - /* 50 */ 62, 62, 61, 61, 61, 61, 500, 63, 63, 63, - /* 60 */ 63, 64, 64, 65, 65, 65, 66, 279, 370, 283, - /* 70 */ 418, 2, 376, 79, 157, 114, 219, 304, 224, 305, - /* 80 */ 169, 244, 855, 118, 558, 503, 203, 2, 245, 388, - /* 90 */ 495, 218, 21, 431, 513, 20, 418, 57, 492, 511, - /* 100 */ 63, 63, 63, 63, 64, 64, 65, 65, 65, 66, - /* 110 */ 60, 58, 287, 439, 440, 436, 436, 62, 62, 61, - /* 120 */ 61, 61, 61, 530, 63, 63, 63, 63, 64, 64, - /* 130 */ 65, 65, 65, 66, 279, 377, 378, 174, 371, 368, - /* 140 */ 330, 333, 334, 219, 304, 224, 305, 169, 244, 510, - /* 150 */ 479, 19, 335, 138, 376, 245, 509, 301, 372, 418, - /* 160 */ 431, 529, 91, 199, 65, 65, 65, 66, 504, 167, - /* 170 */ 191, 64, 64, 65, 65, 65, 66, 60, 58, 287, - /* 180 */ 439, 440, 436, 436, 62, 62, 61, 61, 61, 61, - /* 190 */ 254, 63, 63, 63, 63, 64, 64, 65, 65, 65, - /* 200 */ 66, 279, 250, 410, 410, 430, 109, 395, 426, 204, - /* 210 */ 357, 260, 259, 308, 145, 168, 153, 377, 378, 396, - /* 220 */ 327, 201, 67, 189, 69, 147, 225, 431, 546, 361, - /* 230 */ 465, 365, 397, 499, 318, 409, 40, 413, 428, 312, - /* 240 */ 161, 180, 550, 178, 60, 58, 287, 439, 440, 436, - /* 250 */ 436, 62, 62, 61, 61, 61, 61, 410, 63, 63, - /* 260 */ 63, 63, 64, 64, 65, 65, 65, 66, 279, 471, - /* 270 */ 415, 415, 415, 282, 308, 322, 235, 426, 204, 308, - /* 280 */ 174, 367, 308, 330, 333, 334, 67, 308, 69, 147, - /* 290 */ 148, 559, 371, 368, 431, 335, 409, 34, 165, 465, - /* 300 */ 418, 409, 34, 275, 409, 34, 428, 502, 161, 409, - /* 310 */ 35, 60, 58, 287, 439, 440, 436, 436, 62, 62, - /* 320 */ 61, 61, 61, 61, 410, 63, 63, 63, 63, 64, - /* 330 */ 64, 65, 65, 65, 66, 308, 503, 395, 237, 290, - /* 340 */ 279, 391, 392, 146, 324, 387, 20, 288, 347, 396, - /* 350 */ 174, 450, 350, 330, 333, 334, 450, 409, 27, 450, - /* 360 */ 474, 231, 397, 418, 393, 335, 431, 501, 354, 144, - /* 370 */ 512, 503, 524, 232, 394, 465, 496, 410, 527, 392, - /* 380 */ 555, 20, 75, 60, 58, 287, 439, 440, 436, 436, - /* 390 */ 62, 62, 61, 61, 61, 61, 220, 63, 63, 63, - /* 400 */ 63, 64, 64, 65, 65, 65, 66, 308, 221, 185, - /* 410 */ 338, 254, 279, 308, 239, 443, 475, 308, 319, 308, - /* 420 */ 389, 444, 286, 421, 422, 379, 380, 381, 492, 409, - /* 430 */ 34, 311, 421, 422, 212, 409, 48, 170, 431, 409, - /* 440 */ 40, 409, 48, 410, 122, 314, 526, 442, 442, 1, - /* 450 */ 376, 469, 255, 376, 78, 60, 58, 287, 439, 440, - /* 460 */ 436, 436, 62, 62, 61, 61, 61, 61, 355, 63, - /* 470 */ 63, 63, 63, 64, 64, 65, 65, 65, 66, 279, - /* 480 */ 233, 152, 298, 478, 449, 203, 792, 192, 299, 351, - /* 490 */ 376, 281, 376, 9, 203, 376, 245, 376, 201, 432, - /* 500 */ 314, 376, 442, 442, 490, 431, 314, 325, 442, 442, - /* 510 */ 418, 356, 289, 377, 378, 354, 377, 378, 403, 434, - /* 520 */ 435, 410, 60, 58, 287, 439, 440, 436, 436, 62, - /* 530 */ 62, 61, 61, 61, 61, 263, 63, 63, 63, 63, - /* 540 */ 64, 64, 65, 65, 65, 66, 279, 433, 328, 236, - /* 550 */ 497, 473, 490, 377, 378, 377, 378, 484, 377, 378, - /* 560 */ 377, 378, 308, 522, 377, 378, 314, 521, 442, 442, - /* 570 */ 409, 3, 431, 418, 130, 254, 264, 485, 309, 346, - /* 580 */ 461, 213, 462, 242, 409, 28, 469, 292, 214, 60, - /* 590 */ 58, 287, 439, 440, 436, 436, 62, 62, 61, 61, - /* 600 */ 61, 61, 308, 63, 63, 63, 63, 64, 64, 65, - /* 610 */ 65, 65, 66, 279, 308, 458, 536, 248, 5, 308, - /* 620 */ 201, 308, 469, 308, 409, 23, 308, 202, 291, 308, - /* 630 */ 375, 243, 308, 362, 54, 115, 409, 32, 74, 431, - /* 640 */ 76, 409, 53, 409, 24, 409, 51, 345, 409, 96, - /* 650 */ 149, 409, 93, 265, 409, 98, 60, 58, 287, 439, - /* 660 */ 440, 436, 436, 62, 62, 61, 61, 61, 61, 308, - /* 670 */ 63, 63, 63, 63, 64, 64, 65, 65, 65, 66, - /* 680 */ 279, 308, 404, 297, 410, 90, 308, 176, 308, 405, - /* 690 */ 308, 409, 99, 308, 419, 308, 22, 308, 520, 344, - /* 700 */ 520, 164, 153, 409, 110, 141, 431, 313, 409, 111, - /* 710 */ 409, 16, 409, 97, 254, 409, 33, 409, 94, 409, - /* 720 */ 52, 410, 187, 60, 58, 287, 439, 440, 436, 436, - /* 730 */ 62, 62, 61, 61, 61, 61, 308, 63, 63, 63, - /* 740 */ 63, 64, 64, 65, 65, 65, 66, 279, 308, 490, - /* 750 */ 490, 414, 308, 320, 308, 538, 308, 460, 409, 112, - /* 760 */ 308, 171, 172, 173, 308, 408, 308, 424, 424, 407, - /* 770 */ 409, 113, 427, 431, 409, 25, 409, 36, 409, 37, - /* 780 */ 170, 437, 409, 26, 211, 293, 409, 38, 409, 39, - /* 790 */ 60, 58, 287, 439, 440, 436, 436, 62, 62, 61, - /* 800 */ 61, 61, 61, 308, 63, 63, 63, 63, 64, 64, - /* 810 */ 65, 65, 65, 66, 279, 308, 490, 490, 451, 308, - /* 820 */ 81, 308, 151, 308, 459, 409, 41, 308, 243, 243, - /* 830 */ 400, 401, 308, 448, 281, 12, 464, 409, 42, 468, - /* 840 */ 431, 409, 43, 409, 29, 409, 30, 241, 460, 409, - /* 850 */ 44, 294, 296, 480, 409, 45, 329, 60, 70, 287, - /* 860 */ 439, 440, 436, 436, 62, 62, 61, 61, 61, 61, - /* 870 */ 308, 63, 63, 63, 63, 64, 64, 65, 65, 65, - /* 880 */ 66, 279, 308, 408, 483, 482, 308, 407, 308, 467, - /* 890 */ 308, 166, 409, 46, 308, 243, 243, 476, 488, 12, - /* 900 */ 122, 518, 519, 179, 409, 47, 481, 431, 409, 31, - /* 910 */ 409, 10, 409, 49, 505, 486, 409, 50, 254, 249, - /* 920 */ 254, 254, 254, 158, 279, 58, 287, 439, 440, 436, - /* 930 */ 436, 62, 62, 61, 61, 61, 61, 410, 63, 63, - /* 940 */ 63, 63, 64, 64, 65, 65, 65, 66, 487, 247, - /* 950 */ 431, 122, 254, 337, 525, 122, 122, 251, 533, 539, - /* 960 */ 166, 540, 266, 360, 534, 543, 88, 88, 252, 287, - /* 970 */ 439, 440, 436, 436, 62, 62, 61, 61, 61, 61, - /* 980 */ 195, 63, 63, 63, 63, 64, 64, 65, 65, 65, - /* 990 */ 66, 71, 315, 268, 4, 253, 182, 258, 285, 349, - /* 1000 */ 342, 352, 353, 261, 262, 544, 310, 71, 315, 269, - /* 1010 */ 4, 222, 363, 272, 285, 593, 273, 554, 140, 226, - /* 1020 */ 385, 423, 310, 317, 425, 316, 532, 542, 18, 156, - /* 1030 */ 479, 454, 457, 430, 332, 489, 374, 382, 383, 317, - /* 1040 */ 384, 8, 302, 303, 491, 390, 398, 284, 403, 430, - /* 1050 */ 223, 406, 73, 72, 402, 81, 411, 399, 323, 56, - /* 1060 */ 71, 306, 307, 205, 321, 413, 80, 227, 73, 72, - /* 1070 */ 472, 77, 452, 163, 234, 455, 71, 306, 307, 71, - /* 1080 */ 315, 413, 4, 229, 201, 456, 285, 412, 228, 82, - /* 1090 */ 119, 326, 230, 206, 310, 207, 101, 276, 415, 415, - /* 1100 */ 415, 416, 417, 11, 238, 494, 466, 470, 240, 209, - /* 1110 */ 210, 317, 493, 506, 415, 415, 415, 416, 417, 11, - /* 1120 */ 507, 430, 155, 339, 508, 514, 177, 215, 216, 217, - /* 1130 */ 105, 277, 341, 181, 516, 83, 343, 85, 256, 455, - /* 1140 */ 73, 72, 517, 197, 183, 270, 348, 117, 71, 306, - /* 1150 */ 307, 528, 271, 413, 186, 126, 535, 358, 127, 128, - /* 1160 */ 541, 135, 300, 132, 194, 136, 529, 551, 552, 553, - /* 1170 */ 129, 193, 89, 196, 430, 556, 208, 100, 95, 373, - /* 1180 */ 386, 116, 200, 55, 17, 594, 415, 415, 415, 416, - /* 1190 */ 417, 11, 92, 142, 143, 595, 159, 108, 160, 59, - /* 1200 */ 438, 420, 499, 429, 137, 441, 413, 445, 150, 162, - /* 1210 */ 446, 447, 6, 7, 13, 359, 267, 259, 463, 12, - /* 1220 */ 120, 280, 121, 154, 477, 102, 201, 246, 331, 103, - /* 1230 */ 84, 104, 336, 175, 221, 340, 139, 515, 123, 415, - /* 1240 */ 415, 415, 184, 124, 295, 166, 257, 106, 523, 278, - /* 1250 */ 364, 531, 125, 86, 188, 14, 190, 537, 131, 133, - /* 1260 */ 87, 134, 15, 107, 198, 549, 366, 369, 536, 557, - /* 1270 */ 274, + /* 0 */ 289, 900, 121, 586, 205, 169, 2, 435, 61, 61, + /* 10 */ 61, 61, 435, 63, 63, 63, 63, 64, 64, 65, + /* 20 */ 65, 65, 66, 230, 198, 299, 420, 426, 68, 63, + /* 30 */ 63, 63, 63, 64, 64, 65, 65, 65, 66, 230, + /* 40 */ 67, 447, 69, 151, 230, 60, 59, 294, 430, 431, + /* 50 */ 427, 427, 62, 62, 61, 61, 61, 61, 411, 63, + /* 60 */ 63, 63, 63, 64, 64, 65, 65, 65, 66, 230, + /* 70 */ 289, 487, 515, 435, 570, 415, 80, 67, 435, 69, + /* 80 */ 151, 63, 63, 63, 63, 64, 64, 65, 65, 65, + /* 90 */ 66, 230, 569, 568, 248, 386, 420, 426, 2, 572, + /* 100 */ 58, 115, 238, 340, 243, 341, 173, 417, 417, 417, + /* 110 */ 570, 387, 384, 249, 289, 60, 59, 294, 430, 431, + /* 120 */ 427, 427, 62, 62, 61, 61, 61, 61, 569, 63, + /* 130 */ 63, 63, 63, 64, 64, 65, 65, 65, 66, 230, + /* 140 */ 420, 426, 92, 64, 64, 65, 65, 65, 66, 230, + /* 150 */ 245, 392, 56, 171, 566, 207, 406, 443, 208, 60, + /* 160 */ 59, 294, 430, 431, 427, 427, 62, 62, 61, 61, + /* 170 */ 61, 61, 205, 63, 63, 63, 63, 64, 64, 65, + /* 180 */ 65, 65, 66, 230, 289, 368, 522, 411, 522, 111, + /* 190 */ 378, 207, 447, 467, 223, 403, 21, 532, 21, 172, + /* 200 */ 157, 317, 66, 230, 336, 404, 520, 443, 208, 486, + /* 210 */ 420, 426, 146, 147, 517, 488, 489, 393, 394, 148, + /* 220 */ 531, 224, 487, 410, 41, 407, 415, 567, 289, 60, + /* 230 */ 59, 294, 430, 431, 427, 427, 62, 62, 61, 61, + /* 240 */ 61, 61, 476, 63, 63, 63, 63, 64, 64, 65, + /* 250 */ 65, 65, 66, 230, 420, 426, 491, 492, 417, 417, + /* 260 */ 417, 155, 549, 331, 211, 65, 65, 65, 66, 230, + /* 270 */ 546, 492, 289, 60, 59, 294, 430, 431, 427, 427, + /* 280 */ 62, 62, 61, 61, 61, 61, 467, 63, 63, 63, + /* 290 */ 63, 64, 64, 65, 65, 65, 66, 230, 420, 426, + /* 300 */ 548, 299, 178, 297, 522, 342, 345, 346, 472, 67, + /* 310 */ 460, 69, 151, 577, 21, 338, 347, 60, 59, 294, + /* 320 */ 430, 431, 427, 427, 62, 62, 61, 61, 61, 61, + /* 330 */ 530, 63, 63, 63, 63, 64, 64, 65, 65, 65, + /* 340 */ 66, 230, 409, 523, 76, 289, 408, 478, 452, 482, + /* 350 */ 392, 369, 266, 265, 283, 149, 405, 445, 521, 165, + /* 360 */ 453, 317, 205, 67, 517, 69, 151, 529, 503, 152, + /* 370 */ 248, 420, 426, 454, 528, 493, 161, 115, 238, 340, + /* 380 */ 243, 341, 173, 410, 35, 494, 580, 288, 79, 249, + /* 390 */ 60, 59, 294, 430, 431, 427, 427, 62, 62, 61, + /* 400 */ 61, 61, 61, 411, 63, 63, 63, 63, 64, 64, + /* 410 */ 65, 65, 65, 66, 230, 289, 393, 394, 178, 485, + /* 420 */ 508, 342, 345, 346, 178, 296, 317, 342, 345, 346, + /* 430 */ 366, 317, 347, 20, 317, 141, 317, 457, 347, 150, + /* 440 */ 509, 420, 426, 22, 295, 438, 439, 435, 410, 35, + /* 450 */ 328, 260, 472, 410, 28, 232, 410, 35, 410, 36, + /* 460 */ 60, 59, 294, 430, 431, 427, 427, 62, 62, 61, + /* 470 */ 61, 61, 61, 411, 63, 63, 63, 63, 64, 64, + /* 480 */ 65, 65, 65, 66, 230, 289, 436, 481, 23, 502, + /* 490 */ 298, 234, 380, 301, 317, 217, 317, 476, 333, 317, + /* 500 */ 392, 317, 457, 337, 168, 157, 421, 422, 207, 231, + /* 510 */ 457, 420, 426, 435, 313, 388, 410, 35, 410, 49, + /* 520 */ 204, 410, 41, 410, 49, 410, 3, 197, 424, 425, + /* 530 */ 60, 59, 294, 430, 431, 427, 427, 62, 62, 61, + /* 540 */ 61, 61, 61, 382, 63, 63, 63, 63, 64, 64, + /* 550 */ 65, 65, 65, 66, 230, 289, 443, 423, 357, 252, + /* 560 */ 434, 411, 210, 292, 308, 350, 393, 394, 448, 309, + /* 570 */ 456, 322, 438, 439, 320, 1, 433, 433, 19, 392, + /* 580 */ 541, 420, 426, 191, 540, 375, 584, 891, 543, 891, + /* 590 */ 584, 890, 174, 890, 472, 392, 358, 445, 323, 165, + /* 600 */ 60, 59, 294, 430, 431, 427, 427, 62, 62, 61, + /* 610 */ 61, 61, 61, 383, 63, 63, 63, 63, 64, 64, + /* 620 */ 65, 65, 65, 66, 230, 289, 370, 581, 9, 452, + /* 630 */ 91, 581, 10, 236, 409, 207, 392, 359, 408, 392, + /* 640 */ 156, 453, 169, 362, 435, 393, 394, 320, 291, 433, + /* 650 */ 433, 420, 426, 249, 454, 320, 327, 433, 433, 260, + /* 660 */ 462, 393, 394, 515, 515, 545, 515, 463, 270, 289, + /* 670 */ 60, 59, 294, 430, 431, 427, 427, 62, 62, 61, + /* 680 */ 61, 61, 61, 82, 63, 63, 63, 63, 64, 64, + /* 690 */ 65, 65, 65, 66, 230, 420, 426, 480, 302, 216, + /* 700 */ 261, 303, 393, 394, 822, 393, 394, 273, 515, 271, + /* 710 */ 435, 515, 334, 289, 60, 59, 294, 430, 431, 427, + /* 720 */ 427, 62, 62, 61, 61, 61, 61, 233, 63, 63, + /* 730 */ 63, 63, 64, 64, 65, 65, 65, 66, 230, 420, + /* 740 */ 426, 247, 247, 304, 247, 318, 306, 587, 387, 384, + /* 750 */ 395, 396, 397, 320, 219, 433, 433, 289, 60, 70, + /* 760 */ 294, 430, 431, 427, 427, 62, 62, 61, 61, 61, + /* 770 */ 61, 317, 63, 63, 63, 63, 64, 64, 65, 65, + /* 780 */ 65, 66, 230, 420, 426, 476, 247, 391, 272, 247, + /* 790 */ 539, 356, 539, 410, 29, 175, 176, 177, 162, 260, + /* 800 */ 260, 289, 5, 59, 294, 430, 431, 427, 427, 62, + /* 810 */ 62, 61, 61, 61, 61, 377, 63, 63, 63, 63, + /* 820 */ 64, 64, 65, 65, 65, 66, 230, 420, 426, 392, + /* 830 */ 311, 120, 392, 319, 205, 260, 366, 465, 254, 189, + /* 840 */ 556, 558, 260, 75, 260, 77, 307, 376, 294, 430, + /* 850 */ 431, 427, 427, 62, 62, 61, 61, 61, 61, 260, + /* 860 */ 63, 63, 63, 63, 64, 64, 65, 65, 65, 66, + /* 870 */ 230, 72, 324, 411, 4, 260, 559, 258, 293, 256, + /* 880 */ 174, 125, 317, 560, 317, 274, 321, 72, 324, 193, + /* 890 */ 4, 153, 621, 180, 293, 393, 394, 367, 393, 394, + /* 900 */ 374, 218, 321, 326, 410, 24, 410, 33, 183, 317, + /* 910 */ 428, 206, 441, 441, 447, 317, 276, 317, 55, 326, + /* 920 */ 363, 468, 239, 411, 469, 411, 455, 411, 13, 144, + /* 930 */ 447, 410, 53, 240, 74, 73, 291, 410, 52, 410, + /* 940 */ 96, 116, 411, 72, 315, 316, 582, 474, 415, 170, + /* 950 */ 74, 73, 479, 317, 507, 506, 317, 500, 416, 72, + /* 960 */ 315, 316, 72, 324, 415, 4, 205, 317, 329, 293, + /* 970 */ 317, 458, 483, 444, 13, 410, 94, 321, 410, 99, + /* 980 */ 417, 417, 417, 418, 419, 12, 583, 466, 317, 410, + /* 990 */ 100, 471, 410, 110, 326, 475, 417, 417, 417, 418, + /* 1000 */ 419, 12, 497, 498, 512, 447, 125, 159, 244, 317, + /* 1010 */ 410, 112, 220, 221, 222, 102, 537, 538, 317, 251, + /* 1020 */ 317, 125, 317, 504, 505, 74, 73, 349, 202, 125, + /* 1030 */ 278, 410, 17, 510, 72, 315, 316, 279, 524, 415, + /* 1040 */ 410, 97, 410, 34, 410, 95, 317, 511, 544, 200, + /* 1050 */ 125, 548, 552, 253, 170, 317, 199, 255, 317, 201, + /* 1060 */ 553, 257, 89, 317, 259, 563, 317, 89, 410, 25, + /* 1070 */ 317, 417, 417, 417, 418, 419, 12, 410, 54, 186, + /* 1080 */ 410, 113, 354, 317, 264, 410, 114, 317, 410, 26, + /* 1090 */ 361, 364, 410, 37, 579, 365, 287, 317, 267, 317, + /* 1100 */ 143, 317, 373, 275, 265, 410, 38, 268, 290, 410, + /* 1110 */ 27, 317, 269, 205, 555, 565, 317, 277, 317, 410, + /* 1120 */ 39, 410, 40, 410, 42, 317, 280, 317, 281, 317, + /* 1130 */ 576, 317, 225, 410, 43, 401, 503, 379, 410, 44, + /* 1140 */ 410, 30, 317, 325, 440, 317, 461, 410, 31, 410, + /* 1150 */ 45, 410, 46, 410, 47, 442, 317, 551, 317, 464, + /* 1160 */ 317, 241, 513, 516, 410, 48, 344, 410, 32, 562, + /* 1170 */ 160, 390, 398, 399, 400, 8, 314, 412, 410, 11, + /* 1180 */ 410, 50, 410, 51, 82, 332, 226, 81, 330, 227, + /* 1190 */ 57, 406, 414, 228, 78, 167, 229, 209, 83, 413, + /* 1200 */ 459, 122, 335, 339, 500, 490, 235, 495, 242, 473, + /* 1210 */ 237, 300, 477, 499, 496, 501, 103, 284, 246, 514, + /* 1220 */ 518, 519, 525, 526, 527, 351, 533, 181, 285, 182, + /* 1230 */ 184, 214, 353, 185, 535, 187, 215, 355, 86, 118, + /* 1240 */ 360, 547, 190, 129, 139, 371, 262, 372, 130, 536, + /* 1250 */ 554, 310, 131, 132, 573, 90, 133, 135, 93, 138, + /* 1260 */ 578, 574, 575, 109, 213, 561, 101, 119, 389, 18, + /* 1270 */ 98, 402, 622, 623, 163, 164, 429, 312, 432, 71, + /* 1280 */ 449, 437, 446, 140, 154, 166, 450, 6, 451, 470, + /* 1290 */ 7, 123, 14, 13, 124, 158, 484, 212, 84, 343, + /* 1300 */ 104, 348, 250, 105, 85, 117, 106, 240, 179, 352, + /* 1310 */ 142, 534, 126, 305, 170, 263, 188, 107, 286, 550, + /* 1320 */ 127, 128, 15, 542, 192, 87, 194, 88, 195, 557, + /* 1330 */ 196, 136, 137, 134, 16, 108, 571, 282, 381, 564, + /* 1340 */ 203, 145, 385, 901, 585, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 16, 216, 16, 218, 219, 21, 146, 23, 68, 69, - /* 10 */ 70, 71, 109, 73, 74, 75, 76, 77, 78, 79, - /* 20 */ 80, 81, 82, 82, 164, 165, 42, 72, 73, 74, - /* 30 */ 75, 76, 77, 78, 79, 80, 81, 82, 216, 217, - /* 40 */ 218, 219, 168, 59, 60, 61, 62, 63, 64, 65, - /* 50 */ 66, 67, 68, 69, 70, 71, 168, 73, 74, 75, - /* 60 */ 76, 77, 78, 79, 80, 81, 82, 16, 140, 16, - /* 70 */ 86, 143, 23, 22, 88, 89, 90, 91, 92, 93, - /* 80 */ 94, 95, 138, 139, 140, 146, 226, 143, 102, 166, - /* 90 */ 167, 152, 19, 42, 155, 156, 23, 46, 175, 180, - /* 100 */ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, - /* 110 */ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - /* 120 */ 69, 70, 71, 11, 73, 74, 75, 76, 77, 78, - /* 130 */ 79, 80, 81, 82, 16, 86, 87, 88, 1, 2, - /* 140 */ 91, 92, 93, 90, 91, 92, 93, 94, 95, 175, - /* 150 */ 176, 19, 103, 21, 23, 102, 182, 141, 142, 86, - /* 160 */ 42, 49, 44, 147, 79, 80, 81, 82, 180, 154, - /* 170 */ 154, 77, 78, 79, 80, 81, 82, 59, 60, 61, - /* 180 */ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - /* 190 */ 146, 73, 74, 75, 76, 77, 78, 79, 80, 81, - /* 200 */ 82, 16, 14, 188, 188, 58, 21, 12, 77, 78, - /* 210 */ 98, 99, 100, 146, 22, 200, 201, 86, 87, 24, - /* 220 */ 205, 109, 216, 154, 218, 219, 189, 42, 97, 213, - /* 230 */ 160, 187, 37, 86, 39, 168, 169, 90, 160, 161, - /* 240 */ 162, 53, 236, 55, 59, 60, 61, 62, 63, 64, - /* 250 */ 65, 66, 67, 68, 69, 70, 71, 188, 73, 74, - /* 260 */ 75, 76, 77, 78, 79, 80, 81, 82, 16, 199, - /* 270 */ 123, 124, 125, 149, 146, 208, 209, 77, 78, 146, - /* 280 */ 88, 237, 146, 91, 92, 93, 216, 146, 218, 219, - /* 290 */ 154, 0, 1, 2, 42, 103, 168, 169, 21, 160, - /* 300 */ 23, 168, 169, 157, 168, 169, 160, 161, 162, 168, - /* 310 */ 169, 59, 60, 61, 62, 63, 64, 65, 66, 67, - /* 320 */ 68, 69, 70, 71, 188, 73, 74, 75, 76, 77, - /* 330 */ 78, 79, 80, 81, 82, 146, 146, 12, 199, 211, - /* 340 */ 16, 184, 185, 154, 211, 155, 156, 211, 224, 24, - /* 350 */ 88, 223, 228, 91, 92, 93, 223, 168, 169, 223, - /* 360 */ 20, 220, 37, 86, 39, 103, 42, 159, 146, 179, - /* 370 */ 180, 146, 18, 146, 49, 160, 168, 188, 184, 185, - /* 380 */ 155, 156, 130, 59, 60, 61, 62, 63, 64, 65, - /* 390 */ 66, 67, 68, 69, 70, 71, 90, 73, 74, 75, - /* 400 */ 76, 77, 78, 79, 80, 81, 82, 146, 102, 154, - /* 410 */ 16, 146, 16, 146, 199, 20, 20, 146, 185, 146, - /* 420 */ 167, 20, 163, 164, 165, 7, 8, 9, 175, 168, - /* 430 */ 169, 163, 164, 165, 212, 168, 169, 43, 42, 168, - /* 440 */ 169, 168, 169, 188, 22, 105, 92, 107, 108, 19, - /* 450 */ 23, 146, 187, 23, 130, 59, 60, 61, 62, 63, - /* 460 */ 64, 65, 66, 67, 68, 69, 70, 71, 213, 73, - /* 470 */ 74, 75, 76, 77, 78, 79, 80, 81, 82, 16, - /* 480 */ 209, 146, 215, 20, 223, 226, 132, 154, 215, 234, - /* 490 */ 23, 97, 23, 19, 226, 23, 102, 23, 109, 42, - /* 500 */ 105, 23, 107, 108, 146, 42, 105, 146, 107, 108, - /* 510 */ 23, 122, 207, 86, 87, 146, 86, 87, 96, 62, - /* 520 */ 63, 188, 59, 60, 61, 62, 63, 64, 65, 66, - /* 530 */ 67, 68, 69, 70, 71, 14, 73, 74, 75, 76, - /* 540 */ 77, 78, 79, 80, 81, 82, 16, 90, 146, 146, - /* 550 */ 20, 79, 146, 86, 87, 86, 87, 30, 86, 87, - /* 560 */ 86, 87, 146, 25, 86, 87, 105, 29, 107, 108, - /* 570 */ 168, 169, 42, 86, 53, 146, 55, 50, 146, 41, - /* 580 */ 113, 212, 113, 225, 168, 169, 146, 181, 144, 59, - /* 590 */ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - /* 600 */ 70, 71, 146, 73, 74, 75, 76, 77, 78, 79, - /* 610 */ 80, 81, 82, 16, 146, 22, 187, 20, 190, 146, - /* 620 */ 109, 146, 146, 146, 168, 169, 146, 191, 101, 146, - /* 630 */ 146, 225, 146, 122, 198, 146, 168, 169, 129, 42, - /* 640 */ 131, 168, 169, 168, 169, 168, 169, 207, 168, 169, - /* 650 */ 154, 168, 169, 132, 168, 169, 59, 60, 61, 62, - /* 660 */ 63, 64, 65, 66, 67, 68, 69, 70, 71, 146, - /* 670 */ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, - /* 680 */ 16, 146, 27, 207, 188, 21, 146, 154, 146, 34, - /* 690 */ 146, 168, 169, 146, 20, 146, 22, 146, 98, 99, - /* 700 */ 100, 200, 201, 168, 169, 112, 42, 16, 168, 169, - /* 710 */ 168, 169, 168, 169, 146, 168, 169, 168, 169, 168, - /* 720 */ 169, 188, 22, 59, 60, 61, 62, 63, 64, 65, - /* 730 */ 66, 67, 68, 69, 70, 71, 146, 73, 74, 75, - /* 740 */ 76, 77, 78, 79, 80, 81, 82, 16, 146, 146, - /* 750 */ 146, 146, 146, 146, 146, 187, 146, 22, 168, 169, - /* 760 */ 146, 98, 99, 100, 146, 106, 146, 123, 124, 110, - /* 770 */ 168, 169, 160, 42, 168, 169, 168, 169, 168, 169, - /* 780 */ 43, 90, 168, 169, 181, 181, 168, 169, 168, 169, - /* 790 */ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - /* 800 */ 69, 70, 71, 146, 73, 74, 75, 76, 77, 78, - /* 810 */ 79, 80, 81, 82, 16, 146, 146, 146, 146, 146, - /* 820 */ 120, 146, 87, 146, 202, 168, 169, 146, 225, 225, - /* 830 */ 7, 8, 146, 20, 97, 22, 146, 168, 169, 146, - /* 840 */ 42, 168, 169, 168, 169, 168, 169, 146, 113, 168, - /* 850 */ 169, 181, 181, 146, 168, 169, 79, 59, 60, 61, - /* 860 */ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - /* 870 */ 146, 73, 74, 75, 76, 77, 78, 79, 80, 81, - /* 880 */ 82, 16, 146, 106, 89, 90, 146, 110, 146, 20, - /* 890 */ 146, 22, 168, 169, 146, 225, 225, 20, 20, 22, - /* 900 */ 22, 51, 52, 154, 168, 169, 177, 42, 168, 169, - /* 910 */ 168, 169, 168, 169, 146, 177, 168, 169, 146, 146, - /* 920 */ 146, 146, 146, 19, 16, 60, 61, 62, 63, 64, - /* 930 */ 65, 66, 67, 68, 69, 70, 71, 188, 73, 74, - /* 940 */ 75, 76, 77, 78, 79, 80, 81, 82, 177, 20, - /* 950 */ 42, 22, 146, 20, 20, 22, 22, 146, 20, 187, - /* 960 */ 22, 187, 187, 187, 20, 20, 22, 22, 146, 61, - /* 970 */ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - /* 980 */ 19, 73, 74, 75, 76, 77, 78, 79, 80, 81, - /* 990 */ 82, 16, 17, 187, 19, 146, 230, 146, 23, 146, - /* 1000 */ 231, 146, 146, 146, 146, 146, 31, 16, 17, 146, - /* 1010 */ 19, 171, 146, 146, 23, 111, 146, 146, 190, 192, - /* 1020 */ 148, 227, 31, 48, 227, 222, 193, 193, 67, 6, - /* 1030 */ 176, 171, 171, 58, 172, 171, 145, 145, 145, 48, - /* 1040 */ 145, 22, 153, 97, 171, 170, 170, 40, 96, 58, - /* 1050 */ 170, 170, 77, 78, 172, 120, 188, 178, 117, 119, - /* 1060 */ 85, 86, 87, 221, 115, 90, 118, 193, 77, 78, - /* 1070 */ 79, 129, 151, 111, 95, 23, 85, 86, 87, 16, - /* 1080 */ 17, 90, 19, 195, 109, 159, 23, 197, 194, 97, - /* 1090 */ 151, 114, 196, 210, 31, 210, 19, 173, 123, 124, - /* 1100 */ 125, 126, 127, 128, 203, 178, 204, 204, 203, 210, - /* 1110 */ 210, 48, 159, 170, 123, 124, 125, 126, 127, 128, - /* 1120 */ 170, 58, 5, 15, 170, 151, 150, 10, 11, 12, - /* 1130 */ 13, 173, 151, 151, 151, 19, 38, 129, 232, 23, - /* 1140 */ 77, 78, 233, 26, 150, 28, 151, 59, 85, 86, - /* 1150 */ 87, 183, 35, 90, 183, 19, 193, 15, 186, 186, - /* 1160 */ 193, 214, 151, 183, 47, 214, 49, 33, 151, 151, - /* 1170 */ 186, 54, 235, 56, 58, 136, 174, 174, 158, 1, - /* 1180 */ 20, 32, 44, 19, 229, 111, 123, 124, 125, 126, - /* 1190 */ 127, 128, 235, 77, 78, 111, 111, 238, 111, 19, - /* 1200 */ 90, 20, 86, 20, 19, 106, 90, 11, 19, 22, - /* 1210 */ 20, 20, 116, 116, 22, 98, 99, 100, 113, 22, - /* 1220 */ 19, 104, 20, 111, 20, 19, 109, 20, 44, 19, - /* 1230 */ 19, 19, 44, 94, 102, 16, 21, 17, 97, 123, - /* 1240 */ 124, 125, 97, 45, 36, 22, 132, 19, 45, 5, - /* 1250 */ 133, 1, 101, 67, 121, 19, 112, 17, 112, 101, - /* 1260 */ 67, 121, 19, 14, 134, 20, 57, 3, 239, 4, - /* 1270 */ 135, + /* 0 */ 16, 140, 141, 142, 111, 21, 145, 23, 70, 71, + /* 10 */ 72, 73, 23, 75, 76, 77, 78, 79, 80, 81, + /* 20 */ 82, 83, 84, 85, 156, 16, 42, 43, 74, 75, + /* 30 */ 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + /* 40 */ 217, 59, 219, 220, 85, 61, 62, 63, 64, 65, + /* 50 */ 66, 67, 68, 69, 70, 71, 72, 73, 190, 75, + /* 60 */ 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + /* 70 */ 16, 89, 148, 89, 148, 93, 22, 217, 89, 219, + /* 80 */ 220, 75, 76, 77, 78, 79, 80, 81, 82, 83, + /* 90 */ 84, 85, 166, 167, 85, 142, 42, 43, 145, 239, + /* 100 */ 46, 92, 93, 94, 95, 96, 97, 125, 126, 127, + /* 110 */ 148, 1, 2, 104, 16, 61, 62, 63, 64, 65, + /* 120 */ 66, 67, 68, 69, 70, 71, 72, 73, 166, 75, + /* 130 */ 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + /* 140 */ 42, 43, 44, 79, 80, 81, 82, 83, 84, 85, + /* 150 */ 226, 23, 19, 156, 228, 229, 23, 79, 80, 61, + /* 160 */ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + /* 170 */ 72, 73, 111, 75, 76, 77, 78, 79, 80, 81, + /* 180 */ 82, 83, 84, 85, 16, 124, 148, 190, 148, 21, + /* 190 */ 228, 229, 59, 22, 154, 157, 158, 157, 158, 202, + /* 200 */ 203, 148, 84, 85, 207, 168, 169, 79, 80, 170, + /* 210 */ 42, 43, 79, 80, 177, 170, 161, 89, 90, 181, + /* 220 */ 182, 191, 89, 170, 171, 170, 93, 99, 16, 61, + /* 230 */ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + /* 240 */ 72, 73, 148, 75, 76, 77, 78, 79, 80, 81, + /* 250 */ 82, 83, 84, 85, 42, 43, 186, 187, 125, 126, + /* 260 */ 127, 90, 11, 210, 211, 81, 82, 83, 84, 85, + /* 270 */ 186, 187, 16, 61, 62, 63, 64, 65, 66, 67, + /* 280 */ 68, 69, 70, 71, 72, 73, 115, 75, 76, 77, + /* 290 */ 78, 79, 80, 81, 82, 83, 84, 85, 42, 43, + /* 300 */ 49, 16, 91, 209, 148, 94, 95, 96, 162, 217, + /* 310 */ 218, 219, 220, 157, 158, 81, 105, 61, 62, 63, + /* 320 */ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + /* 330 */ 182, 75, 76, 77, 78, 79, 80, 81, 82, 83, + /* 340 */ 84, 85, 108, 182, 132, 16, 112, 201, 12, 20, + /* 350 */ 23, 100, 101, 102, 159, 22, 169, 162, 163, 164, + /* 360 */ 24, 148, 111, 217, 177, 219, 220, 177, 178, 156, + /* 370 */ 85, 42, 43, 37, 184, 39, 91, 92, 93, 94, + /* 380 */ 95, 96, 97, 170, 171, 49, 245, 246, 132, 104, + /* 390 */ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + /* 400 */ 71, 72, 73, 190, 75, 76, 77, 78, 79, 80, + /* 410 */ 81, 82, 83, 84, 85, 16, 89, 90, 91, 20, + /* 420 */ 30, 94, 95, 96, 91, 212, 148, 94, 95, 96, + /* 430 */ 148, 148, 105, 19, 148, 21, 148, 224, 105, 156, + /* 440 */ 50, 42, 43, 19, 165, 166, 167, 23, 170, 171, + /* 450 */ 187, 148, 162, 170, 171, 148, 170, 171, 170, 171, + /* 460 */ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + /* 470 */ 71, 72, 73, 190, 75, 76, 77, 78, 79, 80, + /* 480 */ 81, 82, 83, 84, 85, 16, 20, 20, 22, 20, + /* 490 */ 212, 201, 189, 103, 148, 213, 148, 148, 212, 148, + /* 500 */ 23, 148, 224, 148, 202, 203, 42, 43, 229, 221, + /* 510 */ 224, 42, 43, 89, 143, 144, 170, 171, 170, 171, + /* 520 */ 149, 170, 171, 170, 171, 170, 171, 156, 64, 65, + /* 530 */ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + /* 540 */ 71, 72, 73, 240, 75, 76, 77, 78, 79, 80, + /* 550 */ 81, 82, 83, 84, 85, 16, 79, 93, 209, 20, + /* 560 */ 20, 190, 211, 151, 216, 16, 89, 90, 20, 216, + /* 570 */ 224, 165, 166, 167, 107, 19, 109, 110, 19, 23, + /* 580 */ 25, 42, 43, 22, 29, 214, 19, 20, 18, 22, + /* 590 */ 19, 20, 43, 22, 162, 23, 41, 162, 163, 164, + /* 600 */ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + /* 610 */ 71, 72, 73, 242, 75, 76, 77, 78, 79, 80, + /* 620 */ 81, 82, 83, 84, 85, 16, 56, 60, 69, 12, + /* 630 */ 21, 60, 19, 201, 108, 229, 23, 225, 112, 23, + /* 640 */ 148, 24, 21, 231, 23, 89, 90, 107, 99, 109, + /* 650 */ 110, 42, 43, 104, 37, 107, 39, 109, 110, 148, + /* 660 */ 27, 89, 90, 148, 148, 95, 148, 34, 14, 16, + /* 670 */ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + /* 680 */ 71, 72, 73, 122, 75, 76, 77, 78, 79, 80, + /* 690 */ 81, 82, 83, 84, 85, 42, 43, 81, 183, 183, + /* 700 */ 189, 183, 89, 90, 134, 89, 90, 53, 148, 55, + /* 710 */ 89, 148, 148, 16, 61, 62, 63, 64, 65, 66, + /* 720 */ 67, 68, 69, 70, 71, 72, 73, 148, 75, 76, + /* 730 */ 77, 78, 79, 80, 81, 82, 83, 84, 85, 42, + /* 740 */ 43, 226, 226, 183, 226, 148, 183, 0, 1, 2, + /* 750 */ 7, 8, 9, 107, 146, 109, 110, 16, 61, 62, + /* 760 */ 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + /* 770 */ 73, 148, 75, 76, 77, 78, 79, 80, 81, 82, + /* 780 */ 83, 84, 85, 42, 43, 148, 226, 148, 134, 226, + /* 790 */ 100, 101, 102, 170, 171, 100, 101, 102, 19, 148, + /* 800 */ 148, 16, 192, 62, 63, 64, 65, 66, 67, 68, + /* 810 */ 69, 70, 71, 72, 73, 92, 75, 76, 77, 78, + /* 820 */ 79, 80, 81, 82, 83, 84, 85, 42, 43, 23, + /* 830 */ 243, 244, 23, 16, 111, 148, 148, 22, 14, 156, + /* 840 */ 189, 189, 148, 131, 148, 133, 209, 124, 63, 64, + /* 850 */ 65, 66, 67, 68, 69, 70, 71, 72, 73, 148, + /* 860 */ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + /* 870 */ 85, 16, 17, 190, 19, 148, 189, 53, 23, 55, + /* 880 */ 43, 22, 148, 189, 148, 189, 31, 16, 17, 156, + /* 890 */ 19, 156, 113, 156, 23, 89, 90, 214, 89, 90, + /* 900 */ 189, 213, 31, 48, 170, 171, 170, 171, 156, 148, + /* 910 */ 93, 193, 125, 126, 59, 148, 189, 148, 200, 48, + /* 920 */ 237, 115, 93, 190, 115, 190, 20, 190, 22, 114, + /* 930 */ 59, 170, 171, 104, 79, 80, 99, 170, 171, 170, + /* 940 */ 171, 148, 190, 88, 89, 90, 20, 20, 93, 22, + /* 950 */ 79, 80, 81, 148, 92, 93, 148, 98, 148, 88, + /* 960 */ 89, 90, 16, 17, 93, 19, 111, 148, 148, 23, + /* 970 */ 148, 148, 20, 162, 22, 170, 171, 31, 170, 171, + /* 980 */ 125, 126, 127, 128, 129, 130, 60, 204, 148, 170, + /* 990 */ 171, 148, 170, 171, 48, 148, 125, 126, 127, 128, + /* 1000 */ 129, 130, 7, 8, 20, 59, 22, 5, 148, 148, + /* 1010 */ 170, 171, 10, 11, 12, 13, 51, 52, 148, 20, + /* 1020 */ 148, 22, 148, 148, 179, 79, 80, 20, 26, 22, + /* 1030 */ 28, 170, 171, 179, 88, 89, 90, 35, 148, 93, + /* 1040 */ 170, 171, 170, 171, 170, 171, 148, 179, 20, 47, + /* 1050 */ 22, 49, 20, 148, 22, 148, 54, 148, 148, 57, + /* 1060 */ 20, 148, 22, 148, 148, 20, 148, 22, 170, 171, + /* 1070 */ 148, 125, 126, 127, 128, 129, 130, 170, 171, 233, + /* 1080 */ 170, 171, 234, 148, 148, 170, 171, 148, 170, 171, + /* 1090 */ 148, 148, 170, 171, 20, 148, 22, 148, 148, 148, + /* 1100 */ 192, 148, 100, 101, 102, 170, 171, 148, 106, 170, + /* 1110 */ 171, 148, 148, 111, 148, 148, 148, 148, 148, 170, + /* 1120 */ 171, 170, 171, 170, 171, 148, 148, 148, 148, 148, + /* 1130 */ 148, 148, 194, 170, 171, 150, 178, 135, 170, 171, + /* 1140 */ 170, 171, 148, 223, 230, 148, 173, 170, 171, 170, + /* 1150 */ 171, 170, 171, 170, 171, 230, 148, 195, 148, 173, + /* 1160 */ 148, 173, 173, 173, 170, 171, 174, 170, 171, 195, + /* 1170 */ 6, 147, 147, 147, 147, 22, 155, 190, 170, 171, + /* 1180 */ 170, 171, 170, 171, 122, 119, 195, 120, 117, 196, + /* 1190 */ 121, 23, 161, 197, 131, 113, 198, 222, 99, 199, + /* 1200 */ 153, 153, 116, 99, 98, 172, 205, 172, 172, 206, + /* 1210 */ 205, 40, 206, 174, 180, 172, 19, 175, 85, 161, + /* 1220 */ 161, 180, 172, 172, 172, 15, 153, 152, 175, 152, + /* 1230 */ 152, 227, 153, 153, 153, 152, 227, 38, 131, 61, + /* 1240 */ 153, 185, 185, 19, 215, 153, 235, 15, 188, 236, + /* 1250 */ 195, 153, 188, 188, 33, 238, 188, 185, 238, 215, + /* 1260 */ 138, 153, 153, 241, 176, 195, 176, 244, 1, 232, + /* 1270 */ 160, 20, 113, 113, 113, 113, 93, 247, 108, 19, + /* 1280 */ 11, 20, 20, 19, 19, 22, 20, 118, 20, 115, + /* 1290 */ 118, 19, 22, 22, 20, 113, 20, 44, 19, 44, + /* 1300 */ 19, 44, 20, 19, 19, 32, 19, 104, 97, 16, + /* 1310 */ 21, 17, 99, 36, 22, 134, 99, 19, 5, 1, + /* 1320 */ 45, 103, 19, 45, 123, 69, 114, 69, 14, 17, + /* 1330 */ 116, 103, 123, 114, 19, 14, 20, 137, 58, 124, + /* 1340 */ 136, 19, 3, 248, 4, }; -#define YY_SHIFT_USE_DFLT (-98) -#define YY_SHIFT_MAX 369 +#define YY_SHIFT_USE_DFLT (-108) +#define YY_SHIFT_MAX 385 static const short yy_shift_ofst[] = { - /* 0 */ 137, 975, 1117, -16, 975, 1063, 1063, 1063, 49, -97, - /* 10 */ 118, 1063, 1063, 1063, 1063, 1063, -45, 112, 131, 478, - /* 20 */ 487, 200, 200, 51, 185, 252, 324, 396, 463, 530, - /* 30 */ 597, 664, 731, 798, 731, 731, 731, 731, 731, 731, - /* 40 */ 731, 731, 731, 731, 731, 731, 731, 731, 731, 731, - /* 50 */ 731, 865, 908, 908, 991, 1063, 1063, 1063, 1063, 1063, - /* 60 */ 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, - /* 70 */ 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, - /* 80 */ 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, - /* 90 */ 1063, 1063, 1063, -60, -60, -14, 27, 27, 94, 85, - /* 100 */ 394, 478, 478, 478, 478, 354, 478, 478, 478, 487, - /* 110 */ -59, -98, -98, -98, 1116, 53, 325, 325, 291, 277, - /* 120 */ 478, 277, 478, 478, 478, 478, 478, 478, 478, 478, - /* 130 */ 478, 478, 478, 478, 478, 389, 511, -97, -97, -97, - /* 140 */ -98, -98, 147, 147, 192, 262, 340, 430, 395, 401, - /* 150 */ 195, 467, 469, 474, 472, 418, 427, 427, 777, 427, - /* 160 */ 427, 73, 427, 427, 735, 427, 427, 461, 735, 427, - /* 170 */ 427, 527, 527, 527, 427, 427, 461, 427, 427, 461, - /* 180 */ 427, 538, 600, 427, 427, 461, 427, 427, 427, 461, - /* 190 */ 427, 461, 461, 427, 427, 427, 427, 427, 427, 132, - /* 200 */ 655, 659, 593, 644, 644, 509, 655, 655, 737, 655, - /* 210 */ 655, 422, 700, 700, 1023, 1023, 1023, 1023, 1019, 946, - /* 220 */ 946, 1007, 946, 952, 946, -97, 935, 941, 948, 949, - /* 230 */ 940, 942, 962, 979, 1052, 979, 962, 992, 977, 992, - /* 240 */ 977, 1077, 979, 979, 1052, 1007, 946, 946, 946, 1077, - /* 250 */ 1108, 962, 962, 962, 962, 1098, 1008, 1108, 962, 1088, - /* 260 */ 1088, 1136, 935, 1142, 1142, 1142, 935, 1088, 1136, 962, - /* 270 */ 1134, 1134, 962, 962, 1039, -98, -98, -98, -98, 457, - /* 280 */ 521, 663, 188, 306, 823, 904, 674, 691, 813, 869, - /* 290 */ 877, 795, 878, 929, 933, 850, 934, 938, 944, 945, - /* 300 */ 961, 1178, 1160, 1149, 1138, 1164, 1074, 1084, 1085, 1087, - /* 310 */ 1180, 1181, 1183, 1110, 1099, 1185, 1196, 1189, 1190, 1187, - /* 320 */ 1191, 1096, 1192, 1097, 1197, 1105, 1201, 1202, 1112, 1204, - /* 330 */ 1184, 1206, 1207, 1210, 1211, 1188, 1212, 1139, 1132, 1219, - /* 340 */ 1220, 1215, 1141, 1208, 1198, 1223, 1203, 1114, 1145, 1228, - /* 350 */ 1244, 1250, 1151, 1186, 1193, 1133, 1236, 1144, 1240, 1146, - /* 360 */ 1158, 1140, 1243, 1245, 1249, 1209, 1130, 1135, 1264, 1265, + /* 0 */ 110, 855, 1002, -16, 855, 946, 946, 946, 327, 128, + /* 10 */ -107, 98, 946, 946, 946, 946, 946, -46, 251, 477, + /* 20 */ 572, -11, 78, 78, 54, 168, 212, 256, 329, 399, + /* 30 */ 469, 539, 609, 653, 697, 653, 653, 653, 653, 653, + /* 40 */ 653, 653, 653, 653, 653, 653, 653, 653, 653, 653, + /* 50 */ 653, 653, 741, 785, 785, 871, 946, 946, 946, 946, + /* 60 */ 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, + /* 70 */ 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, + /* 80 */ 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, + /* 90 */ 946, 946, 946, 946, -62, -62, 6, 6, 285, 64, + /* 100 */ 184, 549, 570, 572, 572, 572, 572, 572, 572, 572, + /* 110 */ 118, -11, -41, -108, -108, 133, 9, 336, 336, 567, + /* 120 */ 571, 747, 621, 572, 621, 572, 572, 572, 572, 572, + /* 130 */ 572, 572, 572, 572, 572, 572, 572, 572, 723, 61, + /* 140 */ -107, -107, -107, -108, -108, -108, -18, -18, 333, 211, + /* 150 */ 467, 556, 540, 548, 617, 806, 809, 613, 616, 743, + /* 160 */ 572, 572, 234, 572, 572, 424, 572, 572, 171, 572, + /* 170 */ 572, 646, 171, 572, 572, 390, 390, 390, 572, 572, + /* 180 */ 646, 572, 572, 646, 572, 555, 690, 572, 572, 646, + /* 190 */ 572, 572, 572, 646, 572, 572, 572, 646, 646, 572, + /* 200 */ 572, 572, 572, 572, 414, 526, 815, 787, 787, 712, + /* 210 */ 633, 633, 633, 837, 633, 633, 859, 561, 561, 1164, + /* 220 */ 1164, 1164, 1164, 1153, -107, 1062, 1066, 1067, 1071, 1069, + /* 230 */ 1168, 1063, 1082, 1082, 1099, 1086, 1099, 1086, 1104, 1104, + /* 240 */ 1171, 1104, 1106, 1104, 1197, 1133, 1168, 1133, 1168, 1171, + /* 250 */ 1104, 1104, 1104, 1197, 1210, 1082, 1210, 1082, 1210, 1082, + /* 260 */ 1082, 1199, 1107, 1210, 1082, 1178, 1178, 1224, 1062, 1082, + /* 270 */ 1232, 1232, 1232, 1232, 1062, 1178, 1224, 1082, 1221, 1221, + /* 280 */ 1082, 1082, 1122, -108, -108, -108, -108, -108, -108, 464, + /* 290 */ 654, 695, 824, 779, 817, 466, 906, 927, 952, 829, + /* 300 */ 995, 862, 984, 999, 1007, 965, 1028, 1032, 1040, 1045, + /* 310 */ 559, 1074, 926, 1267, 1251, 1159, 1160, 1161, 1162, 1183, + /* 320 */ 1170, 1260, 1261, 1262, 1264, 1269, 1265, 1266, 1263, 1268, + /* 330 */ 1169, 1270, 1172, 1271, 1174, 1272, 1274, 1182, 1276, 1273, + /* 340 */ 1253, 1279, 1255, 1281, 1282, 1284, 1285, 1257, 1287, 1211, + /* 350 */ 1203, 1293, 1294, 1289, 1213, 1277, 1275, 1292, 1278, 1181, + /* 360 */ 1217, 1298, 1313, 1318, 1218, 1256, 1258, 1201, 1303, 1212, + /* 370 */ 1314, 1214, 1312, 1219, 1228, 1209, 1315, 1215, 1316, 1321, + /* 380 */ 1280, 1204, 1200, 1322, 1339, 1340, }; -#define YY_REDUCE_USE_DFLT (-216) -#define YY_REDUCE_MAX 278 +#define YY_REDUCE_USE_DFLT (-178) +#define YY_REDUCE_MAX 288 static const short yy_reduce_ofst[] = { - /* 0 */ -56, 136, 16, 70, 189, 128, 67, 133, 190, 15, - /* 10 */ 6, 141, 261, 271, 267, 273, -178, 255, -140, -61, - /* 20 */ 146, 259, 268, -215, -215, -215, -215, -215, -215, -215, - /* 30 */ -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, - /* 40 */ -215, -215, -215, -215, -215, -215, -215, -215, -215, -215, - /* 50 */ -215, -215, -215, -215, 402, 416, 456, 468, 473, 475, - /* 60 */ 477, 480, 483, 486, 523, 535, 540, 542, 544, 547, - /* 70 */ 549, 551, 590, 602, 606, 608, 610, 614, 618, 620, - /* 80 */ 657, 669, 673, 675, 677, 681, 686, 724, 736, 740, - /* 90 */ 742, 744, 748, -215, -215, -77, -215, -215, -215, -215, - /* 100 */ -26, 406, 603, 604, 670, 124, 671, 44, 225, 78, - /* 110 */ -215, -215, -215, -215, 208, 253, 157, 194, -72, 139, - /* 120 */ 305, 215, 358, 265, 440, 222, 476, 429, 568, 772, - /* 130 */ 774, 775, 776, 369, 806, 69, 333, 496, 533, 749, - /* 140 */ 436, 501, -126, -112, -81, -12, 37, 227, 37, 37, - /* 150 */ 233, 335, 361, 403, 432, 444, 484, 489, 428, 432, - /* 160 */ 605, 612, 607, 672, 622, 690, 693, 37, 622, 701, - /* 170 */ 707, 729, 738, 771, 768, 773, 37, 811, 822, 37, - /* 180 */ 849, 766, 769, 851, 853, 37, 855, 856, 857, 37, - /* 190 */ 858, 37, 37, 859, 863, 866, 867, 870, 871, 872, - /* 200 */ 840, 828, 827, 794, 797, 803, 860, 861, 854, 864, - /* 210 */ 873, 862, 833, 834, 891, 892, 893, 895, 889, 875, - /* 220 */ 876, 879, 880, 882, 881, 868, 874, 894, 888, 896, - /* 230 */ 890, 842, 921, 883, 926, 885, 939, 901, 902, 905, - /* 240 */ 903, 924, 899, 900, 953, 927, 943, 950, 954, 958, - /* 250 */ 976, 974, 981, 982, 983, 906, 909, 994, 995, 968, - /* 260 */ 971, 947, 963, 972, 973, 984, 967, 980, 951, 1011, - /* 270 */ 937, 957, 1017, 1018, 959, 1020, 1002, 1003, 955, + /* 0 */ -139, 213, 371, 146, 283, 278, 53, 286, 38, -74, + /* 10 */ -3, -140, 288, 346, 351, 348, 353, 92, 683, -38, + /* 20 */ 40, 195, 279, 406, -177, -177, -177, -177, -177, -177, + /* 30 */ -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, + /* 40 */ -177, -177, -177, -177, -177, -177, -177, -177, -177, -177, + /* 50 */ -177, -177, -177, -177, -177, 355, 623, 734, 736, 761, + /* 60 */ 767, 769, 805, 808, 819, 822, 840, 861, 870, 872, + /* 70 */ 874, 898, 907, 910, 915, 918, 922, 935, 939, 949, + /* 80 */ 951, 953, 963, 968, 970, 977, 979, 981, 983, 994, + /* 90 */ 997, 1008, 1010, 1012, -177, -177, -177, -177, 37, -177, + /* 100 */ -177, 190, 412, 515, 516, 518, 560, 563, 303, 156, + /* 110 */ -177, 435, -177, -177, -177, 55, 187, 70, 84, 141, + /* 120 */ 141, -47, 290, 94, 432, -76, 511, 349, 282, 637, + /* 130 */ 651, 652, 687, 694, 696, 711, 688, 727, -132, 733, + /* 140 */ 735, 737, 752, 718, 302, 587, 39, 45, 148, 161, + /* 150 */ 30, 307, 30, 30, 263, 492, 564, 579, 597, 608, + /* 160 */ 639, 793, 610, 597, 810, 811, 820, 823, 783, 843, + /* 170 */ 847, 30, 783, 860, 875, 845, 854, 868, 890, 905, + /* 180 */ 30, 909, 913, 30, 916, 846, 848, 936, 942, 30, + /* 190 */ 943, 947, 950, 30, 959, 964, 966, 30, 30, 967, + /* 200 */ 969, 978, 980, 982, 985, 908, 938, 914, 925, 920, + /* 210 */ 973, 986, 988, 958, 989, 990, 992, 962, 974, 1024, + /* 220 */ 1025, 1026, 1027, 1021, 987, 991, 993, 996, 998, 1000, + /* 230 */ 1031, 975, 1047, 1048, 1001, 1003, 1005, 1006, 1033, 1035, + /* 240 */ 1034, 1036, 1039, 1043, 1042, 1004, 1058, 1009, 1059, 1041, + /* 250 */ 1050, 1051, 1052, 1053, 1075, 1073, 1077, 1079, 1078, 1080, + /* 260 */ 1081, 1011, 1013, 1083, 1087, 1056, 1057, 1029, 1055, 1092, + /* 270 */ 1060, 1064, 1065, 1068, 1070, 1072, 1044, 1098, 1017, 1020, + /* 280 */ 1108, 1109, 1022, 1110, 1088, 1090, 1037, 1023, 1030, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 565, 789, 854, 680, 854, 789, 854, 789, 854, 684, - /* 10 */ 840, 785, 789, 854, 854, 854, 760, 854, 811, 854, - /* 20 */ 596, 811, 811, 715, 854, 854, 854, 854, 854, 854, - /* 30 */ 854, 854, 716, 854, 788, 784, 780, 782, 781, 717, - /* 40 */ 704, 713, 720, 696, 825, 722, 723, 728, 729, 841, - /* 50 */ 844, 750, 766, 749, 854, 854, 854, 854, 854, 854, - /* 60 */ 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, - /* 70 */ 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, - /* 80 */ 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, - /* 90 */ 854, 854, 854, 752, 771, 589, 751, 759, 753, 754, - /* 100 */ 649, 854, 854, 854, 854, 584, 854, 854, 854, 854, - /* 110 */ 755, 756, 767, 768, 854, 854, 854, 854, 565, 680, - /* 120 */ 854, 680, 854, 854, 854, 854, 854, 854, 854, 854, - /* 130 */ 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, - /* 140 */ 674, 684, 854, 854, 640, 854, 854, 854, 854, 854, - /* 150 */ 854, 854, 854, 854, 854, 572, 570, 854, 672, 854, - /* 160 */ 854, 598, 854, 854, 682, 854, 854, 687, 688, 854, - /* 170 */ 854, 854, 854, 854, 854, 854, 586, 854, 854, 661, - /* 180 */ 854, 817, 854, 854, 854, 832, 854, 854, 854, 830, - /* 190 */ 854, 663, 725, 799, 854, 854, 845, 847, 854, 854, - /* 200 */ 707, 672, 681, 854, 854, 783, 707, 707, 619, 707, - /* 210 */ 707, 622, 719, 719, 569, 569, 569, 569, 639, 651, - /* 220 */ 651, 636, 651, 622, 651, 854, 719, 710, 712, 700, - /* 230 */ 714, 854, 689, 708, 854, 708, 689, 697, 699, 697, - /* 240 */ 699, 793, 708, 708, 854, 636, 651, 651, 651, 793, - /* 250 */ 581, 689, 689, 689, 689, 821, 824, 581, 689, 653, - /* 260 */ 653, 730, 719, 660, 660, 660, 719, 653, 730, 689, - /* 270 */ 843, 843, 689, 689, 852, 606, 624, 624, 827, 854, - /* 280 */ 854, 854, 854, 854, 854, 737, 854, 854, 854, 854, - /* 290 */ 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, - /* 300 */ 806, 854, 854, 854, 854, 854, 742, 738, 854, 739, - /* 310 */ 854, 854, 854, 854, 666, 854, 854, 854, 854, 854, - /* 320 */ 854, 854, 701, 854, 711, 854, 854, 854, 854, 854, - /* 330 */ 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, - /* 340 */ 854, 854, 854, 854, 819, 820, 854, 854, 854, 854, - /* 350 */ 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, - /* 360 */ 854, 854, 854, 854, 854, 851, 854, 854, 566, 854, - /* 370 */ 560, 563, 562, 564, 568, 571, 593, 594, 595, 573, - /* 380 */ 574, 575, 576, 577, 578, 579, 585, 587, 605, 607, - /* 390 */ 614, 652, 655, 656, 657, 835, 836, 837, 615, 634, - /* 400 */ 637, 638, 616, 623, 705, 706, 617, 670, 671, 734, - /* 410 */ 664, 665, 669, 736, 740, 741, 743, 744, 592, 599, - /* 420 */ 600, 603, 604, 807, 809, 808, 810, 602, 601, 745, - /* 430 */ 748, 757, 758, 764, 770, 773, 762, 763, 765, 769, - /* 440 */ 772, 667, 668, 776, 778, 779, 833, 834, 774, 786, - /* 450 */ 787, 690, 777, 761, 702, 591, 709, 703, 673, 683, - /* 460 */ 692, 693, 694, 695, 678, 679, 685, 698, 732, 733, - /* 470 */ 686, 675, 676, 677, 775, 735, 746, 747, 618, 625, - /* 480 */ 626, 627, 630, 631, 632, 633, 628, 629, 794, 795, - /* 490 */ 797, 796, 620, 621, 635, 608, 609, 610, 611, 742, - /* 500 */ 612, 613, 597, 590, 641, 644, 645, 646, 647, 648, - /* 510 */ 650, 642, 643, 588, 580, 582, 691, 813, 822, 823, - /* 520 */ 818, 814, 815, 816, 583, 790, 791, 654, 726, 727, - /* 530 */ 812, 826, 828, 731, 829, 831, 658, 659, 662, 798, - /* 540 */ 838, 718, 721, 724, 800, 801, 802, 803, 804, 805, - /* 550 */ 839, 842, 846, 848, 849, 850, 853, 567, 561, + /* 0 */ 593, 819, 899, 708, 899, 819, 899, 819, 899, 844, + /* 10 */ 712, 873, 815, 819, 899, 899, 899, 790, 899, 844, + /* 20 */ 899, 624, 844, 844, 741, 899, 899, 899, 899, 899, + /* 30 */ 899, 899, 899, 742, 899, 818, 814, 810, 812, 811, + /* 40 */ 743, 732, 739, 746, 724, 858, 748, 749, 755, 756, + /* 50 */ 874, 877, 778, 777, 796, 899, 899, 899, 899, 899, + /* 60 */ 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, + /* 70 */ 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, + /* 80 */ 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, + /* 90 */ 899, 899, 899, 899, 780, 801, 779, 789, 617, 781, + /* 100 */ 782, 677, 612, 899, 899, 899, 899, 899, 899, 899, + /* 110 */ 783, 899, 784, 797, 798, 899, 899, 899, 899, 899, + /* 120 */ 899, 593, 708, 899, 708, 899, 899, 899, 899, 899, + /* 130 */ 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, + /* 140 */ 899, 899, 899, 702, 712, 892, 899, 899, 668, 899, + /* 150 */ 899, 899, 899, 899, 899, 899, 899, 899, 899, 600, + /* 160 */ 598, 899, 700, 899, 899, 626, 899, 899, 710, 899, + /* 170 */ 899, 715, 716, 899, 899, 899, 899, 899, 899, 899, + /* 180 */ 614, 899, 899, 689, 899, 850, 899, 899, 899, 865, + /* 190 */ 899, 899, 899, 863, 899, 899, 899, 691, 751, 831, + /* 200 */ 899, 878, 880, 899, 899, 700, 709, 899, 899, 813, + /* 210 */ 735, 735, 735, 647, 735, 735, 650, 745, 745, 597, + /* 220 */ 597, 597, 597, 667, 899, 745, 736, 738, 728, 740, + /* 230 */ 899, 899, 717, 717, 725, 727, 725, 727, 679, 679, + /* 240 */ 664, 679, 650, 679, 823, 828, 899, 828, 899, 664, + /* 250 */ 679, 679, 679, 823, 609, 717, 609, 717, 609, 717, + /* 260 */ 717, 854, 857, 609, 717, 681, 681, 757, 745, 717, + /* 270 */ 688, 688, 688, 688, 745, 681, 757, 717, 876, 876, + /* 280 */ 717, 717, 885, 634, 652, 652, 860, 892, 897, 899, + /* 290 */ 899, 899, 899, 764, 899, 899, 899, 899, 899, 899, + /* 300 */ 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, + /* 310 */ 837, 899, 899, 899, 899, 769, 765, 899, 766, 899, + /* 320 */ 694, 899, 899, 899, 899, 899, 899, 899, 899, 899, + /* 330 */ 899, 729, 899, 737, 899, 899, 899, 899, 899, 899, + /* 340 */ 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, + /* 350 */ 899, 899, 899, 899, 899, 899, 852, 853, 899, 899, + /* 360 */ 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, + /* 370 */ 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, + /* 380 */ 884, 899, 899, 887, 594, 899, 588, 591, 590, 592, + /* 390 */ 596, 599, 621, 622, 623, 601, 602, 603, 604, 605, + /* 400 */ 606, 607, 613, 615, 633, 635, 619, 637, 698, 699, + /* 410 */ 761, 692, 693, 697, 772, 763, 767, 768, 770, 771, + /* 420 */ 785, 786, 788, 794, 800, 803, 787, 792, 793, 795, + /* 430 */ 799, 802, 695, 696, 806, 620, 627, 628, 631, 632, + /* 440 */ 840, 842, 841, 843, 630, 629, 773, 776, 808, 809, + /* 450 */ 866, 867, 868, 869, 870, 804, 816, 817, 718, 807, + /* 460 */ 791, 730, 733, 734, 731, 701, 711, 720, 721, 722, + /* 470 */ 723, 706, 707, 713, 726, 759, 760, 714, 703, 704, + /* 480 */ 705, 805, 762, 774, 775, 638, 639, 769, 640, 641, + /* 490 */ 642, 680, 683, 684, 685, 643, 662, 665, 666, 644, + /* 500 */ 651, 645, 646, 653, 654, 655, 658, 659, 660, 661, + /* 510 */ 656, 657, 824, 825, 829, 827, 826, 648, 649, 663, + /* 520 */ 636, 625, 618, 669, 672, 673, 674, 675, 676, 678, + /* 530 */ 670, 671, 616, 608, 610, 719, 846, 855, 856, 851, + /* 540 */ 847, 848, 849, 611, 820, 821, 682, 753, 754, 845, + /* 550 */ 859, 861, 758, 862, 864, 889, 686, 687, 690, 830, + /* 560 */ 871, 744, 747, 750, 752, 832, 833, 834, 835, 838, + /* 570 */ 839, 836, 872, 875, 879, 881, 882, 883, 886, 888, + /* 580 */ 893, 894, 895, 898, 896, 595, 589, }; -#define YY_SZ_ACTTAB (sizeof(yy_action)/sizeof(yy_action[0])) +#define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0])) /* The next table maps tokens into fallback tokens. If a construct ** like the following: @@ -635,9 +656,11 @@ static const YYCODETYPE yyFallback[] = { 23, /* TRIGGER => ID */ 23, /* VACUUM => ID */ 23, /* VIEW => ID */ + 23, /* VIRTUAL => ID */ 23, /* REINDEX => ID */ 23, /* RENAME => ID */ 23, /* CTIME_KW => ID */ + 0, /* ANY => nothing */ 0, /* OR => nothing */ 0, /* AND => nothing */ 0, /* IS => nothing */ @@ -662,6 +685,7 @@ static const YYCODETYPE yyFallback[] = { 0, /* SLASH => nothing */ 0, /* REM => nothing */ 0, /* CONCAT => nothing */ + 0, /* COLLATE => nothing */ 0, /* UMINUS => nothing */ 0, /* UPLUS => nothing */ 0, /* BITNOT => nothing */ @@ -674,7 +698,6 @@ static const YYCODETYPE yyFallback[] = { 0, /* UNIQUE => nothing */ 0, /* CHECK => nothing */ 0, /* REFERENCES => nothing */ - 0, /* COLLATE => nothing */ 0, /* AUTOINCR => nothing */ 0, /* ON => nothing */ 0, /* DELETE => nothing */ @@ -800,52 +823,54 @@ static const char *const yyTokenName[] = { "KEY", "OF", "OFFSET", "PRAGMA", "RAISE", "REPLACE", "RESTRICT", "ROW", "STATEMENT", "TRIGGER", "VACUUM", "VIEW", - "REINDEX", "RENAME", "CTIME_KW", "OR", - "AND", "IS", "BETWEEN", "IN", - "ISNULL", "NOTNULL", "NE", "EQ", - "GT", "LE", "LT", "GE", - "ESCAPE", "BITAND", "BITOR", "LSHIFT", - "RSHIFT", "PLUS", "MINUS", "STAR", - "SLASH", "REM", "CONCAT", "UMINUS", - "UPLUS", "BITNOT", "STRING", "JOIN_KW", - "CONSTRAINT", "DEFAULT", "NULL", "PRIMARY", - "UNIQUE", "CHECK", "REFERENCES", "COLLATE", - "AUTOINCR", "ON", "DELETE", "UPDATE", - "INSERT", "SET", "DEFERRABLE", "FOREIGN", - "DROP", "UNION", "ALL", "EXCEPT", - "INTERSECT", "SELECT", "DISTINCT", "DOT", - "FROM", "JOIN", "USING", "ORDER", - "BY", "GROUP", "HAVING", "LIMIT", - "WHERE", "INTO", "VALUES", "INTEGER", - "FLOAT", "BLOB", "REGISTER", "VARIABLE", - "CASE", "WHEN", "THEN", "ELSE", - "INDEX", "ALTER", "TO", "ADD", - "COLUMNKW", "error", "input", "cmdlist", - "ecmd", "cmdx", "cmd", "explain", - "transtype", "trans_opt", "nm", "create_table", - "create_table_args", "temp", "ifnotexists", "dbnm", - "columnlist", "conslist_opt", "select", "column", - "columnid", "type", "carglist", "id", - "ids", "typetoken", "typename", "signed", - "plus_num", "minus_num", "carg", "ccons", - "term", "expr", "onconf", "sortorder", - "autoinc", "idxlist_opt", "refargs", "defer_subclause", - "refarg", "refact", "init_deferred_pred_opt", "conslist", - "tcons", "idxlist", "defer_subclause_opt", "orconf", - "resolvetype", "raisetype", "ifexists", "fullname", - "oneselect", "multiselect_op", "distinct", "selcollist", - "from", "where_opt", "groupby_opt", "having_opt", - "orderby_opt", "limit_opt", "sclp", "as", - "seltablist", "stl_prefix", "joinop", "on_opt", - "using_opt", "seltablist_paren", "joinop2", "inscollist", - "sortlist", "sortitem", "collate", "exprlist", - "setlist", "insert_cmd", "inscollist_opt", "itemlist", - "likeop", "escape", "between_op", "in_op", - "case_operand", "case_exprlist", "case_else", "expritem", - "uniqueflag", "idxitem", "plus_opt", "number", - "trigger_decl", "trigger_cmd_list", "trigger_time", "trigger_event", - "foreach_clause", "when_clause", "trigger_cmd", "database_kw_opt", - "key_opt", "add_column_fullname", "kwcolumn_opt", + "VIRTUAL", "REINDEX", "RENAME", "CTIME_KW", + "ANY", "OR", "AND", "IS", + "BETWEEN", "IN", "ISNULL", "NOTNULL", + "NE", "EQ", "GT", "LE", + "LT", "GE", "ESCAPE", "BITAND", + "BITOR", "LSHIFT", "RSHIFT", "PLUS", + "MINUS", "STAR", "SLASH", "REM", + "CONCAT", "COLLATE", "UMINUS", "UPLUS", + "BITNOT", "STRING", "JOIN_KW", "CONSTRAINT", + "DEFAULT", "NULL", "PRIMARY", "UNIQUE", + "CHECK", "REFERENCES", "AUTOINCR", "ON", + "DELETE", "UPDATE", "INSERT", "SET", + "DEFERRABLE", "FOREIGN", "DROP", "UNION", + "ALL", "EXCEPT", "INTERSECT", "SELECT", + "DISTINCT", "DOT", "FROM", "JOIN", + "USING", "ORDER", "BY", "GROUP", + "HAVING", "LIMIT", "WHERE", "INTO", + "VALUES", "INTEGER", "FLOAT", "BLOB", + "REGISTER", "VARIABLE", "CASE", "WHEN", + "THEN", "ELSE", "INDEX", "ALTER", + "TO", "ADD", "COLUMNKW", "error", + "input", "cmdlist", "ecmd", "cmdx", + "cmd", "explain", "transtype", "trans_opt", + "nm", "create_table", "create_table_args", "temp", + "ifnotexists", "dbnm", "columnlist", "conslist_opt", + "select", "column", "columnid", "type", + "carglist", "id", "ids", "typetoken", + "typename", "signed", "plus_num", "minus_num", + "carg", "ccons", "term", "expr", + "onconf", "sortorder", "autoinc", "idxlist_opt", + "refargs", "defer_subclause", "refarg", "refact", + "init_deferred_pred_opt", "conslist", "tcons", "idxlist", + "defer_subclause_opt", "orconf", "resolvetype", "raisetype", + "ifexists", "fullname", "oneselect", "multiselect_op", + "distinct", "selcollist", "from", "where_opt", + "groupby_opt", "having_opt", "orderby_opt", "limit_opt", + "sclp", "as", "seltablist", "stl_prefix", + "joinop", "on_opt", "using_opt", "seltablist_paren", + "joinop2", "inscollist", "sortlist", "sortitem", + "exprlist", "setlist", "insert_cmd", "inscollist_opt", + "itemlist", "likeop", "escape", "between_op", + "in_op", "case_operand", "case_exprlist", "case_else", + "expritem", "uniqueflag", "idxitem", "collate", + "nmnum", "plus_opt", "number", "trigger_decl", + "trigger_cmd_list", "trigger_time", "trigger_event", "foreach_clause", + "when_clause", "trigger_cmd", "database_kw_opt", "key_opt", + "add_column_fullname", "kwcolumn_opt", "create_vtab", "vtabarglist", + "vtabarg", "vtabargtoken", "lp", "anylist", }; #endif /* NDEBUG */ @@ -903,11 +928,11 @@ static const char *const yyRuleName[] = { /* 47 */ "carglist ::=", /* 48 */ "carg ::= CONSTRAINT nm ccons", /* 49 */ "carg ::= ccons", - /* 50 */ "carg ::= DEFAULT term", - /* 51 */ "carg ::= DEFAULT LP expr RP", - /* 52 */ "carg ::= DEFAULT PLUS term", - /* 53 */ "carg ::= DEFAULT MINUS term", - /* 54 */ "carg ::= DEFAULT id", + /* 50 */ "ccons ::= DEFAULT term", + /* 51 */ "ccons ::= DEFAULT LP expr RP", + /* 52 */ "ccons ::= DEFAULT PLUS term", + /* 53 */ "ccons ::= DEFAULT MINUS term", + /* 54 */ "ccons ::= DEFAULT id", /* 55 */ "ccons ::= NULL onconf", /* 56 */ "ccons ::= NOT NULL onconf", /* 57 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc", @@ -955,7 +980,7 @@ static const char *const yyRuleName[] = { /* 99 */ "cmd ::= DROP TABLE ifexists fullname", /* 100 */ "ifexists ::= IF EXISTS", /* 101 */ "ifexists ::=", - /* 102 */ "cmd ::= CREATE temp VIEW nm dbnm AS select", + /* 102 */ "cmd ::= CREATE temp VIEW ifnotexists nm dbnm AS select", /* 103 */ "cmd ::= DROP VIEW ifexists fullname", /* 104 */ "cmd ::= select", /* 105 */ "select ::= oneselect", @@ -996,49 +1021,49 @@ static const char *const yyRuleName[] = { /* 140 */ "using_opt ::=", /* 141 */ "orderby_opt ::=", /* 142 */ "orderby_opt ::= ORDER BY sortlist", - /* 143 */ "sortlist ::= sortlist COMMA sortitem collate sortorder", - /* 144 */ "sortlist ::= sortitem collate sortorder", + /* 143 */ "sortlist ::= sortlist COMMA sortitem sortorder", + /* 144 */ "sortlist ::= sortitem sortorder", /* 145 */ "sortitem ::= expr", /* 146 */ "sortorder ::= ASC", /* 147 */ "sortorder ::= DESC", /* 148 */ "sortorder ::=", - /* 149 */ "collate ::=", - /* 150 */ "collate ::= COLLATE id", - /* 151 */ "groupby_opt ::=", - /* 152 */ "groupby_opt ::= GROUP BY exprlist", - /* 153 */ "having_opt ::=", - /* 154 */ "having_opt ::= HAVING expr", - /* 155 */ "limit_opt ::=", - /* 156 */ "limit_opt ::= LIMIT expr", - /* 157 */ "limit_opt ::= LIMIT expr OFFSET expr", - /* 158 */ "limit_opt ::= LIMIT expr COMMA expr", - /* 159 */ "cmd ::= DELETE FROM fullname where_opt", - /* 160 */ "where_opt ::=", - /* 161 */ "where_opt ::= WHERE expr", - /* 162 */ "cmd ::= UPDATE orconf fullname SET setlist where_opt", - /* 163 */ "setlist ::= setlist COMMA nm EQ expr", - /* 164 */ "setlist ::= nm EQ expr", - /* 165 */ "cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP", - /* 166 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select", - /* 167 */ "insert_cmd ::= INSERT orconf", - /* 168 */ "insert_cmd ::= REPLACE", - /* 169 */ "itemlist ::= itemlist COMMA expr", - /* 170 */ "itemlist ::= expr", - /* 171 */ "inscollist_opt ::=", - /* 172 */ "inscollist_opt ::= LP inscollist RP", - /* 173 */ "inscollist ::= inscollist COMMA nm", - /* 174 */ "inscollist ::= nm", - /* 175 */ "expr ::= term", - /* 176 */ "expr ::= LP expr RP", - /* 177 */ "term ::= NULL", - /* 178 */ "expr ::= ID", - /* 179 */ "expr ::= JOIN_KW", - /* 180 */ "expr ::= nm DOT nm", - /* 181 */ "expr ::= nm DOT nm DOT nm", - /* 182 */ "term ::= INTEGER|FLOAT|BLOB", - /* 183 */ "term ::= STRING", - /* 184 */ "expr ::= REGISTER", - /* 185 */ "expr ::= VARIABLE", + /* 149 */ "groupby_opt ::=", + /* 150 */ "groupby_opt ::= GROUP BY exprlist", + /* 151 */ "having_opt ::=", + /* 152 */ "having_opt ::= HAVING expr", + /* 153 */ "limit_opt ::=", + /* 154 */ "limit_opt ::= LIMIT expr", + /* 155 */ "limit_opt ::= LIMIT expr OFFSET expr", + /* 156 */ "limit_opt ::= LIMIT expr COMMA expr", + /* 157 */ "cmd ::= DELETE FROM fullname where_opt", + /* 158 */ "where_opt ::=", + /* 159 */ "where_opt ::= WHERE expr", + /* 160 */ "cmd ::= UPDATE orconf fullname SET setlist where_opt", + /* 161 */ "setlist ::= setlist COMMA nm EQ expr", + /* 162 */ "setlist ::= nm EQ expr", + /* 163 */ "cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP", + /* 164 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select", + /* 165 */ "cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES", + /* 166 */ "insert_cmd ::= INSERT orconf", + /* 167 */ "insert_cmd ::= REPLACE", + /* 168 */ "itemlist ::= itemlist COMMA expr", + /* 169 */ "itemlist ::= expr", + /* 170 */ "inscollist_opt ::=", + /* 171 */ "inscollist_opt ::= LP inscollist RP", + /* 172 */ "inscollist ::= inscollist COMMA nm", + /* 173 */ "inscollist ::= nm", + /* 174 */ "expr ::= term", + /* 175 */ "expr ::= LP expr RP", + /* 176 */ "term ::= NULL", + /* 177 */ "expr ::= ID", + /* 178 */ "expr ::= JOIN_KW", + /* 179 */ "expr ::= nm DOT nm", + /* 180 */ "expr ::= nm DOT nm DOT nm", + /* 181 */ "term ::= INTEGER|FLOAT|BLOB", + /* 182 */ "term ::= STRING", + /* 183 */ "expr ::= REGISTER", + /* 184 */ "expr ::= VARIABLE", + /* 185 */ "expr ::= expr COLLATE id", /* 186 */ "expr ::= CAST LP expr AS typetoken RP", /* 187 */ "expr ::= ID LP distinct exprlist RP", /* 188 */ "expr ::= ID LP STAR RP", @@ -1053,101 +1078,118 @@ static const char *const yyRuleName[] = { /* 197 */ "expr ::= expr CONCAT expr", /* 198 */ "likeop ::= LIKE_KW", /* 199 */ "likeop ::= NOT LIKE_KW", - /* 200 */ "escape ::= ESCAPE expr", - /* 201 */ "escape ::=", - /* 202 */ "expr ::= expr likeop expr escape", - /* 203 */ "expr ::= expr ISNULL|NOTNULL", - /* 204 */ "expr ::= expr IS NULL", - /* 205 */ "expr ::= expr NOT NULL", - /* 206 */ "expr ::= expr IS NOT NULL", - /* 207 */ "expr ::= NOT|BITNOT expr", - /* 208 */ "expr ::= MINUS expr", - /* 209 */ "expr ::= PLUS expr", - /* 210 */ "between_op ::= BETWEEN", - /* 211 */ "between_op ::= NOT BETWEEN", - /* 212 */ "expr ::= expr between_op expr AND expr", - /* 213 */ "in_op ::= IN", - /* 214 */ "in_op ::= NOT IN", - /* 215 */ "expr ::= expr in_op LP exprlist RP", - /* 216 */ "expr ::= LP select RP", - /* 217 */ "expr ::= expr in_op LP select RP", - /* 218 */ "expr ::= expr in_op nm dbnm", - /* 219 */ "expr ::= EXISTS LP select RP", - /* 220 */ "expr ::= CASE case_operand case_exprlist case_else END", - /* 221 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", - /* 222 */ "case_exprlist ::= WHEN expr THEN expr", - /* 223 */ "case_else ::= ELSE expr", - /* 224 */ "case_else ::=", - /* 225 */ "case_operand ::= expr", - /* 226 */ "case_operand ::=", - /* 227 */ "exprlist ::= exprlist COMMA expritem", - /* 228 */ "exprlist ::= expritem", - /* 229 */ "expritem ::= expr", - /* 230 */ "expritem ::=", - /* 231 */ "cmd ::= CREATE uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP", - /* 232 */ "uniqueflag ::= UNIQUE", - /* 233 */ "uniqueflag ::=", - /* 234 */ "idxlist_opt ::=", - /* 235 */ "idxlist_opt ::= LP idxlist RP", - /* 236 */ "idxlist ::= idxlist COMMA idxitem collate sortorder", - /* 237 */ "idxlist ::= idxitem collate sortorder", - /* 238 */ "idxitem ::= nm", - /* 239 */ "cmd ::= DROP INDEX ifexists fullname", - /* 240 */ "cmd ::= VACUUM", - /* 241 */ "cmd ::= VACUUM nm", - /* 242 */ "cmd ::= PRAGMA nm dbnm EQ nm", - /* 243 */ "cmd ::= PRAGMA nm dbnm EQ ON", - /* 244 */ "cmd ::= PRAGMA nm dbnm EQ plus_num", - /* 245 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", - /* 246 */ "cmd ::= PRAGMA nm dbnm LP nm RP", - /* 247 */ "cmd ::= PRAGMA nm dbnm", - /* 248 */ "plus_num ::= plus_opt number", - /* 249 */ "minus_num ::= MINUS number", - /* 250 */ "number ::= INTEGER|FLOAT", - /* 251 */ "plus_opt ::= PLUS", - /* 252 */ "plus_opt ::=", - /* 253 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END", - /* 254 */ "trigger_decl ::= temp TRIGGER nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", - /* 255 */ "trigger_time ::= BEFORE", - /* 256 */ "trigger_time ::= AFTER", - /* 257 */ "trigger_time ::= INSTEAD OF", - /* 258 */ "trigger_time ::=", - /* 259 */ "trigger_event ::= DELETE|INSERT", - /* 260 */ "trigger_event ::= UPDATE", - /* 261 */ "trigger_event ::= UPDATE OF inscollist", - /* 262 */ "foreach_clause ::=", - /* 263 */ "foreach_clause ::= FOR EACH ROW", - /* 264 */ "foreach_clause ::= FOR EACH STATEMENT", - /* 265 */ "when_clause ::=", - /* 266 */ "when_clause ::= WHEN expr", - /* 267 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", - /* 268 */ "trigger_cmd_list ::=", - /* 269 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt", - /* 270 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP", - /* 271 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select", - /* 272 */ "trigger_cmd ::= DELETE FROM nm where_opt", - /* 273 */ "trigger_cmd ::= select", - /* 274 */ "expr ::= RAISE LP IGNORE RP", - /* 275 */ "expr ::= RAISE LP raisetype COMMA nm RP", - /* 276 */ "raisetype ::= ROLLBACK", - /* 277 */ "raisetype ::= ABORT", - /* 278 */ "raisetype ::= FAIL", - /* 279 */ "cmd ::= DROP TRIGGER fullname", - /* 280 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", - /* 281 */ "key_opt ::=", - /* 282 */ "key_opt ::= KEY expr", - /* 283 */ "database_kw_opt ::= DATABASE", - /* 284 */ "database_kw_opt ::=", - /* 285 */ "cmd ::= DETACH database_kw_opt expr", - /* 286 */ "cmd ::= REINDEX", - /* 287 */ "cmd ::= REINDEX nm dbnm", - /* 288 */ "cmd ::= ANALYZE", - /* 289 */ "cmd ::= ANALYZE nm dbnm", - /* 290 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", - /* 291 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column", - /* 292 */ "add_column_fullname ::= fullname", - /* 293 */ "kwcolumn_opt ::=", - /* 294 */ "kwcolumn_opt ::= COLUMNKW", + /* 200 */ "likeop ::= MATCH", + /* 201 */ "likeop ::= NOT MATCH", + /* 202 */ "escape ::= ESCAPE expr", + /* 203 */ "escape ::=", + /* 204 */ "expr ::= expr likeop expr escape", + /* 205 */ "expr ::= expr ISNULL|NOTNULL", + /* 206 */ "expr ::= expr IS NULL", + /* 207 */ "expr ::= expr NOT NULL", + /* 208 */ "expr ::= expr IS NOT NULL", + /* 209 */ "expr ::= NOT|BITNOT expr", + /* 210 */ "expr ::= MINUS expr", + /* 211 */ "expr ::= PLUS expr", + /* 212 */ "between_op ::= BETWEEN", + /* 213 */ "between_op ::= NOT BETWEEN", + /* 214 */ "expr ::= expr between_op expr AND expr", + /* 215 */ "in_op ::= IN", + /* 216 */ "in_op ::= NOT IN", + /* 217 */ "expr ::= expr in_op LP exprlist RP", + /* 218 */ "expr ::= LP select RP", + /* 219 */ "expr ::= expr in_op LP select RP", + /* 220 */ "expr ::= expr in_op nm dbnm", + /* 221 */ "expr ::= EXISTS LP select RP", + /* 222 */ "expr ::= CASE case_operand case_exprlist case_else END", + /* 223 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", + /* 224 */ "case_exprlist ::= WHEN expr THEN expr", + /* 225 */ "case_else ::= ELSE expr", + /* 226 */ "case_else ::=", + /* 227 */ "case_operand ::= expr", + /* 228 */ "case_operand ::=", + /* 229 */ "exprlist ::= exprlist COMMA expritem", + /* 230 */ "exprlist ::= expritem", + /* 231 */ "expritem ::= expr", + /* 232 */ "expritem ::=", + /* 233 */ "cmd ::= CREATE uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP", + /* 234 */ "uniqueflag ::= UNIQUE", + /* 235 */ "uniqueflag ::=", + /* 236 */ "idxlist_opt ::=", + /* 237 */ "idxlist_opt ::= LP idxlist RP", + /* 238 */ "idxlist ::= idxlist COMMA idxitem collate sortorder", + /* 239 */ "idxlist ::= idxitem collate sortorder", + /* 240 */ "idxitem ::= nm", + /* 241 */ "collate ::=", + /* 242 */ "collate ::= COLLATE id", + /* 243 */ "cmd ::= DROP INDEX ifexists fullname", + /* 244 */ "cmd ::= VACUUM", + /* 245 */ "cmd ::= VACUUM nm", + /* 246 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", + /* 247 */ "cmd ::= PRAGMA nm dbnm EQ ON", + /* 248 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", + /* 249 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", + /* 250 */ "cmd ::= PRAGMA nm dbnm", + /* 251 */ "nmnum ::= plus_num", + /* 252 */ "nmnum ::= nm", + /* 253 */ "plus_num ::= plus_opt number", + /* 254 */ "minus_num ::= MINUS number", + /* 255 */ "number ::= INTEGER|FLOAT", + /* 256 */ "plus_opt ::= PLUS", + /* 257 */ "plus_opt ::=", + /* 258 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END", + /* 259 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", + /* 260 */ "trigger_time ::= BEFORE", + /* 261 */ "trigger_time ::= AFTER", + /* 262 */ "trigger_time ::= INSTEAD OF", + /* 263 */ "trigger_time ::=", + /* 264 */ "trigger_event ::= DELETE|INSERT", + /* 265 */ "trigger_event ::= UPDATE", + /* 266 */ "trigger_event ::= UPDATE OF inscollist", + /* 267 */ "foreach_clause ::=", + /* 268 */ "foreach_clause ::= FOR EACH ROW", + /* 269 */ "foreach_clause ::= FOR EACH STATEMENT", + /* 270 */ "when_clause ::=", + /* 271 */ "when_clause ::= WHEN expr", + /* 272 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", + /* 273 */ "trigger_cmd_list ::=", + /* 274 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt", + /* 275 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP", + /* 276 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select", + /* 277 */ "trigger_cmd ::= DELETE FROM nm where_opt", + /* 278 */ "trigger_cmd ::= select", + /* 279 */ "expr ::= RAISE LP IGNORE RP", + /* 280 */ "expr ::= RAISE LP raisetype COMMA nm RP", + /* 281 */ "raisetype ::= ROLLBACK", + /* 282 */ "raisetype ::= ABORT", + /* 283 */ "raisetype ::= FAIL", + /* 284 */ "cmd ::= DROP TRIGGER ifexists fullname", + /* 285 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", + /* 286 */ "key_opt ::=", + /* 287 */ "key_opt ::= KEY expr", + /* 288 */ "database_kw_opt ::= DATABASE", + /* 289 */ "database_kw_opt ::=", + /* 290 */ "cmd ::= DETACH database_kw_opt expr", + /* 291 */ "cmd ::= REINDEX", + /* 292 */ "cmd ::= REINDEX nm dbnm", + /* 293 */ "cmd ::= ANALYZE", + /* 294 */ "cmd ::= ANALYZE nm dbnm", + /* 295 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", + /* 296 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column", + /* 297 */ "add_column_fullname ::= fullname", + /* 298 */ "kwcolumn_opt ::=", + /* 299 */ "kwcolumn_opt ::= COLUMNKW", + /* 300 */ "cmd ::= create_vtab", + /* 301 */ "cmd ::= create_vtab LP vtabarglist RP", + /* 302 */ "create_vtab ::= CREATE VIRTUAL TABLE nm dbnm USING nm", + /* 303 */ "vtabarglist ::= vtabarg", + /* 304 */ "vtabarglist ::= vtabarglist COMMA vtabarg", + /* 305 */ "vtabarg ::=", + /* 306 */ "vtabarg ::= vtabarg vtabargtoken", + /* 307 */ "vtabargtoken ::= ANY", + /* 308 */ "vtabargtoken ::= lp anylist RP", + /* 309 */ "lp ::= LP", + /* 310 */ "anylist ::=", + /* 311 */ "anylist ::= anylist ANY", }; #endif /* NDEBUG */ @@ -1205,81 +1247,81 @@ static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){ ** which appear on the RHS of the rule, but which are not used ** inside the C code. */ - case 154: - case 188: - case 205: -#line 371 "parse.y" -{sqlite3SelectDelete((yypminor->yy239));} -#line 1215 "parse.c" + case 156: + case 190: + case 207: +#line 375 "parse.y" +{sqlite3SelectDelete((yypminor->yy43));} +#line 1257 "parse.c" break; - case 168: - case 169: - case 193: + case 170: + case 171: case 195: - case 203: - case 209: - case 217: - case 220: - case 222: + case 197: + case 205: + case 211: + case 218: + case 221: case 223: - case 233: -#line 628 "parse.y" -{sqlite3ExprDelete((yypminor->yy178));} -#line 1230 "parse.c" + case 224: + case 236: +#line 616 "parse.y" +{sqlite3ExprDelete((yypminor->yy450));} +#line 1272 "parse.c" break; - case 173: - case 181: - case 191: - case 194: + case 175: + case 183: + case 193: case 196: case 198: - case 208: - case 211: - case 212: - case 215: - case 221: -#line 859 "parse.y" -{sqlite3ExprListDelete((yypminor->yy462));} -#line 1245 "parse.c" - break; - case 187: - case 192: case 200: - case 201: -#line 499 "parse.y" -{sqlite3SrcListDelete((yypminor->yy285));} -#line 1253 "parse.c" + case 210: + case 212: + case 213: + case 216: + case 222: +#line 856 "parse.y" +{sqlite3ExprListDelete((yypminor->yy242));} +#line 1287 "parse.c" break; - case 197: -#line 560 "parse.y" + case 189: + case 194: + case 202: + case 203: +#line 488 "parse.y" +{sqlite3SrcListDelete((yypminor->yy419));} +#line 1295 "parse.c" + break; + case 199: +#line 546 "parse.y" { - sqlite3ExprDelete((yypminor->yy270).pLimit); - sqlite3ExprDelete((yypminor->yy270).pOffset); + sqlite3ExprDelete((yypminor->yy84).pLimit); + sqlite3ExprDelete((yypminor->yy84).pOffset); } -#line 1261 "parse.c" +#line 1303 "parse.c" break; - case 204: - case 207: - case 214: -#line 516 "parse.y" -{sqlite3IdListDelete((yypminor->yy160));} -#line 1268 "parse.c" + case 206: + case 209: + case 215: +#line 505 "parse.y" +{sqlite3IdListDelete((yypminor->yy352));} +#line 1310 "parse.c" + break; + case 232: + case 237: +#line 957 "parse.y" +{sqlite3DeleteTriggerStep((yypminor->yy75));} +#line 1316 "parse.c" break; - case 229: case 234: -#line 953 "parse.y" -{sqlite3DeleteTriggerStep((yypminor->yy247));} -#line 1274 "parse.c" +#line 941 "parse.y" +{sqlite3IdListDelete((yypminor->yy354).b);} +#line 1321 "parse.c" break; - case 231: -#line 937 "parse.y" -{sqlite3IdListDelete((yypminor->yy132).b);} -#line 1279 "parse.c" - break; - case 236: -#line 1021 "parse.y" -{sqlite3ExprDelete((yypminor->yy292));} -#line 1284 "parse.c" + case 239: +#line 1025 "parse.y" +{sqlite3ExprDelete((yypminor->yy158));} +#line 1326 "parse.c" break; default: break; /* If no destructor action specified: do nothing */ } @@ -1343,7 +1385,7 @@ void sqlite3ParserFree( */ static int yy_find_shift_action( yyParser *pParser, /* The parser */ - int iLookAhead /* The look-ahead token */ + YYCODETYPE iLookAhead /* The look-ahead token */ ){ int i; int stateno = pParser->yystack[pParser->yyidx].stateno; @@ -1356,19 +1398,35 @@ static int yy_find_shift_action( } i += iLookAhead; if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ + if( iLookAhead>0 ){ #ifdef YYFALLBACK - int iFallback; /* Fallback token */ - if( iLookAhead %s\n", - yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); + if( yyTraceFILE ){ + fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n", + yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); + } +#endif + return yy_find_shift_action(pParser, iFallback); } #endif - return yy_find_shift_action(pParser, iFallback); +#ifdef YYWILDCARD + { + int j = i - iLookAhead + YYWILDCARD; + if( j>=0 && j %s\n", + yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]); + } +#endif /* NDEBUG */ + return yy_action[j]; + } + } +#endif /* YYWILDCARD */ } -#endif return yy_default[stateno]; }else{ return yy_action[i]; @@ -1385,7 +1443,7 @@ static int yy_find_shift_action( */ static int yy_find_reduce_action( int stateno, /* Current state number */ - int iLookAhead /* The look-ahead token */ + YYCODETYPE iLookAhead /* The look-ahead token */ ){ int i; /* int stateno = pParser->yystack[pParser->yyidx].stateno; */ @@ -1427,10 +1485,11 @@ static void yy_shift( while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); /* Here code is inserted which will execute if the parser ** stack every overflows */ -#line 43 "parse.y" +#line 44 "parse.y" sqlite3ErrorMsg(pParse, "parser stack overflow"); -#line 1436 "parse.c" + pParse->parseError = 1; +#line 1495 "parse.c" sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument var */ return; } @@ -1457,301 +1516,318 @@ static const struct { YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ unsigned char nrhs; /* Number of right-hand side symbols in the rule */ } yyRuleInfo[] = { - { 138, 1 }, - { 139, 2 }, - { 139, 1 }, - { 141, 1 }, { 140, 1 }, - { 140, 3 }, - { 143, 0 }, + { 141, 2 }, + { 141, 1 }, { 143, 1 }, - { 143, 3 }, + { 142, 1 }, { 142, 3 }, { 145, 0 }, { 145, 1 }, - { 145, 2 }, - { 144, 0 }, - { 144, 1 }, - { 144, 1 }, - { 144, 1 }, - { 142, 2 }, - { 142, 2 }, - { 142, 2 }, - { 142, 2 }, - { 147, 6 }, - { 150, 0 }, - { 150, 3 }, - { 149, 1 }, - { 149, 0 }, - { 148, 4 }, - { 148, 2 }, + { 145, 3 }, + { 144, 3 }, + { 147, 0 }, + { 147, 1 }, + { 147, 2 }, + { 146, 0 }, + { 146, 1 }, + { 146, 1 }, + { 146, 1 }, + { 144, 2 }, + { 144, 2 }, + { 144, 2 }, + { 144, 2 }, + { 149, 6 }, + { 152, 0 }, { 152, 3 }, - { 152, 1 }, - { 155, 3 }, - { 156, 1 }, - { 159, 1 }, - { 160, 1 }, - { 146, 1 }, - { 146, 1 }, - { 146, 1 }, - { 157, 0 }, - { 157, 1 }, + { 151, 1 }, + { 151, 0 }, + { 150, 4 }, + { 150, 2 }, + { 154, 3 }, + { 154, 1 }, + { 157, 3 }, + { 158, 1 }, { 161, 1 }, - { 161, 4 }, - { 161, 6 }, { 162, 1 }, - { 162, 2 }, + { 148, 1 }, + { 148, 1 }, + { 148, 1 }, + { 159, 0 }, + { 159, 1 }, { 163, 1 }, - { 163, 1 }, - { 158, 2 }, - { 158, 0 }, - { 166, 3 }, - { 166, 1 }, - { 166, 2 }, - { 166, 4 }, - { 166, 3 }, - { 166, 3 }, - { 166, 2 }, - { 167, 2 }, - { 167, 3 }, - { 167, 5 }, - { 167, 2 }, - { 167, 4 }, - { 167, 4 }, - { 167, 1 }, - { 167, 2 }, - { 172, 0 }, - { 172, 1 }, + { 163, 4 }, + { 163, 6 }, + { 164, 1 }, + { 164, 2 }, + { 165, 1 }, + { 165, 1 }, + { 160, 2 }, + { 160, 0 }, + { 168, 3 }, + { 168, 1 }, + { 169, 2 }, + { 169, 4 }, + { 169, 3 }, + { 169, 3 }, + { 169, 2 }, + { 169, 2 }, + { 169, 3 }, + { 169, 5 }, + { 169, 2 }, + { 169, 4 }, + { 169, 4 }, + { 169, 1 }, + { 169, 2 }, { 174, 0 }, - { 174, 2 }, + { 174, 1 }, + { 176, 0 }, { 176, 2 }, - { 176, 3 }, - { 176, 3 }, - { 176, 3 }, - { 177, 2 }, - { 177, 2 }, - { 177, 1 }, - { 177, 1 }, - { 175, 3 }, - { 175, 2 }, - { 178, 0 }, { 178, 2 }, - { 178, 2 }, - { 153, 0 }, - { 153, 2 }, - { 179, 3 }, + { 178, 3 }, + { 178, 3 }, + { 178, 3 }, + { 179, 2 }, { 179, 2 }, { 179, 1 }, + { 179, 1 }, + { 177, 3 }, + { 177, 2 }, + { 180, 0 }, { 180, 2 }, - { 180, 7 }, - { 180, 5 }, - { 180, 5 }, - { 180, 10 }, - { 182, 0 }, - { 182, 1 }, - { 170, 0 }, - { 170, 3 }, - { 183, 0 }, - { 183, 2 }, + { 180, 2 }, + { 155, 0 }, + { 155, 2 }, + { 181, 3 }, + { 181, 2 }, + { 181, 1 }, + { 182, 2 }, + { 182, 7 }, + { 182, 5 }, + { 182, 5 }, + { 182, 10 }, + { 184, 0 }, { 184, 1 }, - { 184, 1 }, - { 184, 1 }, - { 142, 4 }, - { 186, 2 }, - { 186, 0 }, - { 142, 7 }, - { 142, 4 }, - { 142, 1 }, - { 154, 1 }, - { 154, 3 }, - { 189, 1 }, - { 189, 2 }, - { 189, 1 }, - { 188, 9 }, - { 190, 1 }, - { 190, 1 }, - { 190, 0 }, - { 198, 2 }, - { 198, 0 }, - { 191, 3 }, + { 172, 0 }, + { 172, 3 }, + { 185, 0 }, + { 185, 2 }, + { 186, 1 }, + { 186, 1 }, + { 186, 1 }, + { 144, 4 }, + { 188, 2 }, + { 188, 0 }, + { 144, 8 }, + { 144, 4 }, + { 144, 1 }, + { 156, 1 }, + { 156, 3 }, + { 191, 1 }, { 191, 2 }, - { 191, 4 }, - { 199, 2 }, - { 199, 1 }, - { 199, 0 }, + { 191, 1 }, + { 190, 9 }, + { 192, 1 }, + { 192, 1 }, { 192, 0 }, - { 192, 2 }, + { 200, 2 }, + { 200, 0 }, + { 193, 3 }, + { 193, 2 }, + { 193, 4 }, { 201, 2 }, + { 201, 1 }, { 201, 0 }, - { 200, 6 }, - { 200, 7 }, - { 205, 1 }, - { 205, 1 }, - { 151, 0 }, - { 151, 2 }, - { 187, 2 }, - { 202, 1 }, - { 202, 2 }, - { 202, 3 }, - { 202, 4 }, + { 194, 0 }, + { 194, 2 }, { 203, 2 }, { 203, 0 }, + { 202, 6 }, + { 202, 7 }, + { 207, 1 }, + { 207, 1 }, + { 153, 0 }, + { 153, 2 }, + { 189, 2 }, + { 204, 1 }, + { 204, 2 }, + { 204, 3 }, { 204, 4 }, - { 204, 0 }, + { 205, 2 }, + { 205, 0 }, + { 206, 4 }, + { 206, 0 }, + { 198, 0 }, + { 198, 3 }, + { 210, 4 }, + { 210, 2 }, + { 211, 1 }, + { 173, 1 }, + { 173, 1 }, + { 173, 0 }, { 196, 0 }, { 196, 3 }, - { 208, 5 }, - { 208, 3 }, - { 209, 1 }, - { 171, 1 }, - { 171, 1 }, - { 171, 0 }, - { 210, 0 }, - { 210, 2 }, - { 194, 0 }, - { 194, 3 }, - { 195, 0 }, - { 195, 2 }, { 197, 0 }, { 197, 2 }, - { 197, 4 }, - { 197, 4 }, - { 142, 4 }, - { 193, 0 }, - { 193, 2 }, - { 142, 6 }, - { 212, 5 }, - { 212, 3 }, - { 142, 8 }, - { 142, 5 }, - { 213, 2 }, - { 213, 1 }, - { 215, 3 }, - { 215, 1 }, - { 214, 0 }, - { 214, 3 }, - { 207, 3 }, - { 207, 1 }, - { 169, 1 }, - { 169, 3 }, - { 168, 1 }, - { 169, 1 }, - { 169, 1 }, - { 169, 3 }, - { 169, 5 }, - { 168, 1 }, - { 168, 1 }, - { 169, 1 }, - { 169, 1 }, - { 169, 6 }, - { 169, 5 }, - { 169, 4 }, - { 168, 1 }, - { 169, 3 }, - { 169, 3 }, - { 169, 3 }, - { 169, 3 }, - { 169, 3 }, - { 169, 3 }, - { 169, 3 }, - { 169, 3 }, + { 199, 0 }, + { 199, 2 }, + { 199, 4 }, + { 199, 4 }, + { 144, 4 }, + { 195, 0 }, + { 195, 2 }, + { 144, 6 }, + { 213, 5 }, + { 213, 3 }, + { 144, 8 }, + { 144, 5 }, + { 144, 6 }, + { 214, 2 }, + { 214, 1 }, + { 216, 3 }, { 216, 1 }, - { 216, 2 }, + { 215, 0 }, + { 215, 3 }, + { 209, 3 }, + { 209, 1 }, + { 171, 1 }, + { 171, 3 }, + { 170, 1 }, + { 171, 1 }, + { 171, 1 }, + { 171, 3 }, + { 171, 5 }, + { 170, 1 }, + { 170, 1 }, + { 171, 1 }, + { 171, 1 }, + { 171, 3 }, + { 171, 6 }, + { 171, 5 }, + { 171, 4 }, + { 170, 1 }, + { 171, 3 }, + { 171, 3 }, + { 171, 3 }, + { 171, 3 }, + { 171, 3 }, + { 171, 3 }, + { 171, 3 }, + { 171, 3 }, + { 217, 1 }, + { 217, 2 }, + { 217, 1 }, { 217, 2 }, - { 217, 0 }, - { 169, 4 }, - { 169, 2 }, - { 169, 3 }, - { 169, 3 }, - { 169, 4 }, - { 169, 2 }, - { 169, 2 }, - { 169, 2 }, - { 218, 1 }, { 218, 2 }, - { 169, 5 }, + { 218, 0 }, + { 171, 4 }, + { 171, 2 }, + { 171, 3 }, + { 171, 3 }, + { 171, 4 }, + { 171, 2 }, + { 171, 2 }, + { 171, 2 }, { 219, 1 }, { 219, 2 }, - { 169, 5 }, - { 169, 3 }, - { 169, 5 }, - { 169, 4 }, - { 169, 4 }, - { 169, 5 }, - { 221, 5 }, - { 221, 4 }, - { 222, 2 }, - { 222, 0 }, + { 171, 5 }, { 220, 1 }, - { 220, 0 }, - { 211, 3 }, - { 211, 1 }, - { 223, 1 }, + { 220, 2 }, + { 171, 5 }, + { 171, 3 }, + { 171, 5 }, + { 171, 4 }, + { 171, 4 }, + { 171, 5 }, + { 222, 5 }, + { 222, 4 }, + { 223, 2 }, { 223, 0 }, - { 142, 11 }, + { 221, 1 }, + { 221, 0 }, + { 212, 3 }, + { 212, 1 }, { 224, 1 }, { 224, 0 }, - { 173, 0 }, - { 173, 3 }, - { 181, 5 }, - { 181, 3 }, + { 144, 11 }, { 225, 1 }, - { 142, 4 }, - { 142, 1 }, - { 142, 2 }, - { 142, 5 }, - { 142, 5 }, - { 142, 5 }, - { 142, 5 }, - { 142, 6 }, - { 142, 3 }, - { 164, 2 }, - { 165, 2 }, - { 227, 1 }, + { 225, 0 }, + { 175, 0 }, + { 175, 3 }, + { 183, 5 }, + { 183, 3 }, { 226, 1 }, - { 226, 0 }, - { 142, 5 }, - { 228, 10 }, + { 227, 0 }, + { 227, 2 }, + { 144, 4 }, + { 144, 1 }, + { 144, 2 }, + { 144, 5 }, + { 144, 5 }, + { 144, 5 }, + { 144, 6 }, + { 144, 3 }, + { 228, 1 }, + { 228, 1 }, + { 166, 2 }, + { 167, 2 }, { 230, 1 }, - { 230, 1 }, - { 230, 2 }, - { 230, 0 }, - { 231, 1 }, - { 231, 1 }, - { 231, 3 }, - { 232, 0 }, - { 232, 3 }, - { 232, 3 }, - { 233, 0 }, - { 233, 2 }, - { 229, 3 }, + { 229, 1 }, { 229, 0 }, - { 234, 6 }, - { 234, 8 }, - { 234, 5 }, - { 234, 4 }, + { 144, 5 }, + { 231, 11 }, + { 233, 1 }, + { 233, 1 }, + { 233, 2 }, + { 233, 0 }, { 234, 1 }, - { 169, 4 }, - { 169, 6 }, - { 185, 1 }, - { 185, 1 }, - { 185, 1 }, - { 142, 3 }, - { 142, 6 }, + { 234, 1 }, + { 234, 3 }, + { 235, 0 }, + { 235, 3 }, + { 235, 3 }, { 236, 0 }, { 236, 2 }, - { 235, 1 }, - { 235, 0 }, - { 142, 3 }, - { 142, 1 }, - { 142, 3 }, - { 142, 1 }, - { 142, 3 }, - { 142, 6 }, - { 142, 6 }, + { 232, 3 }, + { 232, 0 }, + { 237, 6 }, + { 237, 8 }, + { 237, 5 }, + { 237, 4 }, { 237, 1 }, - { 238, 0 }, + { 171, 4 }, + { 171, 6 }, + { 187, 1 }, + { 187, 1 }, + { 187, 1 }, + { 144, 4 }, + { 144, 6 }, + { 239, 0 }, + { 239, 2 }, { 238, 1 }, + { 238, 0 }, + { 144, 3 }, + { 144, 1 }, + { 144, 3 }, + { 144, 1 }, + { 144, 3 }, + { 144, 6 }, + { 144, 6 }, + { 240, 1 }, + { 241, 0 }, + { 241, 1 }, + { 144, 1 }, + { 144, 4 }, + { 242, 7 }, + { 243, 1 }, + { 243, 3 }, + { 244, 0 }, + { 244, 2 }, + { 245, 1 }, + { 245, 3 }, + { 246, 1 }, + { 247, 0 }, + { 247, 2 }, }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -1773,13 +1849,12 @@ static void yy_reduce( yymsp = &yypParser->yystack[yypParser->yyidx]; #ifndef NDEBUG if( yyTraceFILE && yyruleno>=0 - && yyrulenosLastToken.z-yymsp[-2].minor.yy384.z) + pParse->sLastToken.n; + yygotominor.yy178.z = yymsp[-2].minor.yy178.z; + yygotominor.yy178.n = (pParse->sLastToken.z-yymsp[-2].minor.yy178.z) + pParse->sLastToken.n; } -#line 1911 "parse.c" +#line 1992 "parse.c" break; case 31: -#line 156 "parse.y" +#line 158 "parse.y" { - sqlite3AddColumn(pParse,&yymsp[0].minor.yy384); - yygotominor.yy384 = yymsp[0].minor.yy384; + sqlite3AddColumn(pParse,&yymsp[0].minor.yy178); + yygotominor.yy178 = yymsp[0].minor.yy178; } -#line 1919 "parse.c" +#line 2000 "parse.c" break; case 32: case 33: case 34: case 35: case 36: - case 250: -#line 166 "parse.y" -{yygotominor.yy384 = yymsp[0].minor.yy0;} -#line 1929 "parse.c" + case 255: +#line 168 "parse.y" +{yygotominor.yy178 = yymsp[0].minor.yy0;} +#line 2010 "parse.c" break; case 38: -#line 225 "parse.y" -{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy384);} -#line 1934 "parse.c" +#line 229 "parse.y" +{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy178);} +#line 2015 "parse.c" break; case 39: case 42: case 119: case 120: case 131: - case 150: - case 238: - case 248: - case 249: -#line 226 "parse.y" -{yygotominor.yy384 = yymsp[0].minor.yy384;} -#line 1947 "parse.c" + case 240: + case 242: + case 251: + case 252: + case 253: + case 254: +#line 230 "parse.y" +{yygotominor.yy178 = yymsp[0].minor.yy178;} +#line 2030 "parse.c" break; case 40: -#line 227 "parse.y" -{ - yygotominor.yy384.z = yymsp[-3].minor.yy384.z; - yygotominor.yy384.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy384.z; -} -#line 1955 "parse.c" - break; - case 41: #line 231 "parse.y" { - yygotominor.yy384.z = yymsp[-5].minor.yy384.z; - yygotominor.yy384.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy384.z; + yygotominor.yy178.z = yymsp[-3].minor.yy178.z; + yygotominor.yy178.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy178.z; } -#line 1963 "parse.c" +#line 2038 "parse.c" + break; + case 41: +#line 235 "parse.y" +{ + yygotominor.yy178.z = yymsp[-5].minor.yy178.z; + yygotominor.yy178.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy178.z; +} +#line 2046 "parse.c" break; case 43: -#line 237 "parse.y" -{yygotominor.yy384.z=yymsp[-1].minor.yy384.z; yygotominor.yy384.n=yymsp[0].minor.yy384.n+(yymsp[0].minor.yy384.z-yymsp[-1].minor.yy384.z);} -#line 1968 "parse.c" +#line 241 "parse.y" +{yygotominor.yy178.z=yymsp[-1].minor.yy178.z; yygotominor.yy178.n=yymsp[0].minor.yy178.n+(yymsp[0].minor.yy178.z-yymsp[-1].minor.yy178.z);} +#line 2051 "parse.c" break; case 44: -#line 239 "parse.y" -{ yygotominor.yy230 = atoi((char*)yymsp[0].minor.yy384.z); } -#line 1973 "parse.c" +#line 243 "parse.y" +{ yygotominor.yy316 = atoi((char*)yymsp[0].minor.yy178.z); } +#line 2056 "parse.c" break; case 45: -#line 240 "parse.y" -{ yygotominor.yy230 = -atoi((char*)yymsp[0].minor.yy384.z); } -#line 1978 "parse.c" +#line 244 "parse.y" +{ yygotominor.yy316 = -atoi((char*)yymsp[0].minor.yy178.z); } +#line 2061 "parse.c" break; case 50: case 52: -#line 249 "parse.y" -{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy178);} -#line 1984 "parse.c" +#line 253 "parse.y" +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy450);} +#line 2067 "parse.c" break; case 51: -#line 250 "parse.y" -{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy178);} -#line 1989 "parse.c" +#line 254 "parse.y" +{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy450);} +#line 2072 "parse.c" break; case 53: -#line 252 "parse.y" -{ - Expr *p = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy178, 0, 0); - sqlite3AddDefaultValue(pParse,p); -} -#line 1997 "parse.c" - break; - case 54: #line 256 "parse.y" { - Expr *p = sqlite3Expr(TK_STRING, 0, 0, &yymsp[0].minor.yy384); + Expr *p = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy450, 0, 0); sqlite3AddDefaultValue(pParse,p); } -#line 2005 "parse.c" - break; - case 56: -#line 265 "parse.y" -{sqlite3AddNotNull(pParse, yymsp[0].minor.yy230);} -#line 2010 "parse.c" - break; - case 57: -#line 267 "parse.y" -{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy230,yymsp[0].minor.yy230,yymsp[-2].minor.yy230);} -#line 2015 "parse.c" - break; - case 58: -#line 268 "parse.y" -{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy230,0,0,0,0);} -#line 2020 "parse.c" - break; - case 59: -#line 269 "parse.y" -{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy178);} -#line 2025 "parse.c" - break; - case 60: -#line 271 "parse.y" -{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy384,yymsp[-1].minor.yy462,yymsp[0].minor.yy230);} -#line 2030 "parse.c" - break; - case 61: -#line 272 "parse.y" -{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy230);} -#line 2035 "parse.c" - break; - case 62: -#line 273 "parse.y" -{sqlite3AddCollateType(pParse, (char*)yymsp[0].minor.yy384.z, yymsp[0].minor.yy384.n);} -#line 2040 "parse.c" - break; - case 65: -#line 286 "parse.y" -{ yygotominor.yy230 = OE_Restrict * 0x010101; } -#line 2045 "parse.c" - break; - case 66: -#line 287 "parse.y" -{ yygotominor.yy230 = (yymsp[-1].minor.yy230 & yymsp[0].minor.yy13.mask) | yymsp[0].minor.yy13.value; } -#line 2050 "parse.c" - break; - case 67: -#line 289 "parse.y" -{ yygotominor.yy13.value = 0; yygotominor.yy13.mask = 0x000000; } -#line 2055 "parse.c" - break; - case 68: -#line 290 "parse.y" -{ yygotominor.yy13.value = yymsp[0].minor.yy230; yygotominor.yy13.mask = 0x0000ff; } -#line 2060 "parse.c" - break; - case 69: -#line 291 "parse.y" -{ yygotominor.yy13.value = yymsp[0].minor.yy230<<8; yygotominor.yy13.mask = 0x00ff00; } -#line 2065 "parse.c" - break; - case 70: -#line 292 "parse.y" -{ yygotominor.yy13.value = yymsp[0].minor.yy230<<16; yygotominor.yy13.mask = 0xff0000; } -#line 2070 "parse.c" - break; - case 71: -#line 294 "parse.y" -{ yygotominor.yy230 = OE_SetNull; } -#line 2075 "parse.c" - break; - case 72: -#line 295 "parse.y" -{ yygotominor.yy230 = OE_SetDflt; } #line 2080 "parse.c" break; - case 73: + case 54: +#line 260 "parse.y" +{ + Expr *p = sqlite3Expr(TK_STRING, 0, 0, &yymsp[0].minor.yy178); + sqlite3AddDefaultValue(pParse,p); +} +#line 2088 "parse.c" + break; + case 56: +#line 269 "parse.y" +{sqlite3AddNotNull(pParse, yymsp[0].minor.yy316);} +#line 2093 "parse.c" + break; + case 57: +#line 271 "parse.y" +{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy316,yymsp[0].minor.yy316,yymsp[-2].minor.yy316);} +#line 2098 "parse.c" + break; + case 58: +#line 272 "parse.y" +{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy316,0,0,0,0);} +#line 2103 "parse.c" + break; + case 59: +#line 273 "parse.y" +{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy450);} +#line 2108 "parse.c" + break; + case 60: +#line 275 "parse.y" +{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy178,yymsp[-1].minor.yy242,yymsp[0].minor.yy316);} +#line 2113 "parse.c" + break; + case 61: +#line 276 "parse.y" +{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy316);} +#line 2118 "parse.c" + break; + case 62: +#line 277 "parse.y" +{sqlite3AddCollateType(pParse, (char*)yymsp[0].minor.yy178.z, yymsp[0].minor.yy178.n);} +#line 2123 "parse.c" + break; + case 65: +#line 290 "parse.y" +{ yygotominor.yy316 = OE_Restrict * 0x010101; } +#line 2128 "parse.c" + break; + case 66: +#line 291 "parse.y" +{ yygotominor.yy316 = (yymsp[-1].minor.yy316 & yymsp[0].minor.yy207.mask) | yymsp[0].minor.yy207.value; } +#line 2133 "parse.c" + break; + case 67: +#line 293 "parse.y" +{ yygotominor.yy207.value = 0; yygotominor.yy207.mask = 0x000000; } +#line 2138 "parse.c" + break; + case 68: +#line 294 "parse.y" +{ yygotominor.yy207.value = yymsp[0].minor.yy316; yygotominor.yy207.mask = 0x0000ff; } +#line 2143 "parse.c" + break; + case 69: +#line 295 "parse.y" +{ yygotominor.yy207.value = yymsp[0].minor.yy316<<8; yygotominor.yy207.mask = 0x00ff00; } +#line 2148 "parse.c" + break; + case 70: #line 296 "parse.y" -{ yygotominor.yy230 = OE_Cascade; } -#line 2085 "parse.c" +{ yygotominor.yy207.value = yymsp[0].minor.yy316<<16; yygotominor.yy207.mask = 0xff0000; } +#line 2153 "parse.c" + break; + case 71: +#line 298 "parse.y" +{ yygotominor.yy316 = OE_SetNull; } +#line 2158 "parse.c" + break; + case 72: +#line 299 "parse.y" +{ yygotominor.yy316 = OE_SetDflt; } +#line 2163 "parse.c" + break; + case 73: +#line 300 "parse.y" +{ yygotominor.yy316 = OE_Cascade; } +#line 2168 "parse.c" break; case 74: -#line 297 "parse.y" -{ yygotominor.yy230 = OE_Restrict; } -#line 2090 "parse.c" +#line 301 "parse.y" +{ yygotominor.yy316 = OE_Restrict; } +#line 2173 "parse.c" break; case 75: case 76: @@ -2092,488 +2175,483 @@ static void yy_reduce( case 93: case 95: case 96: - case 167: -#line 299 "parse.y" -{yygotominor.yy230 = yymsp[0].minor.yy230;} -#line 2101 "parse.c" + case 166: +#line 303 "parse.y" +{yygotominor.yy316 = yymsp[0].minor.yy316;} +#line 2184 "parse.c" break; case 80: -#line 309 "parse.y" -{yygotominor.yy384.n = 0; yygotominor.yy384.z = 0;} -#line 2106 "parse.c" +#line 313 "parse.y" +{yygotominor.yy178.n = 0; yygotominor.yy178.z = 0;} +#line 2189 "parse.c" break; case 81: -#line 310 "parse.y" -{yygotominor.yy384 = yymsp[-1].minor.yy0;} -#line 2111 "parse.c" +#line 314 "parse.y" +{yygotominor.yy178 = yymsp[-1].minor.yy0;} +#line 2194 "parse.c" break; case 86: -#line 316 "parse.y" -{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy462,yymsp[0].minor.yy230,yymsp[-2].minor.yy230,0);} -#line 2116 "parse.c" +#line 320 "parse.y" +{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy242,yymsp[0].minor.yy316,yymsp[-2].minor.yy316,0);} +#line 2199 "parse.c" break; case 87: -#line 318 "parse.y" -{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy462,yymsp[0].minor.yy230,0,0,0,0);} -#line 2121 "parse.c" +#line 322 "parse.y" +{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy242,yymsp[0].minor.yy316,0,0,0,0);} +#line 2204 "parse.c" break; case 88: -#line 319 "parse.y" -{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy178);} -#line 2126 "parse.c" +#line 323 "parse.y" +{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy450);} +#line 2209 "parse.c" break; case 89: -#line 321 "parse.y" +#line 325 "parse.y" { - sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy462, &yymsp[-3].minor.yy384, yymsp[-2].minor.yy462, yymsp[-1].minor.yy230); - sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy230); + sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy242, &yymsp[-3].minor.yy178, yymsp[-2].minor.yy242, yymsp[-1].minor.yy316); + sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy316); } -#line 2134 "parse.c" +#line 2217 "parse.c" break; case 92: case 94: -#line 335 "parse.y" -{yygotominor.yy230 = OE_Default;} -#line 2140 "parse.c" +#line 339 "parse.y" +{yygotominor.yy316 = OE_Default;} +#line 2223 "parse.c" break; case 97: -#line 340 "parse.y" -{yygotominor.yy230 = OE_Ignore;} -#line 2145 "parse.c" +#line 344 "parse.y" +{yygotominor.yy316 = OE_Ignore;} +#line 2228 "parse.c" break; case 98: - case 168: -#line 341 "parse.y" -{yygotominor.yy230 = OE_Replace;} -#line 2151 "parse.c" + case 167: +#line 345 "parse.y" +{yygotominor.yy316 = OE_Replace;} +#line 2234 "parse.c" break; case 99: -#line 345 "parse.y" +#line 349 "parse.y" { - sqlite3DropTable(pParse, yymsp[0].minor.yy285, 0, yymsp[-1].minor.yy230); + sqlite3DropTable(pParse, yymsp[0].minor.yy419, 0, yymsp[-1].minor.yy316); } -#line 2158 "parse.c" +#line 2241 "parse.c" break; case 102: -#line 355 "parse.y" +#line 359 "parse.y" { - sqlite3CreateView(pParse, &yymsp[-6].minor.yy0, &yymsp[-3].minor.yy384, &yymsp[-2].minor.yy384, yymsp[0].minor.yy239, yymsp[-5].minor.yy230); + sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy178, &yymsp[-2].minor.yy178, yymsp[0].minor.yy43, yymsp[-6].minor.yy316, yymsp[-4].minor.yy316); } -#line 2165 "parse.c" +#line 2248 "parse.c" break; case 103: -#line 358 "parse.y" +#line 362 "parse.y" { - sqlite3DropTable(pParse, yymsp[0].minor.yy285, 1, yymsp[-1].minor.yy230); + sqlite3DropTable(pParse, yymsp[0].minor.yy419, 1, yymsp[-1].minor.yy316); } -#line 2172 "parse.c" +#line 2255 "parse.c" break; case 104: -#line 365 "parse.y" +#line 369 "parse.y" { - sqlite3Select(pParse, yymsp[0].minor.yy239, SRT_Callback, 0, 0, 0, 0, 0); - sqlite3SelectDelete(yymsp[0].minor.yy239); + sqlite3Select(pParse, yymsp[0].minor.yy43, SRT_Callback, 0, 0, 0, 0, 0); + sqlite3SelectDelete(yymsp[0].minor.yy43); } -#line 2180 "parse.c" +#line 2263 "parse.c" break; case 105: case 128: -#line 375 "parse.y" -{yygotominor.yy239 = yymsp[0].minor.yy239;} -#line 2186 "parse.c" +#line 379 "parse.y" +{yygotominor.yy43 = yymsp[0].minor.yy43;} +#line 2269 "parse.c" break; case 106: -#line 377 "parse.y" +#line 381 "parse.y" { - if( yymsp[0].minor.yy239 ){ - yymsp[0].minor.yy239->op = yymsp[-1].minor.yy230; - yymsp[0].minor.yy239->pPrior = yymsp[-2].minor.yy239; + if( yymsp[0].minor.yy43 ){ + yymsp[0].minor.yy43->op = yymsp[-1].minor.yy316; + yymsp[0].minor.yy43->pPrior = yymsp[-2].minor.yy43; } - yygotominor.yy239 = yymsp[0].minor.yy239; + yygotominor.yy43 = yymsp[0].minor.yy43; } -#line 2197 "parse.c" +#line 2280 "parse.c" break; case 108: -#line 386 "parse.y" -{yygotominor.yy230 = TK_ALL;} -#line 2202 "parse.c" +#line 390 "parse.y" +{yygotominor.yy316 = TK_ALL;} +#line 2285 "parse.c" break; case 110: -#line 390 "parse.y" +#line 394 "parse.y" { - yygotominor.yy239 = sqlite3SelectNew(yymsp[-6].minor.yy462,yymsp[-5].minor.yy285,yymsp[-4].minor.yy178,yymsp[-3].minor.yy462,yymsp[-2].minor.yy178,yymsp[-1].minor.yy462,yymsp[-7].minor.yy230,yymsp[0].minor.yy270.pLimit,yymsp[0].minor.yy270.pOffset); + yygotominor.yy43 = sqlite3SelectNew(yymsp[-6].minor.yy242,yymsp[-5].minor.yy419,yymsp[-4].minor.yy450,yymsp[-3].minor.yy242,yymsp[-2].minor.yy450,yymsp[-1].minor.yy242,yymsp[-7].minor.yy316,yymsp[0].minor.yy84.pLimit,yymsp[0].minor.yy84.pOffset); } -#line 2209 "parse.c" +#line 2292 "parse.c" break; case 114: - case 235: -#line 411 "parse.y" -{yygotominor.yy462 = yymsp[-1].minor.yy462;} -#line 2215 "parse.c" + case 237: +#line 415 "parse.y" +{yygotominor.yy242 = yymsp[-1].minor.yy242;} +#line 2298 "parse.c" break; case 115: case 141: - case 151: - case 234: -#line 412 "parse.y" -{yygotominor.yy462 = 0;} -#line 2223 "parse.c" + case 149: + case 236: +#line 416 "parse.y" +{yygotominor.yy242 = 0;} +#line 2306 "parse.c" break; case 116: -#line 413 "parse.y" +#line 417 "parse.y" { - yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-2].minor.yy462,yymsp[-1].minor.yy178,yymsp[0].minor.yy384.n?&yymsp[0].minor.yy384:0); + yygotominor.yy242 = sqlite3ExprListAppend(yymsp[-2].minor.yy242,yymsp[-1].minor.yy450,yymsp[0].minor.yy178.n?&yymsp[0].minor.yy178:0); } -#line 2230 "parse.c" +#line 2313 "parse.c" break; case 117: -#line 416 "parse.y" +#line 420 "parse.y" { - yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-1].minor.yy462, sqlite3Expr(TK_ALL, 0, 0, 0), 0); + yygotominor.yy242 = sqlite3ExprListAppend(yymsp[-1].minor.yy242, sqlite3Expr(TK_ALL, 0, 0, 0), 0); } -#line 2237 "parse.c" +#line 2320 "parse.c" break; case 118: -#line 419 "parse.y" +#line 423 "parse.y" { Expr *pRight = sqlite3Expr(TK_ALL, 0, 0, 0); - Expr *pLeft = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy384); - yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-3].minor.yy462, sqlite3Expr(TK_DOT, pLeft, pRight, 0), 0); + Expr *pLeft = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy178); + yygotominor.yy242 = sqlite3ExprListAppend(yymsp[-3].minor.yy242, sqlite3Expr(TK_DOT, pLeft, pRight, 0), 0); } -#line 2246 "parse.c" - break; - case 121: -#line 431 "parse.y" -{yygotominor.yy384.n = 0;} -#line 2251 "parse.c" - break; - case 122: -#line 443 "parse.y" -{yygotominor.yy285 = sqliteMalloc(sizeof(*yygotominor.yy285));} -#line 2256 "parse.c" - break; - case 123: -#line 444 "parse.y" -{yygotominor.yy285 = yymsp[0].minor.yy285;} -#line 2261 "parse.c" - break; - case 124: -#line 449 "parse.y" -{ - yygotominor.yy285 = yymsp[-1].minor.yy285; - if( yygotominor.yy285 && yygotominor.yy285->nSrc>0 ) yygotominor.yy285->a[yygotominor.yy285->nSrc-1].jointype = yymsp[0].minor.yy230; -} -#line 2269 "parse.c" - break; - case 125: -#line 453 "parse.y" -{yygotominor.yy285 = 0;} -#line 2274 "parse.c" - break; - case 126: -#line 454 "parse.y" -{ - yygotominor.yy285 = sqlite3SrcListAppend(yymsp[-5].minor.yy285,&yymsp[-4].minor.yy384,&yymsp[-3].minor.yy384); - if( yymsp[-2].minor.yy384.n ) sqlite3SrcListAddAlias(yygotominor.yy285,&yymsp[-2].minor.yy384); - if( yymsp[-1].minor.yy178 ){ - if( yygotominor.yy285 && yygotominor.yy285->nSrc>1 ){ yygotominor.yy285->a[yygotominor.yy285->nSrc-2].pOn = yymsp[-1].minor.yy178; } - else { sqlite3ExprDelete(yymsp[-1].minor.yy178); } - } - if( yymsp[0].minor.yy160 ){ - if( yygotominor.yy285 && yygotominor.yy285->nSrc>1 ){ yygotominor.yy285->a[yygotominor.yy285->nSrc-2].pUsing = yymsp[0].minor.yy160; } - else { sqlite3IdListDelete(yymsp[0].minor.yy160); } - } -} -#line 2290 "parse.c" - break; - case 127: -#line 468 "parse.y" -{ - yygotominor.yy285 = sqlite3SrcListAppend(yymsp[-6].minor.yy285,0,0); - yygotominor.yy285->a[yygotominor.yy285->nSrc-1].pSelect = yymsp[-4].minor.yy239; - if( yymsp[-2].minor.yy384.n ) sqlite3SrcListAddAlias(yygotominor.yy285,&yymsp[-2].minor.yy384); - if( yymsp[-1].minor.yy178 ){ - if( yygotominor.yy285 && yygotominor.yy285->nSrc>1 ){ yygotominor.yy285->a[yygotominor.yy285->nSrc-2].pOn = yymsp[-1].minor.yy178; } - else { sqlite3ExprDelete(yymsp[-1].minor.yy178); } - } - if( yymsp[0].minor.yy160 ){ - if( yygotominor.yy285 && yygotominor.yy285->nSrc>1 ){ yygotominor.yy285->a[yygotominor.yy285->nSrc-2].pUsing = yymsp[0].minor.yy160; } - else { sqlite3IdListDelete(yymsp[0].minor.yy160); } - } - } -#line 2307 "parse.c" - break; - case 129: -#line 489 "parse.y" -{ - yygotominor.yy239 = sqlite3SelectNew(0,yymsp[0].minor.yy285,0,0,0,0,0,0,0); - } -#line 2314 "parse.c" - break; - case 130: -#line 495 "parse.y" -{yygotominor.yy384.z=0; yygotominor.yy384.n=0;} -#line 2319 "parse.c" - break; - case 132: -#line 500 "parse.y" -{yygotominor.yy285 = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy384,&yymsp[0].minor.yy384);} -#line 2324 "parse.c" - break; - case 133: -#line 504 "parse.y" -{ yygotominor.yy230 = JT_INNER; } #line 2329 "parse.c" break; - case 134: -#line 505 "parse.y" -{ yygotominor.yy230 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); } + case 121: +#line 435 "parse.y" +{yygotominor.yy178.n = 0;} #line 2334 "parse.c" break; - case 135: -#line 506 "parse.y" -{ yygotominor.yy230 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy384,0); } + case 122: +#line 447 "parse.y" +{yygotominor.yy419 = sqliteMalloc(sizeof(*yygotominor.yy419));} #line 2339 "parse.c" break; + case 123: +#line 448 "parse.y" +{ + yygotominor.yy419 = yymsp[0].minor.yy419; + sqlite3SrcListShiftJoinType(yygotominor.yy419); +} +#line 2347 "parse.c" + break; + case 124: +#line 456 "parse.y" +{ + yygotominor.yy419 = yymsp[-1].minor.yy419; + if( yygotominor.yy419 && yygotominor.yy419->nSrc>0 ) yygotominor.yy419->a[yygotominor.yy419->nSrc-1].jointype = yymsp[0].minor.yy316; +} +#line 2355 "parse.c" + break; + case 125: +#line 460 "parse.y" +{yygotominor.yy419 = 0;} +#line 2360 "parse.c" + break; + case 126: +#line 461 "parse.y" +{ + yygotominor.yy419 = sqlite3SrcListAppendFromTerm(yymsp[-5].minor.yy419,&yymsp[-4].minor.yy178,&yymsp[-3].minor.yy178,&yymsp[-2].minor.yy178,0,yymsp[-1].minor.yy450,yymsp[0].minor.yy352); +} +#line 2367 "parse.c" + break; + case 127: +#line 466 "parse.y" +{ + yygotominor.yy419 = sqlite3SrcListAppendFromTerm(yymsp[-6].minor.yy419,0,0,&yymsp[-2].minor.yy178,yymsp[-4].minor.yy43,yymsp[-1].minor.yy450,yymsp[0].minor.yy352); + } +#line 2374 "parse.c" + break; + case 129: +#line 477 "parse.y" +{ + sqlite3SrcListShiftJoinType(yymsp[0].minor.yy419); + yygotominor.yy43 = sqlite3SelectNew(0,yymsp[0].minor.yy419,0,0,0,0,0,0,0); + } +#line 2382 "parse.c" + break; + case 130: +#line 484 "parse.y" +{yygotominor.yy178.z=0; yygotominor.yy178.n=0;} +#line 2387 "parse.c" + break; + case 132: +#line 489 "parse.y" +{yygotominor.yy419 = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy178,&yymsp[0].minor.yy178);} +#line 2392 "parse.c" + break; + case 133: +#line 493 "parse.y" +{ yygotominor.yy316 = JT_INNER; } +#line 2397 "parse.c" + break; + case 134: +#line 494 "parse.y" +{ yygotominor.yy316 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); } +#line 2402 "parse.c" + break; + case 135: +#line 495 "parse.y" +{ yygotominor.yy316 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy178,0); } +#line 2407 "parse.c" + break; case 136: -#line 508 "parse.y" -{ yygotominor.yy230 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy384,&yymsp[-1].minor.yy384); } -#line 2344 "parse.c" +#line 497 "parse.y" +{ yygotominor.yy316 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy178,&yymsp[-1].minor.yy178); } +#line 2412 "parse.c" break; case 137: case 145: - case 154: - case 161: - case 175: - case 200: - case 223: + case 152: + case 159: + case 174: + case 202: case 225: - case 229: -#line 512 "parse.y" -{yygotominor.yy178 = yymsp[0].minor.yy178;} -#line 2357 "parse.c" + case 227: + case 231: +#line 501 "parse.y" +{yygotominor.yy450 = yymsp[0].minor.yy450;} +#line 2425 "parse.c" break; case 138: - case 153: - case 160: - case 201: - case 224: + case 151: + case 158: + case 203: case 226: - case 230: -#line 513 "parse.y" -{yygotominor.yy178 = 0;} -#line 2368 "parse.c" + case 228: + case 232: +#line 502 "parse.y" +{yygotominor.yy450 = 0;} +#line 2436 "parse.c" break; case 139: - case 172: -#line 517 "parse.y" -{yygotominor.yy160 = yymsp[-1].minor.yy160;} -#line 2374 "parse.c" + case 171: +#line 506 "parse.y" +{yygotominor.yy352 = yymsp[-1].minor.yy352;} +#line 2442 "parse.c" break; case 140: - case 171: -#line 518 "parse.y" -{yygotominor.yy160 = 0;} -#line 2380 "parse.c" + case 170: +#line 507 "parse.y" +{yygotominor.yy352 = 0;} +#line 2448 "parse.c" break; case 142: - case 152: -#line 529 "parse.y" -{yygotominor.yy462 = yymsp[0].minor.yy462;} -#line 2386 "parse.c" + case 150: +#line 518 "parse.y" +{yygotominor.yy242 = yymsp[0].minor.yy242;} +#line 2454 "parse.c" break; case 143: -#line 530 "parse.y" +#line 519 "parse.y" { - yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-4].minor.yy462,yymsp[-2].minor.yy178,yymsp[-1].minor.yy384.n>0?&yymsp[-1].minor.yy384:0); - if( yygotominor.yy462 ) yygotominor.yy462->a[yygotominor.yy462->nExpr-1].sortOrder = yymsp[0].minor.yy230; + yygotominor.yy242 = sqlite3ExprListAppend(yymsp[-3].minor.yy242,yymsp[-1].minor.yy450,0); + if( yygotominor.yy242 ) yygotominor.yy242->a[yygotominor.yy242->nExpr-1].sortOrder = yymsp[0].minor.yy316; } -#line 2394 "parse.c" +#line 2462 "parse.c" break; case 144: -#line 534 "parse.y" +#line 523 "parse.y" { - yygotominor.yy462 = sqlite3ExprListAppend(0,yymsp[-2].minor.yy178,yymsp[-1].minor.yy384.n>0?&yymsp[-1].minor.yy384:0); - if( yygotominor.yy462 && yygotominor.yy462->a ) yygotominor.yy462->a[0].sortOrder = yymsp[0].minor.yy230; + yygotominor.yy242 = sqlite3ExprListAppend(0,yymsp[-1].minor.yy450,0); + if( yygotominor.yy242 && yygotominor.yy242->a ) yygotominor.yy242->a[0].sortOrder = yymsp[0].minor.yy316; } -#line 2402 "parse.c" +#line 2470 "parse.c" break; case 146: case 148: -#line 543 "parse.y" -{yygotominor.yy230 = SQLITE_SO_ASC;} -#line 2408 "parse.c" +#line 531 "parse.y" +{yygotominor.yy316 = SQLITE_SO_ASC;} +#line 2476 "parse.c" break; case 147: -#line 544 "parse.y" -{yygotominor.yy230 = SQLITE_SO_DESC;} -#line 2413 "parse.c" +#line 532 "parse.y" +{yygotominor.yy316 = SQLITE_SO_DESC;} +#line 2481 "parse.c" break; - case 149: -#line 546 "parse.y" -{yygotominor.yy384.z = 0; yygotominor.yy384.n = 0;} -#line 2418 "parse.c" + case 153: +#line 550 "parse.y" +{yygotominor.yy84.pLimit = 0; yygotominor.yy84.pOffset = 0;} +#line 2486 "parse.c" + break; + case 154: +#line 551 "parse.y" +{yygotominor.yy84.pLimit = yymsp[0].minor.yy450; yygotominor.yy84.pOffset = 0;} +#line 2491 "parse.c" break; case 155: -#line 564 "parse.y" -{yygotominor.yy270.pLimit = 0; yygotominor.yy270.pOffset = 0;} -#line 2423 "parse.c" +#line 553 "parse.y" +{yygotominor.yy84.pLimit = yymsp[-2].minor.yy450; yygotominor.yy84.pOffset = yymsp[0].minor.yy450;} +#line 2496 "parse.c" break; case 156: -#line 565 "parse.y" -{yygotominor.yy270.pLimit = yymsp[0].minor.yy178; yygotominor.yy270.pOffset = 0;} -#line 2428 "parse.c" +#line 555 "parse.y" +{yygotominor.yy84.pOffset = yymsp[-2].minor.yy450; yygotominor.yy84.pLimit = yymsp[0].minor.yy450;} +#line 2501 "parse.c" break; case 157: -#line 567 "parse.y" -{yygotominor.yy270.pLimit = yymsp[-2].minor.yy178; yygotominor.yy270.pOffset = yymsp[0].minor.yy178;} -#line 2433 "parse.c" +#line 559 "parse.y" +{sqlite3DeleteFrom(pParse,yymsp[-1].minor.yy419,yymsp[0].minor.yy450);} +#line 2506 "parse.c" break; - case 158: -#line 569 "parse.y" -{yygotominor.yy270.pOffset = yymsp[-2].minor.yy178; yygotominor.yy270.pLimit = yymsp[0].minor.yy178;} -#line 2438 "parse.c" + case 160: +#line 570 "parse.y" +{sqlite3Update(pParse,yymsp[-3].minor.yy419,yymsp[-1].minor.yy242,yymsp[0].minor.yy450,yymsp[-4].minor.yy316);} +#line 2511 "parse.c" break; - case 159: -#line 573 "parse.y" -{sqlite3DeleteFrom(pParse,yymsp[-1].minor.yy285,yymsp[0].minor.yy178);} -#line 2443 "parse.c" + case 161: +#line 576 "parse.y" +{yygotominor.yy242 = sqlite3ExprListAppend(yymsp[-4].minor.yy242,yymsp[0].minor.yy450,&yymsp[-2].minor.yy178);} +#line 2516 "parse.c" break; case 162: -#line 584 "parse.y" -{sqlite3Update(pParse,yymsp[-3].minor.yy285,yymsp[-1].minor.yy462,yymsp[0].minor.yy178,yymsp[-4].minor.yy230);} -#line 2448 "parse.c" +#line 577 "parse.y" +{yygotominor.yy242 = sqlite3ExprListAppend(0,yymsp[0].minor.yy450,&yymsp[-2].minor.yy178);} +#line 2521 "parse.c" break; case 163: -#line 590 "parse.y" -{yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-4].minor.yy462,yymsp[0].minor.yy178,&yymsp[-2].minor.yy384);} -#line 2453 "parse.c" +#line 583 "parse.y" +{sqlite3Insert(pParse, yymsp[-5].minor.yy419, yymsp[-1].minor.yy242, 0, yymsp[-4].minor.yy352, yymsp[-7].minor.yy316);} +#line 2526 "parse.c" break; case 164: -#line 591 "parse.y" -{yygotominor.yy462 = sqlite3ExprListAppend(0,yymsp[0].minor.yy178,&yymsp[-2].minor.yy384);} -#line 2458 "parse.c" +#line 585 "parse.y" +{sqlite3Insert(pParse, yymsp[-2].minor.yy419, 0, yymsp[0].minor.yy43, yymsp[-1].minor.yy352, yymsp[-4].minor.yy316);} +#line 2531 "parse.c" break; case 165: +#line 587 "parse.y" +{sqlite3Insert(pParse, yymsp[-3].minor.yy419, 0, 0, yymsp[-2].minor.yy352, yymsp[-5].minor.yy316);} +#line 2536 "parse.c" + break; + case 168: + case 229: #line 597 "parse.y" -{sqlite3Insert(pParse, yymsp[-5].minor.yy285, yymsp[-1].minor.yy462, 0, yymsp[-4].minor.yy160, yymsp[-7].minor.yy230);} -#line 2463 "parse.c" - break; - case 166: -#line 599 "parse.y" -{sqlite3Insert(pParse, yymsp[-2].minor.yy285, 0, yymsp[0].minor.yy239, yymsp[-1].minor.yy160, yymsp[-4].minor.yy230);} -#line 2468 "parse.c" - break; - case 169: - case 227: -#line 609 "parse.y" -{yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-2].minor.yy462,yymsp[0].minor.yy178,0);} -#line 2474 "parse.c" - break; - case 170: - case 228: -#line 610 "parse.y" -{yygotominor.yy462 = sqlite3ExprListAppend(0,yymsp[0].minor.yy178,0);} -#line 2480 "parse.c" - break; - case 173: -#line 619 "parse.y" -{yygotominor.yy160 = sqlite3IdListAppend(yymsp[-2].minor.yy160,&yymsp[0].minor.yy384);} -#line 2485 "parse.c" - break; - case 174: -#line 620 "parse.y" -{yygotominor.yy160 = sqlite3IdListAppend(0,&yymsp[0].minor.yy384);} -#line 2490 "parse.c" - break; - case 176: -#line 631 "parse.y" -{yygotominor.yy178 = yymsp[-1].minor.yy178; sqlite3ExprSpan(yygotominor.yy178,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); } -#line 2495 "parse.c" - break; - case 177: - case 182: - case 183: -#line 632 "parse.y" -{yygotominor.yy178 = sqlite3Expr(yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);} -#line 2502 "parse.c" - break; - case 178: - case 179: -#line 633 "parse.y" -{yygotominor.yy178 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy0);} -#line 2508 "parse.c" - break; - case 180: -#line 635 "parse.y" -{ - Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy384); - Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy384); - yygotominor.yy178 = sqlite3Expr(TK_DOT, temp1, temp2, 0); -} -#line 2517 "parse.c" - break; - case 181: -#line 640 "parse.y" -{ - Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-4].minor.yy384); - Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy384); - Expr *temp3 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy384); - Expr *temp4 = sqlite3Expr(TK_DOT, temp2, temp3, 0); - yygotominor.yy178 = sqlite3Expr(TK_DOT, temp1, temp4, 0); -} -#line 2528 "parse.c" - break; - case 184: -#line 649 "parse.y" -{yygotominor.yy178 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);} -#line 2533 "parse.c" - break; - case 185: -#line 650 "parse.y" -{ - Token *pToken = &yymsp[0].minor.yy0; - Expr *pExpr = yygotominor.yy178 = sqlite3Expr(TK_VARIABLE, 0, 0, pToken); - sqlite3ExprAssignVarNumber(pParse, pExpr); -} +{yygotominor.yy242 = sqlite3ExprListAppend(yymsp[-2].minor.yy242,yymsp[0].minor.yy450,0);} #line 2542 "parse.c" break; - case 186: -#line 656 "parse.y" + case 169: + case 230: +#line 598 "parse.y" +{yygotominor.yy242 = sqlite3ExprListAppend(0,yymsp[0].minor.yy450,0);} +#line 2548 "parse.c" + break; + case 172: +#line 607 "parse.y" +{yygotominor.yy352 = sqlite3IdListAppend(yymsp[-2].minor.yy352,&yymsp[0].minor.yy178);} +#line 2553 "parse.c" + break; + case 173: +#line 608 "parse.y" +{yygotominor.yy352 = sqlite3IdListAppend(0,&yymsp[0].minor.yy178);} +#line 2558 "parse.c" + break; + case 175: +#line 619 "parse.y" +{yygotominor.yy450 = yymsp[-1].minor.yy450; sqlite3ExprSpan(yygotominor.yy450,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); } +#line 2563 "parse.c" + break; + case 176: + case 181: + case 182: +#line 620 "parse.y" +{yygotominor.yy450 = sqlite3Expr(yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);} +#line 2570 "parse.c" + break; + case 177: + case 178: +#line 621 "parse.y" +{yygotominor.yy450 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy0);} +#line 2576 "parse.c" + break; + case 179: +#line 623 "parse.y" { - yygotominor.yy178 = sqlite3Expr(TK_CAST, yymsp[-3].minor.yy178, 0, &yymsp[-1].minor.yy384); - sqlite3ExprSpan(yygotominor.yy178,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); + Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy178); + Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy178); + yygotominor.yy450 = sqlite3Expr(TK_DOT, temp1, temp2, 0); } -#line 2550 "parse.c" +#line 2585 "parse.c" + break; + case 180: +#line 628 "parse.y" +{ + Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-4].minor.yy178); + Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy178); + Expr *temp3 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy178); + Expr *temp4 = sqlite3Expr(TK_DOT, temp2, temp3, 0); + yygotominor.yy450 = sqlite3Expr(TK_DOT, temp1, temp4, 0); +} +#line 2596 "parse.c" + break; + case 183: +#line 637 "parse.y" +{yygotominor.yy450 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);} +#line 2601 "parse.c" + break; + case 184: +#line 638 "parse.y" +{ + Token *pToken = &yymsp[0].minor.yy0; + Expr *pExpr = yygotominor.yy450 = sqlite3Expr(TK_VARIABLE, 0, 0, pToken); + sqlite3ExprAssignVarNumber(pParse, pExpr); +} +#line 2610 "parse.c" + break; + case 185: +#line 643 "parse.y" +{ + yygotominor.yy450 = sqlite3ExprSetColl(pParse, yymsp[-2].minor.yy450, &yymsp[0].minor.yy178); +} +#line 2617 "parse.c" + break; + case 186: +#line 647 "parse.y" +{ + yygotominor.yy450 = sqlite3Expr(TK_CAST, yymsp[-3].minor.yy450, 0, &yymsp[-1].minor.yy178); + sqlite3ExprSpan(yygotominor.yy450,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); +} +#line 2625 "parse.c" break; case 187: -#line 661 "parse.y" +#line 652 "parse.y" { - yygotominor.yy178 = sqlite3ExprFunction(yymsp[-1].minor.yy462, &yymsp[-4].minor.yy0); - sqlite3ExprSpan(yygotominor.yy178,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); - if( yymsp[-2].minor.yy230 && yygotominor.yy178 ){ - yygotominor.yy178->flags |= EP_Distinct; + yygotominor.yy450 = sqlite3ExprFunction(yymsp[-1].minor.yy242, &yymsp[-4].minor.yy0); + sqlite3ExprSpan(yygotominor.yy450,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); + if( yymsp[-2].minor.yy316 && yygotominor.yy450 ){ + yygotominor.yy450->flags |= EP_Distinct; } } -#line 2561 "parse.c" +#line 2636 "parse.c" break; case 188: -#line 668 "parse.y" +#line 659 "parse.y" { - yygotominor.yy178 = sqlite3ExprFunction(0, &yymsp[-3].minor.yy0); - sqlite3ExprSpan(yygotominor.yy178,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); + yygotominor.yy450 = sqlite3ExprFunction(0, &yymsp[-3].minor.yy0); + sqlite3ExprSpan(yygotominor.yy450,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); } -#line 2569 "parse.c" +#line 2644 "parse.c" break; case 189: -#line 672 "parse.y" +#line 663 "parse.y" { /* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are ** treated as functions that return constants */ - yygotominor.yy178 = sqlite3ExprFunction(0,&yymsp[0].minor.yy0); - if( yygotominor.yy178 ) yygotominor.yy178->op = TK_CONST_FUNC; + yygotominor.yy450 = sqlite3ExprFunction(0,&yymsp[0].minor.yy0); + if( yygotominor.yy450 ){ + yygotominor.yy450->op = TK_CONST_FUNC; + yygotominor.yy450->span = yymsp[0].minor.yy0; + } } -#line 2579 "parse.c" +#line 2657 "parse.c" break; case 190: case 191: @@ -2583,501 +2661,538 @@ static void yy_reduce( case 195: case 196: case 197: -#line 678 "parse.y" -{yygotominor.yy178 = sqlite3Expr(yymsp[-1].major, yymsp[-2].minor.yy178, yymsp[0].minor.yy178, 0);} -#line 2591 "parse.c" +#line 672 "parse.y" +{yygotominor.yy450 = sqlite3Expr(yymsp[-1].major, yymsp[-2].minor.yy450, yymsp[0].minor.yy450, 0);} +#line 2669 "parse.c" break; case 198: -#line 688 "parse.y" -{yygotominor.yy440.eOperator = yymsp[0].minor.yy0; yygotominor.yy440.not = 0;} -#line 2596 "parse.c" + case 200: +#line 682 "parse.y" +{yygotominor.yy86.eOperator = yymsp[0].minor.yy0; yygotominor.yy86.not = 0;} +#line 2675 "parse.c" break; case 199: -#line 689 "parse.y" -{yygotominor.yy440.eOperator = yymsp[0].minor.yy0; yygotominor.yy440.not = 1;} -#line 2601 "parse.c" - break; - case 202: -#line 694 "parse.y" -{ - ExprList *pList; - pList = sqlite3ExprListAppend(0, yymsp[-1].minor.yy178, 0); - pList = sqlite3ExprListAppend(pList, yymsp[-3].minor.yy178, 0); - if( yymsp[0].minor.yy178 ){ - pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy178, 0); - } - yygotominor.yy178 = sqlite3ExprFunction(pList, &yymsp[-2].minor.yy440.eOperator); - if( yymsp[-2].minor.yy440.not ) yygotominor.yy178 = sqlite3Expr(TK_NOT, yygotominor.yy178, 0, 0); - sqlite3ExprSpan(yygotominor.yy178, &yymsp[-3].minor.yy178->span, &yymsp[-1].minor.yy178->span); -} -#line 2616 "parse.c" - break; - case 203: -#line 706 "parse.y" -{ - yygotominor.yy178 = sqlite3Expr(yymsp[0].major, yymsp[-1].minor.yy178, 0, 0); - sqlite3ExprSpan(yygotominor.yy178,&yymsp[-1].minor.yy178->span,&yymsp[0].minor.yy0); -} -#line 2624 "parse.c" + case 201: +#line 683 "parse.y" +{yygotominor.yy86.eOperator = yymsp[0].minor.yy0; yygotominor.yy86.not = 1;} +#line 2681 "parse.c" break; case 204: -#line 710 "parse.y" +#line 690 "parse.y" { - yygotominor.yy178 = sqlite3Expr(TK_ISNULL, yymsp[-2].minor.yy178, 0, 0); - sqlite3ExprSpan(yygotominor.yy178,&yymsp[-2].minor.yy178->span,&yymsp[0].minor.yy0); + ExprList *pList; + pList = sqlite3ExprListAppend(0, yymsp[-1].minor.yy450, 0); + pList = sqlite3ExprListAppend(pList, yymsp[-3].minor.yy450, 0); + if( yymsp[0].minor.yy450 ){ + pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy450, 0); + } + yygotominor.yy450 = sqlite3ExprFunction(pList, &yymsp[-2].minor.yy86.eOperator); + if( yymsp[-2].minor.yy86.not ) yygotominor.yy450 = sqlite3Expr(TK_NOT, yygotominor.yy450, 0, 0); + sqlite3ExprSpan(yygotominor.yy450, &yymsp[-3].minor.yy450->span, &yymsp[-1].minor.yy450->span); + if( yygotominor.yy450 ) yygotominor.yy450->flags |= EP_InfixFunc; } -#line 2632 "parse.c" +#line 2697 "parse.c" break; case 205: -#line 714 "parse.y" +#line 703 "parse.y" { - yygotominor.yy178 = sqlite3Expr(TK_NOTNULL, yymsp[-2].minor.yy178, 0, 0); - sqlite3ExprSpan(yygotominor.yy178,&yymsp[-2].minor.yy178->span,&yymsp[0].minor.yy0); + yygotominor.yy450 = sqlite3Expr(yymsp[0].major, yymsp[-1].minor.yy450, 0, 0); + sqlite3ExprSpan(yygotominor.yy450,&yymsp[-1].minor.yy450->span,&yymsp[0].minor.yy0); } -#line 2640 "parse.c" +#line 2705 "parse.c" break; case 206: -#line 718 "parse.y" +#line 707 "parse.y" { - yygotominor.yy178 = sqlite3Expr(TK_NOTNULL, yymsp[-3].minor.yy178, 0, 0); - sqlite3ExprSpan(yygotominor.yy178,&yymsp[-3].minor.yy178->span,&yymsp[0].minor.yy0); + yygotominor.yy450 = sqlite3Expr(TK_ISNULL, yymsp[-2].minor.yy450, 0, 0); + sqlite3ExprSpan(yygotominor.yy450,&yymsp[-2].minor.yy450->span,&yymsp[0].minor.yy0); } -#line 2648 "parse.c" +#line 2713 "parse.c" break; case 207: -#line 722 "parse.y" +#line 711 "parse.y" { - yygotominor.yy178 = sqlite3Expr(yymsp[-1].major, yymsp[0].minor.yy178, 0, 0); - sqlite3ExprSpan(yygotominor.yy178,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy178->span); + yygotominor.yy450 = sqlite3Expr(TK_NOTNULL, yymsp[-2].minor.yy450, 0, 0); + sqlite3ExprSpan(yygotominor.yy450,&yymsp[-2].minor.yy450->span,&yymsp[0].minor.yy0); } -#line 2656 "parse.c" +#line 2721 "parse.c" break; case 208: -#line 726 "parse.y" +#line 715 "parse.y" { - yygotominor.yy178 = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy178, 0, 0); - sqlite3ExprSpan(yygotominor.yy178,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy178->span); + yygotominor.yy450 = sqlite3Expr(TK_NOTNULL, yymsp[-3].minor.yy450, 0, 0); + sqlite3ExprSpan(yygotominor.yy450,&yymsp[-3].minor.yy450->span,&yymsp[0].minor.yy0); } -#line 2664 "parse.c" +#line 2729 "parse.c" break; case 209: -#line 730 "parse.y" +#line 719 "parse.y" { - yygotominor.yy178 = sqlite3Expr(TK_UPLUS, yymsp[0].minor.yy178, 0, 0); - sqlite3ExprSpan(yygotominor.yy178,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy178->span); + yygotominor.yy450 = sqlite3Expr(yymsp[-1].major, yymsp[0].minor.yy450, 0, 0); + sqlite3ExprSpan(yygotominor.yy450,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy450->span); } -#line 2672 "parse.c" +#line 2737 "parse.c" break; - case 212: -#line 737 "parse.y" + case 210: +#line 723 "parse.y" { - ExprList *pList = sqlite3ExprListAppend(0, yymsp[-2].minor.yy178, 0); - pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy178, 0); - yygotominor.yy178 = sqlite3Expr(TK_BETWEEN, yymsp[-4].minor.yy178, 0, 0); - if( yygotominor.yy178 ){ - yygotominor.yy178->pList = pList; + yygotominor.yy450 = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy450, 0, 0); + sqlite3ExprSpan(yygotominor.yy450,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy450->span); +} +#line 2745 "parse.c" + break; + case 211: +#line 727 "parse.y" +{ + yygotominor.yy450 = sqlite3Expr(TK_UPLUS, yymsp[0].minor.yy450, 0, 0); + sqlite3ExprSpan(yygotominor.yy450,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy450->span); +} +#line 2753 "parse.c" + break; + case 214: +#line 734 "parse.y" +{ + ExprList *pList = sqlite3ExprListAppend(0, yymsp[-2].minor.yy450, 0); + pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy450, 0); + yygotominor.yy450 = sqlite3Expr(TK_BETWEEN, yymsp[-4].minor.yy450, 0, 0); + if( yygotominor.yy450 ){ + yygotominor.yy450->pList = pList; }else{ sqlite3ExprListDelete(pList); } - if( yymsp[-3].minor.yy230 ) yygotominor.yy178 = sqlite3Expr(TK_NOT, yygotominor.yy178, 0, 0); - sqlite3ExprSpan(yygotominor.yy178,&yymsp[-4].minor.yy178->span,&yymsp[0].minor.yy178->span); + if( yymsp[-3].minor.yy316 ) yygotominor.yy450 = sqlite3Expr(TK_NOT, yygotominor.yy450, 0, 0); + sqlite3ExprSpan(yygotominor.yy450,&yymsp[-4].minor.yy450->span,&yymsp[0].minor.yy450->span); } -#line 2688 "parse.c" - break; - case 215: -#line 753 "parse.y" -{ - yygotominor.yy178 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy178, 0, 0); - if( yygotominor.yy178 ){ - yygotominor.yy178->pList = yymsp[-1].minor.yy462; - }else{ - sqlite3ExprListDelete(yymsp[-1].minor.yy462); - } - if( yymsp[-3].minor.yy230 ) yygotominor.yy178 = sqlite3Expr(TK_NOT, yygotominor.yy178, 0, 0); - sqlite3ExprSpan(yygotominor.yy178,&yymsp[-4].minor.yy178->span,&yymsp[0].minor.yy0); - } -#line 2702 "parse.c" - break; - case 216: -#line 763 "parse.y" -{ - yygotominor.yy178 = sqlite3Expr(TK_SELECT, 0, 0, 0); - if( yygotominor.yy178 ){ - yygotominor.yy178->pSelect = yymsp[-1].minor.yy239; - }else{ - sqlite3SelectDelete(yymsp[-1].minor.yy239); - } - sqlite3ExprSpan(yygotominor.yy178,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); - } -#line 2715 "parse.c" +#line 2769 "parse.c" break; case 217: -#line 772 "parse.y" +#line 750 "parse.y" { - yygotominor.yy178 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy178, 0, 0); - if( yygotominor.yy178 ){ - yygotominor.yy178->pSelect = yymsp[-1].minor.yy239; + yygotominor.yy450 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy450, 0, 0); + if( yygotominor.yy450 ){ + yygotominor.yy450->pList = yymsp[-1].minor.yy242; }else{ - sqlite3SelectDelete(yymsp[-1].minor.yy239); + sqlite3ExprListDelete(yymsp[-1].minor.yy242); } - if( yymsp[-3].minor.yy230 ) yygotominor.yy178 = sqlite3Expr(TK_NOT, yygotominor.yy178, 0, 0); - sqlite3ExprSpan(yygotominor.yy178,&yymsp[-4].minor.yy178->span,&yymsp[0].minor.yy0); + if( yymsp[-3].minor.yy316 ) yygotominor.yy450 = sqlite3Expr(TK_NOT, yygotominor.yy450, 0, 0); + sqlite3ExprSpan(yygotominor.yy450,&yymsp[-4].minor.yy450->span,&yymsp[0].minor.yy0); } -#line 2729 "parse.c" +#line 2783 "parse.c" break; case 218: -#line 782 "parse.y" +#line 760 "parse.y" { - SrcList *pSrc = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy384,&yymsp[0].minor.yy384); - yygotominor.yy178 = sqlite3Expr(TK_IN, yymsp[-3].minor.yy178, 0, 0); - if( yygotominor.yy178 ){ - yygotominor.yy178->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,0,0); + yygotominor.yy450 = sqlite3Expr(TK_SELECT, 0, 0, 0); + if( yygotominor.yy450 ){ + yygotominor.yy450->pSelect = yymsp[-1].minor.yy43; + }else{ + sqlite3SelectDelete(yymsp[-1].minor.yy43); + } + sqlite3ExprSpan(yygotominor.yy450,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); + } +#line 2796 "parse.c" + break; + case 219: +#line 769 "parse.y" +{ + yygotominor.yy450 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy450, 0, 0); + if( yygotominor.yy450 ){ + yygotominor.yy450->pSelect = yymsp[-1].minor.yy43; + }else{ + sqlite3SelectDelete(yymsp[-1].minor.yy43); + } + if( yymsp[-3].minor.yy316 ) yygotominor.yy450 = sqlite3Expr(TK_NOT, yygotominor.yy450, 0, 0); + sqlite3ExprSpan(yygotominor.yy450,&yymsp[-4].minor.yy450->span,&yymsp[0].minor.yy0); + } +#line 2810 "parse.c" + break; + case 220: +#line 779 "parse.y" +{ + SrcList *pSrc = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy178,&yymsp[0].minor.yy178); + yygotominor.yy450 = sqlite3Expr(TK_IN, yymsp[-3].minor.yy450, 0, 0); + if( yygotominor.yy450 ){ + yygotominor.yy450->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,0,0); }else{ sqlite3SrcListDelete(pSrc); } - if( yymsp[-2].minor.yy230 ) yygotominor.yy178 = sqlite3Expr(TK_NOT, yygotominor.yy178, 0, 0); - sqlite3ExprSpan(yygotominor.yy178,&yymsp[-3].minor.yy178->span,yymsp[0].minor.yy384.z?&yymsp[0].minor.yy384:&yymsp[-1].minor.yy384); + if( yymsp[-2].minor.yy316 ) yygotominor.yy450 = sqlite3Expr(TK_NOT, yygotominor.yy450, 0, 0); + sqlite3ExprSpan(yygotominor.yy450,&yymsp[-3].minor.yy450->span,yymsp[0].minor.yy178.z?&yymsp[0].minor.yy178:&yymsp[-1].minor.yy178); } -#line 2744 "parse.c" - break; - case 219: -#line 793 "parse.y" -{ - Expr *p = yygotominor.yy178 = sqlite3Expr(TK_EXISTS, 0, 0, 0); - if( p ){ - p->pSelect = yymsp[-1].minor.yy239; - sqlite3ExprSpan(p,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); - }else{ - sqlite3SelectDelete(yymsp[-1].minor.yy239); - } - } -#line 2757 "parse.c" - break; - case 220: -#line 805 "parse.y" -{ - yygotominor.yy178 = sqlite3Expr(TK_CASE, yymsp[-3].minor.yy178, yymsp[-1].minor.yy178, 0); - if( yygotominor.yy178 ){ - yygotominor.yy178->pList = yymsp[-2].minor.yy462; - }else{ - sqlite3ExprListDelete(yymsp[-2].minor.yy462); - } - sqlite3ExprSpan(yygotominor.yy178, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0); -} -#line 2770 "parse.c" +#line 2825 "parse.c" break; case 221: -#line 816 "parse.y" +#line 790 "parse.y" { - yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-4].minor.yy462, yymsp[-2].minor.yy178, 0); - yygotominor.yy462 = sqlite3ExprListAppend(yygotominor.yy462, yymsp[0].minor.yy178, 0); -} -#line 2778 "parse.c" + Expr *p = yygotominor.yy450 = sqlite3Expr(TK_EXISTS, 0, 0, 0); + if( p ){ + p->pSelect = yymsp[-1].minor.yy43; + sqlite3ExprSpan(p,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); + }else{ + sqlite3SelectDelete(yymsp[-1].minor.yy43); + } + } +#line 2838 "parse.c" break; case 222: -#line 820 "parse.y" +#line 802 "parse.y" { - yygotominor.yy462 = sqlite3ExprListAppend(0, yymsp[-2].minor.yy178, 0); - yygotominor.yy462 = sqlite3ExprListAppend(yygotominor.yy462, yymsp[0].minor.yy178, 0); + yygotominor.yy450 = sqlite3Expr(TK_CASE, yymsp[-3].minor.yy450, yymsp[-1].minor.yy450, 0); + if( yygotominor.yy450 ){ + yygotominor.yy450->pList = yymsp[-2].minor.yy242; + }else{ + sqlite3ExprListDelete(yymsp[-2].minor.yy242); + } + sqlite3ExprSpan(yygotominor.yy450, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0); } -#line 2786 "parse.c" +#line 2851 "parse.c" break; - case 231: -#line 847 "parse.y" + case 223: +#line 813 "parse.y" { - sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy384, &yymsp[-5].minor.yy384, sqlite3SrcListAppend(0,&yymsp[-3].minor.yy384,0), yymsp[-1].minor.yy462, yymsp[-9].minor.yy230, - &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy230); + yygotominor.yy242 = sqlite3ExprListAppend(yymsp[-4].minor.yy242, yymsp[-2].minor.yy450, 0); + yygotominor.yy242 = sqlite3ExprListAppend(yygotominor.yy242, yymsp[0].minor.yy450, 0); } -#line 2794 "parse.c" +#line 2859 "parse.c" break; - case 232: - case 277: -#line 853 "parse.y" -{yygotominor.yy230 = OE_Abort;} -#line 2800 "parse.c" + case 224: +#line 817 "parse.y" +{ + yygotominor.yy242 = sqlite3ExprListAppend(0, yymsp[-2].minor.yy450, 0); + yygotominor.yy242 = sqlite3ExprListAppend(yygotominor.yy242, yymsp[0].minor.yy450, 0); +} +#line 2867 "parse.c" break; case 233: -#line 854 "parse.y" -{yygotominor.yy230 = OE_None;} -#line 2805 "parse.c" +#line 844 "parse.y" +{ + sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy178, &yymsp[-5].minor.yy178, sqlite3SrcListAppend(0,&yymsp[-3].minor.yy178,0), yymsp[-1].minor.yy242, yymsp[-9].minor.yy316, + &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy316); +} +#line 2875 "parse.c" break; - case 236: -#line 864 "parse.y" + case 234: + case 282: +#line 850 "parse.y" +{yygotominor.yy316 = OE_Abort;} +#line 2881 "parse.c" + break; + case 235: +#line 851 "parse.y" +{yygotominor.yy316 = OE_None;} +#line 2886 "parse.c" + break; + case 238: +#line 861 "parse.y" { Expr *p = 0; - if( yymsp[-1].minor.yy384.n>0 ){ + if( yymsp[-1].minor.yy178.n>0 ){ p = sqlite3Expr(TK_COLUMN, 0, 0, 0); - if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)yymsp[-1].minor.yy384.z, yymsp[-1].minor.yy384.n); + if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)yymsp[-1].minor.yy178.z, yymsp[-1].minor.yy178.n); } - yygotominor.yy462 = sqlite3ExprListAppend(yymsp[-4].minor.yy462, p, &yymsp[-2].minor.yy384); - if( yygotominor.yy462 ) yygotominor.yy462->a[yygotominor.yy462->nExpr-1].sortOrder = yymsp[0].minor.yy230; + yygotominor.yy242 = sqlite3ExprListAppend(yymsp[-4].minor.yy242, p, &yymsp[-2].minor.yy178); + if( yygotominor.yy242 ) yygotominor.yy242->a[yygotominor.yy242->nExpr-1].sortOrder = yymsp[0].minor.yy316; } -#line 2818 "parse.c" - break; - case 237: -#line 873 "parse.y" -{ - Expr *p = 0; - if( yymsp[-1].minor.yy384.n>0 ){ - p = sqlite3Expr(TK_COLUMN, 0, 0, 0); - if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)yymsp[-1].minor.yy384.z, yymsp[-1].minor.yy384.n); - } - yygotominor.yy462 = sqlite3ExprListAppend(0, p, &yymsp[-2].minor.yy384); - if( yygotominor.yy462 ) yygotominor.yy462->a[yygotominor.yy462->nExpr-1].sortOrder = yymsp[0].minor.yy230; -} -#line 2831 "parse.c" - break; - case 239: -#line 887 "parse.y" -{sqlite3DropIndex(pParse, yymsp[0].minor.yy285, yymsp[-1].minor.yy230);} -#line 2836 "parse.c" - break; - case 240: - case 241: -#line 891 "parse.y" -{sqlite3Vacuum(pParse);} -#line 2842 "parse.c" - break; - case 242: - case 244: -#line 897 "parse.y" -{sqlite3Pragma(pParse,&yymsp[-3].minor.yy384,&yymsp[-2].minor.yy384,&yymsp[0].minor.yy384,0);} -#line 2848 "parse.c" - break; - case 243: -#line 898 "parse.y" -{sqlite3Pragma(pParse,&yymsp[-3].minor.yy384,&yymsp[-2].minor.yy384,&yymsp[0].minor.yy0,0);} -#line 2853 "parse.c" - break; - case 245: -#line 900 "parse.y" -{ - sqlite3Pragma(pParse,&yymsp[-3].minor.yy384,&yymsp[-2].minor.yy384,&yymsp[0].minor.yy384,1); -} -#line 2860 "parse.c" - break; - case 246: -#line 903 "parse.y" -{sqlite3Pragma(pParse,&yymsp[-4].minor.yy384,&yymsp[-3].minor.yy384,&yymsp[-1].minor.yy384,0);} -#line 2865 "parse.c" - break; - case 247: -#line 904 "parse.y" -{sqlite3Pragma(pParse,&yymsp[-1].minor.yy384,&yymsp[0].minor.yy384,0,0);} -#line 2870 "parse.c" - break; - case 253: -#line 916 "parse.y" -{ - Token all; - all.z = yymsp[-3].minor.yy384.z; - all.n = (yymsp[0].minor.yy0.z - yymsp[-3].minor.yy384.z) + yymsp[0].minor.yy0.n; - sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy247, &all); -} -#line 2880 "parse.c" - break; - case 254: -#line 925 "parse.y" -{ - sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy384, &yymsp[-6].minor.yy384, yymsp[-5].minor.yy230, yymsp[-4].minor.yy132.a, yymsp[-4].minor.yy132.b, yymsp[-2].minor.yy285, yymsp[-1].minor.yy230, yymsp[0].minor.yy178, yymsp[-9].minor.yy230); - yygotominor.yy384 = (yymsp[-6].minor.yy384.n==0?yymsp[-7].minor.yy384:yymsp[-6].minor.yy384); -} -#line 2888 "parse.c" - break; - case 255: - case 258: -#line 931 "parse.y" -{ yygotominor.yy230 = TK_BEFORE; } -#line 2894 "parse.c" - break; - case 256: -#line 932 "parse.y" -{ yygotominor.yy230 = TK_AFTER; } #line 2899 "parse.c" break; - case 257: -#line 933 "parse.y" -{ yygotominor.yy230 = TK_INSTEAD;} -#line 2904 "parse.c" + case 239: +#line 870 "parse.y" +{ + Expr *p = 0; + if( yymsp[-1].minor.yy178.n>0 ){ + p = sqlite3Expr(TK_COLUMN, 0, 0, 0); + if( p ) p->pColl = sqlite3LocateCollSeq(pParse, (char*)yymsp[-1].minor.yy178.z, yymsp[-1].minor.yy178.n); + } + yygotominor.yy242 = sqlite3ExprListAppend(0, p, &yymsp[-2].minor.yy178); + if( yygotominor.yy242 ) yygotominor.yy242->a[yygotominor.yy242->nExpr-1].sortOrder = yymsp[0].minor.yy316; +} +#line 2912 "parse.c" + break; + case 241: +#line 882 "parse.y" +{yygotominor.yy178.z = 0; yygotominor.yy178.n = 0;} +#line 2917 "parse.c" + break; + case 243: +#line 888 "parse.y" +{sqlite3DropIndex(pParse, yymsp[0].minor.yy419, yymsp[-1].minor.yy316);} +#line 2922 "parse.c" + break; + case 244: + case 245: +#line 893 "parse.y" +{sqlite3Vacuum(pParse);} +#line 2928 "parse.c" + break; + case 246: +#line 900 "parse.y" +{sqlite3Pragma(pParse,&yymsp[-3].minor.yy178,&yymsp[-2].minor.yy178,&yymsp[0].minor.yy178,0);} +#line 2933 "parse.c" + break; + case 247: +#line 901 "parse.y" +{sqlite3Pragma(pParse,&yymsp[-3].minor.yy178,&yymsp[-2].minor.yy178,&yymsp[0].minor.yy0,0);} +#line 2938 "parse.c" + break; + case 248: +#line 902 "parse.y" +{ + sqlite3Pragma(pParse,&yymsp[-3].minor.yy178,&yymsp[-2].minor.yy178,&yymsp[0].minor.yy178,1); +} +#line 2945 "parse.c" + break; + case 249: +#line 905 "parse.y" +{sqlite3Pragma(pParse,&yymsp[-4].minor.yy178,&yymsp[-3].minor.yy178,&yymsp[-1].minor.yy178,0);} +#line 2950 "parse.c" + break; + case 250: +#line 906 "parse.y" +{sqlite3Pragma(pParse,&yymsp[-1].minor.yy178,&yymsp[0].minor.yy178,0,0);} +#line 2955 "parse.c" + break; + case 258: +#line 920 "parse.y" +{ + Token all; + all.z = yymsp[-3].minor.yy178.z; + all.n = (yymsp[0].minor.yy0.z - yymsp[-3].minor.yy178.z) + yymsp[0].minor.yy0.n; + sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy75, &all); +} +#line 2965 "parse.c" break; case 259: - case 260: -#line 938 "parse.y" -{yygotominor.yy132.a = yymsp[0].major; yygotominor.yy132.b = 0;} -#line 2910 "parse.c" - break; - case 261: -#line 940 "parse.y" -{yygotominor.yy132.a = TK_UPDATE; yygotominor.yy132.b = yymsp[0].minor.yy160;} -#line 2915 "parse.c" - break; - case 262: - case 263: -#line 943 "parse.y" -{ yygotominor.yy230 = TK_ROW; } -#line 2921 "parse.c" - break; - case 264: -#line 945 "parse.y" -{ yygotominor.yy230 = TK_STATEMENT; } -#line 2926 "parse.c" - break; - case 265: -#line 949 "parse.y" -{ yygotominor.yy178 = 0; } -#line 2931 "parse.c" - break; - case 266: -#line 950 "parse.y" -{ yygotominor.yy178 = yymsp[0].minor.yy178; } -#line 2936 "parse.c" - break; - case 267: -#line 954 "parse.y" +#line 929 "parse.y" { - if( yymsp[-2].minor.yy247 ){ - yymsp[-2].minor.yy247->pLast->pNext = yymsp[-1].minor.yy247; - }else{ - yymsp[-2].minor.yy247 = yymsp[-1].minor.yy247; - } - yymsp[-2].minor.yy247->pLast = yymsp[-1].minor.yy247; - yygotominor.yy247 = yymsp[-2].minor.yy247; + sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy178, &yymsp[-6].minor.yy178, yymsp[-5].minor.yy316, yymsp[-4].minor.yy354.a, yymsp[-4].minor.yy354.b, yymsp[-2].minor.yy419, yymsp[-1].minor.yy316, yymsp[0].minor.yy450, yymsp[-10].minor.yy316, yymsp[-8].minor.yy316); + yygotominor.yy178 = (yymsp[-6].minor.yy178.n==0?yymsp[-7].minor.yy178:yymsp[-6].minor.yy178); } -#line 2949 "parse.c" +#line 2973 "parse.c" break; - case 268: -#line 963 "parse.y" -{ yygotominor.yy247 = 0; } -#line 2954 "parse.c" - break; - case 269: -#line 969 "parse.y" -{ yygotominor.yy247 = sqlite3TriggerUpdateStep(&yymsp[-3].minor.yy384, yymsp[-1].minor.yy462, yymsp[0].minor.yy178, yymsp[-4].minor.yy230); } -#line 2959 "parse.c" - break; - case 270: -#line 974 "parse.y" -{yygotominor.yy247 = sqlite3TriggerInsertStep(&yymsp[-5].minor.yy384, yymsp[-4].minor.yy160, yymsp[-1].minor.yy462, 0, yymsp[-7].minor.yy230);} -#line 2964 "parse.c" - break; - case 271: -#line 977 "parse.y" -{yygotominor.yy247 = sqlite3TriggerInsertStep(&yymsp[-2].minor.yy384, yymsp[-1].minor.yy160, 0, yymsp[0].minor.yy239, yymsp[-4].minor.yy230);} -#line 2969 "parse.c" - break; - case 272: -#line 981 "parse.y" -{yygotominor.yy247 = sqlite3TriggerDeleteStep(&yymsp[-1].minor.yy384, yymsp[0].minor.yy178);} -#line 2974 "parse.c" - break; - case 273: -#line 984 "parse.y" -{yygotominor.yy247 = sqlite3TriggerSelectStep(yymsp[0].minor.yy239); } + case 260: + case 263: +#line 935 "parse.y" +{ yygotominor.yy316 = TK_BEFORE; } #line 2979 "parse.c" break; - case 274: -#line 987 "parse.y" -{ - yygotominor.yy178 = sqlite3Expr(TK_RAISE, 0, 0, 0); - if( yygotominor.yy178 ){ - yygotominor.yy178->iColumn = OE_Ignore; - sqlite3ExprSpan(yygotominor.yy178, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0); - } -} -#line 2990 "parse.c" + case 261: +#line 936 "parse.y" +{ yygotominor.yy316 = TK_AFTER; } +#line 2984 "parse.c" break; - case 275: -#line 994 "parse.y" -{ - yygotominor.yy178 = sqlite3Expr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy384); - if( yygotominor.yy178 ) { - yygotominor.yy178->iColumn = yymsp[-3].minor.yy230; - sqlite3ExprSpan(yygotominor.yy178, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0); - } -} -#line 3001 "parse.c" + case 262: +#line 937 "parse.y" +{ yygotominor.yy316 = TK_INSTEAD;} +#line 2989 "parse.c" break; - case 276: -#line 1004 "parse.y" -{yygotominor.yy230 = OE_Rollback;} + case 264: + case 265: +#line 942 "parse.y" +{yygotominor.yy354.a = yymsp[0].major; yygotominor.yy354.b = 0;} +#line 2995 "parse.c" + break; + case 266: +#line 944 "parse.y" +{yygotominor.yy354.a = TK_UPDATE; yygotominor.yy354.b = yymsp[0].minor.yy352;} +#line 3000 "parse.c" + break; + case 267: + case 268: +#line 947 "parse.y" +{ yygotominor.yy316 = TK_ROW; } #line 3006 "parse.c" break; - case 278: -#line 1006 "parse.y" -{yygotominor.yy230 = OE_Fail;} + case 269: +#line 949 "parse.y" +{ yygotominor.yy316 = TK_STATEMENT; } #line 3011 "parse.c" break; - case 279: -#line 1011 "parse.y" + case 270: +#line 953 "parse.y" +{ yygotominor.yy450 = 0; } +#line 3016 "parse.c" + break; + case 271: +#line 954 "parse.y" +{ yygotominor.yy450 = yymsp[0].minor.yy450; } +#line 3021 "parse.c" + break; + case 272: +#line 958 "parse.y" { - sqlite3DropTrigger(pParse,yymsp[0].minor.yy285); + if( yymsp[-2].minor.yy75 ){ + yymsp[-2].minor.yy75->pLast->pNext = yymsp[-1].minor.yy75; + }else{ + yymsp[-2].minor.yy75 = yymsp[-1].minor.yy75; + } + yymsp[-2].minor.yy75->pLast = yymsp[-1].minor.yy75; + yygotominor.yy75 = yymsp[-2].minor.yy75; } -#line 3018 "parse.c" +#line 3034 "parse.c" + break; + case 273: +#line 967 "parse.y" +{ yygotominor.yy75 = 0; } +#line 3039 "parse.c" + break; + case 274: +#line 973 "parse.y" +{ yygotominor.yy75 = sqlite3TriggerUpdateStep(&yymsp[-3].minor.yy178, yymsp[-1].minor.yy242, yymsp[0].minor.yy450, yymsp[-4].minor.yy316); } +#line 3044 "parse.c" + break; + case 275: +#line 978 "parse.y" +{yygotominor.yy75 = sqlite3TriggerInsertStep(&yymsp[-5].minor.yy178, yymsp[-4].minor.yy352, yymsp[-1].minor.yy242, 0, yymsp[-7].minor.yy316);} +#line 3049 "parse.c" + break; + case 276: +#line 981 "parse.y" +{yygotominor.yy75 = sqlite3TriggerInsertStep(&yymsp[-2].minor.yy178, yymsp[-1].minor.yy352, 0, yymsp[0].minor.yy43, yymsp[-4].minor.yy316);} +#line 3054 "parse.c" + break; + case 277: +#line 985 "parse.y" +{yygotominor.yy75 = sqlite3TriggerDeleteStep(&yymsp[-1].minor.yy178, yymsp[0].minor.yy450);} +#line 3059 "parse.c" + break; + case 278: +#line 988 "parse.y" +{yygotominor.yy75 = sqlite3TriggerSelectStep(yymsp[0].minor.yy43); } +#line 3064 "parse.c" + break; + case 279: +#line 991 "parse.y" +{ + yygotominor.yy450 = sqlite3Expr(TK_RAISE, 0, 0, 0); + if( yygotominor.yy450 ){ + yygotominor.yy450->iColumn = OE_Ignore; + sqlite3ExprSpan(yygotominor.yy450, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0); + } +} +#line 3075 "parse.c" break; case 280: -#line 1017 "parse.y" +#line 998 "parse.y" { - sqlite3Attach(pParse, yymsp[-3].minor.yy178, yymsp[-1].minor.yy178, yymsp[0].minor.yy292); + yygotominor.yy450 = sqlite3Expr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy178); + if( yygotominor.yy450 ) { + yygotominor.yy450->iColumn = yymsp[-3].minor.yy316; + sqlite3ExprSpan(yygotominor.yy450, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0); + } } -#line 3025 "parse.c" +#line 3086 "parse.c" break; case 281: -#line 1022 "parse.y" -{ yygotominor.yy292 = 0; } -#line 3030 "parse.c" +#line 1008 "parse.y" +{yygotominor.yy316 = OE_Rollback;} +#line 3091 "parse.c" break; - case 282: -#line 1023 "parse.y" -{ yygotominor.yy292 = yymsp[0].minor.yy178; } -#line 3035 "parse.c" + case 283: +#line 1010 "parse.y" +{yygotominor.yy316 = OE_Fail;} +#line 3096 "parse.c" + break; + case 284: +#line 1015 "parse.y" +{ + sqlite3DropTrigger(pParse,yymsp[0].minor.yy419,yymsp[-1].minor.yy316); +} +#line 3103 "parse.c" break; case 285: -#line 1029 "parse.y" +#line 1021 "parse.y" { - sqlite3Detach(pParse, yymsp[0].minor.yy178); + sqlite3Attach(pParse, yymsp[-3].minor.yy450, yymsp[-1].minor.yy450, yymsp[0].minor.yy158); } -#line 3042 "parse.c" +#line 3110 "parse.c" break; case 286: -#line 1035 "parse.y" -{sqlite3Reindex(pParse, 0, 0);} -#line 3047 "parse.c" +#line 1026 "parse.y" +{ yygotominor.yy158 = 0; } +#line 3115 "parse.c" break; case 287: -#line 1036 "parse.y" -{sqlite3Reindex(pParse, &yymsp[-1].minor.yy384, &yymsp[0].minor.yy384);} -#line 3052 "parse.c" - break; - case 288: -#line 1041 "parse.y" -{sqlite3Analyze(pParse, 0, 0);} -#line 3057 "parse.c" - break; - case 289: -#line 1042 "parse.y" -{sqlite3Analyze(pParse, &yymsp[-1].minor.yy384, &yymsp[0].minor.yy384);} -#line 3062 "parse.c" +#line 1027 "parse.y" +{ yygotominor.yy158 = yymsp[0].minor.yy450; } +#line 3120 "parse.c" break; case 290: -#line 1047 "parse.y" +#line 1033 "parse.y" { - sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy285,&yymsp[0].minor.yy384); + sqlite3Detach(pParse, yymsp[0].minor.yy450); } -#line 3069 "parse.c" +#line 3127 "parse.c" break; case 291: -#line 1050 "parse.y" -{ - sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy384); -} -#line 3076 "parse.c" +#line 1039 "parse.y" +{sqlite3Reindex(pParse, 0, 0);} +#line 3132 "parse.c" break; case 292: -#line 1053 "parse.y" +#line 1040 "parse.y" +{sqlite3Reindex(pParse, &yymsp[-1].minor.yy178, &yymsp[0].minor.yy178);} +#line 3137 "parse.c" + break; + case 293: +#line 1045 "parse.y" +{sqlite3Analyze(pParse, 0, 0);} +#line 3142 "parse.c" + break; + case 294: +#line 1046 "parse.y" +{sqlite3Analyze(pParse, &yymsp[-1].minor.yy178, &yymsp[0].minor.yy178);} +#line 3147 "parse.c" + break; + case 295: +#line 1051 "parse.y" { - sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy285); + sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy419,&yymsp[0].minor.yy178); } -#line 3083 "parse.c" +#line 3154 "parse.c" + break; + case 296: +#line 1054 "parse.y" +{ + sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy178); +} +#line 3161 "parse.c" + break; + case 297: +#line 1057 "parse.y" +{ + sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy419); +} +#line 3168 "parse.c" + break; + case 300: +#line 1066 "parse.y" +{sqlite3VtabFinishParse(pParse,0);} +#line 3173 "parse.c" + break; + case 301: +#line 1067 "parse.y" +{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} +#line 3178 "parse.c" + break; + case 302: +#line 1068 "parse.y" +{ + sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy178, &yymsp[-2].minor.yy178, &yymsp[0].minor.yy178); +} +#line 3185 "parse.c" + break; + case 305: +#line 1073 "parse.y" +{sqlite3VtabArgInit(pParse);} +#line 3190 "parse.c" + break; + case 307: + case 308: + case 309: + case 311: +#line 1075 "parse.y" +{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} +#line 3198 "parse.c" break; }; yygoto = yyRuleInfo[yyruleno].lhs; @@ -3136,14 +3251,15 @@ static void yy_syntax_error( #define TOKEN (yyminor.yy0) #line 34 "parse.y" - if( pParse->zErrMsg==0 ){ + if( !pParse->parseError ){ if( TOKEN.z[0] ){ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN); }else{ sqlite3ErrorMsg(pParse, "incomplete SQL statement"); } + pParse->parseError = 1; } -#line 3150 "parse.c" +#line 3266 "parse.c" sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */ } @@ -3271,7 +3387,9 @@ void sqlite3Parser( while( yypParser->yyidx >= 0 && yymx != YYERRORSYMBOL && - (yyact = yy_find_shift_action(yypParser,YYERRORSYMBOL)) >= YYNSTATE + (yyact = yy_find_reduce_action( + yypParser->yystack[yypParser->yyidx].stateno, + YYERRORSYMBOL)) >= YYNSTATE ){ yy_pop_parser_stack(yypParser); } diff --git a/dlls/sqlite/sqlite-source/parse.h b/dlls/sqlite/sqlite-source/parse.h index 116e7f5b..3a71be19 100644 --- a/dlls/sqlite/sqlite-source/parse.h +++ b/dlls/sqlite/sqlite-source/parse.h @@ -53,99 +53,101 @@ #define TK_TRIGGER 53 #define TK_VACUUM 54 #define TK_VIEW 55 -#define TK_REINDEX 56 -#define TK_RENAME 57 -#define TK_CTIME_KW 58 -#define TK_OR 59 -#define TK_AND 60 -#define TK_IS 61 -#define TK_BETWEEN 62 -#define TK_IN 63 -#define TK_ISNULL 64 -#define TK_NOTNULL 65 -#define TK_NE 66 -#define TK_EQ 67 -#define TK_GT 68 -#define TK_LE 69 -#define TK_LT 70 -#define TK_GE 71 -#define TK_ESCAPE 72 -#define TK_BITAND 73 -#define TK_BITOR 74 -#define TK_LSHIFT 75 -#define TK_RSHIFT 76 -#define TK_PLUS 77 -#define TK_MINUS 78 -#define TK_STAR 79 -#define TK_SLASH 80 -#define TK_REM 81 -#define TK_CONCAT 82 -#define TK_UMINUS 83 -#define TK_UPLUS 84 -#define TK_BITNOT 85 -#define TK_STRING 86 -#define TK_JOIN_KW 87 -#define TK_CONSTRAINT 88 -#define TK_DEFAULT 89 -#define TK_NULL 90 -#define TK_PRIMARY 91 -#define TK_UNIQUE 92 -#define TK_CHECK 93 -#define TK_REFERENCES 94 -#define TK_COLLATE 95 -#define TK_AUTOINCR 96 -#define TK_ON 97 -#define TK_DELETE 98 -#define TK_UPDATE 99 -#define TK_INSERT 100 -#define TK_SET 101 -#define TK_DEFERRABLE 102 -#define TK_FOREIGN 103 -#define TK_DROP 104 -#define TK_UNION 105 -#define TK_ALL 106 -#define TK_EXCEPT 107 -#define TK_INTERSECT 108 -#define TK_SELECT 109 -#define TK_DISTINCT 110 -#define TK_DOT 111 -#define TK_FROM 112 -#define TK_JOIN 113 -#define TK_USING 114 -#define TK_ORDER 115 -#define TK_BY 116 -#define TK_GROUP 117 -#define TK_HAVING 118 -#define TK_LIMIT 119 -#define TK_WHERE 120 -#define TK_INTO 121 -#define TK_VALUES 122 -#define TK_INTEGER 123 -#define TK_FLOAT 124 -#define TK_BLOB 125 -#define TK_REGISTER 126 -#define TK_VARIABLE 127 -#define TK_CASE 128 -#define TK_WHEN 129 -#define TK_THEN 130 -#define TK_ELSE 131 -#define TK_INDEX 132 -#define TK_ALTER 133 -#define TK_TO 134 -#define TK_ADD 135 -#define TK_COLUMNKW 136 -#define TK_TO_TEXT 137 -#define TK_TO_BLOB 138 -#define TK_TO_NUMERIC 139 -#define TK_TO_INT 140 -#define TK_TO_REAL 141 -#define TK_END_OF_FILE 142 -#define TK_ILLEGAL 143 -#define TK_SPACE 144 -#define TK_UNCLOSED_STRING 145 -#define TK_COMMENT 146 -#define TK_FUNCTION 147 -#define TK_COLUMN 148 -#define TK_AGG_FUNCTION 149 -#define TK_AGG_COLUMN 150 -#define TK_CONST_FUNC 151 +#define TK_VIRTUAL 56 +#define TK_REINDEX 57 +#define TK_RENAME 58 +#define TK_CTIME_KW 59 +#define TK_ANY 60 +#define TK_OR 61 +#define TK_AND 62 +#define TK_IS 63 +#define TK_BETWEEN 64 +#define TK_IN 65 +#define TK_ISNULL 66 +#define TK_NOTNULL 67 +#define TK_NE 68 +#define TK_EQ 69 +#define TK_GT 70 +#define TK_LE 71 +#define TK_LT 72 +#define TK_GE 73 +#define TK_ESCAPE 74 +#define TK_BITAND 75 +#define TK_BITOR 76 +#define TK_LSHIFT 77 +#define TK_RSHIFT 78 +#define TK_PLUS 79 +#define TK_MINUS 80 +#define TK_STAR 81 +#define TK_SLASH 82 +#define TK_REM 83 +#define TK_CONCAT 84 +#define TK_COLLATE 85 +#define TK_UMINUS 86 +#define TK_UPLUS 87 +#define TK_BITNOT 88 +#define TK_STRING 89 +#define TK_JOIN_KW 90 +#define TK_CONSTRAINT 91 +#define TK_DEFAULT 92 +#define TK_NULL 93 +#define TK_PRIMARY 94 +#define TK_UNIQUE 95 +#define TK_CHECK 96 +#define TK_REFERENCES 97 +#define TK_AUTOINCR 98 +#define TK_ON 99 +#define TK_DELETE 100 +#define TK_UPDATE 101 +#define TK_INSERT 102 +#define TK_SET 103 +#define TK_DEFERRABLE 104 +#define TK_FOREIGN 105 +#define TK_DROP 106 +#define TK_UNION 107 +#define TK_ALL 108 +#define TK_EXCEPT 109 +#define TK_INTERSECT 110 +#define TK_SELECT 111 +#define TK_DISTINCT 112 +#define TK_DOT 113 +#define TK_FROM 114 +#define TK_JOIN 115 +#define TK_USING 116 +#define TK_ORDER 117 +#define TK_BY 118 +#define TK_GROUP 119 +#define TK_HAVING 120 +#define TK_LIMIT 121 +#define TK_WHERE 122 +#define TK_INTO 123 +#define TK_VALUES 124 +#define TK_INTEGER 125 +#define TK_FLOAT 126 +#define TK_BLOB 127 +#define TK_REGISTER 128 +#define TK_VARIABLE 129 +#define TK_CASE 130 +#define TK_WHEN 131 +#define TK_THEN 132 +#define TK_ELSE 133 +#define TK_INDEX 134 +#define TK_ALTER 135 +#define TK_TO 136 +#define TK_ADD 137 +#define TK_COLUMNKW 138 +#define TK_TO_TEXT 139 +#define TK_TO_BLOB 140 +#define TK_TO_NUMERIC 141 +#define TK_TO_INT 142 +#define TK_TO_REAL 143 +#define TK_END_OF_FILE 144 +#define TK_ILLEGAL 145 +#define TK_SPACE 146 +#define TK_UNCLOSED_STRING 147 +#define TK_COMMENT 148 +#define TK_FUNCTION 149 +#define TK_COLUMN 150 +#define TK_AGG_FUNCTION 151 +#define TK_AGG_COLUMN 152 +#define TK_CONST_FUNC 153 diff --git a/dlls/sqlite/sqlite-source/pragma.c b/dlls/sqlite/sqlite-source/pragma.c index fd114909..b1c5954d 100644 --- a/dlls/sqlite/sqlite-source/pragma.c +++ b/dlls/sqlite/sqlite-source/pragma.c @@ -482,12 +482,17 @@ void sqlite3Pragma( sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "pk", P3_STATIC); sqlite3ViewGetColumnNames(pParse, pTab); for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){ + const Token *pDflt; sqlite3VdbeAddOp(v, OP_Integer, i, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, pCol->zName, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, pCol->zType ? pCol->zType : "", 0); sqlite3VdbeAddOp(v, OP_Integer, pCol->notNull, 0); - sqlite3ExprCode(pParse, pCol->pDflt); + if( pCol->pDflt && (pDflt = &pCol->pDflt->span)->z ){ + sqlite3VdbeOp3(v, OP_String8, 0, 0, (char*)pDflt->z, pDflt->n); + }else{ + sqlite3VdbeAddOp(v, OP_Null, 0, 0); + } sqlite3VdbeAddOp(v, OP_Integer, pCol->isPrimKey, 0); sqlite3VdbeAddOp(v, OP_Callback, 6, 0); } @@ -635,9 +640,13 @@ void sqlite3Pragma( } }else +#ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX +# define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100 +#endif + #ifndef SQLITE_OMIT_INTEGRITY_CHECK if( sqlite3StrICmp(zLeft, "integrity_check")==0 ){ - int i, j, addr; + int i, j, addr, mxErr; /* Code that appears at the end of the integrity check. If no error ** messages have been generated, output OK. Otherwise output the @@ -655,7 +664,16 @@ void sqlite3Pragma( if( sqlite3ReadSchema(pParse) ) goto pragma_out; sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", P3_STATIC); - sqlite3VdbeAddOp(v, OP_MemInt, 0, 0); /* Initialize error count to 0 */ + + /* Set the maximum error count */ + mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; + if( zRight ){ + mxErr = atoi(zRight); + if( mxErr<=0 ){ + mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; + } + } + sqlite3VdbeAddOp(v, OP_MemInt, mxErr, 0); /* Do an integrity check on each database file */ for(i=0; inDb; i++){ @@ -666,6 +684,9 @@ void sqlite3Pragma( if( OMIT_TEMPDB && i==1 ) continue; sqlite3CodeVerifySchema(pParse, i); + addr = sqlite3VdbeAddOp(v, OP_IfMemPos, 0, 0); + sqlite3VdbeAddOp(v, OP_Halt, 0, 0); + sqlite3VdbeJumpHere(v, addr); /* Do an integrity check of the B-Tree */ @@ -680,28 +701,28 @@ void sqlite3Pragma( cnt++; } } - assert( cnt>0 ); - sqlite3VdbeAddOp(v, OP_IntegrityCk, cnt, i); - sqlite3VdbeAddOp(v, OP_Dup, 0, 1); - addr = sqlite3VdbeOp3(v, OP_String8, 0, 0, "ok", P3_STATIC); - sqlite3VdbeAddOp(v, OP_Eq, 0, addr+7); + if( cnt==0 ) continue; + sqlite3VdbeAddOp(v, OP_IntegrityCk, 0, i); + addr = sqlite3VdbeAddOp(v, OP_IsNull, -1, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, sqlite3MPrintf("*** in database %s ***\n", db->aDb[i].zName), P3_DYNAMIC); sqlite3VdbeAddOp(v, OP_Pull, 1, 0); - sqlite3VdbeAddOp(v, OP_Concat, 0, 1); + sqlite3VdbeAddOp(v, OP_Concat, 0, 0); sqlite3VdbeAddOp(v, OP_Callback, 1, 0); - sqlite3VdbeAddOp(v, OP_MemIncr, 1, 0); + sqlite3VdbeJumpHere(v, addr); /* Make sure all the indices are constructed correctly. */ - sqlite3CodeVerifySchema(pParse, i); for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); Index *pIdx; int loopTop; if( pTab->pIndex==0 ) continue; + addr = sqlite3VdbeAddOp(v, OP_IfMemPos, 0, 0); + sqlite3VdbeAddOp(v, OP_Halt, 0, 0); + sqlite3VdbeJumpHere(v, addr); sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead); sqlite3VdbeAddOp(v, OP_MemInt, 0, 1); loopTop = sqlite3VdbeAddOp(v, OP_Rewind, 1, 0); @@ -709,7 +730,7 @@ void sqlite3Pragma( for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ int jmp2; static const VdbeOpList idxErr[] = { - { OP_MemIncr, 1, 0, 0}, + { OP_MemIncr, -1, 0, 0}, { OP_String8, 0, 0, "rowid "}, { OP_Rowid, 1, 0, 0}, { OP_String8, 0, 0, " missing from index "}, @@ -734,13 +755,16 @@ void sqlite3Pragma( { OP_MemLoad, 1, 0, 0}, { OP_MemLoad, 2, 0, 0}, { OP_Eq, 0, 0, 0}, /* 6 */ - { OP_MemIncr, 1, 0, 0}, + { OP_MemIncr, -1, 0, 0}, { OP_String8, 0, 0, "wrong # of entries in index "}, { OP_String8, 0, 0, 0}, /* 9 */ { OP_Concat, 0, 0, 0}, { OP_Callback, 1, 0, 0}, }; if( pIdx->tnum==0 ) continue; + addr = sqlite3VdbeAddOp(v, OP_IfMemPos, 0, 0); + sqlite3VdbeAddOp(v, OP_Halt, 0, 0); + sqlite3VdbeJumpHere(v, addr); addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx); sqlite3VdbeChangeP1(v, addr+1, j+2); sqlite3VdbeChangeP2(v, addr+1, addr+4); @@ -752,6 +776,7 @@ void sqlite3Pragma( } } addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode); + sqlite3VdbeChangeP1(v, addr+1, mxErr); sqlite3VdbeJumpHere(v, addr+2); }else #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ @@ -780,7 +805,7 @@ void sqlite3Pragma( ** useful if invoked immediately after the main database i */ if( sqlite3StrICmp(zLeft, "encoding")==0 ){ - static struct EncName { + static const struct EncName { char *zName; u8 enc; } encnames[] = { @@ -790,12 +815,11 @@ void sqlite3Pragma( { "UTF16le", SQLITE_UTF16LE }, { "UTF-16be", SQLITE_UTF16BE }, { "UTF16be", SQLITE_UTF16BE }, - { "UTF-16", 0 /* Filled in at run-time */ }, - { "UTF16", 0 /* Filled in at run-time */ }, + { "UTF-16", 0 }, /* SQLITE_UTF16NATIVE */ + { "UTF16", 0 }, /* SQLITE_UTF16NATIVE */ { 0, 0 } }; - struct EncName *pEnc; - encnames[6].enc = encnames[7].enc = SQLITE_UTF16NATIVE; + const struct EncName *pEnc; if( !zRight ){ /* "PRAGMA encoding" */ if( sqlite3ReadSchema(pParse) ) goto pragma_out; sqlite3VdbeSetNumCols(v, 1); @@ -820,7 +844,7 @@ void sqlite3Pragma( ){ for(pEnc=&encnames[0]; pEnc->zName; pEnc++){ if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){ - ENC(pParse->db) = pEnc->enc; + ENC(pParse->db) = pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE; break; } } @@ -890,6 +914,7 @@ void sqlite3Pragma( sqlite3VdbeChangeP1(v, addr, iDb); sqlite3VdbeChangeP2(v, addr, iCookie); sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, P3_TRANSIENT); } } #endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */ @@ -941,6 +966,22 @@ void sqlite3Pragma( sqlite3_key(db, zRight, strlen(zRight)); }else #endif +#if SQLITE_HAS_CODEC || defined(SQLITE_ENABLE_CEROD) + if( sqlite3StrICmp(zLeft, "activate_extensions")==0 ){ +#if SQLITE_HAS_CODEC + if( sqlite3StrNICmp(zRight, "see-", 4)==0 ){ + extern void sqlite3_activate_see(const char*); + sqlite3_activate_see(&zRight[4]); + } +#endif +#ifdef SQLITE_ENABLE_CEROD + if( sqlite3StrNICmp(zRight, "cerod-", 6)==0 ){ + extern void sqlite3_activate_cerod(const char*); + sqlite3_activate_cerod(&zRight[6]); + } +#endif + } +#endif {} diff --git a/dlls/sqlite/sqlite-source/prepare.c b/dlls/sqlite/sqlite-source/prepare.c index 8abfb907..e584f789 100644 --- a/dlls/sqlite/sqlite-source/prepare.c +++ b/dlls/sqlite/sqlite-source/prepare.c @@ -28,6 +28,7 @@ static void corruptSchema(InitData *pData, const char *zExtra){ sqlite3SetString(pData->pzErrMsg, "malformed database schema", zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0); } + pData->rc = SQLITE_CORRUPT; } /* @@ -38,28 +39,28 @@ static void corruptSchema(InitData *pData, const char *zExtra){ ** Each callback contains the following information: ** ** argv[0] = name of thing being created -** argv[1] = root page number for table or index. NULL for trigger or view. +** argv[1] = root page number for table or index. 0 for trigger or view. ** argv[2] = SQL text for the CREATE statement. -** argv[3] = "1" for temporary files, "0" for main database, "2" or more -** for auxiliary database files. ** */ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){ InitData *pData = (InitData*)pInit; sqlite3 *db = pData->db; - int iDb; + int iDb = pData->iDb; + pData->rc = SQLITE_OK; + DbClearProperty(db, iDb, DB_Empty); if( sqlite3MallocFailed() ){ + corruptSchema(pData, 0); return SQLITE_NOMEM; } - assert( argc==4 ); + assert( argc==3 ); if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ - if( argv[1]==0 || argv[3]==0 ){ + if( argv[1]==0 ){ corruptSchema(pData, 0); return 1; } - iDb = atoi(argv[3]); assert( iDb>=0 && iDbnDb ); if( argv[2] && argv[2][0] ){ /* Call the parser to process a CREATE TABLE, INDEX or VIEW. @@ -76,13 +77,14 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){ db->init.iDb = 0; assert( rc!=SQLITE_OK || zErr==0 ); if( SQLITE_OK!=rc ){ + pData->rc = rc; if( rc==SQLITE_NOMEM ){ sqlite3FailedMalloc(); - }else{ + }else if( rc!=SQLITE_INTERRUPT ){ corruptSchema(pData, zErr); } sqlite3_free(zErr); - return rc; + return 1; } }else{ /* If the SQL column is blank it means this is an index that @@ -121,8 +123,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ int size; Table *pTab; Db *pDb; - char const *azArg[5]; - char zDbNum[30]; + char const *azArg[4]; int meta[10]; InitData initData; char const *zMasterSchema; @@ -173,15 +174,14 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ azArg[0] = zMasterName; azArg[1] = "1"; azArg[2] = zMasterSchema; - sprintf(zDbNum, "%d", iDb); - azArg[3] = zDbNum; - azArg[4] = 0; + azArg[3] = 0; initData.db = db; + initData.iDb = iDb; initData.pzErrMsg = pzErrMsg; - rc = sqlite3InitCallback(&initData, 4, (char **)azArg, 0); - if( rc!=SQLITE_OK ){ + rc = sqlite3InitCallback(&initData, 3, (char **)azArg, 0); + if( rc ){ sqlite3SafetyOn(db); - return rc; + return initData.rc; } pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName); if( pTab ){ @@ -211,7 +211,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ ** meta[1] File format of schema layer. ** meta[2] Size of the page cache. ** meta[3] Use freelist if 0. Autovacuum if greater than zero. - ** meta[4] Db text encoding. 1:UTF-8 3:UTF-16 LE 4:UTF-16 BE + ** meta[4] Db text encoding. 1:UTF-8 2:UTF-16LE 3:UTF-16BE ** meta[5] The user cookie. Used by the application. ** meta[6] ** meta[7] @@ -291,10 +291,11 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ }else{ char *zSql; zSql = sqlite3MPrintf( - "SELECT name, rootpage, sql, '%s' FROM '%q'.%s", - zDbNum, db->aDb[iDb].zName, zMasterName); + "SELECT name, rootpage, sql FROM '%q'.%s", + db->aDb[iDb].zName, zMasterName); sqlite3SafetyOff(db); rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); + if( rc==SQLITE_ABORT ) rc = initData.rc; sqlite3SafetyOn(db); sqliteFree(zSql); #ifndef SQLITE_OMIT_ANALYZE @@ -444,12 +445,13 @@ int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){ /* ** Compile the UTF-8 encoded SQL statement zSql into a statement handle. */ -int sqlite3_prepare( +int sqlite3Prepare( sqlite3 *db, /* Database handle. */ const char *zSql, /* UTF-8 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ + int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ - const char** pzTail /* OUT: End of parsed string */ + const char **pzTail /* OUT: End of parsed string */ ){ Parse sParse; char *zErrMsg = 0; @@ -499,7 +501,12 @@ int sqlite3_prepare( if( sParse.rc==SQLITE_SCHEMA ){ sqlite3ResetInternalSchema(db, 0); } - if( pzTail ) *pzTail = sParse.zTail; + if( sqlite3MallocFailed() ){ + sParse.rc = SQLITE_NOMEM; + } + if( pzTail ){ + *pzTail = sParse.zTail; + } rc = sParse.rc; #ifndef SQLITE_OMIT_EXPLAIN @@ -517,13 +524,16 @@ int sqlite3_prepare( sqlite3VdbeSetColName(sParse.pVdbe, 3, COLNAME_NAME, "p2", P3_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 4, COLNAME_NAME, "p3", P3_STATIC); } - } + } #endif if( sqlite3SafetyOff(db) ){ rc = SQLITE_MISUSE; } if( rc==SQLITE_OK ){ + if( saveSqlFlag ){ + sqlite3VdbeSetSql(sParse.pVdbe, zSql, sParse.zTail - zSql); + } *ppStmt = (sqlite3_stmt*)sParse.pVdbe; }else if( sParse.pVdbe ){ sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe); @@ -538,17 +548,78 @@ int sqlite3_prepare( rc = sqlite3ApiExit(db, rc); sqlite3ReleaseThreadData(); + assert( (rc&db->errMask)==rc ); return rc; } +/* +** Rerun the compilation of a statement after a schema change. +** Return true if the statement was recompiled successfully. +** Return false if there is an error of some kind. +*/ +int sqlite3Reprepare(Vdbe *p){ + int rc; + Vdbe *pNew; + const char *zSql; + sqlite3 *db; + + zSql = sqlite3VdbeGetSql(p); + if( zSql==0 ){ + return 0; + } + db = sqlite3VdbeDb(p); + rc = sqlite3Prepare(db, zSql, -1, 0, (sqlite3_stmt**)&pNew, 0); + if( rc ){ + assert( pNew==0 ); + return 0; + }else{ + assert( pNew!=0 ); + } + sqlite3VdbeSwap(pNew, p); + sqlite3_transfer_bindings((sqlite3_stmt*)pNew, (sqlite3_stmt*)p); + sqlite3VdbeResetStepResult(pNew); + sqlite3VdbeFinalize(pNew); + return 1; +} + + +/* +** Two versions of the official API. Legacy and new use. In the legacy +** version, the original SQL text is not saved in the prepared statement +** and so if a schema change occurs, SQLITE_SCHEMA is returned by +** sqlite3_step(). In the new version, the original SQL text is retained +** and the statement is automatically recompiled if an schema change +** occurs. +*/ +int sqlite3_prepare( + sqlite3 *db, /* Database handle. */ + const char *zSql, /* UTF-8 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const char **pzTail /* OUT: End of parsed string */ +){ + return sqlite3Prepare(db,zSql,nBytes,0,ppStmt,pzTail); +} +int sqlite3_prepare_v2( + sqlite3 *db, /* Database handle. */ + const char *zSql, /* UTF-8 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const char **pzTail /* OUT: End of parsed string */ +){ + return sqlite3Prepare(db,zSql,nBytes,1,ppStmt,pzTail); +} + + #ifndef SQLITE_OMIT_UTF16 /* ** Compile the UTF-16 encoded SQL statement zSql into a statement handle. */ -int sqlite3_prepare16( +static int sqlite3Prepare16( sqlite3 *db, /* Database handle. */ const void *zSql, /* UTF-8 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ + int saveSqlFlag, /* True to save SQL text into the sqlite3_stmt */ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const void **pzTail /* OUT: End of parsed string */ ){ @@ -565,7 +636,7 @@ int sqlite3_prepare16( } zSql8 = sqlite3utf16to8(zSql, nBytes); if( zSql8 ){ - rc = sqlite3_prepare(db, zSql8, -1, ppStmt, &zTail8); + rc = sqlite3Prepare(db, zSql8, -1, saveSqlFlag, ppStmt, &zTail8); } if( zTail8 && pzTail ){ @@ -580,4 +651,32 @@ int sqlite3_prepare16( sqliteFree(zSql8); return sqlite3ApiExit(db, rc); } + +/* +** Two versions of the official API. Legacy and new use. In the legacy +** version, the original SQL text is not saved in the prepared statement +** and so if a schema change occurs, SQLITE_SCHEMA is returned by +** sqlite3_step(). In the new version, the original SQL text is retained +** and the statement is automatically recompiled if an schema change +** occurs. +*/ +int sqlite3_prepare16( + sqlite3 *db, /* Database handle. */ + const void *zSql, /* UTF-8 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const void **pzTail /* OUT: End of parsed string */ +){ + return sqlite3Prepare16(db,zSql,nBytes,0,ppStmt,pzTail); +} +int sqlite3_prepare16_v2( + sqlite3 *db, /* Database handle. */ + const void *zSql, /* UTF-8 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const void **pzTail /* OUT: End of parsed string */ +){ + return sqlite3Prepare16(db,zSql,nBytes,1,ppStmt,pzTail); +} + #endif /* SQLITE_OMIT_UTF16 */ diff --git a/dlls/sqlite/sqlite-source/printf.c b/dlls/sqlite/sqlite-source/printf.c index 43b353b0..a05fec21 100644 --- a/dlls/sqlite/sqlite-source/printf.c +++ b/dlls/sqlite/sqlite-source/printf.c @@ -230,7 +230,7 @@ static int vxprintf( char buf[etBUFSIZE]; /* Conversion buffer */ char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ etByte errorflag = 0; /* True if an error is encountered */ - etByte xtype = 0; /* Conversion paradigm */ + etByte xtype; /* Conversion paradigm */ char *zExtra; /* Extra memory used for etTCLESCAPE conversions */ static const char spaces[] = " "; @@ -333,6 +333,8 @@ static int vxprintf( infop = &fmtinfo[idx]; if( useExtended || (infop->flags & FLAG_INTERN)==0 ){ xtype = infop->type; + }else{ + return -1; } break; } @@ -804,29 +806,28 @@ char *sqlite3MPrintf(const char *zFormat, ...){ } /* -** Print into memory obtained from malloc(). Do not use the internal -** %-conversion extensions. This routine is for use by external users. +** Print into memory obtained from sqlite3_malloc(). Omit the internal +** %-conversion extensions. +*/ +char *sqlite3_vmprintf(const char *zFormat, va_list ap){ + char zBase[SQLITE_PRINT_BUF_SIZE]; + return base_vprintf(sqlite3_realloc, 0, zBase, sizeof(zBase), zFormat, ap); +} + +/* +** Print into memory obtained from sqlite3_malloc()(). Omit the internal +** %-conversion extensions. */ char *sqlite3_mprintf(const char *zFormat, ...){ va_list ap; char *z; - char zBuf[200]; - - va_start(ap,zFormat); - z = base_vprintf((void*(*)(void*,int))realloc, 0, - zBuf, sizeof(zBuf), zFormat, ap); + char zBase[SQLITE_PRINT_BUF_SIZE]; + va_start(ap, zFormat); + z = base_vprintf(sqlite3_realloc, 0, zBase, sizeof(zBase), zFormat, ap); va_end(ap); return z; } -/* This is the varargs version of sqlite3_mprintf. -*/ -char *sqlite3_vmprintf(const char *zFormat, va_list ap){ - char zBuf[200]; - return base_vprintf((void*(*)(void*,int))realloc, 0, - zBuf, sizeof(zBuf), zFormat, ap); -} - /* ** sqlite3_snprintf() works like snprintf() except that it ignores the ** current locale settings. This is important for SQLite because we @@ -856,7 +857,7 @@ void sqlite3DebugPrintf(const char *zFormat, ...){ va_start(ap, zFormat); base_vprintf(0, 0, zBuf, sizeof(zBuf), zFormat, ap); va_end(ap); - fprintf(stdout,"%d: %s", getpid(), zBuf); + fprintf(stdout,"%s", zBuf); fflush(stdout); } #endif diff --git a/dlls/sqlite/sqlite-source/random.c b/dlls/sqlite/sqlite-source/random.c index 51d5d72e..5adc84aa 100644 --- a/dlls/sqlite/sqlite-source/random.c +++ b/dlls/sqlite/sqlite-source/random.c @@ -37,7 +37,7 @@ ** (Later): Actually, OP_NewRowid does not depend on a good source of ** randomness any more. But we will leave this code in all the same. */ -static int randomByte(){ +static int randomByte(void){ unsigned char t; /* All threads share a single random number generator. diff --git a/dlls/sqlite/sqlite-source/select.c b/dlls/sqlite/sqlite-source/select.c index 96e6c938..a7715218 100644 --- a/dlls/sqlite/sqlite-source/select.c +++ b/dlls/sqlite/sqlite-source/select.c @@ -72,9 +72,9 @@ Select *sqlite3SelectNew( pNew->pOffset = pOffset; pNew->iLimit = -1; pNew->iOffset = -1; - pNew->addrOpenVirt[0] = -1; - pNew->addrOpenVirt[1] = -1; - pNew->addrOpenVirt[2] = -1; + pNew->addrOpenEphm[0] = -1; + pNew->addrOpenEphm[1] = -1; + pNew->addrOpenEphm[2] = -1; if( pNew==&standin) { clearSelect(pNew); pNew = 0; @@ -187,7 +187,7 @@ static void setToken(Token *p, const char *z){ /* ** Create an expression node for an identifier with the name of zName */ -static Expr *createIdExpr(const char *zName){ +Expr *sqlite3CreateIdExpr(const char *zName){ Token dummy; setToken(&dummy, zName); return sqlite3Expr(TK_ID, 0, 0, &dummy); @@ -211,22 +211,27 @@ static void addWhereTerm( Expr *pE2a, *pE2b, *pE2c; Expr *pE; - pE1a = createIdExpr(zCol); - pE2a = createIdExpr(zCol); + pE1a = sqlite3CreateIdExpr(zCol); + pE2a = sqlite3CreateIdExpr(zCol); if( zAlias1==0 ){ zAlias1 = pTab1->zName; } - pE1b = createIdExpr(zAlias1); + pE1b = sqlite3CreateIdExpr(zAlias1); if( zAlias2==0 ){ zAlias2 = pTab2->zName; } - pE2b = createIdExpr(zAlias2); - pE1c = sqlite3Expr(TK_DOT, pE1b, pE1a, 0); - pE2c = sqlite3Expr(TK_DOT, pE2b, pE2a, 0); - pE = sqlite3Expr(TK_EQ, pE1c, pE2c, 0); - ExprSetProperty(pE, EP_FromJoin); - pE->iRightJoinTable = iRightJoinTable; - *ppExpr = sqlite3ExprAnd(*ppExpr, pE); + pE2b = sqlite3CreateIdExpr(zAlias2); + pE1c = sqlite3ExprOrFree(TK_DOT, pE1b, pE1a, 0); + pE2c = sqlite3ExprOrFree(TK_DOT, pE2b, pE2a, 0); + pE = sqlite3ExprOrFree(TK_EQ, pE1c, pE2c, 0); + if( pE ){ + ExprSetProperty(pE, EP_FromJoin); + pE->iRightJoinTable = iRightJoinTable; + } + pE = sqlite3ExprAnd(*ppExpr, pE); + if( pE ){ + *ppExpr = pE; + } } /* @@ -296,8 +301,8 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ /* When the NATURAL keyword is present, add WHERE clause terms for ** every column that the two tables have in common. */ - if( pLeft->jointype & JT_NATURAL ){ - if( pLeft->pOn || pLeft->pUsing ){ + if( pRight->jointype & JT_NATURAL ){ + if( pRight->pOn || pRight->pUsing ){ sqlite3ErrorMsg(pParse, "a NATURAL join may not have " "an ON or USING clause", 0); return 1; @@ -315,7 +320,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ /* Disallow both ON and USING clauses in the same join */ - if( pLeft->pOn && pLeft->pUsing ){ + if( pRight->pOn && pRight->pUsing ){ sqlite3ErrorMsg(pParse, "cannot have both ON and USING " "clauses in the same join"); return 1; @@ -324,10 +329,10 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ /* Add the ON clause to the end of the WHERE clause, connected by ** an AND operator. */ - if( pLeft->pOn ){ - setJoinExpr(pLeft->pOn, pRight->iCursor); - p->pWhere = sqlite3ExprAnd(p->pWhere, pLeft->pOn); - pLeft->pOn = 0; + if( pRight->pOn ){ + setJoinExpr(pRight->pOn, pRight->iCursor); + p->pWhere = sqlite3ExprAnd(p->pWhere, pRight->pOn); + pRight->pOn = 0; } /* Create extra terms on the WHERE clause for each column named @@ -337,8 +342,8 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ ** Report an error if any column mentioned in the USING clause is ** not contained in both tables to be joined. */ - if( pLeft->pUsing ){ - IdList *pList = pLeft->pUsing; + if( pRight->pUsing ){ + IdList *pList = pRight->pUsing; for(j=0; jnId; j++){ char *zName = pList->a[j].zName; if( columnIndex(pLeftTab, zName)<0 || columnIndex(pRightTab, zName)<0 ){ @@ -522,7 +527,7 @@ static int selectInnerLoop( /* Store the result as data using a unique key. */ case SRT_Table: - case SRT_VirtualTab: { + case SRT_EphemTab: { sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0); if( pOrderBy ){ pushOntoSorter(pParse, pOrderBy, p); @@ -705,7 +710,7 @@ static void generateSortTail( sqlite3VdbeAddOp(v, OP_Column, iTab, pOrderBy->nExpr + 1); switch( eDest ){ case SRT_Table: - case SRT_VirtualTab: { + case SRT_EphemTab: { sqlite3VdbeAddOp(v, OP_NewRowid, iParm, 0); sqlite3VdbeAddOp(v, OP_Pull, 1, 0); sqlite3VdbeAddOp(v, OP_Insert, iParm, 0); @@ -805,6 +810,7 @@ static const char *columnType( assert( pExpr->op!=TK_AS ); switch( pExpr->op ){ + case TK_AGG_COLUMN: case TK_COLUMN: { /* The expression is a column. Locate the table the column is being ** extracted from in NameContext.pSrcList. This table may be real @@ -840,7 +846,6 @@ static const char *columnType( } assert( pTab ); -#ifndef SQLITE_OMIT_SUBQUERY if( pS ){ /* The "table" is actually a sub-select or a view in the FROM clause ** of the SELECT statement. Return the declaration type and origin @@ -858,9 +863,7 @@ static const char *columnType( sNC.pParse = pNC->pParse; zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol); } - }else -#endif - if( pTab->pSchema ){ + }else if( pTab->pSchema ){ /* A real table */ assert( !pS ); if( iCol<0 ) iCol = pTab->iPKey; @@ -1068,7 +1071,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){ Expr *p, *pR; char *zType; char *zName; - char *zBasename; + int nName; CollSeq *pColl; int cnt; NameContext sNC; @@ -1101,17 +1104,15 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){ /* Make sure the column name is unique. If the name is not unique, ** append a integer to the name so that it becomes unique. */ - zBasename = zName; + nName = strlen(zName); for(j=cnt=0; jzName = zName; /* Get the typename, type affinity, and collating sequence for the @@ -1200,11 +1201,11 @@ static int prepSelectStmt(Parse *pParse, Select *p){ if( pTab==0 ){ return 1; } - /* The isTransient flag indicates that the Table structure has been + /* The isEphem flag indicates that the Table structure has been ** dynamically allocated and may be freed at any time. In other words, ** pTab is not pointing to a persistent table structure that defines ** part of the schema. */ - pTab->isTransient = 1; + pTab->isEphem = 1; #endif }else{ /* An ordinary table or view name in the FROM clause */ @@ -1215,8 +1216,8 @@ static int prepSelectStmt(Parse *pParse, Select *p){ return 1; } pTab->nRef++; -#ifndef SQLITE_OMIT_VIEW - if( pTab->pSelect ){ +#if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE) + if( pTab->pSelect || IsVirtual(pTab) ){ /* We reach here if the named table is a really a view */ if( sqlite3ViewGetColumnNames(pParse, pTab) ){ return 1; @@ -1308,13 +1309,13 @@ static int prepSelectStmt(Parse *pParse, Select *p){ if( i>0 ){ struct SrcList_item *pLeft = &pTabList->a[i-1]; - if( (pLeft->jointype & JT_NATURAL)!=0 && + if( (pLeft[1].jointype & JT_NATURAL)!=0 && columnIndex(pLeft->pTab, zName)>=0 ){ /* In a NATURAL join, omit the join columns from the ** table on the right */ continue; } - if( sqlite3IdListIndex(pLeft->pUsing, zName)>=0 ){ + if( sqlite3IdListIndex(pLeft[1].pUsing, zName)>=0 ){ /* In a join with a USING clause, omit columns in the ** using clause from the table on the right. */ continue; @@ -1537,10 +1538,10 @@ static void createSortingIndex(Parse *pParse, Select *p, ExprList *pOrderBy){ int addr; assert( pOrderBy->iECursor==0 ); pOrderBy->iECursor = pParse->nTab++; - addr = sqlite3VdbeAddOp(pParse->pVdbe, OP_OpenVirtual, + addr = sqlite3VdbeAddOp(pParse->pVdbe, OP_OpenEphemeral, pOrderBy->iECursor, pOrderBy->nExpr+1); - assert( p->addrOpenVirt[2] == -1 ); - p->addrOpenVirt[2] = addr; + assert( p->addrOpenEphm[2] == -1 ); + p->addrOpenEphm[2] = addr; } } @@ -1646,10 +1647,10 @@ static int multiSelect( /* Create the destination temporary table if necessary */ - if( eDest==SRT_VirtualTab ){ + if( eDest==SRT_EphemTab ){ assert( p->pEList ); assert( nSetP2addrOpenVirt[0] == -1 ); - p->addrOpenVirt[0] = addr; - p->pRightmost->usesVirt = 1; + assert( p->addrOpenEphm[0] == -1 ); + p->addrOpenEphm[0] = addr; + p->pRightmost->usesEphm = 1; } createSortingIndex(pParse, p, pOrderBy); assert( p->pEList ); @@ -1807,10 +1808,10 @@ static int multiSelect( } createSortingIndex(pParse, p, pOrderBy); - addr = sqlite3VdbeAddOp(v, OP_OpenVirtual, tab1, 0); - assert( p->addrOpenVirt[0] == -1 ); - p->addrOpenVirt[0] = addr; - p->pRightmost->usesVirt = 1; + addr = sqlite3VdbeAddOp(v, OP_OpenEphemeral, tab1, 0); + assert( p->addrOpenEphm[0] == -1 ); + p->addrOpenEphm[0] = addr; + p->pRightmost->usesEphm = 1; assert( p->pEList ); /* Code the SELECTs to our left into temporary table "tab1". @@ -1822,9 +1823,9 @@ static int multiSelect( /* Code the current SELECT into temporary table "tab2" */ - addr = sqlite3VdbeAddOp(v, OP_OpenVirtual, tab2, 0); - assert( p->addrOpenVirt[1] == -1 ); - p->addrOpenVirt[1] = addr; + addr = sqlite3VdbeAddOp(v, OP_OpenEphemeral, tab2, 0); + assert( p->addrOpenEphm[1] == -1 ); + p->addrOpenEphm[1] = addr; p->pPrior = 0; pLimit = p->pLimit; p->pLimit = 0; @@ -1898,15 +1899,17 @@ static int multiSelect( ** SELECT might also skip this part if it has no ORDER BY clause and ** no temp tables are required. */ - if( pOrderBy || p->usesVirt ){ + if( pOrderBy || p->usesEphm ){ int i; /* Loop counter */ KeyInfo *pKeyInfo; /* Collating sequence for the result set */ Select *pLoop; /* For looping through SELECT statements */ + int nKeyCol; /* Number of entries in pKeyInfo->aCol[] */ CollSeq **apColl; CollSeq **aCopy; assert( p->pRightmost==p ); - pKeyInfo = sqliteMalloc(sizeof(*pKeyInfo)+nCol*2*sizeof(CollSeq*) + nCol); + nKeyCol = nCol + (pOrderBy ? pOrderBy->nExpr : 0); + pKeyInfo = sqliteMalloc(sizeof(*pKeyInfo)+nKeyCol*(sizeof(CollSeq*) + 1)); if( !pKeyInfo ){ rc = SQLITE_NOMEM; goto multi_select_end; @@ -1924,15 +1927,16 @@ static int multiSelect( for(pLoop=p; pLoop; pLoop=pLoop->pPrior){ for(i=0; i<2; i++){ - int addr = pLoop->addrOpenVirt[i]; + int addr = pLoop->addrOpenEphm[i]; if( addr<0 ){ /* If [0] is unused then [1] is also unused. So we can ** always safely abort as soon as the first unused slot is found */ - assert( pLoop->addrOpenVirt[1]<0 ); + assert( pLoop->addrOpenEphm[1]<0 ); break; } sqlite3VdbeChangeP2(v, addr, nCol); sqlite3VdbeChangeP3(v, addr, (char*)pKeyInfo, P3_KEYINFO); + pLoop->addrOpenEphm[i] = -1; } } @@ -1942,24 +1946,23 @@ static int multiSelect( int addr; u8 *pSortOrder; - aCopy = &pKeyInfo->aColl[nCol]; + aCopy = &pKeyInfo->aColl[nOrderByExpr]; pSortOrder = pKeyInfo->aSortOrder = (u8*)&aCopy[nCol]; memcpy(aCopy, pKeyInfo->aColl, nCol*sizeof(CollSeq*)); apColl = pKeyInfo->aColl; for(i=0; ipExpr; - char *zName = pOTerm->zName; - assert( pExpr->op==TK_COLUMN && pExpr->iColumnflags & EP_ExpCollate) ){ + assert( pExpr->pColl!=0 ); + *apColl = pExpr->pColl; }else{ *apColl = aCopy[pExpr->iColumn]; } *pSortOrder = pOTerm->sortOrder; } assert( p->pRightmost==p ); - assert( p->addrOpenVirt[2]>=0 ); - addr = p->addrOpenVirt[2]; + assert( p->addrOpenEphm[2]>=0 ); + addr = p->addrOpenEphm[2]; sqlite3VdbeChangeP2(v, addr, p->pEList->nExpr+2); pKeyInfo->nField = nOrderByExpr; sqlite3VdbeChangeP3(v, addr, (char*)pKeyInfo, P3_KEYINFO_HANDOFF); @@ -2010,6 +2013,7 @@ static void substExpr(Expr *pExpr, int iTable, ExprList *pEList){ assert( pExpr->pList==0 ); pExpr->pList = sqlite3ExprListDup(pNew->pList); pExpr->iTable = pNew->iTable; + pExpr->pTab = pNew->pTab; pExpr->iColumn = pNew->iColumn; pExpr->iAgg = pNew->iAgg; sqlite3TokenCopy(&pExpr->token, &pNew->token); @@ -2171,7 +2175,7 @@ static int flattenSubquery( ** ** which is not at all the same thing. */ - if( pSubSrc->nSrc>1 && iFrom>0 && (pSrc->a[iFrom-1].jointype & JT_OUTER)!=0 ){ + if( pSubSrc->nSrc>1 && (pSubitem->jointype & JT_OUTER)!=0 ){ return 0; } @@ -2188,8 +2192,7 @@ static int flattenSubquery( ** But the t2.x>0 test will always fail on a NULL row of t2, which ** effectively converts the OUTER JOIN into an INNER JOIN. */ - if( iFrom>0 && (pSrc->a[iFrom-1].jointype & JT_OUTER)!=0 - && pSub->pWhere!=0 ){ + if( (pSubitem->jointype & JT_OUTER)!=0 && pSub->pWhere!=0 ){ return 0; } @@ -2228,7 +2231,7 @@ static int flattenSubquery( pSrc->a[i+iFrom] = pSubSrc->a[i]; memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i])); } - pSrc->a[iFrom+nSubSrc-1].jointype = jointype; + pSrc->a[iFrom].jointype = jointype; } /* Now begin substituting subquery result set expressions for @@ -2374,6 +2377,7 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){ pIdx = 0; }else{ CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr); + if( pColl==0 ) return 0; for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ assert( pIdx->nColumn>=1 ); if( pIdx->aiColumn[0]==iCol && @@ -2393,8 +2397,8 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){ /* If the output is destined for a temporary table, open that table. */ - if( eDest==SRT_VirtualTab ){ - sqlite3VdbeAddOp(v, OP_OpenVirtual, iParm, 1); + if( eDest==SRT_EphemTab ){ + sqlite3VdbeAddOp(v, OP_OpenEphemeral, iParm, 1); } /* Generating code to find the min or the max. Basically all we have @@ -2403,7 +2407,7 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){ ** or last entry in the main table. */ iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - assert( iDb>=0 || pTab->isTransient ); + assert( iDb>=0 || pTab->isEphem ); sqlite3CodeVerifySchema(pParse, iDb); sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); base = pSrc->a[0].iCursor; @@ -2473,8 +2477,14 @@ static int processOrderGroupBy( Expr *pE = pOrderBy->a[i].pExpr; if( sqlite3ExprIsInteger(pE, &iCol) ){ if( iCol>0 && iCol<=pEList->nExpr ){ + CollSeq *pColl = pE->pColl; + int flags = pE->flags & EP_ExpCollate; sqlite3ExprDelete(pE); pE = pOrderBy->a[i].pExpr = sqlite3ExprDup(pEList->a[iCol-1].pExpr); + if( pColl && flags ){ + pE->pColl = pColl; + pE->flags |= flags; + } }else{ sqlite3ErrorMsg(pParse, "%s BY column number %d out of range - should be " @@ -2485,11 +2495,6 @@ static int processOrderGroupBy( if( sqlite3ExprResolveNames(pNC, pE) ){ return 1; } - if( sqlite3ExprIsConstant(pE) ){ - sqlite3ErrorMsg(pParse, - "%s BY terms must not be non-integer constants", zType); - return 1; - } } return 0; } @@ -2605,7 +2610,14 @@ int sqlite3SelectResolve( } } - return SQLITE_OK; + /* If this is one SELECT of a compound, be sure to resolve names + ** in the other SELECTs. + */ + if( p->pPrior ){ + return sqlite3SelectResolve(pParse, p->pPrior, pOuterNC); + }else{ + return SQLITE_OK; + } } /* @@ -2635,7 +2647,7 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ pFunc->iDistinct = -1; }else{ KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->pList); - sqlite3VdbeOp3(v, OP_OpenVirtual, pFunc->iDistinct, 0, + sqlite3VdbeOp3(v, OP_OpenEphemeral, pFunc->iDistinct, 0, (char*)pKeyInfo, P3_KEYINFO_HANDOFF); } } @@ -2775,8 +2787,8 @@ int sqlite3Select( WhereInfo *pWInfo; /* Return from sqlite3WhereBegin() */ Vdbe *v; /* The virtual machine under construction */ int isAgg; /* True for select lists like "count(*)" */ - ExprList *pEList=NULL; /* List of columns to extract. */ - SrcList *pTabList=NULL; /* List of tables to select from */ + ExprList *pEList; /* List of columns to extract. */ + SrcList *pTabList; /* List of tables to select from */ Expr *pWhere; /* The WHERE clause. May be NULL */ ExprList *pOrderBy; /* The ORDER BY clause. May be NULL */ ExprList *pGroupBy; /* The GROUP BY clause. May be NULL */ @@ -2784,7 +2796,7 @@ int sqlite3Select( int isDistinct; /* True if the DISTINCT keyword is present */ int distinct; /* Table to use for the distinct set */ int rc = 1; /* Value to return from this function */ - int addrSortIndex; /* Address of an OP_OpenVirtual instruction */ + int addrSortIndex; /* Address of an OP_OpenEphemeral instruction */ AggInfo sAggInfo; /* Information used by aggregate queries */ int iEnd; /* Address of the end of the query */ @@ -2872,7 +2884,7 @@ int sqlite3Select( }else{ needRestoreContext = 0; } - sqlite3Select(pParse, pItem->pSelect, SRT_VirtualTab, + sqlite3Select(pParse, pItem->pSelect, SRT_EphemTab, pItem->iCursor, p, i, &isAgg, 0); if( needRestoreContext ){ pParse->zAuthContext = zSavedAuthContext; @@ -2907,53 +2919,44 @@ int sqlite3Select( } #endif - /* If there is an ORDER BY clause, resolve any collation sequences - ** names that have been explicitly specified and create a sorting index. - ** - ** This sorting index might end up being unused if the data can be + /* If there is an ORDER BY clause, then this sorting + ** index might end up being unused if the data can be ** extracted in pre-sorted order. If that is the case, then the - ** OP_OpenVirtual instruction will be changed to an OP_Noop once + ** OP_OpenEphemeral instruction will be changed to an OP_Noop once ** we figure out that the sorting index is not needed. The addrSortIndex ** variable is used to facilitate that change. */ if( pOrderBy ){ - struct ExprList_item *pTerm; KeyInfo *pKeyInfo; - for(i=0, pTerm=pOrderBy->a; inExpr; i++, pTerm++){ - if( pTerm->zName ){ - pTerm->pExpr->pColl = sqlite3LocateCollSeq(pParse, pTerm->zName, -1); - } - } if( pParse->nErr ){ goto select_end; } pKeyInfo = keyInfoFromExprList(pParse, pOrderBy); pOrderBy->iECursor = pParse->nTab++; - p->addrOpenVirt[2] = addrSortIndex = - sqlite3VdbeOp3(v, OP_OpenVirtual, pOrderBy->iECursor, pOrderBy->nExpr+2, - (char*)pKeyInfo, P3_KEYINFO_HANDOFF); + p->addrOpenEphm[2] = addrSortIndex = + sqlite3VdbeOp3(v, OP_OpenEphemeral, pOrderBy->iECursor, pOrderBy->nExpr+2, (char*)pKeyInfo, P3_KEYINFO_HANDOFF); }else{ addrSortIndex = -1; } + /* If the output is destined for a temporary table, open that table. + */ + if( eDest==SRT_EphemTab ){ + sqlite3VdbeAddOp(v, OP_OpenEphemeral, iParm, pEList->nExpr); + } + /* Set the limiter. */ iEnd = sqlite3VdbeMakeLabel(v); computeLimitRegisters(pParse, p, iEnd); - /* If the output is destined for a temporary table, open that table. - */ - if( eDest==SRT_VirtualTab ){ - sqlite3VdbeAddOp(v, OP_OpenVirtual, iParm, pEList->nExpr); - } - /* Open a virtual index to use for the distinct set. */ if( isDistinct ){ KeyInfo *pKeyInfo; distinct = pParse->nTab++; pKeyInfo = keyInfoFromExprList(pParse, p->pEList); - sqlite3VdbeOp3(v, OP_OpenVirtual, distinct, 0, + sqlite3VdbeOp3(v, OP_OpenEphemeral, distinct, 0, (char*)pKeyInfo, P3_KEYINFO_HANDOFF); }else{ distinct = -1; @@ -2967,13 +2970,13 @@ int sqlite3Select( pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pOrderBy); if( pWInfo==0 ) goto select_end; - /* If sorting index that was created by a prior OP_OpenVirtual - ** instruction ended up not being needed, then change the OP_OpenVirtual + /* If sorting index that was created by a prior OP_OpenEphemeral + ** instruction ended up not being needed, then change the OP_OpenEphemeral ** into an OP_Noop. */ if( addrSortIndex>=0 && pOrderBy==0 ){ sqlite3VdbeChangeToNoop(v, addrSortIndex, 1); - p->addrOpenVirt[2] = -1; + p->addrOpenEphm[2] = -1; } /* Use the standard inner loop @@ -3007,7 +3010,7 @@ int sqlite3Select( int addrGroupByChange; /* Code that runs when any GROUP BY term changes */ int addrProcessRow; /* Code to process a single input row */ int addrEnd; /* End of all processing */ - int addrSortingIdx; /* The OP_OpenVirtual for the sorting index */ + int addrSortingIdx; /* The OP_OpenEphemeral for the sorting index */ int addrReset; /* Subroutine for resetting the accumulator */ addrEnd = sqlite3VdbeMakeLabel(v); @@ -3054,13 +3057,13 @@ int sqlite3Select( /* If there is a GROUP BY clause we might need a sorting index to ** implement it. Allocate that sorting index now. If it turns out - ** that we do not need it after all, the OpenVirtual instruction + ** that we do not need it after all, the OpenEphemeral instruction ** will be converted into a Noop. */ sAggInfo.sortingIdx = pParse->nTab++; pKeyInfo = keyInfoFromExprList(pParse, pGroupBy); addrSortingIdx = - sqlite3VdbeOp3(v, OP_OpenVirtual, sAggInfo.sortingIdx, + sqlite3VdbeOp3(v, OP_OpenEphemeral, sAggInfo.sortingIdx, sAggInfo.nSortingColumn, (char*)pKeyInfo, P3_KEYINFO_HANDOFF); @@ -3123,7 +3126,7 @@ int sqlite3Select( if( pWInfo==0 ) goto select_end; if( pGroupBy==0 ){ /* The optimizer is able to deliver rows in group by order so - ** we do not have to sort. The OP_OpenVirtual table will be + ** we do not have to sort. The OP_OpenEphemeral table will be ** cancelled later because we still need to use the pKeyInfo */ pGroupBy = p->pGroupBy; @@ -3294,3 +3297,99 @@ select_end: sqliteFree(sAggInfo.aFunc); return rc; } + +#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) +/* +******************************************************************************* +** The following code is used for testing and debugging only. The code +** that follows does not appear in normal builds. +** +** These routines are used to print out the content of all or part of a +** parse structures such as Select or Expr. Such printouts are useful +** for helping to understand what is happening inside the code generator +** during the execution of complex SELECT statements. +** +** These routine are not called anywhere from within the normal +** code base. Then are intended to be called from within the debugger +** or from temporary "printf" statements inserted for debugging. +*/ +void sqlite3PrintExpr(Expr *p){ + if( p->token.z && p->token.n>0 ){ + sqlite3DebugPrintf("(%.*s", p->token.n, p->token.z); + }else{ + sqlite3DebugPrintf("(%d", p->op); + } + if( p->pLeft ){ + sqlite3DebugPrintf(" "); + sqlite3PrintExpr(p->pLeft); + } + if( p->pRight ){ + sqlite3DebugPrintf(" "); + sqlite3PrintExpr(p->pRight); + } + sqlite3DebugPrintf(")"); +} +void sqlite3PrintExprList(ExprList *pList){ + int i; + for(i=0; inExpr; i++){ + sqlite3PrintExpr(pList->a[i].pExpr); + if( inExpr-1 ){ + sqlite3DebugPrintf(", "); + } + } +} +void sqlite3PrintSelect(Select *p, int indent){ + sqlite3DebugPrintf("%*sSELECT(%p) ", indent, "", p); + sqlite3PrintExprList(p->pEList); + sqlite3DebugPrintf("\n"); + if( p->pSrc ){ + char *zPrefix; + int i; + zPrefix = "FROM"; + for(i=0; ipSrc->nSrc; i++){ + struct SrcList_item *pItem = &p->pSrc->a[i]; + sqlite3DebugPrintf("%*s ", indent+6, zPrefix); + zPrefix = ""; + if( pItem->pSelect ){ + sqlite3DebugPrintf("(\n"); + sqlite3PrintSelect(pItem->pSelect, indent+10); + sqlite3DebugPrintf("%*s)", indent+8, ""); + }else if( pItem->zName ){ + sqlite3DebugPrintf("%s", pItem->zName); + } + if( pItem->pTab ){ + sqlite3DebugPrintf("(table: %s)", pItem->pTab->zName); + } + if( pItem->zAlias ){ + sqlite3DebugPrintf(" AS %s", pItem->zAlias); + } + if( ipSrc->nSrc-1 ){ + sqlite3DebugPrintf(","); + } + sqlite3DebugPrintf("\n"); + } + } + if( p->pWhere ){ + sqlite3DebugPrintf("%*s WHERE ", indent, ""); + sqlite3PrintExpr(p->pWhere); + sqlite3DebugPrintf("\n"); + } + if( p->pGroupBy ){ + sqlite3DebugPrintf("%*s GROUP BY ", indent, ""); + sqlite3PrintExprList(p->pGroupBy); + sqlite3DebugPrintf("\n"); + } + if( p->pHaving ){ + sqlite3DebugPrintf("%*s HAVING ", indent, ""); + sqlite3PrintExpr(p->pHaving); + sqlite3DebugPrintf("\n"); + } + if( p->pOrderBy ){ + sqlite3DebugPrintf("%*s ORDER BY ", indent, ""); + sqlite3PrintExprList(p->pOrderBy); + sqlite3DebugPrintf("\n"); + } +} +/* End of the structure debug printing code +*****************************************************************************/ +#endif /* defined(SQLITE_TEST) || defined(SQLITE_DEBUG) */ diff --git a/dlls/sqlite/sqlite-source/shell.c b/dlls/sqlite/sqlite-source/shell.c index 8aafed42..0cf75e20 100644 --- a/dlls/sqlite/sqlite-source/shell.c +++ b/dlls/sqlite/sqlite-source/shell.c @@ -21,7 +21,7 @@ #include "sqlite3.h" #include -#if !defined(_WIN32) && !defined(WIN32) && !defined(__MACOS__) +#if !defined(_WIN32) && !defined(WIN32) && !defined(__MACOS__) && !defined(__OS2__) # include # include # include @@ -37,6 +37,10 @@ # include #endif +#ifdef __OS2__ +# include +#endif + #if defined(HAVE_READLINE) && HAVE_READLINE==1 # include # include @@ -48,9 +52,25 @@ # define stifle_history(X) #endif +#if defined(_WIN32) || defined(WIN32) +# include +#else /* Make sure isatty() has a prototype. */ extern int isatty(); +#endif + +/* +** If the following flag is set, then command execution stops +** at an error if we are not interactive. +*/ +static int bail_on_error = 0; + +/* +** Threat stdin as an interactive input if the following variable +** is true. Otherwise, assume stdin is connected to a file or pipe. +*/ +static int stdin_is_interactive = 1; /* ** The following is the open SQLite database. We make a pointer @@ -176,10 +196,7 @@ static char *local_getline(char *zPrompt, FILE *in){ } /* -** Retrieve a single line of input text. "isatty" is true if text -** is coming from a terminal. In that case, we issue a prompt and -** attempt to use "readline" for command-line editing. If "isatty" -** is false, use "local_getline" instead of "readline" and issue no prompt. +** Retrieve a single line of input text. ** ** zPrior is a string of prior text retrieved. If not the empty ** string, then issue a continuation prompt. @@ -197,7 +214,7 @@ static char *one_input_line(const char *zPrior, FILE *in){ } zResult = readline(zPrompt); #if defined(HAVE_READLINE) && HAVE_READLINE==1 - if( zResult ) add_history(zResult); + if( zResult && *zResult ) add_history(zResult); #endif return zResult; } @@ -208,6 +225,7 @@ struct previous_mode_data { int showHeader; int colWidth[100]; }; + /* ** An pointer to an instance of this structure is passed from ** the main program to the callback. This is used to communicate @@ -219,6 +237,7 @@ struct callback_data { int cnt; /* Number of records displayed so far */ FILE *out; /* Write results here */ int mode; /* An output mode setting */ + int writableSchema; /* True if PRAGMA writable_schema=ON */ int showHeader; /* True to show column names in List or Column mode */ char *zDestTable; /* Name of destination table when MODE_Insert */ char separator[20]; /* Separator character for MODE_List */ @@ -231,7 +250,6 @@ struct callback_data { ** .explain ON */ char outfile[FILENAME_MAX]; /* Filename for *out */ const char *zDbFilename; /* name of the database file */ - char *zKey; /* Encryption key */ }; /* @@ -343,6 +361,29 @@ static void output_html_string(FILE *out, const char *z){ } } +/* +** If a field contains any character identified by a 1 in the following +** array, then the string must be quoted for CSV. +*/ +static const char needCsvQuote[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + /* ** Output a single term of CSV. Actually, p->separator is used for ** the separator, which may or may not be a comma. p->nullvalue is @@ -350,12 +391,27 @@ static void output_html_string(FILE *out, const char *z){ ** appear outside of quotes. */ static void output_csv(struct callback_data *p, const char *z, int bSep){ + FILE *out = p->out; if( z==0 ){ - fprintf(p->out,"%s",p->nullvalue); - }else if( isNumber(z, 0) ){ - fprintf(p->out,"%s",z); + fprintf(out,"%s",p->nullvalue); }else{ - output_c_string(p->out, z); + int i; + for(i=0; z[i]; i++){ + if( needCsvQuote[((unsigned char*)z)[i]] ){ + i = 0; + break; + } + } + if( i==0 ){ + putc('"', out); + for(i=0; z[i]; i++){ + if( z[i]=='"' ) putc('"', out); + putc(z[i], out); + } + putc('"', out); + }else{ + fprintf(out, "%s", z); + } } if( bSep ){ fprintf(p->out, p->separator); @@ -384,12 +440,12 @@ static int callback(void *pArg, int nArg, char **azArg, char **azCol){ int w = 5; if( azArg==0 ) break; for(i=0; iw ) w = len; } if( p->cnt++>0 ) fprintf(p->out,"\n"); for(i=0; iout,"%*s = %s\n", w, azCol[i], + fprintf(p->out,"%*s = %s\n", w, azCol[i], azArg[i] ? azArg[i] : p->nullvalue); } break; @@ -486,7 +542,7 @@ static int callback(void *pArg, int nArg, char **azArg, char **azCol){ case MODE_Tcl: { if( p->cnt++==0 && p->showHeader ){ for(i=0; iout,azCol[i]); + output_c_string(p->out,azCol[i] ? azCol[i] : ""); fprintf(p->out, "%s", p->separator); } fprintf(p->out,"\n"); @@ -502,7 +558,7 @@ static int callback(void *pArg, int nArg, char **azArg, char **azCol){ case MODE_Csv: { if( p->cnt++==0 && p->showHeader ){ for(i=0; iout,"\n"); } @@ -580,7 +636,7 @@ static void set_table_name(struct callback_data *p, const char *zName){ ** If the third argument, quote, is not '\0', then it is used as a ** quote character for zAppend. */ -static char * appendText(char *zIn, char const *zAppend, char quote){ +static char *appendText(char *zIn, char const *zAppend, char quote){ int len; int i; int nAppend = strlen(zAppend); @@ -621,6 +677,9 @@ static char * appendText(char *zIn, char const *zAppend, char quote){ /* ** Execute a query statement that has a single result column. Print ** that result column on a line by itself with a semicolon terminator. +** +** This is used, for example, to show the schema of the database by +** querying the SQLITE_MASTER table. */ static int run_table_dump_query(FILE *out, sqlite3 *db, const char *zSelect){ sqlite3_stmt *pSelect; @@ -662,6 +721,19 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ fprintf(p->out, "ANALYZE sqlite_master;\n"); }else if( strncmp(zTable, "sqlite_", 7)==0 ){ return 0; + }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){ + char *zIns; + if( !p->writableSchema ){ + fprintf(p->out, "PRAGMA writable_schema=ON;\n"); + p->writableSchema = 1; + } + zIns = sqlite3_mprintf( + "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)" + "VALUES('table','%q','%q',0,'%q');", + zTable, zTable, zSql); + fprintf(p->out, "%s\n", zIns); + sqlite3_free(zIns); + return 0; }else{ fprintf(p->out, "%s;\n", zSql); } @@ -695,7 +767,7 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ zSelect = appendText(zSelect, zText, '"'); rc = sqlite3_step(pTableInfo); if( rc==SQLITE_ROW ){ - zSelect = appendText(zSelect, ") || ', ' || ", 0); + zSelect = appendText(zSelect, ") || ',' || ", 0); }else{ zSelect = appendText(zSelect, ") ", 0); } @@ -714,15 +786,14 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ rc = run_table_dump_query(p->out, p->db, zSelect); } if( zSelect ) free(zSelect); - if( rc!=SQLITE_OK ){ - return 1; - } } return 0; } /* -** Run zQuery. Update dump_callback() as the callback routine. +** Run zQuery. Use dump_callback() as the callback routine so that +** the contents of the query are output as SQL statements. +** ** If we get a SQLITE_CORRUPT error, rerun the query after appending ** "ORDER BY rowid DESC" to the end. */ @@ -750,6 +821,7 @@ static int run_schema_dump_query( ** Text of a help message */ static char zHelp[] = + ".bail ON|OFF Stop after hitting an error. Default OFF\n" ".databases List names and files of attached databases\n" ".dump ?TABLE? ... Dump the database in an SQL text format\n" ".echo ON|OFF Turn command echo on or off\n" @@ -759,6 +831,9 @@ static char zHelp[] = ".help Show this message\n" ".import FILE TABLE Import data from FILE into TABLE\n" ".indices TABLE Show names of all indices on TABLE\n" +#ifndef SQLITE_OMIT_LOAD_EXTENSION + ".load FILE ?ENTRY? Load an extension library\n" +#endif ".mode MODE ?TABLE? Set output mode where MODE is one of:\n" " csv Comma-separated values\n" " column Left-aligned columns. (See .width)\n" @@ -783,7 +858,7 @@ static char zHelp[] = ; /* Forward reference */ -static void process_input(struct callback_data *p, FILE *in); +static int process_input(struct callback_data *p, FILE *in); /* ** Make sure the database is open. If it is not, then open it. If @@ -800,6 +875,9 @@ static void open_db(struct callback_data *p){ p->zDbFilename, sqlite3_errmsg(db)); exit(1); } +#ifndef SQLITE_OMIT_LOAD_EXTENSION + sqlite3_enable_load_extension(p->db, 1); +#endif } } @@ -840,11 +918,28 @@ static void resolve_backslashes(char *z){ z[j] = 0; } +/* +** Interpret zArg as a boolean value. Return either 0 or 1. +*/ +static int booleanValue(char *zArg){ + int val = atoi(zArg); + int j; + for(j=0; zArg[j]; j++){ + zArg[j] = tolower(zArg[j]); + } + if( strcmp(zArg,"on")==0 ){ + val = 1; + }else if( strcmp(zArg,"yes")==0 ){ + val = 1; + } + return val; +} + /* ** If an input line begins with "." then invoke this routine to ** process that line. ** -** Return 1 to exit and 0 to continue. +** Return 1 on error, 2 to exit, and 0 otherwise. */ static int do_meta_command(char *zLine, struct callback_data *p){ int i = 1; @@ -879,6 +974,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){ if( nArg==0 ) return rc; n = strlen(azArg[0]); c = azArg[0][0]; + if( c=='b' && n>1 && strncmp(azArg[0], "bail", n)==0 && nArg>1 ){ + bail_on_error = booleanValue(azArg[1]); + }else + if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){ struct callback_data data; char *zErrMsg = 0; @@ -901,14 +1000,15 @@ static int do_meta_command(char *zLine, struct callback_data *p){ char *zErrMsg = 0; open_db(p); fprintf(p->out, "BEGIN TRANSACTION;\n"); + p->writableSchema = 0; if( nArg==1 ){ run_schema_dump_query(p, "SELECT name, type, sql FROM sqlite_master " "WHERE sql NOT NULL AND type=='table'", 0 ); - run_schema_dump_query(p, - "SELECT name, type, sql FROM sqlite_master " - "WHERE sql NOT NULL AND type!='table' AND type!='meta'", 0 + run_table_dump_query(p->out, p->db, + "SELECT sql FROM sqlite_master " + "WHERE sql NOT NULL AND type IN ('index','trigger','view')" ); }else{ int i; @@ -918,13 +1018,19 @@ static int do_meta_command(char *zLine, struct callback_data *p){ "SELECT name, type, sql FROM sqlite_master " "WHERE tbl_name LIKE shellstatic() AND type=='table'" " AND sql NOT NULL", 0); - run_schema_dump_query(p, - "SELECT name, type, sql FROM sqlite_master " - "WHERE tbl_name LIKE shellstatic() AND type!='table'" - " AND type!='meta' AND sql NOT NULL", 0); + run_table_dump_query(p->out, p->db, + "SELECT sql FROM sqlite_master " + "WHERE sql NOT NULL" + " AND type IN ('index','trigger','view')" + " AND tbl_name LIKE shellstatic()" + ); zShellStatic = 0; } } + if( p->writableSchema ){ + fprintf(p->out, "PRAGMA writable_schema=OFF;\n"); + p->writableSchema = 0; + } if( zErrMsg ){ fprintf(stderr,"Error: %s\n", zErrMsg); sqlite3_free(zErrMsg); @@ -934,37 +1040,15 @@ static int do_meta_command(char *zLine, struct callback_data *p){ }else if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){ - int j; - char *z = azArg[1]; - int val = atoi(azArg[1]); - for(j=0; z[j]; j++){ - z[j] = tolower((unsigned char)z[j]); - } - if( strcmp(z,"on")==0 ){ - val = 1; - }else if( strcmp(z,"yes")==0 ){ - val = 1; - } - p->echoOn = val; + p->echoOn = booleanValue(azArg[1]); }else if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){ - rc = 1; + rc = 2; }else if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){ - int j; - static char zOne[] = "1"; - char *z = nArg>=2 ? azArg[1] : zOne; - int val = atoi(z); - for(j=0; z[j]; j++){ - z[j] = tolower((unsigned char)z[j]); - } - if( strcmp(z,"on")==0 ){ - val = 1; - }else if( strcmp(z,"yes")==0 ){ - val = 1; - } + int val = nArg>=2 ? booleanValue(azArg[1]) : 1; if(val == 1) { if(!p->explainPrev.valid) { p->explainPrev.valid = 1; @@ -995,21 +1079,9 @@ static int do_meta_command(char *zLine, struct callback_data *p){ } }else - if( c=='h' && (strncmp(azArg[0], "header", n)==0 - || + if( c=='h' && (strncmp(azArg[0], "header", n)==0 || strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){ - int j; - char *z = azArg[1]; - int val = atoi(azArg[1]); - for(j=0; z[j]; j++){ - z[j] = tolower((unsigned char)z[j]); - } - if( strcmp(z,"on")==0 ){ - val = 1; - }else if( strcmp(z,"yes")==0 ){ - val = 1; - } - p->showHeader = val; + p->showHeader = booleanValue(azArg[1]); }else if( c=='h' && strncmp(azArg[0], "help", n)==0 ){ @@ -1032,6 +1104,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ FILE *in; /* The input file */ int lineno = 0; /* Line number of input file */ + open_db(p); nSep = strlen(p->separator); if( nSep==0 ){ fprintf(stderr, "non-null separator required for import\n"); @@ -1045,6 +1118,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ if( rc ){ fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db)); nCol = 0; + rc = 1; }else{ nCol = sqlite3_column_count(pStmt); } @@ -1065,7 +1139,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ if( rc ){ fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db)); sqlite3_finalize(pStmt); - return 0; + return 1; } in = fopen(zFile, "rb"); if( in==0 ){ @@ -1111,6 +1185,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ if( rc!=SQLITE_OK ){ fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db)); zCommit = "ROLLBACK"; + rc = 1; break; } } @@ -1144,6 +1219,23 @@ static int do_meta_command(char *zLine, struct callback_data *p){ } }else +#ifndef SQLITE_OMIT_LOAD_EXTENSION + if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){ + const char *zFile, *zProc; + char *zErrMsg = 0; + int rc; + zFile = azArg[1]; + zProc = nArg>=3 ? azArg[2] : 0; + open_db(p); + rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg); + if( rc!=SQLITE_OK ){ + fprintf(stderr, "%s\n", zErrMsg); + sqlite3_free(zErrMsg); + rc = 1; + } + }else +#endif + if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){ int n2 = strlen(azArg[1]); if( strncmp(azArg[1],"line",n2)==0 @@ -1174,7 +1266,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ set_table_name(p, "table"); } }else { - fprintf(stderr,"mode should be on of: " + fprintf(stderr,"mode should be one of: " "column csv html insert line list tabs tcl\n"); } }else @@ -1211,7 +1303,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ }else if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){ - rc = 1; + rc = 2; }else if( c=='r' && strncmp(azArg[0], "read", n)==0 && nArg==2 ){ @@ -1363,6 +1455,8 @@ static int do_meta_command(char *zLine, struct callback_data *p){ } printf("\n"); } + }else{ + rc = 1; } sqlite3_free_table(azResult); }else @@ -1442,24 +1536,40 @@ static int _is_command_terminator(const char *zLine){ ** is coming from a file or device. A prompt is issued and history ** is saved only if input is interactive. An interrupt signal will ** cause this routine to exit immediately, unless input is interactive. +** +** Return the number of errors. */ -static void process_input(struct callback_data *p, FILE *in){ +static int process_input(struct callback_data *p, FILE *in){ char *zLine; char *zSql = 0; int nSql = 0; char *zErrMsg; int rc; - while( fflush(p->out), (zLine = one_input_line(zSql, in))!=0 ){ + int errCnt = 0; + int lineno = 0; + int startline = 0; + + while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){ + fflush(p->out); + zLine = one_input_line(zSql, in); + if( zLine==0 ){ + break; /* We have reached EOF */ + } if( seenInterrupt ){ if( in!=0 ) break; seenInterrupt = 0; } + lineno++; if( p->echoOn ) printf("%s\n", zLine); if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue; if( zLine && zLine[0]=='.' && nSql==0 ){ - int rc = do_meta_command(zLine, p); + rc = do_meta_command(zLine, p); free(zLine); - if( rc ) break; + if( rc==2 ){ + break; + }else if( rc ){ + errCnt++; + } continue; } if( _is_command_terminator(zLine) ){ @@ -1471,7 +1581,12 @@ static void process_input(struct callback_data *p, FILE *in){ if( zLine[i]!=0 ){ nSql = strlen(zLine); zSql = malloc( nSql+1 ); + if( zSql==0 ){ + fprintf(stderr, "out of memory\n"); + exit(1); + } strcpy(zSql, zLine); + startline = lineno; } }else{ int len = strlen(zLine); @@ -1490,14 +1605,20 @@ static void process_input(struct callback_data *p, FILE *in){ open_db(p); rc = sqlite3_exec(p->db, zSql, callback, p, &zErrMsg); if( rc || zErrMsg ){ - /* if( in!=0 && !p->echoOn ) printf("%s\n",zSql); */ + char zPrefix[100]; + if( in!=0 || !stdin_is_interactive ){ + sprintf(zPrefix, "SQL error near line %d:", startline); + }else{ + sprintf(zPrefix, "SQL error:"); + } if( zErrMsg!=0 ){ - printf("SQL error: %s\n", zErrMsg); + printf("%s %s\n", zPrefix, zErrMsg); sqlite3_free(zErrMsg); zErrMsg = 0; }else{ - printf("SQL error: %s\n", sqlite3_errmsg(p->db)); + printf("%s %s\n", zPrefix, sqlite3_errmsg(p->db)); } + errCnt++; } free(zSql); zSql = 0; @@ -1508,6 +1629,7 @@ static void process_input(struct callback_data *p, FILE *in){ if( !_all_whitespace(zSql) ) printf("Incomplete SQL: %s\n", zSql); free(zSql); } + return errCnt; } /* @@ -1519,7 +1641,7 @@ static void process_input(struct callback_data *p, FILE *in){ static char *find_home_dir(void){ char *home_dir = NULL; -#if !defined(_WIN32) && !defined(WIN32) && !defined(__MACOS__) +#if !defined(_WIN32) && !defined(WIN32) && !defined(__MACOS__) && !defined(__OS2__) struct passwd *pwent; uid_t uid = getuid(); if( (pwent=getpwuid(uid)) != NULL) { @@ -1532,16 +1654,30 @@ static char *find_home_dir(void){ home_dir = getcwd(home_path, _MAX_PATH); #endif +#if defined(_WIN32) || defined(WIN32) || defined(__OS2__) + if (!home_dir) { + home_dir = getenv("USERPROFILE"); + } +#endif + if (!home_dir) { home_dir = getenv("HOME"); - if (!home_dir) { - home_dir = getenv("HOMEPATH"); /* Windows? */ - } } -#if defined(_WIN32) || defined(WIN32) +#if defined(_WIN32) || defined(WIN32) || defined(__OS2__) if (!home_dir) { - home_dir = "c:"; + char *zDrive, *zPath; + int n; + zDrive = getenv("HOMEDRIVE"); + zPath = getenv("HOMEPATH"); + if( zDrive && zPath ){ + n = strlen(zDrive) + strlen(zPath) + 1; + home_dir = malloc( n ); + if( home_dir==0 ) return 0; + sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath); + return home_dir; + } + home_dir = "c:\\"; } #endif @@ -1584,7 +1720,7 @@ static void process_sqliterc( } in = fopen(sqliterc,"rb"); if( in ){ - if( isatty(fileno(stdout)) ){ + if( stdin_is_interactive ){ printf("Loading resources from %s\n",sqliterc); } process_input(p,in); @@ -1601,19 +1737,25 @@ static const char zOptions[] = " -init filename read/process named file\n" " -echo print commands before execution\n" " -[no]header turn headers on or off\n" + " -bail stop after hitting an error\n" + " -interactive force interactive I/O\n" + " -batch force batch I/O\n" " -column set output mode to 'column'\n" + " -csv set output mode to 'csv'\n" " -html set output mode to HTML\n" " -line set output mode to 'line'\n" " -list set output mode to 'list'\n" " -separator 'x' set output field separator (|)\n" " -nullvalue 'text' set text string for NULL values\n" " -version show SQLite version\n" - " -help show this text, also show dot-commands\n" ; static void usage(int showDetail){ - fprintf(stderr, "Usage: %s [OPTIONS] FILENAME [SQL]\n", Argv0); + fprintf(stderr, + "Usage: %s [OPTIONS] FILENAME [SQL]\n" + "FILENAME is the name of an SQLite database. A new database is created\n" + "if the file does not previously exist.\n", Argv0); if( showDetail ){ - fprintf(stderr, "Options are:\n%s", zOptions); + fprintf(stderr, "OPTIONS include:\n%s", zOptions); }else{ fprintf(stderr, "Use the -help option for additional information\n"); } @@ -1638,6 +1780,7 @@ int main(int argc, char **argv){ const char *zInitFile = 0; char *zFirstCmd = 0; int i; + int rc = 0; #ifdef __MACOS__ argc = ccommand(&argv); @@ -1645,6 +1788,7 @@ int main(int argc, char **argv){ Argv0 = argv[0]; main_init(&data); + stdin_is_interactive = isatty(0); /* Make sure we have a valid signal handler early, before anything ** else is done. @@ -1658,15 +1802,15 @@ int main(int argc, char **argv){ ** and the first command to execute. */ for(i=1; i", where @@ -48,7 +48,7 @@ extern "C" { #ifdef SQLITE_VERSION_NUMBER # undef SQLITE_VERSION_NUMBER #endif -#define SQLITE_VERSION_NUMBER 3003005 +#define SQLITE_VERSION_NUMBER 3003013 /* ** The version string is also compiled into the library so that a program @@ -125,7 +125,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**); ** value then the query is aborted, all subsequent SQL statements ** are skipped and the sqlite3_exec() function returns the SQLITE_ABORT. ** -** The 4th parameter is an arbitrary pointer that is passed +** The 1st parameter is an arbitrary pointer that is passed ** to the callback function as its first parameter. ** ** The 2nd parameter to the callback function is the number of @@ -198,6 +198,44 @@ int sqlite3_exec( #define SQLITE_DONE 101 /* sqlite3_step() has finished executing */ /* end-of-error-codes */ +/* +** Using the sqlite3_extended_result_codes() API, you can cause +** SQLite to return result codes with additional information in +** their upper bits. The lower 8 bits will be the same as the +** primary result codes above. But the upper bits might contain +** more specific error information. +** +** To extract the primary result code from an extended result code, +** simply mask off the lower 8 bits. +** +** primary = extended & 0xff; +** +** New result error codes may be added from time to time. Software +** that uses the extended result codes should plan accordingly and be +** sure to always handle new unknown codes gracefully. +** +** The SQLITE_OK result code will never be extended. It will always +** be exactly zero. +** +** The extended result codes always have the primary result code +** as a prefix. Primary result codes only contain a single "_" +** character. Extended result codes contain two or more "_" characters. +*/ +#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) +#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) +#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) +#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8)) +#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8)) +#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8)) +#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8)) +#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8)) +#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8)) + +/* +** Enable or disable the extended result codes. +*/ +int sqlite3_extended_result_codes(sqlite3*, int onoff); + /* ** Each entry in an SQLite table has a unique integer key. (The key is ** the value of the INTEGER PRIMARY KEY column if there is such a column, @@ -277,13 +315,30 @@ int sqlite3_complete16(const void *sql); ** currently locked by another process or thread. If the busy callback ** is NULL, then sqlite3_exec() returns SQLITE_BUSY immediately if ** it finds a locked table. If the busy callback is not NULL, then -** sqlite3_exec() invokes the callback with three arguments. The -** second argument is the name of the locked table and the third -** argument is the number of times the table has been busy. If the +** sqlite3_exec() invokes the callback with two arguments. The +** first argument to the handler is a copy of the void* pointer which +** is the third argument to this routine. The second argument to +** the handler is the number of times that the busy handler has +** been invoked for this locking event. If the ** busy callback returns 0, then sqlite3_exec() immediately returns ** SQLITE_BUSY. If the callback returns non-zero, then sqlite3_exec() ** tries to open the table again and the cycle repeats. ** +** The presence of a busy handler does not guarantee that +** it will be invoked when there is lock contention. +** If SQLite determines that invoking the busy handler could result in +** a deadlock, it will return SQLITE_BUSY instead. +** Consider a scenario where one process is holding a read lock that +** it is trying to promote to a reserved lock and +** a second process is holding a reserved lock that it is trying +** to promote to an exclusive lock. The first process cannot proceed +** because it is blocked by the second and the second process cannot +** proceed because it is blocked by the first. If both processes +** invoke the busy handlers, neither will make any progress. Therefore, +** SQLite returns SQLITE_BUSY for the first process, hoping that this +** will induce the first process to release its read lock and allow +** the second process to proceed. +** ** The default busy callback is NULL. ** ** Sqlite is re-entrant, so the busy handler may start a new query. @@ -405,9 +460,19 @@ void sqlite3_free_table(char **result); */ char *sqlite3_mprintf(const char*,...); char *sqlite3_vmprintf(const char*, va_list); -void sqlite3_free(char *z); char *sqlite3_snprintf(int,char*,const char*, ...); +/* +** SQLite uses its own memory allocator. On many installations, this +** memory allocator is identical to the standard malloc()/realloc()/free() +** and can be used interchangable. On others, the implementations are +** different. For maximum portability, it is best not to mix calls +** to the standard malloc/realloc/free with the sqlite versions. +*/ +void *sqlite3_malloc(int); +void *sqlite3_realloc(void*, int); +void sqlite3_free(void*); + #ifndef SQLITE_OMIT_AUTHORIZATION /* ** This routine registers a callback with the SQLite library. The @@ -466,7 +531,9 @@ int sqlite3_set_authorizer( #define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */ #define SQLITE_REINDEX 27 /* Index Name NULL */ #define SQLITE_ANALYZE 28 /* Table Name NULL */ - +#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */ +#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */ +#define SQLITE_FUNCTION 31 /* Function Name NULL */ /* ** The return value of the authorization function should be one of the @@ -642,6 +709,31 @@ int sqlite3_prepare16( const void **pzTail /* OUT: Pointer to unused portion of zSql */ ); +/* +** Newer versions of the prepare API work just like the legacy versions +** but with one exception: The a copy of the SQL text is saved in the +** sqlite3_stmt structure that is returned. If this copy exists, it +** modifieds the behavior of sqlite3_step() slightly. First, sqlite3_step() +** will no longer return an SQLITE_SCHEMA error but will instead automatically +** rerun the compiler to rebuild the prepared statement. Secondly, +** sqlite3_step() now turns a full result code - the result code that +** use used to have to call sqlite3_reset() to get. +*/ +int sqlite3_prepare_v2( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nBytes, /* Length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +int sqlite3_prepare16_v2( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nBytes, /* Length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); + /* ** Pointers to the following two opaque structures are used to communicate ** with the implementations of user-defined functions. @@ -926,6 +1018,7 @@ const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); int sqlite3_column_type(sqlite3_stmt*, int iCol); int sqlite3_column_numeric_type(sqlite3_stmt*, int iCol); +sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); /* ** The sqlite3_finalize() function is called to delete a compiled @@ -1092,9 +1185,13 @@ void sqlite3_set_auxdata(sqlite3_context*, int, void*, void (*)(void*)); ** SQLITE_TRANSIENT value means that the content will likely change in ** the near future and that SQLite should make its own private copy of ** the content before returning. +** +** The typedef is necessary to work around problems in certain +** C++ compilers. See ticket #2191. */ -#define SQLITE_STATIC ((void(*)(void *))0) -#define SQLITE_TRANSIENT ((void(*)(void *))-1) +typedef void (*sqlite3_destructor_type)(void*); +#define SQLITE_STATIC ((sqlite3_destructor_type)0) +#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) /* ** User-defined functions invoke the following routines in order to @@ -1468,6 +1565,299 @@ int sqlite3_table_column_metadata( int *pAutoinc /* OUTPUT: True if colums is auto-increment */ ); +/* +****** EXPERIMENTAL - subject to change without notice ************** +** +** Attempt to load an SQLite extension library contained in the file +** zFile. The entry point is zProc. zProc may be 0 in which case the +** name of the entry point defaults to "sqlite3_extension_init". +** +** Return SQLITE_OK on success and SQLITE_ERROR if something goes wrong. +** +** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with +** error message text. The calling function should free this memory +** by calling sqlite3_free(). +** +** Extension loading must be enabled using sqlite3_enable_load_extension() +** prior to calling this API or an error will be returned. +** +****** EXPERIMENTAL - subject to change without notice ************** +*/ +int sqlite3_load_extension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Derived from zFile if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +); + +/* +** So as not to open security holes in older applications that are +** unprepared to deal with extension load, and as a means of disabling +** extension loading while executing user-entered SQL, the following +** API is provided to turn the extension loading mechanism on and +** off. It is off by default. See ticket #1863. +** +** Call this routine with onoff==1 to turn extension loading on +** and call it with onoff==0 to turn it back off again. +*/ +int sqlite3_enable_load_extension(sqlite3 *db, int onoff); + +/* +****** EXPERIMENTAL - subject to change without notice ************** +** +** Register an extension entry point that is automatically invoked +** whenever a new database connection is opened. +** +** This API can be invoked at program startup in order to register +** one or more statically linked extensions that will be available +** to all new database connections. +** +** Duplicate extensions are detected so calling this routine multiple +** times with the same extension is harmless. +** +** This routine stores a pointer to the extension in an array +** that is obtained from malloc(). If you run a memory leak +** checker on your program and it reports a leak because of this +** array, then invoke sqlite3_automatic_extension_reset() prior +** to shutdown to free the memory. +** +** Automatic extensions apply across all threads. +*/ +int sqlite3_auto_extension(void *xEntryPoint); + + +/* +****** EXPERIMENTAL - subject to change without notice ************** +** +** Disable all previously registered automatic extensions. This +** routine undoes the effect of all prior sqlite3_automatic_extension() +** calls. +** +** This call disabled automatic extensions in all threads. +*/ +void sqlite3_reset_auto_extension(void); + + +/* +****** EXPERIMENTAL - subject to change without notice ************** +** +** The interface to the virtual-table mechanism is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stablizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +*/ + +/* +** Structures used by the virtual table interface +*/ +typedef struct sqlite3_vtab sqlite3_vtab; +typedef struct sqlite3_index_info sqlite3_index_info; +typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; +typedef struct sqlite3_module sqlite3_module; + +/* +** A module is a class of virtual tables. Each module is defined +** by an instance of the following structure. This structure consists +** mostly of methods for the module. +*/ +struct sqlite3_module { + int iVersion; + int (*xCreate)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xConnect)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); + int (*xDisconnect)(sqlite3_vtab *pVTab); + int (*xDestroy)(sqlite3_vtab *pVTab); + int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); + int (*xClose)(sqlite3_vtab_cursor*); + int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, + int argc, sqlite3_value **argv); + int (*xNext)(sqlite3_vtab_cursor*); + int (*xEof)(sqlite3_vtab_cursor*); + int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); + int (*xRowid)(sqlite3_vtab_cursor*, sqlite_int64 *pRowid); + int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite_int64 *); + int (*xBegin)(sqlite3_vtab *pVTab); + int (*xSync)(sqlite3_vtab *pVTab); + int (*xCommit)(sqlite3_vtab *pVTab); + int (*xRollback)(sqlite3_vtab *pVTab); + int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), + void **ppArg); +}; + +/* +** The sqlite3_index_info structure and its substructures is used to +** pass information into and receive the reply from the xBestIndex +** method of an sqlite3_module. The fields under **Inputs** are the +** inputs to xBestIndex and are read-only. xBestIndex inserts its +** results into the **Outputs** fields. +** +** The aConstraint[] array records WHERE clause constraints of the +** form: +** +** column OP expr +** +** Where OP is =, <, <=, >, or >=. The particular operator is stored +** in aConstraint[].op. The index of the column is stored in +** aConstraint[].iColumn. aConstraint[].usable is TRUE if the +** expr on the right-hand side can be evaluated (and thus the constraint +** is usable) and false if it cannot. +** +** The optimizer automatically inverts terms of the form "expr OP column" +** and makes other simplificatinos to the WHERE clause in an attempt to +** get as many WHERE clause terms into the form shown above as possible. +** The aConstraint[] array only reports WHERE clause terms in the correct +** form that refer to the particular virtual table being queried. +** +** Information about the ORDER BY clause is stored in aOrderBy[]. +** Each term of aOrderBy records a column of the ORDER BY clause. +** +** The xBestIndex method must fill aConstraintUsage[] with information +** about what parameters to pass to xFilter. If argvIndex>0 then +** the right-hand side of the corresponding aConstraint[] is evaluated +** and becomes the argvIndex-th entry in argv. If aConstraintUsage[].omit +** is true, then the constraint is assumed to be fully handled by the +** virtual table and is not checked again by SQLite. +** +** The idxNum and idxPtr values are recorded and passed into xFilter. +** sqlite3_free() is used to free idxPtr if needToFreeIdxPtr is true. +** +** The orderByConsumed means that output from xFilter will occur in +** the correct order to satisfy the ORDER BY clause so that no separate +** sorting step is required. +** +** The estimatedCost value is an estimate of the cost of doing the +** particular lookup. A full scan of a table with N entries should have +** a cost of N. A binary search of a table of N entries should have a +** cost of approximately log(N). +*/ +struct sqlite3_index_info { + /* Inputs */ + const int nConstraint; /* Number of entries in aConstraint */ + const struct sqlite3_index_constraint { + int iColumn; /* Column on left-hand side of constraint */ + unsigned char op; /* Constraint operator */ + unsigned char usable; /* True if this constraint is usable */ + int iTermOffset; /* Used internally - xBestIndex should ignore */ + } *const aConstraint; /* Table of WHERE clause constraints */ + const int nOrderBy; /* Number of terms in the ORDER BY clause */ + const struct sqlite3_index_orderby { + int iColumn; /* Column number */ + unsigned char desc; /* True for DESC. False for ASC. */ + } *const aOrderBy; /* The ORDER BY clause */ + + /* Outputs */ + struct sqlite3_index_constraint_usage { + int argvIndex; /* if >0, constraint is part of argv to xFilter */ + unsigned char omit; /* Do not code a test for this constraint */ + } *const aConstraintUsage; + int idxNum; /* Number used to identify the index */ + char *idxStr; /* String, possibly obtained from sqlite3_malloc */ + int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ + int orderByConsumed; /* True if output is already ordered */ + double estimatedCost; /* Estimated cost of using this index */ +}; +#define SQLITE_INDEX_CONSTRAINT_EQ 2 +#define SQLITE_INDEX_CONSTRAINT_GT 4 +#define SQLITE_INDEX_CONSTRAINT_LE 8 +#define SQLITE_INDEX_CONSTRAINT_LT 16 +#define SQLITE_INDEX_CONSTRAINT_GE 32 +#define SQLITE_INDEX_CONSTRAINT_MATCH 64 + +/* +** This routine is used to register a new module name with an SQLite +** connection. Module names must be registered before creating new +** virtual tables on the module, or before using preexisting virtual +** tables of the module. +*/ +int sqlite3_create_module( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *, /* Methods for the module */ + void * /* Client data for xCreate/xConnect */ +); + +/* +** Every module implementation uses a subclass of the following structure +** to describe a particular instance of the module. Each subclass will +** be taylored to the specific needs of the module implementation. The +** purpose of this superclass is to define certain fields that are common +** to all module implementations. +** +** Virtual tables methods can set an error message by assigning a +** string obtained from sqlite3_mprintf() to zErrMsg. The method should +** take care that any prior string is freed by a call to sqlite3_free() +** prior to assigning a new string to zErrMsg. After the error message +** is delivered up to the client application, the string will be automatically +** freed by sqlite3_free() and the zErrMsg field will be zeroed. Note +** that sqlite3_mprintf() and sqlite3_free() are used on the zErrMsg field +** since virtual tables are commonly implemented in loadable extensions which +** do not have access to sqlite3MPrintf() or sqlite3Free(). +*/ +struct sqlite3_vtab { + const sqlite3_module *pModule; /* The module for this virtual table */ + int nRef; /* Used internally */ + char *zErrMsg; /* Error message from sqlite3_mprintf() */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* Every module implementation uses a subclass of the following structure +** to describe cursors that point into the virtual table and are used +** to loop through the virtual table. Cursors are created using the +** xOpen method of the module. Each module implementation will define +** the content of a cursor structure to suit its own needs. +** +** This superclass exists in order to define fields of the cursor that +** are common to all implementations. +*/ +struct sqlite3_vtab_cursor { + sqlite3_vtab *pVtab; /* Virtual table of this cursor */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* +** The xCreate and xConnect methods of a module use the following API +** to declare the format (the names and datatypes of the columns) of +** the virtual tables they implement. +*/ +int sqlite3_declare_vtab(sqlite3*, const char *zCreateTable); + +/* +** Virtual tables can provide alternative implementations of functions +** using the xFindFunction method. But global versions of those functions +** must exist in order to be overloaded. +** +** This API makes sure a global version of a function with a particular +** name and number of parameters exists. If no such function exists +** before this API is called, a new function is created. The implementation +** of the new function always causes an exception to be thrown. So +** the new function is not good for anything by itself. Its only +** purpose is to be a place-holder function that can be overloaded +** by virtual tables. +** +** This API should be considered part of the virtual table interface, +** which is experimental and subject to change. +*/ +int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); + +/* +** The interface to the virtual-table mechanism defined above (back up +** to a comment remarkably similar to this one) is currently considered +** to be experimental. The interface might change in incompatible ways. +** If this is a problem for you, do not use the interface at this time. +** +** When the virtual-table mechanism stablizes, we will declare the +** interface fixed, support it indefinitely, and remove this comment. +** +****** EXPERIMENTAL - subject to change without notice ************** +*/ + /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. diff --git a/dlls/sqlite/sqlite-source/sqlite3ext.h b/dlls/sqlite/sqlite-source/sqlite3ext.h new file mode 100644 index 00000000..1df21d6a --- /dev/null +++ b/dlls/sqlite/sqlite-source/sqlite3ext.h @@ -0,0 +1,282 @@ +/* +** 2006 June 7 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This header file defines the SQLite interface for use by +** shared libraries that want to be imported as extensions into +** an SQLite instance. Shared libraries that intend to be loaded +** as extensions by SQLite should #include this file instead of +** sqlite3.h. +** +** @(#) $Id$ +*/ +#ifndef _SQLITE3EXT_H_ +#define _SQLITE3EXT_H_ +#include "sqlite3.h" + +typedef struct sqlite3_api_routines sqlite3_api_routines; + +/* +** The following structure hold pointers to all of the SQLite API +** routines. +*/ +struct sqlite3_api_routines { + void * (*aggregate_context)(sqlite3_context*,int nBytes); + int (*aggregate_count)(sqlite3_context*); + int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*)); + int (*bind_double)(sqlite3_stmt*,int,double); + int (*bind_int)(sqlite3_stmt*,int,int); + int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64); + int (*bind_null)(sqlite3_stmt*,int); + int (*bind_parameter_count)(sqlite3_stmt*); + int (*bind_parameter_index)(sqlite3_stmt*,const char*zName); + const char * (*bind_parameter_name)(sqlite3_stmt*,int); + int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*)); + int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*)); + int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*); + int (*busy_handler)(sqlite3*,int(*)(void*,int),void*); + int (*busy_timeout)(sqlite3*,int ms); + int (*changes)(sqlite3*); + int (*close)(sqlite3*); + int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*,int eTextRep,const char*)); + int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*,int eTextRep,const void*)); + const void * (*column_blob)(sqlite3_stmt*,int iCol); + int (*column_bytes)(sqlite3_stmt*,int iCol); + int (*column_bytes16)(sqlite3_stmt*,int iCol); + int (*column_count)(sqlite3_stmt*pStmt); + const char * (*column_database_name)(sqlite3_stmt*,int); + const void * (*column_database_name16)(sqlite3_stmt*,int); + const char * (*column_decltype)(sqlite3_stmt*,int i); + const void * (*column_decltype16)(sqlite3_stmt*,int); + double (*column_double)(sqlite3_stmt*,int iCol); + int (*column_int)(sqlite3_stmt*,int iCol); + sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol); + const char * (*column_name)(sqlite3_stmt*,int); + const void * (*column_name16)(sqlite3_stmt*,int); + const char * (*column_origin_name)(sqlite3_stmt*,int); + const void * (*column_origin_name16)(sqlite3_stmt*,int); + const char * (*column_table_name)(sqlite3_stmt*,int); + const void * (*column_table_name16)(sqlite3_stmt*,int); + const unsigned char * (*column_text)(sqlite3_stmt*,int iCol); + const void * (*column_text16)(sqlite3_stmt*,int iCol); + int (*column_type)(sqlite3_stmt*,int iCol); + sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol); + void * (*commit_hook)(sqlite3*,int(*)(void*),void*); + int (*complete)(const char*sql); + int (*complete16)(const void*sql); + int (*create_collation)(sqlite3*,const char*,int,void*,int(*)(void*,int,const void*,int,const void*)); + int (*create_collation16)(sqlite3*,const char*,int,void*,int(*)(void*,int,const void*,int,const void*)); + int (*create_function)(sqlite3*,const char*,int,int,void*,void (*xFunc)(sqlite3_context*,int,sqlite3_value**),void (*xStep)(sqlite3_context*,int,sqlite3_value**),void (*xFinal)(sqlite3_context*)); + int (*create_function16)(sqlite3*,const void*,int,int,void*,void (*xFunc)(sqlite3_context*,int,sqlite3_value**),void (*xStep)(sqlite3_context*,int,sqlite3_value**),void (*xFinal)(sqlite3_context*)); + int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*); + int (*data_count)(sqlite3_stmt*pStmt); + sqlite3 * (*db_handle)(sqlite3_stmt*); + int (*declare_vtab)(sqlite3*,const char*); + int (*enable_shared_cache)(int); + int (*errcode)(sqlite3*db); + const char * (*errmsg)(sqlite3*); + const void * (*errmsg16)(sqlite3*); + int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**); + int (*expired)(sqlite3_stmt*); + int (*finalize)(sqlite3_stmt*pStmt); + void (*free)(void*); + void (*free_table)(char**result); + int (*get_autocommit)(sqlite3*); + void * (*get_auxdata)(sqlite3_context*,int); + int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**); + int (*global_recover)(void); + void (*interruptx)(sqlite3*); + sqlite_int64 (*last_insert_rowid)(sqlite3*); + const char * (*libversion)(void); + int (*libversion_number)(void); + void *(*malloc)(int); + char * (*mprintf)(const char*,...); + int (*open)(const char*,sqlite3**); + int (*open16)(const void*,sqlite3**); + int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); + int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); + void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*); + void (*progress_handler)(sqlite3*,int,int(*)(void*),void*); + void *(*realloc)(void*,int); + int (*reset)(sqlite3_stmt*pStmt); + void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_double)(sqlite3_context*,double); + void (*result_error)(sqlite3_context*,const char*,int); + void (*result_error16)(sqlite3_context*,const void*,int); + void (*result_int)(sqlite3_context*,int); + void (*result_int64)(sqlite3_context*,sqlite_int64); + void (*result_null)(sqlite3_context*); + void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*)); + void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_value)(sqlite3_context*,sqlite3_value*); + void * (*rollback_hook)(sqlite3*,void(*)(void*),void*); + int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,const char*,const char*),void*); + void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*)); + char * (*snprintf)(int,char*,const char*,...); + int (*step)(sqlite3_stmt*); + int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,char const**,char const**,int*,int*,int*); + void (*thread_cleanup)(void); + int (*total_changes)(sqlite3*); + void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*); + int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*); + void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*,sqlite_int64),void*); + void * (*user_data)(sqlite3_context*); + const void * (*value_blob)(sqlite3_value*); + int (*value_bytes)(sqlite3_value*); + int (*value_bytes16)(sqlite3_value*); + double (*value_double)(sqlite3_value*); + int (*value_int)(sqlite3_value*); + sqlite_int64 (*value_int64)(sqlite3_value*); + int (*value_numeric_type)(sqlite3_value*); + const unsigned char * (*value_text)(sqlite3_value*); + const void * (*value_text16)(sqlite3_value*); + const void * (*value_text16be)(sqlite3_value*); + const void * (*value_text16le)(sqlite3_value*); + int (*value_type)(sqlite3_value*); + char * (*vmprintf)(const char*,va_list); + int (*overload_function)(sqlite3*, const char *zFuncName, int nArg); +}; + +/* +** The following macros redefine the API routines so that they are +** redirected throught the global sqlite3_api structure. +** +** This header file is also used by the loadext.c source file +** (part of the main SQLite library - not an extension) so that +** it can get access to the sqlite3_api_routines structure +** definition. But the main library does not want to redefine +** the API. So the redefinition macros are only valid if the +** SQLITE_CORE macros is undefined. +*/ +#ifndef SQLITE_CORE +#define sqlite3_aggregate_context sqlite3_api->aggregate_context +#define sqlite3_aggregate_count sqlite3_api->aggregate_count +#define sqlite3_bind_blob sqlite3_api->bind_blob +#define sqlite3_bind_double sqlite3_api->bind_double +#define sqlite3_bind_int sqlite3_api->bind_int +#define sqlite3_bind_int64 sqlite3_api->bind_int64 +#define sqlite3_bind_null sqlite3_api->bind_null +#define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count +#define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index +#define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name +#define sqlite3_bind_text sqlite3_api->bind_text +#define sqlite3_bind_text16 sqlite3_api->bind_text16 +#define sqlite3_bind_value sqlite3_api->bind_value +#define sqlite3_busy_handler sqlite3_api->busy_handler +#define sqlite3_busy_timeout sqlite3_api->busy_timeout +#define sqlite3_changes sqlite3_api->changes +#define sqlite3_close sqlite3_api->close +#define sqlite3_collation_needed sqlite3_api->collation_needed +#define sqlite3_collation_needed16 sqlite3_api->collation_needed16 +#define sqlite3_column_blob sqlite3_api->column_blob +#define sqlite3_column_bytes sqlite3_api->column_bytes +#define sqlite3_column_bytes16 sqlite3_api->column_bytes16 +#define sqlite3_column_count sqlite3_api->column_count +#define sqlite3_column_database_name sqlite3_api->column_database_name +#define sqlite3_column_database_name16 sqlite3_api->column_database_name16 +#define sqlite3_column_decltype sqlite3_api->column_decltype +#define sqlite3_column_decltype16 sqlite3_api->column_decltype16 +#define sqlite3_column_double sqlite3_api->column_double +#define sqlite3_column_int sqlite3_api->column_int +#define sqlite3_column_int64 sqlite3_api->column_int64 +#define sqlite3_column_name sqlite3_api->column_name +#define sqlite3_column_name16 sqlite3_api->column_name16 +#define sqlite3_column_origin_name sqlite3_api->column_origin_name +#define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16 +#define sqlite3_column_table_name sqlite3_api->column_table_name +#define sqlite3_column_table_name16 sqlite3_api->column_table_name16 +#define sqlite3_column_text sqlite3_api->column_text +#define sqlite3_column_text16 sqlite3_api->column_text16 +#define sqlite3_column_type sqlite3_api->column_type +#define sqlite3_column_value sqlite3_api->column_value +#define sqlite3_commit_hook sqlite3_api->commit_hook +#define sqlite3_complete sqlite3_api->complete +#define sqlite3_complete16 sqlite3_api->complete16 +#define sqlite3_create_collation sqlite3_api->create_collation +#define sqlite3_create_collation16 sqlite3_api->create_collation16 +#define sqlite3_create_function sqlite3_api->create_function +#define sqlite3_create_function16 sqlite3_api->create_function16 +#define sqlite3_create_module sqlite3_api->create_module +#define sqlite3_data_count sqlite3_api->data_count +#define sqlite3_db_handle sqlite3_api->db_handle +#define sqlite3_declare_vtab sqlite3_api->declare_vtab +#define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache +#define sqlite3_errcode sqlite3_api->errcode +#define sqlite3_errmsg sqlite3_api->errmsg +#define sqlite3_errmsg16 sqlite3_api->errmsg16 +#define sqlite3_exec sqlite3_api->exec +#define sqlite3_expired sqlite3_api->expired +#define sqlite3_finalize sqlite3_api->finalize +#define sqlite3_free sqlite3_api->free +#define sqlite3_free_table sqlite3_api->free_table +#define sqlite3_get_autocommit sqlite3_api->get_autocommit +#define sqlite3_get_auxdata sqlite3_api->get_auxdata +#define sqlite3_get_table sqlite3_api->get_table +#define sqlite3_global_recover sqlite3_api->global_recover +#define sqlite3_interrupt sqlite3_api->interruptx +#define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid +#define sqlite3_libversion sqlite3_api->libversion +#define sqlite3_libversion_number sqlite3_api->libversion_number +#define sqlite3_malloc sqlite3_api->malloc +#define sqlite3_mprintf sqlite3_api->mprintf +#define sqlite3_open sqlite3_api->open +#define sqlite3_open16 sqlite3_api->open16 +#define sqlite3_prepare sqlite3_api->prepare +#define sqlite3_prepare16 sqlite3_api->prepare16 +#define sqlite3_profile sqlite3_api->profile +#define sqlite3_progress_handler sqlite3_api->progress_handler +#define sqlite3_realloc sqlite3_api->realloc +#define sqlite3_reset sqlite3_api->reset +#define sqlite3_result_blob sqlite3_api->result_blob +#define sqlite3_result_double sqlite3_api->result_double +#define sqlite3_result_error sqlite3_api->result_error +#define sqlite3_result_error16 sqlite3_api->result_error16 +#define sqlite3_result_int sqlite3_api->result_int +#define sqlite3_result_int64 sqlite3_api->result_int64 +#define sqlite3_result_null sqlite3_api->result_null +#define sqlite3_result_text sqlite3_api->result_text +#define sqlite3_result_text16 sqlite3_api->result_text16 +#define sqlite3_result_text16be sqlite3_api->result_text16be +#define sqlite3_result_text16le sqlite3_api->result_text16le +#define sqlite3_result_value sqlite3_api->result_value +#define sqlite3_rollback_hook sqlite3_api->rollback_hook +#define sqlite3_set_authorizer sqlite3_api->set_authorizer +#define sqlite3_set_auxdata sqlite3_api->set_auxdata +#define sqlite3_snprintf sqlite3_api->snprintf +#define sqlite3_step sqlite3_api->step +#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata +#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup +#define sqlite3_total_changes sqlite3_api->total_changes +#define sqlite3_trace sqlite3_api->trace +#define sqlite3_transfer_bindings sqlite3_api->transfer_bindings +#define sqlite3_update_hook sqlite3_api->update_hook +#define sqlite3_user_data sqlite3_api->user_data +#define sqlite3_value_blob sqlite3_api->value_blob +#define sqlite3_value_bytes sqlite3_api->value_bytes +#define sqlite3_value_bytes16 sqlite3_api->value_bytes16 +#define sqlite3_value_double sqlite3_api->value_double +#define sqlite3_value_int sqlite3_api->value_int +#define sqlite3_value_int64 sqlite3_api->value_int64 +#define sqlite3_value_numeric_type sqlite3_api->value_numeric_type +#define sqlite3_value_text sqlite3_api->value_text +#define sqlite3_value_text16 sqlite3_api->value_text16 +#define sqlite3_value_text16be sqlite3_api->value_text16be +#define sqlite3_value_text16le sqlite3_api->value_text16le +#define sqlite3_value_type sqlite3_api->value_type +#define sqlite3_vmprintf sqlite3_api->vmprintf +#define sqlite3_overload_function sqlite3_api->overload_function +#endif /* SQLITE_CORE */ + +#define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api; +#define SQLITE_EXTENSION_INIT2(v) sqlite3_api = v; + +#endif /* _SQLITE3EXT_H_ */ diff --git a/dlls/sqlite/sqlite-source/sqliteInt.h b/dlls/sqlite/sqlite-source/sqliteInt.h index dd06a6ea..cceee77f 100644 --- a/dlls/sqlite/sqlite-source/sqliteInt.h +++ b/dlls/sqlite/sqlite-source/sqliteInt.h @@ -17,7 +17,7 @@ #define _SQLITEINT_H_ #if defined _MSC_VER && _MSC_VER >= 1400 - #define _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE #endif /* @@ -152,7 +152,7 @@ */ #define SQLITE_MAX_FILE_FORMAT 4 #ifndef SQLITE_DEFAULT_FILE_FORMAT -# define SQLITE_DEFAULT_FILE_FORMAT 4 +# define SQLITE_DEFAULT_FILE_FORMAT 1 #endif /* @@ -347,6 +347,7 @@ typedef struct IdList IdList; typedef struct Index Index; typedef struct KeyClass KeyClass; typedef struct KeyInfo KeyInfo; +typedef struct Module Module; typedef struct NameContext NameContext; typedef struct Parse Parse; typedef struct Select Select; @@ -450,6 +451,7 @@ struct sqlite3 { Db *aDb; /* All backends */ int flags; /* Miscellanous flags. See below */ int errCode; /* Most recent error code (SQLITE_*) */ + int errMask; /* & result codes with this before returning */ u8 autoCommit; /* The auto-commit flag. */ u8 temp_store; /* 1: file 2: memory 0: default */ int nTable; /* Number of tables in the database */ @@ -464,6 +466,8 @@ struct sqlite3 { int newTnum; /* Rootpage of table being initialized */ u8 busy; /* TRUE if currently initializing */ } init; + int nExtension; /* Number of loaded extensions */ + void **aExtension; /* Array of shared libraray handles */ struct Vdbe *pVdbe; /* List of active virtual machines */ int activeVdbeCnt; /* Number of vdbes currently executing */ void (*xTrace)(void*,const char*); /* Trace function */ @@ -482,6 +486,10 @@ struct sqlite3 { sqlite3_value *pErr; /* Most recent error message */ char *zErrMsg; /* Most recent error message (UTF-8 encoded) */ char *zErrMsg16; /* Most recent error message (UTF-16 encoded) */ + union { + int isInterrupted; /* True if sqlite3_interrupt has been called */ + double notUsed1; /* Spacer */ + } u1; #ifndef SQLITE_OMIT_AUTHORIZATION int (*xAuth)(void*,int,const char*,const char*,const char*,const char*); /* Access authorization function */ @@ -492,13 +500,16 @@ struct sqlite3 { void *pProgressArg; /* Argument to the progress callback */ int nProgressOps; /* Number of opcodes for progress callback */ #endif -#ifndef SQLITE_OMIT_GLOBALRECOVER - sqlite3 *pNext; /* Linked list of open db handles. */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + Hash aModule; /* populated by sqlite3_create_module() */ + Table *pVTab; /* vtab with active Connect/Create method */ + sqlite3_vtab **aVTrans; /* Virtual tables with open transactions */ + int nVTrans; /* Allocated size of aVTrans */ #endif Hash aFunc; /* All functions that can be in SQL exprs */ Hash aCollSeq; /* All collating sequences */ BusyHandler busyHandler; /* Busy callback */ - int busyTimeout; /* Busy handler timeout, in msec */ + int busyTimeout; /* Busy handler timeout, in msec */ Db aDbStatic[2]; /* Static space for the 2 default backends */ #ifdef SQLITE_SSE sqlite3_stmt *pFetch; /* Used by SSE to fetch stored statements */ @@ -518,7 +529,6 @@ struct sqlite3 { ** transaction is active on that particular database file. */ #define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */ -#define SQLITE_Interrupt 0x00000004 /* Cancel current operation */ #define SQLITE_InTrans 0x00000008 /* True if in a transaction */ #define SQLITE_InternChanges 0x00000010 /* Uncommitted Hash table changes */ #define SQLITE_FullColNames 0x00000020 /* Show full column names on SELECT */ @@ -534,9 +544,10 @@ struct sqlite3 { #define SQLITE_NoReadlock 0x00001000 /* Readlocks are omitted when ** accessing read-only databases */ #define SQLITE_IgnoreChecks 0x00002000 /* Do not enforce check constraints */ -#define SQLITE_ReadUncommitted 0x00004000 /* For shared-cache mode */ +#define SQLITE_ReadUncommitted 0x00004000 /* For shared-cache mode */ #define SQLITE_LegacyFileFmt 0x00008000 /* Create new databases in format 1 */ #define SQLITE_FullFSync 0x00010000 /* Use full fsync on the backend */ +#define SQLITE_LoadExtension 0x00020000 /* Enable load_extension */ /* ** Possible values for the sqlite.magic field. @@ -567,11 +578,23 @@ struct FuncDef { char zName[1]; /* SQL name of the function. MUST BE LAST */ }; +/* +** Each SQLite module (virtual table definition) is defined by an +** instance of the following structure, stored in the sqlite3.aModule +** hash table. +*/ +struct Module { + const sqlite3_module *pModule; /* Callback pointers */ + const char *zName; /* Name passed to create_module() */ + void *pAux; /* pAux passed to create_module() */ +}; + /* ** Possible values for FuncDef.flags */ #define SQLITE_FUNC_LIKE 0x01 /* Candidate for the LIKE optimization */ #define SQLITE_FUNC_CASE 0x02 /* Case-sensitive LIKE-type function */ +#define SQLITE_FUNC_EPHEM 0x04 /* Ephermeral. Delete with VDBE */ /* ** information about each column of an SQL table is held in an instance @@ -674,7 +697,7 @@ struct CollSeq { ** Table.tnum is the page number for the root BTree page of the table in the ** database file. If Table.iDb is the index of the database table backend ** in sqlite.aDb[]. 0 is for the main database and 1 is for the file that -** holds temporary tables and indices. If Table.isTransient +** holds temporary tables and indices. If Table.isEphem ** is true, then the table is stored in a file that is automatically deleted ** when the VDBE cursor to the table is closed. In this case Table.tnum ** refers VDBE cursor number that holds the table open, not to the root @@ -690,11 +713,6 @@ struct Table { Index *pIndex; /* List of SQL indexes on this table. */ int tnum; /* Root BTree node for this table (see note above) */ Select *pSelect; /* NULL for tables. Points to definition if a view. */ - u8 readOnly; /* True if this table should not be written by the user */ - u8 isTransient; /* True if automatically deleted when VDBE finishes */ - u8 hasPrimKey; /* True if there exists a primary key */ - u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */ - u8 autoInc; /* True if the integer primary key is autoincrement */ int nRef; /* Number of pointers to this Table */ Trigger *pTrigger; /* List of SQL triggers on this table */ FKey *pFKey; /* Linked list of all foreign keys in this table */ @@ -704,10 +722,34 @@ struct Table { #endif #ifndef SQLITE_OMIT_ALTERTABLE int addColOffset; /* Offset in CREATE TABLE statement to add a new column */ +#endif + u8 readOnly; /* True if this table should not be written by the user */ + u8 isEphem; /* True if created using OP_OpenEphermeral */ + u8 hasPrimKey; /* True if there exists a primary key */ + u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */ + u8 autoInc; /* True if the integer primary key is autoincrement */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + u8 isVirtual; /* True if this is a virtual table */ + u8 isCommit; /* True once the CREATE TABLE has been committed */ + Module *pMod; /* Pointer to the implementation of the module */ + sqlite3_vtab *pVtab; /* Pointer to the module instance */ + int nModuleArg; /* Number of arguments to the module */ + char **azModuleArg; /* Text of all module args. [0] is module name */ #endif Schema *pSchema; }; +/* +** Test to see whether or not a table is a virtual table. This is +** done as a macro so that it will be optimized out when virtual +** table support is omitted from the build. +*/ +#ifndef SQLITE_OMIT_VIRTUALTABLE +# define IsVirtual(X) ((X)->isVirtual) +#else +# define IsVirtual(X) 0 +#endif + /* ** Each foreign key constraint is an instance of the following structure. ** @@ -899,7 +941,7 @@ struct AggInfo { Expr *pExpr; /* Expression encoding the function */ FuncDef *pFunc; /* The aggregate function implementation */ int iMem; /* Memory location that acts as accumulator */ - int iDistinct; /* Virtual table used to enforce DISTINCT */ + int iDistinct; /* Ephermeral table used to enforce DISTINCT */ } *aFunc; int nFunc; /* Number of entries in aFunc[] */ int nFuncAlloc; /* Number of slots allocated for aFunc[] */ @@ -954,7 +996,7 @@ struct AggInfo { struct Expr { u8 op; /* Operation performed by this node */ char affinity; /* The affinity of the column or 0 if not a column */ - u8 flags; /* Various flags. See below */ + u16 flags; /* Various flags. See below */ CollSeq *pColl; /* The collation type of the column or 0 */ Expr *pLeft, *pRight; /* Left and right subnodes */ ExprList *pList; /* A list of expressions used as function arguments @@ -982,6 +1024,8 @@ struct Expr { #define EP_Distinct 0x10 /* Aggregate function with DISTINCT keyword */ #define EP_VarSelect 0x20 /* pSelect is correlated, not constant */ #define EP_Dequoted 0x40 /* True if the string has been dequoted */ +#define EP_InfixFunc 0x80 /* True for an infix function: LIKE, GLOB, etc */ +#define EP_ExpCollate 0x100 /* Collating sequence specified explicitly */ /* ** These macros can be used to test, set, or clear bits in the @@ -1039,8 +1083,12 @@ struct IdList { /* ** The bitmask datatype defined below is used for various optimizations. +** +** Changing this from a 64-bit to a 32-bit type limits the number of +** tables in a join to 32 instead of 64. But it also reduces the size +** of the library by 738 bytes on ix86. */ -typedef unsigned int Bitmask; +typedef u64 Bitmask; /* ** The following structure describes the FROM clause of a SELECT statement. @@ -1052,6 +1100,11 @@ typedef unsigned int Bitmask; ** is modified by an INSERT, DELETE, or UPDATE statement. In standard SQL, ** such a table must be a simple name: ID. But in SQLite, the table can ** now be identified by a database name, a dot, then the table name: ID.ID. +** +** The jointype starts out showing the join type between the current table +** and the next table on the list. The parser builds the list this way. +** But sqlite3SrcListShiftJoinType() later shifts the jointypes so that each +** jointype expresses the join between the table and the previous table. */ struct SrcList { i16 nSrc; /* Number of tables or subqueries in the FROM clause */ @@ -1063,8 +1116,8 @@ struct SrcList { Table *pTab; /* An SQL table corresponding to zName */ Select *pSelect; /* A SELECT statement used in place of a table name */ u8 isPopulated; /* Temporary table associated with SELECT is populated */ - u8 jointype; /* Type of join between this table and the next */ - i16 iCursor; /* The VDBE cursor number used to access this table */ + u8 jointype; /* Type of join between this able and the previous */ + int iCursor; /* The VDBE cursor number used to access this table */ Expr *pOn; /* The ON clause of a join */ IdList *pUsing; /* The USING clause of a join */ Bitmask colUsed; /* Bit N (1<xAuth callbacks */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + Token sArg; /* Complete text of a module argument */ + u8 declareVtab; /* True if inside sqlite3_declare_vtab() */ + Table *pVirtualLock; /* Require virtual table lock on this table */ +#endif }; +#ifdef SQLITE_OMIT_VIRTUALTABLE + #define IN_DECLARE_VTAB 0 +#else + #define IN_DECLARE_VTAB (pParse->declareVtab) +#endif + /* ** An instance of the following structure can be declared on a stack and used ** to save the Parse.zAuthContext value so that it can be restored later. @@ -1441,7 +1527,9 @@ struct DbFixer { */ typedef struct { sqlite3 *db; /* The database being initialized */ + int iDb; /* 0 for main database. 1 for TEMP, 2.. for ATTACHed */ char **pzErrMsg; /* Error message stored here */ + int rc; /* Result code stored here */ } InitData; /* @@ -1500,6 +1588,7 @@ int sqlite3KeywordCode(const unsigned char*, int); int sqlite3RunParser(Parse*, const char*, char **); void sqlite3FinishCoding(Parse*); Expr *sqlite3Expr(int, Expr*, Expr*, const Token*); +Expr *sqlite3ExprOrFree(int, Expr*, Expr*, const Token*); Expr *sqlite3RegisterExpr(Parse*,Token*); Expr *sqlite3ExprAnd(Expr*, Expr*); void sqlite3ExprSpan(Expr*,Token*,Token*); @@ -1517,7 +1606,7 @@ void sqlite3RollbackInternalChanges(sqlite3*); void sqlite3CommitInternalChanges(sqlite3*); Table *sqlite3ResultSetOfSelect(Parse*,char*,Select*); void sqlite3OpenMasterTable(Parse *, int); -void sqlite3StartTable(Parse*,Token*,Token*,int,int,int); +void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int); void sqlite3AddColumn(Parse*,Token*); void sqlite3AddNotNull(Parse*, int); void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int); @@ -1527,8 +1616,9 @@ void sqlite3AddDefaultValue(Parse*,Expr*); void sqlite3AddCollateType(Parse*, const char*, int); void sqlite3EndTable(Parse*,Token*,Token*,Select*); -#ifndef SQLITE_OMIT_VIEW - void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int); +void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int); + +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) int sqlite3ViewGetColumnNames(Parse*,Table*); #else # define sqlite3ViewGetColumnNames(A,B) 0 @@ -1541,7 +1631,9 @@ int sqlite3ArrayAllocate(void**,int,int); IdList *sqlite3IdListAppend(IdList*, Token*); int sqlite3IdListIndex(IdList*,const char*); SrcList *sqlite3SrcListAppend(SrcList*, Token*, Token*); -void sqlite3SrcListAddAlias(SrcList*, Token*); +SrcList *sqlite3SrcListAppendFromTerm(SrcList*, Token*, Token*, Token*, + Select*, Expr*, IdList*); +void sqlite3SrcListShiftJoinType(SrcList*); void sqlite3SrcListAssignCursors(Parse*, SrcList*); void sqlite3IdListDelete(IdList*); void sqlite3SrcListDelete(SrcList*); @@ -1583,6 +1675,7 @@ int sqlite3ExprResolveNames(NameContext *, Expr *); int sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); int sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); Vdbe *sqlite3GetVdbe(Parse*); +Expr *sqlite3CreateIdExpr(const char*); void sqlite3Randomness(int, void*); void sqlite3RollbackAll(sqlite3*); void sqlite3CodeVerifySchema(Parse*, int); @@ -1616,9 +1709,9 @@ void sqlite3ChangeCookie(sqlite3*, Vdbe*, int); #ifndef SQLITE_OMIT_TRIGGER void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*, - int,Expr*,int); + int,Expr*,int, int); void sqlite3FinishTrigger(Parse*, TriggerStep*, Token*); - void sqlite3DropTrigger(Parse*, SrcList*); + void sqlite3DropTrigger(Parse*, SrcList*, int); void sqlite3DropTriggerPtr(Parse*, Trigger*); int sqlite3TriggersExist(Parse*, Table*, int, ExprList*); int sqlite3CodeRowTrigger(Parse*, int, ExprList*, int, Table *, int, int, @@ -1689,6 +1782,7 @@ int sqlite3ReadSchema(Parse *pParse); CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char *,int,int); CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName); CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); +Expr *sqlite3ExprSetColl(Parse *pParse, Expr *, Token *); int sqlite3CheckCollSeq(Parse *, CollSeq *); int sqlite3CheckIndexCollSeq(Parse *, Index *); int sqlite3CheckObjectName(Parse *, const char *); @@ -1744,6 +1838,14 @@ void sqlite3FailedMalloc(void); void sqlite3AbortOtherActiveVdbes(sqlite3 *, Vdbe *); int sqlite3OpenTempDatabase(Parse *); +#ifndef SQLITE_OMIT_LOAD_EXTENSION + void sqlite3CloseExtensions(sqlite3*); + int sqlite3AutoLoadExtensions(sqlite3*); +#else +# define sqlite3CloseExtensions(X) +# define sqlite3AutoLoadExtensions(X) SQLITE_OK +#endif + #ifndef SQLITE_OMIT_SHARED_CACHE void sqlite3TableLock(Parse *, int, int, u8, const char *); #else @@ -1768,6 +1870,31 @@ int sqlite3OpenTempDatabase(Parse *); #define sqlite3ThreadSafeFree sqlite3FreeX #endif +#ifdef SQLITE_OMIT_VIRTUALTABLE +# define sqlite3VtabClear(X) +# define sqlite3VtabSync(X,Y) (Y) +# define sqlite3VtabRollback(X) +# define sqlite3VtabCommit(X) +#else + void sqlite3VtabClear(Table*); + int sqlite3VtabSync(sqlite3 *db, int rc); + int sqlite3VtabRollback(sqlite3 *db); + int sqlite3VtabCommit(sqlite3 *db); +#endif +void sqlite3VtabLock(sqlite3_vtab*); +void sqlite3VtabUnlock(sqlite3_vtab*); +void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*); +void sqlite3VtabFinishParse(Parse*, Token*); +void sqlite3VtabArgInit(Parse*); +void sqlite3VtabArgExtend(Parse*, Token*); +int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **); +int sqlite3VtabCallConnect(Parse*, Table*); +int sqlite3VtabCallDestroy(sqlite3*, int, const char *); +int sqlite3VtabBegin(sqlite3 *, sqlite3_vtab *); +FuncDef *sqlite3VtabOverloadFunction(FuncDef*, int nArg, Expr*); +void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**); +int sqlite3Reprepare(Vdbe*); + #ifdef SQLITE_SSE #include "sseInt.h" #endif diff --git a/dlls/sqlite/sqlite-source/table.c b/dlls/sqlite/sqlite-source/table.c index 25b83dd0..30c14848 100644 --- a/dlls/sqlite/sqlite-source/table.c +++ b/dlls/sqlite/sqlite-source/table.c @@ -59,7 +59,7 @@ static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){ if( p->nData + need >= p->nAlloc ){ char **azNew; p->nAlloc = p->nAlloc*2 + need + 1; - azNew = realloc( p->azResult, sizeof(char*)*p->nAlloc ); + azNew = sqlite3_realloc( p->azResult, sizeof(char*)*p->nAlloc ); if( azNew==0 ) goto malloc_failed; p->azResult = azNew; } @@ -71,11 +71,9 @@ static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){ p->nColumn = nCol; for(i=0; iazResult[p->nData++] = z; } @@ -94,7 +92,7 @@ static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){ if( argv[i]==0 ){ z = 0; }else{ - z = malloc( strlen(argv[i])+1 ); + z = sqlite3_malloc( strlen(argv[i])+1 ); if( z==0 ) goto malloc_failed; strcpy(z, argv[i]); } @@ -140,34 +138,34 @@ int sqlite3_get_table( res.nData = 1; res.nAlloc = 20; res.rc = SQLITE_OK; - res.azResult = malloc( sizeof(char*)*res.nAlloc ); + res.azResult = sqlite3_malloc( sizeof(char*)*res.nAlloc ); if( res.azResult==0 ) return SQLITE_NOMEM; res.azResult[0] = 0; rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg); if( res.azResult ){ assert( sizeof(res.azResult[0])>= sizeof(res.nData) ); - res.azResult[0] = (void *)(long)res.nData; + res.azResult[0] = (char*)res.nData; } - if( rc==SQLITE_ABORT ){ + if( (rc&0xff)==SQLITE_ABORT ){ sqlite3_free_table(&res.azResult[1]); if( res.zErrMsg ){ if( pzErrMsg ){ - free(*pzErrMsg); + sqlite3_free(*pzErrMsg); *pzErrMsg = sqlite3_mprintf("%s",res.zErrMsg); } sqliteFree(res.zErrMsg); } db->errCode = res.rc; - return res.rc; + return res.rc & db->errMask; } sqliteFree(res.zErrMsg); if( rc!=SQLITE_OK ){ sqlite3_free_table(&res.azResult[1]); - return rc; + return rc & db->errMask; } if( res.nAlloc>res.nData ){ char **azNew; - azNew = realloc( res.azResult, sizeof(char*)*(res.nData+1) ); + azNew = sqlite3_realloc( res.azResult, sizeof(char*)*(res.nData+1) ); if( azNew==0 ){ sqlite3_free_table(&res.azResult[1]); return SQLITE_NOMEM; @@ -178,7 +176,7 @@ int sqlite3_get_table( *pazResult = &res.azResult[1]; if( pnColumn ) *pnColumn = res.nColumn; if( pnRow ) *pnRow = res.nRow; - return rc; + return rc & db->errMask; } /* @@ -191,9 +189,9 @@ void sqlite3_free_table( int i, n; azResult--; if( azResult==0 ) return; - n = (int)(long)azResult[0]; - for(i=1; i #include +/* + * Windows needs to know which symbols to export. Unix does not. + * BUILD_sqlite should be undefined for Unix. + */ +#ifdef BUILD_sqlite +#undef TCL_STORAGE_CLASS +#define TCL_STORAGE_CLASS DLLEXPORT +#endif /* BUILD_sqlite */ #define NUM_PREPARED_STMTS 10 #define MAX_PREPARED_STMTS 100 @@ -543,6 +551,9 @@ static int auth_callback( case SQLITE_ALTER_TABLE : zCode="SQLITE_ALTER_TABLE"; break; case SQLITE_REINDEX : zCode="SQLITE_REINDEX"; break; case SQLITE_ANALYZE : zCode="SQLITE_ANALYZE"; break; + case SQLITE_CREATE_VTABLE : zCode="SQLITE_CREATE_VTABLE"; break; + case SQLITE_DROP_VTABLE : zCode="SQLITE_DROP_VTABLE"; break; + case SQLITE_FUNCTION : zCode="SQLITE_FUNCTION"; break; default : zCode="????"; break; } Tcl_DStringInit(&str); @@ -657,24 +668,25 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ "authorizer", "busy", "cache", "changes", "close", "collate", "collation_needed", "commit_hook", "complete", - "copy", "errorcode", "eval", - "exists", "function", "last_insert_rowid", - "nullvalue", "onecolumn", "profile", - "progress", "rekey", "rollback_hook", - "timeout", "total_changes", "trace", - "transaction", "update_hook", "version", - 0 + "copy", "enable_load_extension","errorcode", + "eval", "exists", "function", + "interrupt", "last_insert_rowid", "nullvalue", + "onecolumn", "profile", "progress", + "rekey", "rollback_hook", "timeout", + "total_changes", "trace", "transaction", + "update_hook", "version", 0 }; enum DB_enum { DB_AUTHORIZER, DB_BUSY, DB_CACHE, DB_CHANGES, DB_CLOSE, DB_COLLATE, DB_COLLATION_NEEDED, DB_COMMIT_HOOK, DB_COMPLETE, - DB_COPY, DB_ERRORCODE, DB_EVAL, - DB_EXISTS, DB_FUNCTION, DB_LAST_INSERT_ROWID, - DB_NULLVALUE, DB_ONECOLUMN, DB_PROFILE, - DB_PROGRESS, DB_REKEY, DB_ROLLBACK_HOOK, - DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE, - DB_TRANSACTION, DB_UPDATE_HOOK, DB_VERSION + DB_COPY, DB_ENABLE_LOAD_EXTENSION,DB_ERRORCODE, + DB_EVAL, DB_EXISTS, DB_FUNCTION, + DB_INTERRUPT, DB_LAST_INSERT_ROWID,DB_NULLVALUE, + DB_ONECOLUMN, DB_PROFILE, DB_PROGRESS, + DB_REKEY, DB_ROLLBACK_HOOK, DB_TIMEOUT, + DB_TOTAL_CHANGES, DB_TRACE, DB_TRANSACTION, + DB_UPDATE_HOOK, DB_VERSION, }; /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */ @@ -1024,7 +1036,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ nSep = strlen(zSep); nNull = strlen(zNull); if( nSep==0 ){ - Tcl_AppendResult(interp, "Error: non-null separator required for copy", 0); + Tcl_AppendResult(interp,"Error: non-null separator required for copy",0); return TCL_ERROR; } if(sqlite3StrICmp(zConflict, "rollback") != 0 && @@ -1043,7 +1055,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ return TCL_ERROR; } nByte = strlen(zSql); - rc = sqlite3_prepare(pDb->db, zSql, 0, &pStmt, 0); + rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0); sqlite3_free(zSql); if( rc ){ Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), 0); @@ -1069,7 +1081,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ } zSql[j++] = ')'; zSql[j] = 0; - rc = sqlite3_prepare(pDb->db, zSql, 0, &pStmt, 0); + rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0); free(zSql); if( rc ){ Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), 0); @@ -1108,11 +1120,13 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ if( i+1!=nCol ){ char *zErr; zErr = malloc(200 + strlen(zFile)); - sprintf(zErr, - "Error: %s line %d: expected %d columns of data but found %d", - zFile, lineno, nCol, i+1); - Tcl_AppendResult(interp, zErr, 0); - free(zErr); + if( zErr ){ + sprintf(zErr, + "Error: %s line %d: expected %d columns of data but found %d", + zFile, lineno, nCol, i+1); + Tcl_AppendResult(interp, zErr, 0); + free(zErr); + } zCommit = "ROLLBACK"; break; } @@ -1152,6 +1166,31 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ break; } + /* + ** $db enable_load_extension BOOLEAN + ** + ** Turn the extension loading feature on or off. It if off by + ** default. + */ + case DB_ENABLE_LOAD_EXTENSION: { +#ifndef SQLITE_OMIT_LOAD_EXTENSION + int onoff; + if( objc!=3 ){ + Tcl_WrongNumArgs(interp, 2, objv, "BOOLEAN"); + return TCL_ERROR; + } + if( Tcl_GetBooleanFromObj(interp, objv[2], &onoff) ){ + return TCL_ERROR; + } + sqlite3_enable_load_extension(pDb->db, onoff); + break; +#else + Tcl_AppendResult(interp, "extension loading is turned off at compile-time", + 0); + return TCL_ERROR; +#endif + } + /* ** $db errorcode ** @@ -1536,6 +1575,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ Tcl_SetObjResult(interp, pRet); } Tcl_DecrRefCount(pRet); + }else if( rc==TCL_OK ){ + Tcl_ResetResult(interp); } break; } @@ -1576,6 +1617,17 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ break; } + /* + ** $db interrupt + ** + ** Interrupt the execution of the inner-most SQL interpreter. This + ** causes the SQL statement to return an error of SQLITE_INTERRUPT. + */ + case DB_INTERRUPT: { + sqlite3_interrupt(pDb->db); + break; + } + /* ** $db nullvalue ?STRING? ** @@ -1614,14 +1666,14 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ */ case DB_LAST_INSERT_ROWID: { Tcl_Obj *pResult; - int rowid; + Tcl_WideInt rowid; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 2, objv, ""); return TCL_ERROR; } rowid = sqlite3_last_insert_rowid(pDb->db); pResult = Tcl_GetObjResult(interp); - Tcl_SetIntObj(pResult, rowid); + Tcl_SetWideIntObj(pResult, rowid); break; } @@ -1956,6 +2008,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ const char *zArg; char *zErrMsg; const char *zFile; + Tcl_DString translatedFilename; if( objc==2 ){ zArg = Tcl_GetStringFromObj(objv[1], 0); if( strcmp(zArg,"-version")==0 ){ @@ -2004,9 +2057,11 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ } memset(p, 0, sizeof(*p)); zFile = Tcl_GetStringFromObj(objv[2], 0); + zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename); sqlite3_open(zFile, &p->db); + Tcl_DStringFree(&translatedFilename); if( SQLITE_OK!=sqlite3_errcode(p->db) ){ - zErrMsg = strdup(sqlite3_errmsg(p->db)); + zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db)); sqlite3_close(p->db); p->db = 0; } @@ -2016,10 +2071,11 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ if( p->db==0 ){ Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE); Tcl_Free((char*)p); - free(zErrMsg); + sqlite3_free(zErrMsg); return TCL_ERROR; } p->maxStmt = NUM_PREPARED_STMTS; + p->interp = interp; zArg = Tcl_GetStringFromObj(objv[1], 0); Tcl_CreateObjCommand(interp, zArg, DbObjCmd, (char*)p, DbDeleteCmd); @@ -2039,7 +2095,6 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ #endif } #endif - p->interp = interp; return TCL_OK; } @@ -2070,7 +2125,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ ** used to open a new SQLite database. See the DbMain() routine above ** for additional information. */ -extern int Sqlite3_Init(Tcl_Interp *interp){ +EXTERN int Sqlite3_Init(Tcl_Interp *interp){ Tcl_InitStubs(interp, "8.4", 0); Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0); Tcl_PkgProvide(interp, "sqlite3", PACKAGE_VERSION); @@ -2078,15 +2133,15 @@ extern int Sqlite3_Init(Tcl_Interp *interp){ Tcl_PkgProvide(interp, "sqlite", PACKAGE_VERSION); return TCL_OK; } -extern int Tclsqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } -extern int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; } -extern int Tclsqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; } +EXTERN int Tclsqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } +EXTERN int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; } +EXTERN int Tclsqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; } #ifndef SQLITE_3_SUFFIX_ONLY -extern int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } -extern int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } -extern int Sqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; } -extern int Tclsqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; } +EXTERN int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } +EXTERN int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } +EXTERN int Sqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; } +EXTERN int Tclsqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; } #endif #ifdef TCLSH @@ -2149,9 +2204,13 @@ int TCLSH_MAIN(int argc, char **argv){ extern int Sqlitetest5_Init(Tcl_Interp*); extern int Sqlitetest6_Init(Tcl_Interp*); extern int Sqlitetest7_Init(Tcl_Interp*); + extern int Sqlitetest8_Init(Tcl_Interp*); extern int Md5_Init(Tcl_Interp*); extern int Sqlitetestsse_Init(Tcl_Interp*); extern int Sqlitetestasync_Init(Tcl_Interp*); + extern int Sqlitetesttclvar_Init(Tcl_Interp*); + extern int Sqlitetestschema_Init(Tcl_Interp*); + extern int Sqlitetest_autoext_Init(Tcl_Interp*); Sqlitetest1_Init(interp); Sqlitetest2_Init(interp); @@ -2160,7 +2219,11 @@ int TCLSH_MAIN(int argc, char **argv){ Sqlitetest5_Init(interp); Sqlitetest6_Init(interp); Sqlitetest7_Init(interp); + Sqlitetest8_Init(interp); Sqlitetestasync_Init(interp); + Sqlitetesttclvar_Init(interp); + Sqlitetestschema_Init(interp); + Sqlitetest_autoext_Init(interp); Md5_Init(interp); #ifdef SQLITE_SSE Sqlitetestsse_Init(interp); @@ -2169,6 +2232,9 @@ int TCLSH_MAIN(int argc, char **argv){ #endif if( argc>=2 || TCLSH==2 ){ int i; + char zArgc[32]; + sqlite3_snprintf(sizeof(zArgc), zArgc, "%d", argc-(3-TCLSH)); + Tcl_SetVar(interp,"argc", zArgc, TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"argv0",argv[1],TCL_GLOBAL_ONLY); Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY); for(i=3-TCLSH; idb; - extern void *sqlite3ParserAlloc(void*(*)(int)); + extern void *sqlite3ParserAlloc(void*(*)(size_t)); extern void sqlite3ParserFree(void*, void(*)(void*)); - extern int sqlite3Parser(void*, int, Token, Parse*); + extern void sqlite3Parser(void*, int, Token, Parse*); - db->flags &= ~SQLITE_Interrupt; + if( db->activeVdbeCnt==0 ){ + db->u1.isInterrupted = 0; + } pParse->rc = SQLITE_OK; i = 0; - pEngine = sqlite3ParserAlloc((void*(*)(int))sqlite3MallocX); + pEngine = sqlite3ParserAlloc((void*(*)(size_t))sqlite3MallocX); if( pEngine==0 ){ return SQLITE_NOMEM; } @@ -418,7 +424,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ switch( tokenType ){ case TK_SPACE: case TK_COMMENT: { - if( (db->flags & SQLITE_Interrupt)!=0 ){ + if( db->u1.isInterrupted ){ pParse->rc = SQLITE_INTERRUPT; sqlite3SetString(pzErrMsg, "interrupt", (char*)0); goto abort_parse; @@ -483,7 +489,15 @@ abort_parse: pParse->nTableLock = 0; } #endif - sqlite3DeleteTable(pParse->db, pParse->pNewTable); + + if( !IN_DECLARE_VTAB ){ + /* If the pParse->declareVtab flag is set, do not delete any table + ** structure built up in pParse->pNewTable. The calling code (see vtab.c) + ** will take responsibility for freeing the Table structure. + */ + sqlite3DeleteTable(pParse->db, pParse->pNewTable); + } + sqlite3DeleteTrigger(pParse->pNewTrigger); sqliteFree(pParse->apVarExpr); if( nErr>0 && (pParse->rc==SQLITE_OK || pParse->rc==SQLITE_DONE) ){ diff --git a/dlls/sqlite/sqlite-source/trigger.c b/dlls/sqlite/sqlite-source/trigger.c index d670e527..a6eabbf6 100644 --- a/dlls/sqlite/sqlite-source/trigger.c +++ b/dlls/sqlite/sqlite-source/trigger.c @@ -49,7 +49,8 @@ void sqlite3BeginTrigger( SrcList *pTableName,/* The name of the table/view the trigger applies to */ int foreach, /* One of TK_ROW or TK_STATEMENT */ Expr *pWhen, /* WHEN clause */ - int isTemp /* True if the TEMPORARY keyword is present */ + int isTemp, /* True if the TEMPORARY keyword is present */ + int noErr /* Suppress errors if the trigger already exists */ ){ Trigger *pTrigger = 0; Table *pTab; @@ -103,6 +104,10 @@ void sqlite3BeginTrigger( /* The table does not exist. */ goto trigger_cleanup; } + if( IsVirtual(pTab) ){ + sqlite3ErrorMsg(pParse, "cannot create triggers on virtual tables"); + goto trigger_cleanup; + } /* Check that the trigger name is not reserved and that no trigger of the ** specified name exists */ @@ -111,7 +116,9 @@ void sqlite3BeginTrigger( goto trigger_cleanup; } if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash), zName,strlen(zName)) ){ - sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); + if( !noErr ){ + sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); + } goto trigger_cleanup; } @@ -435,7 +442,7 @@ void sqlite3DeleteTrigger(Trigger *pTrigger){ ** same job as this routine except it takes a pointer to the trigger ** instead of the trigger name. **/ -void sqlite3DropTrigger(Parse *pParse, SrcList *pName){ +void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){ Trigger *pTrigger = 0; int i; const char *zDb; @@ -459,7 +466,9 @@ void sqlite3DropTrigger(Parse *pParse, SrcList *pName){ if( pTrigger ) break; } if( !pTrigger ){ - sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0); + if( !noErr ){ + sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0); + } goto drop_trigger_cleanup; } sqlite3DropTriggerPtr(pParse, pTrigger); @@ -594,9 +603,10 @@ int sqlite3TriggersExist( int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */ ExprList *pChanges /* Columns that change in an UPDATE statement */ ){ - Trigger *pTrigger = pTab->pTrigger; + Trigger *pTrigger; int mask = 0; + pTrigger = IsVirtual(pTab) ? 0 : pTab->pTrigger; while( pTrigger ){ if( pTrigger->op==op && checkColumnOverLap(pTrigger->pColumns, pChanges) ){ mask |= pTrigger->tr_tm; @@ -658,12 +668,12 @@ static int codeTriggerProgram( pParse->trigStack->orconf = orconf; switch( pTriggerStep->op ){ case TK_SELECT: { - Select * ss = sqlite3SelectDup(pTriggerStep->pSelect); - assert(ss); - assert(ss->pSrc); - sqlite3SelectResolve(pParse, ss, 0); - sqlite3Select(pParse, ss, SRT_Discard, 0, 0, 0, 0, 0); - sqlite3SelectDelete(ss); + Select *ss = sqlite3SelectDup(pTriggerStep->pSelect); + if( ss ){ + sqlite3SelectResolve(pParse, ss, 0); + sqlite3Select(pParse, ss, SRT_Discard, 0, 0, 0, 0, 0); + sqlite3SelectDelete(ss); + } break; } case TK_UPDATE: { diff --git a/dlls/sqlite/sqlite-source/update.c b/dlls/sqlite/sqlite-source/update.c index e61ac8b1..f1cd038b 100644 --- a/dlls/sqlite/sqlite-source/update.c +++ b/dlls/sqlite/sqlite-source/update.c @@ -16,6 +16,19 @@ */ #include "sqliteInt.h" +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Forward declaration */ +static void updateVirtualTable( + Parse *pParse, /* The parsing context */ + SrcList *pSrc, /* The virtual table to be modified */ + Table *pTab, /* The virtual table */ + ExprList *pChanges, /* The columns to change in the UPDATE statement */ + Expr *pRowidExpr, /* Expression used to recompute the rowid */ + int *aXRef, /* Mapping from columns of pTab to entries in pChanges */ + Expr *pWhere /* WHERE clause of the UPDATE statement */ +); +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + /* ** The most recently coded instruction was an OP_Column to retrieve the ** i-th column of table pTab. This routine sets the P3 parameter of the @@ -90,6 +103,7 @@ void sqlite3Update( AuthContext sContext; /* The authorization context */ NameContext sNC; /* The name-context to resolve expressions in */ int iDb; /* Database containing the table being updated */ + int memCnt = 0; /* Memory cell used for counting rows changed */ #ifndef SQLITE_OMIT_TRIGGER int isView; /* Trying to update a view */ @@ -130,10 +144,8 @@ void sqlite3Update( if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){ goto update_cleanup; } - if( isView ){ - if( sqlite3ViewGetColumnNames(pParse, pTab) ){ - goto update_cleanup; - } + if( sqlite3ViewGetColumnNames(pParse, pTab) ){ + goto update_cleanup; } aXRef = sqliteMallocRaw( sizeof(int) * pTab->nCol ); if( aXRef==0 ) goto update_cleanup; @@ -242,6 +254,24 @@ void sqlite3Update( } } + /* Begin generating code. + */ + v = sqlite3GetVdbe(pParse); + if( v==0 ) goto update_cleanup; + if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); + sqlite3BeginWriteOperation(pParse, 1, iDb); + +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* Virtual tables must be handled separately */ + if( IsVirtual(pTab) ){ + updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef, + pWhere); + pWhere = 0; + pTabList = 0; + goto update_cleanup; + } +#endif + /* Resolve the column names in all the expressions in the ** WHERE clause. */ @@ -255,20 +285,13 @@ void sqlite3Update( sqlite3AuthContextPush(pParse, &sContext, pTab->zName); } - /* Begin generating code. - */ - v = sqlite3GetVdbe(pParse); - if( v==0 ) goto update_cleanup; - if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); - sqlite3BeginWriteOperation(pParse, 1, iDb); - /* If we are trying to update a view, realize that view into ** a ephemeral table. */ if( isView ){ Select *pView; pView = sqlite3SelectDup(pTab->pSelect); - sqlite3Select(pParse, pView, SRT_VirtualTab, iCur, 0, 0, 0, 0); + sqlite3Select(pParse, pView, SRT_EphemTab, iCur, 0, 0, 0, 0); sqlite3SelectDelete(pView); } @@ -277,9 +300,9 @@ void sqlite3Update( pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0); if( pWInfo==0 ) goto update_cleanup; - /* Remember the index of every item to be updated. + /* Remember the rowid of every item to be updated. */ - sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0); + sqlite3VdbeAddOp(v, IsVirtual(pTab) ? OP_VRowid : OP_Rowid, iCur, 0); sqlite3VdbeAddOp(v, OP_FifoWrite, 0, 0); /* End the database scan loop. @@ -289,7 +312,8 @@ void sqlite3Update( /* Initialize the count of updated rows */ if( db->flags & SQLITE_CountRows && !pParse->trigStack ){ - sqlite3VdbeAddOp(v, OP_Integer, 0, 0); + memCnt = pParse->nMem++; + sqlite3VdbeAddOp(v, OP_MemInt, 0, memCnt); } if( triggers_exist ){ @@ -358,7 +382,7 @@ void sqlite3Update( } } - if( !isView ){ + if( !isView && !IsVirtual(pTab) ){ /* ** Open every index that needs updating. Note that if any ** index could potentially invoke a REPLACE conflict resolution @@ -390,7 +414,7 @@ void sqlite3Update( /* Loop over every record that needs updating. We have to load ** the old data for each record to be updated because some columns ** might not change and we will need to copy the old value. - ** Also, the old data is needed to delete the old index entires. + ** Also, the old data is needed to delete the old index entries. ** So make the cursor point at the old record. */ if( !triggers_exist ){ @@ -447,7 +471,7 @@ void sqlite3Update( /* Increment the row counter */ if( db->flags & SQLITE_CountRows && !pParse->trigStack){ - sqlite3VdbeAddOp(v, OP_AddImm, 1, 0); + sqlite3VdbeAddOp(v, OP_MemIncr, 1, memCnt); } /* If there are triggers, close all the cursors after each iteration @@ -492,6 +516,7 @@ void sqlite3Update( ** invoke the callback function. */ if( db->flags & SQLITE_CountRows && !pParse->trigStack && pParse->nested==0 ){ + sqlite3VdbeAddOp(v, OP_MemLoad, memCnt, 0); sqlite3VdbeAddOp(v, OP_Callback, 1, 0); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", P3_STATIC); @@ -506,3 +531,95 @@ update_cleanup: sqlite3ExprDelete(pWhere); return; } + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Generate code for an UPDATE of a virtual table. +** +** The strategy is that we create an ephemerial table that contains +** for each row to be changed: +** +** (A) The original rowid of that row. +** (B) The revised rowid for the row. (note1) +** (C) The content of every column in the row. +** +** Then we loop over this ephemeral table and for each row in +** the ephermeral table call VUpdate. +** +** When finished, drop the ephemeral table. +** +** (note1) Actually, if we know in advance that (A) is always the same +** as (B) we only store (A), then duplicate (A) when pulling +** it out of the ephemeral table before calling VUpdate. +*/ +static void updateVirtualTable( + Parse *pParse, /* The parsing context */ + SrcList *pSrc, /* The virtual table to be modified */ + Table *pTab, /* The virtual table */ + ExprList *pChanges, /* The columns to change in the UPDATE statement */ + Expr *pRowid, /* Expression used to recompute the rowid */ + int *aXRef, /* Mapping from columns of pTab to entries in pChanges */ + Expr *pWhere /* WHERE clause of the UPDATE statement */ +){ + Vdbe *v = pParse->pVdbe; /* Virtual machine under construction */ + ExprList *pEList = 0; /* The result set of the SELECT statement */ + Select *pSelect = 0; /* The SELECT statement */ + Expr *pExpr; /* Temporary expression */ + int ephemTab; /* Table holding the result of the SELECT */ + int i; /* Loop counter */ + int addr; /* Address of top of loop */ + + /* Construct the SELECT statement that will find the new values for + ** all updated rows. + */ + pEList = sqlite3ExprListAppend(0, sqlite3CreateIdExpr("_rowid_"), 0); + if( pRowid ){ + pEList = sqlite3ExprListAppend(pEList, sqlite3ExprDup(pRowid), 0); + } + assert( pTab->iPKey<0 ); + for(i=0; inCol; i++){ + if( aXRef[i]>=0 ){ + pExpr = sqlite3ExprDup(pChanges->a[aXRef[i]].pExpr); + }else{ + pExpr = sqlite3CreateIdExpr(pTab->aCol[i].zName); + } + pEList = sqlite3ExprListAppend(pEList, pExpr, 0); + } + pSelect = sqlite3SelectNew(pEList, pSrc, pWhere, 0, 0, 0, 0, 0, 0); + + /* Create the ephemeral table into which the update results will + ** be stored. + */ + assert( v ); + ephemTab = pParse->nTab++; + sqlite3VdbeAddOp(v, OP_OpenEphemeral, ephemTab, pTab->nCol+1+(pRowid!=0)); + + /* fill the ephemeral table + */ + sqlite3Select(pParse, pSelect, SRT_Table, ephemTab, 0, 0, 0, 0); + + /* + ** Generate code to scan the ephemeral table and call VDelete and + ** VInsert + */ + sqlite3VdbeAddOp(v, OP_Rewind, ephemTab, 0); + addr = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp(v, OP_Column, ephemTab, 0); + if( pRowid ){ + sqlite3VdbeAddOp(v, OP_Column, ephemTab, 1); + }else{ + sqlite3VdbeAddOp(v, OP_Dup, 0, 0); + } + for(i=0; inCol; i++){ + sqlite3VdbeAddOp(v, OP_Column, ephemTab, i+1+(pRowid!=0)); + } + pParse->pVirtualLock = pTab; + sqlite3VdbeOp3(v, OP_VUpdate, 0, pTab->nCol+2, + (const char*)pTab->pVtab, P3_VTAB); + sqlite3VdbeAddOp(v, OP_Next, ephemTab, addr); + sqlite3VdbeAddOp(v, OP_Close, ephemTab, 0); + + /* Cleanup */ + sqlite3SelectDelete(pSelect); +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ diff --git a/dlls/sqlite/sqlite-source/utf.c b/dlls/sqlite/sqlite-source/utf.c index 5df00dad..6b78a6de 100644 --- a/dlls/sqlite/sqlite-source/utf.c +++ b/dlls/sqlite/sqlite-source/utf.c @@ -64,7 +64,7 @@ /* ** This table maps from the first byte of a UTF-8 character to the number -** of trailing bytes expected. A value '255' indicates that the table key +** of trailing bytes expected. A value '4' indicates that the table key ** is not a legal first byte for a UTF-8 character. */ static const u8 xtra_utf8_bytes[256] = { @@ -79,10 +79,10 @@ static const u8 xtra_utf8_bytes[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10wwwwww */ -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, /* 110yyyyy */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -92,7 +92,7 @@ static const u8 xtra_utf8_bytes[256] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 11110yyy */ -3, 3, 3, 3, 3, 3, 3, 3, 255, 255, 255, 255, 255, 255, 255, 255, +3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, }; /* @@ -101,11 +101,24 @@ static const u8 xtra_utf8_bytes[256] = { ** read by a naive implementation of a UTF-8 character reader. The code ** in the READ_UTF8 macro explains things best. */ -static const int xtra_utf8_bits[4] = { -0, -12416, /* (0xC0 << 6) + (0x80) */ -925824, /* (0xE0 << 12) + (0x80 << 6) + (0x80) */ -63447168 /* (0xF0 << 18) + (0x80 << 12) + (0x80 << 6) + 0x80 */ +static const int xtra_utf8_bits[] = { + 0, + 12416, /* (0xC0 << 6) + (0x80) */ + 925824, /* (0xE0 << 12) + (0x80 << 6) + (0x80) */ + 63447168 /* (0xF0 << 18) + (0x80 << 12) + (0x80 << 6) + 0x80 */ +}; + +/* +** If a UTF-8 character contains N bytes extra bytes (N bytes follow +** the initial byte so that the total character length is N+1) then +** masking the character with utf8_mask[N] must produce a non-zero +** result. Otherwise, we have an (illegal) overlong encoding. +*/ +static const int utf_mask[] = { + 0x00000000, + 0xffffff80, + 0xfffff800, + 0xffff0000, }; #define READ_UTF8(zIn, c) { \ @@ -113,11 +126,14 @@ static const int xtra_utf8_bits[4] = { c = *(zIn)++; \ xtra = xtra_utf8_bytes[c]; \ switch( xtra ){ \ - case 255: c = (int)0xFFFD; break; \ + case 4: c = (int)0xFFFD; break; \ case 3: c = (c<<6) + *(zIn)++; \ case 2: c = (c<<6) + *(zIn)++; \ case 1: c = (c<<6) + *(zIn)++; \ c -= xtra_utf8_bits[xtra]; \ + if( (utf_mask[xtra]&c)==0 \ + || (c&0xFFFFF800)==0xD800 \ + || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \ } \ } int sqlite3ReadUtf8(const unsigned char *z){ @@ -181,6 +197,7 @@ int sqlite3ReadUtf8(const unsigned char *z){ int c2 = (*zIn++); \ c2 += ((*zIn++)<<8); \ c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10); \ + if( (c & 0xFFFF0000)==0 ) c = 0xFFFD; \ } \ } @@ -191,6 +208,7 @@ int sqlite3ReadUtf8(const unsigned char *z){ int c2 = ((*zIn++)<<8); \ c2 += (*zIn++); \ c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10); \ + if( (c & 0xFFFF0000)==0 ) c = 0xFFFD; \ } \ } @@ -245,7 +263,7 @@ int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){ unsigned char *zIn; /* Input iterator */ unsigned char *zTerm; /* End of input */ unsigned char *z; /* Output iterator */ - int c; + unsigned int c; assert( pMem->flags&MEM_Str ); assert( pMem->enc!=desiredEnc ); @@ -287,11 +305,11 @@ int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){ /* Set len to the maximum number of bytes required in the output buffer. */ if( desiredEnc==SQLITE_UTF8 ){ /* When converting from UTF-16, the maximum growth results from - ** translating a 2-byte character to a 3-byte UTF-8 character (i.e. - ** code-point 0xFFFC). A single byte is required for the output string + ** translating a 2-byte character to a 4-byte UTF-8 character. + ** A single byte is required for the output string ** nul-terminator. */ - len = (pMem->n/2) * 3 + 1; + len = pMem->n * 2 + 1; }else{ /* When converting from UTF-8 to UTF-16 the maximum growth is caused ** when a 1-byte UTF-8 character is translated into a 2-byte UTF-16 @@ -462,8 +480,8 @@ char *sqlite3utf16to8(const void *z, int nByte){ memset(&m, 0, sizeof(m)); sqlite3VdbeMemSetStr(&m, z, nByte, SQLITE_UTF16NATIVE, SQLITE_STATIC); sqlite3VdbeChangeEncoding(&m, SQLITE_UTF8); - assert( m.flags & MEM_Term ); - assert( m.flags & MEM_Str ); + assert( (m.flags & MEM_Term)!=0 || sqlite3MallocFailed() ); + assert( (m.flags & MEM_Str)!=0 || sqlite3MallocFailed() ); return (m.flags & MEM_Dyn)!=0 ? m.z : sqliteStrDup(m.z); } @@ -475,7 +493,7 @@ char *sqlite3utf16to8(const void *z, int nByte){ ** in pZ (or up until the first pair of 0x00 bytes, whichever comes first). */ int sqlite3utf16ByteLen(const void *zIn, int nChar){ - int c = 1; + unsigned int c = 1; char const *z = zIn; int n = 0; if( SQLITE_UTF16NATIVE==SQLITE_UTF16BE ){ @@ -556,11 +574,11 @@ void sqlite3utf16Substr( ** characters in each encoding are inverses of each other. */ void sqlite3utfSelfTest(){ - int i; + unsigned int i, t; unsigned char zBuf[20]; unsigned char *z; int n; - int c; + unsigned int c; for(i=0; i<0x00110000; i++){ z = zBuf; @@ -568,7 +586,10 @@ void sqlite3utfSelfTest(){ n = z-zBuf; z = zBuf; READ_UTF8(z, c); - assert( c==i ); + t = i; + if( i>=0xD800 && i<=0xDFFF ) t = 0xFFFD; + if( (i&0xFFFFFFFE)==0xFFFE ) t = 0xFFFD; + assert( c==t ); assert( (z-zBuf)==n ); } for(i=0; i<0x00110000; i++){ diff --git a/dlls/sqlite/sqlite-source/util.c b/dlls/sqlite/sqlite-source/util.c index e30401ee..4d8b214e 100644 --- a/dlls/sqlite/sqlite-source/util.c +++ b/dlls/sqlite/sqlite-source/util.c @@ -476,8 +476,9 @@ static int OSSIZEOF(void *p){ ** pointer to the space allocated for the application to use. */ static void OSFREE(void *pFree){ + u32 *p; /* Pointer to the OS-layer allocation */ sqlite3OsEnterMutex(); - u32 *p = (u32 *)getOsPointer(pFree); /* p points to Os level allocation */ + p = (u32 *)getOsPointer(pFree); checkGuards(p); unlinkAlloc(p); memset(pFree, 0x55, OSSIZEOF(pFree)); @@ -683,11 +684,11 @@ void sqlite3ReallocOrFree(void **pp, int n){ */ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT void *sqlite3ThreadSafeMalloc(int n){ - ENTER_MALLOC; + (void)ENTER_MALLOC; return sqlite3Malloc(n, 0); } void sqlite3ThreadSafeFree(void *p){ - ENTER_MALLOC; + (void)ENTER_MALLOC; if( p ){ OSFREE(p); } @@ -1150,7 +1151,7 @@ int sqlite3SafetyOn(sqlite3 *db){ return 0; }else if( db->magic==SQLITE_MAGIC_BUSY ){ db->magic = SQLITE_MAGIC_ERROR; - db->flags |= SQLITE_Interrupt; + db->u1.isInterrupted = 1; } return 1; } @@ -1166,7 +1167,7 @@ int sqlite3SafetyOff(sqlite3 *db){ return 0; }else if( db->magic==SQLITE_MAGIC_OPEN ){ db->magic = SQLITE_MAGIC_ERROR; - db->flags |= SQLITE_Interrupt; + db->u1.isInterrupted = 1; } return 1; } @@ -1356,8 +1357,10 @@ void *sqlite3HexToBlob(const char *z){ if( n%2 ) return 0; zBlob = (char *)sqliteMalloc(n/2); - for(i=0; ierrMask : 0xff); } /* diff --git a/dlls/sqlite/sqlite-source/vacuum.c b/dlls/sqlite/sqlite-source/vacuum.c index 336df67c..07f62ae7 100644 --- a/dlls/sqlite/sqlite-source/vacuum.c +++ b/dlls/sqlite/sqlite-source/vacuum.c @@ -21,20 +21,6 @@ #include "os.h" #ifndef SQLITE_OMIT_VACUUM -/* -** Generate a random name of 20 character in length. -*/ -static void randomName(unsigned char *zBuf){ - static const unsigned char zChars[] = - "abcdefghijklmnopqrstuvwxyz" - "0123456789"; - int i; - sqlite3Randomness(20, zBuf); - for(i=0; i<20; i++){ - zBuf[i] = zChars[ zBuf[i]%(sizeof(zChars)-1) ]; - } -} - /* ** Execute zSql on database db. Return an error code. */ @@ -69,8 +55,6 @@ static int execExecSql(sqlite3 *db, const char *zSql){ return sqlite3_finalize(pStmt); } -#endif - /* ** The non-standard VACUUM command is used to clean up the database, ** collapse free space, etc. It is modelled after the VACUUM command @@ -94,60 +78,25 @@ void sqlite3Vacuum(Parse *pParse){ */ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ int rc = SQLITE_OK; /* Return code from service routines */ -#ifndef SQLITE_OMIT_VACUUM - const char *zFilename; /* full pathname of the database file */ - int nFilename; /* number of characters in zFilename[] */ - char *zTemp = 0; /* a temporary file in same directory as zFilename */ Btree *pMain; /* The database being vacuumed */ - Btree *pTemp; - char *zSql = 0; - int saved_flags; /* Saved value of the db->flags */ - Db *pDb = 0; /* Database to detach at end of vacuum */ + Btree *pTemp; /* The temporary database we vacuum into */ + char *zSql = 0; /* SQL statements */ + int saved_flags; /* Saved value of the db->flags */ + Db *pDb = 0; /* Database to detach at end of vacuum */ + char zTemp[SQLITE_TEMPNAME_SIZE+20]; /* Name of the TEMP file */ /* Save the current value of the write-schema flag before setting it. */ saved_flags = db->flags; db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks; + sqlite3OsTempFileName(zTemp); if( !db->autoCommit ){ sqlite3SetString(pzErrMsg, "cannot VACUUM from within a transaction", (char*)0); rc = SQLITE_ERROR; goto end_of_vacuum; } - - /* Get the full pathname of the database file and create a - ** temporary filename in the same directory as the original file. - */ pMain = db->aDb[0].pBt; - zFilename = sqlite3BtreeGetFilename(pMain); - assert( zFilename ); - if( zFilename[0]=='\0' ){ - /* The in-memory database. Do nothing. Return directly to avoid causing - ** an error trying to DETACH the vacuum_db (which never got attached) - ** in the exit-handler. - */ - return SQLITE_OK; - } - nFilename = strlen(zFilename); - zTemp = sqliteMalloc( nFilename+100 ); - if( zTemp==0 ){ - rc = SQLITE_NOMEM; - goto end_of_vacuum; - } - strcpy(zTemp, zFilename); - - /* The randomName() procedure in the following loop uses an excellent - ** source of randomness to generate a name from a space of 1.3e+31 - ** possibilities. So unless the directory already contains on the order - ** of 1.3e+31 files, the probability that the following loop will - ** run more than once or twice is vanishingly small. We are certain - ** enough that this loop will always terminate (and terminate quickly) - ** that we don't even bother to set a maximum loop count. - */ - do { - zTemp[nFilename] = '-'; - randomName((unsigned char*)&zTemp[nFilename+1]); - } while( sqlite3OsFileExists(zTemp) ); /* Attach the temporary database as 'vacuum_db'. The synchronous pragma ** can be set to 'off' for this file, as it is not recovered if a crash @@ -190,7 +139,9 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ */ rc = execExecSql(db, "SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14,100000000) " - " FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'"); + " FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'" + " AND rootpage>0" + ); if( rc!=SQLITE_OK ) goto end_of_vacuum; rc = execExecSql(db, "SELECT 'CREATE INDEX vacuum_db.' || substr(sql,14,100000000)" @@ -200,11 +151,6 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ "SELECT 'CREATE UNIQUE INDEX vacuum_db.' || substr(sql,21,100000000) " " FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %'"); if( rc!=SQLITE_OK ) goto end_of_vacuum; - rc = execExecSql(db, - "SELECT 'CREATE VIEW vacuum_db.' || substr(sql,13,100000000) " - " FROM sqlite_master WHERE type='view'" - ); - if( rc!=SQLITE_OK ) goto end_of_vacuum; /* Loop through the tables in the main database. For each, do ** an "INSERT INTO vacuum_db.xxx SELECT * FROM xxx;" to copy @@ -214,7 +160,9 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ "SELECT 'INSERT INTO vacuum_db.' || quote(name) " "|| ' SELECT * FROM ' || quote(name) || ';'" "FROM sqlite_master " - "WHERE type = 'table' AND name!='sqlite_sequence';" + "WHERE type = 'table' AND name!='sqlite_sequence' " + " AND rootpage>0" + ); if( rc!=SQLITE_OK ) goto end_of_vacuum; @@ -233,17 +181,19 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ if( rc!=SQLITE_OK ) goto end_of_vacuum; - /* Copy the triggers from the main database to the temporary database. - ** This was deferred before in case the triggers interfered with copying - ** the data. It's possible the indices should be deferred until this - ** point also. + /* Copy the triggers, views, and virtual tables from the main database + ** over to the temporary database. None of these objects has any + ** associated storage, so all we have to do is copy their entries + ** from the SQLITE_MASTER table. */ - rc = execExecSql(db, - "SELECT 'CREATE TRIGGER vacuum_db.' || substr(sql, 16, 1000000) " - "FROM sqlite_master WHERE type='trigger'" + rc = execSql(db, + "INSERT INTO vacuum_db.sqlite_master " + " SELECT type, name, tbl_name, rootpage, sql" + " FROM sqlite_master" + " WHERE type='view' OR type='trigger'" + " OR (type='table' AND rootpage=0)" ); - if( rc!=SQLITE_OK ) goto end_of_vacuum; - + if( rc ) goto end_of_vacuum; /* At this point, unless the main db was completely empty, there is now a ** transaction open on the vacuum database, but not on the main database. @@ -309,21 +259,12 @@ end_of_vacuum: pDb->pSchema = 0; } - /* If one of the execSql() calls above returned SQLITE_NOMEM, then the - ** mallocFailed flag will be clear (because execSql() calls sqlite3_exec()). - ** Fix this so the flag and return code match. - */ - if( rc==SQLITE_NOMEM ){ - sqlite3MallocFailed(); - } - - if( zTemp ){ - sqlite3OsDelete(zTemp); - sqliteFree(zTemp); - } + sqlite3OsDelete(zTemp); + strcat(zTemp, "-journal"); + sqlite3OsDelete(zTemp); sqliteFree( zSql ); sqlite3ResetInternalSchema(db, 0); -#endif return rc; } +#endif /* SQLITE_OMIT_VACUUM */ diff --git a/dlls/sqlite/sqlite-source/vdbe.c b/dlls/sqlite/sqlite-source/vdbe.c index 6a5aed89..2e0fa78a 100644 --- a/dlls/sqlite/sqlite-source/vdbe.c +++ b/dlls/sqlite/sqlite-source/vdbe.c @@ -57,17 +57,21 @@ ** working correctly. This variable has no function other than to ** help verify the correct operation of the library. */ +#ifdef SQLITE_TEST int sqlite3_search_count = 0; +#endif /* ** When this global variable is positive, it gets decremented once before -** each instruction in the VDBE. When reaches zero, the SQLITE_Interrupt -** of the db.flags field is set in order to simulate and interrupt. +** each instruction in the VDBE. When reaches zero, the u1.isInterrupted +** field of the sqlite3 structure is set in order to simulate and interrupt. ** ** This facility is used for testing purposes only. It does not function ** in an ordinary build. */ +#ifdef SQLITE_TEST int sqlite3_interrupt_count = 0; +#endif /* ** The next global variable is incremented each type the OP_Sort opcode @@ -76,7 +80,9 @@ int sqlite3_interrupt_count = 0; ** has no function other than to help verify the correct operation of the ** library. */ +#ifdef SQLITE_TEST int sqlite3_sort_count = 0; +#endif /* ** Release the memory associated with the given stack level. This @@ -180,7 +186,7 @@ static Cursor *allocateCursor(Vdbe *p, int iCur, int iDb){ Cursor *pCx; assert( iCurnCursor ); if( p->apCsr[iCur] ){ - sqlite3VdbeFreeCursor(p->apCsr[iCur]); + sqlite3VdbeFreeCursor(p, p->apCsr[iCur]); } p->apCsr[iCur] = pCx = sqliteMalloc( sizeof(Cursor) ); if( pCx ){ @@ -376,7 +382,7 @@ __inline__ unsigned long long int hwtime(void){ ** flag on jump instructions, we get a (small) speed improvement. */ #define CHECK_FOR_INTERRUPT \ - if( db->flags & SQLITE_Interrupt ) goto abort_due_to_interrupt; + if( db->u1.isInterrupted ) goto abort_due_to_interrupt; /* @@ -448,6 +454,21 @@ int sqlite3VdbeExec( p->resOnStack = 0; db->busyHandler.nBusy = 0; CHECK_FOR_INTERRUPT; +#ifdef SQLITE_DEBUG + if( (p->db->flags & SQLITE_VdbeListing)!=0 + || sqlite3OsFileExists("vdbe_explain") + ){ + int i; + printf("VDBE Program Listing:\n"); + sqlite3VdbePrintSql(p); + for(i=0; inOp; i++){ + sqlite3VdbePrintOp(stdout, i, &p->aOp[i]); + } + } + if( sqlite3OsFileExists("vdbe_trace") ){ + p->trace = stdout; + } +#endif for(pc=p->pc; rc==SQLITE_OK; pc++){ assert( pc>=0 && pcnOp ); assert( pTos<=&p->aStack[pc] ); @@ -495,11 +516,14 @@ int sqlite3VdbeExec( */ if( db->xProgress ){ if( db->nProgressOps==nProgressOps ){ + if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; if( db->xProgress(db->pProgressArg)!=0 ){ + sqlite3SafetyOn(db); rc = SQLITE_ABORT; continue; /* skip to the next iteration of the for loop */ } nProgressOps = 0; + if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; } nProgressOps++; } @@ -1803,32 +1827,31 @@ case OP_IfNot: { /* no-push */ /* Opcode: IsNull P1 P2 * ** -** If any of the top abs(P1) values on the stack are NULL, then jump -** to P2. Pop the stack P1 times if P1>0. If P1<0 leave the stack -** unchanged. +** Check the top of the stack and jump to P2 if the top of the stack +** is NULL. If P1 is positive, then pop P1 elements from the stack +** regardless of whether or not the jump is taken. If P1 is negative, +** pop -P1 elements from the stack only if the jump is taken and leave +** the stack unchanged if the jump is not taken. */ case OP_IsNull: { /* same as TK_ISNULL, no-push */ - int i, cnt; - Mem *pTerm; - cnt = pOp->p1; - if( cnt<0 ) cnt = -cnt; - pTerm = &pTos[1-cnt]; - assert( pTerm>=p->aStack ); - for(i=0; iflags & MEM_Null ){ - pc = pOp->p2-1; - break; + if( pTos->flags & MEM_Null ){ + pc = pOp->p2-1; + if( pOp->p1<0 ){ + popStack(&pTos, -pOp->p1); } } - if( pOp->p1>0 ) popStack(&pTos, cnt); + if( pOp->p1>0 ){ + popStack(&pTos, pOp->p1); + } break; } /* Opcode: NotNull P1 P2 * ** -** Jump to P2 if the top P1 values on the stack are all not NULL. Pop the -** stack if P1 times if P1 is greater than zero. If P1 is less than -** zero then leave the stack unchanged. +** Jump to P2 if the top abs(P1) values on the stack are all not NULL. +** Regardless of whether or not the jump is taken, pop the stack +** P1 times if P1 is greater than zero. But if P1 is negative, +** leave the stack unchanged. */ case OP_NotNull: { /* same as TK_NOTNULL, no-push */ int i, cnt; @@ -2001,7 +2024,9 @@ case OP_Column: { pC->aRow = 0; } } - assert( zRec!=0 || avail>=payloadSize || avail>=9 ); + /* The following assert is true in all cases accept when + ** the database file has been corrupted externally. + ** assert( zRec!=0 || avail>=payloadSize || avail>=9 ); */ szHdrSz = GetVarint((u8*)zData, offset); /* The KeyFetch() or DataFetch() above are fast and will get the entire @@ -2492,6 +2517,8 @@ case OP_VerifyCookie: { /* no-push */ } if( rc==SQLITE_OK && iMeta!=pOp->p2 ){ sqlite3SetString(&p->zErrMsg, "database schema has changed", (char*)0); + sqlite3ResetInternalSchema(db, pOp->p1); + sqlite3ExpirePreparedStatements(db); rc = SQLITE_SCHEMA; } break; @@ -2637,9 +2664,9 @@ case OP_OpenWrite: { /* no-push */ break; } -/* Opcode: OpenVirtual P1 P2 P3 +/* Opcode: OpenEphemeral P1 P2 P3 ** -** Open a new cursor P1 to a transient or virtual table. +** Open a new cursor P1 to a transient table. ** The cursor is always opened read/write even if ** the main database is read-only. The transient or virtual ** table is deleted automatically when the cursor is closed. @@ -2648,8 +2675,14 @@ case OP_OpenWrite: { /* no-push */ ** The cursor points to a BTree table if P3==0 and to a BTree index ** if P3 is not 0. If P3 is not NULL, it points to a KeyInfo structure ** that defines the format of keys in the index. +** +** This opcode was once called OpenTemp. But that created +** confusion because the term "temp table", might refer either +** to a TEMP table at the SQL level, or to a table opened by +** this opcode. Then this opcode was call OpenVirtual. But +** that created confusion with the whole virtual-table idea. */ -case OP_OpenVirtual: { /* no-push */ +case OP_OpenEphemeral: { /* no-push */ int i = pOp->p1; Cursor *pCx; assert( i>=0 ); @@ -2724,7 +2757,7 @@ case OP_OpenPseudo: { /* no-push */ case OP_Close: { /* no-push */ int i = pOp->p1; if( i>=0 && inCursor ){ - sqlite3VdbeFreeCursor(p->apCsr[i]); + sqlite3VdbeFreeCursor(p, p->apCsr[i]); p->apCsr[i] = 0; } break; @@ -2815,7 +2848,9 @@ case OP_MoveGt: { /* no-push */ pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; *pC->pIncrKey = 0; +#ifdef SQLITE_TEST sqlite3_search_count++; +#endif if( oc==OP_MoveGe || oc==OP_MoveGt ){ if( res<0 ){ rc = sqlite3BtreeNext(pC->pCursor, &res); @@ -2890,7 +2925,7 @@ case OP_MoveGt: { /* no-push */ ** ** The top of the stack holds a blob constructed by MakeRecord. P1 is ** an index. If no entry exists in P1 that matches the blob then jump -** to P1. If an entry does existing, fall through. The cursor is left +** to P2. If an entry does existing, fall through. The cursor is left ** pointing to the entry that matches. The blob is popped from the stack. ** ** The difference between this operation and Distinct is that @@ -2963,7 +2998,7 @@ case OP_IsUnique: { /* no-push */ R = pTos->i; assert( (pTos->flags & MEM_Dyn)==0 ); pTos--; - assert( i>=0 && i<=p->nCursor ); + assert( i>=0 && inCursor ); pCx = p->apCsr[i]; assert( pCx!=0 ); pCrsr = pCx->pCursor; @@ -3064,6 +3099,9 @@ case OP_NotExists: { /* no-push */ pC->rowidIsValid = res==0; pC->nullRow = 0; pC->cacheStatus = CACHE_STALE; + /* res might be uninitialized if rc!=SQLITE_OK. But if rc!=SQLITE_OK + ** processing is about to abort so we really do not care whether or not + ** the following jump is taken. */ if( res!=0 ){ pc = pOp->p2 - 1; pC->rowidIsValid = 0; @@ -3260,6 +3298,10 @@ case OP_NewRowid: { ** then rowid is stored for subsequent return by the ** sqlite3_last_insert_rowid() function (otherwise it's unmodified). ** +** Parameter P3 may point to a string containing the table-name, or +** may be NULL. If it is not NULL, then the update-hook +** (sqlite3.xUpdateCallback) is invoked following a successful insert. +** ** This instruction only works on tables. The equivalent instruction ** for indices is OP_IdxInsert. */ @@ -3569,8 +3611,10 @@ case OP_Last: { /* no-push */ ** correctly optimizing out sorts. */ case OP_Sort: { /* no-push */ +#ifdef SQLITE_TEST sqlite3_sort_count++; sqlite3_search_count--; +#endif /* Fall through into OP_Rewind */ } /* Opcode: Rewind P1 P2 * @@ -3643,7 +3687,9 @@ case OP_Next: { /* no-push */ } if( res==0 ){ pc = pOp->p2 - 1; +#ifdef SQLITE_TEST sqlite3_search_count++; +#endif } }else{ pC->nullRow = 1; @@ -3827,38 +3873,6 @@ case OP_IdxGE: { /* no-push */ break; } -/* Opcode: IdxIsNull P1 P2 * -** -** The top of the stack contains an index entry such as might be generated -** by the MakeIdxRec opcode. This routine looks at the first P1 fields of -** that key. If any of the first P1 fields are NULL, then a jump is made -** to address P2. Otherwise we fall straight through. -** -** The index entry is always popped from the stack. -*/ -case OP_IdxIsNull: { /* no-push */ - int i = pOp->p1; - int k, n; - const char *z; - u32 serial_type; - - assert( pTos>=p->aStack ); - assert( pTos->flags & MEM_Blob ); - z = pTos->z; - n = pTos->n; - k = sqlite3GetVarint32((u8*)z, &serial_type); - for(; k0; i--){ - k += sqlite3GetVarint32((u8*)&z[k], &serial_type); - if( serial_type==0 ){ /* Serial type 0 is a NULL */ - pc = pOp->p2-1; - break; - } - } - Release(pTos); - pTos--; - break; -} - /* Opcode: Destroy P1 P2 * ** ** Delete an entire database table or index whose root page in the database @@ -3881,19 +3895,31 @@ case OP_IdxIsNull: { /* no-push */ */ case OP_Destroy: { int iMoved; - if( db->activeVdbeCnt>1 ){ + int iCnt; +#ifndef SQLITE_OMIT_VIRTUALTABLE + Vdbe *pVdbe; + iCnt = 0; + for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){ + if( pVdbe->magic==VDBE_MAGIC_RUN && pVdbe->inVtabMethod<2 && pVdbe->pc>=0 ){ + iCnt++; + } + } +#else + iCnt = db->activeVdbeCnt; +#endif + if( iCnt>1 ){ rc = SQLITE_LOCKED; }else{ - assert( db->activeVdbeCnt==1 ); + assert( iCnt==1 ); rc = sqlite3BtreeDropTable(db->aDb[pOp->p2].pBt, pOp->p1, &iMoved); pTos++; pTos->flags = MEM_Int; pTos->i = iMoved; - #ifndef SQLITE_OMIT_AUTOVACUUM +#ifndef SQLITE_OMIT_AUTOVACUUM if( rc==SQLITE_OK && iMoved!=0 ){ sqlite3RootPageMoved(&db->aDb[pOp->p2], iMoved, pOp->p1); } - #endif +#endif } break; } @@ -3995,10 +4021,14 @@ case OP_CreateTable: { break; } -/* Opcode: ParseSchema P1 * P3 +/* Opcode: ParseSchema P1 P2 P3 ** ** Read and parse all entries from the SQLITE_MASTER table of database P1 -** that match the WHERE clause P3. +** that match the WHERE clause P3. P2 is the "force" flag. Always do +** the parsing if P2 is true. If P2 is false, then this routine is a +** no-op if the schema is not currently loaded. In other words, if P2 +** is false, the SQLITE_MASTER table is only parsed if the rest of the +** schema is already loaded into the symbol table. ** ** This opcode invokes the parser to create a new virtual machine, ** then runs the new virtual machine. It is thus a reentrant opcode. @@ -4010,19 +4040,23 @@ case OP_ParseSchema: { /* no-push */ InitData initData; assert( iDb>=0 && iDbnDb ); - if( !DbHasProperty(db, iDb, DB_SchemaLoaded) ) break; + if( !pOp->p2 && !DbHasProperty(db, iDb, DB_SchemaLoaded) ){ + break; + } zMaster = SCHEMA_TABLE(iDb); initData.db = db; + initData.iDb = pOp->p1; initData.pzErrMsg = &p->zErrMsg; zSql = sqlite3MPrintf( - "SELECT name, rootpage, sql, %d FROM '%q'.%s WHERE %s", - pOp->p1, db->aDb[iDb].zName, zMaster, pOp->p3); + "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s", + db->aDb[iDb].zName, zMaster, pOp->p3); if( zSql==0 ) goto no_mem; sqlite3SafetyOff(db); assert( db->init.busy==0 ); db->init.busy = 1; assert( !sqlite3MallocFailed() ); rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); + if( rc==SQLITE_ABORT ) rc = initData.rc; sqliteFree(zSql); db->init.busy = 0; sqlite3SafetyOn(db); @@ -4086,11 +4120,16 @@ case OP_DropTrigger: { /* no-push */ #ifndef SQLITE_OMIT_INTEGRITY_CHECK -/* Opcode: IntegrityCk * P2 * +/* Opcode: IntegrityCk P1 P2 * ** ** Do an analysis of the currently open database. Push onto the ** stack the text of an error message describing any problems. -** If there are no errors, push a "ok" onto the stack. +** If no problems are found, push a NULL onto the stack. +** +** P1 is the address of a memory cell that contains the maximum +** number of allowed errors. At most mem[P1] errors will be reported. +** In other words, the analysis stops as soon as mem[P1] errors are +** seen. Mem[P1] is updated with the number of errors remaining. ** ** The root page numbers of all tables in the database are integer ** values on the stack. This opcode pulls as many integers as it @@ -4099,13 +4138,15 @@ case OP_DropTrigger: { /* no-push */ ** If P2 is not zero, the check is done on the auxiliary database ** file, not the main database file. ** -** This opcode is used for testing purposes only. +** This opcode is used to implement the integrity_check pragma. */ case OP_IntegrityCk: { int nRoot; int *aRoot; int j; + int nErr; char *z; + Mem *pnErr; for(nRoot=0; &pTos[-nRoot]>=p->aStack; nRoot++){ if( (pTos[-nRoot].flags & MEM_Int)==0 ) break; @@ -4113,6 +4154,10 @@ case OP_IntegrityCk: { assert( nRoot>0 ); aRoot = sqliteMallocRaw( sizeof(int*)*(nRoot+1) ); if( aRoot==0 ) goto no_mem; + j = pOp->p1; + assert( j>=0 && jnMem ); + pnErr = &p->aMem[j]; + assert( (pnErr->flags & MEM_Int)!=0 ); for(j=0; ji; @@ -4120,12 +4165,12 @@ case OP_IntegrityCk: { aRoot[j] = 0; popStack(&pTos, nRoot); pTos++; - z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p2].pBt, aRoot, nRoot); - if( z==0 || z[0]==0 ){ - if( z ) sqliteFree(z); - pTos->z = "ok"; - pTos->n = 2; - pTos->flags = MEM_Str | MEM_Static | MEM_Term; + z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p2].pBt, aRoot, nRoot, + (int)pnErr->i, &nErr); + pnErr->i -= nErr; + if( nErr==0 ){ + assert( z==0 ); + pTos->flags = MEM_Null; }else{ pTos->z = z; pTos->n = strlen(z); @@ -4461,6 +4506,7 @@ case OP_AggFinal: { /* no-push */ } +#ifndef SQLITE_OMIT_VACUUM /* Opcode: Vacuum * * * ** ** Vacuum the entire database. This opcode will cause other virtual @@ -4473,6 +4519,7 @@ case OP_Vacuum: { /* no-push */ if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; break; } +#endif /* Opcode: Expire P1 * * ** @@ -4522,7 +4569,316 @@ case OP_TableLock: { /* no-push */ } break; } -#endif /* SHARED_OMIT_SHARED_CACHE */ +#endif /* SQLITE_OMIT_SHARED_CACHE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VBegin * * P3 +** +** P3 a pointer to an sqlite3_vtab structure. Call the xBegin method +** for that table. +*/ +case OP_VBegin: { /* no-push */ + rc = sqlite3VtabBegin(db, (sqlite3_vtab *)pOp->p3); + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VCreate P1 * P3 +** +** P3 is the name of a virtual table in database P1. Call the xCreate method +** for that table. +*/ +case OP_VCreate: { /* no-push */ + rc = sqlite3VtabCallCreate(db, pOp->p1, pOp->p3, &p->zErrMsg); + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VDestroy P1 * P3 +** +** P3 is the name of a virtual table in database P1. Call the xDestroy method +** of that table. +*/ +case OP_VDestroy: { /* no-push */ + p->inVtabMethod = 2; + rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p3); + p->inVtabMethod = 0; + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VOpen P1 * P3 +** +** P3 is a pointer to a virtual table object, an sqlite3_vtab structure. +** P1 is a cursor number. This opcode opens a cursor to the virtual +** table and stores that cursor in P1. +*/ +case OP_VOpen: { /* no-push */ + Cursor *pCur = 0; + sqlite3_vtab_cursor *pVtabCursor = 0; + + sqlite3_vtab *pVtab = (sqlite3_vtab *)(pOp->p3); + sqlite3_module *pModule = (sqlite3_module *)pVtab->pModule; + + assert(pVtab && pModule); + if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; + rc = pModule->xOpen(pVtab, &pVtabCursor); + if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; + if( SQLITE_OK==rc ){ + /* Initialise sqlite3_vtab_cursor base class */ + pVtabCursor->pVtab = pVtab; + + /* Initialise vdbe cursor object */ + pCur = allocateCursor(p, pOp->p1, -1); + if( pCur ){ + pCur->pVtabCursor = pVtabCursor; + pCur->pModule = pVtabCursor->pVtab->pModule; + }else{ + pModule->xClose(pVtabCursor); + } + } + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VFilter P1 P2 P3 +** +** P1 is a cursor opened using VOpen. P2 is an address to jump to if +** the filtered result set is empty. +** +** P3 is either NULL or a string that was generated by the xBestIndex +** method of the module. The interpretation of the P3 string is left +** to the module implementation. +** +** This opcode invokes the xFilter method on the virtual table specified +** by P1. The integer query plan parameter to xFilter is the top of the +** stack. Next down on the stack is the argc parameter. Beneath the +** next of stack are argc additional parameters which are passed to +** xFilter as argv. The topmost parameter (i.e. 3rd element popped from +** the stack) becomes argv[argc-1] when passed to xFilter. +** +** The integer query plan parameter, argc, and all argv stack values +** are popped from the stack before this instruction completes. +** +** A jump is made to P2 if the result set after filtering would be +** empty. +*/ +case OP_VFilter: { /* no-push */ + int nArg; + + const sqlite3_module *pModule; + + Cursor *pCur = p->apCsr[pOp->p1]; + assert( pCur->pVtabCursor ); + pModule = pCur->pVtabCursor->pVtab->pModule; + + /* Grab the index number and argc parameters off the top of the stack. */ + assert( (&pTos[-1])>=p->aStack ); + assert( (pTos[0].flags&MEM_Int)!=0 && pTos[-1].flags==MEM_Int ); + nArg = (int)pTos[-1].i; + + /* Invoke the xFilter method */ + { + int res = 0; + int i; + Mem **apArg = p->apArg; + for(i = 0; iinVtabMethod = 1; + rc = pModule->xFilter(pCur->pVtabCursor, (int)pTos->i, pOp->p3, nArg, apArg); + p->inVtabMethod = 0; + if( rc==SQLITE_OK ){ + res = pModule->xEof(pCur->pVtabCursor); + } + if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; + + if( res ){ + pc = pOp->p2 - 1; + } + } + + /* Pop the index number, argc value and parameters off the stack */ + popStack(&pTos, 2+nArg); + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VRowid P1 * * +** +** Push an integer onto the stack which is the rowid of +** the virtual-table that the P1 cursor is pointing to. +*/ +case OP_VRowid: { + const sqlite3_module *pModule; + + Cursor *pCur = p->apCsr[pOp->p1]; + assert( pCur->pVtabCursor ); + pModule = pCur->pVtabCursor->pVtab->pModule; + if( pModule->xRowid==0 ){ + sqlite3SetString(&p->zErrMsg, "Unsupported module operation: xRowid", 0); + rc = SQLITE_ERROR; + } else { + sqlite_int64 iRow; + + if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; + rc = pModule->xRowid(pCur->pVtabCursor, &iRow); + if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; + + pTos++; + pTos->flags = MEM_Int; + pTos->i = iRow; + } + + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VColumn P1 P2 * +** +** Push onto the stack the value of the P2-th column of +** the row of the virtual-table that the P1 cursor is pointing to. +*/ +case OP_VColumn: { + const sqlite3_module *pModule; + + Cursor *pCur = p->apCsr[pOp->p1]; + assert( pCur->pVtabCursor ); + pModule = pCur->pVtabCursor->pVtab->pModule; + if( pModule->xColumn==0 ){ + sqlite3SetString(&p->zErrMsg, "Unsupported module operation: xColumn", 0); + rc = SQLITE_ERROR; + } else { + sqlite3_context sContext; + memset(&sContext, 0, sizeof(sContext)); + sContext.s.flags = MEM_Null; + if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; + rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2); + + /* Copy the result of the function to the top of the stack. We + ** do this regardless of whether or not an error occured to ensure any + ** dynamic allocation in sContext.s (a Mem struct) is released. + */ + sqlite3VdbeChangeEncoding(&sContext.s, encoding); + pTos++; + pTos->flags = 0; + sqlite3VdbeMemMove(pTos, &sContext.s); + + if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; + } + + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VNext P1 P2 * +** +** Advance virtual table P1 to the next row in its result set and +** jump to instruction P2. Or, if the virtual table has reached +** the end of its result set, then fall through to the next instruction. +*/ +case OP_VNext: { /* no-push */ + const sqlite3_module *pModule; + int res = 0; + + Cursor *pCur = p->apCsr[pOp->p1]; + assert( pCur->pVtabCursor ); + pModule = pCur->pVtabCursor->pVtab->pModule; + if( pModule->xNext==0 ){ + sqlite3SetString(&p->zErrMsg, "Unsupported module operation: xNext", 0); + rc = SQLITE_ERROR; + } else { + /* Invoke the xNext() method of the module. There is no way for the + ** underlying implementation to return an error if one occurs during + ** xNext(). Instead, if an error occurs, true is returned (indicating that + ** data is available) and the error code returned when xColumn or + ** some other method is next invoked on the save virtual table cursor. + */ + if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; + p->inVtabMethod = 1; + rc = pModule->xNext(pCur->pVtabCursor); + p->inVtabMethod = 0; + if( rc==SQLITE_OK ){ + res = pModule->xEof(pCur->pVtabCursor); + } + if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; + + if( !res ){ + /* If there is data, jump to P2 */ + pc = pOp->p2 - 1; + } + } + + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VUpdate P1 P2 P3 +** +** P3 is a pointer to a virtual table object, an sqlite3_vtab structure. +** This opcode invokes the corresponding xUpdate method. P2 values +** are taken from the stack to pass to the xUpdate invocation. The +** value on the top of the stack corresponds to the p2th element +** of the argv array passed to xUpdate. +** +** The xUpdate method will do a DELETE or an INSERT or both. +** The argv[0] element (which corresponds to the P2-th element down +** on the stack) is the rowid of a row to delete. If argv[0] is +** NULL then no deletion occurs. The argv[1] element is the rowid +** of the new row. This can be NULL to have the virtual table +** select the new rowid for itself. The higher elements in the +** stack are the values of columns in the new row. +** +** If P2==1 then no insert is performed. argv[0] is the rowid of +** a row to delete. +** +** P1 is a boolean flag. If it is set to true and the xUpdate call +** is successful, then the value returned by sqlite3_last_insert_rowid() +** is set to the value of the rowid for the row just inserted. +*/ +case OP_VUpdate: { /* no-push */ + sqlite3_vtab *pVtab = (sqlite3_vtab *)(pOp->p3); + sqlite3_module *pModule = (sqlite3_module *)pVtab->pModule; + int nArg = pOp->p2; + assert( pOp->p3type==P3_VTAB ); + if( pModule->xUpdate==0 ){ + sqlite3SetString(&p->zErrMsg, "read-only table", 0); + rc = SQLITE_ERROR; + }else{ + int i; + sqlite_int64 rowid; + Mem **apArg = p->apArg; + Mem *pX = &pTos[1-nArg]; + for(i = 0; ixUpdate(pVtab, nArg, apArg, &rowid); + sqlite3VtabUnlock(pVtab); + if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; + if( pOp->p1 && rc==SQLITE_OK ){ + assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) ); + db->lastRowid = rowid; + } + } + popStack(&pTos, nArg); + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ /* An other opcode is illegal... */ @@ -4560,8 +4916,12 @@ default: { ** the evaluator loop. So we can leave it out when NDEBUG is defined. */ #ifndef NDEBUG - /* Sanity checking on the top element of the stack */ - if( pTos>=p->aStack ){ + /* Sanity checking on the top element of the stack. If the previous + ** instruction was VNoChange, then the flags field of the top + ** of the stack is set to 0. This is technically invalid for a memory + ** cell, so avoid calling MemSanity() in this case. + */ + if( pTos>=p->aStack && pTos->flags ){ sqlite3VdbeMemSanity(pTos); } assert( pc>=-1 && pcnOp ); @@ -4634,8 +4994,7 @@ abort_due_to_error: ** flag. */ abort_due_to_interrupt: - assert( db->flags & SQLITE_Interrupt ); - db->flags &= ~SQLITE_Interrupt; + assert( db->u1.isInterrupted ); if( db->magic!=SQLITE_MAGIC_BUSY ){ rc = SQLITE_MISUSE; }else{ diff --git a/dlls/sqlite/sqlite-source/vdbe.h b/dlls/sqlite/sqlite-source/vdbe.h index 11f8aff5..385a60bd 100644 --- a/dlls/sqlite/sqlite-source/vdbe.h +++ b/dlls/sqlite/sqlite-source/vdbe.h @@ -69,7 +69,9 @@ typedef struct VdbeOpList VdbeOpList; #define P3_KEYINFO (-6) /* P3 is a pointer to a KeyInfo structure */ #define P3_VDBEFUNC (-7) /* P3 is a pointer to a VdbeFunc structure */ #define P3_MEM (-8) /* P3 is a pointer to a Mem* structure */ -#define P3_TRANSIENT (-9) /* P3 is a pointer to a transient string */ +#define P3_TRANSIENT (-9) /* P3 is a pointer to a transient string */ +#define P3_VTAB (-10) /* P3 is a pointer to an sqlite3_vtab structure */ +#define P3_MPRINTF (-11) /* P3 is a string obtained from sqlite3_mprintf() */ /* When adding a P3 argument using P3_KEYINFO, a copy of the KeyInfo structure ** is made. That copy is freed when the Vdbe is finalized. But if the @@ -127,12 +129,16 @@ int sqlite3VdbeFinalize(Vdbe*); void sqlite3VdbeResolveLabel(Vdbe*, int); int sqlite3VdbeCurrentAddr(Vdbe*); void sqlite3VdbeTrace(Vdbe*,FILE*); +void sqlite3VdbeResetStepResult(Vdbe*); int sqlite3VdbeReset(Vdbe*); int sqliteVdbeSetVariables(Vdbe*,int,const char**); void sqlite3VdbeSetNumCols(Vdbe*,int); int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, int); void sqlite3VdbeCountChanges(Vdbe*); sqlite3 *sqlite3VdbeDb(Vdbe*); +void sqlite3VdbeSetSql(Vdbe*, const char *z, int n); +const char *sqlite3VdbeGetSql(Vdbe*); +void sqlite3VdbeSwap(Vdbe*,Vdbe*); #ifndef NDEBUG void sqlite3VdbeComment(Vdbe*, const char*, ...); diff --git a/dlls/sqlite/sqlite-source/vdbeInt.h b/dlls/sqlite/sqlite-source/vdbeInt.h index 01d6a61f..d2f737c9 100644 --- a/dlls/sqlite/sqlite-source/vdbeInt.h +++ b/dlls/sqlite/sqlite-source/vdbeInt.h @@ -15,6 +15,8 @@ ** 6000 lines long) it was split up into several smaller files and ** this header information was factored out. */ +#ifndef _VDBEINT_H_ +#define _VDBEINT_H_ /* ** intToKey() and keyToInt() used to transform the rowid. But with @@ -83,6 +85,8 @@ struct Cursor { KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ int nField; /* Number of fields in the header */ i64 seqCount; /* Sequence counter */ + sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ + const sqlite3_module *pModule; /* Module for cursor pVtabCursor */ /* Cached information about the header for the data record that the ** cursor is currently pointing to. Only valid if cacheValid is true. @@ -268,6 +272,14 @@ struct Context { ** ** The "sqlite3_stmt" structure pointer that is returned by sqlite3_compile() ** is really a pointer to an instance of this structure. +** +** The Vdbe.inVtabMethod variable is set to non-zero for the duration of +** any virtual table method invocations made by the vdbe program. It is +** set to 2 for xDestroy method calls and 1 for all other methods. This +** variable is used for two purposes: to allow xDestroy methods to execute +** "DROP TABLE" statements and to prevent some nasty side effects of +** malloc failure when SQLite is invoked recursively by a virtual table +** method function. */ struct Vdbe { sqlite3 *db; /* The whole database */ @@ -315,8 +327,11 @@ struct Vdbe { u8 aborted; /* True if ROLLBACK in another VM causes an abort */ u8 expired; /* True if the VM needs to be recompiled */ u8 minWriteFileFormat; /* Minimum file format for writable database files */ + u8 inVtabMethod; /* See comments above */ int nChange; /* Number of db changes made since last reset */ i64 startTime; /* Time when query started - used for profiling */ + int nSql; /* Number of bytes in zSql */ + char *zSql; /* Text of the SQL statement that generated this */ #ifdef SQLITE_SSE int fetchId; /* Statement number used by sqlite3_fetch_statement */ int lru; /* Counter used for LRU cache replacement */ @@ -334,7 +349,7 @@ struct Vdbe { /* ** Function prototypes */ -void sqlite3VdbeFreeCursor(Cursor*); +void sqlite3VdbeFreeCursor(Vdbe *, Cursor*); void sqliteVdbePopStack(Vdbe*,int); int sqlite3VdbeCursorMoveto(Cursor*); #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) @@ -390,3 +405,5 @@ void sqlite3VdbeFifoInit(Fifo*); int sqlite3VdbeFifoPush(Fifo*, i64); int sqlite3VdbeFifoPop(Fifo*, i64*); void sqlite3VdbeFifoClear(Fifo*); + +#endif /* !defined(_VDBEINT_H_) */ diff --git a/dlls/sqlite/sqlite-source/vdbeapi.c b/dlls/sqlite/sqlite-source/vdbeapi.c index f25cdcee..b01f5c46 100644 --- a/dlls/sqlite/sqlite-source/vdbeapi.c +++ b/dlls/sqlite/sqlite-source/vdbeapi.c @@ -153,9 +153,13 @@ void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){ /* ** Execute the statement pStmt, either until a row of data is ready, the ** statement is completely executed or an error occurs. +** +** This routine implements the bulk of the logic behind the sqlite_step() +** API. The only thing omitted is the automatic recompile if a +** schema change has occurred. That detail is handled by the +** outer sqlite3_step() wrapper procedure. */ -int sqlite3_step(sqlite3_stmt *pStmt){ - Vdbe *p = (Vdbe*)pStmt; +static int sqlite3Step(Vdbe *p){ sqlite3 *db; int rc; @@ -172,7 +176,8 @@ int sqlite3_step(sqlite3_stmt *pStmt){ if( p->rc==SQLITE_OK ){ p->rc = SQLITE_SCHEMA; } - return SQLITE_ERROR; + rc = SQLITE_ERROR; + goto end_of_step; } db = p->db; if( sqlite3SafetyOn(db) ){ @@ -180,6 +185,14 @@ int sqlite3_step(sqlite3_stmt *pStmt){ return SQLITE_MISUSE; } if( p->pc<0 ){ + /* If there are no other statements currently running, then + ** reset the interrupt flag. This prevents a call to sqlite3_interrupt + ** from interrupting a statement that has not yet started. + */ + if( db->activeVdbeCnt==0 ){ + db->u1.isInterrupted = 0; + } + #ifndef SQLITE_OMIT_TRACE /* Invoke the trace callback if there is one */ @@ -198,7 +211,7 @@ int sqlite3_step(sqlite3_stmt *pStmt){ if( db->xProfile && !db->init.busy ){ double rNow; sqlite3OsCurrentTime(&rNow); - p->startTime = (int)((rNow - (int)rNow)*3600.0*24.0*1000000000.0); + p->startTime = (i64)((rNow - (int)rNow)*3600.0*24.0*1000000000.0); } #endif @@ -246,8 +259,42 @@ int sqlite3_step(sqlite3_stmt *pStmt){ sqlite3Error(p->db, rc, 0); p->rc = sqlite3ApiExit(p->db, p->rc); +end_of_step: + assert( (rc&0xff)==rc ); + if( p->zSql && (rc&0xff)rc; + }else{ + /* This is for legacy sqlite3_prepare() builds and when the code + ** is SQLITE_ROW or SQLITE_DONE */ + return rc; + } +} + +/* +** This is the top-level implementation of sqlite3_step(). Call +** sqlite3Step() to do most of the work. If a schema error occurs, +** call sqlite3Reprepare() and try again. +*/ +#ifdef SQLITE_OMIT_PARSER +int sqlite3_step(sqlite3_stmt *pStmt){ + return sqlite3Step((Vdbe*)pStmt); +} +#else +int sqlite3_step(sqlite3_stmt *pStmt){ + int cnt = 0; + int rc; + Vdbe *v = (Vdbe*)pStmt; + while( (rc = sqlite3Step(v))==SQLITE_SCHEMA + && cnt++ < 5 + && sqlite3Reprepare(v) ){ + sqlite3_reset(pStmt); + v->expired = 0; + } return rc; } +#endif /* ** Extract the user data from a sqlite3_context structure and return a @@ -258,6 +305,27 @@ void *sqlite3_user_data(sqlite3_context *p){ return p->pFunc->pUserData; } +/* +** The following is the implementation of an SQL function that always +** fails with an error message stating that the function is used in the +** wrong context. The sqlite3_overload_function() API might construct +** SQL function that use this routine so that the functions will exist +** for name resolution but are actually overloaded by the xFindFunction +** method of virtual tables. +*/ +void sqlite3InvalidFunction( + sqlite3_context *context, /* The function calling context */ + int argc, /* Number of arguments to the function */ + sqlite3_value **argv /* Value of each argument */ +){ + const char *zName = context->pFunc->zName; + char *zErr; + zErr = sqlite3MPrintf( + "unable to use function %s in the requested context", zName); + sqlite3_result_error(context, zErr, -1); + sqliteFree(zErr); +} + /* ** Allocate or return the aggregate context for a user function. A new ** context is allocated on the first call. Subsequent calls return the @@ -375,10 +443,9 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){ Vdbe *pVm = (Vdbe *)pStmt; int vals = sqlite3_data_count(pStmt); if( i>=vals || i<0 ){ - static Mem nullMem; - if( nullMem.flags==0 ){ nullMem.flags = MEM_Null; } + static const Mem nullMem = {0, 0.0, "", 0, MEM_Null, MEM_Null }; sqlite3Error(pVm->db, SQLITE_RANGE, 0); - return &nullMem; + return (Mem*)&nullMem; } return &pVm->pTos[(1-vals)+i]; } @@ -454,11 +521,9 @@ const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){ columnMallocFailure(pStmt); return val; } -#if 0 sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){ return columnMem(pStmt, i); } -#endif #ifndef SQLITE_OMIT_UTF16 const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){ const void *val = sqlite3_value_text16( columnMem(pStmt,i) ); @@ -713,6 +778,15 @@ int sqlite3_bind_text16( return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE); } #endif /* SQLITE_OMIT_UTF16 */ +int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){ + int rc; + Vdbe *p = (Vdbe *)pStmt; + rc = vdbeUnbind(p, i); + if( rc==SQLITE_OK ){ + sqlite3VdbeMemCopy(&p->aVar[i-1], pValue); + } + return rc; +} /* ** Return the number of wildcards that can be potentially bound to. @@ -801,6 +875,7 @@ int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){ rc = sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]); sqlite3MallocAllow(); } + assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); return rc; } diff --git a/dlls/sqlite/sqlite-source/vdbeaux.c b/dlls/sqlite/sqlite-source/vdbeaux.c index f96a280c..2ebcd84e 100644 --- a/dlls/sqlite/sqlite-source/vdbeaux.c +++ b/dlls/sqlite/sqlite-source/vdbeaux.c @@ -48,6 +48,46 @@ Vdbe *sqlite3VdbeCreate(sqlite3 *db){ return p; } +/* +** Remember the SQL string for a prepared statement. +*/ +void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n){ + if( p==0 ) return; + assert( p->zSql==0 ); + p->zSql = sqlite3StrNDup(z, n); +} + +/* +** Return the SQL associated with a prepared statement +*/ +const char *sqlite3VdbeGetSql(Vdbe *p){ + return p->zSql; +} + +/* +** Swap all content between two VDBE structures. +*/ +void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){ + Vdbe tmp, *pTmp; + char *zTmp; + int nTmp; + tmp = *pA; + *pA = *pB; + *pB = tmp; + pTmp = pA->pNext; + pA->pNext = pB->pNext; + pB->pNext = pTmp; + pTmp = pA->pPrev; + pA->pPrev = pB->pPrev; + pB->pPrev = pTmp; + zTmp = pA->zSql; + pA->zSql = pB->zSql; + pB->zSql = zTmp; + nTmp = pA->nSql; + pA->nSql = pB->nSql; + pB->nSql = nTmp; +} + /* ** Turn tracing on or off */ @@ -228,7 +268,7 @@ int sqlite3VdbeOpcodeNoPush(u8 op){ ** This routine is called once after all opcodes have been inserted. ** ** Variable *pMaxFuncArgs is set to the maximum value of any P2 argument -** to an OP_Function or OP_AggStep opcode. This is used by +** to an OP_Function, OP_AggStep or OP_VFilter opcode. This is used by ** sqlite3VdbeMakeReady() to size the Vdbe.apArg[] array. ** ** The integer *pMaxStack is set to the maximum number of vdbe stack @@ -251,20 +291,25 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs, int *pMaxStack){ for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){ u8 opcode = pOp->opcode; - if( opcode==OP_Function || opcode==OP_AggStep ){ + if( opcode==OP_Function || opcode==OP_AggStep +#ifndef SQLITE_OMIT_VIRTUALTABLE + || opcode==OP_VUpdate +#endif + ){ if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; }else if( opcode==OP_Halt ){ if( pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort ){ doesStatementRollback = 1; } - }else if( opcode==OP_IdxInsert ){ - if( pOp->p2 ){ - doesStatementRollback = 1; - } }else if( opcode==OP_Statement ){ hasStatementBegin = 1; + }else if( opcode==OP_VFilter ){ + int n; + assert( p->nOp - i >= 3 ); + assert( pOp[-2].opcode==OP_Integer ); + n = pOp[-2].p1; + if( n>nMaxArgs ) nMaxArgs = n; } - if( opcodeNoPush(opcode) ){ nMaxStack--; } @@ -368,6 +413,17 @@ void sqlite3VdbeJumpHere(Vdbe *p, int addr){ sqlite3VdbeChangeP2(p, addr, p->nOp); } + +/* +** If the input FuncDef structure is ephemeral, then free it. If +** the FuncDef is not ephermal, then do nothing. +*/ +static void freeEphemeralFunction(FuncDef *pDef){ + if( pDef && (pDef->flags & SQLITE_FUNC_EPHEM)!=0 ){ + sqliteFree(pDef); + } +} + /* ** Delete a P3 value if necessary. */ @@ -380,12 +436,21 @@ static void freeP3(int p3type, void *p3){ sqliteFree(p3); break; } + case P3_MPRINTF: { + sqlite3_free(p3); + break; + } case P3_VDBEFUNC: { VdbeFunc *pVdbeFunc = (VdbeFunc *)p3; + freeEphemeralFunction(pVdbeFunc->pFunc); sqlite3VdbeDeleteAuxData(pVdbeFunc, 0); sqliteFree(pVdbeFunc); break; } + case P3_FUNCDEF: { + freeEphemeralFunction((FuncDef*)p3); + break; + } case P3_MEM: { sqlite3ValueFree((sqlite3_value*)p3); break; @@ -558,15 +623,18 @@ static char *displayP3(Op *pOp, char *zTemp, int nTemp){ } case P3_FUNCDEF: { FuncDef *pDef = (FuncDef*)pOp->p3; - char zNum[30]; - sprintf(zTemp, "%.*s", nTemp, pDef->zName); - sprintf(zNum,"(%d)", pDef->nArg); - if( strlen(zTemp)+strlen(zNum)+1<=(size_t)nTemp ){ - strcat(zTemp, zNum); - } + sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg); zP3 = zTemp; break; } +#ifndef SQLITE_OMIT_VIRTUALTABLE + case P3_VTAB: { + sqlite3_vtab *pVtab = (sqlite3_vtab*)pOp->p3; + sqlite3_snprintf(nTemp, zTemp, "vtab:%p:%p", pVtab, pVtab->pModule); + zP3 = zTemp; + break; + } +#endif default: { zP3 = pOp->p3; if( zP3==0 || pOp->opcode==OP_Noop ){ @@ -574,6 +642,7 @@ static char *displayP3(Op *pOp, char *zTemp, int nTemp){ } } } + assert( zP3!=0 ); return zP3; } #endif @@ -641,8 +710,7 @@ int sqlite3VdbeList( if( i>=p->nOp ){ p->rc = SQLITE_OK; rc = SQLITE_DONE; - }else if( db->flags & SQLITE_Interrupt ){ - db->flags &= ~SQLITE_Interrupt; + }else if( db->u1.isInterrupted ){ p->rc = SQLITE_INTERRUPT; rc = SQLITE_ERROR; sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(p->rc), (char*)0); @@ -656,6 +724,7 @@ int sqlite3VdbeList( pMem->flags = MEM_Static|MEM_Str|MEM_Term; pMem->z = sqlite3OpcodeNames[pOp->opcode]; /* Opcode */ + assert( pMem->z!=0 ); pMem->n = strlen(pMem->z); pMem->type = SQLITE_TEXT; pMem->enc = SQLITE_UTF8; @@ -673,6 +742,7 @@ int sqlite3VdbeList( pMem->flags = MEM_Ephem|MEM_Str|MEM_Term; /* P3 */ pMem->z = displayP3(pOp, pMem->zShort, sizeof(pMem->zShort)); + assert( pMem->z!=0 ); pMem->n = strlen(pMem->z); pMem->type = SQLITE_TEXT; pMem->enc = SQLITE_UTF8; @@ -752,7 +822,9 @@ void sqlite3VdbeMakeReady( resizeOpArray(p, p->nOp); assert( nVar>=0 ); assert( nStacknOp ); - nStack = isExplain ? 10 : nStack; + if( isExplain ){ + nStack = 10; + } p->aStack = sqliteMalloc( nStack*sizeof(p->aStack[0]) /* aStack */ + nArg*sizeof(Mem*) /* apArg */ @@ -780,21 +852,6 @@ void sqlite3VdbeMakeReady( p->aMem[n].flags = MEM_Null; } -#ifdef SQLITE_DEBUG - if( (p->db->flags & SQLITE_VdbeListing)!=0 - || sqlite3OsFileExists("vdbe_explain") - ){ - int i; - printf("VDBE Program Listing:\n"); - sqlite3VdbePrintSql(p); - for(i=0; inOp; i++){ - sqlite3VdbePrintOp(stdout, i, &p->aOp[i]); - } - } - if( sqlite3OsFileExists("vdbe_trace") ){ - p->trace = stdout; - } -#endif p->pTos = &p->aStack[-1]; p->pc = -1; p->rc = SQLITE_OK; @@ -822,7 +879,7 @@ void sqlite3VdbeMakeReady( ** Close a cursor and release all the resources that cursor happens ** to hold. */ -void sqlite3VdbeFreeCursor(Cursor *pCx){ +void sqlite3VdbeFreeCursor(Vdbe *p, Cursor *pCx){ if( pCx==0 ){ return; } @@ -832,6 +889,17 @@ void sqlite3VdbeFreeCursor(Cursor *pCx){ if( pCx->pBt ){ sqlite3BtreeClose(pCx->pBt); } +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( pCx->pVtabCursor ){ + sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor; + const sqlite3_module *pModule = pCx->pModule; + p->inVtabMethod = 1; + sqlite3SafetyOff(p->db); + pModule->xClose(pVtabCursor); + sqlite3SafetyOn(p->db); + p->inVtabMethod = 0; + } +#endif sqliteFree(pCx->pData); sqliteFree(pCx->aType); sqliteFree(pCx); @@ -844,8 +912,10 @@ static void closeAllCursors(Vdbe *p){ int i; if( p->apCsr==0 ) return; for(i=0; inCursor; i++){ - sqlite3VdbeFreeCursor(p->apCsr[i]); - p->apCsr[i] = 0; + if( !p->inVtabMethod || (p->apCsr[i] && !p->apCsr[i]->pVtabCursor) ){ + sqlite3VdbeFreeCursor(p, p->apCsr[i]); + p->apCsr[i] = 0; + } } } @@ -941,6 +1011,23 @@ static int vdbeCommit(sqlite3 *db){ int rc = SQLITE_OK; int needXcommit = 0; + /* Before doing anything else, call the xSync() callback for any + ** virtual module tables written in this transaction. This has to + ** be done before determining whether a master journal file is + ** required, as an xSync() callback may add an attached database + ** to the transaction. + */ + rc = sqlite3VtabSync(db, rc); + if( rc!=SQLITE_OK ){ + return rc; + } + + /* This loop determines (a) if the commit hook should be invoked and + ** (b) how many database files have open write transactions, not + ** including the temp database. (b) is important because if more than + ** one database file has an open write transaction, a master journal + ** file is required for an atomic commit. + */ for(i=0; inDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt && sqlite3BtreeIsInTrans(pBt) ){ @@ -984,6 +1071,7 @@ static int vdbeCommit(sqlite3 *db){ sqlite3BtreeCommit(pBt); } } + sqlite3VtabCommit(db); } } @@ -1065,25 +1153,26 @@ static int vdbeCommit(sqlite3 *db){ ** file name was written into the journal file before the failure ** occured. */ - for(i=0; inDb; i++){ + for(i=0; rc==SQLITE_OK && inDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt && sqlite3BtreeIsInTrans(pBt) ){ rc = sqlite3BtreeSync(pBt, zMaster); - if( rc!=SQLITE_OK ){ - sqlite3OsClose(&master); - sqliteFree(zMaster); - return rc; - } } } sqlite3OsClose(&master); + if( rc!=SQLITE_OK ){ + sqliteFree(zMaster); + return rc; + } /* Delete the master journal file. This commits the transaction. After ** doing this the directory is synced again before any individual ** transaction files are deleted. */ rc = sqlite3OsDelete(zMaster); - assert( rc==SQLITE_OK ); + if( rc ){ + return rc; + } sqliteFree(zMaster); zMaster = 0; rc = sqlite3OsSyncDirectory(zMainFile); @@ -1111,29 +1200,13 @@ static int vdbeCommit(sqlite3 *db){ sqlite3BtreeCommit(pBt); } } + sqlite3VtabCommit(db); } #endif return rc; } -/* -** Find every active VM other than pVdbe and change its status to -** aborted. This happens when one VM causes a rollback due to an -** ON CONFLICT ROLLBACK clause (for example). The other VMs must be -** aborted so that they do not have data rolled out from underneath -** them leading to a segfault. -*/ -void sqlite3AbortOtherActiveVdbes(sqlite3 *db, Vdbe *pExcept){ - Vdbe *pOther; - for(pOther=db->pVdbe; pOther; pOther=pOther->pNext){ - if( pOther==pExcept ) continue; - if( pOther->magic!=VDBE_MAGIC_RUN || pOther->pc<0 ) continue; - closeAllCursors(pOther); - pOther->aborted = 1; - } -} - /* ** This routine checks that the sqlite3.activeVdbeCnt count variable ** matches the number of vdbe's in the list sqlite3.pVdbe that are @@ -1160,6 +1233,25 @@ static void checkActiveVdbeCnt(sqlite3 *db){ #define checkActiveVdbeCnt(x) #endif +/* +** Find every active VM other than pVdbe and change its status to +** aborted. This happens when one VM causes a rollback due to an +** ON CONFLICT ROLLBACK clause (for example). The other VMs must be +** aborted so that they do not have data rolled out from underneath +** them leading to a segfault. +*/ +void sqlite3AbortOtherActiveVdbes(sqlite3 *db, Vdbe *pExcept){ + Vdbe *pOther; + for(pOther=db->pVdbe; pOther; pOther=pOther->pNext){ + if( pOther==pExcept ) continue; + if( pOther->magic!=VDBE_MAGIC_RUN || pOther->pc<0 ) continue; + checkActiveVdbeCnt(db); + closeAllCursors(pOther); + checkActiveVdbeCnt(db); + pOther->aborted = 1; + } +} + /* ** This routine is called the when a VDBE tries to halt. If the VDBE ** has made changes and is in autocommit mode, then commit those @@ -1212,6 +1304,9 @@ int sqlite3VdbeHalt(Vdbe *p){ if( p->magic!=VDBE_MAGIC_RUN ){ /* Already halted. Nothing to do. */ assert( p->magic==VDBE_MAGIC_HALT ); +#ifndef SQLITE_OMIT_VIRTUALTABLE + closeAllCursors(p); +#endif return SQLITE_OK; } closeAllCursors(p); @@ -1219,9 +1314,10 @@ int sqlite3VdbeHalt(Vdbe *p){ /* No commit or rollback needed if the program never started */ if( p->pc>=0 ){ - + int mrc; /* Primary error code from p->rc */ /* Check for one of the special errors - SQLITE_NOMEM or SQLITE_IOERR */ - isSpecialError = ((p->rc==SQLITE_NOMEM || p->rc==SQLITE_IOERR)?1:0); + mrc = p->rc & 0xff; + isSpecialError = ((mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR)?1:0); if( isSpecialError ){ /* This loop does static analysis of the query to see which of the ** following three categories it falls into: @@ -1353,6 +1449,14 @@ int sqlite3VdbeHalt(Vdbe *p){ return SQLITE_OK; } +/* +** Each VDBE holds the result of the most recent sqlite3_step() call +** in p->rc. This routine sets that result back to SQLITE_OK. +*/ +void sqlite3VdbeResetStepResult(Vdbe *p){ + p->rc = SQLITE_OK; +} + /* ** Clean up a VDBE after execution but do not delete the VDBE just yet. ** Write any error messages into *pzErrMsg. Return the result code. @@ -1365,16 +1469,20 @@ int sqlite3VdbeHalt(Vdbe *p){ ** VDBE_MAGIC_INIT. */ int sqlite3VdbeReset(Vdbe *p){ + sqlite3 *db; if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){ sqlite3Error(p->db, SQLITE_MISUSE, 0); return SQLITE_MISUSE; } + db = p->db; /* If the VM did not run to completion or if it encountered an ** error, then it might not have been halted properly. So halt ** it now. */ + sqlite3SafetyOn(db); sqlite3VdbeHalt(p); + sqlite3SafetyOff(db); /* If the VDBE has be run even partially, then transfer the error code ** and error message from the VDBE into the main database structure. But @@ -1383,21 +1491,20 @@ int sqlite3VdbeReset(Vdbe *p){ */ if( p->pc>=0 ){ if( p->zErrMsg ){ - sqlite3* db = p->db; sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, sqlite3FreeX); db->errCode = p->rc; p->zErrMsg = 0; }else if( p->rc ){ - sqlite3Error(p->db, p->rc, 0); + sqlite3Error(db, p->rc, 0); }else{ - sqlite3Error(p->db, SQLITE_OK, 0); + sqlite3Error(db, SQLITE_OK, 0); } }else if( p->rc && p->expired ){ /* The expired flag was set on the VDBE before the first call ** to sqlite3_step(). For consistency (since sqlite3_step() was ** called), set the database error in this case as well. */ - sqlite3Error(p->db, p->rc, 0); + sqlite3Error(db, p->rc, 0); } /* Reclaim all memory used by the VDBE @@ -1432,9 +1539,9 @@ int sqlite3VdbeReset(Vdbe *p){ p->magic = VDBE_MAGIC_INIT; p->aborted = 0; if( p->rc==SQLITE_SCHEMA ){ - sqlite3ResetInternalSchema(p->db, 0); + sqlite3ResetInternalSchema(db, 0); } - return p->rc; + return p->rc & db->errMask; } /* @@ -1443,9 +1550,9 @@ int sqlite3VdbeReset(Vdbe *p){ */ int sqlite3VdbeFinalize(Vdbe *p){ int rc = SQLITE_OK; - if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){ rc = sqlite3VdbeReset(p); + assert( (rc & p->db->errMask)==rc ); }else if( p->magic!=VDBE_MAGIC_INIT ){ return SQLITE_MISUSE; } @@ -1500,6 +1607,7 @@ void sqlite3VdbeDelete(Vdbe *p){ sqliteFree(p->aStack); releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); sqliteFree(p->aColName); + sqliteFree(p->zSql); p->magic = VDBE_MAGIC_DEAD; sqliteFree(p); } @@ -1512,7 +1620,9 @@ void sqlite3VdbeDelete(Vdbe *p){ int sqlite3VdbeCursorMoveto(Cursor *p){ if( p->deferredMoveto ){ int res, rc; +#ifdef SQLITE_TEST extern int sqlite3_search_count; +#endif assert( p->isTable ); if( p->isTable ){ rc = sqlite3BtreeMoveto(p->pCursor, 0, p->movetoTarget, &res); @@ -1528,7 +1638,9 @@ int sqlite3VdbeCursorMoveto(Cursor *p){ rc = sqlite3BtreeNext(p->pCursor, &res); if( rc ) return rc; } +#ifdef SQLITE_TEST sqlite3_search_count++; +#endif p->deferredMoveto = 0; p->cacheStatus = CACHE_STALE; } @@ -1592,7 +1704,7 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){ i64 i = pMem->i; u64 u; if( file_format>=4 && (i&1)==i ){ - return 8+(u32)i; + return (u32)(8+i); } u = i<0 ? -i : i; if( u<=127 ) return 1; @@ -1648,7 +1760,7 @@ int sqlite3VdbeSerialPut(unsigned char *buf, Mem *pMem, int file_format){ } len = i = sqlite3VdbeSerialTypeLen(serial_type); while( i-- ){ - buf[i] = (char)(v&0xFF); + buf[i] = (unsigned char)(v&0xFF); v >>= 8; } return len; @@ -1814,14 +1926,13 @@ int sqlite3VdbeRecordCompare( idx2 += GetVarint( aKey2+idx2, serial_type2 ); if( d2>=(u32)nKey2 && sqlite3VdbeSerialTypeLen(serial_type2)>0 ) break; - /* Assert that there is enough space left in each key for the blob of - ** data to go with the serial type just read. This assert may fail if - ** the file is corrupted. Then read the value from each key into mem1 - ** and mem2 respectively. + /* Extract the values to be compared. */ d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1); d2 += sqlite3VdbeSerialGet(&aKey2[d2], serial_type2, &mem2); + /* Do the comparison + */ rc = sqlite3MemCompare(&mem1, &mem2, iaColl[i] : 0); if( mem1.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem1); if( mem2.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem2); diff --git a/dlls/sqlite/sqlite-source/vdbemem.c b/dlls/sqlite/sqlite-source/vdbemem.c index 279b45c5..73a69018 100644 --- a/dlls/sqlite/sqlite-source/vdbemem.c +++ b/dlls/sqlite/sqlite-source/vdbemem.c @@ -50,14 +50,6 @@ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ assert(rc==SQLITE_OK || rc==SQLITE_NOMEM); assert(rc==SQLITE_OK || pMem->enc!=desiredEnc); assert(rc==SQLITE_NOMEM || pMem->enc==desiredEnc); - - if( rc==SQLITE_NOMEM ){ -/* - sqlite3VdbeMemRelease(pMem); - pMem->flags = MEM_Null; - pMem->z = 0; -*/ - } return rc; #endif } @@ -127,22 +119,9 @@ int sqlite3VdbeMemMakeWriteable(Mem *pMem){ ** Make sure the given Mem is \u0000 terminated. */ int sqlite3VdbeMemNulTerminate(Mem *pMem){ - /* In SQLite, a string without a nul terminator occurs when a string - ** is loaded from disk (in this case the memory management is ephemeral), - ** or when it is supplied by the user as a bound variable or function - ** return value. Therefore, the memory management of the string must be - ** either ephemeral, static or controlled by a user-supplied destructor. - */ - assert( - !(pMem->flags&MEM_Str) || /* it's not a string, or */ - (pMem->flags&MEM_Term) || /* it's nul term. already, or */ - (pMem->flags&(MEM_Ephem|MEM_Static)) || /* it's static or ephem, or */ - (pMem->flags&MEM_Dyn && pMem->xDel) /* external management */ - ); if( (pMem->flags & MEM_Term)!=0 || (pMem->flags & MEM_Str)==0 ){ return SQLITE_OK; /* Nothing to do */ } - if( pMem->flags & (MEM_Static|MEM_Ephem) ){ return sqlite3VdbeMemMakeWriteable(pMem); }else{ @@ -151,9 +130,14 @@ int sqlite3VdbeMemNulTerminate(Mem *pMem){ memcpy(z, pMem->z, pMem->n); z[pMem->n] = 0; z[pMem->n+1] = 0; - pMem->xDel(pMem->z); + if( pMem->xDel ){ + pMem->xDel(pMem->z); + }else{ + sqliteFree(pMem->z); + } pMem->xDel = 0; pMem->z = z; + pMem->flags |= MEM_Term; } return SQLITE_OK; } @@ -776,13 +760,15 @@ const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){ pVal->flags |= (pVal->flags & MEM_Blob)>>3; if( pVal->flags&MEM_Str ){ sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED); - if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&(long)pVal->z) ){ + if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&(int)pVal->z) ){ assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 ); if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){ return 0; } } - }else if( !(pVal->flags&MEM_Blob) ){ + sqlite3VdbeMemNulTerminate(pVal); + }else{ + assert( (pVal->flags&MEM_Blob)==0 ); sqlite3VdbeMemStringify(pVal, enc); assert( 0==(1&(int)pVal->z) ); } diff --git a/dlls/sqlite/sqlite-source/vtab.c b/dlls/sqlite/sqlite-source/vtab.c new file mode 100644 index 00000000..5f1d5602 --- /dev/null +++ b/dlls/sqlite/sqlite-source/vtab.c @@ -0,0 +1,693 @@ +/* +** 2006 June 10 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code used to help implement virtual tables. +** +** $Id$ +*/ +#ifndef SQLITE_OMIT_VIRTUALTABLE +#include "sqliteInt.h" + +/* +** External API function used to create a new virtual-table module. +*/ +int sqlite3_create_module( + sqlite3 *db, /* Database in which module is registered */ + const char *zName, /* Name assigned to this module */ + const sqlite3_module *pModule, /* The definition of the module */ + void *pAux /* Context pointer for xCreate/xConnect */ +){ + int nName = strlen(zName); + Module *pMod = (Module *)sqliteMallocRaw(sizeof(Module) + nName + 1); + if( pMod ){ + char *zCopy = (char *)(&pMod[1]); + strcpy(zCopy, zName); + pMod->zName = zCopy; + pMod->pModule = pModule; + pMod->pAux = pAux; + pMod = (Module *)sqlite3HashInsert(&db->aModule, zCopy, nName, (void*)pMod); + sqliteFree(pMod); + sqlite3ResetInternalSchema(db, 0); + } + return sqlite3ApiExit(db, SQLITE_OK); +} + +/* +** Lock the virtual table so that it cannot be disconnected. +** Locks nest. Every lock should have a corresponding unlock. +** If an unlock is omitted, resources leaks will occur. +** +** If a disconnect is attempted while a virtual table is locked, +** the disconnect is deferred until all locks have been removed. +*/ +void sqlite3VtabLock(sqlite3_vtab *pVtab){ + pVtab->nRef++; +} + +/* +** Unlock a virtual table. When the last lock is removed, +** disconnect the virtual table. +*/ +void sqlite3VtabUnlock(sqlite3_vtab *pVtab){ + pVtab->nRef--; + if( pVtab->nRef==0 ){ + pVtab->pModule->xDisconnect(pVtab); + } +} + +/* +** Clear any and all virtual-table information from the Table record. +** This routine is called, for example, just before deleting the Table +** record. +*/ +void sqlite3VtabClear(Table *p){ + sqlite3_vtab *pVtab = p->pVtab; + if( pVtab ){ + assert( p->pMod && p->pMod->pModule ); + sqlite3VtabUnlock(pVtab); + p->pVtab = 0; + } + if( p->azModuleArg ){ + int i; + for(i=0; inModuleArg; i++){ + sqliteFree(p->azModuleArg[i]); + } + sqliteFree(p->azModuleArg); + } +} + +/* +** Add a new module argument to pTable->azModuleArg[]. +** The string is not copied - the pointer is stored. The +** string will be freed automatically when the table is +** deleted. +*/ +static void addModuleArgument(Table *pTable, char *zArg){ + int i = pTable->nModuleArg++; + int nBytes = sizeof(char *)*(1+pTable->nModuleArg); + char **azModuleArg; + azModuleArg = sqliteRealloc(pTable->azModuleArg, nBytes); + if( azModuleArg==0 ){ + int j; + for(j=0; jazModuleArg[j]); + } + sqliteFree(zArg); + sqliteFree(pTable->azModuleArg); + pTable->nModuleArg = 0; + }else{ + azModuleArg[i] = zArg; + azModuleArg[i+1] = 0; + } + pTable->azModuleArg = azModuleArg; +} + +/* +** The parser calls this routine when it first sees a CREATE VIRTUAL TABLE +** statement. The module name has been parsed, but the optional list +** of parameters that follow the module name are still pending. +*/ +void sqlite3VtabBeginParse( + Parse *pParse, /* Parsing context */ + Token *pName1, /* Name of new table, or database name */ + Token *pName2, /* Name of new table or NULL */ + Token *pModuleName /* Name of the module for the virtual table */ +){ + int iDb; /* The database the table is being created in */ + Table *pTable; /* The new virtual table */ + + sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, 0); + pTable = pParse->pNewTable; + if( pTable==0 || pParse->nErr ) return; + assert( 0==pTable->pIndex ); + + iDb = sqlite3SchemaToIndex(pParse->db, pTable->pSchema); + assert( iDb>=0 ); + + pTable->isVirtual = 1; + pTable->nModuleArg = 0; + addModuleArgument(pTable, sqlite3NameFromToken(pModuleName)); + addModuleArgument(pTable, sqlite3StrDup(pParse->db->aDb[iDb].zName)); + addModuleArgument(pTable, sqlite3StrDup(pTable->zName)); + pParse->sNameToken.n = pModuleName->z + pModuleName->n - pName1->z; + +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Creating a virtual table invokes the authorization callback twice. + ** The first invocation, to obtain permission to INSERT a row into the + ** sqlite_master table, has already been made by sqlite3StartTable(). + ** The second call, to obtain permission to create the table, is made now. + */ + if( pTable->azModuleArg ){ + sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName, + pTable->azModuleArg[0], pParse->db->aDb[iDb].zName); + } +#endif +} + +/* +** This routine takes the module argument that has been accumulating +** in pParse->zArg[] and appends it to the list of arguments on the +** virtual table currently under construction in pParse->pTable. +*/ +static void addArgumentToVtab(Parse *pParse){ + if( pParse->sArg.z && pParse->pNewTable ){ + const char *z = (const char*)pParse->sArg.z; + int n = pParse->sArg.n; + addModuleArgument(pParse->pNewTable, sqliteStrNDup(z, n)); + } +} + +/* +** The parser calls this routine after the CREATE VIRTUAL TABLE statement +** has been completely parsed. +*/ +void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ + Table *pTab; /* The table being constructed */ + sqlite3 *db; /* The database connection */ + char *zModule; /* The module name of the table: USING modulename */ + Module *pMod = 0; + + addArgumentToVtab(pParse); + pParse->sArg.z = 0; + + /* Lookup the module name. */ + pTab = pParse->pNewTable; + if( pTab==0 ) return; + db = pParse->db; + if( pTab->nModuleArg<1 ) return; + zModule = pTab->azModuleArg[0]; + pMod = (Module *)sqlite3HashFind(&db->aModule, zModule, strlen(zModule)); + pTab->pMod = pMod; + + /* If the CREATE VIRTUAL TABLE statement is being entered for the + ** first time (in other words if the virtual table is actually being + ** created now instead of just being read out of sqlite_master) then + ** do additional initialization work and store the statement text + ** in the sqlite_master table. + */ + if( !db->init.busy ){ + char *zStmt; + char *zWhere; + int iDb; + Vdbe *v; + + /* Compute the complete text of the CREATE VIRTUAL TABLE statement */ + if( pEnd ){ + pParse->sNameToken.n = pEnd->z - pParse->sNameToken.z + pEnd->n; + } + zStmt = sqlite3MPrintf("CREATE VIRTUAL TABLE %T", &pParse->sNameToken); + + /* A slot for the record has already been allocated in the + ** SQLITE_MASTER table. We just need to update that slot with all + ** the information we've collected. + ** + ** The top of the stack is the rootpage allocated by sqlite3StartTable(). + ** This value is always 0 and is ignored, a virtual table does not have a + ** rootpage. The next entry on the stack is the rowid of the record + ** in the sqlite_master table. + */ + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + sqlite3NestedParse(pParse, + "UPDATE %Q.%s " + "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q " + "WHERE rowid=#1", + db->aDb[iDb].zName, SCHEMA_TABLE(iDb), + pTab->zName, + pTab->zName, + zStmt + ); + sqliteFree(zStmt); + v = sqlite3GetVdbe(pParse); + sqlite3ChangeCookie(db, v, iDb); + + sqlite3VdbeAddOp(v, OP_Expire, 0, 0); + zWhere = sqlite3MPrintf("name='%q'", pTab->zName); + sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 1, zWhere, P3_DYNAMIC); + sqlite3VdbeOp3(v, OP_VCreate, iDb, 0, pTab->zName, strlen(pTab->zName) + 1); + } + + /* If we are rereading the sqlite_master table create the in-memory + ** record of the table. If the module has already been registered, + ** also call the xConnect method here. + */ + else { + Table *pOld; + Schema *pSchema = pTab->pSchema; + const char *zName = pTab->zName; + int nName = strlen(zName) + 1; + pOld = sqlite3HashInsert(&pSchema->tblHash, zName, nName, pTab); + if( pOld ){ + assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */ + return; + } + pParse->pNewTable = 0; + } +} + +/* +** The parser calls this routine when it sees the first token +** of an argument to the module name in a CREATE VIRTUAL TABLE statement. +*/ +void sqlite3VtabArgInit(Parse *pParse){ + addArgumentToVtab(pParse); + pParse->sArg.z = 0; + pParse->sArg.n = 0; +} + +/* +** The parser calls this routine for each token after the first token +** in an argument to the module name in a CREATE VIRTUAL TABLE statement. +*/ +void sqlite3VtabArgExtend(Parse *pParse, Token *p){ + Token *pArg = &pParse->sArg; + if( pArg->z==0 ){ + pArg->z = p->z; + pArg->n = p->n; + }else{ + assert(pArg->z < p->z); + pArg->n = (p->z + p->n - pArg->z); + } +} + +/* +** Invoke a virtual table constructor (either xCreate or xConnect). The +** pointer to the function to invoke is passed as the fourth parameter +** to this procedure. +*/ +static int vtabCallConstructor( + sqlite3 *db, + Table *pTab, + Module *pMod, + int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**), + char **pzErr +){ + int rc; + int rc2; + sqlite3_vtab *pVtab; + const char *const*azArg = (const char *const*)pTab->azModuleArg; + int nArg = pTab->nModuleArg; + char *zErr = 0; + char *zModuleName = sqlite3MPrintf("%s", pTab->zName); + + assert( !db->pVTab ); + assert( xConstruct ); + + db->pVTab = pTab; + rc = sqlite3SafetyOff(db); + assert( rc==SQLITE_OK ); + rc = xConstruct(db, pMod->pAux, nArg, azArg, &pTab->pVtab, &zErr); + rc2 = sqlite3SafetyOn(db); + pVtab = pTab->pVtab; + if( rc==SQLITE_OK && pVtab ){ + pVtab->pModule = pMod->pModule; + pVtab->nRef = 1; + } + + if( SQLITE_OK!=rc ){ + if( zErr==0 ){ + *pzErr = sqlite3MPrintf("vtable constructor failed: %s", zModuleName); + }else { + *pzErr = sqlite3MPrintf("%s", zErr); + sqlite3_free(zErr); + } + }else if( db->pVTab ){ + const char *zFormat = "vtable constructor did not declare schema: %s"; + *pzErr = sqlite3MPrintf(zFormat, pTab->zName); + rc = SQLITE_ERROR; + } + if( rc==SQLITE_OK ){ + rc = rc2; + } + db->pVTab = 0; + sqliteFree(zModuleName); + return rc; +} + +/* +** This function is invoked by the parser to call the xConnect() method +** of the virtual table pTab. If an error occurs, an error code is returned +** and an error left in pParse. +** +** This call is a no-op if table pTab is not a virtual table. +*/ +int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){ + Module *pMod; + int rc = SQLITE_OK; + + if( !pTab || !pTab->isVirtual || pTab->pVtab ){ + return SQLITE_OK; + } + + pMod = pTab->pMod; + if( !pMod ){ + const char *zModule = pTab->azModuleArg[0]; + sqlite3ErrorMsg(pParse, "no such module: %s", zModule); + rc = SQLITE_ERROR; + } else { + char *zErr = 0; + sqlite3 *db = pParse->db; + rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xConnect, &zErr); + if( rc!=SQLITE_OK ){ + sqlite3ErrorMsg(pParse, "%s", zErr); + } + sqliteFree(zErr); + } + + return rc; +} + +/* +** Add the virtual table pVtab to the array sqlite3.aVTrans[]. +*/ +static int addToVTrans(sqlite3 *db, sqlite3_vtab *pVtab){ + const int ARRAY_INCR = 5; + + /* Grow the sqlite3.aVTrans array if required */ + if( (db->nVTrans%ARRAY_INCR)==0 ){ + sqlite3_vtab **aVTrans; + int nBytes = sizeof(sqlite3_vtab *) * (db->nVTrans + ARRAY_INCR); + aVTrans = sqliteRealloc((void *)db->aVTrans, nBytes); + if( !aVTrans ){ + return SQLITE_NOMEM; + } + memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR); + db->aVTrans = aVTrans; + } + + /* Add pVtab to the end of sqlite3.aVTrans */ + db->aVTrans[db->nVTrans++] = pVtab; + sqlite3VtabLock(pVtab); + return SQLITE_OK; +} + +/* +** This function is invoked by the vdbe to call the xCreate method +** of the virtual table named zTab in database iDb. +** +** If an error occurs, *pzErr is set to point an an English language +** description of the error and an SQLITE_XXX error code is returned. +** In this case the caller must call sqliteFree() on *pzErr. +*/ +int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){ + int rc = SQLITE_OK; + Table *pTab; + Module *pMod; + const char *zModule; + + pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName); + assert(pTab && pTab->isVirtual && !pTab->pVtab); + pMod = pTab->pMod; + zModule = pTab->azModuleArg[0]; + + /* If the module has been registered and includes a Create method, + ** invoke it now. If the module has not been registered, return an + ** error. Otherwise, do nothing. + */ + if( !pMod ){ + *pzErr = sqlite3MPrintf("no such module: %s", zModule); + rc = SQLITE_ERROR; + }else{ + rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xCreate, pzErr); + } + + if( rc==SQLITE_OK && pTab->pVtab ){ + rc = addToVTrans(db, pTab->pVtab); + } + + return rc; +} + +/* +** This function is used to set the schema of a virtual table. It is only +** valid to call this function from within the xCreate() or xConnect() of a +** virtual table module. +*/ +int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ + Parse sParse; + + int rc = SQLITE_OK; + Table *pTab = db->pVTab; + char *zErr = 0; + + if( !pTab ){ + sqlite3Error(db, SQLITE_MISUSE, 0); + return SQLITE_MISUSE; + } + assert(pTab->isVirtual && pTab->nCol==0 && pTab->aCol==0); + + memset(&sParse, 0, sizeof(Parse)); + sParse.declareVtab = 1; + sParse.db = db; + + if( + SQLITE_OK == sqlite3RunParser(&sParse, zCreateTable, &zErr) && + sParse.pNewTable && + !sParse.pNewTable->pSelect && + !sParse.pNewTable->isVirtual + ){ + pTab->aCol = sParse.pNewTable->aCol; + pTab->nCol = sParse.pNewTable->nCol; + sParse.pNewTable->nCol = 0; + sParse.pNewTable->aCol = 0; + } else { + sqlite3Error(db, SQLITE_ERROR, zErr); + sqliteFree(zErr); + rc = SQLITE_ERROR; + } + sParse.declareVtab = 0; + + sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe); + sqlite3DeleteTable(0, sParse.pNewTable); + sParse.pNewTable = 0; + db->pVTab = 0; + + assert( (rc&0xff)==rc ); + return rc; +} + +/* +** This function is invoked by the vdbe to call the xDestroy method +** of the virtual table named zTab in database iDb. This occurs +** when a DROP TABLE is mentioned. +** +** This call is a no-op if zTab is not a virtual table. +*/ +int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab) +{ + int rc = SQLITE_OK; + Table *pTab; + + pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName); + assert(pTab); + if( pTab->pVtab ){ + int (*xDestroy)(sqlite3_vtab *pVTab) = pTab->pMod->pModule->xDestroy; + rc = sqlite3SafetyOff(db); + assert( rc==SQLITE_OK ); + if( xDestroy ){ + rc = xDestroy(pTab->pVtab); + } + sqlite3SafetyOn(db); + if( rc==SQLITE_OK ){ + pTab->pVtab = 0; + } + } + + return rc; +} + +/* +** This function invokes either the xRollback or xCommit method +** of each of the virtual tables in the sqlite3.aVTrans array. The method +** called is identified by the second argument, "offset", which is +** the offset of the method to call in the sqlite3_module structure. +** +** The array is cleared after invoking the callbacks. +*/ +static void callFinaliser(sqlite3 *db, int offset){ + int i; + for(i=0; inVTrans && db->aVTrans[i]; i++){ + sqlite3_vtab *pVtab = db->aVTrans[i]; + int (*x)(sqlite3_vtab *); + x = *(int (**)(sqlite3_vtab *))((char *)pVtab->pModule + offset); + if( x ) x(pVtab); + sqlite3VtabUnlock(pVtab); + } + sqliteFree(db->aVTrans); + db->nVTrans = 0; + db->aVTrans = 0; +} + +/* +** If argument rc2 is not SQLITE_OK, then return it and do nothing. +** Otherwise, invoke the xSync method of all virtual tables in the +** sqlite3.aVTrans array. Return the error code for the first error +** that occurs, or SQLITE_OK if all xSync operations are successful. +*/ +int sqlite3VtabSync(sqlite3 *db, int rc2){ + int i; + int rc = SQLITE_OK; + int rcsafety; + sqlite3_vtab **aVTrans = db->aVTrans; + if( rc2!=SQLITE_OK ) return rc2; + + rc = sqlite3SafetyOff(db); + db->aVTrans = 0; + for(i=0; rc==SQLITE_OK && inVTrans && aVTrans[i]; i++){ + sqlite3_vtab *pVtab = aVTrans[i]; + int (*x)(sqlite3_vtab *); + x = pVtab->pModule->xSync; + if( x ){ + rc = x(pVtab); + } + } + db->aVTrans = aVTrans; + rcsafety = sqlite3SafetyOn(db); + + if( rc==SQLITE_OK ){ + rc = rcsafety; + } + return rc; +} + +/* +** Invoke the xRollback method of all virtual tables in the +** sqlite3.aVTrans array. Then clear the array itself. +*/ +int sqlite3VtabRollback(sqlite3 *db){ + callFinaliser(db, (int)(&((sqlite3_module *)0)->xRollback)); + return SQLITE_OK; +} + +/* +** Invoke the xCommit method of all virtual tables in the +** sqlite3.aVTrans array. Then clear the array itself. +*/ +int sqlite3VtabCommit(sqlite3 *db){ + callFinaliser(db, (int)(&((sqlite3_module *)0)->xCommit)); + return SQLITE_OK; +} + +/* +** If the virtual table pVtab supports the transaction interface +** (xBegin/xRollback/xCommit and optionally xSync) and a transaction is +** not currently open, invoke the xBegin method now. +** +** If the xBegin call is successful, place the sqlite3_vtab pointer +** in the sqlite3.aVTrans array. +*/ +int sqlite3VtabBegin(sqlite3 *db, sqlite3_vtab *pVtab){ + int rc = SQLITE_OK; + const sqlite3_module *pModule; + + /* Special case: If db->aVTrans is NULL and db->nVTrans is greater + ** than zero, then this function is being called from within a + ** virtual module xSync() callback. It is illegal to write to + ** virtual module tables in this case, so return SQLITE_LOCKED. + */ + if( 0==db->aVTrans && db->nVTrans>0 ){ + return SQLITE_LOCKED; + } + if( !pVtab ){ + return SQLITE_OK; + } + pModule = pVtab->pModule; + + if( pModule->xBegin ){ + int i; + + + /* If pVtab is already in the aVTrans array, return early */ + for(i=0; (inVTrans) && 0!=db->aVTrans[i]; i++){ + if( db->aVTrans[i]==pVtab ){ + return SQLITE_OK; + } + } + + /* Invoke the xBegin method */ + rc = pModule->xBegin(pVtab); + if( rc!=SQLITE_OK ){ + return rc; + } + + rc = addToVTrans(db, pVtab); + } + return rc; +} + +/* +** The first parameter (pDef) is a function implementation. The +** second parameter (pExpr) is the first argument to this function. +** If pExpr is a column in a virtual table, then let the virtual +** table implementation have an opportunity to overload the function. +** +** This routine is used to allow virtual table implementations to +** overload MATCH, LIKE, GLOB, and REGEXP operators. +** +** Return either the pDef argument (indicating no change) or a +** new FuncDef structure that is marked as ephemeral using the +** SQLITE_FUNC_EPHEM flag. +*/ +FuncDef *sqlite3VtabOverloadFunction( + FuncDef *pDef, /* Function to possibly overload */ + int nArg, /* Number of arguments to the function */ + Expr *pExpr /* First argument to the function */ +){ + Table *pTab; + sqlite3_vtab *pVtab; + sqlite3_module *pMod; + void (*xFunc)(sqlite3_context*,int,sqlite3_value**); + void *pArg; + FuncDef *pNew; + int rc; + char *zLowerName; + unsigned char *z; + + + /* Check to see the left operand is a column in a virtual table */ + if( pExpr==0 ) return pDef; + if( pExpr->op!=TK_COLUMN ) return pDef; + pTab = pExpr->pTab; + if( pTab==0 ) return pDef; + if( !pTab->isVirtual ) return pDef; + pVtab = pTab->pVtab; + assert( pVtab!=0 ); + assert( pVtab->pModule!=0 ); + pMod = (sqlite3_module *)pVtab->pModule; + if( pMod->xFindFunction==0 ) return pDef; + + /* Call the xFuncFunction method on the virtual table implementation + ** to see if the implementation wants to overload this function + */ + zLowerName = sqlite3StrDup(pDef->zName); + for(z=(unsigned char*)zLowerName; *z; z++){ + *z = sqlite3UpperToLower[*z]; + } + rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xFunc, &pArg); + sqliteFree(zLowerName); + if( rc==0 ){ + return pDef; + } + + /* Create a new ephemeral function definition for the overloaded + ** function */ + pNew = sqliteMalloc( sizeof(*pNew) + strlen(pDef->zName) ); + if( pNew==0 ){ + return pDef; + } + *pNew = *pDef; + strcpy(pNew->zName, pDef->zName); + pNew->xFunc = xFunc; + pNew->pUserData = pArg; + pNew->flags |= SQLITE_FUNC_EPHEM; + return pNew; +} + +#endif /* SQLITE_OMIT_VIRTUALTABLE */ diff --git a/dlls/sqlite/sqlite-source/where.c b/dlls/sqlite/sqlite-source/where.c index 1056e71e..d62c37d5 100644 --- a/dlls/sqlite/sqlite-source/where.c +++ b/dlls/sqlite/sqlite-source/where.c @@ -43,6 +43,7 @@ int sqlite3_where_trace = 0; /* Forward reference */ typedef struct WhereClause WhereClause; +typedef struct ExprMaskSet ExprMaskSet; /* ** The query generator uses an array of instances of this structure to @@ -106,6 +107,7 @@ struct WhereTerm { */ struct WhereClause { Parse *pParse; /* The parser context */ + ExprMaskSet *pMaskSet; /* Mapping of table indices to bitmasks */ int nTerm; /* Number of terms */ int nSlot; /* Number of entries in a[] */ WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */ @@ -138,7 +140,6 @@ struct WhereClause { ** numbers all get mapped into bit numbers that begin with 0 and contain ** no gaps. */ -typedef struct ExprMaskSet ExprMaskSet; struct ExprMaskSet { int n; /* Number of assigned cursor values */ int ix[sizeof(Bitmask)*8]; /* Cursor assigned to each bit */ @@ -156,27 +157,43 @@ struct ExprMaskSet { #define WO_LE (WO_EQ<<(TK_LE-TK_EQ)) #define WO_GT (WO_EQ<<(TK_GT-TK_EQ)) #define WO_GE (WO_EQ<<(TK_GE-TK_EQ)) +#define WO_MATCH 64 +#define WO_ISNULL 128 /* -** Value for flags returned by bestIndex() +** Value for flags returned by bestIndex(). +** +** The least significant byte is reserved as a mask for WO_ values above. +** The WhereLevel.flags field is usually set to WO_IN|WO_EQ|WO_ISNULL. +** But if the table is the right table of a left join, WhereLevel.flags +** is set to WO_IN|WO_EQ. The WhereLevel.flags field can then be used as +** the "op" parameter to findTerm when we are resolving equality constraints. +** ISNULL constraints will then not be used on the right table of a left +** join. Tickets #2177 and #2189. */ -#define WHERE_ROWID_EQ 0x0001 /* rowid=EXPR or rowid IN (...) */ -#define WHERE_ROWID_RANGE 0x0002 /* rowidEXPR */ -#define WHERE_COLUMN_EQ 0x0010 /* x=EXPR or x IN (...) */ -#define WHERE_COLUMN_RANGE 0x0020 /* xEXPR */ -#define WHERE_COLUMN_IN 0x0040 /* x IN (...) */ -#define WHERE_TOP_LIMIT 0x0100 /* xEXPR or x>=EXPR constraint */ -#define WHERE_IDX_ONLY 0x0800 /* Use index only - omit table */ -#define WHERE_ORDERBY 0x1000 /* Output will appear in correct order */ -#define WHERE_REVERSE 0x2000 /* Scan in reverse order */ -#define WHERE_UNIQUE 0x4000 /* Selects no more than one row */ +#define WHERE_ROWID_EQ 0x000100 /* rowid=EXPR or rowid IN (...) */ +#define WHERE_ROWID_RANGE 0x000200 /* rowidEXPR */ +#define WHERE_COLUMN_EQ 0x001000 /* x=EXPR or x IN (...) */ +#define WHERE_COLUMN_RANGE 0x002000 /* xEXPR */ +#define WHERE_COLUMN_IN 0x004000 /* x IN (...) */ +#define WHERE_TOP_LIMIT 0x010000 /* xEXPR or x>=EXPR constraint */ +#define WHERE_IDX_ONLY 0x080000 /* Use index only - omit table */ +#define WHERE_ORDERBY 0x100000 /* Output will appear in correct order */ +#define WHERE_REVERSE 0x200000 /* Scan in reverse order */ +#define WHERE_UNIQUE 0x400000 /* Selects no more than one row */ +#define WHERE_VIRTUALTABLE 0x800000 /* Use virtual-table processing */ /* ** Initialize a preallocated WhereClause structure. */ -static void whereClauseInit(WhereClause *pWC, Parse *pParse){ +static void whereClauseInit( + WhereClause *pWC, /* The WhereClause to be initialized */ + Parse *pParse, /* The parsing context */ + ExprMaskSet *pMaskSet /* Mapping from table indices to bitmasks */ +){ pWC->pParse = pParse; + pWC->pMaskSet = pMaskSet; pWC->nTerm = 0; pWC->nSlot = ARRAYSIZE(pWC->aStatic); pWC->a = pWC->aStatic; @@ -352,7 +369,7 @@ static int allowedOp(int op){ assert( TK_LT>TK_EQ && TK_LTTK_EQ && TK_LE=TK_EQ && op<=TK_GE); + return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL; } /* @@ -386,9 +403,12 @@ static int operatorMask(int op){ assert( allowedOp(op) ); if( op==TK_IN ){ c = WO_IN; + }else if( op==TK_ISNULL ){ + c = WO_ISNULL; }else{ c = WO_EQ<<(op-TK_EQ); } + assert( op!=TK_ISNULL || c==WO_ISNULL ); assert( op!=TK_IN || c==WO_IN ); assert( op!=TK_EQ || c==WO_EQ ); assert( op!=TK_LT || c==WO_LT ); @@ -420,7 +440,7 @@ static WhereTerm *findTerm( && pTerm->leftColumn==iColumn && (pTerm->eOperator & op)!=0 ){ - if( iCur>=0 && pIdx ){ + if( iCur>=0 && pIdx && pTerm->eOperator!=WO_ISNULL ){ Expr *pX = pTerm->pExpr; CollSeq *pColl; char idxaff; @@ -449,7 +469,7 @@ static WhereTerm *findTerm( } /* Forward reference */ -static void exprAnalyze(SrcList*, ExprMaskSet*, WhereClause*, int); +static void exprAnalyze(SrcList*, WhereClause*, int); /* ** Call exprAnalyze on all terms in a WHERE clause. @@ -458,12 +478,11 @@ static void exprAnalyze(SrcList*, ExprMaskSet*, WhereClause*, int); */ static void exprAnalyzeAll( SrcList *pTabList, /* the FROM clause */ - ExprMaskSet *pMaskSet, /* table masks */ WhereClause *pWC /* the WHERE clause to be analyzed */ ){ int i; for(i=pWC->nTerm-1; i>=0; i--){ - exprAnalyze(pTabList, pMaskSet, pWC, i); + exprAnalyze(pTabList, pWC, i); } } @@ -522,6 +541,38 @@ static int isLikeOrGlob( } #endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Check to see if the given expression is of the form +** +** column MATCH expr +** +** If it is then return TRUE. If not, return FALSE. +*/ +static int isMatchOfColumn( + Expr *pExpr /* Test this expression */ +){ + ExprList *pList; + + if( pExpr->op!=TK_FUNCTION ){ + return 0; + } + if( pExpr->token.n!=5 || + sqlite3StrNICmp((const char*)pExpr->token.z,"match",5)!=0 ){ + return 0; + } + pList = pExpr->pList; + if( pList->nExpr!=2 ){ + return 0; + } + if( pList->a[1].pExpr->op != TK_COLUMN ){ + return 0; + } + return 1; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + /* ** If the pBase expression originated in the ON or USING clause of ** a join, then transfer the appropriate markings over to derived. @@ -546,23 +597,27 @@ static void transferJoinMarkings(Expr *pDerived, Expr *pBase){ */ static void exprAnalyze( SrcList *pSrc, /* the FROM clause */ - ExprMaskSet *pMaskSet, /* table masks */ WhereClause *pWC, /* the WHERE clause */ int idxTerm /* Index of the term to be analyzed */ ){ WhereTerm *pTerm = &pWC->a[idxTerm]; + ExprMaskSet *pMaskSet = pWC->pMaskSet; Expr *pExpr = pTerm->pExpr; Bitmask prereqLeft; Bitmask prereqAll; int nPattern; int isComplete; + int op; if( sqlite3MallocFailed() ) return; prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft); - if( pExpr->op==TK_IN ){ + op = pExpr->op; + if( op==TK_IN ){ assert( pExpr->pRight==0 ); pTerm->prereqRight = exprListTableUsage(pMaskSet, pExpr->pList) | exprSelectTableUsage(pMaskSet, pExpr->pSelect); + }else if( op==TK_ISNULL ){ + pTerm->prereqRight = 0; }else{ pTerm->prereqRight = exprTableUsage(pMaskSet, pExpr->pRight); } @@ -574,13 +629,13 @@ static void exprAnalyze( pTerm->leftCursor = -1; pTerm->iParent = -1; pTerm->eOperator = 0; - if( allowedOp(pExpr->op) && (pTerm->prereqRight & prereqLeft)==0 ){ + if( allowedOp(op) && (pTerm->prereqRight & prereqLeft)==0 ){ Expr *pLeft = pExpr->pLeft; Expr *pRight = pExpr->pRight; if( pLeft->op==TK_COLUMN ){ pTerm->leftCursor = pLeft->iTable; pTerm->leftColumn = pLeft->iColumn; - pTerm->eOperator = operatorMask(pExpr->op); + pTerm->eOperator = operatorMask(op); } if( pRight && pRight->op==TK_COLUMN ){ WhereTerm *pNew; @@ -588,6 +643,10 @@ static void exprAnalyze( if( pTerm->leftCursor>=0 ){ int idxNew; pDup = sqlite3ExprDup(pExpr); + if( sqlite3MallocFailed() ){ + sqliteFree(pDup); + return; + } idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC); if( idxNew==0 ) return; pNew = &pWC->a[idxNew]; @@ -625,7 +684,7 @@ static void exprAnalyze( pNewExpr = sqlite3Expr(ops[i], sqlite3ExprDup(pExpr->pLeft), sqlite3ExprDup(pList->a[i].pExpr), 0); idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); - exprAnalyze(pSrc, pMaskSet, pWC, idxNew); + exprAnalyze(pSrc, pWC, idxNew); pTerm = &pWC->a[idxTerm]; pWC->a[idxNew].iParent = idxTerm; } @@ -654,9 +713,9 @@ static void exprAnalyze( WhereTerm *pOrTerm; assert( (pTerm->flags & TERM_DYNAMIC)==0 ); - whereClauseInit(&sOr, pWC->pParse); + whereClauseInit(&sOr, pWC->pParse, pMaskSet); whereSplit(&sOr, pExpr, TK_OR); - exprAnalyzeAll(pSrc, pMaskSet, &sOr); + exprAnalyzeAll(pSrc, &sOr); assert( sOr.nTerm>0 ); j = 0; do{ @@ -681,23 +740,22 @@ static void exprAnalyze( if( ok ){ ExprList *pList = 0; Expr *pNew, *pDup; + Expr *pLeft = 0; for(i=sOr.nTerm-1, pOrTerm=sOr.a; i>=0 && ok; i--, pOrTerm++){ if( (pOrTerm->flags & TERM_OR_OK)==0 ) continue; pDup = sqlite3ExprDup(pOrTerm->pExpr->pRight); pList = sqlite3ExprListAppend(pList, pDup, 0); + pLeft = pOrTerm->pExpr->pLeft; } - pDup = sqlite3Expr(TK_COLUMN, 0, 0, 0); - if( pDup ){ - pDup->iTable = iCursor; - pDup->iColumn = iColumn; - } + assert( pLeft!=0 ); + pDup = sqlite3ExprDup(pLeft); pNew = sqlite3Expr(TK_IN, pDup, 0, 0); if( pNew ){ int idxNew; transferJoinMarkings(pNew, pExpr); pNew->pList = pList; idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC); - exprAnalyze(pSrc, pMaskSet, pWC, idxNew); + exprAnalyze(pSrc, pWC, idxNew); pTerm = &pWC->a[idxTerm]; pWC->a[idxNew].iParent = idxTerm; pTerm->nChild = 1; @@ -734,10 +792,10 @@ or_not_possible: } pNewExpr1 = sqlite3Expr(TK_GE, sqlite3ExprDup(pLeft), pStr1, 0); idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC); - exprAnalyze(pSrc, pMaskSet, pWC, idxNew1); + exprAnalyze(pSrc, pWC, idxNew1); pNewExpr2 = sqlite3Expr(TK_LT, sqlite3ExprDup(pLeft), pStr2, 0); idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC); - exprAnalyze(pSrc, pMaskSet, pWC, idxNew2); + exprAnalyze(pSrc, pWC, idxNew2); pTerm = &pWC->a[idxTerm]; if( isComplete ){ pWC->a[idxNew1].iParent = idxTerm; @@ -746,6 +804,60 @@ or_not_possible: } } #endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* Add a WO_MATCH auxiliary term to the constraint set if the + ** current expression is of the form: column MATCH expr. + ** This information is used by the xBestIndex methods of + ** virtual tables. The native query optimizer does not attempt + ** to do anything with MATCH functions. + */ + if( isMatchOfColumn(pExpr) ){ + int idxNew; + Expr *pRight, *pLeft; + WhereTerm *pNewTerm; + Bitmask prereqColumn, prereqExpr; + + pRight = pExpr->pList->a[0].pExpr; + pLeft = pExpr->pList->a[1].pExpr; + prereqExpr = exprTableUsage(pMaskSet, pRight); + prereqColumn = exprTableUsage(pMaskSet, pLeft); + if( (prereqExpr & prereqColumn)==0 ){ + Expr *pNewExpr; + pNewExpr = sqlite3Expr(TK_MATCH, 0, sqlite3ExprDup(pRight), 0); + idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); + pNewTerm = &pWC->a[idxNew]; + pNewTerm->prereqRight = prereqExpr; + pNewTerm->leftCursor = pLeft->iTable; + pNewTerm->leftColumn = pLeft->iColumn; + pNewTerm->eOperator = WO_MATCH; + pNewTerm->iParent = idxTerm; + pTerm = &pWC->a[idxTerm]; + pTerm->nChild = 1; + pTerm->flags |= TERM_COPIED; + pNewTerm->prereqAll = pTerm->prereqAll; + } + } +#endif /* SQLITE_OMIT_VIRTUALTABLE */ +} + +/* +** Return TRUE if any of the expressions in pList->a[iFirst...] contain +** a reference to any table other than the iBase table. +*/ +static int referencesOtherTables( + ExprList *pList, /* Search expressions in ths list */ + ExprMaskSet *pMaskSet, /* Mapping from tables to bitmaps */ + int iFirst, /* Be searching with the iFirst-th expression */ + int iBase /* Ignore references to this table */ +){ + Bitmask allowed = ~getMask(pMaskSet, iBase); + while( iFirstnExpr ){ + if( (exprTableUsage(pMaskSet, pList->a[iFirst++].pExpr)&allowed)!=0 ){ + return 1; + } + } + return 0; } @@ -770,6 +882,7 @@ or_not_possible: */ static int isSortingIndex( Parse *pParse, /* Parsing context */ + ExprMaskSet *pMaskSet, /* Mapping from table indices to bitmaps */ Index *pIdx, /* The index we are testing */ int base, /* Cursor number for the table to be sorted */ ExprList *pOrderBy, /* The ORDER BY clause */ @@ -788,22 +901,43 @@ static int isSortingIndex( /* Match terms of the ORDER BY clause against columns of ** the index. + ** + ** Note that indices have pIdx->nColumn regular columns plus + ** one additional column containing the rowid. The rowid column + ** of the index is also allowed to match against the ORDER BY + ** clause. */ - for(i=j=0, pTerm=pOrderBy->a; jnColumn; i++){ + for(i=j=0, pTerm=pOrderBy->a; jnColumn; i++){ Expr *pExpr; /* The expression of the ORDER BY pTerm */ CollSeq *pColl; /* The collating sequence of pExpr */ int termSortOrder; /* Sort order for this term */ + int iColumn; /* The i-th column of the index. -1 for rowid */ + int iSortOrder; /* 1 for DESC, 0 for ASC on the i-th index term */ + const char *zColl; /* Name of the collating sequence for i-th index term */ pExpr = pTerm->pExpr; if( pExpr->op!=TK_COLUMN || pExpr->iTable!=base ){ /* Can not use an index sort on anything that is not a column in the ** left-most table of the FROM clause */ - return 0; + break; } pColl = sqlite3ExprCollSeq(pParse, pExpr); - if( !pColl ) pColl = db->pDfltColl; - if( pExpr->iColumn!=pIdx->aiColumn[i] || - sqlite3StrICmp(pColl->zName, pIdx->azColl[i]) ){ + if( !pColl ){ + pColl = db->pDfltColl; + } + if( inColumn ){ + iColumn = pIdx->aiColumn[i]; + if( iColumn==pIdx->pTable->iPKey ){ + iColumn = -1; + } + iSortOrder = pIdx->aSortOrder[i]; + zColl = pIdx->azColl[i]; + }else{ + iColumn = -1; + iSortOrder = 0; + zColl = pColl->zName; + } + if( pExpr->iColumn!=iColumn || sqlite3StrICmp(pColl->zName, zColl) ){ /* Term j of the ORDER BY clause does not match column i of the index */ if( iaSortOrder!=0 ); assert( pTerm->sortOrder==0 || pTerm->sortOrder==1 ); - assert( pIdx->aSortOrder[i]==0 || pIdx->aSortOrder[i]==1 ); - termSortOrder = pIdx->aSortOrder[i] ^ pTerm->sortOrder; + assert( iSortOrder==0 || iSortOrder==1 ); + termSortOrder = iSortOrder ^ pTerm->sortOrder; if( i>nEqCol ){ if( termSortOrder!=sortOrder ){ /* Indices can only be used if all ORDER BY terms past the @@ -832,13 +966,29 @@ static int isSortingIndex( } j++; pTerm++; + if( iColumn<0 && !referencesOtherTables(pOrderBy, pMaskSet, j, base) ){ + /* If the indexed column is the primary key and everything matches + ** so far and none of the ORDER BY terms to the right reference other + ** tables in the join, then we are assured that the index can be used + ** to sort because the primary key is unique and so none of the other + ** columns will make any difference + */ + j = nTerm; + } } - /* The index can be used for sorting if all terms of the ORDER BY clause - ** are covered. - */ + *pbRev = sortOrder!=0; if( j>=nTerm ){ - *pbRev = sortOrder!=0; + /* All terms of the ORDER BY clause are covered by this index so + ** this index can be used for sorting. */ + return 1; + } + if( pIdx->onError!=OE_None && i==pIdx->nColumn + && !referencesOtherTables(pOrderBy, pMaskSet, j, base) ){ + /* All terms of this index match some prefix of the ORDER BY clause + ** and the index is UNIQUE and no terms on the tail of the ORDER BY + ** clause reference other tables in a join. If this is all true then + ** the order by clause is superfluous. */ return 1; } return 0; @@ -852,6 +1002,7 @@ static int isSortingIndex( static int sortableByRowid( int base, /* Cursor number for table to be sorted */ ExprList *pOrderBy, /* The ORDER BY clause */ + ExprMaskSet *pMaskSet, /* Mapping from tables to bitmaps */ int *pbRev /* Set to 1 if ORDER BY is DESC */ ){ Expr *p; @@ -859,8 +1010,8 @@ static int sortableByRowid( assert( pOrderBy!=0 ); assert( pOrderBy->nExpr>0 ); p = pOrderBy->a[0].pExpr; - if( pOrderBy->nExpr==1 && p->op==TK_COLUMN && p->iTable==base - && p->iColumn==-1 ){ + if( p->op==TK_COLUMN && p->iTable==base && p->iColumn==-1 + && !referencesOtherTables(pOrderBy, pMaskSet, 1, base) ){ *pbRev = pOrderBy->a[0].sortOrder; return 1; } @@ -884,6 +1035,247 @@ static double estLog(double N){ return logN; } +/* +** Two routines for printing the content of an sqlite3_index_info +** structure. Used for testing and debugging only. If neither +** SQLITE_TEST or SQLITE_DEBUG are defined, then these routines +** are no-ops. +*/ +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && \ + (defined(SQLITE_TEST) || defined(SQLITE_DEBUG)) +static void TRACE_IDX_INPUTS(sqlite3_index_info *p){ + int i; + if( !sqlite3_where_trace ) return; + for(i=0; inConstraint; i++){ + sqlite3DebugPrintf(" constraint[%d]: col=%d termid=%d op=%d usabled=%d\n", + i, + p->aConstraint[i].iColumn, + p->aConstraint[i].iTermOffset, + p->aConstraint[i].op, + p->aConstraint[i].usable); + } + for(i=0; inOrderBy; i++){ + sqlite3DebugPrintf(" orderby[%d]: col=%d desc=%d\n", + i, + p->aOrderBy[i].iColumn, + p->aOrderBy[i].desc); + } +} +static void TRACE_IDX_OUTPUTS(sqlite3_index_info *p){ + int i; + if( !sqlite3_where_trace ) return; + for(i=0; inConstraint; i++){ + sqlite3DebugPrintf(" usage[%d]: argvIdx=%d omit=%d\n", + i, + p->aConstraintUsage[i].argvIndex, + p->aConstraintUsage[i].omit); + } + sqlite3DebugPrintf(" idxNum=%d\n", p->idxNum); + sqlite3DebugPrintf(" idxStr=%s\n", p->idxStr); + sqlite3DebugPrintf(" orderByConsumed=%d\n", p->orderByConsumed); + sqlite3DebugPrintf(" estimatedCost=%g\n", p->estimatedCost); +} +#else +#define TRACE_IDX_INPUTS(A) +#define TRACE_IDX_OUTPUTS(A) +#endif + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Compute the best index for a virtual table. +** +** The best index is computed by the xBestIndex method of the virtual +** table module. This routine is really just a wrapper that sets up +** the sqlite3_index_info structure that is used to communicate with +** xBestIndex. +** +** In a join, this routine might be called multiple times for the +** same virtual table. The sqlite3_index_info structure is created +** and initialized on the first invocation and reused on all subsequent +** invocations. The sqlite3_index_info structure is also used when +** code is generated to access the virtual table. The whereInfoDelete() +** routine takes care of freeing the sqlite3_index_info structure after +** everybody has finished with it. +*/ +static double bestVirtualIndex( + Parse *pParse, /* The parsing context */ + WhereClause *pWC, /* The WHERE clause */ + struct SrcList_item *pSrc, /* The FROM clause term to search */ + Bitmask notReady, /* Mask of cursors that are not available */ + ExprList *pOrderBy, /* The order by clause */ + int orderByUsable, /* True if we can potential sort */ + sqlite3_index_info **ppIdxInfo /* Index information passed to xBestIndex */ +){ + Table *pTab = pSrc->pTab; + sqlite3_index_info *pIdxInfo; + struct sqlite3_index_constraint *pIdxCons; + struct sqlite3_index_orderby *pIdxOrderBy; + struct sqlite3_index_constraint_usage *pUsage; + WhereTerm *pTerm; + int i, j; + int nOrderBy; + int rc; + + /* If the sqlite3_index_info structure has not been previously + ** allocated and initialized for this virtual table, then allocate + ** and initialize it now + */ + pIdxInfo = *ppIdxInfo; + if( pIdxInfo==0 ){ + WhereTerm *pTerm; + int nTerm; + TRACE(("Recomputing index info for %s...\n", pTab->zName)); + + /* Count the number of possible WHERE clause constraints referring + ** to this virtual table */ + for(i=nTerm=0, pTerm=pWC->a; inTerm; i++, pTerm++){ + if( pTerm->leftCursor != pSrc->iCursor ) continue; + if( pTerm->eOperator==WO_IN ) continue; + nTerm++; + } + + /* If the ORDER BY clause contains only columns in the current + ** virtual table then allocate space for the aOrderBy part of + ** the sqlite3_index_info structure. + */ + nOrderBy = 0; + if( pOrderBy ){ + for(i=0; inExpr; i++){ + Expr *pExpr = pOrderBy->a[i].pExpr; + if( pExpr->op!=TK_COLUMN || pExpr->iTable!=pSrc->iCursor ) break; + } + if( i==pOrderBy->nExpr ){ + nOrderBy = pOrderBy->nExpr; + } + } + + /* Allocate the sqlite3_index_info structure + */ + pIdxInfo = sqliteMalloc( sizeof(*pIdxInfo) + + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm + + sizeof(*pIdxOrderBy)*nOrderBy ); + if( pIdxInfo==0 ){ + sqlite3ErrorMsg(pParse, "out of memory"); + return 0.0; + } + *ppIdxInfo = pIdxInfo; + + /* Initialize the structure. The sqlite3_index_info structure contains + ** many fields that are declared "const" to prevent xBestIndex from + ** changing them. We have to do some funky casting in order to + ** initialize those fields. + */ + pIdxCons = (struct sqlite3_index_constraint*)&pIdxInfo[1]; + pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm]; + pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy]; + *(int*)&pIdxInfo->nConstraint = nTerm; + *(int*)&pIdxInfo->nOrderBy = nOrderBy; + *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint = pIdxCons; + *(struct sqlite3_index_orderby**)&pIdxInfo->aOrderBy = pIdxOrderBy; + *(struct sqlite3_index_constraint_usage**)&pIdxInfo->aConstraintUsage = + pUsage; + + for(i=j=0, pTerm=pWC->a; inTerm; i++, pTerm++){ + if( pTerm->leftCursor != pSrc->iCursor ) continue; + if( pTerm->eOperator==WO_IN ) continue; + pIdxCons[j].iColumn = pTerm->leftColumn; + pIdxCons[j].iTermOffset = i; + pIdxCons[j].op = (unsigned char)pTerm->eOperator; + /* The direct assignment in the previous line is possible only because + ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The + ** following asserts verify this fact. */ + assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ ); + assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT ); + assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE ); + assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT ); + assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE ); + assert( WO_MATCH==SQLITE_INDEX_CONSTRAINT_MATCH ); + assert( pTerm->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) ); + j++; + } + for(i=0; ia[i].pExpr; + pIdxOrderBy[i].iColumn = pExpr->iColumn; + pIdxOrderBy[i].desc = pOrderBy->a[i].sortOrder; + } + } + + /* At this point, the sqlite3_index_info structure that pIdxInfo points + ** to will have been initialized, either during the current invocation or + ** during some prior invocation. Now we just have to customize the + ** details of pIdxInfo for the current invocation and pass it to + ** xBestIndex. + */ + + /* The module name must be defined */ + assert( pTab->azModuleArg && pTab->azModuleArg[0] ); + if( pTab->pVtab==0 ){ + sqlite3ErrorMsg(pParse, "undefined module %s for table %s", + pTab->azModuleArg[0], pTab->zName); + return 0.0; + } + + /* Set the aConstraint[].usable fields and initialize all + ** output variables to zero. + ** + ** aConstraint[].usable is true for constraints where the right-hand + ** side contains only references to tables to the left of the current + ** table. In other words, if the constraint is of the form: + ** + ** column = expr + ** + ** and we are evaluating a join, then the constraint on column is + ** only valid if all tables referenced in expr occur to the left + ** of the table containing column. + ** + ** The aConstraints[] array contains entries for all constraints + ** on the current table. That way we only have to compute it once + ** even though we might try to pick the best index multiple times. + ** For each attempt at picking an index, the order of tables in the + ** join might be different so we have to recompute the usable flag + ** each time. + */ + pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; + pUsage = pIdxInfo->aConstraintUsage; + for(i=0; inConstraint; i++, pIdxCons++){ + j = pIdxCons->iTermOffset; + pTerm = &pWC->a[j]; + pIdxCons->usable = (pTerm->prereqRight & notReady)==0; + } + memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint); + if( pIdxInfo->needToFreeIdxStr ){ + sqlite3_free(pIdxInfo->idxStr); + } + pIdxInfo->idxStr = 0; + pIdxInfo->idxNum = 0; + pIdxInfo->needToFreeIdxStr = 0; + pIdxInfo->orderByConsumed = 0; + pIdxInfo->estimatedCost = SQLITE_BIG_DBL / 2.0; + nOrderBy = pIdxInfo->nOrderBy; + if( pIdxInfo->nOrderBy && !orderByUsable ){ + *(int*)&pIdxInfo->nOrderBy = 0; + } + + sqlite3SafetyOff(pParse->db); + TRACE(("xBestIndex for %s\n", pTab->zName)); + TRACE_IDX_INPUTS(pIdxInfo); + rc = pTab->pVtab->pModule->xBestIndex(pTab->pVtab, pIdxInfo); + TRACE_IDX_OUTPUTS(pIdxInfo); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_NOMEM ){ + sqlite3FailedMalloc(); + }else { + sqlite3ErrorMsg(pParse, "%s", sqlite3ErrStr(rc)); + } + sqlite3SafetyOn(pParse->db); + }else{ + rc = sqlite3SafetyOn(pParse->db); + } + *(int*)&pIdxInfo->nOrderBy = nOrderBy; + return pIdxInfo->estimatedCost; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + /* ** Find the best index for accessing a particular table. Return a pointer ** to the index, flags that describe how the index should be used, the @@ -922,6 +1314,7 @@ static double bestIndex( int rev; /* True to scan in reverse order */ int flags; /* Flags associated with pProbe */ int nEq; /* Number of == or IN constraints */ + int eqTermMask; /* Mask of valid equality operators */ double cost; /* Cost of using pProbe */ TRACE(("bestIndex: tbl=%s notReady=%x\n", pSrc->pTab->zName, notReady)); @@ -936,7 +1329,7 @@ static double bestIndex( */ if( pProbe==0 && findTerm(pWC, iCur, -1, 0, WO_EQ|WO_IN|WO_LT|WO_LE|WO_GT|WO_GE,0)==0 && - (pOrderBy==0 || !sortableByRowid(iCur, pOrderBy, &rev)) ){ + (pOrderBy==0 || !sortableByRowid(iCur, pOrderBy, pWC->pMaskSet, &rev)) ){ *pFlags = 0; *ppIndex = 0; *pnEq = 0; @@ -998,7 +1391,7 @@ static double bestIndex( /* If the table scan does not satisfy the ORDER BY clause, increase ** the cost by NlogN to cover the expense of sorting. */ if( pOrderBy ){ - if( sortableByRowid(iCur, pOrderBy, &rev) ){ + if( sortableByRowid(iCur, pOrderBy, pWC->pMaskSet, &rev) ){ flags |= WHERE_ORDERBY|WHERE_ROWID_RANGE; if( rev ){ flags |= WHERE_REVERSE; @@ -1013,6 +1406,17 @@ static double bestIndex( bestFlags = flags; } + /* If the pSrc table is the right table of a LEFT JOIN then we may not + ** use an index to satisfy IS NULL constraints on that table. This is + ** because columns might end up being NULL if the table does not match - + ** a circumstance which the index cannot help us discover. Ticket #2177. + */ + if( (pSrc->jointype & JT_LEFT)!=0 ){ + eqTermMask = WO_EQ|WO_IN; + }else{ + eqTermMask = WO_EQ|WO_IN|WO_ISNULL; + } + /* Look at each index. */ for(; pProbe; pProbe=pProbe->pNext){ @@ -1027,14 +1431,14 @@ static double bestIndex( flags = 0; for(i=0; inColumn; i++){ int j = pProbe->aiColumn[i]; - pTerm = findTerm(pWC, iCur, j, notReady, WO_EQ|WO_IN, pProbe); + pTerm = findTerm(pWC, iCur, j, notReady, eqTermMask, pProbe); if( pTerm==0 ) break; flags |= WHERE_COLUMN_EQ; if( pTerm->eOperator & WO_IN ){ Expr *pExpr = pTerm->pExpr; flags |= WHERE_COLUMN_IN; if( pExpr->pSelect!=0 ){ - inMultiplier *= 100; + inMultiplier *= 25; }else if( pExpr->pList!=0 ){ inMultiplier *= pExpr->pList->nExpr + 1; } @@ -1071,7 +1475,7 @@ static double bestIndex( */ if( pOrderBy ){ if( (flags & WHERE_COLUMN_IN)==0 && - isSortingIndex(pParse,pProbe,iCur,pOrderBy,nEq,&rev) ){ + isSortingIndex(pParse,pWC->pMaskSet,pProbe,iCur,pOrderBy,nEq,&rev) ){ if( flags==0 ){ flags = WHERE_COLUMN_RANGE; } @@ -1121,7 +1525,7 @@ static double bestIndex( *ppIndex = bestIdx; TRACE(("best index is %s, cost=%.9g, flags=%x, nEq=%d\n", bestIdx ? bestIdx->zName : "(none)", lowestCost, bestFlags, bestNEq)); - *pFlags = bestFlags; + *pFlags = bestFlags | eqTermMask; *pnEq = bestNEq; return lowestCost; } @@ -1166,30 +1570,18 @@ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){ } /* -** Generate code that builds a probe for an index. Details: -** -** * Check the top nColumn entries on the stack. If any -** of those entries are NULL, jump immediately to brk, -** which is the loop exit, since no index entry will match -** if any part of the key is NULL. Pop (nColumn+nExtra) -** elements from the stack. -** -** * Construct a probe entry from the top nColumn entries in -** the stack with affinities appropriate for index pIdx. -** Only nColumn elements are popped from the stack in this case -** (by OP_MakeRecord). +** Generate code that builds a probe for an index. ** +** There should be nColumn values on the stack. The index +** to be probed is pIdx. Pop the values from the stack and +** replace them all with a single record that is the index +** problem. */ static void buildIndexProbe( - Vdbe *v, - int nColumn, - int nExtra, - int brk, - Index *pIdx + Vdbe *v, /* Generate code into this VM */ + int nColumn, /* The number of columns to check for NULL */ + Index *pIdx /* Index that we will be searching */ ){ - sqlite3VdbeAddOp(v, OP_NotNull, -nColumn, sqlite3VdbeCurrentAddr(v)+3); - sqlite3VdbeAddOp(v, OP_Pop, nColumn+nExtra, 0); - sqlite3VdbeAddOp(v, OP_Goto, 0, brk); sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0); sqlite3IndexAffinityStr(v, pIdx); } @@ -1213,28 +1605,29 @@ static void codeEqualityTerm( WhereLevel *pLevel /* When level of the FROM clause we are working on */ ){ Expr *pX = pTerm->pExpr; - if( pX->op!=TK_IN ){ - assert( pX->op==TK_EQ ); + Vdbe *v = pParse->pVdbe; + if( pX->op==TK_EQ ){ sqlite3ExprCode(pParse, pX->pRight); + }else if( pX->op==TK_ISNULL ){ + sqlite3VdbeAddOp(v, OP_Null, 0, 0); #ifndef SQLITE_OMIT_SUBQUERY }else{ int iTab; int *aIn; - Vdbe *v = pParse->pVdbe; + assert( pX->op==TK_IN ); sqlite3CodeSubselect(pParse, pX); iTab = pX->iTable; - sqlite3VdbeAddOp(v, OP_Rewind, iTab, brk); + sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0); VdbeComment((v, "# %.*s", pX->span.n, pX->span.z)); pLevel->nIn++; sqliteReallocOrFree((void**)&pLevel->aInLoop, - sizeof(pLevel->aInLoop[0])*3*pLevel->nIn); + sizeof(pLevel->aInLoop[0])*2*pLevel->nIn); aIn = pLevel->aInLoop; if( aIn ){ - aIn += pLevel->nIn*3 - 3; - aIn[0] = OP_Next; - aIn[1] = iTab; - aIn[2] = sqlite3VdbeAddOp(v, OP_Column, iTab, 0); + aIn += pLevel->nIn*2 - 2; + aIn[0] = iTab; + aIn[1] = sqlite3VdbeAddOp(v, OP_Column, iTab, 0); }else{ pLevel->nIn = 0; } @@ -1294,17 +1687,20 @@ static void codeAllEqualityTerms( /* Evaluate the equality constraints */ - for(j=0; jnColumn; j++){ + assert( pIdx->nColumn>=nEq ); + for(j=0; jaiColumn[j]; - pTerm = findTerm(pWC, iCur, k, notReady, WO_EQ|WO_IN, pIdx); + pTerm = findTerm(pWC, iCur, k, notReady, pLevel->flags, pIdx); if( pTerm==0 ) break; assert( (pTerm->flags & TERM_CODED)==0 ); codeEqualityTerm(pParse, pTerm, brk, pLevel); + if( (pTerm->eOperator & WO_ISNULL)==0 ){ + sqlite3VdbeAddOp(v, OP_IsNull, termsInMem ? -1 : -(j+1), brk); + } if( termsInMem ){ sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem+j+1, 1); } } - assert( j==nEq ); /* Make sure all the constraint values are on the top of the stack */ @@ -1328,6 +1724,25 @@ static int nQPlan = 0; /* Next free slow in _query_plan[] */ #endif /* SQLITE_TEST */ +/* +** Free a WhereInfo structure +*/ +static void whereInfoFree(WhereInfo *pWInfo){ + if( pWInfo ){ + int i; + for(i=0; inLevel; i++){ + sqlite3_index_info *pInfo = pWInfo->a[i].pIdxInfo; + if( pInfo ){ + if( pInfo->needToFreeIdxStr ){ + sqlite3_free(pInfo->idxStr); + } + sqliteFree(pInfo); + } + } + sqliteFree(pWInfo); + } +} + /* ** Generate the beginning of the loop used for WHERE clause processing. @@ -1448,7 +1863,7 @@ WhereInfo *sqlite3WhereBegin( ** subexpression is separated by an AND operator. */ initMaskSet(&maskSet); - whereClauseInit(&wc, pParse); + whereClauseInit(&wc, pParse, &maskSet); whereSplit(&wc, pWhere, TK_AND); /* Allocate and initialize the WhereInfo structure that will become the @@ -1458,6 +1873,7 @@ WhereInfo *sqlite3WhereBegin( if( sqlite3MallocFailed() ){ goto whereBeginNoMem; } + pWInfo->nLevel = pTabList->nSrc; pWInfo->pParse = pParse; pWInfo->pTabList = pTabList; pWInfo->iBreak = sqlite3VdbeMakeLabel(v); @@ -1478,7 +1894,7 @@ WhereInfo *sqlite3WhereBegin( for(i=0; inSrc; i++){ createMask(&maskSet, pTabList->a[i].iCursor); } - exprAnalyzeAll(pTabList, &maskSet, &wc); + exprAnalyzeAll(pTabList, &wc); if( sqlite3MallocFailed() ){ goto whereBeginNoMem; } @@ -1515,23 +1931,41 @@ WhereInfo *sqlite3WhereBegin( int bestJ = 0; /* The value of j */ Bitmask m; /* Bitmask value for j or bestJ */ int once = 0; /* True when first table is seen */ + sqlite3_index_info *pIndex; /* Current virtual index */ lowestCost = SQLITE_BIG_DBL; for(j=iFrom, pTabItem=&pTabList->a[j]; jnSrc; j++, pTabItem++){ - if( once && - ((pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0 - || (j>0 && (pTabItem[-1].jointype & (JT_LEFT|JT_CROSS))!=0)) - ){ - break; - } + int doNotReorder; /* True if this table should not be reordered */ + + doNotReorder = (pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0; + if( once && doNotReorder ) break; m = getMask(&maskSet, pTabItem->iCursor); if( (m & notReady)==0 ){ if( j==iFrom ) iFrom++; continue; } - cost = bestIndex(pParse, &wc, pTabItem, notReady, - (i==0 && ppOrderBy) ? *ppOrderBy : 0, - &pIdx, &flags, &nEq); + assert( pTabItem->pTab ); +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTabItem->pTab) ){ + sqlite3_index_info **ppIdxInfo = &pWInfo->a[j].pIdxInfo; + cost = bestVirtualIndex(pParse, &wc, pTabItem, notReady, + ppOrderBy ? *ppOrderBy : 0, i==0, + ppIdxInfo); + flags = WHERE_VIRTUALTABLE; + pIndex = *ppIdxInfo; + if( pIndex && pIndex->orderByConsumed ){ + flags = WHERE_VIRTUALTABLE | WHERE_ORDERBY; + } + pIdx = 0; + nEq = 0; + }else +#endif + { + cost = bestIndex(pParse, &wc, pTabItem, notReady, + (i==0 && ppOrderBy) ? *ppOrderBy : 0, + &pIdx, &flags, &nEq); + pIndex = 0; + } if( costpBestIdx = pIndex; } + if( doNotReorder ) break; } TRACE(("*** Optimizer choose table %d for loop %d\n", bestJ, pLevel-pWInfo->a)); @@ -1573,7 +2009,6 @@ WhereInfo *sqlite3WhereBegin( ** searching those tables. */ sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */ - pLevel = pWInfo->a; for(i=0, pLevel=pWInfo->a; inSrc; i++, pLevel++){ Table *pTab; /* Table to open */ Index *pIx; /* Index used to access pTab (if any) */ @@ -1593,13 +2028,29 @@ WhereInfo *sqlite3WhereBegin( }else if( pLevel->flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){ zMsg = sqlite3MPrintf("%z USING PRIMARY KEY", zMsg); } +#ifndef SQLITE_OMIT_VIRTUALTABLE + else if( pLevel->pBestIdx ){ + sqlite3_index_info *pBestIdx = pLevel->pBestIdx; + zMsg = sqlite3MPrintf("%z VIRTUAL TABLE INDEX %d:%s", zMsg, + pBestIdx->idxNum, pBestIdx->idxStr); + } +#endif + if( pLevel->flags & WHERE_ORDERBY ){ + zMsg = sqlite3MPrintf("%z ORDER BY", zMsg); + } sqlite3VdbeOp3(v, OP_Explain, i, pLevel->iFrom, zMsg, P3_DYNAMIC); } #endif /* SQLITE_OMIT_EXPLAIN */ pTabItem = &pTabList->a[pLevel->iFrom]; pTab = pTabItem->pTab; iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - if( pTab->isTransient || pTab->pSelect ) continue; + if( pTab->isEphem || pTab->pSelect ) continue; +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( pLevel->pBestIdx ){ + int iCur = pTabItem->iCursor; + sqlite3VdbeOp3(v, OP_VOpen, iCur, 0, (const char*)pTab->pVtab, P3_VTAB); + }else +#endif if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){ sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, OP_OpenRead); if( pTab->nCol<(sizeof(Bitmask)*8) ){ @@ -1621,7 +2072,9 @@ WhereInfo *sqlite3WhereBegin( sqlite3VdbeOp3(v, OP_OpenRead, iIdxCur, pIx->tnum, (char*)pKey, P3_KEYINFO_HANDOFF); } - if( (pLevel->flags & WHERE_IDX_ONLY)!=0 ){ + if( (pLevel->flags & (WHERE_IDX_ONLY|WHERE_COLUMN_RANGE))!=0 ){ + /* Only call OP_SetNumColumns on the index if we might later use + ** OP_Column on the index. */ sqlite3VdbeAddOp(v, OP_SetNumColumns, iIdxCur, pIx->nColumn+1); } sqlite3CodeVerifySchema(pParse, iDb); @@ -1660,13 +2113,54 @@ WhereInfo *sqlite3WhereBegin( ** initialize a memory cell that records if this table matches any ** row of the left table of the join. */ - if( pLevel->iFrom>0 && (pTabItem[-1].jointype & JT_LEFT)!=0 ){ + if( pLevel->iFrom>0 && (pTabItem[0].jointype & JT_LEFT)!=0 ){ if( !pParse->nMem ) pParse->nMem++; pLevel->iLeftJoin = pParse->nMem++; sqlite3VdbeAddOp(v, OP_MemInt, 0, pLevel->iLeftJoin); VdbeComment((v, "# init LEFT JOIN no-match flag")); } +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( pLevel->pBestIdx ){ + /* Case 0: The table is a virtual-table. Use the VFilter and VNext + ** to access the data. + */ + int j; + sqlite3_index_info *pBestIdx = pLevel->pBestIdx; + int nConstraint = pBestIdx->nConstraint; + struct sqlite3_index_constraint_usage *aUsage = + pBestIdx->aConstraintUsage; + const struct sqlite3_index_constraint *aConstraint = + pBestIdx->aConstraint; + + for(j=1; j<=nConstraint; j++){ + int k; + for(k=0; kpRight); + break; + } + } + if( k==nConstraint ) break; + } + sqlite3VdbeAddOp(v, OP_Integer, j-1, 0); + sqlite3VdbeAddOp(v, OP_Integer, pBestIdx->idxNum, 0); + sqlite3VdbeOp3(v, OP_VFilter, iCur, brk, pBestIdx->idxStr, + pBestIdx->needToFreeIdxStr ? P3_MPRINTF : P3_STATIC); + pBestIdx->needToFreeIdxStr = 0; + for(j=0; jnConstraint; j++){ + if( aUsage[j].omit ){ + int iTerm = aConstraint[j].iTermOffset; + disableTerm(pLevel, &wc.a[iTerm]); + } + } + pLevel->op = OP_VNext; + pLevel->p1 = iCur; + pLevel->p2 = sqlite3VdbeCurrentAddr(v); + }else +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + if( pLevel->flags & WHERE_ROWID_EQ ){ /* Case 1: We can directly reference a single row using an ** equality comparison against the ROWID field. Or @@ -1753,7 +2247,6 @@ WhereInfo *sqlite3WhereBegin( int btmEq=0; /* True if btm limit uses ==. False if strictly > */ int topOp, btmOp; /* Operators for the top and bottom search bounds */ int testOp; - int nNotNull; /* Number of rows of index that must be non-NULL */ int topLimit = (pLevel->flags & WHERE_TOP_LIMIT)!=0; int btmLimit = (pLevel->flags & WHERE_BTM_LIMIT)!=0; @@ -1775,7 +2268,6 @@ WhereInfo *sqlite3WhereBegin( ** operator and the top bound is a < or <= operator. For a descending ** index the operators are reversed. */ - nNotNull = nEq + topLimit; if( pIdx->aSortOrder[nEq]==SQLITE_SO_ASC ){ topOp = WO_LT|WO_LE; btmOp = WO_GT|WO_GE; @@ -1800,6 +2292,7 @@ WhereInfo *sqlite3WhereBegin( pX = pTerm->pExpr; assert( (pTerm->flags & TERM_CODED)==0 ); sqlite3ExprCode(pParse, pX->pRight); + sqlite3VdbeAddOp(v, OP_IsNull, -(nEq+1), brk); topEq = pTerm->eOperator & (WO_LE|WO_GE); disableTerm(pLevel, pTerm); testOp = OP_IdxGE; @@ -1810,7 +2303,7 @@ WhereInfo *sqlite3WhereBegin( if( testOp!=OP_Noop ){ int nCol = nEq + topLimit; pLevel->iMem = pParse->nMem++; - buildIndexProbe(v, nCol, nEq, brk, pIdx); + buildIndexProbe(v, nCol, pIdx); if( bRev ){ int op = topEq ? OP_MoveLe : OP_MoveLt; sqlite3VdbeAddOp(v, op, iIdxCur, brk); @@ -1838,6 +2331,7 @@ WhereInfo *sqlite3WhereBegin( pX = pTerm->pExpr; assert( (pTerm->flags & TERM_CODED)==0 ); sqlite3ExprCode(pParse, pX->pRight); + sqlite3VdbeAddOp(v, OP_IsNull, -(nEq+1), brk); btmEq = pTerm->eOperator & (WO_LE|WO_GE); disableTerm(pLevel, pTerm); }else{ @@ -1845,7 +2339,7 @@ WhereInfo *sqlite3WhereBegin( } if( nEq>0 || btmLimit ){ int nCol = nEq + btmLimit; - buildIndexProbe(v, nCol, 0, brk, pIdx); + buildIndexProbe(v, nCol, pIdx); if( bRev ){ pLevel->iMem = pParse->nMem++; sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1); @@ -1872,8 +2366,10 @@ WhereInfo *sqlite3WhereBegin( sqlite3VdbeChangeP3(v, -1, "+", P3_STATIC); } } - sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0); - sqlite3VdbeAddOp(v, OP_IdxIsNull, nNotNull, cont); + if( topLimit | btmLimit ){ + sqlite3VdbeAddOp(v, OP_Column, iIdxCur, nEq); + sqlite3VdbeAddOp(v, OP_IsNull, 1, cont); + } if( !omitTable ){ sqlite3VdbeAddOp(v, OP_IdxRowid, iIdxCur, 0); sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0); @@ -1899,7 +2395,7 @@ WhereInfo *sqlite3WhereBegin( /* Generate a single key that will be used to both start and terminate ** the search */ - buildIndexProbe(v, nEq, 0, brk, pIdx); + buildIndexProbe(v, nEq, pIdx); sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 0); /* Generate code (1) to move to the first matching element of the table. @@ -1920,8 +2416,6 @@ WhereInfo *sqlite3WhereBegin( sqlite3VdbeOp3(v, OP_IdxGE, iIdxCur, brk, "+", P3_STATIC); pLevel->op = OP_Next; } - sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0); - sqlite3VdbeAddOp(v, OP_IdxIsNull, nEq, cont); if( !omitTable ){ sqlite3VdbeAddOp(v, OP_IdxRowid, iIdxCur, 0); sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0); @@ -2030,7 +2524,7 @@ WhereInfo *sqlite3WhereBegin( /* Jump here if malloc fails */ whereBeginNoMem: whereClauseClear(&wc); - sqliteFree(pWInfo); + whereInfoFree(pWInfo); return 0; } @@ -2056,8 +2550,9 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ if( pLevel->nIn ){ int *a; int j; - for(j=pLevel->nIn, a=&pLevel->aInLoop[j*3-3]; j>0; j--, a-=3){ - sqlite3VdbeAddOp(v, a[0], a[1], a[2]); + for(j=pLevel->nIn, a=&pLevel->aInLoop[j*2-2]; j>0; j--, a-=2){ + sqlite3VdbeAddOp(v, OP_Next, a[0], a[1]); + sqlite3VdbeJumpHere(v, a[1]-1); } sqliteFree(pLevel->aInLoop); } @@ -2084,7 +2579,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom]; Table *pTab = pTabItem->pTab; assert( pTab!=0 ); - if( pTab->isTransient || pTab->pSelect ) continue; + if( pTab->isEphem || pTab->pSelect ) continue; if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){ sqlite3VdbeAddOp(v, OP_Close, pTabItem->iCursor, 0); } @@ -2131,6 +2626,6 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ /* Final cleanup */ - sqliteFree(pWInfo); + whereInfoFree(pWInfo); return; }