diff options
author | drh <drh@noemail.net> | 2014-11-18 21:20:57 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2014-11-18 21:20:57 +0000 |
commit | 04e8a5866948996e4dd1540a9a736d00609c27e8 (patch) | |
tree | fcf53188c46e77ce3d90818bc17e118298813b18 /src/vdbeapi.c | |
parent | ca3e10ea37c4808fa84063f06b02229801b28cc0 (diff) | |
parent | 64b600ff13d4bac1d459cf54b649b45e520aba4c (diff) | |
download | sqlite-04e8a5866948996e4dd1540a9a736d00609c27e8.tar.gz sqlite-04e8a5866948996e4dd1540a9a736d00609c27e8.zip |
Merge recent trunk enhancements, including the read-after-ROLLBACK change
and the addition of sqlite3_stmt_scanstatus() support, as well as various
minor bug fixes.
FossilOrigin-Name: f09055f3c4348264c7336f90646375f0d98b061e
Diffstat (limited to 'src/vdbeapi.c')
-rw-r--r-- | src/vdbeapi.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/vdbeapi.c b/src/vdbeapi.c index e0b204cd1..c7c14d9c3 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1656,3 +1656,72 @@ int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ return sqlite3ApiExit(db, rc); } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ + +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS +/* +** Return status data for a single loop within query pStmt. +*/ +int sqlite3_stmt_scanstatus( + sqlite3_stmt *pStmt, /* Prepared statement being queried */ + int idx, /* Index of loop to report on */ + int iScanStatusOp, /* Which metric to return */ + void *pOut /* OUT: Write the answer here */ +){ + Vdbe *p = (Vdbe*)pStmt; + ScanStatus *pScan; + if( idx<0 || idx>=p->nScan ) return 1; + pScan = &p->aScan[idx]; + switch( iScanStatusOp ){ + case SQLITE_SCANSTAT_NLOOP: { + *(sqlite3_int64*)pOut = p->anExec[pScan->addrLoop]; + break; + } + case SQLITE_SCANSTAT_NVISIT: { + *(sqlite3_int64*)pOut = p->anExec[pScan->addrVisit]; + break; + } + case SQLITE_SCANSTAT_EST: { + double r = 1.0; + LogEst x = pScan->nEst; + while( x<100 ){ + x += 10; + r *= 0.5; + } + *(double*)pOut = r*sqlite3LogEstToInt(x); + break; + } + case SQLITE_SCANSTAT_NAME: { + *(const char**)pOut = pScan->zName; + break; + } + case SQLITE_SCANSTAT_EXPLAIN: { + if( pScan->addrExplain ){ + *(const char**)pOut = p->aOp[ pScan->addrExplain ].p4.z; + }else{ + *(const char**)pOut = 0; + } + break; + } + case SQLITE_SCANSTAT_SELECTID: { + if( pScan->addrExplain ){ + *(int*)pOut = p->aOp[ pScan->addrExplain ].p1; + }else{ + *(int*)pOut = -1; + } + break; + } + default: { + return 1; + } + } + return 0; +} + +/* +** Zero all counters associated with the sqlite3_stmt_scanstatus() data. +*/ +void sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){ + Vdbe *p = (Vdbe*)pStmt; + memset(p->anExec, 0, p->nOp * sizeof(i64)); +} +#endif /* SQLITE_ENABLE_STMT_SCANSTATUS */ |