Index: src/alter.c ================================================================== --- src/alter.c +++ src/alter.c @@ -44,11 +44,11 @@ ){ unsigned char const *zSql = sqlite3_value_text(argv[0]); unsigned char const *zTableName = sqlite3_value_text(argv[1]); int token; - Token tname; + Token tname = {0,0,0}; /* Initialized to placate warning */ unsigned char const *zCsr = zSql; int len = 0; char *zRet; sqlite3 *db = sqlite3_context_db_handle(context); @@ -99,11 +99,11 @@ ){ unsigned char const *zSql = sqlite3_value_text(argv[0]); unsigned char const *zTableName = sqlite3_value_text(argv[1]); int token; - Token tname; + Token tname = {0,0,0}; /* Initialized to placate warning */ int dist = 3; unsigned char const *zCsr = zSql; int len = 0; char *zRet; Index: src/attach.c ================================================================== --- src/attach.c +++ src/attach.c @@ -142,12 +142,15 @@ } pPager = sqlite3BtreePager(aNew->pBt); sqlite3PagerLockingMode(pPager, db->dfltLockMode); sqlite3PagerJournalMode(pPager, db->dfltJournalMode); } - aNew->zName = sqlite3DbStrDup(db, zName); aNew->safety_level = 3; + aNew->zName = sqlite3DbStrDup(db, zName); + if( rc==SQLITE_OK && aNew->zName==0 ){ + rc = SQLITE_NOMEM; + } #if SQLITE_HAS_CODEC { extern int sqlite3CodecAttach(sqlite3*, int, const void*, int); extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*); Index: src/btree.c ================================================================== --- src/btree.c +++ src/btree.c @@ -3019,11 +3019,11 @@ Pgno ovfl, /* Overflow page */ MemPage **ppPage, /* OUT: MemPage handle */ Pgno *pPgnoNext /* OUT: Next overflow page number */ ){ Pgno next = 0; - int rc; + int rc = SQLITE_OK; /* Initialized to placate warning */ assert( sqlite3_mutex_held(pBt->mutex) ); /* One of these must not be NULL. Otherwise, why call this function? */ assert(ppPage || pPgnoNext); Index: src/build.c ================================================================== --- src/build.c +++ src/build.c @@ -2752,11 +2752,12 @@ } /* Clean up before exiting */ exit_create_index: if( pIndex ){ - freeIndex(pIndex); + sqlite3_free(pIndex->zColAff); + sqlite3DbFree(db, pIndex); } sqlite3ExprListDelete(db, pList); sqlite3SrcListDelete(db, pTblName); sqlite3DbFree(db, zName); return; Index: src/date.c ================================================================== --- src/date.c +++ src/date.c @@ -51,27 +51,10 @@ #include #include #ifndef SQLITE_OMIT_DATETIME_FUNCS -/* -** On recent Windows platforms, the localtime_s() function is available -** as part of the "Secure CRT". It is essentially equivalent to -** localtime_r() available under most POSIX platforms, except that the -** order of the parameters is reversed. -** -** See http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx. -** -** If the user has not indicated to use localtime_r() or localtime_s() -** already, check for an MSVC build environment that provides -** localtime_s(). -*/ -#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S) && \ - defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE) -#define HAVE_LOCALTIME_S 1 -#endif - /* ** A structure for holding a single date and time. */ typedef struct DateTime DateTime; struct DateTime { @@ -421,19 +404,71 @@ p->validYMD = 0; p->validHMS = 0; p->validTZ = 0; } +/* +** On recent Windows platforms, the localtime_s() function is available +** as part of the "Secure CRT". It is essentially equivalent to +** localtime_r() available under most POSIX platforms, except that the +** order of the parameters is reversed. +** +** See http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx. +** +** If the user has not indicated to use localtime_r() or localtime_s() +** already, check for an MSVC build environment that provides +** localtime_s(). +*/ +#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S) && \ + defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE) +#define HAVE_LOCALTIME_S 1 +#endif + +#ifndef SQLITE_OMIT_LOCALTIME +/* +** The following routine implements the rough equivalent of localtime_r() +** using whatever operating-system specific localtime facility that +** is available. This routine returns 0 on success and +** non-zero on any kind of error. +*/ +int osLocaltime(time_t *t, struct tm *pTm){ + int rc; +#if (!defined(HAVE_LOCALTIME_R) || !HAVE_LOCALTIME_R) \ + && (!defined(HAVE_LOCALTIME_S) || !HAVE_LOCALTIME_S) + struct tm *pX; + sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); + sqlite3_mutex_enter(mutex); + pX = localtime(t); + if( pX ) *pTm = *pX; + sqlite3_mutex_leave(mutex); + rc = pX==0; +#else +#if defined(HAVE_LOCALTIME_R) && HAVE_LOCALTIME_R + rc = localtime_r(t, pTm)==0; +#else + rc = localtime_s(pTm, t); +#endif /* HAVE_LOCALTIME_R */ +#endif /* HAVE_LOCALTIME_R || HAVE_LOCALTIME_S */ + return rc; +} +#endif /* SQLITE_OMIT_LOCALTIME */ + #ifndef SQLITE_OMIT_LOCALTIME /* ** Compute the difference (in milliseconds) ** between localtime and UTC (a.k.a. GMT) ** for the time value p where p is in UTC. */ -static int localtimeOffset(DateTime *p){ +static sqlite3_int64 localtimeOffset( + DateTime *p, /* Date at which to calculate offset */ + sqlite3_context *pCtx, /* Write error here if one occurs */ + int *pRc /* OUT: Error code. SQLITE_OK or ERROR */ +){ DateTime x, y; time_t t; + struct tm sLocal; + x = *p; computeYMD_HMS(&x); if( x.Y<1971 || x.Y>=2038 ){ x.Y = 2000; x.M = 1; @@ -447,46 +482,21 @@ } x.tz = 0; x.validJD = 0; computeJD(&x); t = x.iJD/1000 - 2440587.5*86400.0; -#ifdef HAVE_LOCALTIME_R - { - struct tm sLocal; - localtime_r(&t, &sLocal); - y.Y = sLocal.tm_year + 1900; - y.M = sLocal.tm_mon + 1; - y.D = sLocal.tm_mday; - y.h = sLocal.tm_hour; - y.m = sLocal.tm_min; - y.s = sLocal.tm_sec; - } -#elif defined(HAVE_LOCALTIME_S) - { - struct tm sLocal; - localtime_s(&sLocal, &t); - y.Y = sLocal.tm_year + 1900; - y.M = sLocal.tm_mon + 1; - y.D = sLocal.tm_mday; - y.h = sLocal.tm_hour; - y.m = sLocal.tm_min; - y.s = sLocal.tm_sec; - } -#else - { - struct tm *pTm; - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); - pTm = localtime(&t); - y.Y = pTm->tm_year + 1900; - y.M = pTm->tm_mon + 1; - y.D = pTm->tm_mday; - y.h = pTm->tm_hour; - y.m = pTm->tm_min; - y.s = pTm->tm_sec; - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); - } -#endif + if( osLocaltime(&t, &sLocal) ){ + sqlite3_result_error(pCtx, "local time unavailable", -1); + *pRc = SQLITE_ERROR; + return 0; + } + y.Y = sLocal.tm_year + 1900; + y.M = sLocal.tm_mon + 1; + y.D = sLocal.tm_mday; + y.h = sLocal.tm_hour; + y.m = sLocal.tm_min; + y.s = sLocal.tm_sec; y.validYMD = 1; y.validHMS = 1; y.validJD = 0; y.validTZ = 0; computeJD(&y); @@ -513,11 +523,11 @@ ** localtime ** utc ** ** Return 0 on success and 1 if there is any kind of error. */ -static int parseModifier(const char *zMod, DateTime *p){ +static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ int rc = 1; int n; double r; char *z, zBuf[30]; z = zBuf; @@ -533,13 +543,12 @@ ** Assuming the current time value is UTC (a.k.a. GMT), shift it to ** show local time. */ if( strcmp(z, "localtime")==0 ){ computeJD(p); - p->iJD += localtimeOffset(p); + p->iJD += localtimeOffset(p, pCtx, &rc); clearYMD_HMS_TZ(p); - rc = 0; } break; } #endif case 'u': { @@ -556,15 +565,19 @@ } #ifndef SQLITE_OMIT_LOCALTIME else if( strcmp(z, "utc")==0 ){ double c1; computeJD(p); - c1 = localtimeOffset(p); + c1 = localtimeOffset(p, pCtx, &rc); p->iJD -= c1; clearYMD_HMS_TZ(p); - p->iJD += c1 - localtimeOffset(p); - rc = 0; + c1 = localtimeOffset(p, pCtx, &rc); + if( rc==SQLITE_OK ){ + p->iJD -= c1; + clearYMD_HMS_TZ(p); + p->iJD += c1 - localtimeOffset(p, pCtx, &rc); + } } #endif break; } case 'w': { @@ -731,11 +744,12 @@ if( !z || parseDateOrTime(context, (char*)z, p) ){ return 1; } } for(i=1; idb; if( pParse->nErr || db->mallocFailed ){ Index: src/expr.c ================================================================== --- src/expr.c +++ src/expr.c @@ -2735,11 +2735,11 @@ ExprList *pEList; /* List of WHEN terms */ struct ExprList_item *aListelem; /* Array of WHEN terms */ Expr opCompare; /* The X==Ei expression */ Expr cacheX; /* Cached expression X */ Expr *pX; /* The X expression */ - Expr *pTest; /* X==Ei (form A) or just Ei (form B) */ + Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */ assert(pExpr->pList); assert((pExpr->pList->nExpr % 2) == 0); assert(pExpr->pList->nExpr > 0); pEList = pExpr->pList; Index: src/func.c ================================================================== --- src/func.c +++ src/func.c @@ -909,11 +909,11 @@ } if( nChar>0 ){ flags = SQLITE_PTR_TO_INT(sqlite3_user_data(context)); if( flags & 1 ){ while( nIn>0 ){ - int len; + int len = 0; /* Initialized to placate warning. */ for(i=0; i=nChar ) break; @@ -921,11 +921,11 @@ nIn -= len; } } if( flags & 2 ){ while( nIn>0 ){ - int len; + int len = 0; /* Initialized to placate warning. */ for(i=0; i=nChar ) break; Index: src/insert.c ================================================================== --- src/insert.c +++ src/insert.c @@ -386,18 +386,18 @@ int iDb; /* Index of database holding TABLE */ Db *pDb; /* The database containing table being inserted into */ int appendFlag = 0; /* True if the insert is likely to be an append */ /* Register allocations */ - int regFromSelect; /* Base register for data coming from SELECT */ + int regFromSelect = 0;/* Base register for data coming from SELECT */ int regAutoinc = 0; /* Register holding the AUTOINCREMENT counter */ int regRowCount = 0; /* Memory cell used for the row counter */ int regIns; /* Block of regs holding rowid+data being inserted */ int regRowid; /* registers holding insert rowid */ int regData; /* register holding first column to insert */ int regRecord; /* Holds the assemblied row record */ - int regEof; /* Register recording end of SELECT data */ + int regEof = 0; /* Register recording end of SELECT data */ int *aRegIdx = 0; /* One register allocated to each index */ #ifndef SQLITE_OMIT_TRIGGER int isView; /* True if attempting to insert into a view */ @@ -1093,11 +1093,12 @@ ){ int i; Vdbe *v; int nCol; int onError; - int j1, j2, j3; /* Addresses of jump instructions */ + int j1, j3; /* Addresses of jump instructions */ + int j2 = 0; /* Initialized to placate warning */ int regData; /* Register containing first data column */ int iCur; Index *pIdx; int seenReplace = 0; int hasTwoRowids = (isUpdate && rowidChng); Index: src/main.c ================================================================== --- src/main.c +++ src/main.c @@ -1129,35 +1129,28 @@ /* ** Return UTF-16 encoded English language explanation of the most recent ** error. */ const void *sqlite3_errmsg16(sqlite3 *db){ - /* Because all the characters in the string are in the unicode - ** range 0x00-0xFF, if we pad the big-endian string with a - ** zero byte, we can obtain the little-endian string with - ** &big_endian[1]. - */ - static const char outOfMemBe[] = { - 0, 'o', 0, 'u', 0, 't', 0, ' ', - 0, 'o', 0, 'f', 0, ' ', - 0, 'm', 0, 'e', 0, 'm', 0, 'o', 0, 'r', 0, 'y', 0, 0, 0 + static const u16 outOfMem[] = { + 'o', 'u', 't', ' ', 'o', 'f', ' ', 'm', 'e', 'm', 'o', 'r', 'y', 0 }; - static const char misuseBe [] = { - 0, 'l', 0, 'i', 0, 'b', 0, 'r', 0, 'a', 0, 'r', 0, 'y', 0, ' ', - 0, 'r', 0, 'o', 0, 'u', 0, 't', 0, 'i', 0, 'n', 0, 'e', 0, ' ', - 0, 'c', 0, 'a', 0, 'l', 0, 'l', 0, 'e', 0, 'd', 0, ' ', - 0, 'o', 0, 'u', 0, 't', 0, ' ', - 0, 'o', 0, 'f', 0, ' ', - 0, 's', 0, 'e', 0, 'q', 0, 'u', 0, 'e', 0, 'n', 0, 'c', 0, 'e', 0, 0, 0 + static const u16 misuse[] = { + 'l', 'i', 'b', 'r', 'a', 'r', 'y', ' ', + 'r', 'o', 'u', 't', 'i', 'n', 'e', ' ', + 'c', 'a', 'l', 'l', 'e', 'd', ' ', + 'o', 'u', 't', ' ', + 'o', 'f', ' ', + 's', 'e', 'q', 'u', 'e', 'n', 'c', 'e', 0 }; const void *z; if( !db ){ - return (void *)(&outOfMemBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]); + return (void *)outOfMem; } if( !sqlite3SafetyCheckSickOrOk(db) ){ - return (void *)(&misuseBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]); + return (void *)misuse; } sqlite3_mutex_enter(db->mutex); assert( !db->mallocFailed ); z = sqlite3_value_text16(db->pErr); if( z==0 ){ Index: src/os_unix.c ================================================================== --- src/os_unix.c +++ src/os_unix.c @@ -2052,10 +2052,16 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ switch( op ){ case SQLITE_FCNTL_LOCKSTATE: { *(int*)pArg = ((unixFile*)id)->locktype; return SQLITE_OK; + } + case SQLITE_FCNTL_SIZE_HINT: { + sqlite3_int64 szFile = *(sqlite3_int64*)pArg; + unixFile *pFile = (unixFile*)id; + ftruncate(pFile->h, szFile); + return SQLITE_OK; } } return SQLITE_ERROR; } Index: src/pager.c ================================================================== --- src/pager.c +++ src/pager.c @@ -3060,19 +3060,27 @@ pList = sort_pagelist(pList); for(p=pList; p; p=p->pDirty){ assert( p->dirty ); p->dirty = 0; } + + /* If the file has not yet been opened, open it now. */ + if( !pPager->fd->pMethods ){ + assert(pPager->tempFile); + rc = sqlite3PagerOpentemp(pPager, pPager->fd, pPager->vfsFlags); + if( rc ) return rc; + } + + /* Before the first write, give the VFS a hint of what the final + ** file size will be. + */ + if( pPager->dbSize > (pPager->origDbSize+1) ){ + sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize; + sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile); + } + while( pList ){ - - /* If the file has not yet been opened, open it now. */ - if( !pPager->fd->pMethods ){ - assert(pPager->tempFile); - rc = sqlite3PagerOpentemp(pPager, pPager->fd, pPager->vfsFlags); - if( rc ) return rc; - } - /* If there are dirty pages in the page cache with page numbers greater ** than Pager.dbSize, this means sqlite3PagerTruncate() was called to ** make the file smaller (presumably by auto-vacuum code). Do not write ** any such pages to the file. */ @@ -3653,11 +3661,11 @@ if( pPager->nPagemxPage || pPager->lru.pFirst==0 || MEMDB || (pPager->lru.pFirstSynced==0 && pPager->doNotSync) ){ - void *pData; + void *pData = 0; /* Initialized to placate warning */ if( pPager->nPage>=pPager->nHash ){ pager_resize_hash_table(pPager, pPager->nHash<256 ? 256 : pPager->nHash*2); if( pPager->nHash==0 ){ rc = SQLITE_NOMEM; Index: src/printf.c ================================================================== --- src/printf.c +++ src/printf.c @@ -245,11 +245,11 @@ LONGDOUBLE_TYPE realvalue; /* Value for real types */ const et_info *infop; /* Pointer to the appropriate info structure */ char buf[etBUFSIZE]; /* Conversion buffer */ char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ etByte errorflag = 0; /* True if an error is encountered */ - etByte xtype; /* Conversion paradigm */ + etByte xtype = 0; /* Conversion paradigm */ char *zExtra; /* Extra memory used for etTCLESCAPE conversions */ #ifndef SQLITE_OMIT_FLOATING_POINT int exp, e2; /* exponent of real numbers */ double rounder; /* Used for rounding floating point values */ etByte flag_dp; /* True if decimal point should be shown */ Index: src/select.c ================================================================== --- src/select.c +++ src/select.c @@ -2465,11 +2465,11 @@ int addrSelectA; /* Address of the select-A coroutine */ int addrSelectB; /* Address of the select-B coroutine */ int regOutA; /* Address register for the output-A subroutine */ int regOutB; /* Address register for the output-B subroutine */ int addrOutA; /* Address of the output-A subroutine */ - int addrOutB; /* Address of the output-B subroutine */ + int addrOutB = 0; /* Address of the output-B subroutine */ int addrEofA; /* Address of the select-A-exhausted subroutine */ int addrEofB; /* Address of the select-B-exhausted subroutine */ int addrAltB; /* Address of the AB subroutine */ @@ -2480,11 +2480,11 @@ int savedOffset; /* Saved value of p->iOffset */ int labelCmpr; /* Label for the start of the merge algorithm */ int labelEnd; /* Label for the end of the overall SELECT stmt */ int j1; /* Jump instructions that get retargetted */ int op; /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */ - KeyInfo *pKeyDup; /* Comparison information for duplicate removal */ + KeyInfo *pKeyDup = 0; /* Comparison information for duplicate removal */ KeyInfo *pKeyMerge; /* Comparison information for merging rows */ sqlite3 *db; /* Database connection */ ExprList *pOrderBy; /* The ORDER BY clause */ int nOrderBy; /* Number of terms in the ORDER BY clause */ int *aPermute; /* Mapping from ORDER BY terms to result set columns */ Index: src/sqlite.h.in ================================================================== --- src/sqlite.h.in +++ src/sqlite.h.in @@ -696,12 +696,20 @@ ** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], ** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) ** into an integer that the pArg argument points to. This capability ** is used during testing and only needs to be supported when SQLITE_TEST ** is defined. +** +** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS +** layer a hint of how large the database file will grow to be during the +** current transaction. This hint is not guaranteed to be accurate but it +** is often close. The underlying VFS might choose to preallocate database +** file space based on this hint in order to help writes to the database +** file run faster. */ #define SQLITE_FCNTL_LOCKSTATE 1 +#define SQLITE_FCNTL_SIZE_HINT 2 /* ** CAPI3REF: Mutex Handle {H17110} ** ** The mutex module within SQLite defines [sqlite3_mutex] to be an Index: src/update.c ================================================================== --- src/update.c +++ src/update.c @@ -107,14 +107,14 @@ #ifndef SQLITE_OMIT_TRIGGER int isView; /* Trying to update a view */ int triggers_exist = 0; /* True if any row triggers exist */ #endif - int iBeginAfterTrigger; /* Address of after trigger program */ - int iEndAfterTrigger; /* Exit of after trigger program */ - int iBeginBeforeTrigger; /* Address of before trigger program */ - int iEndBeforeTrigger; /* Exit of before trigger program */ + int iBeginAfterTrigger = 0; /* Address of after trigger program */ + int iEndAfterTrigger = 0; /* Exit of after trigger program */ + int iBeginBeforeTrigger = 0; /* Address of before trigger program */ + int iEndBeforeTrigger = 0; /* Exit of before trigger program */ u32 old_col_mask = 0; /* Mask of OLD.* columns in use */ u32 new_col_mask = 0; /* Mask of NEW.* columns in use */ int newIdx = -1; /* index of trigger "new" temp table */ int oldIdx = -1; /* index of trigger "old" temp table */ Index: src/util.c ================================================================== --- src/util.c +++ src/util.c @@ -542,10 +542,23 @@ p[1] = v & 0x7f; return 2; } return sqlite3PutVarint(p, v); } + +/* +** Bitmasks used by sqlite3GetVarint(). These precomputed constants +** are defined here rather than simply putting the constant expressions +** inline in order to work around bugs in the RVT compiler. +** +** SLOT_2_0 A mask for (0x7f<<14) | 0x7f +** +** SLOT_4_2_0 A mask for (0x7f<<28) | SLOT_2_0 +*/ +#define SLOT_2_0 0x001fc07f +#define SLOT_4_2_0 0xf01fc07f + /* ** Read a 64-bit variable-length integer from memory starting at p[0]. ** Return the number of bytes read. The value is stored in *v. */ @@ -570,33 +583,37 @@ a |= b; *v = a; return 2; } + /* Verify that constants are precomputed correctly */ + assert( SLOT_2_0 == ((0x7f<<14) | (0x7f)) ); + assert( SLOT_4_2_0 == ((0xf<<28) | (0x7f<<14) | (0x7f)) ); + p++; a = a<<14; a |= *p; /* a: p0<<14 | p2 (unmasked) */ if (!(a&0x80)) { - a &= (0x7f<<14)|(0x7f); + a &= SLOT_2_0; b &= 0x7f; b = b<<7; a |= b; *v = a; return 3; } /* CSE1 from below */ - a &= (0x7f<<14)|(0x7f); + a &= SLOT_2_0; p++; b = b<<14; b |= *p; /* b: p1<<14 | p3 (unmasked) */ if (!(b&0x80)) { - b &= (0x7f<<14)|(0x7f); + b &= SLOT_2_0; /* moved CSE1 up */ /* a &= (0x7f<<14)|(0x7f); */ a = a<<7; a |= b; *v = a; @@ -606,11 +623,11 @@ /* a: p0<<14 | p2 (masked) */ /* b: p1<<14 | p3 (unmasked) */ /* 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ /* moved CSE1 up */ /* a &= (0x7f<<14)|(0x7f); */ - b &= (0x7f<<14)|(0x7f); + b &= SLOT_2_0; s = a; /* s: p0<<14 | p2 (masked) */ p++; a = a<<14; @@ -639,11 +656,11 @@ /* b: p1<<28 | p3<<14 | p5 (unmasked) */ if (!(b&0x80)) { /* we can skip this cause it was (effectively) done above in calc'ing s */ /* b &= (0x7f<<28)|(0x7f<<14)|(0x7f); */ - a &= (0x7f<<14)|(0x7f); + a &= SLOT_2_0; a = a<<7; a |= b; s = s>>18; *v = ((u64)s)<<32 | a; return 6; @@ -653,28 +670,28 @@ a = a<<14; a |= *p; /* a: p2<<28 | p4<<14 | p6 (unmasked) */ if (!(a&0x80)) { - a &= (0x7f<<28)|(0x7f<<14)|(0x7f); - b &= (0x7f<<14)|(0x7f); + a &= SLOT_4_2_0; + b &= SLOT_2_0; b = b<<7; a |= b; s = s>>11; *v = ((u64)s)<<32 | a; return 7; } /* CSE2 from below */ - a &= (0x7f<<14)|(0x7f); + a &= SLOT_2_0; p++; b = b<<14; b |= *p; /* b: p3<<28 | p5<<14 | p7 (unmasked) */ if (!(b&0x80)) { - b &= (0x7f<<28)|(0x7f<<14)|(0x7f); + b &= SLOT_4_2_0; /* moved CSE2 up */ /* a &= (0x7f<<14)|(0x7f); */ a = a<<7; a |= b; s = s>>4; @@ -687,11 +704,11 @@ a |= *p; /* a: p4<<29 | p6<<15 | p8 (unmasked) */ /* moved CSE2 up */ /* a &= (0x7f<<29)|(0x7f<<15)|(0xff); */ - b &= (0x7f<<14)|(0x7f); + b &= SLOT_2_0; b = b<<8; a |= b; s = s<<4; b = p[-4]; @@ -765,12 +782,12 @@ a = a<<14; a |= *p; /* a: p0<<28 | p2<<14 | p4 (unmasked) */ if (!(a&0x80)) { - a &= (0x7f<<28)|(0x7f<<14)|(0x7f); - b &= (0x7f<<28)|(0x7f<<14)|(0x7f); + a &= SLOT_4_2_0; + b &= SLOT_4_2_0; b = b<<7; *v = a | b; return 5; } Index: src/vdbe.c ================================================================== --- src/vdbe.c +++ src/vdbe.c @@ -541,12 +541,14 @@ 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 *pIn1, *pIn2, *pIn3; /* Input operands */ - Mem *pOut; /* Output operand */ + Mem *pIn1 = 0; /* Input operands */ + Mem *pIn2 = 0; /* Input operands */ + Mem *pIn3 = 0; /* Input operands */ + Mem *pOut = 0; /* Output operand */ u8 opProperty; int iCompare = 0; /* Result of last OP_Compare operation */ int *aPermute = 0; /* Permuation of columns for OP_Compare */ #ifdef VDBE_PROFILE u64 start; /* CPU clock count at start of opcode */ @@ -3530,11 +3532,11 @@ ** If P4 is not NULL then the P1 cursor must have been positioned ** using OP_NotFound prior to invoking this opcode. */ case OP_Delete: { int i = pOp->p1; - i64 iKey; + i64 iKey = 0; Cursor *pC; assert( i>=0 && inCursor ); pC = p->apCsr[i]; assert( pC!=0 ); Index: src/vdbeapi.c ================================================================== --- src/vdbeapi.c +++ src/vdbeapi.c @@ -742,11 +742,11 @@ sqlite3_mutex_enter(pVm->db->mutex); vals = sqlite3_data_count(pStmt); pOut = &pVm->pResultSet[i]; }else{ static const Mem nullMem = {{0}, 0.0, 0, "", 0, MEM_Null, SQLITE_NULL, 0, 0, 0 }; - if( pVm->db ){ + if( pVm && pVm->db ){ sqlite3_mutex_enter(pVm->db->mutex); sqlite3Error(pVm->db, SQLITE_RANGE, 0); } pOut = (Mem*)&nullMem; } Index: src/vdbemem.c ================================================================== --- src/vdbemem.c +++ src/vdbemem.c @@ -13,11 +13,11 @@ ** This file contains code use to manipulate "Mem" structure. A "Mem" ** stores a single value in the VDBE. Mem is an opaque structure visible ** only within the VDBE. Interface routines refer to a Mem using the ** name sqlite_value ** -** $Id: vdbemem.c,v 1.121 2008/08/01 20:10:09 drh Exp $ +** $Id: vdbemem.c,v 1.123 2008/09/16 12:06:08 danielk1977 Exp $ */ #include "sqliteInt.h" #include #include "vdbeInt.h" @@ -737,26 +737,25 @@ if( pMem1->enc==pColl->enc ){ /* The strings are already in the correct encoding. Call the ** comparison function directly */ return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z); }else{ - u8 origEnc = pMem1->enc; const void *v1, *v2; int n1, n2; - /* Convert the strings into the encoding that the comparison - ** function expects */ - v1 = sqlite3ValueText((sqlite3_value*)pMem1, pColl->enc); - n1 = v1==0 ? 0 : pMem1->n; - assert( n1==sqlite3ValueBytes((sqlite3_value*)pMem1, pColl->enc) ); - v2 = sqlite3ValueText((sqlite3_value*)pMem2, pColl->enc); - n2 = v2==0 ? 0 : pMem2->n; - assert( n2==sqlite3ValueBytes((sqlite3_value*)pMem2, pColl->enc) ); - /* Do the comparison */ + Mem c1; + Mem c2; + memset(&c1, 0, sizeof(c1)); + memset(&c2, 0, sizeof(c2)); + sqlite3VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem); + sqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem); + v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc); + n1 = v1==0 ? 0 : c1.n; + v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc); + n2 = v2==0 ? 0 : c2.n; rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2); - /* Convert the strings back into the database encoding */ - sqlite3ValueText((sqlite3_value*)pMem1, origEnc); - sqlite3ValueText((sqlite3_value*)pMem2, origEnc); + sqlite3VdbeMemRelease(&c1); + sqlite3VdbeMemRelease(&c2); return rc; } } /* If a NULL pointer was passed as the collate function, fall through ** to the blob case and use memcmp(). */ Index: test/attachmalloc.test ================================================================== --- test/attachmalloc.test +++ test/attachmalloc.test @@ -43,7 +43,19 @@ ATTACH 'test3.db' AS three; CREATE TABLE three.t1(x); ATTACH 'test4.db' AS four; CREATE TABLE four.t1(x); } + +set enable_shared_cache [sqlite3_enable_shared_cache 1] +sqlite3 dbaux test2.db +dbaux eval {SELECT * FROM sqlite_master} +do_malloc_test attachmalloc-2 -sqlbody { + SELECT * FROM sqlite_master; + ATTACH 'test2.db' AS two; +} -cleanup { + db eval { DETACH two } +} +dbaux close +sqlite3_enable_shared_cache $enable_shared_cache finish_test Index: test/filefmt.test ================================================================== --- test/filefmt.test +++ test/filefmt.test @@ -61,11 +61,11 @@ sqlite3 db test.db db eval "PRAGMA auto_vacuum=OFF" db eval "PRAGMA page_size=$pagesize" db eval {CREATE TABLE t1(x)} file size test.db - } [expr $pagesize*2] + } [expr {$pagesize*2<$sqlite_pending_byte ? $pagesize*2 : $pagesize*3}] do_test filefmt-1.5.$pagesize.2 { hexio_get_int [hexio_read test.db 16 2] } $pagesize } } Index: test/io.test ================================================================== --- test/io.test +++ test/io.test @@ -399,11 +399,11 @@ INSERT INTO abc SELECT * FROM abc; } # File has grown - showing there was a cache-spill - but there # have been no calls to fsync(): list [file size test.db] [nSync] - } {31744 0} + } {38912 0} do_test io-3.3 { # The COMMIT requires a single fsync() - to the database file. execsql { COMMIT } list [file size test.db] [nSync] } {39936 1} Index: test/varint.test ================================================================== --- test/varint.test +++ test/varint.test @@ -28,5 +28,7 @@ btree_varint_test $start $mult 5000 $incr } {} } } } + +finish_test