From: drh Date: Sat, 10 Sep 2005 16:46:12 +0000 (+0000) Subject: Add the experimental EXPLAIN QUERY PLAN diagnostic capability. (CVS 2685) X-Git-Tag: version-3.6.10~3474 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ecc9242f6f2b7703f2f45b854b5553f8eba6a0c6;p=thirdparty%2Fsqlite.git Add the experimental EXPLAIN QUERY PLAN diagnostic capability. (CVS 2685) FossilOrigin-Name: 986efb7b12643800805ad4b1f1e90e30fcf6d38a --- diff --git a/manifest b/manifest index 22502d5733..99d853d8d5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sa\smemory\sleak\sand/or\sassertion\sfailure\swhen\sparsing\sa\stable\r\ndeclaration\sthat\scontains\sa\sduplicate\scolumn\sname.\r\nTicket\s#1418.\s(CVS\s2684) -D 2005-09-10T15:35:07 +C Add\sthe\sexperimental\sEXPLAIN\sQUERY\sPLAN\sdiagnostic\scapability.\s(CVS\s2685) +D 2005-09-10T16:46:13 F Makefile.in 12784cdce5ffc8dfb707300c34e4f1eb3b8a14f1 F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -58,9 +58,9 @@ F src/os_win.c ed03a35b2894f9b99840415f941a9f8594dea756 F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b F src/pager.c 2b48db1cc6073a6d2577100866db6ae039d20940 F src/pager.h 17b13225abd93c1e9f470060f40a21b9edb5a164 -F src/parse.y 13c3d16e999184cb5fba39e44f133cdf01288e3e +F src/parse.y c97d885c344579c55257e0bbaeaa1daa1659ef2d F src/pragma.c 69413fbdc0c6aaa493a776ea52c1b3e6cf35dfb2 -F src/prepare.c 86f0d8e744b8d956eff6bc40e29049efee017610 +F src/prepare.c fc098db25d2a121affb08686cf04833fd50452d4 F src/printf.c c01e9ad473d79463fb1f483b1eca5c3cbed2a4e5 F src/random.c 90adff4e73a3b249eb4f1fc2a6ff9cf78c7233a4 F src/select.c a255ca7eddd14c68d966b6323234dd94fcc7a31f @@ -80,14 +80,14 @@ F src/update.c c2716c2115533ffae3d08bf8853aaba4f970f37e F src/utf.c bda5eb85039ef16f2d17004c1e18c96e1ab0a80c F src/util.c 5650f6fe5ee30e0678985ad7b94da91e3f85752b F src/vacuum.c 829d9e1a6d7c094b80e0899686670932eafd768c -F src/vdbe.c f722fbaf81890c342a1e1bf5a8a1600c5212ba47 +F src/vdbe.c 7b20b81b2643c0cc616c3fec6435f13c6e5fa6db F src/vdbe.h c8e105979fc7aaf5b8004e9621904e3bd096dfa2 F src/vdbeInt.h 3dd2a29c7b0a55404c35f93caae81fb42f4cb70a F src/vdbeapi.c 72213ce0c1ab8b215b2ae0ed342511bf769c1e60 -F src/vdbeaux.c a0aaf135c39825027366b5129f85191226d8b333 +F src/vdbeaux.c 670264f8b8ddbc4277adf85ab945a59a3aaef871 F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5 F src/vdbemem.c fea0744936008831daa17cdc75056c3ca1469690 -F src/where.c d032cca1b983ad14fb0361f1f7a2706c5e7a9720 +F src/where.c 715e317eb37b89961ad7c5515a18f1e2eb1c7fd8 F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42 F test/all.test 7f0988442ab811dfa41793b5b550f5828ce316f3 F test/alter.test 9d6837a3d946b73df692b7cef2a7644d2e2f6bc6 @@ -243,7 +243,7 @@ F tool/lempar.c f0c30abcae762a7d1eb37cd88b2232ab8dd625fb F tool/memleak.awk 4e7690a51bf3ed757e611273d43fe3f65b510133 F tool/memleak2.awk 9cc20c8e8f3c675efac71ea0721ee6874a1566e8 F tool/memleak3.tcl 009da0ea82dc5893edca76cf1a21fb7260e9412e -F tool/mkkeywordhash.c e0b7833fef924e3c75d5e5c28fdcdb879909bdfb +F tool/mkkeywordhash.c 5263a654e5c9fd8d6e3238fb39c2d5c3126be32f F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c F tool/report1.txt 9eae07f26a8fc53889b45fc833a66a33daa22816 @@ -306,7 +306,7 @@ F www/tclsqlite.tcl 3df553505b6efcad08f91e9b975deb2e6c9bb955 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 -P 415b8b24629aa12756d8285c094b5f85d8a8e532 -R 235cc9d948e051600520eade7dbee36c +P f43427742b1c086f2621c900f4ede1a34a8b44ee +R ab598fe85832474fa8020d661437e050 U drh -Z be7b5a2752d3ffcf1cf1e2330b39e495 +Z 6732d617323055d4bde842448e4c98ca diff --git a/manifest.uuid b/manifest.uuid index ae88ac8ec8..fe81e8b687 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f43427742b1c086f2621c900f4ede1a34a8b44ee \ No newline at end of file +986efb7b12643800805ad4b1f1e90e30fcf6d38a \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 20c2ef84e2..e0e4199f44 100644 --- a/src/parse.y +++ b/src/parse.y @@ -14,7 +14,7 @@ ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** -** @(#) $Id: parse.y,v 1.177 2005/09/09 01:33:19 drh Exp $ +** @(#) $Id: parse.y,v 1.178 2005/09/10 16:46:13 drh Exp $ */ // All token codes are small integers with #defines that begin with "TK_" @@ -104,7 +104,8 @@ ecmd ::= SEMI. ecmd ::= explain cmdx SEMI. explain ::= . { sqlite3BeginParse(pParse, 0); } %ifndef SQLITE_OMIT_EXPLAIN -explain ::= EXPLAIN. { sqlite3BeginParse(pParse, 1); } +explain ::= EXPLAIN. { sqlite3BeginParse(pParse, 1); } +explain ::= EXPLAIN QUERY PLAN. { sqlite3BeginParse(pParse, 2); } %endif ///////////////////// Begin and end transactions. //////////////////////////// @@ -172,7 +173,7 @@ id(A) ::= ID(X). {A = X;} %fallback ID ABORT AFTER ANALYZE ASC ATTACH BEFORE BEGIN CASCADE CAST CONFLICT DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR - IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH KEY + IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH PLAN QUERY KEY OF OFFSET PRAGMA RAISE REPLACE RESTRICT ROW STATEMENT TEMP TRIGGER VACUUM VIEW %ifdef SQLITE_OMIT_COMPOUND_SELECT diff --git a/src/prepare.c b/src/prepare.c index 50d03e8356..b3222a82f7 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -13,7 +13,7 @@ ** interface, and routines that contribute to loading the database schema ** from disk. ** -** $Id: prepare.c,v 1.3 2005/08/19 00:14:42 drh Exp $ +** $Id: prepare.c,v 1.4 2005/09/10 16:46:13 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -458,12 +458,19 @@ int sqlite3_prepare( #ifndef SQLITE_OMIT_EXPLAIN if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){ - sqlite3VdbeSetNumCols(sParse.pVdbe, 5); - sqlite3VdbeSetColName(sParse.pVdbe, 0, "addr", P3_STATIC); - sqlite3VdbeSetColName(sParse.pVdbe, 1, "opcode", P3_STATIC); - sqlite3VdbeSetColName(sParse.pVdbe, 2, "p1", P3_STATIC); - sqlite3VdbeSetColName(sParse.pVdbe, 3, "p2", P3_STATIC); - sqlite3VdbeSetColName(sParse.pVdbe, 4, "p3", P3_STATIC); + if( sParse.explain==2 ){ + sqlite3VdbeSetNumCols(sParse.pVdbe, 3); + sqlite3VdbeSetColName(sParse.pVdbe, 0, "order", P3_STATIC); + sqlite3VdbeSetColName(sParse.pVdbe, 1, "from", P3_STATIC); + sqlite3VdbeSetColName(sParse.pVdbe, 2, "detail", P3_STATIC); + }else{ + sqlite3VdbeSetNumCols(sParse.pVdbe, 5); + sqlite3VdbeSetColName(sParse.pVdbe, 0, "addr", P3_STATIC); + sqlite3VdbeSetColName(sParse.pVdbe, 1, "opcode", P3_STATIC); + sqlite3VdbeSetColName(sParse.pVdbe, 2, "p1", P3_STATIC); + sqlite3VdbeSetColName(sParse.pVdbe, 3, "p2", P3_STATIC); + sqlite3VdbeSetColName(sParse.pVdbe, 4, "p3", P3_STATIC); + } } #endif diff --git a/src/vdbe.c b/src/vdbe.c index c327598781..7b573bb0fe 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -43,7 +43,7 @@ ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.485 2005/09/08 14:17:20 drh Exp $ +** $Id: vdbe.c,v 1.486 2005/09/10 16:46:13 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -1645,6 +1645,13 @@ case OP_BitNot: { /* same as TK_BITNOT, no-push */ ** Do nothing. This instruction is often useful as a jump ** destination. */ +/* +** The magic Explain opcode are only inserted when explain==2 (which +** is to say when the EXPLAIN QUERY PLAN syntax is used.) +** This opcode records information from the optimizer. It is the +** the same as a no-op. This opcodesnever appears in a real VM program. +*/ +case OP_Explain: case OP_Noop: { /* no-push */ break; } diff --git a/src/vdbeaux.c b/src/vdbeaux.c index c1ccd83596..1096077050 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -577,8 +577,9 @@ int sqlite3VdbeList( } p->resOnStack = 0; - - i = p->pc++; + do{ + i = p->pc++; + }while( inOp && p->explain==2 && p->aOp[i].opcode!=OP_Explain ); if( i>=p->nOp ){ p->rc = SQLITE_OK; rc = SQLITE_DONE; @@ -617,7 +618,7 @@ int sqlite3VdbeList( pMem->type = SQLITE_TEXT; pMem->enc = SQLITE_UTF8; - p->nResColumn = 5; + p->nResColumn = 5 - 2*(p->explain-1); p->pTos = pMem; p->rc = SQLITE_OK; p->resOnStack = 1; diff --git a/src/where.c b/src/where.c index 50ef5d6d9f..1cb479c9ba 100644 --- a/src/where.c +++ b/src/where.c @@ -16,7 +16,7 @@ ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** -** $Id: where.c,v 1.170 2005/09/10 15:28:09 drh Exp $ +** $Id: where.c,v 1.171 2005/09/10 16:46:13 drh Exp $ */ #include "sqliteInt.h" @@ -1499,6 +1499,20 @@ WhereInfo *sqlite3WhereBegin( Index *pIx; int iIdxCur = pLevel->iIdxCur; +#ifndef SQLITE_OMIT_EXPLAIN + if( pParse->explain==2 ){ + char *zMsg; + struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom]; + zMsg = sqlite3MPrintf("TABLE %s", pItem->zName); + if( pItem->zAlias ){ + zMsg = sqlite3MPrintf("%z AS %s", zMsg, pItem->zAlias); + } + if( (pIx = pLevel->pIdx)!=0 ){ + zMsg = sqlite3MPrintf("%z WITH INDEX %s", zMsg, pIx->zName); + } + sqlite3VdbeOp3(v, OP_Explain, i, pLevel->iFrom, zMsg, P3_DYNAMIC); + } +#endif /* SQLITE_OMIT_EXPLAIN */ pTabItem = &pTabList->a[pLevel->iFrom]; pTab = pTabItem->pTab; if( pTab->isTransient || pTab->pSelect ) continue; diff --git a/tool/mkkeywordhash.c b/tool/mkkeywordhash.c index 58d4b9cb78..c43a767a30 100644 --- a/tool/mkkeywordhash.c +++ b/tool/mkkeywordhash.c @@ -193,8 +193,10 @@ static Keyword aKeywordTable[] = { { "OR", "TK_OR", ALWAYS }, { "ORDER", "TK_ORDER", ALWAYS }, { "OUTER", "TK_JOIN_KW", ALWAYS }, + { "PLAN", "TK_PLAN", EXPLAIN }, { "PRAGMA", "TK_PRAGMA", PRAGMA }, { "PRIMARY", "TK_PRIMARY", ALWAYS }, + { "QUERY", "TK_QUERY", EXPLAIN }, { "RAISE", "TK_RAISE", TRIGGER }, { "REFERENCES", "TK_REFERENCES", FKEY }, { "REGEXP", "TK_LIKE_KW", ALWAYS },