From 569c6676a6ddb0ff73821d7693b5e18ddef809b9 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 16 Oct 2014 22:51:35 -0400 Subject: Imported Upstream version 3.2.0 --- src/vdbeapi.c | 185 +++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 119 insertions(+), 66 deletions(-) (limited to 'src/vdbeapi.c') diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 7c861e2..5e5bb81 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -135,7 +135,6 @@ const void *sqlite3_value_blob(sqlite3_value *pVal){ Mem *p = (Mem*)pVal; if( p->flags & (MEM_Blob|MEM_Str) ){ sqlite3VdbeMemExpandBlob(p); - p->flags &= ~MEM_Str; p->flags |= MEM_Blob; return p->n ? p->z : 0; }else{ @@ -172,7 +171,41 @@ const void *sqlite3_value_text16le(sqlite3_value *pVal){ } #endif /* SQLITE_OMIT_UTF16 */ int sqlite3_value_type(sqlite3_value* pVal){ - return pVal->type; + static const u8 aType[] = { + SQLITE_BLOB, /* 0x00 */ + SQLITE_NULL, /* 0x01 */ + SQLITE_TEXT, /* 0x02 */ + SQLITE_NULL, /* 0x03 */ + SQLITE_INTEGER, /* 0x04 */ + SQLITE_NULL, /* 0x05 */ + SQLITE_INTEGER, /* 0x06 */ + SQLITE_NULL, /* 0x07 */ + SQLITE_FLOAT, /* 0x08 */ + SQLITE_NULL, /* 0x09 */ + SQLITE_FLOAT, /* 0x0a */ + SQLITE_NULL, /* 0x0b */ + SQLITE_INTEGER, /* 0x0c */ + SQLITE_NULL, /* 0x0d */ + SQLITE_INTEGER, /* 0x0e */ + SQLITE_NULL, /* 0x0f */ + SQLITE_BLOB, /* 0x10 */ + SQLITE_NULL, /* 0x11 */ + SQLITE_TEXT, /* 0x12 */ + SQLITE_NULL, /* 0x13 */ + SQLITE_INTEGER, /* 0x14 */ + SQLITE_NULL, /* 0x15 */ + SQLITE_INTEGER, /* 0x16 */ + SQLITE_NULL, /* 0x17 */ + SQLITE_FLOAT, /* 0x18 */ + SQLITE_NULL, /* 0x19 */ + SQLITE_FLOAT, /* 0x1a */ + SQLITE_NULL, /* 0x1b */ + SQLITE_INTEGER, /* 0x1c */ + SQLITE_NULL, /* 0x1d */ + SQLITE_INTEGER, /* 0x1e */ + SQLITE_NULL, /* 0x1f */ + }; + return aType[pVal->flags&MEM_AffMask]; } /**************************** sqlite3_result_ ******************************* @@ -211,12 +244,14 @@ void sqlite3_result_double(sqlite3_context *pCtx, double rVal){ void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); pCtx->isError = SQLITE_ERROR; + pCtx->fErrorOrAux = 1; sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, SQLITE_TRANSIENT); } #ifndef SQLITE_OMIT_UTF16 void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); pCtx->isError = SQLITE_ERROR; + pCtx->fErrorOrAux = 1; sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT); } #endif @@ -280,6 +315,7 @@ void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){ } void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ pCtx->isError = errCode; + pCtx->fErrorOrAux = 1; if( pCtx->s.flags & MEM_Null ){ sqlite3VdbeMemSetStr(&pCtx->s, sqlite3ErrStr(errCode), -1, SQLITE_UTF8, SQLITE_STATIC); @@ -290,6 +326,7 @@ void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ void sqlite3_result_error_toobig(sqlite3_context *pCtx){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); pCtx->isError = SQLITE_TOOBIG; + pCtx->fErrorOrAux = 1; sqlite3VdbeMemSetStr(&pCtx->s, "string or blob too big", -1, SQLITE_UTF8, SQLITE_STATIC); } @@ -299,6 +336,7 @@ void sqlite3_result_error_nomem(sqlite3_context *pCtx){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); sqlite3VdbeMemSetNull(&pCtx->s); pCtx->isError = SQLITE_NOMEM; + pCtx->fErrorOrAux = 1; pCtx->s.db->mallocFailed = 1; } @@ -382,11 +420,13 @@ static int sqlite3Step(Vdbe *p){ ** reset the interrupt flag. This prevents a call to sqlite3_interrupt ** from interrupting a statement that has not yet started. */ - if( db->activeVdbeCnt==0 ){ + if( db->nVdbeActive==0 ){ db->u1.isInterrupted = 0; } - assert( db->writeVdbeCnt>0 || db->autoCommit==0 || db->nDeferredCons==0 ); + assert( db->nVdbeWrite>0 || db->autoCommit==0 + || (db->nDeferredCons==0 && db->nDeferredImmCons==0) + ); #ifndef SQLITE_OMIT_TRACE if( db->xProfile && !db->init.busy ){ @@ -394,8 +434,9 @@ static int sqlite3Step(Vdbe *p){ } #endif - db->activeVdbeCnt++; - if( p->readOnly==0 ) db->writeVdbeCnt++; + db->nVdbeActive++; + if( p->readOnly==0 ) db->nVdbeWrite++; + if( p->bIsReader ) db->nVdbeRead++; p->pc = 0; } #ifndef SQLITE_OMIT_EXPLAIN @@ -404,9 +445,9 @@ static int sqlite3Step(Vdbe *p){ }else #endif /* SQLITE_OMIT_EXPLAIN */ { - db->vdbeExecCnt++; + db->nVdbeExec++; rc = sqlite3VdbeExec(p); - db->vdbeExecCnt--; + db->nVdbeExec--; } #ifndef SQLITE_OMIT_TRACE @@ -478,7 +519,7 @@ int sqlite3_step(sqlite3_stmt *pStmt){ v->doingRerun = 1; assert( v->expired==0 ); } - if( rc2!=SQLITE_OK && ALWAYS(v->isPrepareV2) && ALWAYS(db->pErr) ){ + if( rc2!=SQLITE_OK ){ /* This case occurs after failing to recompile an sql statement. ** The error message from the SQL compiler has already been loaded ** into the database handle. This block copies the error message @@ -488,6 +529,7 @@ int sqlite3_step(sqlite3_stmt *pStmt){ ** sqlite3_errmsg() and sqlite3_errcode(). */ const char *zErr = (const char *)sqlite3_value_text(db->pErr); + assert( zErr!=0 || db->mallocFailed ); sqlite3DbFree(db, v->zErrMsg); if( !db->mallocFailed ){ v->zErrMsg = sqlite3DbStrDup(db, zErr); @@ -502,6 +544,7 @@ int sqlite3_step(sqlite3_stmt *pStmt){ return rc; } + /* ** Extract the user data from a sqlite3_context structure and return a ** pointer to it. @@ -526,6 +569,19 @@ sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){ return p->s.db; } +/* +** Return the current time for a statement +*/ +sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){ + Vdbe *v = p->pVdbe; + int rc; + if( v->iCurrentTime==0 ){ + rc = sqlite3OsCurrentTimeInt64(p->s.db->pVfs, &v->iCurrentTime); + if( rc ) v->iCurrentTime = 0; + } + return v->iCurrentTime; +} + /* ** The following is the implementation of an SQL function that always ** fails with an error message stating that the function is used in the @@ -581,14 +637,14 @@ void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){ ** the user-function defined by pCtx. */ void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){ - VdbeFunc *pVdbeFunc; + AuxData *pAuxData; assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); - pVdbeFunc = pCtx->pVdbeFunc; - if( !pVdbeFunc || iArg>=pVdbeFunc->nAux || iArg<0 ){ - return 0; + for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){ + if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break; } - return pVdbeFunc->apAux[iArg].pAux; + + return (pAuxData ? pAuxData->pAux : 0); } /* @@ -602,29 +658,30 @@ void sqlite3_set_auxdata( void *pAux, void (*xDelete)(void*) ){ - struct AuxData *pAuxData; - VdbeFunc *pVdbeFunc; - if( iArg<0 ) goto failed; + AuxData *pAuxData; + Vdbe *pVdbe = pCtx->pVdbe; assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); - pVdbeFunc = pCtx->pVdbeFunc; - if( !pVdbeFunc || pVdbeFunc->nAux<=iArg ){ - int nAux = (pVdbeFunc ? pVdbeFunc->nAux : 0); - int nMalloc = sizeof(VdbeFunc) + sizeof(struct AuxData)*iArg; - pVdbeFunc = sqlite3DbRealloc(pCtx->s.db, pVdbeFunc, nMalloc); - if( !pVdbeFunc ){ - goto failed; - } - pCtx->pVdbeFunc = pVdbeFunc; - memset(&pVdbeFunc->apAux[nAux], 0, sizeof(struct AuxData)*(iArg+1-nAux)); - pVdbeFunc->nAux = iArg+1; - pVdbeFunc->pFunc = pCtx->pFunc; - } + if( iArg<0 ) goto failed; - pAuxData = &pVdbeFunc->apAux[iArg]; - if( pAuxData->pAux && pAuxData->xDelete ){ + for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){ + if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break; + } + if( pAuxData==0 ){ + pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData)); + if( !pAuxData ) goto failed; + pAuxData->iOp = pCtx->iOp; + pAuxData->iArg = iArg; + pAuxData->pNext = pVdbe->pAuxData; + pVdbe->pAuxData = pAuxData; + if( pCtx->fErrorOrAux==0 ){ + pCtx->isError = 0; + pCtx->fErrorOrAux = 1; + } + }else if( pAuxData->xDelete ){ pAuxData->xDelete(pAuxData->pAux); } + pAuxData->pAux = pAux; pAuxData->xDelete = xDelete; return; @@ -669,6 +726,30 @@ int sqlite3_data_count(sqlite3_stmt *pStmt){ return pVm->nResColumn; } +/* +** Return a pointer to static memory containing an SQL NULL value. +*/ +static const Mem *columnNullValue(void){ + /* Even though the Mem structure contains an element + ** of type i64, on certain architectures (x86) with certain compiler + ** switches (-Os), gcc may align this Mem object on a 4-byte boundary + ** instead of an 8-byte one. This all works fine, except that when + ** running with SQLITE_DEBUG defined the SQLite code sometimes assert()s + ** that a Mem structure is located on an 8-byte boundary. To prevent + ** these assert()s from failing, when building with SQLITE_DEBUG defined + ** using gcc, we force nullMem to be 8-byte aligned using the magical + ** __attribute__((aligned(8))) macro. */ + static const Mem nullMem +#if defined(SQLITE_DEBUG) && defined(__GNUC__) + __attribute__((aligned(8))) +#endif + = {0, "", (double)0, {0}, 0, MEM_Null, 0, +#ifdef SQLITE_DEBUG + 0, 0, /* pScopyFrom, pFiller */ +#endif + 0, 0 }; + return &nullMem; +} /* ** Check to see if column iCol of the given statement is valid. If @@ -685,32 +766,11 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){ sqlite3_mutex_enter(pVm->db->mutex); pOut = &pVm->pResultSet[i]; }else{ - /* If the value passed as the second argument is out of range, return - ** a pointer to the following static Mem object which contains the - ** value SQL NULL. Even though the Mem structure contains an element - ** of type i64, on certain architectures (x86) with certain compiler - ** switches (-Os), gcc may align this Mem object on a 4-byte boundary - ** instead of an 8-byte one. This all works fine, except that when - ** running with SQLITE_DEBUG defined the SQLite code sometimes assert()s - ** that a Mem structure is located on an 8-byte boundary. To prevent - ** these assert()s from failing, when building with SQLITE_DEBUG defined - ** using gcc, we force nullMem to be 8-byte aligned using the magical - ** __attribute__((aligned(8))) macro. */ - static const Mem nullMem -#if defined(SQLITE_DEBUG) && defined(__GNUC__) - __attribute__((aligned(8))) -#endif - = {0, "", (double)0, {0}, 0, MEM_Null, SQLITE_NULL, 0, -#ifdef SQLITE_DEBUG - 0, 0, /* pScopyFrom, pFiller */ -#endif - 0, 0 }; - if( pVm && ALWAYS(pVm->db) ){ sqlite3_mutex_enter(pVm->db->mutex); sqlite3Error(pVm->db, SQLITE_RANGE, 0); } - pOut = (Mem*)&nullMem; + pOut = (Mem*)columnNullValue(); } return pOut; } @@ -813,13 +873,6 @@ int sqlite3_column_type(sqlite3_stmt *pStmt, int i){ return iType; } -/* The following function is experimental and subject to change or -** removal */ -/*int sqlite3_column_numeric_type(sqlite3_stmt *pStmt, int i){ -** return sqlite3_value_numeric_type( columnMem(pStmt,i) ); -**} -*/ - /* ** Convert the N-th element of pStmt->pColName[] into a string using ** xFunc() then return that string. If N is out of range, return 0. @@ -1114,7 +1167,7 @@ int sqlite3_bind_text16( #endif /* SQLITE_OMIT_UTF16 */ int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){ int rc; - switch( pValue->type ){ + switch( sqlite3_value_type((sqlite3_value*)pValue) ){ case SQLITE_INTEGER: { rc = sqlite3_bind_int64(pStmt, i, pValue->u.i); break; @@ -1270,7 +1323,7 @@ int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){ */ int sqlite3_stmt_busy(sqlite3_stmt *pStmt){ Vdbe *v = (Vdbe*)pStmt; - return v!=0 && v->pc>0 && v->magic==VDBE_MAGIC_RUN; + return v!=0 && v->pc>=0 && v->magic==VDBE_MAGIC_RUN; } /* @@ -1296,7 +1349,7 @@ sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){ */ int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){ Vdbe *pVdbe = (Vdbe*)pStmt; - int v = pVdbe->aCounter[op-1]; - if( resetFlag ) pVdbe->aCounter[op-1] = 0; - return v; + u32 v = pVdbe->aCounter[op]; + if( resetFlag ) pVdbe->aCounter[op] = 0; + return (int)v; } -- cgit v1.2.3