mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Experimental changes to improve the performance of OP_Next.
FossilOrigin-Name: 1a249845251199c00817893add300a1a654b4df9
This commit is contained in:
45
src/vdbe.c
45
src/vdbe.c
@@ -2550,7 +2550,7 @@ case OP_Count: { /* out2-prerelease */
|
||||
BtCursor *pCrsr;
|
||||
|
||||
pCrsr = p->apCsr[pOp->p1]->pCursor;
|
||||
if( pCrsr ){
|
||||
if( ALWAYS(pCrsr) ){
|
||||
rc = sqlite3BtreeCount(pCrsr, &nEntry);
|
||||
}else{
|
||||
nEntry = 0;
|
||||
@@ -3112,15 +3112,9 @@ case OP_OpenWrite: {
|
||||
rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor);
|
||||
pCur->pKeyInfo = pKeyInfo;
|
||||
|
||||
/* Since it performs no memory allocation or IO, the only values that
|
||||
** sqlite3BtreeCursor() may return are SQLITE_EMPTY and SQLITE_OK.
|
||||
** SQLITE_EMPTY is only returned when attempting to open the table
|
||||
** rooted at page 1 of a zero-byte database. */
|
||||
assert( rc==SQLITE_EMPTY || rc==SQLITE_OK );
|
||||
if( rc==SQLITE_EMPTY ){
|
||||
pCur->pCursor = 0;
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
/* Since it performs no memory allocation or IO, the only value that
|
||||
** sqlite3BtreeCursor() may return is SQLITE_OK. */
|
||||
assert( rc==SQLITE_OK );
|
||||
|
||||
/* Set the VdbeCursor.isTable and isIndex variables. Previous versions of
|
||||
** SQLite used to check if the root-page flags were sane at this point
|
||||
@@ -3333,7 +3327,7 @@ case OP_SeekGt: { /* jump, in3 */
|
||||
assert( OP_SeekGe == OP_SeekLt+2 );
|
||||
assert( OP_SeekGt == OP_SeekLt+3 );
|
||||
assert( pC->isOrdered );
|
||||
if( pC->pCursor!=0 ){
|
||||
if( ALWAYS(pC->pCursor!=0) ){
|
||||
oc = pOp->opcode;
|
||||
pC->nullRow = 0;
|
||||
if( pC->isTable ){
|
||||
@@ -3691,7 +3685,7 @@ case OP_NotExists: { /* jump, in3 */
|
||||
assert( pC->isTable );
|
||||
assert( pC->pseudoTableReg==0 );
|
||||
pCrsr = pC->pCursor;
|
||||
if( pCrsr!=0 ){
|
||||
if( ALWAYS(pCrsr!=0) ){
|
||||
res = 0;
|
||||
iKey = pIn3->u.i;
|
||||
rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res);
|
||||
@@ -4218,6 +4212,7 @@ case OP_NullRow: {
|
||||
assert( pC!=0 );
|
||||
pC->nullRow = 1;
|
||||
pC->rowidIsValid = 0;
|
||||
assert( pC->pCursor || pC->pVtabCursor );
|
||||
if( pC->pCursor ){
|
||||
sqlite3BtreeClearCursor(pC->pCursor);
|
||||
}
|
||||
@@ -4241,7 +4236,7 @@ case OP_Last: { /* jump */
|
||||
pC = p->apCsr[pOp->p1];
|
||||
assert( pC!=0 );
|
||||
pCrsr = pC->pCursor;
|
||||
if( pCrsr==0 ){
|
||||
if( NEVER(pCrsr==0) ){
|
||||
res = 1;
|
||||
}else{
|
||||
rc = sqlite3BtreeLast(pCrsr, &res);
|
||||
@@ -4296,7 +4291,9 @@ case OP_Rewind: { /* jump */
|
||||
res = 1;
|
||||
if( isSorter(pC) ){
|
||||
rc = sqlite3VdbeSorterRewind(db, pC, &res);
|
||||
}else if( (pCrsr = pC->pCursor)!=0 ){
|
||||
}else{
|
||||
pCrsr = pC->pCursor;
|
||||
assert( pCrsr );
|
||||
rc = sqlite3BtreeFirst(pCrsr, &res);
|
||||
pC->atFirst = res==0 ?1:0;
|
||||
pC->deferredMoveto = 0;
|
||||
@@ -4311,7 +4308,7 @@ case OP_Rewind: { /* jump */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: Next P1 P2 * * P5
|
||||
/* Opcode: Next P1 P2 * P4 P5
|
||||
**
|
||||
** Advance cursor P1 so that it points to the next key/data pair in its
|
||||
** table or index. If there are no more key/value pairs then fall through
|
||||
@@ -4320,6 +4317,9 @@ case OP_Rewind: { /* jump */
|
||||
**
|
||||
** The P1 cursor must be for a real table, not a pseudo-table.
|
||||
**
|
||||
** P4 is always of type P4_ADVANCE. The function pointer points to
|
||||
** sqlite3BtreeNext().
|
||||
**
|
||||
** If P5 is positive and the jump is taken, then event counter
|
||||
** number P5-1 in the prepared statement is incremented.
|
||||
**
|
||||
@@ -4334,13 +4334,15 @@ case OP_Rewind: { /* jump */
|
||||
**
|
||||
** The P1 cursor must be for a real table, not a pseudo-table.
|
||||
**
|
||||
** P4 is always of type P4_ADVANCE. The function pointer points to
|
||||
** sqlite3BtreePrevious().
|
||||
**
|
||||
** If P5 is positive and the jump is taken, then event counter
|
||||
** number P5-1 in the prepared statement is incremented.
|
||||
*/
|
||||
case OP_Prev: /* jump */
|
||||
case OP_Next: { /* jump */
|
||||
VdbeCursor *pC;
|
||||
BtCursor *pCrsr;
|
||||
int res;
|
||||
|
||||
CHECK_FOR_INTERRUPT;
|
||||
@@ -4354,15 +4356,12 @@ case OP_Next: { /* jump */
|
||||
assert( pOp->opcode==OP_Next );
|
||||
rc = sqlite3VdbeSorterNext(db, pC, &res);
|
||||
}else{
|
||||
pCrsr = pC->pCursor;
|
||||
if( pCrsr==0 ){
|
||||
pC->nullRow = 1;
|
||||
break;
|
||||
}
|
||||
res = 1;
|
||||
assert( pC->deferredMoveto==0 );
|
||||
rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(pCrsr, &res) :
|
||||
sqlite3BtreePrevious(pCrsr, &res);
|
||||
assert( pC->pCursor );
|
||||
assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext );
|
||||
assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious );
|
||||
rc = pOp->p4.xAdvance(pC->pCursor, &res);
|
||||
}
|
||||
pC->nullRow = (u8)res;
|
||||
pC->cacheStatus = CACHE_STALE;
|
||||
|
Reference in New Issue
Block a user