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:
22
manifest
22
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
|
||||
|
||||
@@ -1 +1 @@
|
||||
f43427742b1c086f2621c900f4ede1a34a8b44ee
|
||||
986efb7b12643800805ad4b1f1e90e30fcf6d38a
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -577,8 +577,9 @@ int sqlite3VdbeList(
|
||||
}
|
||||
p->resOnStack = 0;
|
||||
|
||||
|
||||
i = p->pc++;
|
||||
do{
|
||||
i = p->pc++;
|
||||
}while( i<p->nOp && 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;
|
||||
|
||||
16
src/where.c
16
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;
|
||||
|
||||
@@ -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 },
|
||||
|
||||
Reference in New Issue
Block a user