1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-11 01:42:22 +03:00

Generalize the LEFT JOIN strength reduction optimization so that it works for

RIGHT and FULL JOIN as well.  Rename it to the "OUTER JOIN strength reduction"
optimization.

FossilOrigin-Name: d747afda5683ca5feb92866a14ccc4c5127d3378ece5cad2c3da819f2477b457
This commit is contained in:
drh
2023-06-01 20:38:22 +00:00
parent 39a7a1a9be
commit 179c32cb57
7 changed files with 139 additions and 19 deletions

View File

@@ -7222,16 +7222,52 @@ int sqlite3Select(
** to a real table */
assert( pTab!=0 );
/* Convert LEFT JOIN into JOIN if there are terms of the right table
** of the LEFT JOIN used in the WHERE clause.
/* Try to simplify joins:
**
** LEFT JOIN -> JOIN
** RIGHT JOIN -> JOIN
** FULL JOIN -> RIGHT JOIN
**
** If terms of the i-th table are used in the WHERE clause in such a
** way that the i-th table cannot be the NULL row of a join, then
** perform the appropriate simplification. This is called
** "OUTER JOIN strength reduction" in the SQLite documentation.
*/
if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==JT_LEFT
if( (pItem->fg.jointype & (JT_LEFT|JT_LTORJ))!=0
&& sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor)
&& OptimizationEnabled(db, SQLITE_SimplifyJoin)
){
TREETRACE(0x1000,pParse,p,
("LEFT-JOIN simplifies to JOIN on term %d\n",i));
pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER);
if( pItem->fg.jointype & JT_LEFT ){
if( pItem->fg.jointype & JT_RIGHT ){
TREETRACE(0x1000,pParse,p,
("FULL-JOIN simplifies to RIGHT-JOIN on term %d\n",i));
pItem->fg.jointype &= ~JT_LEFT;
}else{
TREETRACE(0x1000,pParse,p,
("LEFT-JOIN simplifies to JOIN on term %d\n",i));
pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER);
}
}
if( pItem->fg.jointype & JT_LTORJ ){
for(j=i+1; j<pTabList->nSrc; j++){
SrcItem *pI2 = &pTabList->a[j];
if( pI2->fg.jointype & JT_RIGHT ){
if( pI2->fg.jointype & JT_LEFT ){
TREETRACE(0x1000,pParse,p,
("FULL-JOIN simplifies to LEFT-JOIN on term %d\n",j));
pI2->fg.jointype &= ~JT_RIGHT;
}else{
TREETRACE(0x1000,pParse,p,
("RIGHT-JOIN simplifies to JOIN on term %d\n",j));
pI2->fg.jointype &= ~(JT_RIGHT|JT_OUTER);
}
}
}
for(j=pTabList->nSrc-1; j>=i; j--){
pTabList->a[j].fg.jointype &= ~JT_LTORJ;
if( pTabList->a[j].fg.jointype & JT_RIGHT ) break;
}
}
assert( pItem->iCursor>=0 );
unsetJoinExpr(p->pWhere, pItem->iCursor,
pTabList->a[0].fg.jointype & JT_LTORJ);