1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-05 15:55:57 +03:00

Enhance the EXISTS-to-JOIN optimization so that it works on EXISTS subqueries

that do not have a WHERE clause, and so that it works on nested EXISTS
subqueries.

FossilOrigin-Name: c1d5295724f9cf7f49e0786d28016eff2d268a2b670f934d24c76787626089db
This commit is contained in:
drh
2025-07-05 23:33:21 +00:00
parent 45bc9b9f97
commit 8bc112e3e4
4 changed files with 24 additions and 16 deletions

View File

@@ -7418,11 +7418,17 @@ static int fromClauseTermCanBeCoroutine(
**
** SELECT name FROM sailors AS S, reserves AS R
** WHERE S.sid = R.sid AND R.day = '2022-10-25';
**
** **Approximately**. Really, we have to ensure that the FROM-clause term
** that was formerly inside the EXISTS is only executed once. This is handled
** by setting the SrcItem.fg.fromExists flag, which then causes code in
** the where.c file to exit the corresponding loop after the first successful
** match (if any).
*/
static SQLITE_NOINLINE void existsToJoin(
Parse *pParse,
Select *p,
Expr *pWhere
Parse *pParse, /* Parsing context */
Select *p, /* The SELECT statement being optimized */
Expr *pWhere /* part of the WHERE clause currently being examined */
){
if( pWhere
&& !ExprHasProperty(pWhere, EP_OuterON|EP_InnerON)
@@ -7437,9 +7443,9 @@ static SQLITE_NOINLINE void existsToJoin(
}
else if( pWhere->op==TK_EXISTS ){
Select *pSub = pWhere->x.pSelect;
Expr *pSubWhere = pSub->pWhere;
if( pSub->pSrc->nSrc==1
&& (pSub->selFlags & SF_Aggregate)==0
&& pSub->pWhere
&& !pSub->pSrc->a[0].fg.isSubquery
){
memset(pWhere, 0, sizeof(*pWhere));
@@ -7451,9 +7457,10 @@ static SQLITE_NOINLINE void existsToJoin(
pSub->pSrc->a[0].fg.fromExists = 1;
pSub->pSrc->a[0].fg.jointype |= JT_CROSS;
p->pSrc = sqlite3SrcListAppendList(pParse, p->pSrc, pSub->pSrc);
p->pWhere = sqlite3PExpr(pParse, TK_AND, p->pWhere, pSub->pWhere);
pSub->pWhere = 0;
if( pSubWhere ){
p->pWhere = sqlite3PExpr(pParse, TK_AND, p->pWhere, pSubWhere);
pSub->pWhere = 0;
}
pSub->pSrc = 0;
sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pSub);
#if TREETRACE_ENABLED
@@ -7463,6 +7470,7 @@ static SQLITE_NOINLINE void existsToJoin(
sqlite3TreeViewSelect(0, p, 0);
}
#endif
existsToJoin(pParse, p, pSubWhere);
}
}
}