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:
44
src/vdbe.c
44
src/vdbe.c
@@ -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 * * * * *
|
||||
**
|
||||
|
Reference in New Issue
Block a user