@@ -16,9 +16,9 @@
** if you want a wrapper to interface SQLite with your choice of programming
** language. The code for the "sqlite3" command-line shell is also in a
** separate file. This file contains only code for the core SQLite library.
**
-** This amalgamation was generated on 2009-09-09 16:11:06 UTC.
+** This amalgamation was generated on 2009-09-10 22:23:14 UTC.
*/
#define SQLITE_CORE 1
#define SQLITE_AMALGAMATION 1
#ifndef SQLITE_PRIVATE
@@ -276,9 +276,13 @@
/*
** Maximum depth of recursion for triggers.
*/
#ifndef SQLITE_MAX_TRIGGER_DEPTH
+#if defined(SQLITE_SMALL_STACK)
+# define SQLITE_MAX_TRIGGER_DEPTH 10
+#else
# define SQLITE_MAX_TRIGGER_DEPTH 1000
+#endif
#endif
/************** End of sqliteLimit.h *****************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
@@ -644,9 +648,9 @@
** Requirements: [H10011] [H10014]
*/
#define SQLITE_VERSION "3.6.18"
#define SQLITE_VERSION_NUMBER 3006018
-#define SQLITE_SOURCE_ID "2009-09-09 16:10:51 f0c72a53c5d57d7487b48a06a40816153f47aaac"
+#define SQLITE_SOURCE_ID "2009-09-10 20:23:30 f42ec993ac9d42ca31305f26b09924108c36d9f4"
/*
** CAPI3REF: Run-Time Library Version Numbers {H10020} <S60100>
** KEYWORDS: sqlite3_version
@@ -7507,9 +7511,9 @@
SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int);
SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*);
#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE int sqlite3VdbeMayAbort(Vdbe*);
+SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *, int);
SQLITE_PRIVATE void sqlite3VdbeTrace(Vdbe*,FILE*);
#endif
SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe*);
SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe*);
@@ -11374,9 +11378,9 @@
}
x.tz = 0;
x.validJD = 0;
computeJD(&x);
- t = x.iJD/1000 - 21086676*(i64)10000;
+ t = (time_t)(x.iJD/1000 - 21086676*(i64)10000);
#ifdef HAVE_LOCALTIME_R
{
struct tm sLocal;
localtime_r(&t, &sLocal);
@@ -14370,8 +14374,18 @@
**
** $Id: mutex.c,v 1.31 2009/07/16 18:21:18 drh Exp $
*/
+#if defined(SQLITE_DEBUG) && !defined(SQLITE_MUTEX_OMIT)
+/*
+** For debugging purposes, record when the mutex subsystem is initialized
+** and uninitialized so that we can assert() if there is an attempt to
+** allocate a mutex while the system is uninitialized.
+*/
+static SQLITE_WSD int mutexIsInit = 0;
+#endif /* SQLITE_DEBUG */
+
+
#ifndef SQLITE_MUTEX_OMIT
/*
** Initialize the mutex system.
*/
@@ -14394,8 +14408,12 @@
}
rc = sqlite3GlobalConfig.mutex.xMutexInit();
}
+#ifdef SQLITE_DEBUG
+ GLOBAL(int, mutexIsInit) = 1;
+#endif
+
return rc;
}
/*
@@ -14406,8 +14424,13 @@
int rc = SQLITE_OK;
if( sqlite3GlobalConfig.mutex.xMutexEnd ){
rc = sqlite3GlobalConfig.mutex.xMutexEnd();
}
+
+#ifdef SQLITE_DEBUG
+ GLOBAL(int, mutexIsInit) = 0;
+#endif
+
return rc;
}
/*
@@ -14423,8 +14446,9 @@
SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){
if( !sqlite3GlobalConfig.bCoreMutex ){
return 0;
}
+ assert( GLOBAL(int, mutexIsInit) );
return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
}
/*
@@ -22404,9 +22428,19 @@
if( pOpen->pNext ){
assert( pOpen->pNext->pPrev==pOpen );
pOpen->pNext->pPrev = pOpen->pPrev;
}
- assert( !pOpen->pUnused );
+#if SQLITE_THREADSAFE && defined(__linux__)
+ assert( !pOpen->pUnused || threadsOverrideEachOthersLocks==0 );
+#endif
+
+ /* If pOpen->pUnused is not null, then memory and file-descriptors
+ ** are leaked.
+ **
+ ** This will only happen if, under Linuxthreads, the user has opened
+ ** a transaction in one thread, then attempts to close the database
+ ** handle from another thread (without first unlocking the db file).
+ ** This is a misuse. */
sqlite3_free(pOpen);
}
}
}
@@ -27556,10 +27590,10 @@
if (!pFile->hMutex) return TRUE;
winceMutexAcquire(pFile->hMutex);
/* Wanting an exclusive lock? */
- if (dwFileOffsetLow == SHARED_FIRST
- && nNumberOfBytesToLockLow == SHARED_SIZE){
+ if (dwFileOffsetLow == (DWORD)SHARED_FIRST
+ && nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){
if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){
pFile->shared->bExclusive = TRUE;
pFile->local.bExclusive = TRUE;
bReturn = TRUE;
@@ -27566,9 +27600,9 @@
}
}
/* Want a read-only lock? */
- else if (dwFileOffsetLow == SHARED_FIRST &&
+ else if (dwFileOffsetLow == (DWORD)SHARED_FIRST &&
nNumberOfBytesToLockLow == 1){
if (pFile->shared->bExclusive == 0){
pFile->local.nReaders ++;
if (pFile->local.nReaders == 1){
@@ -27578,9 +27612,9 @@
}
}
/* Want a pending lock? */
- else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToLockLow == 1){
+ else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToLockLow == 1){
/* If no pending lock has been acquired, then acquire it */
if (pFile->shared->bPending == 0) {
pFile->shared->bPending = TRUE;
pFile->local.bPending = TRUE;
@@ -27588,9 +27622,9 @@
}
}
/* Want a reserved lock? */
- else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToLockLow == 1){
+ else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToLockLow == 1){
if (pFile->shared->bReserved == 0) {
pFile->shared->bReserved = TRUE;
pFile->local.bReserved = TRUE;
bReturn = TRUE;
@@ -27620,20 +27654,20 @@
if (!pFile->hMutex) return TRUE;
winceMutexAcquire(pFile->hMutex);
/* Releasing a reader lock or an exclusive lock */
- if (dwFileOffsetLow == SHARED_FIRST){
+ if (dwFileOffsetLow == (DWORD)SHARED_FIRST){
/* Did we have an exclusive lock? */
if (pFile->local.bExclusive){
- assert(nNumberOfBytesToUnlockLow == SHARED_SIZE);
+ assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE);
pFile->local.bExclusive = FALSE;
pFile->shared->bExclusive = FALSE;
bReturn = TRUE;
}
/* Did we just have a reader lock? */
else if (pFile->local.nReaders){
- assert(nNumberOfBytesToUnlockLow == 1);
+ assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE || nNumberOfBytesToUnlockLow == 1);
pFile->local.nReaders --;
if (pFile->local.nReaders == 0)
{
pFile->shared->nReaders --;
@@ -27642,17 +27676,17 @@
}
}
/* Releasing a pending lock */
- else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){
+ else if (dwFileOffsetLow == (DWORD)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){
+ else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){
if (pFile->local.bReserved) {
pFile->local.bReserved = FALSE;
pFile->shared->bReserved = FALSE;
bReturn = TRUE;
@@ -27678,11 +27712,11 @@
UNUSED_PARAMETER(nNumberOfBytesToLockHigh);
/* If the caller wants a shared read lock, forward this call
** to winceLockFile */
- if (lpOverlapped->Offset == SHARED_FIRST &&
+ if (lpOverlapped->Offset == (DWORD)SHARED_FIRST &&
dwFlags == 1 &&
- nNumberOfBytesToLockLow == SHARED_SIZE){
+ nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){
return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0);
}
return FALSE;
}
@@ -47374,9 +47408,9 @@
return pRet;
}
/*
-** Return true if the program stored in the VM passed as an argument may
+** Check if the program stored in the VM associated with pParse may
** throw an ABORT exception (causing the statement, but not transaction
** to be rolled back). This condition is true if the main program or any
** sub-programs contains any of the following:
**
@@ -47385,12 +47419,17 @@
** * OP_Destroy
** * OP_VUpdate
** * OP_VRename
**
-** This function is only used as part of an assert() statement.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMayAbort(Vdbe *v){
- int mayAbort = 0;
+** Then check that the value of Parse.mayAbort is true if an
+** ABORT may be thrown, or false otherwise. Return true if it does
+** match, or false otherwise. This function is intended to be used as
+** part of an assert statement in the compiler. Similar to:
+**
+** assert( sqlite3VdbeAssertMayAbort(pParse->pVdbe, pParse->mayAbort) );
+*/
+SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
+ int hasAbort = 0;
Op *pOp;
VdbeOpIter sIter;
memset(&sIter, 0, sizeof(sIter));
sIter.v = v;
@@ -47400,15 +47439,20 @@
if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename
|| ((opcode==OP_Halt || opcode==OP_HaltIfNull)
&& (pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
){
- mayAbort = 1;
- break;
- }
- }
-
+ hasAbort = 1;
+ break;
+ }
+ }
sqlite3DbFree(v->db, sIter.apSub);
- return mayAbort;
+
+ /* Return true if hasAbort==mayAbort. Or if a malloc failure occured.
+ ** If malloc failed, then the while() loop above may not have iterated
+ ** through all opcodes and hasAbort may be set incorrectly. Return
+ ** true for this case to prevent the assert() in the callers frame
+ ** from failing. */
+ return ( v->db->mallocFailed || hasAbort==mayAbort );
}
#endif
/*
@@ -48366,9 +48410,9 @@
int nMem, /* Number of memory cells to allocate */
int nCursor, /* Number of cursors to allocate */
int nArg, /* Maximum number of args in SubPrograms */
int isExplain, /* True if the EXPLAIN keywords is present */
- int usesStmtJournal /* True to set Vdbe.usesStmtJournal */
+ int usesStmtJournal /* True to set Vdbe.usesStmtJournal */
){
int n;
sqlite3 *db = p->db;
@@ -48402,9 +48446,9 @@
u8 *zCsr = (u8 *)&p->aOp[p->nOp];
u8 *zEnd = (u8 *)&p->aOp[p->nOpAlloc];
int nByte;
resolveP2Values(p, &nArg);
- p->usesStmtJournal = usesStmtJournal;
+ p->usesStmtJournal = (u8)usesStmtJournal;
if( isExplain && nMem<10 ){
nMem = 10;
}
memset(zCsr, 0, zEnd-zCsr);
@@ -55383,16 +55427,20 @@
}
#ifndef SQLITE_OMIT_AUTOINCREMENT
if( pOp->p3 ){
+ /* Assert that P3 is a valid memory cell. */
+ assert( pOp->p3>0 );
if( p->pFrame ){
for(u.be.pFrame=p->pFrame; u.be.pFrame->pParent; u.be.pFrame=u.be.pFrame->pParent);
+ /* Assert that P3 is a valid memory cell. */
+ assert( pOp->p3<=u.be.pFrame->nMem );
u.be.pMem = &u.be.pFrame->aMem[pOp->p3];
}else{
+ /* Assert that P3 is a valid memory cell. */
+ assert( pOp->p3<=p->nMem );
u.be.pMem = &p->aMem[pOp->p3];
}
- /* Assert that P3 is a valid memory cell. */
- assert( pOp->p3>0 && pOp->p3<=(p->pFrame ? u.be.pFrame->nMem : p->nMem) );
REGISTER_TRACE(pOp->p3, u.be.pMem);
sqlite3VdbeMemIntegerify(u.be.pMem);
assert( (u.be.pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */
@@ -65442,9 +65490,10 @@
/* Begin by generating some termination code at the end of the
** vdbe program
*/
v = sqlite3GetVdbe(pParse);
- assert( pParse->isMultiWrite==0 || sqlite3VdbeMayAbort(v)==pParse->mayAbort );
+ assert( !pParse->isMultiWrite
+ || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort));
if( v ){
sqlite3VdbeAddOp0(v, OP_Halt);
/* The cookie mask contains one bit for each database file open.
@@ -77659,9 +77708,9 @@
Select *pS = 0; /* Select the column is extracted from */
int iCol = pExpr->iColumn; /* Index of column in pTab */
testcase( pExpr->op==TK_AGG_COLUMN );
testcase( pExpr->op==TK_COLUMN );
- while( ALWAYS(pNC) && !pTab ){
+ while( pNC && !pTab ){
SrcList *pTabList = pNC->pSrcList;
for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++);
if( j<pTabList->nSrc ){
pTab = pTabList->a[j].pTab;
@@ -77670,20 +77719,30 @@
pNC = pNC->pNext;
}
}
- if( NEVER(pTab==0) ){
+ if( pTab==0 ){
/* At one time, code such as "SELECT new.x" within a trigger would
** cause this condition to run. Since then, we have restructured how
** trigger code is generated and so this condition is no longer
- ** possible. But it seems prudent to keep the test in place in
- ** case something else changes.
- */
- zType = "TEXT";
- break;
- }
-
- assert( pTab );
+ ** possible. However, it can still be true for statements like
+ ** the following:
+ **
+ ** CREATE TABLE t1(col INTEGER);
+ ** SELECT (SELECT t1.col) FROM FROM t1;
+ **
+ ** when columnType() is called on the expression "t1.col" in the
+ ** sub-select. In this case, set the column type to NULL, even
+ ** though it should really be "INTEGER".
+ **
+ ** This is not a problem, as the column type of "t1.col" is never
+ ** used. When columnType() is called on the expression
+ ** "(SELECT t1.col)", the correct type is returned (see the TK_SELECT
+ ** branch below. */
+ break;
+ }
+
+ assert( pTab && pExpr->pTab==pTab );
if( pS ){
/* The "table" is actually a sub-select or a view in the FROM clause
** of the SELECT statement. Return the declaration type and origin
** data for the result-set column of the sub-select.
@@ -77695,9 +77754,9 @@
*/
NameContext sNC;
Expr *p = pS->pEList->a[iCol].pExpr;
sNC.pSrcList = pS->pSrc;
- sNC.pNext = 0;
+ sNC.pNext = pNC;
sNC.pParse = pNC->pParse;
zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol);
}
}else if( ALWAYS(pTab->pSchema) ){