aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <>2022-04-11 14:26:37 +0000
committerdrh <>2022-04-11 14:26:37 +0000
commitc583719b65d2fca51178d40826f3b325329fe12a (patch)
treea041e6390ad648c12e9458b147de2004a1dba929 /src
parent37259f4e6b5c4645aa732b0e2c7dada27c3f3259 (diff)
downloadsqlite-c583719b65d2fca51178d40826f3b325329fe12a.tar.gz
sqlite-c583719b65d2fca51178d40826f3b325329fe12a.zip
Show LEFT and RIGHT JOIN processing in the EXPLAIN QUERY PLAN output.
FossilOrigin-Name: d91faeffea5cf0585fb71e5311fdcc6b8be85c7e9c732050b4448e617c970101
Diffstat (limited to 'src')
-rw-r--r--src/sqliteInt.h2
-rw-r--r--src/where.c4
-rw-r--r--src/wherecode.c13
3 files changed, 12 insertions, 7 deletions
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index b9eb970c7..330d58fa4 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -3163,7 +3163,7 @@ struct SrcList {
#define WHERE_SORTBYGROUP 0x0200 /* Support sqlite3WhereIsSorted() */
#define WHERE_AGG_DISTINCT 0x0400 /* Query is "SELECT agg(DISTINCT ...)" */
#define WHERE_ORDERBY_LIMIT 0x0800 /* ORDERBY+LIMIT on the inner loop */
- /* 0x1000 not currently used */
+#define WHERE_RIGHT_JOIN 0x1000 /* Processing a RIGHT JOIN */
/* 0x2000 not currently used */
#define WHERE_USE_LIMIT 0x4000 /* Use the LIMIT in cost estimates */
/* 0x8000 not currently used */
diff --git a/src/where.c b/src/where.c
index 1cd8f4ded..3677759ce 100644
--- a/src/where.c
+++ b/src/where.c
@@ -6191,8 +6191,9 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
sFrom.nAlloc = 1;
memcpy(&sFrom.a[0], pTabItem, sizeof(SrcItem));
sFrom.a[0].fg.jointype = 0;
+ ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTab->zName));
pSubWInfo = sqlite3WhereBegin(pParse, &sFrom, pSubWhere, 0, 0, 0,
- WHERE_OR_SUBCLAUSE, 0);
+ WHERE_RIGHT_JOIN, 0);
if( pSubWInfo ){
int iCur = pLevel->iTabCur;
int r = ++pParse->nMem;
@@ -6219,6 +6220,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
sqlite3WhereEnd(pSubWInfo);
}
sqlite3ExprDelete(pParse->db, pSubWhere);
+ ExplainQueryPlanPop(pParse);
continue;
}
diff --git a/src/wherecode.c b/src/wherecode.c
index 0c8104867..410d6f206 100644
--- a/src/wherecode.c
+++ b/src/wherecode.c
@@ -204,6 +204,9 @@ int sqlite3WhereExplainOneScan(
pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
}
#endif
+ if( pItem->fg.jointype & JT_LEFT ){
+ sqlite3_str_appendf(&str, " LEFT-JOIN");
+ }
#ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS
if( pLoop->nOut>=10 ){
sqlite3_str_appendf(&str, " (~%llu rows)",
@@ -1150,7 +1153,7 @@ static void codeDeferredSeek(
pWInfo->bDeferredSeek = 1;
sqlite3VdbeAddOp3(v, OP_DeferredSeek, iIdxCur, 0, iCur);
- if( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)
+ if( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))
&& DbMaskAllZero(sqlite3ParseToplevel(pParse)->writeMask)
){
int i;
@@ -1502,7 +1505,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
** initialize a memory cell that records if this table matches any
** row of the left table of the join.
*/
- assert( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)
+ assert( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))
|| pLevel->iFrom>0 || (pTabItem[0].fg.jointype & JT_LEFT)==0
);
if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){
@@ -2140,7 +2143,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
/* Seek the table cursor, if required */
omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0
- && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0;
+ && (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))==0;
if( omitTable ){
/* pIdx is a covering index. No need to access the main table. */
}else if( HasRowid(pIdx->pTable) ){
@@ -2174,7 +2177,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
** move forward to the next index.
** https://sqlite.org/src/info/4e8e4857d32d401f
*/
- if( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){
+ if( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))==0 ){
whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo);
}
@@ -2193,7 +2196,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
/* The following assert() is not a requirement, merely an observation:
** The OR-optimization doesn't work for the right hand table of
** a LEFT JOIN: */
- assert( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 );
+ assert( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))==0 );
}
/* Record the instruction used to terminate the loop. */