]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Restore the LEFT JOIN strength reduction that was partially lost in
authordrh <>
Fri, 2 Jun 2023 18:05:54 +0000 (18:05 +0000)
committerdrh <>
Fri, 2 Jun 2023 18:05:54 +0000 (18:05 +0000)
[d747afda5683ca5f] when strength reduction was generalized to all OUTER JOINs.

FossilOrigin-Name: 2d962b84dd8ac2d0968f0283f8f082c1c2a7a1f99b59053b2ad8f58745396447

manifest
manifest.uuid
src/expr.c
src/select.c
src/sqliteInt.h

index ac3549b97fddcda71da38aa564eff07ba1f6d085..37f9e828e380a43ccd792fced6543c20960587d8 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Do\sthat\slast\sCLI\sfix\smore\ssimply,\susing\sestablished\smeans.
-D 2023-06-02T13:31:12.174
+C Restore\sthe\sLEFT\sJOIN\sstrength\sreduction\sthat\swas\spartially\slost\sin\n[d747afda5683ca5f]\swhen\sstrength\sreduction\swas\sgeneralized\sto\sall\sOUTER\sJOINs.
+D 2023-06-02T18:05:54.277
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -587,7 +587,7 @@ F src/date.c cb71f73d5df5303ec6630971b9c8b8c7df466fa3233dbdc643d613806e53e554
 F src/dbpage.c f3eea5f7ec47e09ee7da40f42b25092ecbe961fc59566b8e5f705f34335b2387
 F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef
 F src/delete.c 05e27e3a55dcfeadf2f7ca95a5c5e0928f182c04640ec1954ffa42f3d5c19341
-F src/expr.c 93a8292352d7f6f0f10fbf601342b8a481bc79edb2686b60e0f3e9344f07f4b5
+F src/expr.c 099cf96cf72f1b8cebf0d91a8f75e111454cd011deed9c6dadcd0241c2abdca8
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
 F src/fkey.c 03c134cc8bffe54835f742ddea0b72ebfc8f6b32773d175c71b8afeea6cb5c83
 F src/func.c 03e6b501f3056d0ba398bda17df938b2b566aa0b3ca7e1942a3cd1925d04ec36
@@ -637,12 +637,12 @@ F src/printf.c b9320cdbeca0b336c3f139fd36dd121e4167dd62b35fbe9ccaa9bab44c0af38d
 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
 F src/resolve.c 3e53e02ce87c9582bd7e7d22f13f4094a271678d9dc72820fa257a2abb5e4032
 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
-F src/select.c 0f9b9bfd0ea01aeb15ed5e92a99a28465d3421e0686ce08a2bfad1c61f7ec357
+F src/select.c a42b88d8bb9e824f45ccea16e7dfc5a812a32e2b8a0c5727b893734a14d83ade
 F src/shell.c.in 6915835eee0775c02ea1fb474da19f07ed76acbfc92444aef09e16b963abb46f
 F src/sqlite.h.in 03515ff55fafc0ba9ec75adbee250905cb59275f1714f0b6562e0bd466776334
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h da473ce2b3d0ae407a6300c4a164589b9a6bfdbec9462688a8593ff16f3bb6e4
-F src/sqliteInt.h a3ced8b9ebc573189c87b69f24bf10d2b9cd3cefefaae52623a2fa79e6fdd408
+F src/sqliteInt.h a531b7f352a0db457b5e0c56f41a3905273252ec8646526f8f897f0815519182
 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
 F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749
 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@@ -2072,8 +2072,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 cd24178bbaad4a1dafc3848e7d74240f90030160b5c43c93e1e0e11b073c2df5
-R 82919da296f71693b73364c8679802ba
-U larrybr
-Z dcbd07d0b87a8855abf3514a8f1d56da
+P a1823b297616bc2bd64eda9df4850fb460d8da8959ae3728195db896d1f89e7b
+R a573527528f24d1895ad95759b6c42d0
+U drh
+Z 2b72f92c0c9e7979e6a3e950cbc9cc6f
 # Remove this line to create a well-formed Fossil manifest.
