| Index: third_party/sqlite/src/src/vdbeapi.c
|
| diff --git a/third_party/sqlite/src/src/vdbeapi.c b/third_party/sqlite/src/src/vdbeapi.c
|
| index 634c29c45da0ebd97528401035cc3d63897abc90..90baaccc68a4e087f6ac6ddb5b146d1777b7d8d2 100644
|
| --- a/third_party/sqlite/src/src/vdbeapi.c
|
| +++ b/third_party/sqlite/src/src/vdbeapi.c
|
| @@ -12,8 +12,6 @@
|
| **
|
| ** This file contains code use to implement APIs that are part of the
|
| ** VDBE.
|
| -**
|
| -** $Id: vdbeapi.c,v 1.167 2009/06/25 01:47:12 drh Exp $
|
| */
|
| #include "sqliteInt.h"
|
| #include "vdbeInt.h"
|
| @@ -34,6 +32,28 @@ int sqlite3_expired(sqlite3_stmt *pStmt){
|
| #endif
|
|
|
| /*
|
| +** Check on a Vdbe to make sure it has not been finalized. Log
|
| +** an error and return true if it has been finalized (or is otherwise
|
| +** invalid). Return false if it is ok.
|
| +*/
|
| +static int vdbeSafety(Vdbe *p){
|
| + if( p->db==0 ){
|
| + sqlite3_log(SQLITE_MISUSE, "API called with finalized prepared statement");
|
| + return 1;
|
| + }else{
|
| + return 0;
|
| + }
|
| +}
|
| +static int vdbeSafetyNotNull(Vdbe *p){
|
| + if( p==0 ){
|
| + sqlite3_log(SQLITE_MISUSE, "API called with NULL prepared statement");
|
| + return 1;
|
| + }else{
|
| + return vdbeSafety(p);
|
| + }
|
| +}
|
| +
|
| +/*
|
| ** The following routine destroys a virtual machine that is created by
|
| ** the sqlite3_compile() routine. The integer returned is an SQLITE_
|
| ** success/failure code that describes the result of executing the virtual
|
| @@ -45,12 +65,18 @@ int sqlite3_expired(sqlite3_stmt *pStmt){
|
| int sqlite3_finalize(sqlite3_stmt *pStmt){
|
| int rc;
|
| if( pStmt==0 ){
|
| + /* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite3_finalize() on a NULL
|
| + ** pointer is a harmless no-op. */
|
| rc = SQLITE_OK;
|
| }else{
|
| Vdbe *v = (Vdbe*)pStmt;
|
| sqlite3 *db = v->db;
|
| #if SQLITE_THREADSAFE
|
| - sqlite3_mutex *mutex = v->db->mutex;
|
| + sqlite3_mutex *mutex;
|
| +#endif
|
| + if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT;
|
| +#if SQLITE_THREADSAFE
|
| + mutex = v->db->mutex;
|
| #endif
|
| sqlite3_mutex_enter(mutex);
|
| rc = sqlite3VdbeFinalize(v);
|
| @@ -99,6 +125,9 @@ int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
|
| sqlite3VdbeMemRelease(&p->aVar[i]);
|
| p->aVar[i].flags = MEM_Null;
|
| }
|
| + if( p->isPrepareV2 && p->expmask ){
|
| + p->expired = 1;
|
| + }
|
| sqlite3_mutex_leave(mutex);
|
| return rc;
|
| }
|
| @@ -114,7 +143,7 @@ const void *sqlite3_value_blob(sqlite3_value *pVal){
|
| sqlite3VdbeMemExpandBlob(p);
|
| p->flags &= ~MEM_Str;
|
| p->flags |= MEM_Blob;
|
| - return p->z;
|
| + return p->n ? p->z : 0;
|
| }else{
|
| return sqlite3_value_text(pVal);
|
| }
|
| @@ -280,6 +309,27 @@ void sqlite3_result_error_nomem(sqlite3_context *pCtx){
|
| }
|
|
|
| /*
|
| +** This function is called after a transaction has been committed. It
|
| +** invokes callbacks registered with sqlite3_wal_hook() as required.
|
| +*/
|
| +static int doWalCallbacks(sqlite3 *db){
|
| + int rc = SQLITE_OK;
|
| +#ifndef SQLITE_OMIT_WAL
|
| + int i;
|
| + for(i=0; i<db->nDb; i++){
|
| + Btree *pBt = db->aDb[i].pBt;
|
| + if( pBt ){
|
| + int nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt));
|
| + if( db->xWalCallback && nEntry>0 && rc==SQLITE_OK ){
|
| + rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zName, nEntry);
|
| + }
|
| + }
|
| + }
|
| +#endif
|
| + return rc;
|
| +}
|
| +
|
| +/*
|
| ** Execute the statement pStmt, either until a row of data is ready, the
|
| ** statement is completely executed or an error occurs.
|
| **
|
| @@ -294,26 +344,45 @@ static int sqlite3Step(Vdbe *p){
|
|
|
| assert(p);
|
| if( p->magic!=VDBE_MAGIC_RUN ){
|
| - return SQLITE_MISUSE;
|
| + /* We used to require that sqlite3_reset() be called before retrying
|
| + ** sqlite3_step() after any error or after SQLITE_DONE. But beginning
|
| + ** with version 3.7.0, we changed this so that sqlite3_reset() would
|
| + ** be called automatically instead of throwing the SQLITE_MISUSE error.
|
| + ** This "automatic-reset" change is not technically an incompatibility,
|
| + ** since any application that receives an SQLITE_MISUSE is broken by
|
| + ** definition.
|
| + **
|
| + ** Nevertheless, some published applications that were originally written
|
| + ** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE
|
| + ** returns, and the so were broken by the automatic-reset change. As a
|
| + ** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the
|
| + ** legacy behavior of returning SQLITE_MISUSE for cases where the
|
| + ** previous sqlite3_step() returned something other than a SQLITE_LOCKED
|
| + ** or SQLITE_BUSY error.
|
| + */
|
| +#ifdef SQLITE_OMIT_AUTORESET
|
| + if( p->rc==SQLITE_BUSY || p->rc==SQLITE_LOCKED ){
|
| + sqlite3_reset((sqlite3_stmt*)p);
|
| + }else{
|
| + return SQLITE_MISUSE_BKPT;
|
| + }
|
| +#else
|
| + sqlite3_reset((sqlite3_stmt*)p);
|
| +#endif
|
| }
|
|
|
| - /* Assert that malloc() has not failed */
|
| + /* Check that malloc() has not failed. If it has, return early. */
|
| db = p->db;
|
| if( db->mallocFailed ){
|
| + p->rc = SQLITE_NOMEM;
|
| return SQLITE_NOMEM;
|
| }
|
|
|
| if( p->pc<=0 && p->expired ){
|
| - if( ALWAYS(p->rc==SQLITE_OK) ){
|
| - p->rc = SQLITE_SCHEMA;
|
| - }
|
| + p->rc = SQLITE_SCHEMA;
|
| rc = SQLITE_ERROR;
|
| goto end_of_step;
|
| }
|
| - if( sqlite3SafetyOn(db) ){
|
| - p->rc = SQLITE_MISUSE;
|
| - return SQLITE_MISUSE;
|
| - }
|
| if( p->pc<0 ){
|
| /* If there are no other statements currently running, then
|
| ** reset the interrupt flag. This prevents a call to sqlite3_interrupt
|
| @@ -323,11 +392,11 @@ static int sqlite3Step(Vdbe *p){
|
| db->u1.isInterrupted = 0;
|
| }
|
|
|
| + assert( db->writeVdbeCnt>0 || db->autoCommit==0 || db->nDeferredCons==0 );
|
| +
|
| #ifndef SQLITE_OMIT_TRACE
|
| if( db->xProfile && !db->init.busy ){
|
| - double rNow;
|
| - sqlite3OsCurrentTime(db->pVfs, &rNow);
|
| - p->startTime = (u64)((rNow - (int)rNow)*3600.0*24.0*1000000000.0);
|
| + sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime);
|
| }
|
| #endif
|
|
|
| @@ -341,27 +410,29 @@ static int sqlite3Step(Vdbe *p){
|
| }else
|
| #endif /* SQLITE_OMIT_EXPLAIN */
|
| {
|
| + db->vdbeExecCnt++;
|
| rc = sqlite3VdbeExec(p);
|
| - }
|
| -
|
| - if( sqlite3SafetyOff(db) ){
|
| - rc = SQLITE_MISUSE;
|
| + db->vdbeExecCnt--;
|
| }
|
|
|
| #ifndef SQLITE_OMIT_TRACE
|
| /* Invoke the profile callback if there is one
|
| */
|
| if( rc!=SQLITE_ROW && db->xProfile && !db->init.busy && p->zSql ){
|
| - double rNow;
|
| - u64 elapseTime;
|
| -
|
| - sqlite3OsCurrentTime(db->pVfs, &rNow);
|
| - elapseTime = (u64)((rNow - (int)rNow)*3600.0*24.0*1000000000.0);
|
| - elapseTime -= p->startTime;
|
| - db->xProfile(db->pProfileArg, p->zSql, elapseTime);
|
| + sqlite3_int64 iNow;
|
| + sqlite3OsCurrentTimeInt64(db->pVfs, &iNow);
|
| + db->xProfile(db->pProfileArg, p->zSql, (iNow - p->startTime)*1000000);
|
| }
|
| #endif
|
|
|
| + if( rc==SQLITE_DONE ){
|
| + assert( p->rc==SQLITE_OK );
|
| + p->rc = doWalCallbacks(db);
|
| + if( p->rc!=SQLITE_OK ){
|
| + rc = SQLITE_ERROR;
|
| + }
|
| + }
|
| +
|
| db->errCode = rc;
|
| if( SQLITE_NOMEM==sqlite3ApiExit(p->db, p->rc) ){
|
| p->rc = SQLITE_NOMEM;
|
| @@ -394,39 +465,44 @@ end_of_step:
|
| ** call sqlite3Reprepare() and try again.
|
| */
|
| int sqlite3_step(sqlite3_stmt *pStmt){
|
| - int rc = SQLITE_MISUSE;
|
| - if( pStmt ){
|
| - int cnt = 0;
|
| - Vdbe *v = (Vdbe*)pStmt;
|
| - sqlite3 *db = v->db;
|
| - sqlite3_mutex_enter(db->mutex);
|
| - while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
|
| - && cnt++ < 5
|
| - && (rc = sqlite3Reprepare(v))==SQLITE_OK ){
|
| - sqlite3_reset(pStmt);
|
| - v->expired = 0;
|
| - }
|
| - if( rc==SQLITE_SCHEMA && ALWAYS(v->isPrepareV2) && ALWAYS(db->pErr) ){
|
| - /* 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
|
| - ** from the database handle into the statement and sets the statement
|
| - ** program counter to 0 to ensure that when the statement is
|
| - ** finalized or reset the parser error message is available via
|
| - ** sqlite3_errmsg() and sqlite3_errcode().
|
| - */
|
| - const char *zErr = (const char *)sqlite3_value_text(db->pErr);
|
| - sqlite3DbFree(db, v->zErrMsg);
|
| - if( !db->mallocFailed ){
|
| - v->zErrMsg = sqlite3DbStrDup(db, zErr);
|
| - } else {
|
| - v->zErrMsg = 0;
|
| - v->rc = SQLITE_NOMEM;
|
| - }
|
| + int rc = SQLITE_OK; /* Result from sqlite3Step() */
|
| + int rc2 = SQLITE_OK; /* Result from sqlite3Reprepare() */
|
| + Vdbe *v = (Vdbe*)pStmt; /* the prepared statement */
|
| + int cnt = 0; /* Counter to prevent infinite loop of reprepares */
|
| + sqlite3 *db; /* The database connection */
|
| +
|
| + if( vdbeSafetyNotNull(v) ){
|
| + return SQLITE_MISUSE_BKPT;
|
| + }
|
| + db = v->db;
|
| + sqlite3_mutex_enter(db->mutex);
|
| + while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
|
| + && cnt++ < 5
|
| + && (rc2 = rc = sqlite3Reprepare(v))==SQLITE_OK ){
|
| + sqlite3_reset(pStmt);
|
| + v->expired = 0;
|
| + }
|
| + if( rc2!=SQLITE_OK && ALWAYS(v->isPrepareV2) && ALWAYS(db->pErr) ){
|
| + /* 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
|
| + ** from the database handle into the statement and sets the statement
|
| + ** program counter to 0 to ensure that when the statement is
|
| + ** finalized or reset the parser error message is available via
|
| + ** sqlite3_errmsg() and sqlite3_errcode().
|
| + */
|
| + const char *zErr = (const char *)sqlite3_value_text(db->pErr);
|
| + sqlite3DbFree(db, v->zErrMsg);
|
| + if( !db->mallocFailed ){
|
| + v->zErrMsg = sqlite3DbStrDup(db, zErr);
|
| + v->rc = rc2;
|
| + } else {
|
| + v->zErrMsg = 0;
|
| + v->rc = rc = SQLITE_NOMEM;
|
| }
|
| - rc = sqlite3ApiExit(db, rc);
|
| - sqlite3_mutex_leave(db->mutex);
|
| }
|
| + rc = sqlite3ApiExit(db, rc);
|
| + sqlite3_mutex_leave(db->mutex);
|
| return rc;
|
| }
|
|
|
| @@ -442,6 +518,12 @@ void *sqlite3_user_data(sqlite3_context *p){
|
| /*
|
| ** Extract the user data from a sqlite3_context structure and return a
|
| ** pointer to it.
|
| +**
|
| +** IMPLEMENTATION-OF: R-46798-50301 The sqlite3_context_db_handle() interface
|
| +** returns a copy of the pointer to the database connection (the 1st
|
| +** parameter) of the sqlite3_create_function() and
|
| +** sqlite3_create_function16() routines that originally registered the
|
| +** application defined function.
|
| */
|
| sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){
|
| assert( p && p->pFunc );
|
| @@ -480,8 +562,9 @@ void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
|
| assert( p && p->pFunc && p->pFunc->xStep );
|
| assert( sqlite3_mutex_held(p->s.db->mutex) );
|
| pMem = p->pMem;
|
| + testcase( nByte<0 );
|
| if( (pMem->flags & MEM_Agg)==0 ){
|
| - if( nByte==0 ){
|
| + if( nByte<=0 ){
|
| sqlite3VdbeMemReleaseExternal(pMem);
|
| pMem->flags = MEM_Null;
|
| pMem->z = 0;
|
| @@ -599,13 +682,11 @@ int sqlite3_data_count(sqlite3_stmt *pStmt){
|
| */
|
| static Mem *columnMem(sqlite3_stmt *pStmt, int i){
|
| Vdbe *pVm;
|
| - int vals;
|
| Mem *pOut;
|
|
|
| pVm = (Vdbe *)pStmt;
|
| if( pVm && pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){
|
| sqlite3_mutex_enter(pVm->db->mutex);
|
| - vals = sqlite3_data_count(pStmt);
|
| pOut = &pVm->pResultSet[i];
|
| }else{
|
| /* If the value passed as the second argument is out of range, return
|
| @@ -623,7 +704,11 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){
|
| #if defined(SQLITE_DEBUG) && defined(__GNUC__)
|
| __attribute__((aligned(8)))
|
| #endif
|
| - = {{0}, (double)0, 0, "", 0, MEM_Null, SQLITE_NULL, 0, 0, 0 };
|
| + = {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);
|
| @@ -650,8 +735,7 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){
|
| ** sqlite3_column_real()
|
| ** sqlite3_column_bytes()
|
| ** sqlite3_column_bytes16()
|
| -**
|
| -** But not for sqlite3_column_blob(), which never calls malloc().
|
| +** sqiite3_column_blob()
|
| */
|
| static void columnMallocFailure(sqlite3_stmt *pStmt)
|
| {
|
| @@ -895,12 +979,16 @@ const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
|
| */
|
| static int vdbeUnbind(Vdbe *p, int i){
|
| Mem *pVar;
|
| - if( p==0 ) return SQLITE_MISUSE;
|
| + if( vdbeSafetyNotNull(p) ){
|
| + return SQLITE_MISUSE_BKPT;
|
| + }
|
| sqlite3_mutex_enter(p->db->mutex);
|
| if( p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){
|
| sqlite3Error(p->db, SQLITE_MISUSE, 0);
|
| sqlite3_mutex_leave(p->db->mutex);
|
| - return SQLITE_MISUSE;
|
| + sqlite3_log(SQLITE_MISUSE,
|
| + "bind on a busy prepared statement: [%s]", p->zSql);
|
| + return SQLITE_MISUSE_BKPT;
|
| }
|
| if( i<1 || i>p->nVar ){
|
| sqlite3Error(p->db, SQLITE_RANGE, 0);
|
| @@ -912,6 +1000,21 @@ static int vdbeUnbind(Vdbe *p, int i){
|
| sqlite3VdbeMemRelease(pVar);
|
| pVar->flags = MEM_Null;
|
| sqlite3Error(p->db, SQLITE_OK, 0);
|
| +
|
| + /* If the bit corresponding to this variable in Vdbe.expmask is set, then
|
| + ** binding a new value to this variable invalidates the current query plan.
|
| + **
|
| + ** IMPLEMENTATION-OF: R-48440-37595 If the specific value bound to host
|
| + ** parameter in the WHERE clause might influence the choice of query plan
|
| + ** for a statement, then the statement will be automatically recompiled,
|
| + ** as if there had been a schema change, on the first sqlite3_step() call
|
| + ** following any change to the bindings of that parameter.
|
| + */
|
| + if( p->isPrepareV2 &&
|
| + ((i<32 && p->expmask & ((u32)1 << i)) || p->expmask==0xffffffff)
|
| + ){
|
| + p->expired = 1;
|
| + }
|
| return SQLITE_OK;
|
| }
|
|
|
| @@ -942,6 +1045,8 @@ static int bindText(
|
| rc = sqlite3ApiExit(p->db, rc);
|
| }
|
| sqlite3_mutex_leave(p->db->mutex);
|
| + }else if( xDel!=SQLITE_STATIC && xDel!=SQLITE_TRANSIENT ){
|
| + xDel((void*)zData);
|
| }
|
| return rc;
|
| }
|
| @@ -1108,8 +1213,7 @@ const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
|
| ** with that name. If there is no variable with the given name,
|
| ** return 0.
|
| */
|
| -int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){
|
| - Vdbe *p = (Vdbe*)pStmt;
|
| +int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nName){
|
| int i;
|
| if( p==0 ){
|
| return 0;
|
| @@ -1118,13 +1222,16 @@ int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){
|
| if( zName ){
|
| for(i=0; i<p->nVar; i++){
|
| const char *z = p->azVar[i];
|
| - if( z && strcmp(z,zName)==0 ){
|
| + if( z && memcmp(z,zName,nName)==0 && z[nName]==0 ){
|
| return i+1;
|
| }
|
| }
|
| }
|
| return 0;
|
| }
|
| +int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){
|
| + return sqlite3VdbeParameterIndex((Vdbe*)pStmt, zName, sqlite3Strlen30(zName));
|
| +}
|
|
|
| /*
|
| ** Transfer all bindings from the first statement over to the second.
|
| @@ -1162,6 +1269,12 @@ int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
|
| if( pFrom->nVar!=pTo->nVar ){
|
| return SQLITE_ERROR;
|
| }
|
| + if( pTo->isPrepareV2 && pTo->expmask ){
|
| + pTo->expired = 1;
|
| + }
|
| + if( pFrom->isPrepareV2 && pFrom->expmask ){
|
| + pFrom->expired = 1;
|
| + }
|
| return sqlite3TransferBindings(pFromStmt, pToStmt);
|
| }
|
| #endif
|
| @@ -1177,6 +1290,14 @@ sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){
|
| }
|
|
|
| /*
|
| +** Return true if the prepared statement is guaranteed to not modify the
|
| +** database.
|
| +*/
|
| +int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){
|
| + return pStmt ? ((Vdbe*)pStmt)->readOnly : 1;
|
| +}
|
| +
|
| +/*
|
| ** Return a pointer to the next prepared statement after pStmt associated
|
| ** with database connection pDb. If pStmt is NULL, return the first
|
| ** prepared statement for the database connection. Return NULL if there
|
|
|