From 2fc3300b2bfa15ed7172221ffb806dc7083f5304 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 13 Aug 2015 21:43:19 +0000 Subject: [PATCH] Convert the hint expression of the CursorHint opcode into a string for display by EXPLAIN. FossilOrigin-Name: 12640cb22240ee436cad99360ceb9a208edd14f5 --- manifest | 20 +++++++------ manifest.uuid | 2 +- src/vdbeInt.h | 11 ++++++++ src/vdbeaux.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 97 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 6cff144128..2cbaa534ee 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssimple\stests\sfor\snew\ssqlite3BtreeCursorHint()\sfunctionality. -D 2014-07-15T11:59:44.612 +C Convert\sthe\shint\sexpression\sof\sthe\sCursorHint\sopcode\sinto\sa\sstring\sfor\ndisplay\sby\sEXPLAIN. +D 2015-08-13T21:43:19.244 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -283,9 +283,9 @@ F src/util.c 76ed0519296e3f62e97e57dab1999e34184c8e49 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 F src/vdbe.c 54e269c6268a6f37697e27d6bc572674f14b1581 F src/vdbe.h 57b87844270b2e92647b8b82a8948f7a29efae8d -F src/vdbeInt.h 05fbda0e061dbc4aaa2709a8cccf3515c245b263 +F src/vdbeInt.h 9ad955ca89d4dc4b6056cece1896b4b85a8521fe F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed -F src/vdbeaux.c c7c9219cb31cef9917db3b3b41604ac74c5bc41b +F src/vdbeaux.c f4ed66c45336e42e7f1bdaccf7586c84eba06bac F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde F src/vdbemem.c 20e349d2ca928802fc8f2d42a2cc488fd6981d3f F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 @@ -1148,7 +1148,11 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P f9dddd008c6ef7940a1d66363fbb456cff7207c1 -R 9fb1051a18f0e187efee634c86c45e62 -U dan -Z 04e07c13931dc702da8721e6980ca969 +P 1efa6ed584172291edce78faf9021e577583d03b +Q +206884718782331a7aaacc2c811e4e9d2effae91 +R fcae2238c266b3818e83c96b2fcbbede +T *branch * cursor-hints-displayP4 +T *sym-cursor-hints-displayP4 * +T -sym-cursor-hints * +U drh +Z 41561b125b2ba8dcbfb094780611e534 diff --git a/manifest.uuid b/manifest.uuid index f1780b6a8f..fc01caa725 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1efa6ed584172291edce78faf9021e577583d03b \ No newline at end of file +12640cb22240ee436cad99360ceb9a208edd14f5 \ No newline at end of file diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 371c4d6dc1..2ca47f8277 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -26,6 +26,17 @@ # define SQLITE_MAX_SCHEMA_RETRY 50 #endif +/* +** VDBE_DISPLAY_P4 is true or false depending on whether or not the +** "explain" P4 display logic is enabled. +*/ +#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \ + || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) +# define VDBE_DISPLAY_P4 1 +#else +# define VDBE_DISPLAY_P4 0 +#endif + /* ** SQL is translated into a sequence of instructions to be ** executed by a virtual machine. Each instruction is an instance diff --git a/src/vdbeaux.c b/src/vdbeaux.c index cd55592cfe..bcaf1c36ba 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -947,9 +947,78 @@ static int displayComment( } #endif /* SQLITE_DEBUG */ +#if VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) +/* +** Translate the P4.pExpr value for an OP_CursorHint opcode into text +** that can be displayed in the P4 column of EXPLAIN output. +*/ +static int displayP4Expr(int nTemp, char *zTemp, Expr *pExpr){ + const char *zBinOp = 0; + switch( pExpr->op ){ + case TK_STRING: + sqlite3_snprintf(nTemp, zTemp, "%Q", pExpr->u.zToken); + break; + + case TK_INTEGER: + sqlite3_snprintf(nTemp, zTemp, "%d", pExpr->u.iValue); + break; + + case TK_NULL: + sqlite3_snprintf(nTemp, zTemp, "NULL"); + break; + + case TK_REGISTER: { + sqlite3_snprintf(nTemp, zTemp, "r[%d]", pExpr->iTable); + break; + } + + case TK_COLUMN: { + sqlite3_snprintf(nTemp, zTemp, "c%d", (int)pExpr->iColumn); + break; + } + + case TK_LT: zBinOp = "<"; break; + case TK_LE: zBinOp = "<="; break; + case TK_GT: zBinOp = ">"; break; + case TK_GE: zBinOp = ">="; break; + case TK_NE: zBinOp = "!="; break; + case TK_EQ: zBinOp = "=="; break; + case TK_IS: zBinOp = " IS "; break; + case TK_ISNOT: zBinOp = " IS NOT "; break; + case TK_AND: zBinOp = " AND "; break; + case TK_OR: zBinOp = " OR "; break; + case TK_PLUS: zBinOp = "+"; break; + case TK_STAR: zBinOp = "*"; break; + case TK_MINUS: zBinOp = "-"; break; + case TK_REM: zBinOp = "%"; break; + case TK_BITAND: zBinOp = "&"; break; + case TK_BITOR: zBinOp = "|"; break; + case TK_SLASH: zBinOp = "/"; break; + case TK_LSHIFT: zBinOp = "<<"; break; + case TK_RSHIFT: zBinOp = ">>"; break; + case TK_CONCAT: zBinOp = "||"; break; + + default: + sqlite3_snprintf(nTemp, zTemp, "%s", "expr"); + break; + } -#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \ - || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) + if( zBinOp && nTemp>5 ){ + int n = 1; + zTemp[0] = '('; + n += displayP4Expr(nTemp-n, zTemp+n, pExpr->pLeft); + sqlite3_snprintf(nTemp-n, zTemp+n, "%s", zBinOp); + n += sqlite3Strlen30(zTemp+n); + n += displayP4Expr(nTemp-n, zTemp+n, pExpr->pRight); + sqlite3_snprintf(nTemp-n, zTemp+n, ")"); + } + + return sqlite3Strlen30(zTemp); +} +#endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */ + + +#if VDBE_DISPLAY_P4 /* ** Compute a string that describes the P4 parameter for an opcode. ** Use zTemp for any required temporary buffer space. @@ -990,7 +1059,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ } #ifdef SQLITE_ENABLE_CURSOR_HINTS case P4_EXPR: { - sqlite3_snprintf(nTemp, zTemp, "(expr)"); + displayP4Expr(nTemp, zTemp, pOp->p4.pExpr); break; } #endif @@ -1062,7 +1131,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ assert( zP4!=0 ); return zP4; } -#endif +#endif /* VDBE_DISPLAY_P4 */ /* ** Declare to the Vdbe that the BTree object at db->aDb[i] is used. -- 2.39.5