]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Factor out the RIGHT JOIN non-matched row loop from sqlite3WhereEnd(). This
authordrh <>
Tue, 12 Apr 2022 18:04:29 +0000 (18:04 +0000)
committerdrh <>
Tue, 12 Apr 2022 18:04:29 +0000 (18:04 +0000)
reduces the register pressure on that routine and helps it to run faster
in the common case where there is no RIGHT JOIN.

FossilOrigin-Name: beeecf1604d4fb11e45058f48cb2289c6542e0bc218d63a245198113d8d5476b

manifest
manifest.uuid
src/where.c
src/whereInt.h
src/wherecode.c

index b250272df0ea134347af48af26637972e6066ae9..a4942b77dc6146d426b3ec23ed792e700a8ac4fd 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-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
@@ -639,9 +639,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
 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
@@ -1946,8 +1946,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 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.
index 6963963ddb23316e9dbc30849f8404b1720a3cab..4182150ca6a8d41b5fff0ccf33723633cb0a7741 100644 (file)
@@ -1 +1 @@
-b3e57ba120067c79e0398e39da9f00ecb11a5e18c36479da4c36a39e88a78a27
\ No newline at end of file
+beeecf1604d4fb11e45058f48cb2289c6542e0bc218d63a245198113d8d5476b
\ No newline at end of file
index 4c9ba86b122f01c7fa4513220b3c60799a3d75b1..836b7d6dc93c4785a8c7479c9e93b106591400fb 100644 (file)
@@ -6174,64 +6174,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
     ** 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;
     }
 
index 6be8234e270e87f42e9f9d62e4701bb7583bf9d6..c8a188f80c55efe251e571219a64dab14db00665 100644 (file)
@@ -565,6 +565,11 @@ Bitmask sqlite3WhereCodeOneLoopStart(
   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*);
index 410d6f206e0a617a1a1c136583785cff5d4e8038..d2cb85aee7fc941990bba20e77f30fff4e4684fb 100644 (file)
@@ -2786,3 +2786,79 @@ Bitmask sqlite3WhereCodeOneLoopStart(
 #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);
+}