aboutsummaryrefslogtreecommitdiff
path: root/src/wherecode.c
diff options
context:
space:
mode:
authordrh <>2022-04-09 12:27:20 +0000
committerdrh <>2022-04-09 12:27:20 +0000
commit7c1734b09e436176c2aac461e835c29532403ad4 (patch)
tree31980b91155d55166411d6be8f963e85514ca12d /src/wherecode.c
parentc2308ad2a0cb4f6d957518c615d308ed79b42d04 (diff)
downloadsqlite-7c1734b09e436176c2aac461e835c29532403ad4.tar.gz
sqlite-7c1734b09e436176c2aac461e835c29532403ad4.zip
The interior of the RIGHT JOIN loop is now a subroutine.
FossilOrigin-Name: 549f5a7ee639de80f049445002f58e93c805f9a3d3db1987ec9d139ccef4805e
Diffstat (limited to 'src/wherecode.c')
-rw-r--r--src/wherecode.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/src/wherecode.c b/src/wherecode.c
index 5b8ed8934..853646c71 100644
--- a/src/wherecode.c
+++ b/src/wherecode.c
@@ -2724,12 +2724,18 @@ Bitmask sqlite3WhereCodeOneLoopStart(
/* For a RIGHT OUTER JOIN, record the fact that the current row has
** been matched at least once.
*/
- if( pLevel->iRJMatch ){
+ if( pLevel->pRJ ){
Table *pTab;
int nPk;
int r;
int jmp1 = 0;
+ WhereRightJoin *pRJ = pLevel->pRJ;
+ /* pTab is the right-hand table of the RIGHT JOIN. Generate code that
+ ** will record that the current row of that table has been matched at
+ ** least once. This is accomplished by storing the PK for the row in
+ ** both the iMatch index and the regBloom Bloom filter.
+ */
pTab = pWInfo->pTabList->a[pLevel->iFrom].pTab;
if( HasRowid(pTab) ){
r = sqlite3GetTempRange(pParse, 2);
@@ -2745,15 +2751,23 @@ Bitmask sqlite3WhereCodeOneLoopStart(
sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+1+iPk);
}
}
- jmp1 = sqlite3VdbeAddOp4Int(v, OP_Found, pLevel->iRJMatch, 0, r+1, nPk);
+ jmp1 = sqlite3VdbeAddOp4Int(v, OP_Found, pRJ->iMatch, 0, r+1, nPk);
VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_MakeRecord, r+1, nPk, r);
- sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pLevel->iRJMatch, r, r+1, nPk);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pRJ->iMatch, r, r+1, nPk);
+ sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pRJ->regBloom, 0, r+1, nPk);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
sqlite3VdbeJumpHere(v, jmp1);
-
- /* Release the array of temp registers */
sqlite3ReleaseTempRange(pParse, r, nPk+1);
+
+ /* Create a subroutine used to process all interior loops and code
+ ** of the RIGHT JOIN. During normal operation, the subroutine will
+ ** be in-line with the rest of the code. But at the end, a separate
+ ** loop will run that invokes this subroutine for unmatched rows
+ ** of pTab, with all tables to left begin set to NULL.
+ */
+ sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pRJ->regReturn);
+ pRJ->addrSubrtn = sqlite3VdbeCurrentAddr(v);
}
#if WHERETRACE_ENABLED /* 0x20800 */