diff options
author | drh <> | 2022-05-13 17:45:52 +0000 |
---|---|---|
committer | drh <> | 2022-05-13 17:45:52 +0000 |
commit | 767bc8de8e3859777eab42a32e034ef807759f8a (patch) | |
tree | e9b7cbfa5a396341711345b8f9edb4cc2bef5f81 /src/wherecode.c | |
parent | a6e8ee12e2bbb353ae4548e38083d1855f7b86aa (diff) | |
download | sqlite-767bc8de8e3859777eab42a32e034ef807759f8a.tar.gz sqlite-767bc8de8e3859777eab42a32e034ef807759f8a.zip |
Defer generating WHERE clause constraints for a RIGHT JOIN until after the
ON-clause processing for the RIGHT JOIN has done its own row elimination.
This fixes and incorrect output from some RIGHT JOINs that was identified
by [forum:/forumpost/41cc3851d864c5e6|forum post 41cc3851d864c5e6].
FossilOrigin-Name: 238d9c247cf69cc77fdb1af9d42ebe258610a533ac4204e2ddf8af17f24d18c4
Diffstat (limited to 'src/wherecode.c')
-rw-r--r-- | src/wherecode.c | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/src/wherecode.c b/src/wherecode.c index 2d7602ae3..e079b944e 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -2620,10 +2620,12 @@ Bitmask sqlite3WhereCodeOneLoopStart( } pE = pTerm->pExpr; assert( pE!=0 ); - if( (pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ)) + if( (pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT)) && (!ExprHasProperty(pE,EP_OuterON|EP_InnerON) || pE->w.iJoin!=pTabItem->iCursor) ){ + /* Defer processing WHERE clause constraints until after outer + ** join processing. tag-20220513a */ continue; } @@ -2764,18 +2766,8 @@ Bitmask sqlite3WhereCodeOneLoopStart( pLevel->addrFirst = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin); VdbeComment((v, "record LEFT JOIN hit")); - for(pTerm=pWC->a, j=0; j<pWC->nBase; j++, pTerm++){ - testcase( pTerm->wtFlags & TERM_VIRTUAL ); - testcase( pTerm->wtFlags & TERM_CODED ); - if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; - if( (pTerm->prereqAll & pLevel->notReady)!=0 ){ - assert( pWInfo->untestedTerms ); - continue; - } - if( pTabItem->fg.jointype & JT_LTORJ ) continue; - assert( pTerm->pExpr ); - sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); - pTerm->wtFlags |= TERM_CODED; + if( pLevel->pRJ==0 ){ + goto code_outer_join_constraints; /* WHERE clause constraints */ } } @@ -2791,6 +2783,26 @@ Bitmask sqlite3WhereCodeOneLoopStart( pRJ->addrSubrtn = sqlite3VdbeCurrentAddr(v); assert( pParse->withinRJSubrtn < 255 ); pParse->withinRJSubrtn++; + + /* WHERE clause constraints must be deferred until after outer join + ** row elimination has completed, since WHERE clause constraints apply + ** to the results of the OUTER JOIN. The following loop generates the + ** appropriate WHERE clause constraint checks. tag-20220513a. + */ + code_outer_join_constraints: + for(pTerm=pWC->a, j=0; j<pWC->nBase; j++, pTerm++){ + testcase( pTerm->wtFlags & TERM_VIRTUAL ); + testcase( pTerm->wtFlags & TERM_CODED ); + if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; + if( (pTerm->prereqAll & pLevel->notReady)!=0 ){ + assert( pWInfo->untestedTerms ); + continue; + } + if( pTabItem->fg.jointype & JT_LTORJ ) continue; + assert( pTerm->pExpr ); + sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); + pTerm->wtFlags |= TERM_CODED; + } } #if WHERETRACE_ENABLED /* 0x20800 */ |