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

The OP_SeekScan opcode works, but using it requires disabling the

IN-earlyout optimization because the OP_IfNoHope opcode might move the
cursor.

FossilOrigin-Name: f3c36b840c9a29c0add28039db216f4207a308e5057fc76e3f0004024a8267ac
This commit is contained in:
drh
2020-09-29 01:48:46 +00:00
parent 68cf0ace3d
commit f761d937c2
5 changed files with 76 additions and 20 deletions

View File

@@ -4425,6 +4425,11 @@ seek_not_found:
** opcode is to bypass unnecessary OP_SeekGE operations.
*/
case OP_SeekScan: {
VdbeCursor *pC;
int res;
int n;
UnpackedRecord r;
assert( pOp[1].opcode==OP_SeekGE );
assert( pOp[2].opcode==OP_IdxGT );
assert( pOp[1].p1==pOp[2].p1 );
@@ -4432,7 +4437,61 @@ case OP_SeekScan: {
assert( pOp[1].p3==pOp[2].p3 );
assert( pOp[1].p4.i==pOp[2].p4.i );
assert( pOp->p1>0 );
break; /* No-op for now. FIX ME. */
pC = p->apCsr[pOp[1].p1];
assert( pC!=0 );
assert( pC->eCurType==CURTYPE_BTREE );
assert( !pC->isTable );
if( pC->nullRow ){
#ifdef SQLITE_DEBUG
if( db->flags&SQLITE_VdbeTrace ){
printf("... no prior seeks - fall through\n");
}
#endif
break;
}
n = pOp->p1;
assert( n>=1 );
r.pKeyInfo = pC->pKeyInfo;
r.nField = (u16)pOp[1].p4.i;
r.default_rc = 0;
r.aMem = &aMem[pOp[1].p3];
#ifdef SQLITE_DEBUG
{
int i;
for(i=0; i<r.nField; i++){
assert( memIsValid(&r.aMem[i]) );
REGISTER_TRACE(pOp[1].p3+i, &aMem[pOp[1].p3+i]);
}
}
#endif
res = 0; /* Not needed. Only used to silence a warning. */
while(1){
rc = sqlite3VdbeIdxKeyCompare(db, pC, &r, &res);
if( rc ) goto abort_due_to_error;
if( res>0 ){
#ifdef SQLITE_DEBUG
if( db->flags&SQLITE_VdbeTrace ){
printf("... %d steps and then skip\n", pOp->p1 - n);
}
#endif
pOp++;
goto jump_to_p2;
}
if( res==0 ){
#ifdef SQLITE_DEBUG
if( db->flags&SQLITE_VdbeTrace ){
printf("... %d steps and then success\n", pOp->p1 - n);
}
#endif
pOp += 2;
break;
}
if( n<=0 ) break;
n--;
rc = sqlite3BtreeNext(pC->uc.pCursor, 0);
if( rc ) goto abort_due_to_error;
}
break;
}