diff options
author | drh <> | 2022-04-11 14:26:37 +0000 |
---|---|---|
committer | drh <> | 2022-04-11 14:26:37 +0000 |
commit | c583719b65d2fca51178d40826f3b325329fe12a (patch) | |
tree | a041e6390ad648c12e9458b147de2004a1dba929 /src | |
parent | 37259f4e6b5c4645aa732b0e2c7dada27c3f3259 (diff) | |
download | sqlite-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.h | 2 | ||||
-rw-r--r-- | src/where.c | 4 | ||||
-rw-r--r-- | src/wherecode.c | 13 |
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. */ |