mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Further simplification and modularization of the EXPLAIN logic.
FossilOrigin-Name: aee1c12f4227cea9e8c6295cee3ec11797422c31b48c9468f176eb52f8261fe8
This commit is contained in:
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
||||
C Begin\sbreaking\sappear\sthe\ssqlite3VdbeList()\sroutine\sinto\ssubroutines\sthat\ncan\sbe\sreused\sby\sthe\sbytecode()\stable.
|
||||
D 2020-03-23T17:24:46.014
|
||||
C Further\ssimplification\sand\smodularization\sof\sthe\sEXPLAIN\slogic.
|
||||
D 2020-03-23T19:14:11.433
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -607,7 +607,7 @@ F src/vdbe.c c1c123c6248fa88940b932a00bcc75056921b6d046d45a82566cb97415d2299c
|
||||
F src/vdbe.h 07b8c636a87df8b6e58f29d6badd7f10d5844353deff1d7c88ed1c2bfe3bbd35
|
||||
F src/vdbeInt.h 198e552a1a8945061c7576d3d7f8c8603300bbbb9ba0a337184bf13a7cdda65d
|
||||
F src/vdbeapi.c 1252d80c548711e47a6d84dae88ed4e95d3fbb4e7bd0eaa1347299af7efddf02
|
||||
F src/vdbeaux.c 46991da5699ff4986c15264c46d6300a56c008b758adade974dcebb5b9dba74e
|
||||
F src/vdbeaux.c a041e907fed078029e6d7608f62acf9d69ea262d515b00254f8736eff5f4d363
|
||||
F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1
|
||||
F src/vdbemem.c 39b942ecca179f4f30a32b54579a85d74ccaefa5af2a0ad2700abe5ef0768b22
|
||||
F src/vdbesort.c 2be76d26998ce2b3324cdcc9f6443728e54b6c7677c553ad909c7d7cfab587df
|
||||
@ -821,7 +821,7 @@ F test/descidx1.test edc8adee58d491b06c7157c50364eaf1c3605c9c19f8093cb1ea2b6184f
|
||||
F test/descidx2.test a0ba347037ff3b811f4c6ceca5fd0f9d5d72e74e59f2d9de346a9d2f6ad78298
|
||||
F test/descidx3.test 953c831df7ea219c73826dfbf2f6ee02d95040725aa88ccb4fa43d1a1999b926
|
||||
F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
|
||||
F test/distinct.test 8b6c652f0b2d477f0830884736f2a1cd2e8f7fc10a04aa6d571a401fa13ed88b
|
||||
F test/distinct.test e7d0cf371944dd0cbedff86420744e2f1ea2b528156451c97eb6ff41a99b9236
|
||||
F test/distinct2.test 11b0594c932098e969d084ba45ab81d5040f4d4e766db65d49146705a305ed98
|
||||
F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
|
||||
F test/e_blobbytes.test 439a945953b35cb6948a552edaec4dc31fd70a05
|
||||
@ -1861,7 +1861,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 2795f0d633577e0de66b389d9e8e44c55e85975bdc62f1a0b8f93959d19b22bf
|
||||
R d0c0c7fad919870cffac31ef6d1a6170
|
||||
P 2c4dd79fbd4b9f72634a732abb9ed833cd8c9b05fe1e10af8f23e6d6ec023c7c
|
||||
R 4748d2ea6081821a30c83e5089756745
|
||||
U drh
|
||||
Z bedd18e23757a54ddb7ae33ec04cb1e6
|
||||
Z 573498e339f1a839323caa9c87282f78
|
||||
|
@ -1 +1 @@
|
||||
2c4dd79fbd4b9f72634a732abb9ed833cd8c9b05fe1e10af8f23e6d6ec023c7c
|
||||
aee1c12f4227cea9e8c6295cee3ec11797422c31b48c9468f176eb52f8261fe8
|
142
src/vdbeaux.c
142
src/vdbeaux.c
@ -1464,11 +1464,10 @@ static int translateP(char c, const Op *pOp){
|
||||
** "PX@PY+1" -> "r[X..X+Y]" or "r[x]" if y is 0
|
||||
** "PY..PY" -> "r[X..Y]" or "r[x]" if y<=x
|
||||
*/
|
||||
static int displayComment(
|
||||
static char *displayComment(
|
||||
sqlite3 *db, /* Optional - Oom error reporting only */
|
||||
const Op *pOp, /* The opcode to be commented */
|
||||
const char *zP4, /* Previously obtained value for P4 */
|
||||
char *zTemp, /* Write result here */
|
||||
int nTemp /* Space available in zTemp[] */
|
||||
const char *zP4 /* Previously obtained value for P4 */
|
||||
){
|
||||
const char *zOpName;
|
||||
const char *zSynopsis;
|
||||
@ -1476,8 +1475,8 @@ static int displayComment(
|
||||
int ii;
|
||||
char zAlt[50];
|
||||
StrAccum x;
|
||||
sqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0);
|
||||
|
||||
sqlite3StrAccumInit(&x, 0, 0, 0, SQLITE_MAX_LENGTH);
|
||||
zOpName = sqlite3OpcodeName(pOp->opcode);
|
||||
nOpName = sqlite3Strlen30(zOpName);
|
||||
if( zOpName[nOpName+1] ){
|
||||
@ -1544,8 +1543,10 @@ static int displayComment(
|
||||
}else if( pOp->zComment ){
|
||||
sqlite3_str_appendall(&x, pOp->zComment);
|
||||
}
|
||||
sqlite3StrAccumFinish(&x);
|
||||
return x.nChar;
|
||||
if( (x.accError & SQLITE_NOMEM)!=0 && db!=0 ){
|
||||
sqlite3OomFault(db);
|
||||
}
|
||||
return sqlite3StrAccumFinish(&x);
|
||||
}
|
||||
#endif /* SQLITE_DEBUG */
|
||||
|
||||
@ -1628,11 +1629,11 @@ static void displayP4Expr(StrAccum *p, Expr *pExpr){
|
||||
** Compute a string that describes the P4 parameter for an opcode.
|
||||
** Use zTemp for any required temporary buffer space.
|
||||
*/
|
||||
static char *displayP4(Op *pOp, char *zTemp, int nTemp){
|
||||
char *zP4 = zTemp;
|
||||
static char *displayP4(sqlite3 *db, Op *pOp){
|
||||
char *zP4 = 0;
|
||||
StrAccum x;
|
||||
assert( nTemp>=20 );
|
||||
sqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0);
|
||||
|
||||
sqlite3StrAccumInit(&x, 0, 0, 0, SQLITE_MAX_LENGTH);
|
||||
switch( pOp->p4type ){
|
||||
case P4_KEYINFO: {
|
||||
int j;
|
||||
@ -1718,34 +1719,31 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
|
||||
for(i=1; i<=n; i++){
|
||||
sqlite3_str_appendf(&x, ",%d", ai[i]);
|
||||
}
|
||||
zTemp[0] = '[';
|
||||
if( !x.accError ) x.zText[0] = '[';
|
||||
sqlite3_str_append(&x, "]", 1);
|
||||
break;
|
||||
}
|
||||
case P4_SUBPROGRAM: {
|
||||
sqlite3_str_appendf(&x, "program");
|
||||
zP4 = "program";
|
||||
break;
|
||||
}
|
||||
case P4_DYNBLOB:
|
||||
case P4_ADVANCE: {
|
||||
zTemp[0] = 0;
|
||||
break;
|
||||
}
|
||||
case P4_TABLE: {
|
||||
sqlite3_str_appendf(&x, "%s", pOp->p4.pTab->zName);
|
||||
zP4 = pOp->p4.pTab->zName;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
zP4 = pOp->p4.z;
|
||||
if( zP4==0 ){
|
||||
zP4 = zTemp;
|
||||
zTemp[0] = 0;
|
||||
}
|
||||
}
|
||||
if( zP4 ) sqlite3_str_appendall(&x, zP4);
|
||||
if( (x.accError & SQLITE_NOMEM)!=0 && db!=0 ){
|
||||
sqlite3OomFault(db);
|
||||
}
|
||||
sqlite3StrAccumFinish(&x);
|
||||
assert( zP4!=0 );
|
||||
return zP4;
|
||||
return sqlite3StrAccumFinish(&x);
|
||||
}
|
||||
#endif /* VDBE_DISPLAY_P4 */
|
||||
|
||||
@ -1835,24 +1833,25 @@ void sqlite3VdbeLeave(Vdbe *p){
|
||||
*/
|
||||
void sqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){
|
||||
char *zP4;
|
||||
char zPtr[50];
|
||||
char zCom[100];
|
||||
char *zCom;
|
||||
static const char *zFormat1 = "%4d %-13s %4d %4d %4d %-13s %.2X %s\n";
|
||||
if( pOut==0 ) pOut = stdout;
|
||||
zP4 = displayP4(pOp, zPtr, sizeof(zPtr));
|
||||
zP4 = displayP4(0, pOp);
|
||||
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||
displayComment(pOp, zP4, zCom, sizeof(zCom));
|
||||
zCom = displayComment(0, pOp, zP4);
|
||||
#else
|
||||
zCom[0] = 0;
|
||||
zCom = 0;
|
||||
#endif
|
||||
/* NB: The sqlite3OpcodeName() function is implemented by code created
|
||||
** by the mkopcodeh.awk and mkopcodec.awk scripts which extract the
|
||||
** information from the vdbe.c source text */
|
||||
fprintf(pOut, zFormat1, pc,
|
||||
sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4, pOp->p5,
|
||||
zCom
|
||||
zCom ? zCom : ""
|
||||
);
|
||||
fflush(pOut);
|
||||
sqlite3_free(zP4);
|
||||
sqlite3_free(zCom);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -2133,78 +2132,43 @@ int sqlite3VdbeList(
|
||||
rc = SQLITE_ERROR;
|
||||
sqlite3VdbeError(p, sqlite3ErrStr(p->rc));
|
||||
}else{
|
||||
char *zP4;
|
||||
if( p->explain==1 ){
|
||||
pMem->flags = MEM_Int;
|
||||
pMem->u.i = i; /* Program counter */
|
||||
pMem++;
|
||||
|
||||
pMem->flags = MEM_Static|MEM_Str|MEM_Term;
|
||||
pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */
|
||||
assert( pMem->z!=0 );
|
||||
pMem->n = sqlite3Strlen30(pMem->z);
|
||||
pMem->enc = SQLITE_UTF8;
|
||||
pMem++;
|
||||
}
|
||||
|
||||
pMem->flags = MEM_Int;
|
||||
pMem->u.i = pOp->p1; /* P1 */
|
||||
pMem++;
|
||||
|
||||
pMem->flags = MEM_Int;
|
||||
pMem->u.i = pOp->p2; /* P2 */
|
||||
pMem++;
|
||||
|
||||
pMem->flags = MEM_Int;
|
||||
pMem->u.i = pOp->p3; /* P3 */
|
||||
pMem++;
|
||||
|
||||
if( sqlite3VdbeMemClearAndResize(pMem, 100) ){ /* P4 */
|
||||
assert( p->db->mallocFailed );
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
pMem->flags = MEM_Str|MEM_Term;
|
||||
zP4 = displayP4(pOp, pMem->z, pMem->szMalloc);
|
||||
if( zP4!=pMem->z ){
|
||||
pMem->n = 0;
|
||||
sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0);
|
||||
char *zP4 = displayP4(db, pOp);
|
||||
if( p->explain==2 ){
|
||||
sqlite3VdbeMemSetInt64(pMem, pOp->p1);
|
||||
sqlite3VdbeMemSetInt64(pMem+1, pOp->p2);
|
||||
sqlite3VdbeMemSetInt64(pMem+2, pOp->p3);
|
||||
sqlite3VdbeMemSetStr(pMem+3, zP4, -1, SQLITE_UTF8, sqlite3_free);
|
||||
p->nResColumn = 4;
|
||||
}else{
|
||||
assert( pMem->z!=0 );
|
||||
pMem->n = sqlite3Strlen30(pMem->z);
|
||||
pMem->enc = SQLITE_UTF8;
|
||||
}
|
||||
pMem++;
|
||||
|
||||
if( p->explain==1 ){
|
||||
if( sqlite3VdbeMemClearAndResize(pMem, 4) ){
|
||||
assert( p->db->mallocFailed );
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
pMem->flags = MEM_Str|MEM_Term;
|
||||
pMem->n = 2;
|
||||
sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */
|
||||
pMem->enc = SQLITE_UTF8;
|
||||
pMem++;
|
||||
|
||||
sqlite3VdbeMemSetInt64(pMem+0, i);
|
||||
sqlite3VdbeMemSetStr(pMem+1, (char*)sqlite3OpcodeName(pOp->opcode),
|
||||
-1, SQLITE_UTF8, SQLITE_STATIC);
|
||||
sqlite3VdbeMemSetInt64(pMem+2, pOp->p1);
|
||||
sqlite3VdbeMemSetInt64(pMem+3, pOp->p2);
|
||||
sqlite3VdbeMemSetInt64(pMem+4, pOp->p3);
|
||||
/* pMem+5 for p4 is done last */
|
||||
sqlite3VdbeMemSetInt64(pMem+6, pOp->p5);
|
||||
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
|
||||
if( sqlite3VdbeMemClearAndResize(pMem, 500) ){
|
||||
assert( p->db->mallocFailed );
|
||||
return SQLITE_ERROR;
|
||||
{
|
||||
char *zCom = displayComment(db, pOp, zP4);
|
||||
sqlite3VdbeMemSetStr(pMem+7, zCom, -1, SQLITE_UTF8, sqlite3_free);
|
||||
}
|
||||
pMem->flags = MEM_Str|MEM_Term;
|
||||
pMem->n = displayComment(pOp, zP4, pMem->z, 500);
|
||||
pMem->enc = SQLITE_UTF8;
|
||||
#else
|
||||
pMem->flags = MEM_Null; /* Comment */
|
||||
sqlite3VdbeMemSetNull(pMem+7);
|
||||
#endif
|
||||
sqlite3VdbeMemSetStr(pMem+5, zP4, -1, SQLITE_UTF8, sqlite3_free);
|
||||
p->nResColumn = 8;
|
||||
}
|
||||
|
||||
p->nResColumn = 8 - 4*(p->explain-1);
|
||||
p->pResultSet = &p->aMem[1];
|
||||
p->pResultSet = pMem;
|
||||
if( db->mallocFailed ){
|
||||
p->rc = SQLITE_NOMEM;
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
p->rc = SQLITE_OK;
|
||||
rc = SQLITE_ROW;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
#endif /* SQLITE_OMIT_EXPLAIN */
|
||||
|
@ -51,8 +51,8 @@ proc do_temptables_test {tn sql temptables} {
|
||||
set ret ""
|
||||
db eval "EXPLAIN [set sql]" {
|
||||
if {$opcode == "OpenEphemeral" || $opcode == "SorterOpen"} {
|
||||
if {$p5 != "08" && $p5!="00"} { error "p5 = $p5" }
|
||||
if {$p5 == "08"} {
|
||||
if {$p5!=8 && $p5!=0} { error "p5 = $p5" }
|
||||
if {$p5==8} {
|
||||
lappend ret hash
|
||||
} else {
|
||||
lappend ret btree
|
||||
|
Reference in New Issue
Block a user