1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-16 23:02:26 +03:00

Add the experimental EXPLAIN QUERY PLAN diagnostic capability. (CVS 2685)

FossilOrigin-Name: 986efb7b12643800805ad4b1f1e90e30fcf6d38a
This commit is contained in:
drh
2005-09-10 16:46:12 +00:00
parent d891967052
commit ecc9242f6f
8 changed files with 59 additions and 27 deletions

View File

@@ -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) C Add\sthe\sexperimental\sEXPLAIN\sQUERY\sPLAN\sdiagnostic\scapability.\s(CVS\s2685)
D 2005-09-10T15:35:07 D 2005-09-10T16:46:13
F Makefile.in 12784cdce5ffc8dfb707300c34e4f1eb3b8a14f1 F Makefile.in 12784cdce5ffc8dfb707300c34e4f1eb3b8a14f1
F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7 F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -58,9 +58,9 @@ F src/os_win.c ed03a35b2894f9b99840415f941a9f8594dea756
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
F src/pager.c 2b48db1cc6073a6d2577100866db6ae039d20940 F src/pager.c 2b48db1cc6073a6d2577100866db6ae039d20940
F src/pager.h 17b13225abd93c1e9f470060f40a21b9edb5a164 F src/pager.h 17b13225abd93c1e9f470060f40a21b9edb5a164
F src/parse.y 13c3d16e999184cb5fba39e44f133cdf01288e3e F src/parse.y c97d885c344579c55257e0bbaeaa1daa1659ef2d
F src/pragma.c 69413fbdc0c6aaa493a776ea52c1b3e6cf35dfb2 F src/pragma.c 69413fbdc0c6aaa493a776ea52c1b3e6cf35dfb2
F src/prepare.c 86f0d8e744b8d956eff6bc40e29049efee017610 F src/prepare.c fc098db25d2a121affb08686cf04833fd50452d4
F src/printf.c c01e9ad473d79463fb1f483b1eca5c3cbed2a4e5 F src/printf.c c01e9ad473d79463fb1f483b1eca5c3cbed2a4e5
F src/random.c 90adff4e73a3b249eb4f1fc2a6ff9cf78c7233a4 F src/random.c 90adff4e73a3b249eb4f1fc2a6ff9cf78c7233a4
F src/select.c a255ca7eddd14c68d966b6323234dd94fcc7a31f F src/select.c a255ca7eddd14c68d966b6323234dd94fcc7a31f
@@ -80,14 +80,14 @@ F src/update.c c2716c2115533ffae3d08bf8853aaba4f970f37e
F src/utf.c bda5eb85039ef16f2d17004c1e18c96e1ab0a80c F src/utf.c bda5eb85039ef16f2d17004c1e18c96e1ab0a80c
F src/util.c 5650f6fe5ee30e0678985ad7b94da91e3f85752b F src/util.c 5650f6fe5ee30e0678985ad7b94da91e3f85752b
F src/vacuum.c 829d9e1a6d7c094b80e0899686670932eafd768c F src/vacuum.c 829d9e1a6d7c094b80e0899686670932eafd768c
F src/vdbe.c f722fbaf81890c342a1e1bf5a8a1600c5212ba47 F src/vdbe.c 7b20b81b2643c0cc616c3fec6435f13c6e5fa6db
F src/vdbe.h c8e105979fc7aaf5b8004e9621904e3bd096dfa2 F src/vdbe.h c8e105979fc7aaf5b8004e9621904e3bd096dfa2
F src/vdbeInt.h 3dd2a29c7b0a55404c35f93caae81fb42f4cb70a F src/vdbeInt.h 3dd2a29c7b0a55404c35f93caae81fb42f4cb70a
F src/vdbeapi.c 72213ce0c1ab8b215b2ae0ed342511bf769c1e60 F src/vdbeapi.c 72213ce0c1ab8b215b2ae0ed342511bf769c1e60
F src/vdbeaux.c a0aaf135c39825027366b5129f85191226d8b333 F src/vdbeaux.c 670264f8b8ddbc4277adf85ab945a59a3aaef871
F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5 F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
F src/vdbemem.c fea0744936008831daa17cdc75056c3ca1469690 F src/vdbemem.c fea0744936008831daa17cdc75056c3ca1469690
F src/where.c d032cca1b983ad14fb0361f1f7a2706c5e7a9720 F src/where.c 715e317eb37b89961ad7c5515a18f1e2eb1c7fd8
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42 F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
F test/all.test 7f0988442ab811dfa41793b5b550f5828ce316f3 F test/all.test 7f0988442ab811dfa41793b5b550f5828ce316f3
F test/alter.test 9d6837a3d946b73df692b7cef2a7644d2e2f6bc6 F test/alter.test 9d6837a3d946b73df692b7cef2a7644d2e2f6bc6
@@ -243,7 +243,7 @@ F tool/lempar.c f0c30abcae762a7d1eb37cd88b2232ab8dd625fb
F tool/memleak.awk 4e7690a51bf3ed757e611273d43fe3f65b510133 F tool/memleak.awk 4e7690a51bf3ed757e611273d43fe3f65b510133
F tool/memleak2.awk 9cc20c8e8f3c675efac71ea0721ee6874a1566e8 F tool/memleak2.awk 9cc20c8e8f3c675efac71ea0721ee6874a1566e8
F tool/memleak3.tcl 009da0ea82dc5893edca76cf1a21fb7260e9412e F tool/memleak3.tcl 009da0ea82dc5893edca76cf1a21fb7260e9412e
F tool/mkkeywordhash.c e0b7833fef924e3c75d5e5c28fdcdb879909bdfb F tool/mkkeywordhash.c 5263a654e5c9fd8d6e3238fb39c2d5c3126be32f
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
F tool/report1.txt 9eae07f26a8fc53889b45fc833a66a33daa22816 F tool/report1.txt 9eae07f26a8fc53889b45fc833a66a33daa22816
@@ -306,7 +306,7 @@ F www/tclsqlite.tcl 3df553505b6efcad08f91e9b975deb2e6c9bb955
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
P 415b8b24629aa12756d8285c094b5f85d8a8e532 P f43427742b1c086f2621c900f4ede1a34a8b44ee
R 235cc9d948e051600520eade7dbee36c R ab598fe85832474fa8020d661437e050
U drh U drh
Z be7b5a2752d3ffcf1cf1e2330b39e495 Z 6732d617323055d4bde842448e4c98ca

