1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Add the experimental sqlite3_stmt_scanstatus() API.

FossilOrigin-Name: 6a9bab34aeb6a01b612211a28c140de60a3e883c
This commit is contained in:
dan
2014-10-31 20:11:32 +00:00
parent 0fb5daed34
commit 04489b6dce
12 changed files with 394 additions and 31 deletions

View File

@@ -167,6 +167,18 @@ int sqlite3_found_count = 0;
/* Return true if the cursor was opened using the OP_OpenSorter opcode. */
#define isSorter(x) ((x)->pSorter!=0)
/*
** The first argument passed to the IncrementExplainCounter() macro must
** be a non-NULL pointer to an object of type VdbeCursor. The second
** argument must be either "nLoop" or "nVisit" (without the double-quotes).
*/
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
# define IncrementExplainCounter(pCsr, counter) \
if( (pCsr)->pExplain ) (pCsr)->pExplain->counter++
#else
# define IncrementExplainCounter(pCsr, counter)
#endif
/*
** Allocate VdbeCursor number iCur. Return a pointer to it. Return NULL
** if we run out of memory.
@@ -3556,6 +3568,7 @@ case OP_SeekGT: { /* jump, in3 */
#ifdef SQLITE_DEBUG
pC->seekOp = pOp->opcode;
#endif
IncrementExplainCounter(pC, nLoop);
if( pC->isTable ){
/* The input value in P3 might be of any type: integer, real, string,
** blob, or NULL. But it needs to be an integer before we can do
@@ -3664,6 +3677,8 @@ case OP_SeekGT: { /* jump, in3 */
VdbeBranchTaken(res!=0,2);
if( res ){
pc = pOp->p2 - 1;
}else{
IncrementExplainCounter(pC, nVisit);
}
break;
}
@@ -4449,6 +4464,8 @@ case OP_Last: { /* jump */
res = 0;
assert( pCrsr!=0 );
rc = sqlite3BtreeLast(pCrsr, &res);
IncrementExplainCounter(pC, nLoop);
if( res==0 ) IncrementExplainCounter(pC, nVisit);
pC->nullRow = (u8)res;
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
@@ -4488,9 +4505,9 @@ case OP_Sort: { /* jump */
**
** The next use of the Rowid or Column or Next instruction for P1
** will refer to the first entry in the database table or index.
** If the table or index is empty and P2>0, then jump immediately to P2.
** If P2 is 0 or if the table or index is not empty, fall through
** to the following instruction.
** If the table or index is empty, jump immediately to P2.
** If the table or index is not empty, fall through to the following
** instruction.
**
** This opcode leaves the cursor configured to move in forward order,
** from the beginning toward the end. In other words, the cursor is
@@ -4518,11 +4535,14 @@ case OP_Rewind: { /* jump */
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
}
IncrementExplainCounter(pC, nLoop);
pC->nullRow = (u8)res;
assert( pOp->p2>0 && pOp->p2<p->nOp );
VdbeBranchTaken(res!=0,2);
if( res ){
pc = pOp->p2 - 1;
}else{
IncrementExplainCounter(pC, nVisit);
}
break;
}
@@ -4633,6 +4653,7 @@ next_tail:
pC->cacheStatus = CACHE_STALE;
VdbeBranchTaken(res==0,2);
if( res==0 ){
IncrementExplainCounter(pC, nVisit);
pC->nullRow = 0;
pc = pOp->p2 - 1;
p->aCounter[pOp->p5]++;
@@ -6055,7 +6076,10 @@ case OP_VFilter: { /* jump */
VdbeBranchTaken(res!=0,2);
if( res ){
pc = pOp->p2 - 1;
}else{
IncrementExplainCounter(pCur, nVisit);
}
IncrementExplainCounter(pCur, nLoop);
}
pCur->nullRow = 0;
@@ -6148,6 +6172,7 @@ case OP_VNext: { /* jump */
if( !res ){
/* If there is data, jump to P2 */
pc = pOp->p2 - 1;
IncrementExplainCounter(pCur, nVisit);
}
goto check_for_interrupt;
}
@@ -6347,6 +6372,19 @@ case OP_Init: { /* jump */
break;
}
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
case OP_Explain: {
ExplainArg *pArg;
VdbeCursor *pCur;
if( pOp->p4type==P4_EXPLAIN && (pArg = pOp->p4.pExplain)->iCsr>=0 ){
pArg = pOp->p4.pExplain;
pCur = p->apCsr[pArg->iCsr];
pCur->pExplain = pArg;
}
break;
}
#endif
/* Opcode: Noop * * * * *
**