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

Import the "PRAGMA vdbe_eqp" enhancement and the enhanced EXPLAIN formatting

the shell from trunk.  Fix a bug in skip-scan and add a test case to prevent
a regression.

FossilOrigin-Name: f668616a29686f3ce532731c534b168e536adbb5
This commit is contained in:
drh
2013-11-13 19:01:41 +00:00
13 changed files with 198 additions and 74 deletions

View File

@@ -1,5 +1,5 @@
C Add\sVDBE\scomments\sto\sthe\sbeginning\sand\send\sof\sskip-scan\sloops.
D 2013-11-13T17:24:39.000
C Import\sthe\s"PRAGMA\svdbe_eqp"\senhancement\sand\sthe\senhanced\sEXPLAIN\sformatting\nthe\sshell\sfrom\strunk.\s\sFix\sa\sbug\sin\sskip-scan\sand\sadd\sa\stest\scase\sto\sprevent\na\sregression.
D 2013-11-13T19:01:41.390
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -169,7 +169,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
F src/btree.c 260dedc13119e6fb7930380bd3d294b98362bf5a
F src/btree.h bfe0e8c5759b4ec77b0d18390064a6ef3cdffaaf
F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0
F src/build.c 4d740243144d9e5058a46df7d05d1243f449b4d7
F src/build.c 2baeed38bdaa9f1199f101c63db41fdcc4b39ba5
F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c
@@ -213,18 +213,18 @@ F src/parse.y 073a8294e1826f1b1656e84806b77e4199f4bb57
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
F src/pcache1.c a467393909a4ed7ca9de066d85ba5c5b04a5be63
F src/pragma.c 3b7b766382ac679d3c1a7ba368aa008f9a756d59
F src/pragma.c c8d70c47ec8d8ba93575d92e34d30ddff8e9b517
F src/prepare.c fa6988589f39af8504a61731614cd4f6ae71554f
F src/printf.c da9119eb31a187a4b99f60aa4a225141c0ebb74b
F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68
F src/resolve.c fc4673cc49b116e51e7f12de074c0acf8f2388f9
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
F src/select.c 7317406831ecced390edba972818f3c5f82238c0
F src/shell.c 03d8d9b4052430343ff30d646334621f980f1202
F src/shell.c 6ccc22b717afe4f6d7d3c8b6baa02e3b99a5fdf0
F src/sqlite.h.in 4dedcab5b32358bf7a596badffe7363be1f1a82d
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
F src/sqliteInt.h 3da1940a2ba05a663e9016d57f1ea1f79ffcb03e
F src/sqliteInt.h 2ec1d71220307fa5ee85a918a6240cf0b4635b0e
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -280,11 +280,11 @@ F src/update.c 3de7e657b98ac67338d775c114a4068faf732402
F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
F src/vdbe.c fda0d2ba5a3a5ab588f0467782e7fd64930ddb22
F src/vdbe.h 8d5a7351024d80374fc0acdbbe3cfe65c51ba8b6
F src/vdbeInt.h f2fa3ceccceeb757773921fb08af7c6e9f3caa1c
F src/vdbe.c 3d73013b4ef54061e768443fb35a36b3dd289663
F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644
F src/vdbeInt.h 62eb680327011f3a4b0336642b0ca9d6ecc6eb91
F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed
F src/vdbeaux.c 75c5fee307004739d814a840699df5e853e02b79
F src/vdbeaux.c dd0f6ab9dc159911facfc0a7a2164af44779bdda
F src/vdbeblob.c ff60adf2953e0ffc1d59541b3101c9886b03a3de
F src/vdbemem.c cc529bbf4f13e4e181bdb446bf6e6962ab030b4b
F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147
@@ -293,7 +293,7 @@ F src/vtab.c 5a423b042eb1402ef77697d03d6a67378d97bc8d
F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74
F src/where.c 1d19a1d49a608441fa697ae32627399073be8dcf
F src/where.c 2eb88f96a73d77bd61d6afd50c33ec5d63c15dd5
F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@@ -805,7 +805,7 @@ F test/shell5.test 46c8c18d62732415c4fe084816c13d559831705e
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868
F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
F test/skipscan1.test bc65ecb228eba396c404aa038f49798340f0677f
F test/skipscan1.test 6bb4891c2cc5efd5690a9da9e7508e53d4a68e10
F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f
F test/softheap1.test 40562fe6cac6d9827b7b42b86d45aedf12c15e24
F test/sort.test 0e4456e729e5a92a625907c63dcdedfbe72c5dc5
@@ -1106,7 +1106,7 @@ F tool/logest.c 7ad625cac3d54012b27d468b7af6612f78b9ba75
F tool/mkautoconfamal.sh f8d8dbf7d62f409ebed5134998bf5b51d7266383
F tool/mkkeywordhash.c 189d76644e373c7d0864c628deb8ce7b4f403591
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
F tool/mkpragmatab.tcl 17d40faae6c4b865633bfc5763821402a1cbefc3
F tool/mkpragmatab.tcl 78a77b2c554d534c6f2dc903130186ed15715460
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
F tool/mksqlite3c-noext.tcl 8bce31074e4cbe631bb7676526a048335f4c9f02
F tool/mksqlite3c.tcl e2ba20d3f690990079d17f3e5a7417dfb7ada543
@@ -1139,7 +1139,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
P 5e75ab93881b85801cb4ebf70f2063ff7c51ac19
R 324d2d53e7ac48858b72f1751f7e7610
P 0c85d93b52311dee7980d977be6ed0dc70b060c1 e7d34ec6814ed4606a6d5d7f68c218ae4d25e666
R 0f42dd23f60246e0b55a84d51974156a
U drh
Z 7cfb6326eedc7a21a0bd15f40c4f97e2
Z 2c708550c85df0e56ea327d75809b287

