diff options
Diffstat (limited to 'src/vdbeapi.c')
-rw-r--r-- | src/vdbeapi.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 66dfd7152..107c1eb6c 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -914,6 +914,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 is set in Vdbe.opmask, set + ** the optimizable flag before returning. This tells the sqlite3_reoptimize() + ** function that the VM program may benefit from recompilation. + ** + ** If the bit in Vdbe.expmask is set, then binding a new value to this + ** variable invalidates the current query plan. This comes about when the + ** variable is the RHS of a LIKE or GLOB operator and the LIKE/GLOB is + ** able to use an index. */ + if( (i<32 && p->optmask & ((u32)1 << i)) || p->optmask==0xffffffff ){ + p->optimizable = 1; + } + if( (i<32 && p->expmask & ((u32)1 << i)) || p->expmask==0xffffffff ){ + p->expired = 1; + } return SQLITE_OK; } @@ -1205,3 +1220,25 @@ int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){ if( resetFlag ) pVdbe->aCounter[op-1] = 0; return v; } + +/* +** If possible, optimize the statement for the current bindings. +*/ +int sqlite3_reoptimize(sqlite3_stmt *pStmt){ + int rc = SQLITE_OK; + Vdbe *v = (Vdbe *)pStmt; + sqlite3 *db = v->db; + + sqlite3_mutex_enter(db->mutex); + if( v->isPrepareV2==0 || v->pc>0 ){ + rc = SQLITE_MISUSE; + }else if( v->optimizable ){ + rc = sqlite3Reprepare(v); + rc = sqlite3ApiExit(db, rc); + } + assert( rc!=SQLITE_OK || v->optimizable==0 ); + sqlite3_mutex_leave(db->mutex); + + return rc; +} + |