index fe7a61f7b77617080816aae61b26f290373e5dcc..646c4680806cb0586b0aab7405396d5ad3169ea6 100644 (file)
@@ -1 +1 @@
-a1823b297616bc2bd64eda9df4850fb460d8da8959ae3728195db896d1f89e7b
\ No newline at end of file
+2d962b84dd8ac2d0968f0283f8f082c1c2a7a1f99b59053b2ad8f58745396447
\ No newline at end of file
index 92e96b0f12379926d4c9d3facf4491226f1bd30a..f5d922f5664da797850545ee18c9ea7057618e65 100644 (file)
@@ -4131,7 +4131,7 @@ static int exprCodeInlineFunction(
       pA1 = pFarg->a[1].pExpr;
       if( pA1->op==TK_COLUMN ){
         sqlite3VdbeAddOp2(v, OP_Integer, 
-           sqlite3ExprImpliesNonNullRow(pFarg->a[0].pExpr,pA1->iTable),
+           sqlite3ExprImpliesNonNullRow(pFarg->a[0].pExpr,pA1->iTable,1),
            target);
       }else{
         sqlite3VdbeAddOp2(v, OP_Null, 0, target);
@@ -6010,6 +6010,10 @@ static void bothImplyNotNullRow(Walker *pWalker, Expr *pE1, Expr *pE2){
 ** If the expression node requires that the table at pWalker->iCur
 ** have one or more non-NULL column, then set pWalker->eCode to 1 and abort.
 **
+** pWalker->mWFlags is non-zero if this inquiry is being undertaking on
+** behalf of a RIGHT JOIN (or FULL JOIN).  That makes a difference when
+** evaluting terms in the ON claue of an inner join.
+**
 ** This routine controls an optimization.  False positives (setting
 ** pWalker->eCode to 1 when it should not be) are deadly, but false-negatives
 ** (never setting pWalker->eCode) is a harmless missed optimization.
@@ -6017,7 +6021,15 @@ static void bothImplyNotNullRow(Walker *pWalker, Expr *pE1, Expr *pE2){
 static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
   testcase( pExpr->op==TK_AGG_COLUMN );
   testcase( pExpr->op==TK_AGG_FUNCTION );
-  if( ExprHasProperty(pExpr, EP_OuterON|EP_InnerON) ) return WRC_Prune;
+  if( ExprHasProperty(pExpr, EP_OuterON) ) return WRC_Prune;
+  if( ExprHasProperty(pExpr, EP_InnerON) && pWalker->mWFlags ){
+    /* If iCur is used in an inner-join ON clause to the left of a
+    ** RIGHT JOIN, that does *not* mean that the table must be non-null.
+    ** But it is difficult to check for that condition precisely.
+    ** To keep things simple, any use of iCur from any inner-join is
+    ** ignored while attempting to simplify a RIGHT JOIN. */
+    return WRC_Prune;
+  }
   switch( pExpr->op ){
     case TK_ISNOT:
     case TK_ISNULL:
@@ -6137,7 +6149,7 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
 ** be non-NULL, then the LEFT JOIN can be safely converted into an
 ** ordinary join.
 */
-int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){
+int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab, int isRJ){
   Walker w;
   p = sqlite3ExprSkipCollateAndLikely(p);
   if( p==0 ) return 0;
@@ -6145,7 +6157,7 @@ int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){
     p = p->pLeft;
   }else{
     while( p->op==TK_AND ){
-      if( sqlite3ExprImpliesNonNullRow(p->pLeft, iTab) ) return 1;
+      if( sqlite3ExprImpliesNonNullRow(p->pLeft, iTab, isRJ) ) return 1;
       p = p->pRight;
     }
   }
@@ -6153,6 +6165,7 @@ int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){
   w.xSelectCallback = 0;
   w.xSelectCallback2 = 0;
   w.eCode = 0;
+  w.mWFlags = isRJ!=0;
   w.u.iCur = iTab;
   sqlite3WalkExpr(&w, p);
   return w.eCode;
index 0058955d1603b27b4721a7e1397f71c631560449..4e787036583a5844c571057fa0a18d24baf9dbb8 100644 (file)
@@ -7234,7 +7234,8 @@ int sqlite3Select(
     ** "OUTER JOIN strength reduction" in the SQLite documentation.
     */
     if( (pItem->fg.jointype & (JT_LEFT|JT_LTORJ))!=0
-     && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor)
+     && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor,
+                                     pItem->fg.jointype & JT_LTORJ)
      && OptimizationEnabled(db, SQLITE_SimplifyJoin)
     ){
       if( pItem->fg.jointype & JT_LEFT ){
index 2c893770b04e06932b9c4405ff9b41a13aff68d0..1be14a5c9ae85624d9c7389df40f6cb62629d898 100644 (file)
@@ -4169,6 +4169,7 @@ struct Walker {
   void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */
   int walkerDepth;                          /* Number of subqueries */
   u16 eCode;                                /* A small processing code */
+  u16 mWFlags;                              /* Use-dependent flags */
   union {                                   /* Extra data for callback */
     NameContext *pNC;                         /* Naming context */
     int n;                                    /* A counter */
@@ -4879,7 +4880,7 @@ int sqlite3ExprCompare(const Parse*,const Expr*,const Expr*, int);
 int sqlite3ExprCompareSkip(Expr*,Expr*,int);
 int sqlite3ExprListCompare(const ExprList*,const ExprList*, int);
 int sqlite3ExprImpliesExpr(const Parse*,const Expr*,const Expr*, int);
-int sqlite3ExprImpliesNonNullRow(Expr*,int);
+int sqlite3ExprImpliesNonNullRow(Expr*,int,int);
 void sqlite3AggInfoPersistWalkerInit(Walker*,Parse*);
 void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
 void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);