View File

@@ -1 +1 @@
f43427742b1c086f2621c900f4ede1a34a8b44ee 986efb7b12643800805ad4b1f1e90e30fcf6d38a

View File

@@ -14,7 +14,7 @@
** the parser. Lemon will also generate a header file containing ** the parser. Lemon will also generate a header file containing
** numeric codes for all of the tokens. ** 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_" // All token codes are small integers with #defines that begin with "TK_"
@@ -104,7 +104,8 @@ ecmd ::= SEMI.
ecmd ::= explain cmdx SEMI. ecmd ::= explain cmdx SEMI.
explain ::= . { sqlite3BeginParse(pParse, 0); } explain ::= . { sqlite3BeginParse(pParse, 0); }
%ifndef SQLITE_OMIT_EXPLAIN %ifndef SQLITE_OMIT_EXPLAIN
explain ::= EXPLAIN. { sqlite3BeginParse(pParse, 1); } explain ::= EXPLAIN. { sqlite3BeginParse(pParse, 1); }
explain ::= EXPLAIN QUERY PLAN. { sqlite3BeginParse(pParse, 2); }
%endif %endif
///////////////////// Begin and end transactions. //////////////////////////// ///////////////////// Begin and end transactions. ////////////////////////////
@@ -172,7 +173,7 @@ id(A) ::= ID(X). {A = X;}
%fallback ID %fallback ID
ABORT AFTER ANALYZE ASC ATTACH BEFORE BEGIN CASCADE CAST CONFLICT ABORT AFTER ANALYZE ASC ATTACH BEFORE BEGIN CASCADE CAST CONFLICT
DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR 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 OF OFFSET PRAGMA RAISE REPLACE RESTRICT ROW STATEMENT
TEMP TRIGGER VACUUM VIEW TEMP TRIGGER VACUUM VIEW
%ifdef SQLITE_OMIT_COMPOUND_SELECT %ifdef SQLITE_OMIT_COMPOUND_SELECT

View File

