aboutsummaryrefslogtreecommitdiff
path: root/src/select.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/select.c')
-rw-r--r--src/select.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/src/select.c b/src/select.c
index 750de5e8f..b15300237 100644
--- a/src/select.c
+++ b/src/select.c
@@ -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);
}
}
}