Index: SQLite.Interop/src/alter.c ================================================================== --- SQLite.Interop/src/alter.c +++ SQLite.Interop/src/alter.c @@ -10,11 +10,11 @@ ** ************************************************************************* ** This file contains C code routines that used to generate VDBE code ** that implements the ALTER TABLE command. ** -** $Id: alter.c,v 1.13 2006/01/11 03:22:29 rmsimpson Exp $ +** $Id: alter.c,v 1.14 2006/01/12 20:54:07 rmsimpson Exp $ */ #include "sqliteInt.h" #include /* @@ -265,11 +265,11 @@ Vdbe *v; #ifndef SQLITE_OMIT_TRIGGER char *zWhere = 0; /* Where clause to locate temp triggers */ #endif - if( sqlite3ThreadData()->mallocFailed ) goto exit_rename_table; + if( sqlite3ThreadDataReadOnly()->mallocFailed ) goto exit_rename_table; assert( pSrc->nSrc==1 ); pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase); if( !pTab ) goto exit_rename_table; iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); @@ -499,11 +499,11 @@ int i; int nAlloc; /* Look up the table being altered. */ assert( pParse->pNewTable==0 ); - if( sqlite3ThreadData()->mallocFailed ) goto exit_begin_add_column; + if( sqlite3ThreadDataReadOnly()->mallocFailed ) goto exit_begin_add_column; pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase); if( !pTab ) goto exit_begin_add_column; /* Make sure this is not an attempt to ALTER a view. */ if( pTab->pSelect ){ Index: SQLite.Interop/src/analyze.c ================================================================== --- SQLite.Interop/src/analyze.c +++ SQLite.Interop/src/analyze.c @@ -9,11 +9,11 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code associated with the ANALYZE command. ** -** @(#) $Id: analyze.c,v 1.7 2006/01/11 03:22:29 rmsimpson Exp $ +** @(#) $Id: analyze.c,v 1.8 2006/01/12 20:54:07 rmsimpson Exp $ */ #ifndef SQLITE_OMIT_ANALYZE #include "sqliteInt.h" /* Index: SQLite.Interop/src/attach.c ================================================================== --- SQLite.Interop/src/attach.c +++ SQLite.Interop/src/attach.c @@ -9,11 +9,11 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the ATTACH and DETACH commands. ** -** $Id: attach.c,v 1.13 2006/01/11 03:22:29 rmsimpson Exp $ +** $Id: attach.c,v 1.14 2006/01/12 20:54:07 rmsimpson Exp $ */ #include "sqliteInt.h" /* ** Resolve an expression that was part of an ATTACH or DETACH statement. This @@ -169,11 +169,10 @@ ** If this fails, or if opening the file failed, then close the file and ** remove the entry from the db->aDb[] array. i.e. put everything back the way ** we found it. */ if( rc==SQLITE_OK ){ - db->flags &= ~SQLITE_Initialized; sqlite3SafetyOn(db); rc = sqlite3Init(db, &zErrDyn); sqlite3SafetyOff(db); } if( rc ){ @@ -271,11 +270,11 @@ Vdbe *v; FuncDef *pFunc; sqlite3* db = pParse->db; #ifndef SQLITE_OMIT_AUTHORIZATION - assert( sqlite3ThreadData()->mallocFailed || pAuthArg ); + assert( sqlite3ThreadDataReadOnly()->mallocFailed || pAuthArg ); if( pAuthArg ){ char *zAuthArg = sqlite3NameFromToken(&pAuthArg->span); if( !zAuthArg ){ goto attach_end; } @@ -302,11 +301,11 @@ v = sqlite3GetVdbe(pParse); sqlite3ExprCode(pParse, pFilename); sqlite3ExprCode(pParse, pDbname); sqlite3ExprCode(pParse, pKey); - assert(v || sqlite3ThreadData()->mallocFailed); + assert(v || sqlite3ThreadDataReadOnly()->mallocFailed); if( v ){ sqlite3VdbeAddOp(v, OP_Function, 0, nFunc); pFunc = sqlite3FindFunction(db, zFunc, strlen(zFunc), nFunc, SQLITE_UTF8,0); sqlite3VdbeChangeP3(v, -1, (char *)pFunc, P3_FUNCDEF); Index: SQLite.Interop/src/auth.c ================================================================== --- SQLite.Interop/src/auth.c +++ SQLite.Interop/src/auth.c @@ -12,11 +12,11 @@ ** This file contains code used to implement the sqlite3_set_authorizer() ** API. This facility is an optional feature of the library. Embedded ** systems that do not need this facility may omit it by recompiling ** the library with -DSQLITE_OMIT_AUTHORIZATION=1 ** -** $Id: auth.c,v 1.13 2006/01/11 03:22:29 rmsimpson Exp $ +** $Id: auth.c,v 1.14 2006/01/12 20:54:07 rmsimpson Exp $ */ #include "sqliteInt.h" /* ** All of the code in this file may be omitted by defining a single Index: SQLite.Interop/src/btree.c ================================================================== --- SQLite.Interop/src/btree.c +++ SQLite.Interop/src/btree.c @@ -7,11 +7,11 @@ ** 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. ** ************************************************************************* -** $Id: btree.c,v 1.15 2006/01/11 03:22:29 rmsimpson Exp $ +** $Id: btree.c,v 1.16 2006/01/12 20:54:07 rmsimpson Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to ** ** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3: @@ -555,11 +555,11 @@ ** 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( sqlite3ThreadData()->useSharedData ){ + if( sqlite3ThreadDataReadOnly()->useSharedData ){ for(p=pBt->pCursor; p; p=p->pNext){ if( p!=pExcept && p->pgnoRoot==iRoot && p->eState==CURSOR_VALID ){ int rc = saveCursorPosition(p); if( SQLITE_OK!=rc ){ return rc; @@ -582,11 +582,11 @@ ** and the cursor state set to CURSOR_INVALID. */ static int restoreCursorPosition(BtCursor *pCur, int doSeek){ int rc = SQLITE_OK; if( pCur->eState==CURSOR_REQUIRESEEK ){ - assert( sqlite3ThreadData()->useSharedData ); + assert( sqlite3ThreadDataReadOnly()->useSharedData ); if( doSeek ){ rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, &pCur->skip); }else{ pCur->eState = CURSOR_INVALID; } @@ -608,11 +608,11 @@ static int queryTableLock(Btree *p, Pgno iTab, u8 eLock){ BtShared *pBt = p->pBt; BtLock *pIter; /* This is a no-op if the shared-cache is not enabled */ - if( 0==sqlite3ThreadData()->useSharedData ){ + if( 0==sqlite3ThreadDataReadOnly()->useSharedData ){ return SQLITE_OK; } /* This (along with lockTable()) is where the ReadUncommitted flag is ** dealt with. If the caller is querying for a read-lock and the flag is @@ -656,11 +656,11 @@ BtShared *pBt = p->pBt; BtLock *pLock = 0; BtLock *pIter; /* This is a no-op if the shared-cache is not enabled */ - if( 0==sqlite3ThreadData()->useSharedData ){ + if( 0==sqlite3ThreadDataReadOnly()->useSharedData ){ return SQLITE_OK; } assert( SQLITE_OK==queryTableLock(p, iTable, eLock) ); @@ -721,11 +721,11 @@ /* If the shared-cache extension is not enabled, there should be no ** locks in the BtShared.pLock list, making this procedure a no-op. Assert ** that this is the case. */ - assert( sqlite3ThreadData()->useSharedData || 0==*ppIter ); + assert( sqlite3ThreadDataReadOnly()->useSharedData || 0==*ppIter ); while( *ppIter ){ BtLock *pLock = *ppIter; if( pLock->pBtree==p ){ *ppIter = pLock->pNext; @@ -1544,12 +1544,12 @@ BtShared *pBt; /* Shared part of btree structure */ Btree *p; /* Handle to return */ int rc; int nReserve; unsigned char zDbHeader[100]; -#ifndef SQLITE_OMIT_SHARED_CACHE - ThreadData *pTsd = sqlite3ThreadData(); +#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) + const ThreadData *pTsdro; #endif /* Set the variable isMemdb to true for an in-memory database, or ** false for a file-based database. This symbol is only required if ** either of the shared-data or autovacuum features are compiled @@ -1570,17 +1570,19 @@ p->inTrans = TRANS_NONE; p->pSqlite = pSqlite; /* Try to find an existing Btree structure opened on zFilename. */ #if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) - if( pTsd->useSharedData && zFilename && !isMemdb ){ + pTsdro = sqlite3ThreadDataReadOnly(); + if( pTsdro->useSharedData && zFilename && !isMemdb ){ char *zFullPathname = sqlite3OsFullPathname(zFilename); if( !zFullPathname ){ sqliteFree(p); return SQLITE_NOMEM; } - for(pBt=pTsd->pBtree; pBt; pBt=pBt->pNext){ + for(pBt=pTsdro->pBtree; pBt; pBt=pBt->pNext){ + assert( pBt->nRef>0 ); if( 0==strcmp(zFullPathname, sqlite3pager_filename(pBt->pPager)) ){ p->pBt = pBt; *ppBtree = p; pBt->nRef++; sqliteFree(zFullPathname); @@ -1657,13 +1659,13 @@ assert( (pBt->pageSize & 7)==0 ); /* 8-byte alignment of pageSize */ sqlite3pager_set_pagesize(pBt->pPager, pBt->pageSize); #ifndef SQLITE_OMIT_SHARED_CACHE /* Add the new btree to the linked list starting at ThreadData.pBtree */ - if( pTsd->useSharedData && zFilename && !isMemdb ){ - pBt->pNext = pTsd->pBtree; - pTsd->pBtree = pBt; + if( pTsdro->useSharedData && zFilename && !isMemdb ){ + pBt->pNext = pTsdro->pBtree; + sqlite3ThreadData()->pBtree = pBt; } #endif pBt->nRef = 1; *ppBtree = p; return SQLITE_OK; @@ -1675,11 +1677,11 @@ int sqlite3BtreeClose(Btree *p){ BtShared *pBt = p->pBt; BtCursor *pCur; #ifndef SQLITE_OMIT_SHARED_CACHE - ThreadData *pTsd = sqlite3ThreadData(); + ThreadData *pTsd; #endif /* Drop any table-locks */ unlockAllTables(p); @@ -1705,10 +1707,11 @@ if( pBt->nRef ){ return SQLITE_OK; } /* Remove the shared-btree from the thread wide list */ + pTsd = sqlite3ThreadData(); if( pTsd->pBtree==pBt ){ pTsd->pBtree = pBt->pNext; }else{ BtShared *pPrev; for(pPrev=pTsd->pBtree; pPrev && pPrev->pNext!=pBt; pPrev=pPrev->pNext); @@ -3321,22 +3324,30 @@ pageIntegrity(pPage); while( lwr<=upr ){ void *pCellKey; i64 nCellKey; pCur->idx = (lwr+upr)/2; - pCur->info.nSize = 0; - sqlite3BtreeKeySize(pCur, &nCellKey); if( pPage->intKey ){ + u8 *pCell = findCell(pPage, pCur->idx); + pCell += pPage->childPtrSize; + if( pPage->hasData ){ + int dummy; + pCell += getVarint32(pCell, &dummy); + } + getVarint(pCell, &nCellKey); + pCur->info.nSize = 0; if( nCellKeynKey ){ c = +1; }else{ c = 0; } }else{ int available; + parseCell(pPage, pCur->idx, &pCur->info); + nCellKey = pCur->info.nKey; pCellKey = (void *)fetchPayload(pCur, &available, 0); if( available>=nCellKey ){ c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey); }else{ pCellKey = sqliteMallocRaw( nCellKey ); @@ -6496,5 +6507,33 @@ rc = lockTable(p, iTab, lockType); } #endif return rc; } + +/* +** The following debugging interface has to be in this file (rather +** than in, for example, test1.c) so that it can get access to +** the definition of BtShared. +*/ +#if defined(SQLITE_TEST) && defined(TCLSH) +#include +int sqlite3_shared_cache_report( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + const ThreadData *pTd = sqlite3ThreadDataReadOnly(); + if( pTd->useSharedData ){ + BtShared *pBt; + Tcl_Obj *pRet = Tcl_NewObj(); + for(pBt=pTd->pBtree; pBt; pBt=pBt->pNext){ + const char *zFile = sqlite3pager_filename(pBt->pPager); + Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj(zFile, -1)); + Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(pBt->nRef)); + } + Tcl_SetObjResult(interp, pRet); + } + return TCL_OK; +} +#endif Index: SQLite.Interop/src/btree.h ================================================================== --- SQLite.Interop/src/btree.h +++ SQLite.Interop/src/btree.h @@ -11,11 +11,11 @@ ************************************************************************* ** This header file defines the interface that the sqlite B-Tree file ** subsystem. See comments in the source code for a detailed description ** of what each interface routine does. ** -** @(#) $Id: btree.h,v 1.14 2006/01/11 03:22:29 rmsimpson Exp $ +** @(#) $Id: btree.h,v 1.15 2006/01/12 20:54:07 rmsimpson Exp $ */ #ifndef _BTREE_H_ #define _BTREE_H_ /* TODO: This definition is just included so other modules compile. It Index: SQLite.Interop/src/build.c ================================================================== --- SQLite.Interop/src/build.c +++ SQLite.Interop/src/build.c @@ -20,11 +20,11 @@ ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** -** $Id: build.c,v 1.13 2006/01/11 03:22:29 rmsimpson Exp $ +** $Id: build.c,v 1.14 2006/01/12 20:54:07 rmsimpson Exp $ */ #include "sqliteInt.h" #include /* @@ -64,13 +64,12 @@ const char *zName ){ int i; int nBytes; TableLock *p; - ThreadData *pTsd = sqlite3ThreadData(); - if( 0==pTsd->useSharedData || iDb<0 ){ + if( 0==sqlite3ThreadDataReadOnly()->useSharedData || iDb<0 ){ return; } for(i=0; inTableLock; i++){ p = &pParse->aTableLock[i]; @@ -96,11 +95,11 @@ ** statement (configured by calls to sqlite3TableLock()). */ static void codeTableLocks(Parse *pParse){ int i; Vdbe *pVdbe; - assert( sqlite3ThreadData()->useSharedData || pParse->nTableLock==0 ); + assert( sqlite3ThreadDataReadOnly()->useSharedData || pParse->nTableLock==0 ); if( 0==(pVdbe = sqlite3GetVdbe(pParse)) ){ return; } @@ -129,11 +128,11 @@ */ void sqlite3FinishCoding(Parse *pParse){ sqlite3 *db; Vdbe *v; - if( sqlite3ThreadData()->mallocFailed ) return; + if( sqlite3ThreadDataReadOnly()->mallocFailed ) return; if( pParse->nested ) return; if( !pParse->pVdbe ){ if( pParse->rc==SQLITE_OK && pParse->nErr ){ pParse->rc = SQLITE_ERROR; } @@ -253,11 +252,10 @@ */ Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){ Table *p = 0; int i; assert( zName!=0 ); - assert( (db->flags & SQLITE_Initialized) || db->init.busy ); for(i=OMIT_TEMPDB; inDb; i++){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue; p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName, strlen(zName)+1); if( p ) break; @@ -309,11 +307,10 @@ ** using the ATTACH command. */ Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){ Index *p = 0; int i; - assert( (db->flags & SQLITE_Initialized) || db->init.busy ); for(i=OMIT_TEMPDB; inDb; i++){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ Schema *pSchema = db->aDb[j].pSchema; if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue; assert( pSchema || (j==1 && !db->aDb[1].pBt) ); @@ -391,11 +388,10 @@ */ void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){ int i, j; assert( iDb>=0 && iDbnDb ); - db->flags &= ~SQLITE_Initialized; for(i=iDb; inDb; i++){ Db *pDb = &db->aDb[i]; if( pDb->pSchema ){ sqlite3SchemaFree(pDb->pSchema); } @@ -835,19 +831,22 @@ ** indices. Hence, the record number for the table must be allocated ** now. */ if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){ int lbl; + int fileFormat; sqlite3BeginWriteOperation(pParse, 0, iDb); /* If the file format and encoding in the database have not been set, ** set them now. */ sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1); /* file_format */ lbl = sqlite3VdbeMakeLabel(v); sqlite3VdbeAddOp(v, OP_If, 0, lbl); - sqlite3VdbeAddOp(v, OP_Integer, SQLITE_DEFAULT_FILE_FORMAT, 0); + fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ? + 1 : SQLITE_DEFAULT_FILE_FORMAT; + sqlite3VdbeAddOp(v, OP_Integer, fileFormat, 0); sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1); sqlite3VdbeAddOp(v, OP_Integer, ENC(db), 0); sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 4); sqlite3VdbeResolveLabel(v, lbl); @@ -1364,11 +1363,11 @@ Table *p; sqlite3 *db = pParse->db; int iDb; if( (pEnd==0 && pSelect==0) || - pParse->nErr || sqlite3ThreadData()->mallocFailed ) { + pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ) { return; } p = pParse->pNewTable; if( p==0 ) return; @@ -1601,11 +1600,11 @@ ** allocated rather than point to the input string - which means that ** they will persist after the current sqlite3_exec() call returns. */ p->pSelect = sqlite3SelectDup(pSelect); sqlite3SelectDelete(pSelect); - if( sqlite3ThreadData()->mallocFailed ){ + if( sqlite3ThreadDataReadOnly()->mallocFailed ){ return; } if( !pParse->db->init.busy ){ sqlite3ViewGetColumnNames(pParse, p); } @@ -1843,11 +1842,13 @@ Table *pTab; Vdbe *v; sqlite3 *db = pParse->db; int iDb; - if( pParse->nErr || sqlite3ThreadData()->mallocFailed ) goto exit_drop_table; + if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ){ + goto exit_drop_table; + } assert( pName->nSrc==1 ); pTab = sqlite3LocateTable(pParse, pName->a[0].zName, pName->a[0].zDatabase); if( pTab==0 ){ if( noErr ){ @@ -2202,11 +2203,11 @@ struct ExprList_item *pListItem; /* For looping over pList */ int nCol; int nExtra = 0; char *zExtra; - if( pParse->nErr || sqlite3ThreadData()->mallocFailed ){ + if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ){ goto exit_create_index; } /* ** Find the table that is to be indexed. Return early if not found. @@ -2356,11 +2357,11 @@ sizeof(char *)*nCol + /* Index.azColl */ sizeof(u8)*nCol + /* Index.aSortOrder */ nName + 1 + /* Index.zName */ nExtra /* Collation sequence names */ ); - if( sqlite3ThreadData()->mallocFailed ) goto exit_create_index; + if( sqlite3ThreadDataReadOnly()->mallocFailed ) goto exit_create_index; pIndex->aiColumn = (int *)(&pIndex[1]); pIndex->aiRowEst = (int *)(&pIndex->aiColumn[nCol]); pIndex->azColl = (char **)(&pIndex->aiRowEst[nCol+1]); pIndex->aSortOrder = (u8 *)(&pIndex->azColl[nCol]); pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]); @@ -2643,11 +2644,11 @@ Index *pIndex; Vdbe *v; sqlite3 *db = pParse->db; int iDb; - if( pParse->nErr || sqlite3ThreadData()->mallocFailed ){ + if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ){ goto exit_drop_index; } assert( pName->nSrc==1 ); if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto exit_drop_index; @@ -2852,11 +2853,11 @@ ** Assign cursors to all tables in a SrcList */ void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ int i; struct SrcList_item *pItem; - assert(pList || sqlite3ThreadData()->mallocFailed); + assert(pList || sqlite3ThreadDataReadOnly()->mallocFailed); if( pList ){ for(i=0, pItem=pList->a; inSrc; i++, pItem++){ if( pItem->iCursor>=0 ) break; pItem->iCursor = pParse->nTab++; if( pItem->pSelect ){ @@ -2901,11 +2902,11 @@ sqlite3 *db; Vdbe *v; int i; if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return; - if( pParse->nErr || sqlite3ThreadData()->mallocFailed ) return; + if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ) return; if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ) return; v = sqlite3GetVdbe(pParse); if( !v ) return; if( type!=TK_DEFERRED ){ @@ -2922,11 +2923,11 @@ void sqlite3CommitTransaction(Parse *pParse){ sqlite3 *db; Vdbe *v; if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return; - if( pParse->nErr || sqlite3ThreadData()->mallocFailed ) return; + if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ) return; if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ) return; v = sqlite3GetVdbe(pParse); if( v ){ sqlite3VdbeAddOp(v, OP_AutoCommit, 1, 0); @@ -2939,11 +2940,11 @@ void sqlite3RollbackTransaction(Parse *pParse){ sqlite3 *db; Vdbe *v; if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return; - if( pParse->nErr || sqlite3ThreadData()->mallocFailed ) return; + if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ) return; if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ) return; v = sqlite3GetVdbe(pParse); if( v ){ sqlite3VdbeAddOp(v, OP_AutoCommit, 1, 1); @@ -3213,6 +3214,5 @@ sqliteFree(pKey); pKey = 0; } return pKey; } - Index: SQLite.Interop/src/callback.c ================================================================== --- SQLite.Interop/src/callback.c +++ SQLite.Interop/src/callback.c @@ -11,11 +11,11 @@ ************************************************************************* ** ** This file contains functions used to access the internal hash tables ** of user defined functions and collation sequences. ** -** $Id: callback.c,v 1.9 2006/01/11 03:22:29 rmsimpson Exp $ +** $Id: callback.c,v 1.10 2006/01/12 20:54:07 rmsimpson Exp $ */ #include "sqliteInt.h" /* @@ -176,11 +176,12 @@ /* If a malloc() failure occured in sqlite3HashInsert(), it will ** return the pColl pointer to be deleted (because it wasn't added ** to the hash table). */ - assert( !pDel || (sqlite3ThreadData()->mallocFailed && pDel==pColl) ); + assert( !pDel || + (sqlite3ThreadDataReadOnly()->mallocFailed && pDel==pColl) ); sqliteFree(pDel); } } return pColl; } Index: SQLite.Interop/src/complete.c ================================================================== --- SQLite.Interop/src/complete.c +++ SQLite.Interop/src/complete.c @@ -14,11 +14,11 @@ ** This file contains C code that implements the sqlite3_complete() API. ** This code used to be part of the tokenizer.c source file. But by ** separating it out, the code will be automatically omitted from ** static links that do not use it. ** -** $Id: complete.c,v 1.7 2006/01/11 03:22:29 rmsimpson Exp $ +** $Id: complete.c,v 1.8 2006/01/12 20:54:07 rmsimpson Exp $ */ #include "sqliteInt.h" #ifndef SQLITE_OMIT_COMPLETE /* Index: SQLite.Interop/src/date.c ================================================================== --- SQLite.Interop/src/date.c +++ SQLite.Interop/src/date.c @@ -14,11 +14,11 @@ ** ** There is only one exported symbol in this file - the function ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: date.c,v 1.13 2006/01/11 03:22:29 rmsimpson Exp $ +** $Id: date.c,v 1.14 2006/01/12 20:54:07 rmsimpson Exp $ ** ** NOTES: ** ** SQLite processes all times and dates as Julian Day numbers. The ** dates and times are stored as the number of days since noon Index: SQLite.Interop/src/delete.c ================================================================== --- SQLite.Interop/src/delete.c +++ SQLite.Interop/src/delete.c @@ -10,11 +10,11 @@ ** ************************************************************************* ** This file contains C code routines that are called by the parser ** in order to generate code for DELETE FROM statements. ** -** $Id: delete.c,v 1.13 2006/01/11 03:22:29 rmsimpson Exp $ +** $Id: delete.c,v 1.14 2006/01/12 20:54:07 rmsimpson Exp $ */ #include "sqliteInt.h" /* ** Look up every table that is named in pSrc. If any table is not found, @@ -106,11 +106,11 @@ int isView; /* True if attempting to delete from a view */ int triggers_exist = 0; /* True if any triggers exist */ #endif sContext.pParse = 0; - if( pParse->nErr || sqlite3ThreadData()->mallocFailed ){ + if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ){ goto delete_from_cleanup; } db = pParse->db; assert( pTabList->nSrc==1 ); Index: SQLite.Interop/src/experimental.c ================================================================== --- SQLite.Interop/src/experimental.c +++ SQLite.Interop/src/experimental.c @@ -10,11 +10,11 @@ ** ************************************************************************* ** This file contains C code routines that are not a part of the official ** SQLite API. These routines are unsupported. ** -** $Id: experimental.c,v 1.3 2006/01/11 03:22:30 rmsimpson Exp $ +** $Id: experimental.c,v 1.4 2006/01/12 20:54:07 rmsimpson Exp $ */ #include "sqliteInt.h" /* ** Set all the parameters in the compiled SQL statement to NULL. Index: SQLite.Interop/src/expr.c ================================================================== --- SQLite.Interop/src/expr.c +++ SQLite.Interop/src/expr.c @@ -10,11 +10,11 @@ ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.20 2006/01/11 03:22:29 rmsimpson Exp $ +** $Id: expr.c,v 1.21 2006/01/12 20:54:07 rmsimpson Exp $ */ #include "sqliteInt.h" #include /* @@ -261,11 +261,11 @@ ** text between the two given tokens. */ void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){ assert( pRight!=0 ); assert( pLeft!=0 ); - if( !sqlite3ThreadData()->mallocFailed && pRight->z && pLeft->z ){ + if( !sqlite3ThreadDataReadOnly()->mallocFailed && pRight->z && pLeft->z ){ assert( pLeft->dyn==0 || pLeft->z[pLeft->n]==0 ); if( pLeft->dyn==0 && pRight->dyn==0 ){ pExpr->span.z = pLeft->z; pExpr->span.n = pRight->n + (pRight->z - pLeft->z); }else{ @@ -356,11 +356,11 @@ if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){ pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10; sqlite3ReallocOrFree((void**)&pParse->apVarExpr, pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0]) ); } - if( !sqlite3ThreadData()->mallocFailed ){ + if( !sqlite3ThreadDataReadOnly()->mallocFailed ){ assert( pParse->apVarExpr!=0 ); pParse->apVarExpr[pParse->nVarExpr++] = pExpr; } } } @@ -460,11 +460,12 @@ ** expression list. The logic in SELECT processing that determines ** the names of columns in the result set needs this information */ sqlite3TokenCopy(&pNewExpr->span, &pOldExpr->span); } assert( pNewExpr==0 || pNewExpr->span.z!=0 - || pOldExpr->span.z==0 || sqlite3ThreadData()->mallocFailed ); + || pOldExpr->span.z==0 + || sqlite3ThreadDataReadOnly()->mallocFailed ); pItem->zName = sqliteStrDup(pOldItem->zName); pItem->sortOrder = pOldItem->sortOrder; pItem->isAgg = pOldItem->isAgg; pItem->done = 0; } @@ -829,11 +830,11 @@ assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */ zDb = sqlite3NameFromToken(pDbToken); zTab = sqlite3NameFromToken(pTableToken); zCol = sqlite3NameFromToken(pColumnToken); - if( sqlite3ThreadData()->mallocFailed ){ + if( sqlite3ThreadDataReadOnly()->mallocFailed ){ goto lookupname_end; } pExpr->iTable = -1; while( pNC && cnt==0 ){ @@ -1306,11 +1307,11 @@ */ if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->trigStack ){ int mem = pParse->nMem++; sqlite3VdbeAddOp(v, OP_MemLoad, mem, 0); testAddr = sqlite3VdbeAddOp(v, OP_If, 0, 0); - assert( testAddr>0 || sqlite3ThreadData()->mallocFailed ); + assert( testAddr>0 || sqlite3ThreadDataReadOnly()->mallocFailed ); sqlite3VdbeAddOp(v, OP_MemInt, 1, mem); } switch( pExpr->op ){ case TK_IN: { Index: SQLite.Interop/src/func.c ================================================================== --- SQLite.Interop/src/func.c +++ SQLite.Interop/src/func.c @@ -14,11 +14,11 @@ ** ** There is only one exported symbol in this file - the function ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: func.c,v 1.14 2006/01/11 03:22:29 rmsimpson Exp $ +** $Id: func.c,v 1.15 2006/01/12 20:54:07 rmsimpson Exp $ */ #include "sqliteInt.h" #include /* #include */ #include Index: SQLite.Interop/src/hash.c ================================================================== --- SQLite.Interop/src/hash.c +++ SQLite.Interop/src/hash.c @@ -10,11 +10,11 @@ ** ************************************************************************* ** This is the implementation of generic hash-tables ** used in SQLite. ** -** $Id: hash.c,v 1.13 2006/01/11 03:22:29 rmsimpson Exp $ +** $Id: hash.c,v 1.14 2006/01/12 20:54:07 rmsimpson Exp $ */ #include "sqliteInt.h" #include /* Turn bulk memory into a hash table object by initializing the Index: SQLite.Interop/src/hash.h ================================================================== --- SQLite.Interop/src/hash.h +++ SQLite.Interop/src/hash.h @@ -10,11 +10,11 @@ ** ************************************************************************* ** This is the header file for the generic hash-table implemenation ** used in SQLite. ** -** $Id: hash.h,v 1.13 2006/01/11 03:22:29 rmsimpson Exp $ +** $Id: hash.h,v 1.14 2006/01/12 20:54:07 rmsimpson Exp $ */ #ifndef _SQLITE_HASH_H_ #define _SQLITE_HASH_H_ /* Forward declarations of structures. */ Index: SQLite.Interop/src/insert.c ================================================================== --- SQLite.Interop/src/insert.c +++ SQLite.Interop/src/insert.c @@ -10,11 +10,11 @@ ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** -** $Id: insert.c,v 1.13 2006/01/11 03:22:29 rmsimpson Exp $ +** $Id: insert.c,v 1.14 2006/01/12 20:54:07 rmsimpson Exp $ */ #include "sqliteInt.h" /* ** Set P3 of the most recently inserted opcode to a column affinity @@ -223,11 +223,13 @@ #ifndef SQLITE_OMIT_AUTOINCREMENT int counterRowid; /* Memory cell holding rowid of autoinc counter */ #endif - if( pParse->nErr || sqlite3ThreadData()->mallocFailed ) goto insert_cleanup; + if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ){ + goto insert_cleanup; + } db = pParse->db; /* Locate the table into which we will be inserting new information. */ assert( pTabList->nSrc==1 ); @@ -329,11 +331,13 @@ iSelectLoop = sqlite3VdbeCurrentAddr(v); iInsertBlock = sqlite3VdbeMakeLabel(v); /* Resolve the expressions in the SELECT statement and execute it. */ rc = sqlite3Select(pParse, pSelect, SRT_Subroutine, iInsertBlock,0,0,0,0); - if( rc || pParse->nErr || sqlite3ThreadData()->mallocFailed ) goto insert_cleanup; + if( rc || pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ){ + goto insert_cleanup; + } iCleanup = sqlite3VdbeMakeLabel(v); sqlite3VdbeAddOp(v, OP_Goto, 0, iCleanup); assert( pSelect->pEList ); nColumn = pSelect->pEList->nExpr; Index: SQLite.Interop/src/keywordhash.h ================================================================== --- SQLite.Interop/src/keywordhash.h +++ SQLite.Interop/src/keywordhash.h @@ -10,40 +10,40 @@ "FAILIMITFROMFULLGROUPDATEIFIMMEDIATEINSERTINSTEADINTOFFSETISNULL" "JOINORDEREPLACEOUTERESTRICTPRIMARYQUERYRIGHTROLLBACKROWHENUNION" "UNIQUEUSINGVACUUMVALUESVIEWHERE"; 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, + 96, 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, - 0, 63, 19, 0, 105, 36, 104, 0, 108, 74, 0, 0, 33, + 0, 63, 19, 0, 105, 36, 104, 0, 108, 75, 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, - 75, 26, 0, 72, 0, 0, 0, 64, 47, 67, 22, 87, 29, + 74, 26, 0, 72, 0, 0, 0, 64, 47, 67, 22, 87, 29, 69, 86, 0, 1, 0, 9, 101, 58, 18, 0, 112, 82, 99, - 54, 6, 85, 0, 0, 49, 94, 0, 102, 0, 70, 0, 0, - 15, 0, 116, 51, 56, 0, 2, 55, 0, 111, + 55, 6, 85, 0, 0, 49, 94, 0, 102, 0, 70, 0, 0, + 15, 0, 116, 51, 56, 0, 2, 54, 0, 111, }; static const unsigned char aNext[116] = { 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, - 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, - 0, 0, 16, 0, 23, 52, 0, 0, 0, 0, 45, 0, 59, - 0, 0, 0, 0, 0, 0, 0, 0, 73, 42, 0, 24, 60, + 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, + 0, 16, 0, 0, 23, 52, 0, 0, 0, 0, 45, 0, 59, + 0, 0, 0, 0, 0, 0, 0, 0, 43, 73, 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, 0, 0, 0, 0, 39, 95, 98, 0, 0, 100, 0, 32, 0, 14, 27, 78, 0, 57, 89, 0, 35, 0, 62, 0, }; static const unsigned char aLen[116] = { 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, - 4, 6, 3, 7, 6, 7, 5, 13, 2, 2, 5, 5, 6, - 7, 3, 7, 4, 4, 2, 7, 3, 8, 6, 4, 4, 7, - 6, 6, 8, 10, 9, 6, 5, 12, 12, 17, 4, 4, 6, + 4, 6, 7, 3, 6, 7, 5, 13, 2, 2, 5, 5, 6, + 7, 7, 3, 4, 4, 2, 7, 3, 8, 6, 4, 4, 7, + 6, 6, 8, 10, 9, 6, 5, 12, 17, 12, 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, + 6, 7, 4, 6, 2, 3, 6, 4, 5, 7, 5, 8, 7, 5, 5, 8, 3, 4, 5, 6, 5, 6, 6, 4, 5, }; static const unsigned short int aOffset[116] = { 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, @@ -62,22 +62,22 @@ TK_JOIN_KW, TK_ALTER, TK_RAISE, TK_EACH, TK_CHECK, TK_KEY, TK_AFTER, TK_REFERENCES, TK_ESCAPE, TK_ELSE, TK_EXCEPT, TK_TRIGGER, TK_LIKE_KW, TK_EXPLAIN, TK_INITIALLY, TK_ALL, TK_ANALYZE, TK_EXCLUSIVE, TK_EXISTS, TK_STATEMENT, TK_AND, TK_DEFERRABLE, TK_ATTACH, TK_HAVING, TK_LIKE_KW, - TK_BEFORE, TK_FOR, TK_FOREIGN, TK_IGNORE, TK_REINDEX, + TK_BEFORE, TK_FOREIGN, TK_FOR, TK_IGNORE, TK_REINDEX, TK_INDEX, TK_AUTOINCR, TK_TO, TK_IN, TK_BEGIN, - TK_JOIN_KW, TK_RENAME, TK_BETWEEN, TK_NOT, TK_NOTNULL, + TK_JOIN_KW, TK_RENAME, TK_BETWEEN, TK_NOTNULL, TK_NOT, TK_NULL, TK_LIKE_KW, TK_BY, TK_CASCADE, TK_ASC, TK_DEFERRED, TK_DELETE, TK_CASE, TK_CAST, TK_COLLATE, TK_COLUMNKW, TK_COMMIT, TK_CONFLICT, TK_CONSTRAINT, TK_INTERSECT, TK_CREATE, TK_JOIN_KW, TK_CTIME_KW, TK_CTIME_KW, TK_CTIME_KW, TK_PLAN, TK_DESC, TK_DETACH, TK_DISTINCT, TK_IS, TK_DROP, TK_PRAGMA, TK_MATCH, TK_FAIL, TK_LIMIT, TK_FROM, TK_JOIN_KW, TK_GROUP, TK_UPDATE, TK_IF, - TK_IMMEDIATE, TK_INSERT, TK_INSTEAD, TK_INTO, TK_OF, - TK_OFFSET, TK_SET, TK_ISNULL, TK_JOIN, TK_ORDER, + TK_IMMEDIATE, TK_INSERT, TK_INSTEAD, TK_INTO, TK_OFFSET, + TK_OF, TK_SET, TK_ISNULL, TK_JOIN, TK_ORDER, 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, }; Index: SQLite.Interop/src/legacy.c ================================================================== --- SQLite.Interop/src/legacy.c +++ SQLite.Interop/src/legacy.c @@ -12,11 +12,11 @@ ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: legacy.c,v 1.13 2006/01/11 03:22:29 rmsimpson Exp $ +** $Id: legacy.c,v 1.14 2006/01/12 20:54:07 rmsimpson Exp $ */ #include "sqliteInt.h" #include "os.h" #include @@ -119,11 +119,11 @@ exec_out: if( pStmt ) sqlite3_finalize(pStmt); if( azCols ) sqliteFree(azCols); - if( sqlite3ThreadData()->mallocFailed ){ + if( sqlite3ThreadDataReadOnly()->mallocFailed ){ rc = SQLITE_NOMEM; sqlite3MallocClearFailed(); } if( rc!=SQLITE_OK && rc==sqlite3_errcode(db) && pzErrMsg ){ Index: SQLite.Interop/src/main.c ================================================================== --- SQLite.Interop/src/main.c +++ SQLite.Interop/src/main.c @@ -12,11 +12,11 @@ ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: main.c,v 1.13 2006/01/11 03:22:29 rmsimpson Exp $ +** $Id: main.c,v 1.14 2006/01/12 20:54:07 rmsimpson Exp $ */ #include "sqliteInt.h" #include "os.h" #include @@ -174,13 +174,13 @@ ** So it needs to be freed here. Todo: Why not roll the temp schema into ** the same sqliteMalloc() as the one that allocates the database ** structure? */ sqliteFree(db->aDb[1].pSchema); - sqliteFree(db); sqlite3MallocAllow(); + sqlite3ReleaseThreadData(); return SQLITE_OK; } /* ** Rollback all database files. @@ -643,11 +643,11 @@ ** Return UTF-8 encoded English language explanation of the most recent ** error. */ const char *sqlite3_errmsg(sqlite3 *db){ const char *z; - if( sqlite3ThreadData()->mallocFailed ){ + if( sqlite3ThreadDataReadOnly()->mallocFailed ){ return sqlite3ErrStr(SQLITE_NOMEM); } if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){ return sqlite3ErrStr(SQLITE_MISUSE); } @@ -682,11 +682,11 @@ 0, 'o', 0, 'f', 0, ' ', 0, 's', 0, 'e', 0, 'q', 0, 'u', 0, 'e', 0, 'n', 0, 'c', 0, 'e', 0, 0, 0 }; const void *z; - if( sqlite3ThreadData()->mallocFailed ){ + if( sqlite3ThreadDataReadOnly()->mallocFailed ){ return (void *)(&outOfMemBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]); } if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){ return (void *)(&misuseBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]); } @@ -703,11 +703,11 @@ /* ** Return the most recent error code generated by an SQLite routine. If NULL is ** passed to this function, we assume a malloc() failed during sqlite3_open(). */ int sqlite3_errcode(sqlite3 *db){ - if( !db || sqlite3ThreadData()->mallocFailed ){ + if( !db || sqlite3ThreadDataReadOnly()->mallocFailed ){ return SQLITE_NOMEM; } if( sqlite3SafetyCheck(db) ){ return SQLITE_MISUSE; } @@ -725,11 +725,11 @@ ){ sqlite3 *db; int rc; CollSeq *pColl; - assert( !sqlite3ThreadData()->mallocFailed ); + assert( !sqlite3ThreadDataReadOnly()->mallocFailed ); /* Allocate the sqlite data structure */ db = sqliteMalloc( sizeof(sqlite3) ); if( db==0 ) goto opendb_out; db->priorNewRowid = 0; @@ -852,11 +852,11 @@ rc = openDatabase(zFilename8, ppDb); if( rc==SQLITE_OK && *ppDb ){ rc = sqlite3_exec(*ppDb, "PRAGMA encoding = 'UTF-16'", 0, 0, 0); } }else{ - assert( sqlite3ThreadData()->mallocFailed ); + assert( sqlite3ThreadDataReadOnly()->mallocFailed ); sqlite3MallocClearFailed(); } sqlite3ValueFree(pVal); return rc; @@ -1075,8 +1075,19 @@ assert( pTd->useSharedData ); return SQLITE_MISUSE; } pTd->useSharedData = enable; + sqlite3ReleaseThreadData(); return SQLITE_OK; } #endif + +/* +** This is a convenience routine that makes sure that all thread-specific +** data for this thread has been deallocated. +*/ +void sqlite3_thread_cleanup(void){ + ThreadData *pTd = sqlite3ThreadData(); + memset(pTd, 0, sizeof(*pTd)); + sqlite3ReleaseThreadData(); +} Index: SQLite.Interop/src/opcodes.c ================================================================== --- SQLite.Interop/src/opcodes.c +++ SQLite.Interop/src/opcodes.c @@ -1,30 +1,41 @@ /* Automatically generated. Do not edit */ /* See the mkopcodec.awk script for details. */ #if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) const char *const sqlite3OpcodeNames[] = { "?", /* 1 */ "MemLoad", + /* 125 */ "HexBlob", /* 2 */ "Column", /* 3 */ "SetCookie", /* 4 */ "IfMemPos", + /* 124 */ "Real", /* 5 */ "Sequence", /* 6 */ "MoveGt", + /* 71 */ "Ge", /* 7 */ "RowKey", + /* 67 */ "Eq", /* 8 */ "OpenWrite", + /* 65 */ "NotNull", /* 9 */ "If", + /* 140 */ "ToInt", + /* 86 */ "String8", /* 10 */ "Pop", /* 11 */ "CollSeq", /* 12 */ "OpenRead", /* 13 */ "Expire", /* 14 */ "AutoCommit", + /* 68 */ "Gt", /* 15 */ "IntegrityCk", - /* 16 */ "Not", /* 17 */ "Sort", /* 18 */ "Function", + /* 60 */ "And", + /* 78 */ "Subtract", /* 19 */ "Noop", /* 20 */ "Return", + /* 81 */ "Remainder", /* 21 */ "NewRowid", + /* 79 */ "Multiply", /* 22 */ "IfMemNeg", /* 23 */ "Variable", /* 24 */ "String", /* 25 */ "RealAffinity", /* 26 */ "ParseSchema", @@ -41,75 +52,69 @@ /* 37 */ "AddImm", /* 38 */ "Statement", /* 39 */ "RowData", /* 40 */ "MemMax", /* 41 */ "Push", + /* 59 */ "Or", /* 42 */ "NotExists", /* 43 */ "MemIncr", /* 44 */ "Gosub", + /* 80 */ "Divide", /* 45 */ "Integer", + /* 139 */ "ToNumeric", /* 46 */ "MemInt", /* 47 */ "Prev", + /* 82 */ "Concat", + /* 73 */ "BitAnd", /* 48 */ "CreateTable", /* 49 */ "Last", + /* 64 */ "IsNull", /* 50 */ "IdxRowid", /* 51 */ "MakeIdxRec", + /* 76 */ "ShiftRight", /* 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", + /* 138 */ "ToBlob", /* 88 */ "Delete", /* 89 */ "AggFinal", + /* 75 */ "ShiftLeft", /* 90 */ "Dup", /* 91 */ "Goto", /* 92 */ "TableLock", /* 93 */ "FifoRead", /* 94 */ "Clear", /* 95 */ "IdxGT", /* 96 */ "MoveLt", + /* 69 */ "Le", /* 97 */ "VerifyCookie", /* 98 */ "AggStep", /* 99 */ "Pull", + /* 137 */ "ToText", + /* 16 */ "Not", + /* 141 */ "ToReal", /* 100 */ "SetNumColumns", /* 101 */ "AbsValue", /* 102 */ "Transaction", + /* 83 */ "Negative", + /* 66 */ "Ne", /* 103 */ "ContextPop", + /* 74 */ "BitOr", /* 104 */ "Next", /* 105 */ "IdxInsert", /* 106 */ "Distinct", + /* 70 */ "Lt", /* 107 */ "Insert", /* 108 */ "Destroy", /* 109 */ "ReadCookie", /* 110 */ "ForceInt", /* 111 */ "LoadAnalysis", @@ -117,18 +122,18 @@ /* 113 */ "Explain", /* 114 */ "IfMemZero", /* 115 */ "OpenPseudo", /* 116 */ "Null", /* 117 */ "Blob", + /* 77 */ "Add", /* 118 */ "MemStore", /* 119 */ "Rewind", /* 120 */ "MoveGe", + /* 85 */ "BitNot", /* 121 */ "MemMove", /* 122 */ "MemNull", /* 123 */ "Found", - /* 124 */ "Real", - /* 125 */ "HexBlob", /* 126 */ "NullRow", /* 127 */ "NotUsed_127", /* 128 */ "NotUsed_128", /* 129 */ "NotUsed_129", /* 130 */ "NotUsed_130", @@ -136,12 +141,7 @@ /* 132 */ "NotUsed_132", /* 133 */ "NotUsed_133", /* 134 */ "NotUsed_134", /* 135 */ "NotUsed_135", /* 136 */ "NotUsed_136", - /* 137 */ "ToText", - /* 138 */ "ToBlob", - /* 139 */ "ToNumeric", - /* 140 */ "ToInt", - /* 141 */ "ToReal", }; #endif Index: SQLite.Interop/src/os.h ================================================================== --- SQLite.Interop/src/os.h +++ SQLite.Interop/src/os.h @@ -290,11 +290,11 @@ int sqlite3OsSleep(int ms); int sqlite3OsCurrentTime(double*); void sqlite3OsEnterMutex(void); void sqlite3OsLeaveMutex(void); int sqlite3OsInMutex(void); -void *sqlite3OsThreadSpecificData(int); +ThreadData *sqlite3OsThreadSpecificData(int); void *sqlite3OsMalloc(int); void *sqlite3OsRealloc(void *, int); void sqlite3OsFree(void *); int sqlite3OsAllocationSize(void *); @@ -333,11 +333,11 @@ int (*xCurrentTime)(double*); void (*xEnterMutex)(void); void (*xLeaveMutex)(void); int (*xInMutex)(void); - void *(*xThreadSpecificData)(int); + ThreadData *(*xThreadSpecificData)(int); void *(*xMalloc)(int); void *(*xRealloc)(void *, int); void (*xFree)(void *); int (*xAllocationSize)(void *); Index: SQLite.Interop/src/os_unix.c ================================================================== --- SQLite.Interop/src/os_unix.c +++ SQLite.Interop/src/os_unix.c @@ -1625,42 +1625,56 @@ int sqlite3UnixInMutex(){ return inMutex; } /* -** This function is called automatically when a thread exists to delete -** the threads ThreadData structure. -** -** Because the ThreadData structure is required by higher level routines -** such as sqliteMalloc() we use OsFree() and OsMalloc() directly to -** allocate the thread specific data. +** Remember the number of thread-specific-data blocks allocated. +** Use this to verify that we are not leaking thread-specific-data. +** Ticket #1601 */ -#ifdef SQLITE_UNIX_THREADS -static void deleteTsd(void *pTsd){ - sqlite3OsFree(pTsd); -} +#ifdef SQLITE_TEST +int sqlite3_tsd_count = 0; +# ifdef SQLITE_UNIX_THREADS + static pthread_mutex_t tsd_counter_mutex = PTHREAD_MUTEX_INITIALIZER; +# define TSD_COUNTER(N) \ + pthread_mutex_lock(&tsd_counter_mutex); \ + sqlite3_tsd_count += N; \ + pthread_mutex_unlock(&tsd_counter_mutex); +# else +# define TSD_COUNTER(N) sqlite3_tsd_count += N +# endif +#else +# define TSD_COUNTER(N) /* no-op */ #endif -/* -** The first time this function is called from a specific thread, nByte -** bytes of data area are allocated and zeroed. A pointer to the new -** allocation is returned to the caller. + +/* +** If called with allocateFlag>1, then return a pointer to thread +** specific data for the current thread. Allocate and zero the +** thread-specific data if it does not already exist necessary. +** +** If called with allocateFlag==0, then check the current thread +** specific data. Return it if it exists. If it does not exist, +** then return NULL. ** -** Each subsequent call to this function from the thread returns the same -** pointer. The argument is ignored in this case. +** If called with allocateFlag<0, check to see if the thread specific +** data is allocated and is all zero. If it is then deallocate it. +** Return a pointer to the thread specific data or NULL if it is +** unallocated or gets deallocated. */ -void *sqlite3UnixThreadSpecificData(int nByte){ +ThreadData *sqlite3UnixThreadSpecificData(int allocateFlag){ + static const ThreadData zeroData; #ifdef SQLITE_UNIX_THREADS static pthread_key_t key; static int keyInit = 0; - void *pTsd; + ThreadData *pTsd; if( !keyInit ){ sqlite3OsEnterMutex(); if( !keyInit ){ int rc; - rc = pthread_key_create(&key, deleteTsd); + rc = pthread_key_create(&key, 0); if( rc ){ sqlite3OsLeaveMutex(); return 0; } keyInit = 1; @@ -1667,25 +1681,42 @@ } sqlite3OsLeaveMutex(); } pTsd = pthread_getspecific(key); - if( !pTsd ){ - pTsd = sqlite3OsMalloc(nByte); - if( pTsd ){ - memset(pTsd, 0, nByte); - pthread_setspecific(key, pTsd); + if( allocateFlag>0 ){ + if( pTsd==0 ){ + pTsd = sqlite3OsMalloc(sizeof(zeroData)); + if( pTsd ){ + *pTsd = zeroData; + pthread_setspecific(key, pTsd); + TSD_COUNTER(+1); + } } + }else if( pTsd!=0 && allocateFlag<0 + && memcmp(pTsd, &zeroData, sizeof(zeroData))==0 ){ + sqlite3OsFree(pTsd); + pthread_setspecific(key, 0); + TSD_COUNTER(-1); + pTsd = 0; } return pTsd; #else - static void *pTsd = 0; - if( !pTsd ){ - pTsd = sqlite3OsMalloc(nByte); - if( pTsd ){ - memset(pTsd, 0, nByte); + static ThreadData *pTsd = 0; + if( allocateFlag>0 ){ + if( pTsd==0 ){ + pTsd = sqlite3OsMalloc( sizeof(zeroData) ); + if( pTsd ){ + *pTsd = zeroData; + TSD_COUNTER(+1); + } } + }else if( pTsd!=0 && allocateFlag<0 + && memcmp(pTsd, &zeroData, sizeof(zeroData))==0 ){ + sqlite3OsFree(pTsd); + TSD_COUNTER(-1); + pTsd = 0; } return pTsd; #endif } Index: SQLite.Interop/src/os_win.c ================================================================== --- SQLite.Interop/src/os_win.c +++ SQLite.Interop/src/os_win.c @@ -42,18 +42,21 @@ # define OS_WINCE 1 #else # define OS_WINCE 0 #endif +/* +** WinCE lacks native support for file locking so we have to fake it +** with some code of our own. +*/ #if OS_WINCE -typedef struct _LOCKDATA -{ - long nReaders; - long nPending; - long nReserved; - long nExclusive; -} LOCKDATA; +typedef struct winceLock { + int nReaders; /* Number of reader locks obtained */ + BOOL bPending; /* Indicates a pending lock has been obtained */ + BOOL bReserved; /* Indicates a reserved lock has been obtained */ + BOOL bExclusive; /* Indicates an exclusive lock has been obtained */ +} winceLock; #endif /* ** The winFile structure is a subclass of OsFile specific to the win32 ** portability layer. @@ -63,19 +66,15 @@ IoMethod const *pMethod;/* Must be first */ HANDLE h; /* Handle for accessing the file */ unsigned char locktype; /* Type of lock currently held on this file */ short sharedLockByte; /* Randomly chosen byte used as a shared lock */ #if OS_WINCE - WCHAR *zDeleteOnClose; /* Name of file to delete when closing */ - -#ifndef SQLITE_OMIT_WIN_LOCKS - HANDLE hMutex; - HANDLE hShared; - LOCKDATA local; - LOCKDATA *shared; -#endif - + WCHAR *zDeleteOnClose; /* Name of file to delete when closing */ + HANDLE hMutex; /* Mutex used to control access to shared lock */ + HANDLE hShared; /* Shared memory segment used for locking */ + winceLock local; /* Locks obtained by this instance of winFile */ + winceLock *shared; /* Global shared lock memory for the file */ #endif }; /* @@ -122,58 +121,10 @@ } return sqlite3_os_type==2; } #endif /* OS_WINCE */ -#if OS_WINCE -/* -** WindowsCE does not have a localtime() function. So create a -** substitute. -*/ -#include -struct tm *__cdecl localtime(const time_t *t) -{ - static struct tm y; - FILETIME uTm, lTm; - SYSTEMTIME pTm; - i64 t64; - t64 = *t; - t64 = (t64 + 11644473600)*10000000; - uTm.dwLowDateTime = t64 & 0xFFFFFFFF; - uTm.dwHighDateTime= t64 >> 32; - FileTimeToLocalFileTime(&uTm,&lTm); - FileTimeToSystemTime(&lTm,&pTm); - y.tm_year = pTm.wYear - 1900; - y.tm_mon = pTm.wMonth - 1; - y.tm_wday = pTm.wDayOfWeek; - y.tm_mday = pTm.wDay; - y.tm_hour = pTm.wHour; - y.tm_min = pTm.wMinute; - y.tm_sec = pTm.wSecond; - return &y; -} - -/* This will never be called, but defined to make the code compile */ -#define GetTempPathA(a,b) - -#endif - -/* -** Compile with -DSQLITE_OMIT_WIN_LOCKS to disable file locking on -** windows. If you do this and two or more connections attempt to -** write the database at the same time, the database file will be -** corrupted. But some versions of WindowsCE do not support locking, -** in which case compiling with this option is required just to get -** it to work at all. -*/ -#ifdef SQLITE_OMIT_WIN_LOCKS -# define LockFile(a,b,c,d,e) (1) -# define LockFileEx(a,b,c,d,e,f) (1) -# define UnlockFile(a,b,c,d,e) (1) -# define UnlockFileEx(a,b,c,d,e) (1) -#endif - /* ** Convert a UTF-8 string to UTF-32. Space to hold the returned string ** is obtained from sqliteMalloc. */ static WCHAR *utf8ToUnicode(const char *zFilename){ @@ -216,263 +167,315 @@ zFilename = 0; } return zFilename; } -#if OS_WINCE && !SQLITE_OMIT_WIN_LOCKS -#define LockFile(a, b, c, d, e) pseudoLockFile(&a, b, c, d, e) -#define UnlockFile(a, b, c, d, e) pseudoUnlockFile(&a, b, c, d, e) -#define LockFileEx(a, b, c, d, e, f) pseudoLockFileEx(&a, b, c, d, e, f) - -#define LOCKSTRUCT winFile - -#ifndef PtrToInt -#define PtrToInt( p ) ((INT)(INT_PTR) (p) ) -#endif - -#define HANDLE_TO_LOCKSTRUCT(a) (LOCKSTRUCT *)&((LPBYTE)a)[-PtrToInt((&((LOCKSTRUCT *)0)->h))] - -#define MUTEX_ACQUIRE(h) { DWORD dwErr; do { dwErr = WaitForSingleObject(h, INFINITE); } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED); } -#define MUTEX_RELEASE(h) ReleaseMutex(h) - -static BOOL CreateLockStruct(const char *pszFilename, LOCKSTRUCT *pLocks) -{ - WCHAR *pszTok; - WCHAR *pszName = utf8ToUnicode(pszFilename); +#if OS_WINCE +/************************************************************************* +** This section contains code for WinCE only. +*/ +/* +** WindowsCE does not have a localtime() function. So create a +** substitute. +*/ +#include +struct tm *__cdecl localtime(const time_t *t) +{ + static struct tm y; + FILETIME uTm, lTm; + SYSTEMTIME pTm; + i64 t64; + t64 = *t; + t64 = (t64 + 11644473600)*10000000; + uTm.dwLowDateTime = t64 & 0xFFFFFFFF; + uTm.dwHighDateTime= t64 >> 32; + FileTimeToLocalFileTime(&uTm,&lTm); + FileTimeToSystemTime(&lTm,&pTm); + y.tm_year = pTm.wYear - 1900; + y.tm_mon = pTm.wMonth - 1; + y.tm_wday = pTm.wDayOfWeek; + y.tm_mday = pTm.wDay; + y.tm_hour = pTm.wHour; + y.tm_min = pTm.wMinute; + y.tm_sec = pTm.wSecond; + return &y; +} + +/* This will never be called, but defined to make the code compile */ +#define GetTempPathA(a,b) + +#define LockFile(a,b,c,d,e) winceLockFile(&a, b, c, d, e) +#define UnlockFile(a,b,c,d,e) winceUnlockFile(&a, b, c, d, e) +#define LockFileEx(a,b,c,d,e,f) winceLockFileEx(&a, b, c, d, e, f) + +#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-offsetof(winFile,h)] + +/* +** Acquire a lock on the handle h +*/ +static void winceMutexAcquire(HANDLE h){ + DWORD dwErr; + do { + dwErr = WaitForSingleObject(h, INFINITE); + } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED); +} +/* +** Release a lock acquired by winceMutexAcquire() +*/ +#define winceMutexRelease(h) ReleaseMutex(h) + +/* +** Create the mutex and shared memory used for locking in the file +** descriptor pFile +*/ +static BOOL winceCreateLock(const char *zFilename, winFile *pFile){ + WCHAR *zTok; + WCHAR *zName = utf8ToUnicode(zFilename); BOOL bInit = TRUE; /* Initialize the local lockdata */ - ZeroMemory(&pLocks->local, sizeof(LOCKDATA)); + ZeroMemory(&pFile->local, sizeof(pFile->local)); - /* Create a unique global name for the mutex and subsequently the shared memory */ - CharLowerW(pszName); - while (pszTok = wcschr(pszName, '\\')) - { - *pszTok = '_'; + /* Replace the backslashes from the filename and lowercase it + ** to derive a mutex name. */ + zTok = CharLowerW(zName); + for (;*zTok;zTok++){ + if (*zTok == '\\') *zTok = '_'; } /* Create/open the named mutex */ - pLocks->hMutex = CreateMutexW(NULL, FALSE, pszName); - if (!pLocks->hMutex) - { - sqliteFree(pszName); + pFile->hMutex = CreateMutexW(NULL, FALSE, zName); + if (!pFile->hMutex){ + sqliteFree(zName); return FALSE; } /* Acquire the mutex before continuing */ - MUTEX_ACQUIRE(pLocks->hMutex); - - /* Create/open the shared memory */ - CharUpperW(pszName); - pLocks->hShared = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(LOCKDATA), pszName); - - /* Set a flag that indicates we're the first to create the memory so it must be zero-initialized */ - if (GetLastError() == ERROR_ALREADY_EXISTS) - { + winceMutexAcquire(pFile->hMutex); + + /* Since the names of named mutexes, semaphores, file mappings etc are + ** case-sensitive, take advantage of that by uppercasing the mutex name + ** and using that as the shared filemapping name. + */ + CharUpperW(zName); + pFile->hShared = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, + PAGE_READWRITE, 0, sizeof(winceLock), + zName); + + /* Set a flag that indicates we're the first to create the memory so it + ** must be zero-initialized */ + if (GetLastError() == ERROR_ALREADY_EXISTS){ bInit = FALSE; } - sqliteFree(pszName); + sqliteFree(zName); /* If we succeeded in making the shared memory handle, map it. */ - if (pLocks->hShared) - { - pLocks->shared = (LOCKDATA *)MapViewOfFile(pLocks->hShared, FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(LOCKDATA)); + if (pFile->hShared){ + pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared, + FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock)); /* If mapping failed, close the shared memory handle and erase it */ - if (!pLocks->shared) - { - CloseHandle(pLocks->hShared); - pLocks->hShared = NULL; + if (!pFile->shared){ + CloseHandle(pFile->hShared); + pFile->hShared = NULL; } } /* If shared memory could not be created, then close the mutex and fail */ - if (pLocks->hShared == NULL) - { - MUTEX_RELEASE(pLocks->hMutex); - CloseHandle(pLocks->hMutex); - pLocks->hMutex = NULL; + if (pFile->hShared == NULL){ + winceMutexRelease(pFile->hMutex); + CloseHandle(pFile->hMutex); + pFile->hMutex = NULL; return FALSE; } /* Initialize the shared memory if we're supposed to */ - if (bInit) - { - ZeroMemory(pLocks->shared, sizeof(LOCKDATA)); + if (bInit) { + ZeroMemory(pFile->shared, sizeof(winceLock)); } - MUTEX_RELEASE(pLocks->hMutex); - + winceMutexRelease(pFile->hMutex); return TRUE; } -static void DestroyLockStruct(LOCKSTRUCT *pLocks) -{ - if (pLocks->hMutex) - { +/* +** Destroy the part of winFile that deals with wince locks +*/ +static void winceDestroyLock(winFile *pFile){ + if (pFile->hMutex){ /* Acquire the mutex */ - MUTEX_ACQUIRE(pLocks->hMutex); + winceMutexAcquire(pFile->hMutex); /* The following blocks should probably assert in debug mode, but they are to cleanup in case any locks remained open */ - if (pLocks->local.nReaders) - { - pLocks->shared->nReaders --; - } - - if (pLocks->local.nReserved) - { - pLocks->shared->nReserved = 0; - } - - if (pLocks->local.nPending) - { - pLocks->shared->nPending = 0; - } - - if (pLocks->local.nExclusive) - { - pLocks->shared->nExclusive = 0; + if (pFile->local.nReaders){ + pFile->shared->nReaders --; + } + if (pFile->local.bReserved){ + pFile->shared->bReserved = FALSE; + } + if (pFile->local.bPending){ + pFile->shared->bPending = FALSE; + } + if (pFile->local.bExclusive){ + pFile->shared->bExclusive = FALSE; } /* De-reference and close our copy of the shared memory handle */ - UnmapViewOfFile(pLocks->shared); - CloseHandle(pLocks->hShared); + UnmapViewOfFile(pFile->shared); + CloseHandle(pFile->hShared); /* Done with the mutex */ - MUTEX_RELEASE(pLocks->hMutex); - CloseHandle(pLocks->hMutex); - pLocks->hMutex = NULL; + winceMutexRelease(pFile->hMutex); + CloseHandle(pFile->hMutex); + pFile->hMutex = NULL; } } -/* Custom pseudo file locking support specifically for SQLite */ -BOOL pseudoLockFile(HANDLE *phFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh, DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh) -{ - LOCKSTRUCT *pls = HANDLE_TO_LOCKSTRUCT(phFile); +/* +** An implementation of the LockFile() API of windows for wince +*/ +static BOOL winceLockFile( + HANDLE *phFile, + DWORD dwFileOffsetLow, + DWORD dwFileOffsetHigh, + DWORD nNumberOfBytesToLockLow, + DWORD nNumberOfBytesToLockHigh +){ + winFile *pFile = HANDLE_TO_WINFILE(phFile); BOOL bReturn = FALSE; - if (!pls->hMutex) return TRUE; - - MUTEX_ACQUIRE(pls->hMutex); + if (!pFile->hMutex) return TRUE; + winceMutexAcquire(pFile->hMutex); /* Wanting an exclusive lock? */ - if (dwFileOffsetLow == SHARED_FIRST && nNumberOfBytesToLockLow == SHARED_SIZE) - { - if (pls->shared->nReaders == 0 && pls->shared->nExclusive == 0) - { - pls->shared->nExclusive = 1; - pls->local.nExclusive = 1; - bReturn = TRUE; + if (dwFileOffsetLow == SHARED_FIRST + && nNumberOfBytesToLockLow == SHARED_SIZE){ + if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){ + pFile->shared->bExclusive = TRUE; + pFile->local.bExclusive = TRUE; + bReturn = TRUE; } } + /* Want a read-only lock? */ - else if ((dwFileOffsetLow >= SHARED_FIRST && dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE) && nNumberOfBytesToLockLow == 1) - { - if (pls->shared->nExclusive == 0) - { - pls->local.nReaders ++; - if (pls->local.nReaders == 1) - { - pls->shared->nReaders ++; + else if ((dwFileOffsetLow >= SHARED_FIRST && + dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE) && + nNumberOfBytesToLockLow == 1){ + if (pFile->shared->bExclusive == 0){ + pFile->local.nReaders ++; + if (pFile->local.nReaders == 1){ + pFile->shared->nReaders ++; } bReturn = TRUE; } } + /* Want a pending lock? */ - else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToLockLow == 1) - { + else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToLockLow == 1){ /* If no pending lock has been acquired, then acquire it */ - if (pls->shared->nPending == 0) - { - pls->shared->nPending = 1; - pls->local.nPending = 1; + if (pFile->shared->bPending == 0) { + pFile->shared->bPending = TRUE; + pFile->local.bPending = TRUE; bReturn = TRUE; } } /* Want a reserved lock? */ - else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToLockLow == 1) - { - if (pls->shared->nReserved == 0) - { - pls->shared->nReserved = 1; - pls->local.nReserved = 1; - bReturn = TRUE; - } - } - - MUTEX_RELEASE(pls->hMutex); - - return bReturn; -} - -BOOL pseudoUnlockFile(HANDLE *phFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh, DWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh) -{ - LOCKSTRUCT *pls = HANDLE_TO_LOCKSTRUCT(phFile); - BOOL bReturn = FALSE; - - if (!pls->hMutex) return TRUE; - - MUTEX_ACQUIRE(pls->hMutex); - - /* Releasing a reader lock or an exclusive lock */ - if (dwFileOffsetLow >= SHARED_FIRST && dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE) - { - /* Did we have an exclusive lock? */ - if (pls->local.nExclusive) - { - pls->local.nExclusive = 0; - pls->shared->nExclusive = 0; - bReturn = TRUE; - } - /* Did we just have a reader lock? */ - else if (pls->local.nReaders) - { - pls->local.nReaders --; - if (pls->local.nReaders == 0) - { - pls->shared->nReaders --; - } - bReturn = TRUE; - } - } - /* Releasing a pending lock */ - else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToUnlockLow == 1) - { - if (pls->local.nPending) - { - pls->local.nPending = 0; - pls->shared->nPending = 0; - bReturn = TRUE; - } - } - /* Releasing a reserved lock */ - else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1) - { - if (pls->local.nReserved) - { - pls->local.nReserved = 0; - pls->shared->nReserved = 0; - bReturn = TRUE; - } - } - - MUTEX_RELEASE(pls->hMutex); - - return bReturn; -} - -BOOL pseudoLockFileEx(HANDLE *phFile, DWORD dwFlags, DWORD dwReserved, DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh, LPOVERLAPPED lpOverlapped) -{ - /* If the caller wants a shared read lock, forward this call to pseudoLockFile */ - if (lpOverlapped->Offset == SHARED_FIRST && dwFlags == 1 && nNumberOfBytesToLockLow == SHARED_SIZE) - return pseudoLockFile(phFile, SHARED_FIRST, 0, 1, 0); - - return FALSE; -} - -#endif /* OS_WINCE && !SQLITE_OMIT_WIN_LOCKS */ + else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToLockLow == 1){ + if (pFile->shared->bReserved == 0) { + pFile->shared->bReserved = TRUE; + pFile->local.bReserved = TRUE; + bReturn = TRUE; + } + } + + winceMutexRelease(pFile->hMutex); + return bReturn; +} + +/* +** An implementation of the UnlockFile API of windows for wince +*/ +static BOOL winceUnlockFile( + HANDLE *phFile, + DWORD dwFileOffsetLow, + DWORD dwFileOffsetHigh, + DWORD nNumberOfBytesToUnlockLow, + DWORD nNumberOfBytesToUnlockHigh +){ + winFile *pFile = HANDLE_TO_WINFILE(phFile); + BOOL bReturn = FALSE; + + if (!pFile->hMutex) return TRUE; + winceMutexAcquire(pFile->hMutex); + + /* Releasing a reader lock or an exclusive lock */ + if (dwFileOffsetLow >= SHARED_FIRST && + dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE){ + /* Did we have an exclusive lock? */ + if (pFile->local.bExclusive){ + pFile->local.bExclusive = FALSE; + pFile->shared->bExclusive = FALSE; + bReturn = TRUE; + } + + /* Did we just have a reader lock? */ + else if (pFile->local.nReaders){ + pFile->local.nReaders --; + if (pFile->local.nReaders == 0) + { + pFile->shared->nReaders --; + } + bReturn = TRUE; + } + } + + /* Releasing a pending lock */ + else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){ + if (pFile->local.bPending){ + pFile->local.bPending = FALSE; + pFile->shared->bPending = FALSE; + bReturn = TRUE; + } + } + /* Releasing a reserved lock */ + else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){ + if (pFile->local.bReserved) { + pFile->local.bReserved = FALSE; + pFile->shared->bReserved = FALSE; + bReturn = TRUE; + } + } + + winceMutexRelease(pFile->hMutex); + return bReturn; +} + +/* +** An implementation of the LockFileEx() API of windows for wince +*/ +static BOOL winceLockFileEx( + HANDLE *phFile, + DWORD dwFlags, + DWORD dwReserved, + DWORD nNumberOfBytesToLockLow, + DWORD nNumberOfBytesToLockHigh, + LPOVERLAPPED lpOverlapped +){ + /* If the caller wants a shared read lock, forward this call + ** to winceLockFile */ + if (lpOverlapped->Offset == SHARED_FIRST && + dwFlags == 1 && + nNumberOfBytesToLockLow == SHARED_SIZE){ + return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0); + } + return FALSE; +} +/* +** End of the special code for wince +*****************************************************************************/ +#endif /* OS_WINCE */ /* ** Delete the named file */ int sqlite3WinDelete(const char *zFilename){ @@ -559,12 +562,12 @@ } *pReadonly = 1; }else{ *pReadonly = 0; } -#if OS_WINCE && !SQLITE_OMIT_WIN_LOCKS - if (!CreateLockStruct(zFilename, &f)){ +#if OS_WINCE + if (!winceCreateLock(zFilename, &f)){ CloseHandle(h); sqliteFree(zWide); return SQLITE_CANTOPEN; } #endif @@ -666,13 +669,11 @@ f.h = h; f.locktype = NO_LOCK; f.sharedLockByte = 0; #if OS_WINCE f.zDeleteOnClose = delFlag ? utf8ToUnicode(zFilename) : 0; -#ifndef SQLITE_OMIT_WIN_LOCKS f.hMutex = NULL; -#endif #endif TRACE3("OPEN EX %d \"%s\"\n", h, zFilename); return allocateWinFile(&f, pId); } @@ -718,13 +719,11 @@ f.h = h; f.locktype = NO_LOCK; f.sharedLockByte = 0; #if OS_WINCE f.zDeleteOnClose = 0; -#ifndef SQLITE_OMIT_WIN_LOCKS f.hMutex = NULL; -#endif #endif TRACE3("OPEN RO %d \"%s\"\n", h, zFilename); return allocateWinFile(&f, pId); } @@ -808,13 +807,11 @@ winFile *pFile; if( pId && (pFile = (winFile*)*pId)!=0 ){ TRACE2("CLOSE %d\n", pFile->h); CloseHandle(pFile->h); #if OS_WINCE -#ifndef SQLITE_OMIT_WIN_LOCKS - DestroyLockStruct(pFile); -#endif + winceDestroyLock(pFile); if( pFile->zDeleteOnClose ){ DeleteFileW(pFile->zDeleteOnClose); sqliteFree(pFile->zDeleteOnClose); } #endif @@ -1437,22 +1434,45 @@ } #endif return 0; } -/* -** The first time this function is called from a specific thread, nByte -** bytes of data area are allocated and zeroed. A pointer to the new -** allocation is returned to the caller. +/* +** Remember the number of thread-specific-data blocks allocated. +** Use this to verify that we are not leaking thread-specific-data. +** Ticket #1601 +*/ +#ifdef SQLITE_TEST +int sqlite3_tsd_count = 0; +# define TSD_COUNTER_INCR InterlockedIncrement(&sqlite3_tsd_count) +# define TSD_COUNTER_DECR InterlockedDecrement(&sqlite3_tsd_count) +#else +# define TSD_COUNTER_INCR /* no-op */ +# define TSD_COUNTER_DECR /* no-op */ +#endif + + + +/* +** If called with allocateFlag>1, then return a pointer to thread +** specific data for the current thread. Allocate and zero the +** thread-specific data if it does not already exist necessary. +** +** If called with allocateFlag==0, then check the current thread +** specific data. Return it if it exists. If it does not exist, +** then return NULL. ** -** Each subsequent call to this function from the thread returns the same -** pointer. The argument is ignored in this case. +** If called with allocateFlag<0, check to see if the thread specific +** data is allocated and is all zero. If it is then deallocate it. +** Return a pointer to the thread specific data or NULL if it is +** unallocated or gets deallocated. */ -void *sqlite3WinThreadSpecificData(int nByte){ - static void *pTsd = 0; +ThreadData *sqlite3WinThreadSpecificData(int allocateFlag){ static int key; static int keyInit = 0; + static const ThreadData zeroData; + ThreadData *pTsd; if( !keyInit ){ sqlite3OsEnterMutex(); if( !keyInit ){ key = TlsAlloc(); @@ -1463,15 +1483,24 @@ keyInit = 1; } sqlite3OsLeaveMutex(); } pTsd = TlsGetValue(key); - if( !pTsd ){ - pTsd = sqlite3OsMalloc(nByte); - if( pTsd ){ - memset(pTsd, 0, nByte); - TlsSetValue(key, pTsd); + if( allocateFlag>0 ){ + if( !pTsd ){ + pTsd = sqlite3OsMalloc( sizeof(zeroData) ); + if( pTsd ){ + *pTsd = zeroData; + TlsSetValue(key, pTsd); + TSD_COUNTER_INCR; + } } + }else if( pTsd!=0 && allocateFlag<0 + && memcmp(pTsd, &zeroData, sizeof(zeroData))==0 ){ + sqlite3OsFree(pTsd); + TlsSetValue(key, 0); + TSD_COUNTER_DECR; + pTsd = 0; } return pTsd; } #endif /* OS_WIN */ Index: SQLite.Interop/src/pager.c ================================================================== --- SQLite.Interop/src/pager.c +++ SQLite.Interop/src/pager.c @@ -16,11 +16,11 @@ ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.14 2006/01/11 03:22:29 rmsimpson Exp $ +** @(#) $Id: pager.c,v 1.15 2006/01/12 20:54:07 rmsimpson Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" #include "os.h" #include "pager.h" @@ -282,11 +282,11 @@ void (*xDestructor)(void*,int); /* Call this routine when freeing pages */ 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 */ -#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT Pager *pNext; /* Linked list of pagers in this thread */ #endif }; /* @@ -1616,20 +1616,20 @@ int memDb = 0; int readOnly = 0; int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; int noReadlock = (flags & PAGER_NO_READLOCK)!=0; char zTemp[SQLITE_TEMPNAME_SIZE]; -#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT - ThreadData *pTsd = sqlite3ThreadData(); +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT + const ThreadData *pTsdro = sqlite3ThreadDataReadOnly(); #endif /* If malloc() has already failed return SQLITE_NOMEM. Before even ** testing for this, set *ppPager to NULL so the caller knows the pager ** structure was never allocated. */ *ppPager = 0; - if( sqlite3ThreadData()->mallocFailed ){ + if( sqlite3ThreadDataReadOnly()->mallocFailed ){ return SQLITE_NOMEM; } memset(&fd, 0, sizeof(fd)); /* Open the pager file and set zFullPathname to point at malloc()ed @@ -1718,12 +1718,13 @@ pPager->nExtra = FORCE_ALIGNMENT(nExtra); pPager->sectorSize = PAGER_SECTOR_SIZE; pPager->pBusyHandler = 0; memset(pPager->aHash, 0, sizeof(pPager->aHash)); *ppPager = pPager; -#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT - if( pTsd->useMemoryManagement ){ +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT + if( pTsdro->useMemoryManagement ){ + ThreadData *pTsd = sqlite3ThreadData(); pPager->pNext = pTsd->pPager; pTsd->pPager = pPager; } #endif return SQLITE_OK; @@ -2025,12 +2026,12 @@ ** a hot journal may be left in the filesystem but no error is returned ** to the caller. */ int sqlite3pager_close(Pager *pPager){ PgHdr *pPg, *pNext; -#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT - ThreadData *pTsd = sqlite3ThreadData(); +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT + const ThreadData *pTsd = sqlite3ThreadDataReadOnly(); #endif switch( pPager->state ){ case PAGER_RESERVED: case PAGER_SYNCED: @@ -2085,11 +2086,11 @@ ** if( pPager->tempFile ){ ** sqlite3OsDelete(pPager->zFilename); ** } */ -#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT /* Remove the pager from the linked list of pagers starting at ** ThreadData.pPager if memory-management is enabled. */ if( pTsd->useMemoryManagement ){ if( pPager==pTsd->pPager ){ @@ -2100,10 +2101,13 @@ pTmp->pNext = pPager->pNext; } } #endif +#ifdef SQLITE_HAS_CODEC + sqlite3pager_free_codecarg(pPager->pCodecArg); +#endif sqliteFree(pPager); return SQLITE_OK; } /* @@ -2454,13 +2458,13 @@ ** nReq is the number of bytes of memory required. Once this much has ** been released, the function returns. A negative value for nReq means ** free as much memory as possible. The return value is the total number ** of bytes of memory released. */ -#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT int sqlite3pager_release_memory(int nReq){ - ThreadData *pTsd = sqlite3ThreadData(); + const ThreadData *pTsdro = sqlite3ThreadDataReadOnly(); Pager *p; int nReleased = 0; int i; /* If the the global mutex is held, this subroutine becomes a @@ -2479,11 +2483,11 @@ ** expensive. */ for(i=0; i<=1; i++){ /* Loop through all the SQLite pagers opened by the current thread. */ - for(p=pTsd->pPager; p && (nReq<0 || nReleasedpNext){ + for(p=pTsdro->pPager; p && (nReq<0 || nReleasedpNext){ PgHdr *pPg; int rc; /* For each pager, try to free as many pages as possible (without ** calling fsync() if this is the first iteration of the outermost @@ -2525,11 +2529,11 @@ } } return nReleased; } -#endif /* SQLITE_OMIT_MEMORY_MANAGEMENT */ +#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */ /* ** Acquire a page. ** ** A read lock on the disk file is obtained when the first page is acquired. Index: SQLite.Interop/src/pager.h ================================================================== --- SQLite.Interop/src/pager.h +++ SQLite.Interop/src/pager.h @@ -11,11 +11,11 @@ ************************************************************************* ** This header file defines the interface that the sqlite page cache ** subsystem. The page cache subsystem reads and writes a file a page ** at a time and provides a journal for rollback. ** -** @(#) $Id: pager.h,v 1.14 2006/01/11 03:22:29 rmsimpson Exp $ +** @(#) $Id: pager.h,v 1.15 2006/01/12 20:54:07 rmsimpson Exp $ */ #ifndef _PAGER_H_ #define _PAGER_H_ Index: SQLite.Interop/src/parse.c ================================================================== --- SQLite.Interop/src/parse.c +++ SQLite.Interop/src/parse.c @@ -173,400 +173,400 @@ ** yy_reduce_ofst[] For each state, the offset into yy_action for ** shifting non-terminals after a reduce. ** yy_default[] Default action for each state. */ static const YYACTIONTYPE yy_action[] = { - /* 0 */ 280, 68, 284, 70, 148, 166, 547, 420, 62, 62, - /* 10 */ 62, 62, 202, 64, 64, 64, 64, 65, 65, 66, - /* 20 */ 66, 66, 67, 67, 549, 550, 433, 69, 64, 64, - /* 30 */ 64, 64, 65, 65, 66, 66, 66, 67, 68, 455, - /* 40 */ 70, 148, 500, 61, 59, 288, 441, 442, 438, 438, - /* 50 */ 63, 63, 62, 62, 62, 62, 502, 64, 64, 64, - /* 60 */ 64, 65, 65, 66, 66, 66, 67, 280, 372, 284, - /* 70 */ 420, 2, 378, 80, 158, 115, 220, 305, 225, 306, - /* 80 */ 170, 245, 857, 119, 560, 505, 204, 2, 246, 390, - /* 90 */ 497, 219, 22, 433, 515, 21, 420, 58, 494, 171, - /* 100 */ 64, 64, 64, 64, 65, 65, 66, 66, 66, 67, - /* 110 */ 61, 59, 288, 441, 442, 438, 438, 63, 63, 62, - /* 120 */ 62, 62, 62, 513, 64, 64, 64, 64, 65, 65, - /* 130 */ 66, 66, 66, 67, 280, 379, 380, 175, 202, 378, - /* 140 */ 331, 334, 335, 220, 305, 225, 306, 170, 245, 203, - /* 150 */ 146, 358, 336, 282, 378, 246, 55, 302, 374, 420, - /* 160 */ 433, 506, 92, 200, 531, 66, 66, 66, 67, 526, - /* 170 */ 192, 65, 65, 66, 66, 66, 67, 61, 59, 288, - /* 180 */ 441, 442, 438, 438, 63, 63, 62, 62, 62, 62, - /* 190 */ 434, 64, 64, 64, 64, 65, 65, 66, 66, 66, - /* 200 */ 67, 280, 379, 380, 412, 432, 110, 226, 428, 205, - /* 210 */ 436, 437, 309, 359, 262, 261, 175, 379, 380, 331, - /* 220 */ 334, 335, 373, 370, 202, 512, 481, 433, 548, 363, - /* 230 */ 467, 336, 511, 501, 411, 41, 277, 415, 435, 430, - /* 240 */ 504, 162, 233, 528, 61, 59, 288, 441, 442, 438, - /* 250 */ 438, 63, 63, 62, 62, 62, 62, 320, 64, 64, - /* 260 */ 64, 64, 65, 65, 66, 66, 66, 67, 280, 473, - /* 270 */ 417, 417, 417, 309, 323, 236, 309, 68, 309, 70, - /* 280 */ 148, 1, 309, 794, 309, 378, 68, 153, 70, 148, - /* 290 */ 149, 378, 326, 283, 433, 411, 35, 552, 411, 35, - /* 300 */ 411, 36, 428, 205, 411, 35, 411, 35, 287, 423, - /* 310 */ 424, 61, 59, 288, 441, 442, 438, 438, 63, 63, - /* 320 */ 62, 62, 62, 62, 412, 64, 64, 64, 64, 65, - /* 330 */ 65, 66, 66, 66, 67, 309, 505, 467, 291, 255, - /* 340 */ 280, 325, 486, 147, 237, 389, 21, 289, 379, 380, - /* 350 */ 452, 420, 232, 452, 379, 380, 309, 411, 28, 452, - /* 360 */ 175, 451, 487, 331, 334, 335, 433, 215, 348, 145, - /* 370 */ 514, 204, 351, 186, 168, 336, 238, 412, 411, 41, - /* 380 */ 256, 463, 76, 61, 59, 288, 441, 442, 438, 438, - /* 390 */ 63, 63, 62, 62, 62, 62, 310, 64, 64, 64, - /* 400 */ 64, 65, 65, 66, 66, 66, 67, 412, 412, 186, - /* 410 */ 397, 309, 280, 292, 420, 339, 477, 309, 391, 234, - /* 420 */ 169, 154, 398, 476, 397, 328, 494, 312, 423, 424, - /* 430 */ 445, 378, 357, 411, 49, 399, 398, 395, 433, 411, - /* 440 */ 49, 503, 171, 412, 430, 313, 162, 396, 352, 399, - /* 450 */ 498, 319, 471, 353, 79, 61, 59, 288, 441, 442, - /* 460 */ 438, 438, 63, 63, 62, 62, 62, 62, 357, 64, - /* 470 */ 64, 64, 64, 65, 65, 66, 66, 66, 67, 280, - /* 480 */ 299, 446, 377, 480, 533, 406, 300, 11, 505, 353, - /* 490 */ 204, 378, 407, 378, 379, 380, 282, 557, 21, 492, - /* 500 */ 492, 246, 561, 373, 370, 433, 393, 394, 315, 123, - /* 510 */ 444, 444, 166, 290, 420, 315, 116, 444, 444, 251, - /* 520 */ 265, 464, 61, 59, 288, 441, 442, 438, 438, 63, - /* 530 */ 63, 62, 62, 62, 62, 293, 64, 64, 64, 64, - /* 540 */ 65, 65, 66, 66, 66, 67, 280, 460, 329, 475, - /* 550 */ 499, 309, 202, 309, 379, 380, 379, 380, 181, 131, - /* 560 */ 179, 266, 309, 5, 309, 364, 315, 356, 444, 444, - /* 570 */ 411, 3, 433, 411, 29, 411, 24, 420, 243, 244, - /* 580 */ 381, 382, 383, 405, 411, 33, 411, 54, 467, 61, - /* 590 */ 59, 288, 441, 442, 438, 438, 63, 63, 62, 62, - /* 600 */ 62, 62, 309, 64, 64, 64, 64, 65, 65, 66, - /* 610 */ 66, 66, 67, 280, 522, 345, 522, 249, 309, 492, - /* 620 */ 309, 471, 309, 471, 411, 25, 309, 240, 309, 315, - /* 630 */ 309, 444, 444, 213, 172, 173, 174, 142, 267, 433, - /* 640 */ 411, 52, 411, 97, 411, 94, 529, 394, 411, 99, - /* 650 */ 411, 100, 411, 111, 212, 255, 61, 59, 288, 441, - /* 660 */ 442, 438, 438, 63, 63, 62, 62, 62, 62, 309, - /* 670 */ 64, 64, 64, 64, 65, 65, 66, 66, 66, 67, - /* 680 */ 280, 309, 346, 188, 298, 91, 309, 492, 309, 416, - /* 690 */ 309, 411, 112, 309, 429, 309, 538, 309, 244, 165, - /* 700 */ 154, 410, 356, 411, 18, 409, 433, 321, 411, 98, - /* 710 */ 411, 34, 411, 95, 314, 411, 53, 411, 113, 411, - /* 720 */ 114, 255, 294, 61, 59, 288, 441, 442, 438, 438, - /* 730 */ 63, 63, 62, 62, 62, 62, 309, 64, 64, 64, - /* 740 */ 64, 65, 65, 66, 66, 66, 67, 280, 309, 492, - /* 750 */ 492, 524, 309, 453, 309, 523, 309, 462, 411, 26, - /* 760 */ 309, 75, 540, 77, 309, 461, 244, 347, 214, 466, - /* 770 */ 411, 37, 470, 433, 411, 38, 411, 27, 411, 39, - /* 780 */ 242, 82, 411, 40, 295, 297, 411, 42, 439, 330, - /* 790 */ 61, 59, 288, 441, 442, 438, 438, 63, 63, 62, - /* 800 */ 62, 62, 62, 309, 64, 64, 64, 64, 65, 65, - /* 810 */ 66, 66, 66, 67, 280, 309, 410, 190, 221, 309, - /* 820 */ 409, 309, 152, 309, 159, 411, 43, 309, 244, 244, - /* 830 */ 222, 20, 309, 139, 426, 426, 482, 411, 44, 483, - /* 840 */ 433, 411, 30, 411, 31, 411, 45, 488, 462, 411, - /* 850 */ 46, 412, 507, 255, 411, 47, 489, 61, 71, 288, - /* 860 */ 441, 442, 438, 438, 63, 63, 62, 62, 62, 62, - /* 870 */ 309, 64, 64, 64, 64, 65, 65, 66, 66, 66, - /* 880 */ 67, 280, 309, 402, 403, 250, 309, 193, 309, 421, - /* 890 */ 309, 23, 411, 48, 541, 450, 255, 14, 469, 478, - /* 900 */ 167, 14, 485, 484, 411, 32, 252, 433, 411, 12, - /* 910 */ 411, 50, 411, 51, 255, 255, 595, 255, 255, 150, - /* 920 */ 490, 412, 123, 253, 280, 59, 288, 441, 442, 438, - /* 930 */ 438, 63, 63, 62, 62, 62, 62, 542, 64, 64, - /* 940 */ 64, 64, 65, 65, 66, 66, 66, 67, 254, 248, - /* 950 */ 433, 123, 338, 412, 123, 268, 270, 196, 362, 367, - /* 960 */ 183, 177, 180, 520, 521, 260, 535, 123, 167, 288, - /* 970 */ 441, 442, 438, 438, 63, 63, 62, 62, 62, 62, - /* 980 */ 343, 64, 64, 64, 64, 65, 65, 66, 66, 66, - /* 990 */ 67, 72, 316, 259, 4, 412, 412, 536, 286, 89, - /* 1000 */ 545, 350, 89, 354, 355, 19, 311, 72, 316, 369, - /* 1010 */ 4, 387, 263, 264, 286, 223, 546, 271, 365, 274, - /* 1020 */ 275, 141, 311, 318, 227, 317, 556, 425, 427, 481, - /* 1030 */ 456, 459, 491, 432, 333, 493, 534, 157, 544, 318, - /* 1040 */ 376, 384, 385, 386, 8, 303, 304, 392, 285, 432, - /* 1050 */ 405, 400, 74, 73, 224, 404, 408, 82, 324, 322, - /* 1060 */ 72, 307, 308, 401, 231, 415, 81, 206, 74, 73, - /* 1070 */ 474, 57, 78, 164, 454, 413, 72, 307, 308, 72, - /* 1080 */ 316, 415, 4, 228, 202, 229, 286, 235, 230, 457, - /* 1090 */ 458, 414, 207, 120, 311, 83, 327, 102, 417, 417, - /* 1100 */ 417, 418, 419, 13, 239, 496, 468, 241, 278, 208, - /* 1110 */ 472, 318, 495, 210, 417, 417, 417, 418, 419, 13, - /* 1120 */ 211, 432, 156, 279, 340, 508, 509, 216, 217, 218, - /* 1130 */ 106, 510, 516, 178, 344, 84, 342, 182, 518, 457, - /* 1140 */ 74, 73, 86, 198, 519, 272, 257, 184, 72, 307, - /* 1150 */ 308, 349, 273, 415, 527, 530, 118, 187, 127, 537, - /* 1160 */ 360, 136, 128, 543, 195, 129, 531, 301, 553, 90, - /* 1170 */ 554, 194, 137, 197, 432, 130, 133, 555, 558, 96, - /* 1180 */ 209, 101, 375, 388, 117, 201, 417, 417, 417, 418, - /* 1190 */ 419, 13, 93, 143, 144, 56, 596, 109, 597, 160, - /* 1200 */ 161, 60, 501, 422, 431, 440, 415, 443, 138, 447, - /* 1210 */ 151, 6, 448, 449, 7, 361, 269, 261, 163, 15, - /* 1220 */ 465, 281, 14, 121, 155, 122, 202, 479, 103, 332, - /* 1230 */ 247, 104, 85, 105, 337, 222, 176, 341, 140, 417, - /* 1240 */ 417, 417, 517, 124, 296, 167, 125, 525, 185, 107, - /* 1250 */ 366, 258, 9, 532, 10, 126, 16, 189, 539, 191, - /* 1260 */ 132, 87, 88, 134, 135, 17, 108, 276, 551, 371, - /* 1270 */ 536, 199, 368, 559, + /* 0 */ 281, 67, 344, 80, 150, 157, 225, 517, 92, 92, + /* 10 */ 92, 92, 288, 59, 59, 59, 59, 58, 58, 57, + /* 20 */ 57, 57, 65, 346, 478, 48, 544, 86, 59, 59, + /* 30 */ 59, 59, 58, 58, 57, 57, 57, 65, 67, 481, + /* 40 */ 80, 150, 231, 64, 88, 295, 525, 518, 530, 530, + /* 50 */ 72, 72, 92, 92, 92, 92, 219, 59, 59, 59, + /* 60 */ 59, 58, 58, 57, 57, 57, 65, 281, 252, 189, + /* 70 */ 517, 296, 344, 81, 59, 59, 59, 59, 58, 58, + /* 80 */ 57, 57, 57, 65, 166, 115, 246, 303, 264, 323, + /* 90 */ 196, 236, 158, 544, 478, 49, 387, 69, 228, 857, + /* 100 */ 128, 560, 247, 56, 2, 381, 22, 476, 456, 363, + /* 110 */ 64, 88, 295, 525, 518, 530, 530, 72, 72, 92, + /* 120 */ 92, 92, 92, 283, 59, 59, 59, 59, 58, 58, + /* 130 */ 57, 57, 57, 65, 281, 344, 279, 386, 395, 553, + /* 140 */ 388, 165, 386, 276, 361, 288, 223, 439, 520, 451, + /* 150 */ 344, 58, 58, 57, 57, 57, 65, 478, 38, 365, + /* 160 */ 544, 145, 143, 282, 67, 393, 80, 150, 451, 500, + /* 170 */ 393, 189, 478, 36, 500, 424, 425, 64, 88, 295, + /* 180 */ 525, 518, 530, 530, 72, 72, 92, 92, 92, 92, + /* 190 */ 71, 59, 59, 59, 59, 58, 58, 57, 57, 57, + /* 200 */ 65, 281, 508, 508, 508, 429, 146, 508, 508, 508, + /* 210 */ 294, 512, 507, 198, 344, 520, 350, 357, 362, 246, + /* 220 */ 303, 264, 323, 196, 236, 283, 221, 544, 367, 310, + /* 230 */ 228, 228, 57, 57, 57, 65, 478, 48, 308, 299, + /* 240 */ 534, 537, 306, 417, 64, 88, 295, 525, 518, 530, + /* 250 */ 530, 72, 72, 92, 92, 92, 92, 551, 59, 59, + /* 260 */ 59, 59, 58, 58, 57, 57, 57, 65, 281, 550, + /* 270 */ 202, 416, 198, 375, 520, 350, 357, 362, 512, 507, + /* 280 */ 413, 414, 344, 293, 344, 372, 21, 367, 198, 522, + /* 290 */ 517, 350, 357, 362, 544, 359, 539, 371, 374, 126, + /* 300 */ 403, 209, 200, 367, 478, 18, 478, 43, 194, 169, + /* 310 */ 384, 64, 88, 295, 525, 518, 530, 530, 72, 72, + /* 320 */ 92, 92, 92, 92, 232, 59, 59, 59, 59, 58, + /* 330 */ 58, 57, 57, 57, 65, 511, 344, 512, 507, 427, + /* 340 */ 281, 420, 479, 479, 148, 419, 331, 233, 344, 67, + /* 350 */ 344, 80, 150, 517, 344, 176, 155, 309, 478, 32, + /* 360 */ 315, 436, 149, 184, 464, 195, 544, 348, 78, 533, + /* 370 */ 478, 51, 478, 51, 378, 428, 478, 51, 479, 443, + /* 380 */ 158, 377, 85, 64, 88, 295, 525, 518, 530, 530, + /* 390 */ 72, 72, 92, 92, 92, 92, 479, 59, 59, 59, + /* 400 */ 59, 58, 58, 57, 57, 57, 65, 281, 387, 467, + /* 410 */ 504, 162, 77, 324, 344, 290, 521, 457, 22, 300, + /* 420 */ 353, 520, 513, 513, 432, 487, 14, 487, 329, 271, + /* 430 */ 257, 487, 426, 544, 523, 524, 478, 51, 217, 208, + /* 440 */ 206, 144, 380, 355, 534, 537, 353, 55, 513, 513, + /* 450 */ 64, 88, 295, 525, 518, 530, 530, 72, 72, 92, + /* 460 */ 92, 92, 92, 375, 59, 59, 59, 59, 58, 58, + /* 470 */ 57, 57, 57, 65, 281, 372, 11, 127, 71, 218, + /* 480 */ 520, 241, 182, 126, 512, 507, 164, 155, 374, 520, + /* 490 */ 338, 488, 452, 398, 543, 353, 200, 513, 513, 1, + /* 500 */ 544, 401, 353, 520, 513, 513, 200, 553, 366, 165, + /* 510 */ 157, 463, 517, 358, 540, 538, 479, 64, 88, 295, + /* 520 */ 525, 518, 530, 530, 72, 72, 92, 92, 92, 92, + /* 530 */ 468, 59, 59, 59, 59, 58, 58, 57, 57, 57, + /* 540 */ 65, 370, 541, 512, 507, 437, 281, 344, 172, 506, + /* 550 */ 239, 344, 512, 507, 344, 387, 224, 448, 93, 344, + /* 560 */ 89, 344, 313, 344, 555, 22, 512, 507, 182, 478, + /* 570 */ 27, 520, 544, 478, 43, 517, 478, 50, 561, 547, + /* 580 */ 369, 478, 47, 478, 114, 478, 95, 528, 91, 64, + /* 590 */ 88, 295, 525, 518, 530, 530, 72, 72, 92, 92, + /* 600 */ 92, 92, 479, 59, 59, 59, 59, 58, 58, 57, + /* 610 */ 57, 57, 65, 281, 226, 344, 251, 174, 110, 344, + /* 620 */ 141, 147, 344, 465, 344, 449, 325, 370, 270, 344, + /* 630 */ 421, 344, 450, 554, 512, 507, 2, 478, 52, 544, + /* 640 */ 595, 478, 44, 311, 478, 30, 478, 45, 313, 173, + /* 650 */ 418, 478, 53, 478, 25, 479, 64, 88, 295, 525, + /* 660 */ 518, 530, 530, 72, 72, 92, 92, 92, 92, 344, + /* 670 */ 59, 59, 59, 59, 58, 58, 57, 57, 57, 65, + /* 680 */ 281, 344, 404, 479, 433, 344, 470, 344, 152, 344, + /* 690 */ 469, 478, 112, 344, 415, 314, 415, 344, 411, 344, + /* 700 */ 126, 287, 161, 478, 94, 440, 544, 478, 113, 478, + /* 710 */ 12, 478, 99, 401, 465, 478, 41, 292, 456, 478, + /* 720 */ 100, 478, 46, 64, 88, 295, 525, 518, 530, 530, + /* 730 */ 72, 72, 92, 92, 92, 92, 344, 59, 59, 59, + /* 740 */ 59, 58, 58, 57, 57, 57, 65, 281, 344, 485, + /* 750 */ 19, 404, 344, 514, 344, 79, 307, 260, 478, 111, + /* 760 */ 344, 242, 344, 548, 548, 344, 503, 501, 497, 466, + /* 770 */ 478, 42, 404, 544, 478, 26, 478, 39, 478, 3, + /* 780 */ 304, 423, 478, 31, 478, 40, 291, 478, 37, 305, + /* 790 */ 64, 88, 295, 525, 518, 530, 530, 72, 72, 92, + /* 800 */ 92, 92, 92, 344, 59, 59, 59, 59, 58, 58, + /* 810 */ 57, 57, 57, 65, 281, 344, 470, 404, 126, 344, + /* 820 */ 469, 344, 20, 344, 139, 478, 97, 344, 320, 7, + /* 830 */ 242, 344, 190, 181, 180, 208, 451, 478, 28, 258, + /* 840 */ 544, 478, 54, 478, 35, 478, 33, 222, 327, 478, + /* 850 */ 34, 262, 204, 478, 29, 435, 191, 64, 76, 295, + /* 860 */ 525, 518, 530, 530, 72, 72, 92, 92, 92, 92, + /* 870 */ 404, 59, 59, 59, 59, 58, 58, 57, 57, 57, + /* 880 */ 65, 281, 404, 454, 177, 162, 344, 208, 344, 175, + /* 890 */ 479, 320, 447, 235, 211, 794, 242, 286, 456, 516, + /* 900 */ 352, 441, 409, 410, 409, 298, 385, 544, 478, 24, + /* 910 */ 478, 98, 252, 252, 252, 252, 275, 284, 479, 252, + /* 920 */ 334, 252, 252, 479, 281, 88, 295, 525, 518, 530, + /* 930 */ 530, 72, 72, 92, 92, 92, 92, 274, 59, 59, + /* 940 */ 59, 59, 58, 58, 57, 57, 57, 65, 517, 242, + /* 950 */ 544, 244, 252, 237, 340, 215, 494, 214, 390, 546, + /* 960 */ 492, 242, 256, 489, 475, 406, 79, 397, 273, 295, + /* 970 */ 525, 518, 530, 530, 72, 72, 92, 92, 92, 92, + /* 980 */ 116, 59, 59, 59, 59, 58, 58, 57, 57, 57, + /* 990 */ 65, 62, 345, 484, 4, 407, 412, 269, 289, 126, + /* 1000 */ 519, 259, 23, 550, 202, 552, 349, 62, 345, 549, + /* 1010 */ 4, 517, 354, 493, 289, 14, 547, 369, 402, 316, + /* 1020 */ 240, 453, 349, 339, 472, 356, 142, 266, 471, 477, + /* 1030 */ 249, 319, 505, 386, 459, 343, 529, 428, 255, 339, + /* 1040 */ 71, 458, 499, 118, 333, 130, 121, 192, 389, 386, + /* 1050 */ 123, 156, 60, 61, 483, 103, 87, 125, 212, 480, + /* 1060 */ 62, 328, 330, 178, 277, 500, 229, 210, 60, 61, + /* 1070 */ 438, 297, 399, 491, 476, 473, 62, 328, 330, 62, + /* 1080 */ 345, 500, 4, 474, 208, 302, 289, 342, 207, 186, + /* 1090 */ 498, 68, 278, 120, 349, 136, 400, 556, 508, 508, + /* 1100 */ 508, 509, 510, 17, 312, 106, 243, 326, 205, 245, + /* 1110 */ 373, 339, 434, 285, 508, 508, 508, 509, 510, 17, + /* 1120 */ 74, 386, 160, 431, 248, 8, 321, 227, 220, 230, + /* 1130 */ 102, 332, 137, 382, 383, 536, 405, 234, 75, 183, + /* 1140 */ 60, 61, 317, 170, 265, 254, 135, 336, 62, 328, + /* 1150 */ 330, 442, 267, 500, 263, 66, 318, 261, 201, 455, + /* 1160 */ 447, 73, 461, 408, 168, 531, 443, 83, 482, 446, + /* 1170 */ 376, 171, 396, 167, 444, 542, 545, 208, 238, 272, + /* 1180 */ 213, 163, 188, 101, 364, 96, 508, 508, 508, 509, + /* 1190 */ 510, 17, 490, 63, 270, 322, 153, 105, 335, 535, + /* 1200 */ 526, 108, 558, 394, 527, 532, 250, 515, 379, 391, + /* 1210 */ 13, 368, 557, 107, 351, 337, 216, 257, 82, 132, + /* 1220 */ 559, 280, 109, 179, 347, 140, 208, 159, 65, 185, + /* 1230 */ 502, 341, 268, 193, 392, 131, 129, 203, 496, 151, + /* 1240 */ 10, 104, 154, 430, 486, 138, 253, 199, 495, 422, + /* 1250 */ 360, 162, 445, 5, 15, 597, 9, 187, 117, 122, + /* 1260 */ 596, 119, 133, 16, 6, 124, 301, 134, 14, 90, + /* 1270 */ 70, 462, 84, 460, 197, }; 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, + /* 0 */ 16, 216, 146, 218, 219, 21, 146, 23, 68, 69, + /* 10 */ 70, 71, 16, 73, 74, 75, 76, 77, 78, 79, + /* 20 */ 80, 81, 82, 146, 168, 169, 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, 43, - /* 100 */ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + /* 40 */ 218, 219, 146, 59, 60, 61, 62, 63, 64, 65, + /* 50 */ 66, 67, 68, 69, 70, 71, 146, 73, 74, 75, + /* 60 */ 76, 77, 78, 79, 80, 81, 82, 16, 146, 43, + /* 70 */ 86, 215, 146, 22, 73, 74, 75, 76, 77, 78, + /* 80 */ 79, 80, 81, 82, 88, 89, 90, 91, 92, 93, + /* 90 */ 94, 95, 22, 42, 168, 169, 146, 46, 102, 138, + /* 100 */ 139, 140, 152, 19, 143, 155, 156, 23, 160, 187, /* 110 */ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - /* 120 */ 69, 70, 71, 180, 73, 74, 75, 76, 77, 78, - /* 130 */ 79, 80, 81, 82, 16, 86, 87, 88, 109, 23, - /* 140 */ 91, 92, 93, 90, 91, 92, 93, 94, 95, 191, - /* 150 */ 22, 122, 103, 97, 23, 102, 198, 141, 142, 86, - /* 160 */ 42, 180, 44, 147, 49, 79, 80, 81, 82, 18, - /* 170 */ 154, 77, 78, 79, 80, 81, 82, 59, 60, 61, + /* 120 */ 69, 70, 71, 97, 73, 74, 75, 76, 77, 78, + /* 130 */ 79, 80, 81, 82, 16, 146, 157, 58, 20, 160, + /* 140 */ 161, 162, 58, 189, 16, 16, 220, 199, 23, 146, + /* 150 */ 146, 77, 78, 79, 80, 81, 82, 168, 169, 237, + /* 160 */ 42, 77, 78, 149, 216, 86, 218, 219, 146, 90, + /* 170 */ 86, 43, 168, 169, 90, 89, 90, 59, 60, 61, /* 180 */ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - /* 190 */ 42, 73, 74, 75, 76, 77, 78, 79, 80, 81, - /* 200 */ 82, 16, 86, 87, 188, 58, 21, 189, 77, 78, - /* 210 */ 62, 63, 146, 98, 99, 100, 88, 86, 87, 91, - /* 220 */ 92, 93, 1, 2, 109, 175, 176, 42, 97, 213, - /* 230 */ 160, 103, 182, 86, 168, 169, 157, 90, 90, 160, - /* 240 */ 161, 162, 146, 92, 59, 60, 61, 62, 63, 64, - /* 250 */ 65, 66, 67, 68, 69, 70, 71, 185, 73, 74, - /* 260 */ 75, 76, 77, 78, 79, 80, 81, 82, 16, 199, - /* 270 */ 123, 124, 125, 146, 208, 209, 146, 216, 146, 218, - /* 280 */ 219, 19, 146, 132, 146, 23, 216, 146, 218, 219, - /* 290 */ 154, 23, 146, 149, 42, 168, 169, 236, 168, 169, - /* 300 */ 168, 169, 77, 78, 168, 169, 168, 169, 163, 164, - /* 310 */ 165, 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, 160, 211, 146, - /* 340 */ 16, 211, 30, 154, 146, 155, 156, 211, 86, 87, - /* 350 */ 223, 23, 220, 223, 86, 87, 146, 168, 169, 223, - /* 360 */ 88, 223, 50, 91, 92, 93, 42, 144, 224, 179, - /* 370 */ 180, 226, 228, 154, 154, 103, 199, 188, 168, 169, - /* 380 */ 187, 113, 130, 59, 60, 61, 62, 63, 64, 65, - /* 390 */ 66, 67, 68, 69, 70, 71, 146, 73, 74, 75, - /* 400 */ 76, 77, 78, 79, 80, 81, 82, 188, 188, 154, - /* 410 */ 12, 146, 16, 101, 86, 16, 20, 146, 167, 209, - /* 420 */ 200, 201, 24, 20, 12, 205, 175, 163, 164, 165, - /* 430 */ 20, 23, 213, 168, 169, 37, 24, 39, 42, 168, - /* 440 */ 169, 159, 43, 188, 160, 161, 162, 49, 229, 37, - /* 450 */ 168, 39, 146, 234, 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 */ 215, 20, 146, 20, 229, 27, 215, 19, 146, 234, - /* 490 */ 226, 23, 34, 23, 86, 87, 97, 155, 156, 146, - /* 500 */ 146, 102, 0, 1, 2, 42, 184, 185, 105, 22, - /* 510 */ 107, 108, 21, 207, 23, 105, 146, 107, 108, 14, - /* 520 */ 14, 113, 59, 60, 61, 62, 63, 64, 65, 66, - /* 530 */ 67, 68, 69, 70, 71, 181, 73, 74, 75, 76, - /* 540 */ 77, 78, 79, 80, 81, 82, 16, 22, 146, 79, - /* 550 */ 20, 146, 109, 146, 86, 87, 86, 87, 53, 53, - /* 560 */ 55, 55, 146, 190, 146, 122, 105, 146, 107, 108, - /* 570 */ 168, 169, 42, 168, 169, 168, 169, 86, 225, 225, - /* 580 */ 7, 8, 9, 96, 168, 169, 168, 169, 160, 59, + /* 190 */ 120, 73, 74, 75, 76, 77, 78, 79, 80, 81, + /* 200 */ 82, 16, 123, 124, 125, 20, 22, 123, 124, 125, + /* 210 */ 207, 86, 87, 88, 146, 23, 91, 92, 93, 90, + /* 220 */ 91, 92, 93, 94, 95, 97, 146, 42, 103, 207, + /* 230 */ 102, 102, 79, 80, 81, 82, 168, 169, 224, 163, + /* 240 */ 164, 165, 228, 177, 59, 60, 61, 62, 63, 64, + /* 250 */ 65, 66, 67, 68, 69, 70, 71, 146, 73, 74, + /* 260 */ 75, 76, 77, 78, 79, 80, 81, 82, 16, 77, + /* 270 */ 78, 177, 88, 12, 23, 91, 92, 93, 86, 87, + /* 280 */ 51, 52, 146, 215, 146, 24, 19, 103, 88, 97, + /* 290 */ 23, 91, 92, 93, 42, 141, 142, 20, 37, 22, + /* 300 */ 39, 147, 226, 103, 168, 169, 168, 169, 154, 154, + /* 310 */ 49, 59, 60, 61, 62, 63, 64, 65, 66, 67, + /* 320 */ 68, 69, 70, 71, 14, 73, 74, 75, 76, 77, + /* 330 */ 78, 79, 80, 81, 82, 20, 146, 86, 87, 146, + /* 340 */ 16, 25, 188, 188, 154, 29, 208, 209, 146, 216, + /* 350 */ 146, 218, 219, 86, 146, 200, 201, 41, 168, 169, + /* 360 */ 205, 20, 154, 53, 113, 55, 42, 213, 44, 236, + /* 370 */ 168, 169, 168, 169, 175, 176, 168, 169, 188, 49, + /* 380 */ 22, 182, 130, 59, 60, 61, 62, 63, 64, 65, + /* 390 */ 66, 67, 68, 69, 70, 71, 188, 73, 74, 75, + /* 400 */ 76, 77, 78, 79, 80, 81, 82, 16, 146, 20, + /* 410 */ 20, 22, 21, 211, 146, 211, 146, 155, 156, 211, + /* 420 */ 105, 23, 107, 108, 20, 223, 22, 223, 98, 99, + /* 430 */ 100, 223, 177, 42, 164, 165, 168, 169, 14, 109, + /* 440 */ 191, 179, 180, 163, 164, 165, 105, 198, 107, 108, + /* 450 */ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + /* 460 */ 69, 70, 71, 12, 73, 74, 75, 76, 77, 78, + /* 470 */ 79, 80, 81, 82, 16, 24, 19, 53, 120, 55, + /* 480 */ 23, 20, 154, 22, 86, 87, 200, 201, 37, 23, + /* 490 */ 39, 223, 166, 167, 42, 105, 226, 107, 108, 19, + /* 500 */ 42, 175, 105, 23, 107, 108, 226, 160, 161, 162, + /* 510 */ 21, 113, 23, 16, 62, 63, 188, 59, 60, 61, + /* 520 */ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + /* 530 */ 22, 73, 74, 75, 76, 77, 78, 79, 80, 81, + /* 540 */ 82, 213, 90, 86, 87, 79, 16, 146, 19, 146, + /* 550 */ 20, 146, 86, 87, 146, 146, 132, 229, 129, 146, + /* 560 */ 131, 146, 234, 146, 155, 156, 86, 87, 154, 168, + /* 570 */ 169, 23, 42, 168, 169, 86, 168, 169, 0, 1, + /* 580 */ 2, 168, 169, 168, 169, 168, 169, 90, 130, 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, 98, 99, 100, 20, 146, 146, - /* 620 */ 146, 146, 146, 146, 168, 169, 146, 199, 146, 105, - /* 630 */ 146, 107, 108, 212, 98, 99, 100, 112, 132, 42, - /* 640 */ 168, 169, 168, 169, 168, 169, 184, 185, 168, 169, - /* 650 */ 168, 169, 168, 169, 181, 146, 59, 60, 61, 62, + /* 600 */ 70, 71, 188, 73, 74, 75, 76, 77, 78, 79, + /* 610 */ 80, 81, 82, 16, 209, 146, 90, 230, 21, 146, + /* 620 */ 112, 154, 146, 22, 146, 27, 231, 213, 102, 146, + /* 630 */ 30, 146, 34, 140, 86, 87, 143, 168, 169, 42, + /* 640 */ 111, 168, 169, 229, 168, 169, 168, 169, 234, 154, + /* 650 */ 50, 168, 169, 168, 169, 188, 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, 207, 22, 207, 21, 146, 146, 146, 146, - /* 690 */ 146, 168, 169, 146, 160, 146, 187, 146, 225, 200, - /* 700 */ 201, 106, 146, 168, 169, 110, 42, 146, 168, 169, - /* 710 */ 168, 169, 168, 169, 16, 168, 169, 168, 169, 168, - /* 720 */ 169, 146, 181, 59, 60, 61, 62, 63, 64, 65, + /* 680 */ 16, 146, 146, 188, 20, 146, 106, 146, 87, 146, + /* 690 */ 110, 168, 169, 146, 98, 99, 100, 146, 20, 146, + /* 700 */ 22, 101, 19, 168, 169, 167, 42, 168, 169, 168, + /* 710 */ 169, 168, 169, 175, 113, 168, 169, 181, 160, 168, + /* 720 */ 169, 168, 169, 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, 25, 146, 146, 146, 29, 146, 22, 168, 169, - /* 760 */ 146, 129, 187, 131, 146, 202, 225, 41, 212, 146, + /* 750 */ 67, 146, 146, 20, 146, 22, 146, 199, 168, 169, + /* 760 */ 146, 225, 146, 123, 124, 146, 7, 8, 9, 202, /* 770 */ 168, 169, 146, 42, 168, 169, 168, 169, 168, 169, - /* 780 */ 146, 120, 168, 169, 181, 181, 168, 169, 90, 79, + /* 780 */ 146, 18, 168, 169, 168, 169, 181, 168, 169, 79, /* 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, 106, 154, 90, 146, - /* 820 */ 110, 146, 87, 146, 19, 168, 169, 146, 225, 225, - /* 830 */ 102, 19, 146, 21, 123, 124, 146, 168, 169, 177, - /* 840 */ 42, 168, 169, 168, 169, 168, 169, 177, 113, 168, - /* 850 */ 169, 188, 146, 146, 168, 169, 177, 59, 60, 61, + /* 810 */ 79, 80, 81, 82, 16, 146, 106, 146, 22, 146, + /* 820 */ 110, 146, 19, 146, 21, 168, 169, 146, 146, 190, + /* 830 */ 225, 146, 98, 99, 100, 109, 146, 168, 169, 146, + /* 840 */ 42, 168, 169, 168, 169, 168, 169, 146, 122, 168, + /* 850 */ 169, 225, 181, 168, 169, 92, 154, 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, 7, 8, 146, 146, 154, 146, 20, - /* 890 */ 146, 22, 168, 169, 187, 20, 146, 22, 20, 20, - /* 900 */ 22, 22, 89, 90, 168, 169, 146, 42, 168, 169, - /* 910 */ 168, 169, 168, 169, 146, 146, 111, 146, 146, 154, - /* 920 */ 20, 188, 22, 146, 16, 60, 61, 62, 63, 64, - /* 930 */ 65, 66, 67, 68, 69, 70, 71, 187, 73, 74, - /* 940 */ 75, 76, 77, 78, 79, 80, 81, 82, 146, 20, - /* 950 */ 42, 22, 20, 188, 22, 187, 187, 19, 187, 187, - /* 960 */ 230, 154, 154, 51, 52, 20, 20, 22, 22, 61, + /* 880 */ 82, 16, 146, 20, 154, 22, 146, 109, 146, 154, + /* 890 */ 188, 146, 96, 146, 212, 132, 225, 207, 160, 146, + /* 900 */ 122, 184, 185, 184, 185, 181, 146, 42, 168, 169, + /* 910 */ 168, 169, 146, 146, 146, 146, 146, 181, 188, 146, + /* 920 */ 146, 146, 146, 188, 16, 60, 61, 62, 63, 64, + /* 930 */ 65, 66, 67, 68, 69, 70, 71, 199, 73, 74, + /* 940 */ 75, 76, 77, 78, 79, 80, 81, 82, 23, 225, + /* 950 */ 42, 146, 146, 187, 187, 187, 187, 212, 159, 227, + /* 960 */ 187, 225, 187, 187, 20, 171, 22, 168, 146, 61, /* 970 */ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - /* 980 */ 231, 73, 74, 75, 76, 77, 78, 79, 80, 81, - /* 990 */ 82, 16, 17, 146, 19, 188, 188, 20, 23, 22, - /* 1000 */ 20, 146, 22, 146, 146, 67, 31, 16, 17, 237, - /* 1010 */ 19, 148, 146, 146, 23, 171, 146, 146, 146, 146, - /* 1020 */ 146, 190, 31, 48, 192, 222, 146, 227, 227, 176, - /* 1030 */ 171, 171, 171, 58, 172, 171, 193, 6, 193, 48, - /* 1040 */ 145, 145, 145, 145, 22, 153, 97, 170, 40, 58, - /* 1050 */ 96, 170, 77, 78, 170, 172, 170, 120, 117, 115, - /* 1060 */ 85, 86, 87, 178, 196, 90, 118, 221, 77, 78, - /* 1070 */ 79, 119, 129, 111, 151, 188, 85, 86, 87, 16, - /* 1080 */ 17, 90, 19, 193, 109, 194, 23, 95, 195, 23, - /* 1090 */ 159, 197, 210, 151, 31, 97, 114, 19, 123, 124, - /* 1100 */ 125, 126, 127, 128, 203, 178, 204, 203, 173, 210, - /* 1110 */ 204, 48, 159, 210, 123, 124, 125, 126, 127, 128, - /* 1120 */ 210, 58, 5, 173, 15, 170, 170, 10, 11, 12, - /* 1130 */ 13, 170, 151, 150, 38, 19, 151, 151, 151, 23, - /* 1140 */ 77, 78, 129, 26, 233, 28, 232, 150, 85, 86, - /* 1150 */ 87, 151, 35, 90, 170, 183, 59, 183, 19, 193, - /* 1160 */ 15, 214, 186, 193, 47, 186, 49, 151, 33, 235, - /* 1170 */ 151, 54, 214, 56, 58, 186, 183, 151, 136, 158, - /* 1180 */ 174, 174, 1, 20, 32, 44, 123, 124, 125, 126, - /* 1190 */ 127, 128, 235, 77, 78, 19, 111, 238, 111, 111, - /* 1200 */ 111, 19, 86, 20, 20, 90, 90, 106, 19, 11, - /* 1210 */ 19, 116, 20, 20, 116, 98, 99, 100, 22, 22, - /* 1220 */ 113, 104, 22, 19, 111, 20, 109, 20, 19, 44, - /* 1230 */ 20, 19, 19, 19, 44, 102, 94, 16, 21, 123, - /* 1240 */ 124, 125, 17, 97, 36, 22, 45, 45, 97, 19, - /* 1250 */ 133, 132, 5, 11, 1, 101, 19, 121, 17, 112, - /* 1260 */ 112, 67, 67, 101, 121, 19, 14, 135, 20, 3, - /* 1270 */ 239, 134, 57, 4, + /* 980 */ 146, 73, 74, 75, 76, 77, 78, 79, 80, 81, + /* 990 */ 82, 16, 17, 187, 19, 7, 8, 20, 23, 22, + /* 1000 */ 20, 171, 22, 77, 78, 160, 31, 16, 17, 227, + /* 1010 */ 19, 86, 172, 20, 23, 22, 1, 2, 171, 146, + /* 1020 */ 192, 146, 31, 48, 171, 146, 190, 144, 148, 171, + /* 1030 */ 146, 146, 193, 58, 146, 222, 146, 176, 146, 48, + /* 1040 */ 120, 193, 193, 59, 15, 183, 186, 111, 151, 58, + /* 1050 */ 186, 6, 77, 78, 145, 19, 129, 186, 221, 193, + /* 1060 */ 85, 86, 87, 151, 173, 90, 95, 210, 77, 78, + /* 1070 */ 79, 40, 178, 145, 23, 159, 85, 86, 87, 16, + /* 1080 */ 17, 90, 19, 145, 109, 151, 23, 15, 210, 150, + /* 1090 */ 197, 119, 173, 19, 31, 214, 159, 136, 123, 124, + /* 1100 */ 125, 126, 127, 128, 97, 238, 193, 117, 210, 194, + /* 1110 */ 170, 48, 170, 151, 123, 124, 125, 126, 127, 128, + /* 1120 */ 118, 58, 5, 170, 195, 22, 153, 10, 11, 12, + /* 1130 */ 13, 115, 214, 170, 170, 33, 151, 196, 235, 150, + /* 1140 */ 77, 78, 38, 26, 170, 28, 151, 151, 85, 86, + /* 1150 */ 87, 183, 35, 90, 232, 97, 114, 203, 210, 204, + /* 1160 */ 96, 129, 170, 233, 47, 145, 49, 235, 151, 172, + /* 1170 */ 170, 54, 178, 56, 204, 151, 151, 109, 135, 203, + /* 1180 */ 174, 183, 134, 174, 57, 158, 123, 124, 125, 126, + /* 1190 */ 127, 128, 188, 19, 102, 146, 146, 14, 185, 1, + /* 1200 */ 90, 19, 180, 168, 20, 20, 20, 106, 180, 168, + /* 1210 */ 19, 44, 20, 19, 44, 98, 99, 100, 19, 121, + /* 1220 */ 4, 104, 19, 111, 3, 19, 109, 121, 82, 111, + /* 1230 */ 11, 16, 146, 97, 17, 101, 112, 44, 20, 19, + /* 1240 */ 5, 19, 111, 20, 17, 21, 132, 22, 20, 45, + /* 1250 */ 133, 22, 11, 116, 22, 111, 1, 112, 32, 45, + /* 1260 */ 111, 101, 20, 19, 116, 97, 36, 19, 22, 67, + /* 1270 */ 19, 113, 67, 20, 94, }; -#define YY_SHIFT_USE_DFLT (-98) +#define YY_SHIFT_USE_DFLT (-61) #define YY_SHIFT_MAX 371 static const short yy_shift_ofst[] = { - /* 0 */ 221, 975, 1117, -16, 975, 1063, 1063, 1063, 49, 115, - /* 10 */ 115, -97, 118, 1063, 1063, 1063, 1063, 1063, -45, 131, - /* 20 */ 116, 328, 225, 225, 51, 185, 252, 324, 396, 463, - /* 30 */ 530, 597, 664, 731, 798, 731, 731, 731, 731, 731, - /* 40 */ 731, 731, 731, 731, 731, 731, 731, 731, 731, 731, + /* 0 */ 1015, 975, 1117, -16, 975, 1063, 1063, 1063, 125, 330, + /* 10 */ 330, 1068, 324, 1063, 1063, 1063, 1063, 1063, -45, 192, + /* 20 */ 548, 926, 925, 926, 51, 391, 118, 185, 252, 458, + /* 30 */ 530, 597, 664, 731, 731, 731, 731, 731, 731, 731, + /* 40 */ 731, 731, 798, 731, 731, 731, 731, 731, 731, 731, /* 50 */ 731, 731, 865, 908, 908, 991, 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, 1063, -60, -60, -14, 27, 27, 94, - /* 100 */ 86, 399, 116, 116, 116, 116, 151, 116, 116, 116, - /* 110 */ 328, -59, -98, -98, -98, 1116, 53, 398, 398, 502, - /* 120 */ 491, 116, 491, 116, 116, 116, 116, 116, 116, 116, - /* 130 */ 116, 116, 116, 116, 116, 116, 29, 443, -97, -97, - /* 140 */ -97, -98, -98, 147, 147, 128, 272, 403, 262, 410, - /* 150 */ 461, 412, 268, 408, 468, 470, 573, 116, 116, 710, - /* 160 */ 116, 116, 73, 116, 116, 735, 116, 116, 524, 735, - /* 170 */ 116, 116, 312, 312, 312, 116, 116, 524, 116, 116, - /* 180 */ 524, 116, 726, 516, 116, 116, 524, 116, 116, 116, - /* 190 */ 524, 116, 524, 524, 116, 116, 116, 116, 116, 116, - /* 200 */ 812, 458, 595, 525, 711, 711, 632, 458, 458, 56, - /* 210 */ 458, 458, 487, 661, 661, 1031, 1031, 1031, 1031, 1022, - /* 220 */ 949, 949, 1008, 949, 954, 949, -97, 937, 941, 948, - /* 230 */ 944, 952, 943, 962, 992, 1066, 992, 962, 998, 982, - /* 240 */ 998, 982, 1078, 992, 992, 1066, 1008, 949, 949, 949, - /* 250 */ 1078, 1109, 962, 962, 962, 962, 1096, 1013, 1109, 962, - /* 260 */ 949, 1097, 1097, 1139, 937, 1145, 1145, 1145, 937, 1097, - /* 270 */ 1139, 962, 1135, 1135, 962, 962, 1042, -98, -98, -98, - /* 280 */ 148, 506, 536, 505, 728, 876, 805, 869, 698, 875, - /* 290 */ 878, 879, 813, 900, 929, 932, 912, 945, 946, 977, - /* 300 */ 980, 938, 1181, 1163, 1152, 1141, 1176, 1085, 1087, 1088, - /* 310 */ 1089, 1182, 1183, 1184, 1115, 1101, 1189, 1198, 1191, 1192, - /* 320 */ 1196, 1193, 1095, 1197, 1098, 1200, 1107, 1204, 1205, 1113, - /* 330 */ 1207, 1185, 1209, 1210, 1212, 1213, 1190, 1214, 1142, 1133, - /* 340 */ 1221, 1225, 1217, 1146, 1208, 1201, 1223, 1202, 1119, 1151, - /* 350 */ 1230, 1247, 1242, 1253, 1154, 1194, 1195, 1136, 1237, 1147, - /* 360 */ 1241, 1148, 1162, 1143, 1246, 1248, 1252, 1215, 1137, 1132, - /* 370 */ 1266, 1269, + /* 90 */ 1063, 1063, 1063, 1063, -60, -60, -4, 1, 1, 74, + /* 100 */ 153, 128, 763, 548, 548, 548, 548, 548, 548, 548, + /* 110 */ 925, 1146, -61, -61, -61, 84, 129, 261, 261, 548, + /* 120 */ 548, 548, 548, 548, 548, 548, 548, 548, 578, 548, + /* 130 */ 548, 548, 548, 489, 548, 489, 778, 726, 1068, 1068, + /* 140 */ 1068, -61, -61, 79, 184, 79, 200, 390, 341, 315, + /* 150 */ 480, 451, 251, 398, 466, 457, 548, 548, 548, 548, + /* 160 */ 759, 548, 548, 548, 601, 267, 548, 548, 548, 397, + /* 170 */ 548, 548, 710, 397, 596, 397, 601, 397, 316, 548, + /* 180 */ 600, 600, 397, 548, 548, 548, 548, 548, 548, 548, + /* 190 */ 600, 397, 548, 548, 397, 548, 548, 548, 548, 548, + /* 200 */ 640, 598, 640, 598, 796, 598, 508, 598, 580, 803, + /* 210 */ 598, 70, 429, 26, 358, 920, 984, 1029, 1029, 936, + /* 220 */ 1045, 920, 1036, 927, 1029, 936, 971, 1045, 1031, 1051, + /* 230 */ 1045, 936, 1072, 971, 972, 1036, 1051, 1074, 961, 1007, + /* 240 */ 920, 1007, 971, 990, 936, 1002, 1007, 1103, 1016, 1074, + /* 250 */ 1007, 1007, 936, 1072, 1102, 936, 1104, 984, 936, 1007, + /* 260 */ 1058, 1042, 971, 1032, 1007, 1064, 1045, 1102, 936, 1007, + /* 270 */ 1031, 984, 1042, 936, 1058, 936, 1068, -61, -61, -61, + /* 280 */ 424, 452, 310, 734, 277, 683, 389, 86, 526, 529, + /* 290 */ 404, 461, 678, 733, 863, 497, 944, 988, 977, 980, + /* 300 */ 993, 229, 1136, 1193, 1222, 1223, 1235, 1131, 1114, 1204, + /* 310 */ 1229, 1241, 1226, 1255, 1214, 1242, 1160, 1230, 1248, 1202, + /* 320 */ 1205, 1253, 1158, 1251, 1246, 1168, 1148, 1244, 1149, 1145, + /* 330 */ 1144, 1232, 1137, 1227, 1228, 1225, 1224, 1124, 1218, 1220, + /* 340 */ 1134, 1217, 1215, 1219, 1118, 1206, 1112, 1216, 1098, 1199, + /* 350 */ 1170, 1194, 1191, 1101, 1186, 1185, 1184, 1182, 1110, 1198, + /* 360 */ 1183, 1092, 1174, 1127, 1048, 1043, 1192, 1167, 1203, 1221, + /* 370 */ 1106, 1180, }; #define YY_REDUCE_USE_DFLT (-216) #define YY_REDUCE_MAX 279 static const short yy_reduce_ofst[] = { - /* 0 */ -56, 136, 16, 70, 189, 127, 66, 130, 190, 219, - /* 10 */ 255, 220, 61, 132, 138, 210, 265, 271, -178, -140, - /* 20 */ -61, 79, 145, 264, -215, -215, -215, -215, -215, -215, + /* 0 */ -39, 208, 154, -52, 190, 138, 202, 204, 262, 328, + /* 10 */ 414, 155, 133, 68, 268, 405, -144, -74, -178, 270, + /* 20 */ -50, 76, -21, 280, -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, -215, 402, 405, 407, 416, 418, - /* 60 */ 456, 472, 474, 476, 480, 482, 484, 523, 535, 540, - /* 70 */ 542, 544, 547, 549, 551, 590, 602, 606, 608, 610, - /* 80 */ 614, 618, 657, 669, 673, 675, 677, 681, 686, 724, - /* 90 */ 736, 740, 742, 744, -215, -215, -77, -215, -215, -215, - /* 100 */ -215, 50, 354, 473, 541, 603, 144, 604, 772, 342, - /* 110 */ 284, -215, -215, -215, -215, 282, 251, 322, 462, -72, - /* 120 */ 177, 306, 428, 353, 193, 475, 421, 477, 509, 575, - /* 130 */ 707, 750, 768, 771, 556, 769, 663, 733, 765, 807, - /* 140 */ 808, -42, 499, -126, -112, -57, -19, 18, 96, 18, - /* 150 */ 18, 72, 141, 146, 198, 250, 223, 336, 370, 373, - /* 160 */ 250, 543, 534, 561, 607, 563, 623, 626, 18, 563, - /* 170 */ 634, 690, 662, 670, 679, 706, 739, 18, 760, 777, - /* 180 */ 18, 802, 730, 749, 847, 855, 18, 857, 858, 866, - /* 190 */ 18, 867, 18, 18, 870, 871, 872, 873, 874, 880, - /* 200 */ 863, 844, 831, 832, 800, 801, 803, 859, 860, 853, - /* 210 */ 861, 864, 862, 843, 845, 895, 896, 897, 898, 892, - /* 220 */ 877, 881, 885, 884, 883, 886, 887, 890, 891, 893, - /* 230 */ 868, 894, 846, 923, 882, 931, 899, 942, 901, 902, - /* 240 */ 904, 906, 935, 903, 910, 953, 927, 955, 956, 961, - /* 250 */ 950, 983, 981, 985, 986, 987, 914, 911, 997, 1000, - /* 260 */ 984, 972, 974, 947, 966, 976, 979, 989, 970, 993, - /* 270 */ 958, 1016, 934, 957, 1019, 1026, 959, 1021, 1006, 1007, + /* 50 */ -215, -215, -215, -215, -215, 610, 606, 590, 551, 543, + /* 60 */ 539, 523, 483, 476, 469, 415, 408, 136, 740, -11, + /* 70 */ 401, 413, 417, 473, 478, 485, 535, 541, 547, 553, + /* 80 */ 602, 608, 614, 4, 616, 619, 657, 669, 673, 675, + /* 90 */ 677, 681, 742, 685, -215, -215, 326, -215, -215, -215, + /* 100 */ -215, 199, 14, 536, 605, -78, 409, 671, 724, 736, + /* 110 */ 347, -215, -215, -215, -215, 799, 538, 719, 717, 745, + /* 120 */ 690, 806, 22, 776, 775, 773, 626, 769, 493, 768, + /* 130 */ 767, 682, 766, 738, 3, 558, 735, 730, 702, 495, + /* 140 */ 467, 286, 249, 1041, 1028, 1035, 1022, -46, -46, -46, + /* 150 */ 1086, 1013, 1050, 1049, -123, 892, 890, 888, 885, 884, + /* 160 */ 883, 879, 875, 873, 567, 845, 834, 822, 805, -46, + /* 170 */ 770, 753, 639, -46, 395, -46, 567, -46, 387, 403, + /* 180 */ 94, 66, -46, -104, -140, -123, -90, 80, 111, 193, + /* 190 */ 255, -46, 603, 634, -46, 693, 701, 747, 760, 774, + /* 200 */ 732, 794, 782, 830, 840, 847, 828, 853, 836, 880, + /* 210 */ 858, 839, 813, 861, 848, 849, 862, 860, 864, 897, + /* 220 */ 909, 866, 891, 837, 871, 912, 857, 928, 894, 916, + /* 230 */ 938, 934, 939, 878, 893, 919, 937, 881, 867, 940, + /* 240 */ 913, 942, 898, 915, 962, 929, 953, 973, 941, 918, + /* 250 */ 963, 964, 985, 989, 903, 995, 922, 968, 996, 974, + /* 260 */ 954, 955, 948, 930, 992, 997, 1020, 932, 1017, 1000, + /* 270 */ 994, 998, 970, 1024, 976, 1025, 1004, 1006, 1009, 1027, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 567, 791, 856, 682, 856, 791, 856, 791, 856, 829, - /* 10 */ 829, 686, 842, 787, 791, 856, 856, 856, 762, 813, - /* 20 */ 856, 598, 813, 813, 717, 856, 856, 856, 856, 856, - /* 30 */ 856, 856, 856, 718, 856, 790, 786, 782, 784, 783, - /* 40 */ 719, 706, 715, 722, 698, 827, 724, 725, 730, 731, - /* 50 */ 843, 846, 752, 768, 751, 856, 856, 856, 856, 856, + /* 0 */ 567, 791, 856, 682, 856, 856, 791, 791, 856, 829, + /* 10 */ 829, 686, 842, 856, 791, 856, 856, 787, 762, 813, + /* 20 */ 856, 813, 598, 813, 717, 856, 856, 856, 856, 856, + /* 30 */ 856, 856, 856, 724, 782, 784, 846, 783, 718, 719, + /* 40 */ 725, 843, 856, 706, 827, 715, 730, 722, 731, 786, + /* 50 */ 698, 790, 752, 768, 751, 856, 856, 856, 856, 856, /* 60 */ 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, /* 70 */ 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, /* 80 */ 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, - /* 90 */ 856, 856, 856, 856, 754, 773, 591, 753, 761, 755, - /* 100 */ 756, 651, 856, 856, 856, 856, 586, 856, 856, 856, - /* 110 */ 856, 757, 758, 769, 770, 856, 856, 856, 856, 567, - /* 120 */ 682, 856, 682, 856, 856, 856, 856, 856, 856, 856, - /* 130 */ 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, - /* 140 */ 856, 676, 686, 856, 856, 642, 856, 856, 856, 856, - /* 150 */ 856, 856, 856, 856, 856, 856, 574, 572, 856, 674, - /* 160 */ 856, 856, 600, 856, 856, 684, 856, 856, 689, 690, - /* 170 */ 856, 856, 856, 856, 856, 856, 856, 588, 856, 856, - /* 180 */ 663, 856, 819, 856, 856, 856, 834, 856, 856, 856, - /* 190 */ 832, 856, 665, 727, 801, 856, 856, 847, 849, 856, - /* 200 */ 856, 709, 674, 683, 856, 856, 785, 709, 709, 621, - /* 210 */ 709, 709, 624, 721, 721, 571, 571, 571, 571, 641, - /* 220 */ 653, 653, 638, 653, 624, 653, 856, 721, 712, 714, - /* 230 */ 702, 716, 856, 691, 710, 856, 710, 691, 699, 701, - /* 240 */ 699, 701, 795, 710, 710, 856, 638, 653, 653, 653, - /* 250 */ 795, 583, 691, 691, 691, 691, 823, 826, 583, 691, - /* 260 */ 653, 655, 655, 732, 721, 662, 662, 662, 721, 655, - /* 270 */ 732, 691, 845, 845, 691, 691, 854, 608, 626, 626, - /* 280 */ 856, 856, 856, 856, 856, 856, 739, 856, 856, 856, + /* 90 */ 856, 856, 856, 856, 773, 754, 591, 761, 753, 755, + /* 100 */ 756, 651, 586, 856, 856, 856, 856, 856, 856, 856, + /* 110 */ 856, 757, 769, 770, 758, 856, 856, 856, 856, 856, + /* 120 */ 856, 856, 856, 856, 856, 856, 856, 856, 567, 856, + /* 130 */ 856, 856, 856, 682, 856, 682, 856, 856, 856, 856, + /* 140 */ 856, 686, 676, 856, 642, 856, 856, 856, 856, 856, + /* 150 */ 856, 856, 856, 856, 856, 856, 572, 856, 856, 856, + /* 160 */ 574, 856, 856, 856, 684, 600, 856, 847, 856, 689, + /* 170 */ 849, 801, 674, 588, 856, 727, 690, 832, 819, 856, + /* 180 */ 856, 856, 834, 856, 856, 856, 856, 856, 856, 856, + /* 190 */ 856, 663, 856, 856, 665, 856, 856, 856, 856, 856, + /* 200 */ 856, 709, 856, 709, 624, 709, 683, 709, 674, 856, + /* 210 */ 709, 721, 785, 621, 721, 721, 655, 662, 662, 691, + /* 220 */ 571, 721, 795, 856, 662, 691, 710, 571, 638, 856, + /* 230 */ 571, 691, 583, 710, 716, 795, 856, 732, 854, 653, + /* 240 */ 721, 653, 710, 712, 691, 714, 653, 641, 702, 732, + /* 250 */ 653, 653, 691, 583, 845, 691, 823, 655, 691, 653, + /* 260 */ 699, 701, 710, 826, 653, 624, 571, 845, 691, 653, + /* 270 */ 638, 655, 701, 691, 699, 691, 856, 626, 626, 608, + /* 280 */ 856, 856, 856, 856, 856, 808, 856, 856, 856, 739, /* 290 */ 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, - /* 300 */ 856, 808, 856, 856, 856, 856, 856, 744, 740, 856, - /* 310 */ 741, 856, 856, 856, 856, 668, 856, 856, 856, 856, - /* 320 */ 856, 856, 856, 703, 856, 713, 856, 856, 856, 856, - /* 330 */ 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, - /* 340 */ 856, 856, 856, 856, 856, 821, 822, 856, 856, 856, - /* 350 */ 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, - /* 360 */ 856, 856, 856, 856, 856, 856, 856, 853, 856, 856, - /* 370 */ 568, 856, 562, 565, 564, 566, 570, 573, 595, 596, - /* 380 */ 597, 575, 576, 577, 578, 579, 580, 581, 587, 589, - /* 390 */ 607, 609, 616, 654, 657, 658, 659, 837, 838, 839, - /* 400 */ 617, 636, 639, 640, 618, 625, 707, 708, 619, 672, - /* 410 */ 673, 736, 666, 667, 671, 738, 742, 743, 745, 746, - /* 420 */ 594, 601, 602, 605, 606, 809, 811, 810, 812, 604, - /* 430 */ 603, 747, 750, 759, 760, 766, 772, 775, 764, 765, - /* 440 */ 767, 771, 774, 669, 670, 778, 780, 781, 835, 836, - /* 450 */ 776, 788, 789, 692, 779, 763, 704, 593, 711, 705, - /* 460 */ 675, 685, 694, 695, 696, 697, 680, 681, 687, 700, - /* 470 */ 734, 735, 688, 677, 678, 679, 777, 737, 748, 749, - /* 480 */ 620, 627, 628, 629, 632, 633, 634, 635, 630, 631, - /* 490 */ 796, 797, 799, 798, 622, 623, 637, 610, 611, 612, - /* 500 */ 613, 744, 614, 615, 599, 592, 643, 646, 647, 648, - /* 510 */ 649, 650, 652, 644, 645, 590, 582, 584, 693, 815, - /* 520 */ 824, 825, 820, 816, 817, 818, 585, 792, 793, 656, - /* 530 */ 728, 729, 814, 828, 830, 733, 831, 833, 660, 661, - /* 540 */ 664, 800, 840, 720, 723, 726, 802, 803, 804, 805, - /* 550 */ 806, 807, 841, 844, 848, 850, 851, 852, 855, 569, + /* 300 */ 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, + /* 310 */ 822, 856, 856, 856, 821, 856, 856, 856, 856, 856, + /* 320 */ 856, 856, 856, 856, 713, 856, 856, 856, 744, 856, + /* 330 */ 740, 703, 856, 856, 856, 856, 856, 856, 856, 856, + /* 340 */ 856, 856, 856, 856, 856, 856, 741, 856, 856, 856, + /* 350 */ 856, 856, 856, 668, 856, 856, 856, 856, 856, 856, + /* 360 */ 856, 856, 856, 853, 856, 856, 856, 856, 856, 568, + /* 370 */ 856, 856, 838, 649, 839, 837, 648, 650, 652, 644, + /* 380 */ 645, 590, 647, 617, 659, 646, 750, 592, 599, 582, + /* 390 */ 615, 614, 584, 744, 613, 612, 636, 611, 610, 637, + /* 400 */ 623, 622, 798, 658, 799, 693, 797, 639, 815, 657, + /* 410 */ 654, 796, 640, 824, 825, 820, 631, 630, 635, 816, + /* 420 */ 817, 634, 818, 585, 633, 632, 629, 628, 627, 620, + /* 430 */ 749, 616, 748, 737, 792, 793, 777, 679, 678, 677, + /* 440 */ 609, 656, 728, 729, 688, 814, 618, 625, 828, 707, + /* 450 */ 708, 735, 607, 734, 700, 687, 681, 589, 830, 680, + /* 460 */ 587, 619, 697, 696, 695, 694, 685, 733, 675, 672, + /* 470 */ 673, 581, 705, 711, 580, 831, 593, 704, 736, 666, + /* 480 */ 833, 763, 779, 579, 660, 692, 661, 789, 788, 664, + /* 490 */ 667, 578, 800, 776, 840, 836, 835, 577, 671, 720, + /* 500 */ 738, 576, 781, 575, 780, 723, 742, 597, 743, 745, + /* 510 */ 746, 778, 596, 670, 726, 669, 802, 594, 774, 601, + /* 520 */ 595, 803, 804, 805, 806, 771, 767, 807, 765, 573, + /* 530 */ 764, 570, 602, 841, 605, 566, 844, 606, 775, 564, + /* 540 */ 772, 766, 848, 760, 759, 850, 809, 565, 811, 810, + /* 550 */ 812, 851, 604, 603, 562, 852, 855, 747, 643, 569, /* 560 */ 563, }; #define YY_SZ_ACTTAB (sizeof(yy_action)/sizeof(yy_action[0])) /* The next table maps tokens into fallback tokens. If a construct Index: SQLite.Interop/src/pragma.c ================================================================== --- SQLite.Interop/src/pragma.c +++ SQLite.Interop/src/pragma.c @@ -9,11 +9,11 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** -** $Id: pragma.c,v 1.13 2006/01/11 03:22:29 rmsimpson Exp $ +** $Id: pragma.c,v 1.14 2006/01/12 20:54:07 rmsimpson Exp $ */ #include "sqliteInt.h" #include "os.h" #include @@ -149,10 +149,11 @@ { "vdbe_listing", SQLITE_VdbeListing }, { "full_column_names", SQLITE_FullColNames }, { "short_column_names", SQLITE_ShortColNames }, { "count_changes", SQLITE_CountRows }, { "empty_result_callbacks", SQLITE_NullCallback }, + { "legacy_file_format", SQLITE_LegacyFileFmt }, #ifndef SQLITE_OMIT_CHECK { "ignore_check_constraints", SQLITE_IgnoreChecks }, #endif /* The following is VERY experimental */ { "writable_schema", SQLITE_WriteSchema }, @@ -806,11 +807,14 @@ /* Only change the value of sqlite.enc if the database handle is not ** initialized. If the main database exists, the new sqlite.enc value ** will be overwritten when the schema is next loaded. If it does not ** already exists, it will be created to use the new encoding value. */ - if( !(pParse->db->flags&SQLITE_Initialized) ){ + if( + !(DbHasProperty(db, 0, DB_SchemaLoaded)) || + DbHasProperty(db, 0, DB_Empty) + ){ for(pEnc=&encnames[0]; pEnc->zName; pEnc++){ if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){ ENC(pParse->db) = pEnc->enc; break; } Index: SQLite.Interop/src/prepare.c ================================================================== --- SQLite.Interop/src/prepare.c +++ SQLite.Interop/src/prepare.c @@ -11,11 +11,11 @@ ************************************************************************* ** This file contains the implementation of the sqlite3_prepare() ** interface, and routines that contribute to loading the database schema ** from disk. ** -** $Id: prepare.c,v 1.9 2006/01/11 03:22:29 rmsimpson Exp $ +** $Id: prepare.c,v 1.10 2006/01/12 20:54:07 rmsimpson Exp $ */ #include "sqliteInt.h" #include "os.h" #include @@ -22,11 +22,11 @@ /* ** Fill the InitData structure with an error message that indicates ** that the database is corrupt. */ static void corruptSchema(InitData *pData, const char *zExtra){ - if( !sqlite3ThreadData()->mallocFailed ){ + if( !sqlite3ThreadDataReadOnly()->mallocFailed ){ sqlite3SetString(pData->pzErrMsg, "malformed database schema", zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0); } } @@ -47,11 +47,11 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){ InitData *pData = (InitData*)pInit; sqlite3 *db = pData->db; int iDb; - if( sqlite3ThreadData()->mallocFailed ){ + if( sqlite3ThreadDataReadOnly()->mallocFailed ){ return SQLITE_NOMEM; } assert( argc==4 ); if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ @@ -152,31 +152,11 @@ #else #define temp_master_schema 0 #endif assert( iDb>=0 && iDbnDb ); - assert( db->aDb[iDb].pSchema ); -#if 0 - if( 0==db->aDb[iDb].pSchema ){ - Schema *pS = sqlite3SchemaGet(db->aDb[iDb].pBt); - db->aDb[iDb].pSchema = pS; - if( !pS ){ - return SQLITE_NOMEM; - }else if( pS->file_format!=0 ){ - /* This means that the shared-schema associated with the the btree - ** is already open and populated. - */ - if( pS->enc!=ENC(db) ){ - sqlite3SetString(pzErrMsg, "attached databases must use the same" - " text encoding as main database", (char*)0); - return SQLITE_ERROR; - } - return SQLITE_OK; - } - } -#endif /* zMasterSchema and zInitScript are set to point at the master schema ** and initialisation script appropriate for the database being ** initialised. zMasterName is the name of the master table. */ @@ -210,11 +190,13 @@ /* Create a cursor to hold the database open */ pDb = &db->aDb[iDb]; if( pDb->pBt==0 ){ - if( !OMIT_TEMPDB && iDb==1 ) DbSetProperty(db, 1, DB_SchemaLoaded); + if( !OMIT_TEMPDB && iDb==1 ){ + DbSetProperty(db, 1, DB_SchemaLoaded); + } return SQLITE_OK; } rc = sqlite3BtreeCursor(pDb->pBt, MASTER_ROOT, 0, 0, 0, &curMain); if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){ sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0); @@ -270,10 +252,12 @@ sqlite3SetString(pzErrMsg, "attached databases must use the same" " text encoding as main database", (char*)0); return SQLITE_ERROR; } } + }else{ + DbSetProperty(db, iDb, DB_Empty); } pDb->pSchema->enc = ENC(db); size = meta[2]; if( size==0 ){ size = MAX_PAGES; } @@ -317,11 +301,11 @@ sqlite3AnalysisLoad(db, iDb); } #endif sqlite3BtreeCloseCursor(curMain); } - if( sqlite3ThreadData()->mallocFailed ){ + if( sqlite3ThreadDataReadOnly()->mallocFailed ){ sqlite3SetString(pzErrMsg, "out of memory", (char*)0); rc = SQLITE_NOMEM; sqlite3ResetInternalSchema(db, 0); } if( rc==SQLITE_OK ){ @@ -341,21 +325,22 @@ ** After the database is initialized, the SQLITE_Initialized ** bit is set in the flags field of the sqlite structure. */ int sqlite3Init(sqlite3 *db, char **pzErrMsg){ int i, rc; + int called_initone = 0; if( db->init.busy ) return SQLITE_OK; - assert( (db->flags & SQLITE_Initialized)==0 ); rc = SQLITE_OK; db->init.busy = 1; for(i=0; rc==SQLITE_OK && inDb; i++){ if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue; rc = sqlite3InitOne(db, i, pzErrMsg); if( rc ){ sqlite3ResetInternalSchema(db, i); } + called_initone = 1; } /* Once all the other databases have been initialised, load the schema ** for the TEMP database. This is loaded last, as the TEMP database ** schema may contain references to objects in other databases. @@ -364,23 +349,20 @@ if( rc==SQLITE_OK && db->nDb>1 && !DbHasProperty(db, 1, DB_SchemaLoaded) ){ rc = sqlite3InitOne(db, 1, pzErrMsg); if( rc ){ sqlite3ResetInternalSchema(db, 1); } + called_initone = 1; } #endif db->init.busy = 0; - if( rc==SQLITE_OK ){ - db->flags |= SQLITE_Initialized; + if( rc==SQLITE_OK && called_initone ){ sqlite3CommitInternalChanges(db); } - if( rc!=SQLITE_OK ){ - db->flags &= ~SQLITE_Initialized; - } - return rc; + return rc; } /* ** This routine is a no-op if the database schema is already initialised. ** Otherwise, the schema is loaded. An error code is returned. @@ -387,15 +369,12 @@ */ int sqlite3ReadSchema(Parse *pParse){ int rc = SQLITE_OK; sqlite3 *db = pParse->db; if( !db->init.busy ){ - if( (db->flags & SQLITE_Initialized)==0 ){ - rc = sqlite3Init(db, &pParse->zErrMsg); - } + rc = sqlite3Init(db, &pParse->zErrMsg); } - assert( rc!=SQLITE_OK || (db->flags & SQLITE_Initialized) || db->init.busy ); if( rc!=SQLITE_OK ){ pParse->rc = rc; pParse->nErr++; } return rc; @@ -513,11 +492,11 @@ Parse sParse; char *zErrMsg = 0; int rc = SQLITE_OK; int i; - assert( !sqlite3ThreadData()->mallocFailed ); + assert( !sqlite3ThreadDataReadOnly()->mallocFailed ); assert( ppStmt ); *ppStmt = 0; if( sqlite3SafetyOn(db) ){ return SQLITE_MISUSE; @@ -536,13 +515,15 @@ } } memset(&sParse, 0, sizeof(sParse)); sParse.db = db; + sParse.pTsd = sqlite3ThreadData(); + sParse.pTsd->nRef++; sqlite3RunParser(&sParse, zSql, &zErrMsg); - if( sqlite3ThreadData()->mallocFailed ){ + if( sParse.pTsd->mallocFailed ){ sParse.rc = SQLITE_NOMEM; } if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK; if( sParse.checkSchema && !schemaIsValid(db) ){ sParse.rc = SQLITE_SCHEMA; @@ -588,16 +569,18 @@ } /* We must check for malloc failure last of all, in case malloc() failed ** inside of the sqlite3Error() call above or something. */ - if( sqlite3ThreadData()->mallocFailed ){ + if( sParse.pTsd->mallocFailed ){ rc = SQLITE_NOMEM; sqlite3Error(db, rc, 0); } + sParse.pTsd->nRef--; sqlite3MallocClearFailed(); + sqlite3ReleaseThreadData(); return rc; } #ifndef SQLITE_OMIT_UTF16 /* Index: SQLite.Interop/src/random.c ================================================================== --- SQLite.Interop/src/random.c +++ SQLite.Interop/src/random.c @@ -13,11 +13,11 @@ ** generator (PRNG) for SQLite. ** ** Random numbers are used by some of the database backends in order ** to generate random integer keys for tables or random filenames. ** -** $Id: random.c,v 1.13 2006/01/11 03:22:29 rmsimpson Exp $ +** $Id: random.c,v 1.14 2006/01/12 20:54:07 rmsimpson Exp $ */ #include "sqliteInt.h" #include "os.h" Index: SQLite.Interop/src/select.c ================================================================== --- SQLite.Interop/src/select.c +++ SQLite.Interop/src/select.c @@ -10,11 +10,11 @@ ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** -** $Id: select.c,v 1.13 2006/01/11 03:22:30 rmsimpson Exp $ +** $Id: select.c,v 1.14 2006/01/12 20:54:07 rmsimpson Exp $ */ #include "sqliteInt.h" /* @@ -870,11 +870,12 @@ return; } #endif assert( v!=0 ); - if( pParse->colNamesSet || v==0 || sqlite3ThreadData()->mallocFailed ) return; + if( pParse->colNamesSet || v==0 + || sqlite3ThreadDataReadOnly()->mallocFailed ) return; pParse->colNamesSet = 1; fullNames = (db->flags & SQLITE_FullColNames)!=0; shortNames = (db->flags & SQLITE_ShortColNames)!=0; sqlite3VdbeSetNumCols(v, pEList->nExpr); for(i=0; inExpr; i++){ @@ -999,11 +1000,11 @@ }else{ /* If all else fails, make up a name */ zName = sqlite3MPrintf("column%d", i+1); } sqlite3Dequote(zName); - if( sqlite3ThreadData()->mallocFailed ){ + if( sqlite3ThreadDataReadOnly()->mallocFailed ){ sqliteFree(zName); sqlite3DeleteTable(0, pTab); return 0; } @@ -1071,11 +1072,13 @@ SrcList *pTabList; ExprList *pEList; Table *pTab; struct SrcList_item *pFrom; - if( p==0 || p->pSrc==0 || sqlite3ThreadData()->mallocFailed ) return 1; + if( p==0 || p->pSrc==0 || sqlite3ThreadDataReadOnly()->mallocFailed ){ + return 1; + } pTabList = p->pSrc; pEList = p->pEList; /* Make sure cursor numbers have been assigned to all entries in ** the FROM clause of the SELECT statement. @@ -2688,11 +2691,13 @@ int rc = 1; /* Value to return from this function */ int addrSortIndex; /* Address of an OP_OpenVirtual instruction */ AggInfo sAggInfo; /* Information used by aggregate queries */ int iEnd; /* Address of the end of the query */ - if( sqlite3ThreadData()->mallocFailed || pParse->nErr || p==0 ) return 1; + if( p==0 || sqlite3ThreadDataReadOnly()->mallocFailed || pParse->nErr ){ + return 1; + } if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; memset(&sAggInfo, 0, sizeof(sAggInfo)); #ifndef SQLITE_OMIT_COMPOUND_SELECT /* If there is are a sequence of queries, do the earlier ones first. @@ -2942,11 +2947,11 @@ for(i=0; ipList) ){ goto select_end; } } - if( sqlite3ThreadData()->mallocFailed ) goto select_end; + if( sqlite3ThreadDataReadOnly()->mallocFailed ) goto select_end; /* Processing for aggregates with GROUP BY is very different and ** much more complex tha aggregates without a GROUP BY. */ if( pGroupBy ){ Index: SQLite.Interop/src/server.c ================================================================== --- SQLite.Interop/src/server.c +++ SQLite.Interop/src/server.c @@ -60,12 +60,11 @@ ** and concurrency improvements and memory usage reductions by going ** client/server. ** ** Note: The extra features of version 3.3.0 described by points (2) ** through (4) above are only available if you compile without the -** option -DSQLITE_OMIT_SHARED_CACHE. For reasons of backwards -** compatibility, SQLite is compile with this option by default. +** option -DSQLITE_OMIT_SHARED_CACHE. ** ** Here is how the client/server approach works: The database server ** thread is started on this procedure: ** ** void *sqlite3_server(void *NotUsed); @@ -254,11 +253,11 @@ ** sqlite3_reset ** sqlite3_finalize ** sqlite3_close ** ** Clients should use the following client-side routines instead of -** the core routines. +** the core routines above. ** ** sqlite3_client_open ** sqlite3_client_prepare ** sqlite3_client_step ** sqlite3_client_reset @@ -329,11 +328,13 @@ ** on this procedure. See the sqlite3_server_start() routine below ** for an example. This procedure loops until g.serverHalt becomes ** true. */ void *sqlite3_server(void *NotUsed){ + sqlite3_enable_shared_cache(1); if( pthread_mutex_trylock(&g.serverMutex) ){ + sqlite3_enable_shared_cache(0); return 0; /* Another server is already running */ } while( !g.serverHalt ){ SqlMessage *pMsg; @@ -391,10 +392,11 @@ pMsg->op = MSG_Done; pthread_mutex_unlock(&pMsg->clientMutex); pthread_cond_signal(&pMsg->clientWakeup); } pthread_mutex_unlock(&g.serverMutex); + sqlite3_thread_cleanup(); return 0; } /* ** Start a server thread if one is not already running. If there Index: SQLite.Interop/src/shell.c ================================================================== --- SQLite.Interop/src/shell.c +++ SQLite.Interop/src/shell.c @@ -10,11 +10,11 @@ ** ************************************************************************* ** This file contains code to implement the "sqlite" command line ** utility for accessing SQLite databases. ** -** $Id: shell.c,v 1.13 2006/01/11 03:22:29 rmsimpson Exp $ +** $Id: shell.c,v 1.14 2006/01/12 20:54:07 rmsimpson Exp $ */ #include #include #include #include Index: SQLite.Interop/src/sqlite3.def ================================================================== --- SQLite.Interop/src/sqlite3.def +++ SQLite.Interop/src/sqlite3.def @@ -38,11 +38,10 @@ sqlite3_create_collation16 sqlite3_create_function sqlite3_create_function16 sqlite3_data_count sqlite3_db_handle -sqlite3_enable_memory_management sqlite3_enable_shared_cache sqlite3_errcode sqlite3_errmsg sqlite3_errmsg16 sqlite3_exec @@ -62,11 +61,10 @@ sqlite3_open sqlite3_open16 sqlite3_prepare sqlite3_prepare16 sqlite3_progress_handler -sqlite3_release_memory sqlite3_reset sqlite3_result_blob sqlite3_result_double sqlite3_result_error sqlite3_result_error16 @@ -80,12 +78,12 @@ sqlite3_result_value sqlite3_rollback_hook sqlite3_set_authorizer sqlite3_set_auxdata sqlite3_snprintf -sqlite3_soft_heap_limit sqlite3_step +sqlite3_thread_cleanup sqlite3_total_changes sqlite3_trace sqlite3_transfer_bindings sqlite3_update_hook sqlite3_user_data Index: SQLite.Interop/src/sqlite3.h ================================================================== --- SQLite.Interop/src/sqlite3.h +++ SQLite.Interop/src/sqlite3.h @@ -10,11 +10,11 @@ ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** -** @(#) $Id: sqlite3.h,v 1.14 2006/01/11 03:22:30 rmsimpson Exp $ +** @(#) $Id: sqlite3.h,v 1.15 2006/01/12 20:54:07 rmsimpson Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ #include /* Needed for the definition of va_list */ @@ -190,10 +190,11 @@ #define SQLITE_FORMAT 24 /* Auxiliary database format error */ #define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */ #define SQLITE_NOTADB 26 /* File opened that is not a database file */ #define SQLITE_ROW 100 /* sqlite3_step() has another row ready */ #define SQLITE_DONE 101 /* sqlite3_step() has finished executing */ +/* end-of-return-codes */ /* ** 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, ** otherwise the key is generated at random. The unique key is always @@ -1327,25 +1328,17 @@ ** disable (if the argument is true or false, respectively) the ** "shared pager" feature. */ int sqlite3_enable_shared_cache(int); -/* -** This function is only available if the library is compiled without -** the SQLITE_OMIT_MEMORY_MANAGEMENT macro defined. It is used to enable or -** disable (if the argument is true or false, respectively) the -** "memory management" features (accessed via the sqlite3_soft_heap_limit() -** and sqlite3_release_memory() APIs). -*/ -int sqlite3_enable_memory_management(int); - /* ** Attempt to free N bytes of heap memory by deallocating non-essential ** memory allocations held by the database library (example: memory ** used to cache database pages to improve performance). ** -** This function is a no-op unless memory-management has been enabled. +** This function is not a part of standard builds. It is only created +** if SQLite is compiled with the SQLITE_ENABLE_MEMORY_MANAGEMENT macro. */ int sqlite3_release_memory(int); /* ** Place a "soft" limit on the amount of heap memory that may be allocated by @@ -1355,16 +1348,29 @@ ** ** The limit is called "soft", because if sqlite3_release_memory() cannot free ** sufficient memory to prevent the limit from being exceeded, the memory is ** allocated anyway and the current operation proceeds. ** -** This function is only available if the library was compiled without the -** SQLITE_OMIT_MEMORY_MANAGEMENT option set. It is a no-op unless +** This function is only available if the library was compiled with the +** SQLITE_ENABLE_MEMORY_MANAGEMENT option set. ** memory-management has been enabled. */ void sqlite3_soft_heap_limit(int); +/* +** This routine makes sure that all thread-local storage has been +** deallocated for the current thread. +** +** This routine is not technically necessary. All thread-local storage +** will be automatically deallocated once memory-management and +** shared-cache are disabled and the soft heap limit has been set +** to zero. This routine is provided as a convenience for users who +** want to make absolutely sure they have not forgotten something +** prior to killing off a thread. +*/ +void sqlite3_thread_cleanup(void); + /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. */ #ifdef SQLITE_OMIT_FLOATING_POINT Index: SQLite.Interop/src/sqliteInt.h ================================================================== --- SQLite.Interop/src/sqliteInt.h +++ SQLite.Interop/src/sqliteInt.h @@ -9,11 +9,11 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.13 2006/01/11 03:22:30 rmsimpson Exp $ +** @(#) $Id: sqliteInt.h,v 1.14 2006/01/12 20:54:07 rmsimpson Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* @@ -284,18 +284,22 @@ #define sqliteFree(x) sqlite3FreeX(x) #define sqliteAllocSize(x) sqlite3AllocSize(x) /* -** An instance of this structure is allocated for each thread that uses SQLite. +** An instance of this structure might be allocated to store information +** specific to a single thread. +** +** To avoid a memory leak on windows, the content of this structure is +** checked at the conclusion of each API call. If it is all zero, it +** is deallocated. */ struct ThreadData { - u8 isInit; /* True if structure has been initialised */ - u8 mallocFailed; /* True after a malloc() has failed */ + int mallocFailed; /* True after a malloc() has failed */ + int nRef; /* Number of users */ -#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT - u8 useMemoryManagement; /* True if memory-management is enabled */ +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT int nSoftHeapLimit; /* Suggested max mem allocation. No limit if <0 */ int nAlloc; /* Number of bytes currently allocated */ Pager *pPager; /* Linked list of all pagers in this thread */ #endif @@ -304,11 +308,11 @@ BtShared *pBtree; /* Linked list of all currently open BTrees */ #endif #ifdef SQLITE_MEMDEBUG int nMaxAlloc; /* High water mark of ThreadData.nAlloc */ - int mallocAllowed; /* assert() in sqlite3Malloc() if not set */ + int mallocDisallowed; /* assert() in sqlite3Malloc() if set */ int isFail; /* True if all malloc() calls should fail */ const char *zFile; /* Filename to associate debugging info with */ int iLine; /* Line number to associate debugging info with */ void *pFirst; /* Pointer to linked list of allocations */ #endif @@ -395,13 +399,13 @@ Hash idxHash; /* All (named) indices indexed by name */ Hash trigHash; /* All triggers indexed by name */ Hash aFKey; /* Foreign keys indexed by to-table */ Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */ u8 file_format; /* Schema format version for this file */ + u8 enc; /* Text encoding used by this database */ u16 flags; /* Flags associated with this schema */ int cache_size; /* Number of pages to use in the cache */ - u8 enc; /* Text encoding used by this database */ }; /* ** These macros can be used to test, set, or clear bits in the ** Db.flags field. @@ -421,10 +425,11 @@ ** have been filled out. If the schema changes, these column names might ** changes and so the view will need to be reset. */ #define DB_SchemaLoaded 0x0001 /* The schema has been loaded */ #define DB_UnresetViews 0x0002 /* Some views have defined column names */ +#define DB_Empty 0x0004 /* The file is empty (length 0 bytes) */ #define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE) /* ** Each database is an instance of the following structure. @@ -520,11 +525,10 @@ ** On sqlite.flags, the SQLITE_InTrans value means that we have ** executed a BEGIN. On Db.flags, SQLITE_InTrans means a statement ** transaction is active on that particular database file. */ #define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */ -#define SQLITE_Initialized 0x00000002 /* True after initialization */ #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 */ #define SQLITE_ShortColNames 0x00000040 /* Show short columns names */ @@ -538,10 +542,11 @@ #define SQLITE_WriteSchema 0x00000800 /* OK to update SQLITE_MASTER */ #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_LegacyFileFmt 0x00008000 /* Create new databases in format 1 */ /* ** Possible values for the sqlite.magic field. ** The numbers are obtained at random and have no special meaning, other ** than being distinct from one another. @@ -1250,10 +1255,11 @@ int nMem; /* Number of memory cells used so far */ int nSet; /* Number of sets used so far */ int ckOffset; /* Stack offset to data used by CHECK constraints */ u32 writeMask; /* Start a write transaction on these databases */ u32 cookieMask; /* Bitmask of schema verified databases */ + ThreadData *pTsd; /* Thread specific data for this thread */ int cookieGoto; /* Address of OP_Goto to cookie verifier subroutine */ int cookieValue[MAX_ATTACHED+2]; /* Values of cookies to verify */ #ifndef SQLITE_OMIT_SHARED_CACHE int nTableLock; /* Number of locks in aTableLock */ TableLock *aTableLock; /* Required table locks for shared-cache mode */ @@ -1728,11 +1734,13 @@ int sqlite3FindDb(sqlite3*, Token*); void sqlite3AnalysisLoad(sqlite3*,int iDB); void sqlite3DefaultRowEst(Index*); void sqlite3RegisterLikeFunctions(sqlite3*, int); int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*); -ThreadData *sqlite3ThreadData(); +ThreadData *sqlite3ThreadData(void); +const ThreadData *sqlite3ThreadDataReadOnly(void); +void sqlite3ReleaseThreadData(void); void sqlite3AttachFunctions(sqlite3 *); void sqlite3MinimumFileFormat(Parse*, int, int); void sqlite3SchemaFree(void *); Schema *sqlite3SchemaGet(Btree *); int sqlite3SchemaToIndex(sqlite3 *db, Schema *); Index: SQLite.Interop/src/tclsqlite.c ================================================================== --- SQLite.Interop/src/tclsqlite.c +++ SQLite.Interop/src/tclsqlite.c @@ -9,11 +9,11 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* ** A TCL Interface to SQLite ** -** $Id: tclsqlite.c,v 1.13 2006/01/11 03:22:30 rmsimpson Exp $ +** $Id: tclsqlite.c,v 1.14 2006/01/12 20:54:08 rmsimpson Exp $ */ #ifndef NO_TCL /* Omit this whole file if TCL is unavailable */ #include "sqliteInt.h" #include "hash.h" Index: SQLite.Interop/src/tokenize.c ================================================================== --- SQLite.Interop/src/tokenize.c +++ SQLite.Interop/src/tokenize.c @@ -13,11 +13,11 @@ ** ** This file contains C code that splits an SQL input string up into ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** -** $Id: tokenize.c,v 1.16 2006/01/11 03:22:30 rmsimpson Exp $ +** $Id: tokenize.c,v 1.17 2006/01/12 20:54:08 rmsimpson Exp $ */ #include "sqliteInt.h" #include "os.h" #include #include @@ -259,11 +259,12 @@ ** a digit. Try to match #AAAA where AAAA is a parameter name. */ } #ifndef SQLITE_OMIT_TCL_VARIABLE case '$': #endif - case '@': case ':': { + case '@': + case ':': { int n = 0; *tokenType = TK_VARIABLE; for(i=1; (c=z[i])!=0; i++){ if( IdChar(c) ){ n++; @@ -337,10 +338,11 @@ int i; void *pEngine; int tokenType; int lastTokenParsed = -1; sqlite3 *db = pParse->db; + ThreadData *pTsd = pParse->pTsd; extern void *sqlite3ParserAlloc(void*(*)(int)); extern void sqlite3ParserFree(void*, void(*)(void*)); extern int sqlite3Parser(void*, int, Token, Parse*); db->flags &= ~SQLITE_Interrupt; @@ -356,11 +358,11 @@ assert( pParse->nVar==0 ); assert( pParse->nVarExpr==0 ); assert( pParse->nVarExprAlloc==0 ); assert( pParse->apVarExpr==0 ); pParse->zTail = pParse->zSql = zSql; - while( sqlite3ThreadData()->mallocFailed==0 && zSql[i]!=0 ){ + while( pTsd->mallocFailed==0 && zSql[i]!=0 ){ assert( i>=0 ); pParse->sLastToken.z = (u8*)&zSql[i]; assert( pParse->sLastToken.dyn==0 ); pParse->sLastToken.n = getToken((unsigned char*)&zSql[i],&tokenType); i += pParse->sLastToken.n; @@ -404,11 +406,11 @@ pParse->zTail = &zSql[i]; } sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse); } sqlite3ParserFree(pEngine, sqlite3FreeX); - if( sqlite3ThreadData()->mallocFailed ){ + if( pTsd->mallocFailed ){ pParse->rc = SQLITE_NOMEM; } if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){ sqlite3SetString(&pParse->zErrMsg, sqlite3ErrStr(pParse->rc), (char*)0); } Index: SQLite.Interop/src/trigger.c ================================================================== --- SQLite.Interop/src/trigger.c +++ SQLite.Interop/src/trigger.c @@ -79,18 +79,20 @@ /* If the trigger name was unqualified, and the table is a temp table, ** then set iDb to 1 to create the trigger in the temporary database. ** If sqlite3SrcListLookup() returns 0, indicating the table does not ** exist, the error is caught by the block below. */ - if( !pTableName || sqlite3ThreadData()->mallocFailed ) goto trigger_cleanup; + if( !pTableName || sqlite3ThreadDataReadOnly()->mallocFailed ){ + goto trigger_cleanup; + } pTab = sqlite3SrcListLookup(pParse, pTableName); if( pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){ iDb = 1; } /* Ensure the table name matches database name and that the table exists */ - if( sqlite3ThreadData()->mallocFailed ) goto trigger_cleanup; + if( sqlite3ThreadDataReadOnly()->mallocFailed ) goto trigger_cleanup; assert( pTableName->nSrc==1 ); if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName) && sqlite3FixSrcList(&sFix, pTableName) ){ goto trigger_cleanup; } @@ -253,11 +255,11 @@ Table *pTab; Trigger *pDel; pDel = sqlite3HashInsert(&db->aDb[iDb].pSchema->trigHash, pTrig->name, strlen(pTrig->name)+1, pTrig); if( pDel ){ - assert( sqlite3ThreadData()->mallocFailed && pDel==pTrig ); + assert( sqlite3ThreadDataReadOnly()->mallocFailed && pDel==pTrig ); goto triggerfinish_cleanup; } n = strlen(pTrig->table) + 1; pTab = sqlite3HashFind(&pTrig->pTabSchema->tblHash, pTrig->table, n); assert( pTab!=0 ); @@ -437,11 +439,11 @@ const char *zDb; const char *zName; int nName; sqlite3 *db = pParse->db; - if( sqlite3ThreadData()->mallocFailed ) goto drop_trigger_cleanup; + if( sqlite3ThreadDataReadOnly()->mallocFailed ) goto drop_trigger_cleanup; if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto drop_trigger_cleanup; } assert( pName->nSrc==1 ); Index: SQLite.Interop/src/update.c ================================================================== --- SQLite.Interop/src/update.c +++ SQLite.Interop/src/update.c @@ -10,11 +10,11 @@ ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** -** $Id: update.c,v 1.13 2006/01/11 03:22:30 rmsimpson Exp $ +** $Id: update.c,v 1.14 2006/01/12 20:54:08 rmsimpson Exp $ */ #include "sqliteInt.h" /* ** The most recently coded instruction was an OP_Column to retrieve the @@ -98,11 +98,13 @@ int newIdx = -1; /* index of trigger "new" temp table */ int oldIdx = -1; /* index of trigger "old" temp table */ sContext.pParse = 0; - if( pParse->nErr || sqlite3ThreadData()->mallocFailed ) goto update_cleanup; + if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ){ + goto update_cleanup; + } db = pParse->db; assert( pTabList->nSrc==1 ); /* Locate the table which we want to update. */ Index: SQLite.Interop/src/utf.c ================================================================== --- SQLite.Interop/src/utf.c +++ SQLite.Interop/src/utf.c @@ -10,11 +10,11 @@ ** ************************************************************************* ** This file contains routines used to translate between UTF-8, ** UTF-16, UTF-16BE, and UTF-16LE. ** -** $Id: utf.c,v 1.13 2006/01/11 03:22:30 rmsimpson Exp $ +** $Id: utf.c,v 1.14 2006/01/12 20:54:08 rmsimpson Exp $ ** ** Notes on UTF-8: ** ** Byte-0 Byte-1 Byte-2 Byte-3 Value ** 0xxxxxxx 00000000 00000000 0xxxxxxx Index: SQLite.Interop/src/util.c ================================================================== --- SQLite.Interop/src/util.c +++ SQLite.Interop/src/util.c @@ -12,11 +12,11 @@ ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** -** $Id: util.c,v 1.14 2006/01/11 03:22:30 rmsimpson Exp $ +** $Id: util.c,v 1.15 2006/01/12 20:54:08 rmsimpson Exp $ */ #include "sqliteInt.h" #include "os.h" #include #include @@ -64,27 +64,28 @@ ** * Audit outstanding memory allocations (i.e check for leaks). */ #define MAX(x,y) ((x)>(y)?(x):(y)) -#if !defined(SQLITE_OMIT_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO) +#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO) /* ** Set the soft heap-size limit for the current thread. Passing a negative ** value indicates no limit. */ void sqlite3_soft_heap_limit(int n){ sqlite3ThreadData()->nSoftHeapLimit = n; + sqlite3ReleaseThreadData(); } /* ** Release memory held by SQLite instances created by the current thread. */ int sqlite3_release_memory(int n){ return sqlite3pager_release_memory(n); } #else -/* If SQLITE_OMIT_MEMORY_MANAGEMENT is defined, then define a version +/* If SQLITE_ENABLE_MEMORY_MANAGEMENT is not defined, then define a version ** of sqlite3_release_memory() to be used by other code in this file. ** This is done for no better reason than to reduce the number of ** pre-processor #ifndef statements. */ #define sqlite3_release_memory(x) 0 /* 0 == no memory freed */ @@ -119,11 +120,13 @@ /* ** Number of 32-bit guard words. This should probably be a multiple of ** 2 since on 64-bit machines we want the value returned by sqliteMalloc() ** to be 8-byte aligned. */ -#define TESTALLOC_NGUARD 2 +#ifndef TESTALLOC_NGUARD +# define TESTALLOC_NGUARD 2 +#endif /* ** Size reserved for storing file-name along with each malloc()ed blob. */ #define TESTALLOC_FILESIZE 64 @@ -432,14 +435,15 @@ /* ** This is the test layer's wrapper around sqlite3OsMalloc(). */ static void * OSMALLOC(int n){ -#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT ThreadData *pTsd = sqlite3ThreadData(); pTsd->nMaxAlloc = MAX(pTsd->nMaxAlloc, pTsd->nAlloc); #endif + assert( !sqlite3ThreadData()->mallocDisallowed ); if( !failMalloc() ){ u32 *p; p = (u32 *)sqlite3OsMalloc(n + TESTALLOC_OVERHEAD); assert(p); sqlite3_nMalloc++; @@ -473,14 +477,15 @@ /* ** This is the test layer's wrapper around sqlite3OsRealloc(). */ static void * OSREALLOC(void *pRealloc, int n){ -#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT ThreadData *pTsd = sqlite3ThreadData(); pTsd->nMaxAlloc = MAX(pTsd->nMaxAlloc, pTsd->nAlloc); #endif + assert( !sqlite3ThreadData()->mallocDisallowed ); if( !failMalloc() ){ u32 *p = (u32 *)getOsPointer(pRealloc); checkGuards(p); p = sqlite3OsRealloc(p, n + TESTALLOC_OVERHEAD); applyGuards(p); @@ -502,11 +507,11 @@ #define OSREALLOC(x,y) sqlite3OsRealloc(x,y) #define OSFREE(x) sqlite3OsFree(x) #define OSSIZEOF(x) sqlite3OsAllocationSize(x) #define OSMALLOC_FAILED() -#endif +#endif /* SQLITE_MEMDEBUG */ /* ** End code for memory allocation system test layer. **--------------------------------------------------------------------------*/ /* @@ -517,18 +522,22 @@ ** means that the total memory allocated to SQLite in this thread would exceed ** the limit set by sqlite3_soft_heap_limit(), then sqlite3_release_memory() is ** called to try to avoid this. No indication of whether or not this is ** successful is returned to the caller. ** -** If SQLITE_OMIT_MEMORY_MANAGEMENT is defined, this function is a no-op. +** If SQLITE_ENABLE_MEMORY_MANAGEMENT is not defined, this routine is +** a no-op */ -#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT static void handleSoftLimit(int n){ ThreadData *pTsd = sqlite3ThreadData(); pTsd->nAlloc += n; + assert( pTsd->nAlloc>=0 ); if( n>0 && pTsd->nSoftHeapLimit>0 ){ while( pTsd->nAlloc>pTsd->nSoftHeapLimit && sqlite3_release_memory(n) ); + }else if( pTsd->nAlloc==0 && pTsd->nSoftHeapLimit==0 ){ + sqlite3ReleaseThreadData(); } } #else #define handleSoftLimit(x) #endif @@ -537,13 +546,12 @@ ** Allocate and return N bytes of uninitialised memory by calling ** sqlite3OsMalloc(). If the Malloc() call fails, attempt to free memory ** by calling sqlite3_release_memory(). */ void *sqlite3MallocRaw(int n){ - ThreadData *pTsd = sqlite3ThreadData(); void *p = 0; - if( n>0 && !pTsd->mallocFailed ){ + if( n>0 && !sqlite3ThreadDataReadOnly()->mallocFailed ){ handleSoftLimit(n); while( !(p = OSMALLOC(n)) && sqlite3_release_memory(n) ); if( !p ){ /* If the allocation failed, call handleSoftLimit() again, this time ** with the additive inverse of the argument passed to @@ -562,12 +570,11 @@ ** Resize the allocation at p to n bytes by calling sqlite3OsRealloc(). The ** pointer to the new allocation is returned. If the Realloc() call fails, ** attempt to free memory by calling sqlite3_release_memory(). */ void *sqlite3Realloc(void *p, int n){ - ThreadData *pTsd = sqlite3ThreadData(); - if( pTsd->mallocFailed ){ + if( sqlite3ThreadDataReadOnly()->mallocFailed ){ return 0; } if( !p ){ return sqlite3Malloc(n); @@ -580,11 +587,11 @@ ** with the additive inverse of the argument passed to ** handleSoftLimit() above. This is so the ThreadData.nAlloc variable is ** still correct after a malloc() failure. */ handleSoftLimit(OSSIZEOF(p) - n); - pTsd->mallocFailed = 1; + sqlite3ThreadData()->mallocFailed = 1; OSMALLOC_FAILED(); } return np; } } @@ -1304,65 +1311,58 @@ /* ** Return a pointer to the ThreadData associated with the calling thread. */ ThreadData *sqlite3ThreadData(){ - ThreadData *pTsd = sqlite3OsThreadSpecificData(sizeof(ThreadData)); - if( pTsd && !pTsd->isInit ){ -#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT - pTsd->nSoftHeapLimit = -1; -#endif -#ifndef NDEBUG - pTsd->mallocAllowed = 1; -#endif - pTsd->isInit = 1; - } - return pTsd; + return (ThreadData*)sqlite3OsThreadSpecificData(1); +} + +/* +** Return a pointer to the ThreadData associated with the calling thread. +** If no ThreadData has been allocated to this thread yet, return a pointer +** to a substitute ThreadData structure that is all zeros. +*/ +const ThreadData *sqlite3ThreadDataReadOnly(){ + static const ThreadData zeroData; + const ThreadData *pTd = sqlite3OsThreadSpecificData(0); + return pTd ? pTd : &zeroData; +} + +/* +** Check to see if the ThreadData for this thread is all zero. If it +** is, then deallocate it. +*/ +void sqlite3ReleaseThreadData(){ + sqlite3OsThreadSpecificData(-1); } /* ** Clear the "mallocFailed" flag. This should be invoked before exiting any ** entry points that may have called sqliteMalloc(). */ void sqlite3MallocClearFailed(){ - sqlite3ThreadData()->mallocFailed = 0; -} - -#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT -/* -** Enable the shared pager and schema features. -*/ -int sqlite3_enable_memory_management(int enable){ - ThreadData *pTsd = sqlite3ThreadData(); - - /* It is only legal to call sqlite3_enable_memory_management() when there - ** are no currently open connections that were opened by the calling - ** thread. This condition is only easy to detect if the feature were - ** previously enabled (and is being disabled). - */ - if( pTsd->pPager && !enable ){ - return SQLITE_MISUSE; - } - pTsd->useMemoryManagement = enable; - return SQLITE_OK; -} -#endif + ThreadData *pTd = sqlite3OsThreadSpecificData(0); + if( pTd && pTd->mallocFailed ){ + pTd->mallocFailed = 0; + sqlite3OsThreadSpecificData(0); + } +} #ifndef NDEBUG /* ** This function sets a flag in the thread-specific-data structure that will ** cause an assert to fail if sqliteMalloc() or sqliteRealloc() is called. */ void sqlite3MallocDisallow(){ - assert(sqlite3ThreadData()->mallocAllowed); - sqlite3ThreadData()->mallocAllowed = 0; + assert(!sqlite3ThreadData()->mallocDisallowed); + sqlite3ThreadData()->mallocDisallowed = 1; } /* ** This function clears the flag set in the thread-specific-data structure set ** by sqlite3MallocDisallow(). */ void sqlite3MallocAllow(){ - assert(!sqlite3ThreadData()->mallocAllowed); - sqlite3ThreadData()->mallocAllowed = 1; + assert(sqlite3ThreadData()->mallocDisallowed); + sqlite3ThreadData()->mallocDisallowed = 0; } #endif Index: SQLite.Interop/src/vacuum.c ================================================================== --- SQLite.Interop/src/vacuum.c +++ SQLite.Interop/src/vacuum.c @@ -12,11 +12,11 @@ ** This file contains code used to implement the VACUUM command. ** ** Most of the code in this file may be omitted by defining the ** SQLITE_OMIT_VACUUM macro. ** -** $Id: vacuum.c,v 1.13 2006/01/11 03:22:30 rmsimpson Exp $ +** $Id: vacuum.c,v 1.14 2006/01/12 20:54:08 rmsimpson Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" #include "os.h" @@ -101,11 +101,11 @@ Btree *pMain; /* The database being vacuumed */ Btree *pTemp; char *zSql = 0; int rc2; int saved_flags; /* Saved value of the db->flags */ - sqlite3_stmt *pDetach = 0; + Db *pDb = 0; /* Database to detach at end of vacuum */ /* Save the current value of the write-schema flag before setting it. */ saved_flags = db->flags; db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks; @@ -148,19 +148,10 @@ do { zTemp[nFilename] = '-'; randomName((unsigned char*)&zTemp[nFilename+1]); } while( sqlite3OsFileExists(zTemp) ); - /* Before we even attach it, compile a DETACH statement for vacuum_db. This - ** way, if malloc() fails we can detach the database without needing to - ** dynamically allocate memory. - */ - rc = sqlite3_prepare(db, "DETACH vacuum_db", -1, &pDetach, 0); - if( rc!=SQLITE_OK ){ - goto end_of_vacuum; - } - /* 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 ** occurs anyway. The integrity of the database is maintained by a ** (possibly synchronous) transaction opened on the main database before ** sqlite3BtreeCopyFile() is called. @@ -174,10 +165,11 @@ } rc = execSql(db, zSql); sqliteFree(zSql); zSql = 0; if( rc!=SQLITE_OK ) goto end_of_vacuum; + pDb = &db->aDb[db->nDb-1]; assert( strcmp(db->aDb[db->nDb-1].zName,"vacuum_db")==0 ); pTemp = db->aDb[db->nDb-1].pBt; sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain), sqlite3BtreeGetReserve(pMain)); assert( sqlite3BtreeGetPageSize(pTemp)==sqlite3BtreeGetPageSize(pMain) ); @@ -308,22 +300,16 @@ ** vacuum database. The vacuum_db journal file is deleted when the pager ** is closed by the DETACH. */ db->autoCommit = 1; - if( pDetach ){ - int mf = sqlite3ThreadData()->mallocFailed; - sqlite3ThreadData()->mallocFailed = 0; + if( pDb ){ sqlite3MallocDisallow(); - ((Vdbe *)pDetach)->expired = 0; - sqlite3_step(pDetach); - rc2 = sqlite3_finalize(pDetach); - if( rc==SQLITE_OK ){ - rc = rc2; - } + sqlite3BtreeClose(pDb->pBt); sqlite3MallocAllow(); - sqlite3ThreadData()->mallocFailed = mf; + pDb->pBt = 0; + 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. Index: SQLite.Interop/src/vdbe.c ================================================================== --- SQLite.Interop/src/vdbe.c +++ SQLite.Interop/src/vdbe.c @@ -41,11 +41,11 @@ ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.13 2006/01/11 03:22:30 rmsimpson Exp $ +** $Id: vdbe.c,v 1.14 2006/01/12 20:54:08 rmsimpson Exp $ */ #include "sqliteInt.h" #include "os.h" #include #include "vdbeInt.h" @@ -377,10 +377,11 @@ ){ int pc; /* The program counter */ Op *pOp; /* Current operation */ int rc = SQLITE_OK; /* Value to return */ sqlite3 *db = p->db; /* The database */ + u8 encoding = ENC(db); /* The database encoding */ Mem *pTos; /* Top entry in the operand stack */ #ifdef VDBE_PROFILE unsigned long long start; /* CPU clock count at start of opcode */ int origPc; /* Program counter at start of opcode */ #endif @@ -388,12 +389,14 @@ int nProgressOps = 0; /* Opcodes executed since progress callback. */ #endif #ifndef NDEBUG Mem *pStackLimit; #endif + ThreadData *pTsd = sqlite3ThreadData(); if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE; + pTsd->nRef++; assert( db->magic==SQLITE_MAGIC_BUSY ); pTos = p->pTos; if( p->rc==SQLITE_NOMEM ){ /* This happens if a malloc() inside a call to sqlite3_column_text() or ** sqlite3_column_text16() failed. */ @@ -410,11 +413,11 @@ db->busyHandler.nBusy = 0; CHECK_FOR_INTERRUPT; for(pc=p->pc; rc==SQLITE_OK; pc++){ assert( pc>=0 && pcnOp ); assert( pTos<=&p->aStack[pc] ); - if( sqlite3ThreadData()->mallocFailed ) goto no_mem; + if( pTsd->mallocFailed ) goto no_mem; #ifdef VDBE_PROFILE origPc = pc; start = hwtime(); #endif pOp = &p->aOp[pc]; @@ -590,10 +593,11 @@ if( pOp->p3 ){ sqlite3SetString(&p->zErrMsg, pOp->p3, (char*)0); } rc = sqlite3VdbeHalt(p); assert( rc==SQLITE_BUSY || rc==SQLITE_OK ); + pTsd->nRef--; if( rc==SQLITE_BUSY ){ p->rc = SQLITE_BUSY; return SQLITE_BUSY; } return p->rc ? SQLITE_ERROR : SQLITE_DONE; @@ -637,11 +641,11 @@ pTos->z = pOp->p3; pTos->n = strlen(pTos->z); pTos->enc = SQLITE_UTF8; pTos->r = sqlite3VdbeRealValue(pTos); pTos->flags |= MEM_Real; - sqlite3VdbeChangeEncoding(pTos, ENC(db)); + sqlite3VdbeChangeEncoding(pTos, encoding); break; } /* Opcode: String8 * * P3 ** @@ -653,14 +657,14 @@ assert( pOp->p3!=0 ); pOp->opcode = OP_String; pOp->p1 = strlen(pOp->p3); #ifndef SQLITE_OMIT_UTF16 - if( ENC(db)!=SQLITE_UTF8 ){ + if( encoding!=SQLITE_UTF8 ){ pTos++; sqlite3VdbeMemSetStr(pTos, pOp->p3, -1, SQLITE_UTF8, SQLITE_STATIC); - if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pTos, ENC(db)) ) goto no_mem; + if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pTos, encoding) ) goto no_mem; if( SQLITE_OK!=sqlite3VdbeMemDynamicify(pTos) ) goto no_mem; pTos->flags &= ~(MEM_Dyn); pTos->flags |= MEM_Static; if( pOp->p3type==P3_DYNAMIC ){ sqliteFree(pOp->p3); @@ -682,11 +686,11 @@ pTos++; assert( pOp->p3!=0 ); pTos->flags = MEM_Str|MEM_Static|MEM_Term; pTos->z = pOp->p3; pTos->n = pOp->p1; - pTos->enc = ENC(db); + pTos->enc = encoding; break; } /* Opcode: Null * * * ** @@ -886,11 +890,11 @@ ** and have an assigned type. The results are deephemeralized as ** as side effect. */ for(; pMem<=pTos; pMem++ ){ sqlite3VdbeMemNulTerminate(pMem); - storeTypeInfo(pMem, ENC(db)); + storeTypeInfo(pMem, encoding); } /* Set up the statement structure so that it will pop the current ** results from the stack when the statement returns. */ @@ -897,10 +901,11 @@ p->resOnStack = 1; p->nCallback++; p->popStack = pOp->p1; p->pc = pc + 1; p->pTos = pTos; + pTsd->nRef--; return SQLITE_ROW; } /* Opcode: Concat P1 P2 * ** @@ -927,11 +932,11 @@ assert( pOp->p2==0 || (pTerm->flags&MEM_Str) ); if( pTerm->flags&MEM_Null ){ nByte = -1; break; } - Stringify(pTerm, ENC(db)); + Stringify(pTerm, encoding); nByte += pTerm->n; } if( nByte<0 ){ /* If nByte is less than zero, then there is a NULL value on the stack. @@ -966,11 +971,11 @@ } pTos++; pTos->n = j; pTos->flags = MEM_Str|MEM_Dyn|MEM_Term; pTos->xDel = 0; - pTos->enc = ENC(db); + pTos->enc = encoding; pTos->z = zNew; } break; } @@ -1140,11 +1145,11 @@ assert( apVal || n==0 ); pArg = &pTos[1-n]; for(i=0; ip3type==P3_FUNCDEF || pOp->p3type==P3_VDBEFUNC ); if( pOp->p3type==P3_FUNCDEF ){ ctx.pFunc = (FuncDef*)pOp->p3; @@ -1165,11 +1170,11 @@ ctx.pColl = (CollSeq *)pOp[-1].p3; } if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; (*ctx.pFunc->xFunc)(&ctx, n, apVal); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; - if( sqlite3ThreadData()->mallocFailed ) goto no_mem; + if( pTsd->mallocFailed ) goto no_mem; popStack(&pTos, n); /* If any auxilary data functions have been called by this user function, ** immediately call the destructor for any non-static values. */ @@ -1178,11 +1183,11 @@ pOp->p3 = (char *)ctx.pVdbeFunc; pOp->p3type = P3_VDBEFUNC; } /* Copy the result of the function to the top of the stack */ - sqlite3VdbeChangeEncoding(&ctx.s, ENC(db)); + sqlite3VdbeChangeEncoding(&ctx.s, encoding); pTos++; pTos->flags = 0; sqlite3VdbeMemMove(pTos, &ctx.s); /* If the function returned an error, throw an exception */ @@ -1189,11 +1194,11 @@ if( ctx.isError ){ if( !(pTos->flags&MEM_Str) ){ sqlite3SetString(&p->zErrMsg, "user function error", (char*)0); }else{ sqlite3SetString(&p->zErrMsg, sqlite3_value_text(pTos), (char*)0); - sqlite3VdbeChangeEncoding(pTos, ENC(db)); + sqlite3VdbeChangeEncoding(pTos, encoding); } rc = SQLITE_ERROR; } break; } @@ -1282,11 +1287,11 @@ ** greater than its current value if P1==1. */ case OP_ForceInt: { /* no-push */ i64 v; assert( pTos>=p->aStack ); - applyAffinity(pTos, SQLITE_AFF_NUMERIC, ENC(db)); + applyAffinity(pTos, SQLITE_AFF_NUMERIC, encoding); if( (pTos->flags & (MEM_Int|MEM_Real))==0 ){ Release(pTos); pTos--; pc = pOp->p2 - 1; break; @@ -1317,11 +1322,11 @@ ** P1 is 1, then the stack is popped. In all other cases, the depth ** of the stack is unchanged. */ case OP_MustBeInt: { /* no-push */ assert( pTos>=p->aStack ); - applyAffinity(pTos, SQLITE_AFF_NUMERIC, ENC(db)); + applyAffinity(pTos, SQLITE_AFF_NUMERIC, encoding); if( (pTos->flags & MEM_Int)==0 ){ if( pOp->p2==0 ){ rc = SQLITE_MISMATCH; goto abort_due_to_error; }else{ @@ -1365,11 +1370,11 @@ case OP_ToText: { /* same as TK_TO_TEXT, no-push */ assert( pTos>=p->aStack ); if( pTos->flags & MEM_Null ) break; assert( MEM_Str==(MEM_Blob>>3) ); pTos->flags |= (pTos->flags&MEM_Blob)>>3; - applyAffinity(pTos, SQLITE_AFF_TEXT, ENC(db)); + applyAffinity(pTos, SQLITE_AFF_TEXT, encoding); assert( pTos->flags & MEM_Str ); pTos->flags &= ~(MEM_Int|MEM_Real|MEM_Blob); break; } @@ -1384,11 +1389,11 @@ */ case OP_ToBlob: { /* same as TK_TO_BLOB, no-push */ assert( pTos>=p->aStack ); if( pTos->flags & MEM_Null ) break; if( (pTos->flags & MEM_Blob)==0 ){ - applyAffinity(pTos, SQLITE_AFF_TEXT, ENC(db)); + applyAffinity(pTos, SQLITE_AFF_TEXT, encoding); assert( pTos->flags & MEM_Str ); pTos->flags |= MEM_Blob; } pTos->flags &= ~(MEM_Int|MEM_Real|MEM_Str); break; @@ -1565,12 +1570,12 @@ } } affinity = pOp->p1 & 0xFF; if( affinity ){ - applyAffinity(pNos, affinity, ENC(db)); - applyAffinity(pTos, affinity, ENC(db)); + applyAffinity(pNos, affinity, encoding); + applyAffinity(pTos, affinity, encoding); } assert( pOp->p3type==P3_COLLSEQ || pOp->p3==0 ); res = sqlite3MemCompare(pNos, pTos, (CollSeq*)pOp->p3); switch( pOp->opcode ){ @@ -2066,11 +2071,11 @@ goto op_column_out; } zData = sMem.z; } sqlite3VdbeSerialGet((u8*)zData, aType[p2], pTos); - pTos->enc = ENC(db); + pTos->enc = encoding; }else{ if( pOp->p3type==P3_MEM ){ sqlite3VdbeMemShallowCopy(pTos, (Mem *)(pOp->p3), MEM_Static); }else{ pTos->flags = MEM_Null; @@ -2190,11 +2195,11 @@ /* Loop through the elements that will make up the record to figure ** out how much space is required for the new record. */ for(pRec=pData0; pRec<=pTos; pRec++){ if( zAffinity ){ - applyAffinity(pRec, zAffinity[pRec-pData0], ENC(db)); + applyAffinity(pRec, zAffinity[pRec-pData0], encoding); } if( pRec->flags&MEM_Null ){ containsNull = 1; } serial_type = sqlite3VdbeSerialType(pRec, file_format); @@ -2324,10 +2329,11 @@ */ sqlite3SetString(&p->zErrMsg, "cannot ", rollback?"rollback":"commit", " transaction - SQL statements in progress", (char*)0); rc = SQLITE_ERROR; }else if( i!=db->autoCommit ){ + pTsd->nRef--; if( pOp->p2 ){ assert( i==1 ); sqlite3RollbackAll(db); db->autoCommit = 1; }else{ @@ -2383,10 +2389,11 @@ rc = sqlite3BtreeBeginTrans(pBt, pOp->p2); if( rc==SQLITE_BUSY ){ p->pc = pc; p->rc = SQLITE_BUSY; p->pTos = pTos; + pTsd->nRef--; return SQLITE_BUSY; } if( rc!=SQLITE_OK && rc!=SQLITE_READONLY /* && rc!=SQLITE_BUSY */ ){ goto abort_due_to_error; } @@ -2590,10 +2597,11 @@ switch( rc ){ case SQLITE_BUSY: { p->pc = pc; p->rc = SQLITE_BUSY; p->pTos = &pTos[1 + (pOp->p2<=0)]; /* Operands must remain on stack */ + pTsd->nRef--; return SQLITE_BUSY; } case SQLITE_OK: { int flags = sqlite3BtreeFlags(pCur->pCursor); /* Sanity checking. Only the lower four bits of the flags byte should @@ -2798,11 +2806,11 @@ } pC->lastRowid = pTos->i; pC->rowidIsValid = res==0; }else{ assert( pTos->flags & MEM_Blob ); - /* Stringify(pTos, ENC(db)); */ + /* Stringify(pTos, encoding); */ rc = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } pC->rowidIsValid = 0; @@ -2903,11 +2911,11 @@ assert( i>=0 && inCursor ); assert( p->apCsr[i]!=0 ); if( (pC = p->apCsr[i])->pCursor!=0 ){ int res, rx; assert( pC->isTable==0 ); - Stringify(pTos, ENC(db)); + Stringify(pTos, encoding); rx = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res); alreadyExists = rx==SQLITE_OK && res==0; pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; } @@ -2970,11 +2978,11 @@ int len; /* Number of bytes in K without the rowid at the end */ int szRowid; /* Size of the rowid column at the end of zKey */ /* Make sure K is a string and make zKey point to K */ - Stringify(pNos, ENC(db)); + Stringify(pNos, encoding); zKey = pNos->z; nKey = pNos->n; szRowid = sqlite3VdbeIdxRowidLen(nKey, (u8*)zKey); len = nKey-szRowid; @@ -3801,11 +3809,11 @@ assert( pTos>=p->aStack ); if( (pC = p->apCsr[i])->pCursor!=0 ){ int res, rc; assert( pTos->flags & MEM_Blob ); /* Created using OP_Make*Key */ - Stringify(pTos, ENC(db)); + Stringify(pTos, encoding); assert( pC->deferredMoveto==0 ); *pC->pIncrKey = pOp->p3!=0; assert( pOp->p3==0 || pOp->opcode!=OP_IdxGT ); rc = sqlite3VdbeIdxKeyCompare(pC, pTos->n, (u8*)pTos->z, &res); *pC->pIncrKey = 0; @@ -4018,17 +4026,17 @@ pOp->p1, 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(0==sqlite3ThreadData()->mallocFailed); + assert(0==pTsd->mallocFailed); rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); sqliteFree(zSql); db->init.busy = 0; sqlite3SafetyOn(db); if( rc==SQLITE_NOMEM ){ - sqlite3ThreadData()->mallocFailed = 1; + pTsd->mallocFailed = 1; goto no_mem; } break; } @@ -4130,11 +4138,11 @@ pTos->n = strlen(z); pTos->flags = MEM_Str | MEM_Dyn | MEM_Term; pTos->xDel = 0; } pTos->enc = SQLITE_UTF8; - sqlite3VdbeChangeEncoding(pTos, ENC(db)); + sqlite3VdbeChangeEncoding(pTos, encoding); sqliteFree(aRoot); break; } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ @@ -4406,11 +4414,11 @@ assert( pRec>=p->aStack ); apVal = p->apArg; assert( apVal || n==0 ); for(i=0; ip3; assert( pOp->p1>=0 && pOp->p1nMem ); ctx.pMem = pMem = &p->aMem[pOp->p1]; pMem->n++; @@ -4551,11 +4559,11 @@ ** 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 ){ - sqlite3VdbeMemSanity(pTos, ENC(db)); + sqlite3VdbeMemSanity(pTos, encoding); } assert( pc>=-1 && pcnOp ); #ifdef SQLITE_DEBUG /* Code for tracing the vdbe stack. */ if( p->trace && pTos>=p->aStack ){ @@ -4593,10 +4601,11 @@ }else{ rc = SQLITE_DONE; } sqlite3VdbeHalt(p); p->pTos = pTos; + pTsd->nRef--; return rc; /* Jump to here if a malloc() fails. It's hard to get a malloc() ** to fail on a modern VM computer, so this code is untested. */ @@ -4614,11 +4623,11 @@ /* Jump to here for any other kind of fatal error. The "rc" variable ** should hold the error number. */ abort_due_to_error: if( p->zErrMsg==0 ){ - if( sqlite3ThreadData()->mallocFailed ) rc = SQLITE_NOMEM; + if( pTsd->mallocFailed ) rc = SQLITE_NOMEM; sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0); } goto vdbe_halt; /* Jump to here if the sqlite3_interrupt() API sets the interrupt Index: SQLite.Interop/src/vdbe.h ================================================================== --- SQLite.Interop/src/vdbe.h +++ SQLite.Interop/src/vdbe.h @@ -13,11 +13,11 @@ ** ** This header defines the interface to the virtual database engine ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** -** $Id: vdbe.h,v 1.13 2006/01/11 03:22:30 rmsimpson Exp $ +** $Id: vdbe.h,v 1.14 2006/01/12 20:54:08 rmsimpson Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ #include Index: SQLite.Interop/src/vdbeapi.c ================================================================== --- SQLite.Interop/src/vdbeapi.c +++ SQLite.Interop/src/vdbeapi.c @@ -154,11 +154,11 @@ int sqlite3_step(sqlite3_stmt *pStmt){ Vdbe *p = (Vdbe*)pStmt; sqlite3 *db; int rc; - assert(!sqlite3ThreadData()->mallocFailed); + assert(!sqlite3ThreadDataReadOnly()->mallocFailed); if( p==0 || p->magic!=VDBE_MAGIC_RUN ){ return SQLITE_MISUSE; } if( p->aborted ){ @@ -402,11 +402,11 @@ /* If malloc() failed during an encoding conversion within an ** sqlite3_column_XXX API, then set the return code of the statement to ** SQLITE_NOMEM. The next call to _step() (if any) will return SQLITE_ERROR ** and _finalize() will return NOMEM. */ - if( sqlite3ThreadData()->mallocFailed ){ + if( sqlite3ThreadDataReadOnly()->mallocFailed ){ ((Vdbe *)pStmt)->rc = SQLITE_NOMEM; sqlite3MallocClearFailed(); } } Index: SQLite.Interop/src/vdbeaux.c ================================================================== --- SQLite.Interop/src/vdbeaux.c +++ SQLite.Interop/src/vdbeaux.c @@ -100,11 +100,11 @@ i = p->nOp; p->nOp++; assert( p->magic==VDBE_MAGIC_INIT ); resizeOpArray(p, i+1); - if( sqlite3ThreadData()->mallocFailed ){ + if( p->aOp==0 || p->nOp<=i ){ return 0; } pOp = &p->aOp[i]; pOp->opcode = op; pOp->p1 = p1; @@ -299,11 +299,11 @@ */ int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){ int addr; assert( p->magic==VDBE_MAGIC_INIT ); resizeOpArray(p, p->nOp + nOp); - if( sqlite3ThreadData()->mallocFailed ){ + if( sqlite3ThreadDataReadOnly()->mallocFailed ){ return 0; } addr = p->nOp; if( nOp>0 ){ int i; @@ -413,11 +413,11 @@ ** If addr<0 then change P3 on the most recently inserted instruction. */ void sqlite3VdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){ Op *pOp; assert( p->magic==VDBE_MAGIC_INIT ); - if( p==0 || p->aOp==0 || sqlite3ThreadData()->mallocFailed ){ + if( p==0 || p->aOp==0 || sqlite3ThreadDataReadOnly()->mallocFailed ){ if (n != P3_KEYINFO) { freeP3(n, (void*)*(char**)&zP3); } return; } @@ -470,11 +470,12 @@ ** comment text. */ void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){ va_list ap; assert( p->nOp>0 ); - assert( p->aOp==0 || p->aOp[p->nOp-1].p3==0 || sqlite3ThreadData()->mallocFailed ); + assert( p->aOp==0 || p->aOp[p->nOp-1].p3==0 + || sqlite3ThreadDataReadOnly()->mallocFailed ); va_start(ap, zFormat); sqlite3VdbeChangeP3(p, -1, sqlite3VMPrintf(zFormat, ap), P3_DYNAMIC); va_end(ap); } #endif @@ -736,11 +737,11 @@ + nVar*sizeof(Mem) /* aVar */ + nVar*sizeof(char*) /* azVar */ + nMem*sizeof(Mem) /* aMem */ + nCursor*sizeof(Cursor*) /* apCsr */ ); - if( !sqlite3ThreadData()->mallocFailed ){ + if( !sqlite3ThreadDataReadOnly()->mallocFailed ){ p->aMem = &p->aStack[nStack]; p->nMem = nMem; p->aVar = &p->aMem[nMem]; p->nVar = nVar; p->okVar = 0; @@ -888,11 +889,11 @@ */ int sqlite3VdbeSetColName(Vdbe *p, int idx, const char *zName, int N){ int rc; Mem *pColName; assert( idx<(2*p->nResColumn) ); - if( sqlite3ThreadData()->mallocFailed ) return SQLITE_NOMEM; + if( sqlite3ThreadDataReadOnly()->mallocFailed ) return SQLITE_NOMEM; assert( p->aColName!=0 ); pColName = &(p->aColName[idx]); if( N==P3_DYNAMIC || N==P3_STATIC ){ rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, SQLITE_STATIC); }else{ @@ -1151,11 +1152,11 @@ int sqlite3VdbeHalt(Vdbe *p){ sqlite3 *db = p->db; int i; int (*xFunc)(Btree *pBt) = 0; /* Function to call on each btree backend */ - if( sqlite3ThreadData()->mallocFailed ){ + if( sqlite3ThreadDataReadOnly()->mallocFailed ){ p->rc = SQLITE_NOMEM; } if( p->magic!=VDBE_MAGIC_RUN ){ /* Already halted. Nothing to do. */ @@ -1677,10 +1678,27 @@ } } return 0; } +/* +** The header of a record consists of a sequence variable-length integers. +** These integers are almost always small and are encoded as a single byte. +** The following macro takes advantage this fact to provide a fast decode +** of the integers in a record header. It is faster for the common case +** where the integer is a single byte. It is a little slower when the +** integer is two or more bytes. But overall it is faster. +** +** The following expressions are equivalent: +** +** x = sqlite3GetVarint32( A, &B ); +** +** x = GetVarint( A, B ); +** +*/ +#define GetVarint(A,B) ((B = *(A))<=0x7f ? 1 : sqlite3GetVarint32(A, &B)) + /* ** This function compares the two table rows or index records specified by ** {nKey1, pKey1} and {nKey2, pKey2}, returning a negative, zero ** or positive integer if {nKey1, pKey1} is less than, equal to or ** greater than {nKey2, pKey2}. Both Key1 and Key2 must be byte strings @@ -1704,23 +1722,23 @@ Mem mem1; Mem mem2; mem1.enc = pKeyInfo->enc; mem2.enc = pKeyInfo->enc; - idx1 = sqlite3GetVarint32(pKey1, &szHdr1); + idx1 = GetVarint(aKey1, szHdr1); d1 = szHdr1; - idx2 = sqlite3GetVarint32(pKey2, &szHdr2); + idx2 = GetVarint(aKey2, szHdr2); d2 = szHdr2; nField = pKeyInfo->nField; while( idx1=nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break; - idx2 += sqlite3GetVarint32(&aKey2[idx2], &serial_type2); + idx2 += GetVarint( aKey2+idx2, serial_type2 ); if( d2>=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 Index: SQLite.Interop/src/vdbemem.c ================================================================== --- SQLite.Interop/src/vdbemem.c +++ SQLite.Interop/src/vdbemem.c @@ -749,16 +749,18 @@ assert( enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE || enc==SQLITE_UTF8); if( pVal->flags&MEM_Null ){ return 0; } + assert( (MEM_Blob>>3) == MEM_Str ); + pVal->flags |= (pVal->flags & MEM_Blob)>>3; if( pVal->flags&MEM_Str ){ sqlite3VdbeChangeEncoding(pVal, enc); }else if( !(pVal->flags&MEM_Blob) ){ sqlite3VdbeMemStringify(pVal, enc); } - assert(pVal->enc==enc || sqlite3ThreadData()->mallocFailed); + assert(pVal->enc==enc || sqlite3ThreadDataReadOnly()->mallocFailed); return (const void *)(pVal->enc==enc ? (pVal->z) : 0); } /* ** Create a new sqlite3_value object. Index: SQLite.Interop/src/where.c ================================================================== --- SQLite.Interop/src/where.c +++ SQLite.Interop/src/where.c @@ -14,11 +14,11 @@ ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** -** $Id: where.c,v 1.15 2006/01/11 03:22:30 rmsimpson Exp $ +** $Id: where.c,v 1.16 2006/01/12 20:54:08 rmsimpson Exp $ */ #include "sqliteInt.h" /* ** The number of bits in a Bitmask. "BMS" means "BitMask Size". @@ -565,11 +565,11 @@ Bitmask prereqLeft; Bitmask prereqAll; int nPattern; int isComplete; - if( sqlite3ThreadData()->mallocFailed ) return; + if( sqlite3ThreadDataReadOnly()->mallocFailed ) return; prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft); if( pExpr->op==TK_IN ){ assert( pExpr->pRight==0 ); pTerm->prereqRight = exprListTableUsage(pMaskSet, pExpr->pList) | exprSelectTableUsage(pMaskSet, pExpr->pSelect); @@ -1436,11 +1436,11 @@ /* Allocate and initialize the WhereInfo structure that will become the ** return value. */ pWInfo = sqliteMalloc( sizeof(WhereInfo) + pTabList->nSrc*sizeof(WhereLevel)); - if( sqlite3ThreadData()->mallocFailed ){ + if( sqlite3ThreadDataReadOnly()->mallocFailed ){ goto whereBeginNoMem; } pWInfo->pParse = pParse; pWInfo->pTabList = pTabList; pWInfo->iBreak = sqlite3VdbeMakeLabel(v); @@ -1460,11 +1460,11 @@ */ for(i=0; inSrc; i++){ createMask(&maskSet, pTabList->a[i].iCursor); } exprAnalyzeAll(pTabList, &maskSet, &wc); - if( sqlite3ThreadData()->mallocFailed ){ + if( sqlite3ThreadDataReadOnly()->mallocFailed ){ goto whereBeginNoMem; } /* Chose the best index to use for each table in the FROM clause. **