-C Merge\sthe\slatest\senhancements\sfrom\strunk\sinto\sthe\sright-join\sbranch.
-D 2022-04-12T17:43:30.239
+C Factor\sout\sthe\sRIGHT\sJOIN\snon-matched\srow\sloop\sfrom\ssqlite3WhereEnd().\s\sThis\nreduces\sthe\sregister\spressure\son\sthat\sroutine\sand\shelps\sit\sto\srun\sfaster\nin\sthe\scommon\scase\swhere\sthere\sis\sno\sRIGHT\sJOIN.
+D 2022-04-12T18:04:29.831
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d
F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b
-F src/where.c 5473af25fd2acd2898574950f51e4eaec77d57c450c0d3339905f3db42c6bb30
-F src/whereInt.h cd6bddac3a26640b92d86e2b45ecc6e82d663cbcac6fd5d6d9690dfb280b1668
-F src/wherecode.c bdf7de22c7ac38ad92e78214231a6054019521bfab943c2bfd5ddfb9e8ad9255
+F src/where.c 4176c858089e521de3f0961751016dc23314bd8bc5ae382ef2619eb38f6b968e
+F src/whereInt.h ea1e4b6639c4c32246f4c54b733143df76109894adf08bedee4f3999ece62c2d
+F src/wherecode.c 3b0cfb2f794ae3f84c01c6d1c38ccd99886c79caab5c18550b1781ccfc27aa9c
F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5
F src/window.c 42a71595263dbd8ef8248218e4fc7d4b5ddccece52146ad48e079342d93f6f8f
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 34c2f7b237fa4e0e1cd94fb9c44ebe194b86b88dc575055cc46c7f3695d02756 bff4f083eb1c35544988493a5d73a42e646c4250b841f5aae38c2183f0867a0e
-R 6edf425faad4274a6a777cbfb5cf556e
+P b3e57ba120067c79e0398e39da9f00ecb11a5e18c36479da4c36a39e88a78a27
+R bf3e23f39f0d1aa0a416881bc1478c40
U drh
-Z d12d0f4af27fba9957f9dda2ef72c12a
+Z ccf3d060da235adb8537400c4c3b77af
# Remove this line to create a well-formed Fossil manifest.
-b3e57ba120067c79e0398e39da9f00ecb11a5e18c36479da4c36a39e88a78a27
\ No newline at end of file
+beeecf1604d4fb11e45058f48cb2289c6542e0bc218d63a245198113d8d5476b
\ No newline at end of file
** all of the columns of the left operand set to NULL.
*/
if( pLevel->pRJ ){
- WhereRightJoin *pRJ = pLevel->pRJ;
- Expr *pSubWhere = 0;
- WhereClause *pWC = &pWInfo->sWC;
- WhereInfo *pSubWInfo;
- SrcList sFrom;
- Bitmask mAll = 0;
- for(k=0; k<i; k++){
- int iIdxCur;
- mAll |= pWInfo->a[k].pWLoop->maskSelf;
- sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur);
- iIdxCur = pWInfo->a[k].iIdxCur;
- if( iIdxCur ){
- sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur);
- }
- }
- mAll |= pLoop->maskSelf;
- for(k=0; k<pWC->nTerm; k++){
- WhereTerm *pTerm = &pWC->a[k];
- if( pTerm->wtFlags & TERM_VIRTUAL ) break;
- if( pTerm->prereqAll & ~mAll ) continue;
- if( ExprHasProperty(pTerm->pExpr, EP_FromJoin|EP_InnerJoin) ) continue;
- pSubWhere = sqlite3ExprAnd(pParse, pSubWhere,
- sqlite3ExprDup(db, pTerm->pExpr, 0));
- }
- sFrom.nSrc = 1;
- sFrom.nAlloc = 1;
- memcpy(&sFrom.a[0], pTabItem, sizeof(SrcItem));
- sFrom.a[0].fg.jointype = 0;
- ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTab->zName));
- pSubWInfo = sqlite3WhereBegin(pParse, &sFrom, pSubWhere, 0, 0, 0,
- WHERE_RIGHT_JOIN, 0);
- if( pSubWInfo ){
- int iCur = pLevel->iTabCur;
- int r = ++pParse->nMem;
- int nPk;
- int jmp;
- int addrCont = sqlite3WhereContinueLabel(pSubWInfo);
- if( HasRowid(pTab) ){
- sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, r);
- nPk = 1;
- }else{
- int iPk;
- Index *pPk = sqlite3PrimaryKeyIndex(pTab);
- nPk = pPk->nKeyCol;
- pParse->nMem += nPk - 1;
- for(iPk=0; iPk<nPk; iPk++){
- int iCol = pPk->aiColumn[iPk];
- sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+iPk);
- }
- }
- jmp = sqlite3VdbeAddOp4Int(v, OP_Filter, pRJ->regBloom, 0, r, nPk);
- sqlite3VdbeAddOp4Int(v, OP_Found, pRJ->iMatch, addrCont, r, nPk);
- sqlite3VdbeJumpHere(v, jmp);
- sqlite3VdbeAddOp2(v, OP_Gosub, pRJ->regReturn, pRJ->addrSubrtn);
- sqlite3WhereEnd(pSubWInfo);
- }
- sqlite3ExprDelete(pParse->db, pSubWhere);
- ExplainQueryPlanPop(pParse);
+ sqlite3WhereRightJoinLoop(pWInfo, i, pLevel);
continue;
}
WhereLevel *pLevel, /* The current level pointer */
Bitmask notReady /* Which tables are currently available */
);
+SQLITE_NOINLINE void sqlite3WhereRightJoinLoop(
+ WhereInfo *pWInfo,
+ int iLevel,
+ WhereLevel *pLevel
+);
/* whereexpr.c: */
void sqlite3WhereClauseInit(WhereClause*,WhereInfo*);
#endif
return pLevel->notReady;
}
+
+/*
+** Generate the code for the loop that finds all non-matched terms
+** for a RIGHT JOIN.
+*/
+SQLITE_NOINLINE void sqlite3WhereRightJoinLoop(
+ WhereInfo *pWInfo,
+ int iLevel,
+ WhereLevel *pLevel
+){
+ Parse *pParse = pWInfo->pParse;
+ Vdbe *v = pParse->pVdbe;
+ WhereRightJoin *pRJ = pLevel->pRJ;
+ Expr *pSubWhere = 0;
+ WhereClause *pWC = &pWInfo->sWC;
+ WhereInfo *pSubWInfo;
+ WhereLoop *pLoop = pLevel->pWLoop;
+ SrcItem *pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
+ SrcList sFrom;
+ Bitmask mAll = 0;
+ int k;
+
+ for(k=0; k<iLevel; k++){
+ int iIdxCur;
+ mAll |= pWInfo->a[k].pWLoop->maskSelf;
+ sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur);
+ iIdxCur = pWInfo->a[k].iIdxCur;
+ if( iIdxCur ){
+ sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur);
+ }
+ }
+ mAll |= pLoop->maskSelf;
+ for(k=0; k<pWC->nTerm; k++){
+ WhereTerm *pTerm = &pWC->a[k];
+ if( pTerm->wtFlags & TERM_VIRTUAL ) break;
+ if( pTerm->prereqAll & ~mAll ) continue;
+ if( ExprHasProperty(pTerm->pExpr, EP_FromJoin|EP_InnerJoin) ) continue;
+ pSubWhere = sqlite3ExprAnd(pParse, pSubWhere,
+ sqlite3ExprDup(pParse->db, pTerm->pExpr, 0));
+ }
+ sFrom.nSrc = 1;
+ sFrom.nAlloc = 1;
+ memcpy(&sFrom.a[0], pTabItem, sizeof(SrcItem));
+ sFrom.a[0].fg.jointype = 0;
+ ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pTab->zName));
+ pSubWInfo = sqlite3WhereBegin(pParse, &sFrom, pSubWhere, 0, 0, 0,
+ WHERE_RIGHT_JOIN, 0);
+ if( pSubWInfo ){
+ int iCur = pLevel->iTabCur;
+ int r = ++pParse->nMem;
+ int nPk;
+ int jmp;
+ int addrCont = sqlite3WhereContinueLabel(pSubWInfo);
+ Table *pTab = pTabItem->pTab;
+ if( HasRowid(pTab) ){
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, r);
+ nPk = 1;
+ }else{
+ int iPk;
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+ nPk = pPk->nKeyCol;
+ pParse->nMem += nPk - 1;
+ for(iPk=0; iPk<nPk; iPk++){
+ int iCol = pPk->aiColumn[iPk];
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+iPk);
+ }
+ }
+ jmp = sqlite3VdbeAddOp4Int(v, OP_Filter, pRJ->regBloom, 0, r, nPk);
+ sqlite3VdbeAddOp4Int(v, OP_Found, pRJ->iMatch, addrCont, r, nPk);
+ sqlite3VdbeJumpHere(v, jmp);
+ sqlite3VdbeAddOp2(v, OP_Gosub, pRJ->regReturn, pRJ->addrSubrtn);
+ sqlite3WhereEnd(pSubWInfo);
+ }
+ sqlite3ExprDelete(pParse->db, pSubWhere);
+ ExplainQueryPlanPop(pParse);
+}