mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Improvements to the EQP display for compound select statements.
FossilOrigin-Name: 699a77e479010a331b0423f157a2fbfc373688e3d0d04ae5e64376c00cb3d488
This commit is contained in:
15
manifest
15
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Begin\sreengineering\sthe\sEXPLAIN\sQUERY\sPLAN\sfunction\sto\sprovide\smore\nintuitive\soutput.
|
C Improvements\sto\sthe\sEQP\sdisplay\sfor\scompound\sselect\sstatements.
|
||||||
D 2018-05-02T00:33:43.157
|
D 2018-05-02T02:22:22.993
|
||||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||||
F Makefile.in 5ce9343cba9c189046f1afe6d2bcc1f68079439febc05267b98aec6ecc752439
|
F Makefile.in 5ce9343cba9c189046f1afe6d2bcc1f68079439febc05267b98aec6ecc752439
|
||||||
@@ -493,7 +493,7 @@ F src/printf.c d3b7844ddeb11fbbdd38dd84d09c9c1ac171d21fb038473c3aa97981201cc660
|
|||||||
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
||||||
F src/resolve.c 6415381a0e9d22c0e7cba33ca4a53f81474190862f5d4838190f5eb5b0b47bc9
|
F src/resolve.c 6415381a0e9d22c0e7cba33ca4a53f81474190862f5d4838190f5eb5b0b47bc9
|
||||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||||
F src/select.c 8481fa6ec8bb3b24465da8e81438d4d85056d69232f501c153ab8402409c8619
|
F src/select.c 41962df2f21593db4eb5e0d7d8f15848b9ebd3ffed9b7584677033a8db37223b
|
||||||
F src/shell.c.in 29309f2ab656c8817fbc3b7910b9af8464557b91cba75277a03669399c8e2730
|
F src/shell.c.in 29309f2ab656c8817fbc3b7910b9af8464557b91cba75277a03669399c8e2730
|
||||||
F src/sqlite.h.in d669de545f18f2f01362de02e309cd7f15185958c71bac8f53cd5438b46d2bea
|
F src/sqlite.h.in d669de545f18f2f01362de02e309cd7f15185958c71bac8f53cd5438b46d2bea
|
||||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||||
@@ -1727,10 +1727,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P 853f3163597b9946c0cbeb808ea6fd33a0cf48ae6b8f4459c4165db377f33a9e
|
P 70b48a7972dfbb44af3ccd8ccd830e984bec88d80a78b3566a5de86a16e7fc14
|
||||||
R 4157eb92d30294276c327d965c794c5a
|
R 21b35e2f4fb3267c4b0452fc48ac12e8
|
||||||
T *branch * rework-EQP
|
|
||||||
T *sym-rework-EQP *
|
|
||||||
T -sym-trunk *
|
|
||||||
U drh
|
U drh
|
||||||
Z 60e64f1bce0fa6f0f61a0e5e536f0823
|
Z 26b206c16e8cc64ca80991a86c32cf32
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
70b48a7972dfbb44af3ccd8ccd830e984bec88d80a78b3566a5de86a16e7fc14
|
699a77e479010a331b0423f157a2fbfc373688e3d0d04ae5e64376c00cb3d488
|
||||||
64
src/select.c
64
src/select.c
@@ -1314,33 +1314,6 @@ static void explainTempTable(Parse *pParse, const char *zUsage){
|
|||||||
# define explainSetInteger(y,z)
|
# define explainSetInteger(y,z)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(SQLITE_OMIT_EXPLAIN) && !defined(SQLITE_OMIT_COMPOUND_SELECT)
|
|
||||||
/*
|
|
||||||
** Unless an "EXPLAIN QUERY PLAN" command is being processed, this function
|
|
||||||
** is a no-op. Otherwise, it adds a single row of output to the EQP result,
|
|
||||||
** where the caption is of one of the two forms:
|
|
||||||
**
|
|
||||||
** "COMPOSITE (op)"
|
|
||||||
** "COMPOSITE USING TEMP B-TREE (op)"
|
|
||||||
**
|
|
||||||
** where op is the text representation of the parameter
|
|
||||||
** of the same name. The parameter "op" must be one of TK_UNION, TK_EXCEPT,
|
|
||||||
** TK_INTERSECT or TK_ALL. The first form is used if argument bUseTmp is
|
|
||||||
** false, or the second form if it is true.
|
|
||||||
*/
|
|
||||||
static void explainComposite(
|
|
||||||
Parse *pParse, /* Parse context */
|
|
||||||
int op, /* One of TK_UNION, TK_EXCEPT etc. */
|
|
||||||
int bUseTmp /* True if a temp table was used */
|
|
||||||
){
|
|
||||||
assert( op==TK_UNION || op==TK_EXCEPT || op==TK_INTERSECT || op==TK_ALL );
|
|
||||||
ExplainQueryPlan((pParse, 1, "COMPOUND %s(%s)",
|
|
||||||
bUseTmp?"USING TEMP B-TREE ":"", selectOpName(op)));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
/* No-op versions of the explainXXX() functions and macros. */
|
|
||||||
# define explainComposite(v,y,z)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** If the inner loop was generated using a non-null pOrderBy argument,
|
** If the inner loop was generated using a non-null pOrderBy argument,
|
||||||
@@ -2516,9 +2489,16 @@ static int multiSelect(
|
|||||||
return multiSelectOrderBy(pParse, p, pDest);
|
return multiSelectOrderBy(pParse, p, pDest);
|
||||||
}else
|
}else
|
||||||
|
|
||||||
|
#ifndef SQLITE_OMIT_EXPLAIN
|
||||||
|
if( pPrior->pPrior==0 ){
|
||||||
|
ExplainQueryPlan((pParse, 1, "COMPOUND QUERY"));
|
||||||
|
ExplainQueryPlan((pParse, 1, "LEFT-MOST SUBQUERY"));
|
||||||
|
ExplainQueryPlanSetId(pParse, pPrior);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Generate code for the left and right SELECT statements.
|
/* Generate code for the left and right SELECT statements.
|
||||||
*/
|
*/
|
||||||
explainComposite(pParse, p->op, p->op!=TK_ALL);
|
|
||||||
switch( p->op ){
|
switch( p->op ){
|
||||||
case TK_ALL: {
|
case TK_ALL: {
|
||||||
int addr = 0;
|
int addr = 0;
|
||||||
@@ -2543,6 +2523,8 @@ static int multiSelect(
|
|||||||
p->iLimit, p->iOffset+1, p->iOffset);
|
p->iLimit, p->iOffset+1, p->iOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ExplainQueryPlan((pParse, 1, "UNION ALL"));
|
||||||
|
ExplainQueryPlanSetId(pParse, p);
|
||||||
rc = sqlite3Select(pParse, p, &dest);
|
rc = sqlite3Select(pParse, p, &dest);
|
||||||
testcase( rc!=SQLITE_OK );
|
testcase( rc!=SQLITE_OK );
|
||||||
pDelete = p->pPrior;
|
pDelete = p->pPrior;
|
||||||
@@ -2611,6 +2593,9 @@ static int multiSelect(
|
|||||||
pLimit = p->pLimit;
|
pLimit = p->pLimit;
|
||||||
p->pLimit = 0;
|
p->pLimit = 0;
|
||||||
uniondest.eDest = op;
|
uniondest.eDest = op;
|
||||||
|
ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
|
||||||
|
selectOpName(p->op)));
|
||||||
|
ExplainQueryPlanSetId(pParse, p);
|
||||||
rc = sqlite3Select(pParse, p, &uniondest);
|
rc = sqlite3Select(pParse, p, &uniondest);
|
||||||
testcase( rc!=SQLITE_OK );
|
testcase( rc!=SQLITE_OK );
|
||||||
/* Query flattening in sqlite3Select() might refill p->pOrderBy.
|
/* Query flattening in sqlite3Select() might refill p->pOrderBy.
|
||||||
@@ -2687,6 +2672,9 @@ static int multiSelect(
|
|||||||
pLimit = p->pLimit;
|
pLimit = p->pLimit;
|
||||||
p->pLimit = 0;
|
p->pLimit = 0;
|
||||||
intersectdest.iSDParm = tab2;
|
intersectdest.iSDParm = tab2;
|
||||||
|
ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
|
||||||
|
selectOpName(p->op)));
|
||||||
|
ExplainQueryPlanSetId(pParse, p);
|
||||||
rc = sqlite3Select(pParse, p, &intersectdest);
|
rc = sqlite3Select(pParse, p, &intersectdest);
|
||||||
testcase( rc!=SQLITE_OK );
|
testcase( rc!=SQLITE_OK );
|
||||||
pDelete = p->pPrior;
|
pDelete = p->pPrior;
|
||||||
@@ -2718,7 +2706,11 @@ static int multiSelect(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ExplainQueryPlanPop(pParse);
|
#ifndef SQLITE_OMIT_EXPLAIN
|
||||||
|
if( p->pNext==0 ){
|
||||||
|
ExplainQueryPlanPop(pParse);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Compute collating sequences used by
|
/* Compute collating sequences used by
|
||||||
** temporary tables needed to implement the compound select.
|
** temporary tables needed to implement the compound select.
|
||||||
@@ -3175,8 +3167,8 @@ static int multiSelectOrderBy(
|
|||||||
regOutB = ++pParse->nMem;
|
regOutB = ++pParse->nMem;
|
||||||
sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA);
|
sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA);
|
||||||
sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB);
|
sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB);
|
||||||
explainComposite(pParse, p->op, 0);
|
|
||||||
|
|
||||||
|
ExplainQueryPlan((pParse, 1, "MERGE (%s)", selectOpName(p->op)));
|
||||||
|
|
||||||
/* Generate a coroutine to evaluate the SELECT statement to the
|
/* Generate a coroutine to evaluate the SELECT statement to the
|
||||||
** left of the compound operator - the "A" select.
|
** left of the compound operator - the "A" select.
|
||||||
@@ -3185,6 +3177,8 @@ static int multiSelectOrderBy(
|
|||||||
addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA);
|
addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA);
|
||||||
VdbeComment((v, "left SELECT"));
|
VdbeComment((v, "left SELECT"));
|
||||||
pPrior->iLimit = regLimitA;
|
pPrior->iLimit = regLimitA;
|
||||||
|
ExplainQueryPlan((pParse, 1, "LEFT"));
|
||||||
|
ExplainQueryPlanSetId(pParse, pPrior);
|
||||||
sqlite3Select(pParse, pPrior, &destA);
|
sqlite3Select(pParse, pPrior, &destA);
|
||||||
sqlite3VdbeEndCoroutine(v, regAddrA);
|
sqlite3VdbeEndCoroutine(v, regAddrA);
|
||||||
sqlite3VdbeJumpHere(v, addr1);
|
sqlite3VdbeJumpHere(v, addr1);
|
||||||
@@ -3199,6 +3193,8 @@ static int multiSelectOrderBy(
|
|||||||
savedOffset = p->iOffset;
|
savedOffset = p->iOffset;
|
||||||
p->iLimit = regLimitB;
|
p->iLimit = regLimitB;
|
||||||
p->iOffset = 0;
|
p->iOffset = 0;
|
||||||
|
ExplainQueryPlan((pParse, 1, "RIGHT"));
|
||||||
|
ExplainQueryPlanSetId(pParse, p);
|
||||||
sqlite3Select(pParse, p, &destB);
|
sqlite3Select(pParse, p, &destB);
|
||||||
p->iLimit = savedLimit;
|
p->iLimit = savedLimit;
|
||||||
p->iOffset = savedOffset;
|
p->iOffset = savedOffset;
|
||||||
@@ -5322,12 +5318,6 @@ int sqlite3Select(
|
|||||||
}
|
}
|
||||||
if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
|
if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
|
||||||
memset(&sAggInfo, 0, sizeof(sAggInfo));
|
memset(&sAggInfo, 0, sizeof(sAggInfo));
|
||||||
#ifndef SQLITE_OMIT_EXPLAIN
|
|
||||||
if( p->iSelectId==0 && pParse->addrExplain ){
|
|
||||||
ExplainQueryPlan((pParse, 1, "SUBQUERY"));
|
|
||||||
p->iSelectId = pParse->addrExplain;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if SELECTTRACE_ENABLED
|
#if SELECTTRACE_ENABLED
|
||||||
SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain));
|
SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain));
|
||||||
if( sqlite3SelectTrace & 0x100 ){
|
if( sqlite3SelectTrace & 0x100 ){
|
||||||
@@ -5464,7 +5454,7 @@ int sqlite3Select(
|
|||||||
sqlite3TreeViewSelect(0, p, 0);
|
sqlite3TreeViewSelect(0, p, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
sqlite3VdbeExplainPop(pParse);
|
if( p->pNext==0 ) ExplainQueryPlanPop(pParse);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user