View File

@@ -1 +1 @@
0c85d93b52311dee7980d977be6ed0dc70b060c1
f668616a29686f3ce532731c534b168e536adbb5

View File

@@ -193,10 +193,6 @@ void sqlite3FinishCoding(Parse *pParse){
/* Get the VDBE program ready for execution
*/
if( v && ALWAYS(pParse->nErr==0) && !db->mallocFailed ){
#ifdef SQLITE_DEBUG
FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;
sqlite3VdbeTrace(v, trace);
#endif
assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */
/* A minimum of one cursor is required if autoincrement is used
* See ticket [a696379c1f08866] */

View File

@@ -434,6 +434,10 @@ static const struct sPragmaNames {
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlag: */ 0,
/* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace },
{ /* zName: */ "vdbe_eqp",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlag: */ 0,
/* iArg: */ SQLITE_VdbeEQP },
{ /* zName: */ "vdbe_listing",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlag: */ 0,
@@ -461,7 +465,7 @@ static const struct sPragmaNames {
/* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
#endif
};
/* Number of pragmas: 56 on by default, 68 total. */
/* Number of pragmas: 56 on by default, 69 total. */
/* End of the automatically generated pragma table.
***************************************************************************/

View File

@@ -464,6 +464,8 @@ struct callback_data {
const char *zVfs; /* Name of VFS to use */
sqlite3_stmt *pStmt; /* Current statement if any. */
FILE *pLog; /* Write log output here */
int *aiIndent; /* Array of indents used in MODE_Explain */
int nIndent; /* Size of array aiIndent[] */
};
/*
@@ -765,10 +767,15 @@ static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int
}else{
w = 10;
}
if( p->mode==MODE_Explain && azArg[i] &&
strlen30(azArg[i])>w ){
if( p->mode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
w = strlen30(azArg[i]);
}
if( i==1 && p->aiIndent && p->pStmt ){
int iOp = sqlite3_column_int(p->pStmt, 0);
if( iOp<p->nIndent ){
fprintf(p->out, "%*.s", p->aiIndent[iOp], "");
}
}
if( w<0 ){
fprintf(p->out,"%*.*s%s",-w,-w,
azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
@@ -1141,6 +1148,90 @@ static int display_stats(
return 0;
}
/*
** Parameter azArray points to a zero-terminated array of strings. zStr
** points to a single nul-terminated string. Return non-zero if zStr
** is equal, according to strcmp(), to any of the strings in the array.
** Otherwise, return zero.
*/
static int str_in_array(const char *zStr, const char **azArray){
int i;
for(i=0; azArray[i]; i++){
if( 0==strcmp(zStr, azArray[i]) ) return 1;
}
return 0;
}
/*
** If compiled statement pSql appears to be an EXPLAIN statement, allocate
** and populate the callback_data.aiIndent[] array with the number of
** spaces each opcode should be indented before it is output.
**
** The indenting rules are:
**
** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
** all opcodes that occur between the p2 jump destination and the opcode
** itself by 2 spaces.
**
** * For each "Goto", if the jump destination is a "Yield", "SeekGt",
** or "SeekLt" instruction that occurs earlier in the program than
** the Goto itself, indent all opcodes between the earlier instruction
** and "Goto" by 2 spaces.
*/
static void explain_data_prepare(struct callback_data *p, sqlite3_stmt *pSql){
const char *zSql; /* The text of the SQL statement */
const char *z; /* Used to check if this is an EXPLAIN */
int *abYield = 0; /* True if op is an OP_Yield */
int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
int iOp;
const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", 0 };
const char *azYield[] = { "Yield", "SeekLt", "SeekGt", 0 };
const char *azGoto[] = { "Goto", 0 };
/* Try to figure out if this is really an EXPLAIN statement. If this
** cannot be verified, return early. */
zSql = sqlite3_sql(pSql);
if( zSql==0 ) return;
for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
if( sqlite3_strnicmp(z, "explain", 7) ) return;
for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
int i;
const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
int p2 = sqlite3_column_int(pSql, 3);
/* Grow the p->aiIndent array as required */
if( iOp>=nAlloc ){
nAlloc += 100;
p->aiIndent = (int*)sqlite3_realloc(p->aiIndent, nAlloc*sizeof(int));
abYield = (int*)sqlite3_realloc(abYield, nAlloc*sizeof(int));
}
abYield[iOp] = str_in_array(zOp, azYield);
p->aiIndent[iOp] = 0;
p->nIndent = iOp+1;
if( str_in_array(zOp, azNext) ){
for(i=p2; i<iOp; i++) p->aiIndent[i] += 2;
}
if( str_in_array(zOp, azGoto) && p2<p->nIndent && abYield[p2] ){
for(i=p2+1; i<iOp; i++) p->aiIndent[i] += 2;
}
}
sqlite3_free(abYield);
sqlite3_reset(pSql);
}
/*
** Free the array allocated by explain_data_prepare().
*/
static void explain_data_delete(struct callback_data *p){
sqlite3_free(p->aiIndent);
p->aiIndent = 0;
p->nIndent = 0;
}
/*
** Execute a statement or set of statements. Print
** any result rows/columns depending on the current mode
@@ -1202,6 +1293,12 @@ static int shell_exec(
}
}
/* If the shell is currently in ".explain" mode, gather the extra
** data required to add indents to the output.*/
if( pArg->mode==MODE_Explain ){
explain_data_prepare(pArg, pStmt);
}
/* perform the first step. this will tell us if we
** have a result set or not and how wide it is.
*/
@@ -1259,6 +1356,8 @@ static int shell_exec(
}
}
explain_data_delete(pArg);
/* print usage stats if stats on */
if( pArg && pArg->statsOn ){
display_stats(db, pArg, 0);

View File

@@ -1043,6 +1043,7 @@ struct sqlite3 {
#define SQLITE_EnableTrigger 0x00800000 /* True to enable triggers */
#define SQLITE_DeferFKs 0x01000000 /* Defer all FK constraints */
#define SQLITE_QueryOnly 0x02000000 /* Disable database changes */
#define SQLITE_VdbeEQP 0x04000000 /* Debug EXPLAIN QUERY PLAN */
/*

View File

@@ -417,37 +417,36 @@ void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){
/*
** Print the value of a register for tracing purposes:
*/
static void memTracePrint(FILE *out, Mem *p){
static void memTracePrint(Mem *p){
if( p->flags & MEM_Invalid ){
fprintf(out, " undefined");
printf(" undefined");
}else if( p->flags & MEM_Null ){
fprintf(out, " NULL");
printf(" NULL");
}else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
fprintf(out, " si:%lld", p->u.i);
printf(" si:%lld", p->u.i);
}else if( p->flags & MEM_Int ){
fprintf(out, " i:%lld", p->u.i);
printf(" i:%lld", p->u.i);
#ifndef SQLITE_OMIT_FLOATING_POINT
}else if( p->flags & MEM_Real ){
fprintf(out, " r:%g", p->r);
printf(" r:%g", p->r);
#endif
}else if( p->flags & MEM_RowSet ){
fprintf(out, " (rowset)");
printf(" (rowset)");
}else{
char zBuf[200];
sqlite3VdbeMemPrettyPrint(p, zBuf);
fprintf(out, " ");
fprintf(out, "%s", zBuf);
printf(" %s", zBuf);
}
}
static void registerTrace(FILE *out, int iReg, Mem *p){
fprintf(out, "REG[%d] = ", iReg);
memTracePrint(out, p);
fprintf(out, "\n");
static void registerTrace(int iReg, Mem *p){
printf("REG[%d] = ", iReg);
memTracePrint(p);
printf("\n");
}
#endif
#ifdef SQLITE_DEBUG
# define REGISTER_TRACE(R,M) if(p->trace)registerTrace(p->trace,R,M)
# define REGISTER_TRACE(R,M) if(db->flags&SQLITE_VdbeTrace)registerTrace(R,M)
#else
# define REGISTER_TRACE(R,M)
#endif
@@ -586,14 +585,29 @@ int sqlite3VdbeExec(
#endif
#ifdef SQLITE_DEBUG
sqlite3BeginBenignMalloc();
if( p->pc==0 && (p->db->flags & SQLITE_VdbeListing)!=0 ){
if( p->pc==0
&& (p->db->flags & (SQLITE_VdbeListing|SQLITE_VdbeEQP|SQLITE_VdbeTrace))!=0
){
int i;
printf("VDBE Program Listing:\n");
int once = 1;
sqlite3VdbePrintSql(p);
if( p->db->flags & SQLITE_VdbeListing ){
printf("VDBE Program Listing:\n");
for(i=0; i<p->nOp; i++){
sqlite3VdbePrintOp(stdout, i, &aOp[i]);
}
}
if( p->db->flags & SQLITE_VdbeEQP ){
for(i=0; i<p->nOp; i++){
if( aOp[i].opcode==OP_Explain ){
if( once ) printf("VDBE Query Plan:\n");
printf("%s\n", aOp[i].p4.z);
once = 0;
}
}
}
if( p->db->flags & SQLITE_VdbeTrace ) printf("VDBE Trace:\n");
}
sqlite3EndBenignMalloc();
#endif
for(pc=p->pc; rc==SQLITE_OK; pc++){
@@ -609,12 +623,8 @@ int sqlite3VdbeExec(
/* Only allow tracing if SQLITE_DEBUG is defined.
*/
#ifdef SQLITE_DEBUG
if( p->trace ){
if( pc==0 ){
printf("VDBE Execution Trace:\n");
sqlite3VdbePrintSql(p);
}
sqlite3VdbePrintOp(p->trace, pc, pOp);
if( db->flags & SQLITE_VdbeTrace ){
sqlite3VdbePrintOp(stdout, pc, pOp);
}
#endif
@@ -6255,13 +6265,13 @@ default: { /* This is really OP_Noop and OP_Explain */
assert( pc>=-1 && pc<p->nOp );
#ifdef SQLITE_DEBUG
if( p->trace ){
if( rc!=0 ) fprintf(p->trace,"rc=%d\n",rc);
if( db->flags & SQLITE_VdbeTrace ){
if( rc!=0 ) printf("rc=%d\n",rc);
if( pOp->opflags & (OPFLG_OUT2_PRERELEASE|OPFLG_OUT2) ){
registerTrace(p->trace, pOp->p2, &aMem[pOp->p2]);
registerTrace(pOp->p2, &aMem[pOp->p2]);
}
if( pOp->opflags & OPFLG_OUT3 ){
registerTrace(p->trace, pOp->p3, &aMem[pOp->p3]);
registerTrace(pOp->p3, &aMem[pOp->p3]);
}
}
#endif /* SQLITE_DEBUG */

View File

@@ -189,7 +189,6 @@ void sqlite3VdbeResolveLabel(Vdbe*, int);
int sqlite3VdbeCurrentAddr(Vdbe*);
#ifdef SQLITE_DEBUG
int sqlite3VdbeAssertMayAbort(Vdbe *, int);
void sqlite3VdbeTrace(Vdbe*,FILE*);
#endif
void sqlite3VdbeResetStepResult(Vdbe*);
void sqlite3VdbeRewind(Vdbe*);

View File

@@ -355,9 +355,6 @@ struct Vdbe {
i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */
char *zSql; /* Text of the SQL statement that generated this */
void *pFree; /* Free this when deleting the vdbe */
#ifdef SQLITE_DEBUG
FILE *trace; /* Write an execution trace here, if not NULL */
#endif
#ifdef SQLITE_ENABLE_TREE_EXPLAIN
Explain *pExplain; /* The explainer */
char *zExplain; /* Explanation of data structures */

View File

@@ -78,15 +78,6 @@ void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
pB->isPrepareV2 = pA->isPrepareV2;
}
#ifdef SQLITE_DEBUG
/*
** Turn tracing on or off
*/
void sqlite3VdbeTrace(Vdbe *p, FILE *trace){
p->trace = trace;
}
#endif
/*
** Resize the Vdbe.aOp array so that it is at least one op larger than
** it was.
@@ -1415,15 +1406,17 @@ int sqlite3VdbeList(
** Print the SQL that was used to generate a VDBE program.
*/
void sqlite3VdbePrintSql(Vdbe *p){
int nOp = p->nOp;
VdbeOp *pOp;
if( nOp<1 ) return;
pOp = &p->aOp[0];
const char *z = 0;
if( p->zSql ){
z = p->zSql;
}else if( p->nOp>=1 ){
const VdbeOp *pOp = &p->aOp[0];
if( pOp->opcode==OP_Trace && pOp->p4.z!=0 ){
const char *z = pOp->p4.z;
z = pOp->p4.z;
while( sqlite3Isspace(*z) ) z++;
printf("SQL: [%s]\n", z);
}
}
if( z ) printf("SQL: [%s]\n", z);
}
#endif

View File

@@ -2650,7 +2650,10 @@ static void explainOneScan(
int iFrom, /* Value for "from" column of output */
u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */
){
if( pParse->explain==2 ){
#ifndef SQLITE_DEBUG
if( pParse->explain==2 )
#endif
{
struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
Vdbe *v = pParse->pVdbe; /* VM being constructed */
sqlite3 *db = pParse->db; /* Database handle */
@@ -3852,6 +3855,7 @@ static void whereLoopOutputAdjust(WhereClause *pWC, WhereLoop *pLoop){
if( (pTerm->prereqAll & notAllowed)!=0 ) continue;
for(j=pLoop->nLTerm-1; j>=0; j--){
pX = pLoop->aLTerm[j];
if( pX==0 ) continue;
if( pX==pTerm ) break;
if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break;
}

View File

@@ -98,6 +98,21 @@ do_execsql_test skipscan1-1.6sort {
SELECT a,b,c,d,'|' FROM t1 WHERE c BETWEEN 6 AND 7 ORDER BY a, b, c;
} {~/*ORDER BY*/}
do_execsql_test skipscan1-1.7 {
SELECT a,b,c,d,'|' FROM t1 WHERE b IN (234, 345) AND c BETWEEN 6 AND 7
ORDER BY a, b;
} {abc 234 6 7 | abc 345 7 8 |}
do_execsql_test skipscan1-1.7eqp {
EXPLAIN QUERY PLAN
SELECT a,b,c,d,'|' FROM t1 WHERE b IN (234, 345) AND c BETWEEN 6 AND 7
ORDER BY a, b;
} {/* USING INDEX t1abc (ANY(a) AND b=? AND c>? AND c<?)*/}
do_execsql_test skipscan1-1.7sort {
EXPLAIN QUERY PLAN
SELECT a,b,c,d,'|' FROM t1 WHERE b IN (234, 345) AND c BETWEEN 6 AND 7
ORDER BY a, b;
} {~/*ORDER BY*/}
# Joins
#

View File

@@ -97,6 +97,12 @@ set pragma_def {
IF: !defined(SQLITE_OMIT_FLAG_PRAGMAS)
IF: defined(SQLITE_DEBUG)
NAME: vdbe_eqp
TYPE: FLAG
ARG: SQLITE_VdbeEQP
IF: !defined(SQLITE_OMIT_FLAG_PRAGMAS)
IF: defined(SQLITE_DEBUG)
NAME: ignore_check_constraints
TYPE: FLAG
ARG: SQLITE_IgnoreChecks