@@ -13,7 +13,7 @@
** interface, and routines that contribute to loading the database schema ** interface, and routines that contribute to loading the database schema
** from disk. ** 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 "sqliteInt.h"
#include "os.h" #include "os.h"
@@ -458,12 +458,19 @@ int sqlite3_prepare(
#ifndef SQLITE_OMIT_EXPLAIN #ifndef SQLITE_OMIT_EXPLAIN
if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){ if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
sqlite3VdbeSetNumCols(sParse.pVdbe, 5); if( sParse.explain==2 ){
sqlite3VdbeSetColName(sParse.pVdbe, 0, "addr", P3_STATIC); sqlite3VdbeSetNumCols(sParse.pVdbe, 3);
sqlite3VdbeSetColName(sParse.pVdbe, 1, "opcode", P3_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 0, "order", P3_STATIC);
sqlite3VdbeSetColName(sParse.pVdbe, 2, "p1", P3_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 1, "from", P3_STATIC);
sqlite3VdbeSetColName(sParse.pVdbe, 3, "p2", P3_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 2, "detail", P3_STATIC);
sqlite3VdbeSetColName(sParse.pVdbe, 4, "p3", 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 #endif

View File

@@ -43,7 +43,7 @@
** in this file for details. If in doubt, do not deviate from existing ** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code. ** 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 "sqliteInt.h"
#include "os.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 ** Do nothing. This instruction is often useful as a jump
** destination. ** 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 */ case OP_Noop: { /* no-push */
break; break;
} }

View File

@@ -577,8 +577,9 @@ int sqlite3VdbeList(
} }
p->resOnStack = 0; p->resOnStack = 0;
do{
i = p->pc++; i = p->pc++;
}while( i<p->nOp && p->explain==2 && p->aOp[i].opcode!=OP_Explain );
if( i>=p->nOp ){ if( i>=p->nOp ){
p->rc = SQLITE_OK; p->rc = SQLITE_OK;
rc = SQLITE_DONE; rc = SQLITE_DONE;
@@ -617,7 +618,7 @@ int sqlite3VdbeList(
pMem->type = SQLITE_TEXT; pMem->type = SQLITE_TEXT;
pMem->enc = SQLITE_UTF8; pMem->enc = SQLITE_UTF8;
p->nResColumn = 5; p->nResColumn = 5 - 2*(p->explain-1);
p->pTos = pMem; p->pTos = pMem;
p->rc = SQLITE_OK; p->rc = SQLITE_OK;
p->resOnStack = 1; p->resOnStack = 1;

View File

@@ -16,7 +16,7 @@
** so is applicable. Because this module is responsible for selecting ** so is applicable. Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer". ** 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" #include "sqliteInt.h"
@@ -1499,6 +1499,20 @@ WhereInfo *sqlite3WhereBegin(
Index *pIx; Index *pIx;
int iIdxCur = pLevel->iIdxCur; 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]; pTabItem = &pTabList->a[pLevel->iFrom];
pTab = pTabItem->pTab; pTab = pTabItem->pTab;
if( pTab->isTransient || pTab->pSelect ) continue; if( pTab->isTransient || pTab->pSelect ) continue;

View File

@@ -193,8 +193,10 @@ static Keyword aKeywordTable[] = {
{ "OR", "TK_OR", ALWAYS }, { "OR", "TK_OR", ALWAYS },
{ "ORDER", "TK_ORDER", ALWAYS }, { "ORDER", "TK_ORDER", ALWAYS },
{ "OUTER", "TK_JOIN_KW", ALWAYS }, { "OUTER", "TK_JOIN_KW", ALWAYS },
{ "PLAN", "TK_PLAN", EXPLAIN },
{ "PRAGMA", "TK_PRAGMA", PRAGMA }, { "PRAGMA", "TK_PRAGMA", PRAGMA },
{ "PRIMARY", "TK_PRIMARY", ALWAYS }, { "PRIMARY", "TK_PRIMARY", ALWAYS },
{ "QUERY", "TK_QUERY", EXPLAIN },
{ "RAISE", "TK_RAISE", TRIGGER }, { "RAISE", "TK_RAISE", TRIGGER },
{ "REFERENCES", "TK_REFERENCES", FKEY }, { "REFERENCES", "TK_REFERENCES", FKEY },
{ "REGEXP", "TK_LIKE_KW", ALWAYS }, { "REGEXP", "TK_LIKE_KW", ALWAYS },