diff options
author | drh <> | 2022-04-11 17:27:38 +0000 |
---|---|---|
committer | drh <> | 2022-04-11 17:27:38 +0000 |
commit | 6134b2dff2d5df510210880f935bbd2b0a08f93c (patch) | |
tree | 9872e7deb3017e5b1c637fb916e99d815cb01932 /src | |
parent | ff02ac7f078bbe25c3940ffa35458f0807055fa3 (diff) | |
download | sqlite-6134b2dff2d5df510210880f935bbd2b0a08f93c.tar.gz sqlite-6134b2dff2d5df510210880f935bbd2b0a08f93c.zip |
Fix handling of "continue" and "break" from inside the loop for the right
operand of a RIGHT JOIN.
FossilOrigin-Name: b6e773a26c2c6ee76ea61acb059b4e676d07ea62f6db9c513638f8986557cf04
Diffstat (limited to 'src')
-rw-r--r-- | src/vdbe.c | 10 | ||||
-rw-r--r-- | src/where.c | 11 | ||||
-rw-r--r-- | src/whereInt.h | 1 |
3 files changed, 16 insertions, 6 deletions
diff --git a/src/vdbe.c b/src/vdbe.c index 18286c297..45a47756e 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -993,8 +993,12 @@ jump_to_p2: /* Opcode: Return P1 P2 P3 * * ** -** Jump to the next instruction after the address in register P1. After -** the jump, register P1 becomes undefined. +** Jump to the next instruction after the address stored in register P1. +** +** It used to be that after the jump, register P1 would become undefined. +** However, for the subroutine used for the inner loop of a RIGHT JOIN, +** it is useful for R1 register to be unchanged, so that is what happens +** now. ** ** P2 is not used by the byte-code engine. However, if P2 is positive ** and also less than the current address, then the "EXPLAIN" output @@ -1012,7 +1016,7 @@ case OP_Return: { /* in1 */ pIn1 = &aMem[pOp->p1]; assert( pIn1->flags==MEM_Int ); pOp = &aOp[pIn1->u.i]; - pIn1->flags = MEM_Undefined; + /* pIn1->flags = MEM_Undefined; */ break; } diff --git a/src/where.c b/src/where.c index 3677759ce..defbc860f 100644 --- a/src/where.c +++ b/src/where.c @@ -5880,6 +5880,7 @@ WhereInfo *sqlite3WhereBegin( pRJ->regBloom = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Blob, 65536, pRJ->regBloom); pRJ->regReturn = ++pParse->nMem; + pRJ->addrInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, pRJ->regReturn); assert( pTab==pTabItem->pTab ); if( HasRowid(pTab) ){ KeyInfo *pInfo; @@ -6013,7 +6014,11 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ /* Terminate the subroutine that forms the interior of the loop of ** the RIGHT JOIN table */ WhereRightJoin *pRJ = pLevel->pRJ; - sqlite3VdbeChangeP1(v, pRJ->addrSubrtn-1, sqlite3VdbeCurrentAddr(v)); + int addrHere = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeChangeP1(v, pRJ->addrSubrtn-1, addrHere); + sqlite3VdbeChangeP1(v, pRJ->addrInit, addrHere); + sqlite3VdbeResolveLabel(v, pLevel->addrCont); + pLevel->addrCont = 0; sqlite3VdbeAddOp2(v, OP_Return, pRJ->regReturn, pRJ->addrSubrtn); } pLoop = pLevel->pWLoop; @@ -6043,7 +6048,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ } #endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */ /* The common case: Advance to the next row */ - sqlite3VdbeResolveLabel(v, pLevel->addrCont); + if( pLevel->addrCont ) sqlite3VdbeResolveLabel(v, pLevel->addrCont); sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3); sqlite3VdbeChangeP5(v, pLevel->p5); VdbeCoverage(v); @@ -6058,7 +6063,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek); #endif - }else{ + }else if( pLevel->addrCont ){ sqlite3VdbeResolveLabel(v, pLevel->addrCont); } if( (pLoop->wsFlags & WHERE_IN_ABLE)!=0 && pLevel->u.in.nIn>0 ){ diff --git a/src/whereInt.h b/src/whereInt.h index 7b5be3011..6be8234e2 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -52,6 +52,7 @@ struct WhereRightJoin { int regBloom; /* Bloom filter for iRJMatch */ int regReturn; /* Return register for the interior subroutine */ int addrSubrtn; /* Starting address for the interior subroutine */ + int addrInit; /* OP_Integer used for early init of regReturn */ }; /* |