Have sqlite3_stmt_scanstatus_v2() return an NCYCLE value for all loops, not just virtual tables ones. The value returned is the sum of the NCYCLE counts for the various opcodes that move or read data from the table or index cursor associated with the loop.
FossilOrigin-Name: 9499b2f51e8174c6b8a67840c92ba23b7dd1dc8dc2b91fca0c5dc07b71662149
This commit is contained in:
parent
29226fc023
commit
2adb309ead
22
manifest
22
manifest
@ -1,5 +1,5 @@
|
||||
C Clear\sa\sfew\smore\s-Wall\swarnings\sand\ssimplify\sdynaprompt\sfeature\skeep/omit\smacros.
|
||||
D 2022-12-06T17:59:05.853
|
||||
C Have\ssqlite3_stmt_scanstatus_v2()\sreturn\san\sNCYCLE\svalue\sfor\sall\sloops,\snot\sjust\svirtual\stables\sones.\sThe\svalue\sreturned\sis\sthe\ssum\sof\sthe\sNCYCLE\scounts\sfor\sthe\svarious\sopcodes\sthat\smove\sor\sread\sdata\sfrom\sthe\stable\sor\sindex\scursor\sassociated\swith\sthe\sloop.
|
||||
D 2022-12-06T18:48:06.154
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -717,10 +717,10 @@ F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145
|
||||
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
|
||||
F src/util.c 313f3154e2b85a447326f5dd15de8d31a4df6ab0c3579bd58f426ff634ec9050
|
||||
F src/vacuum.c 84ce7f01f8a7a08748e107a441db83bcec13970190ddcb0c9ff522adbc1c23fd
|
||||
F src/vdbe.c e744259050ec9bbcd47acf9a03a66fe3305d7429c823995de11ed524ca06d16f
|
||||
F src/vdbe.c 8fdef91d3c9bfa363e8eb381d362e2f0cadec456975ec5595c0bfdf65da84e53
|
||||
F src/vdbe.h 6d921884cf8ec6a53efba99f8b68e32e955367631743e29039840e781aaf547c
|
||||
F src/vdbeInt.h e83be1eea422758d42302941e96e59d93193c373da655a87befdc03a851e0f95
|
||||
F src/vdbeapi.c 959cef4c1e5cb6589e67b3295fe9d3e45cbd109ae6618d57b74c900dbd6be0cd
|
||||
F src/vdbeapi.c 5e265ab5165b0dfeac55e6a2ad3929d64584c4e7ca106b438137d7596da91348
|
||||
F src/vdbeaux.c 0b81f317c86ed9f4ba822af66a52777fed6e8180edc79d4fc62ffe75c8e52d80
|
||||
F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd
|
||||
F src/vdbemem.c 6cfed43758d57b6e3b99d9cdedfeccd86e45a07e427b22d8487cbdbebb6c522a
|
||||
@ -734,7 +734,7 @@ F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
|
||||
F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b
|
||||
F src/where.c 20f4f51d2d5fb19b984e6ea381b26cf627cc93e64dd9b2ce6a94531aec2f5916
|
||||
F src/whereInt.h e25203e5bfee149f5f1225ae0166cfb4f1e65490c998a024249e98bb0647377c
|
||||
F src/wherecode.c d3146e215f3a716c0e153ded68bfcc747aad550e114a79729bda887cf4ea6f00
|
||||
F src/wherecode.c 76bca3379219880d2527493b71a3be49e696f75396d3481e4de5d4ceec7886b2
|
||||
F src/whereexpr.c 05295b44b54eea76d1ba766f0908928d0e20e990c249344c9521454d3d09c7ae
|
||||
F src/window.c 14836767adb26573b50f528eb37f8b1336f2c430ab38de7cead1e5c546bb4d8c
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
@ -1458,7 +1458,7 @@ F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7
|
||||
F test/savepoint7.test cde525ea3075283eb950cdcdefe23ead4f700daa
|
||||
F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2
|
||||
F test/scanstatus.test 7dbcfd6adc6a8df6abc59f83d6da5a27e1bce0b2f6fa55147c8176d7c44e0450
|
||||
F test/scanstatus2.test cc0be2f645c32ede50affa7d4ecfaffd2b4572a4fd7f723082397c65a910a2b5
|
||||
F test/scanstatus2.test 3f45ec1d8b45dcb0df7f98daf3364fc2e03bf89a8c3dd2428251a5e0a34de7af
|
||||
F test/schema.test 5dd11c96ba64744de955315d2e4f8992e447533690153b93377dffb2a5ef5431
|
||||
F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5
|
||||
F test/schema3.test 8ed4ae66e082cdd8b1b1f22d8549e1e7a0db4527a8e6ee8b6193053ee1e5c9ce
|
||||
@ -1996,7 +1996,7 @@ F tool/mkctimec.tcl c185cf1bdcd3d9bd3c06f77a2fd2df8a4a0d07266f992ecda75286965ba3
|
||||
F tool/mkkeywordhash.c 35bfc41adacc4aa6ef6fca7fd0c63e0ec0534b78daf4d0cfdebe398216bbffc3
|
||||
F tool/mkmsvcmin.tcl 6ecab9fe22c2c8de4d82d4c46797bda3d2deac8e763885f5a38d0c44a895ab33
|
||||
F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61a07ef
|
||||
F tool/mkopcodeh.tcl bcb2bd5affb545fd219ef0304c7978e2a356407ab723f45ec8569235892c1c3f
|
||||
F tool/mkopcodeh.tcl 769d9e6a8b462323150dc13a8539d6064664b72974f7894befe2491cc73e05cd
|
||||
F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa
|
||||
F tool/mkpragmatab.tcl bd07bd59d45d0f3448e123d6937e9811195f9908a51e09d774609883055bfd3d
|
||||
F tool/mkshellc.tcl 02d0de8349ef830c0fb20d29680320bde2466e2ec422e5bd94c4317a7a7e8cc9
|
||||
@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 0d80500d358fa1c9b5867c2c8250d278ba813bf2ad81bb0bc3f820a71489b374
|
||||
R d2096b6607984433a4c4474baae68bae
|
||||
U larrybr
|
||||
Z 397638802057e8cab20b3ed1dff696d1
|
||||
P 540e895d877fab1ea138786e56923a202018f68c78199a89adfc296c75735b30
|
||||
R e347a9226ee206cfe1e680e2e5e722d0
|
||||
U dan
|
||||
Z eaf9f5c14b0f034256d24205aa5d85c9
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
540e895d877fab1ea138786e56923a202018f68c78199a89adfc296c75735b30
|
||||
9499b2f51e8174c6b8a67840c92ba23b7dd1dc8dc2b91fca0c5dc07b71662149
|
76
src/vdbe.c
76
src/vdbe.c
@ -2780,7 +2780,7 @@ case OP_Offset: { /* out3 */
|
||||
** typeof() function or the IS NULL or IS NOT NULL operators or the
|
||||
** equivalent. In this case, all content loading can be omitted.
|
||||
*/
|
||||
case OP_Column: {
|
||||
case OP_Column: { /* ncycle */
|
||||
u32 p2; /* column number to retrieve */
|
||||
VdbeCursor *pC; /* The VDBE cursor */
|
||||
BtCursor *pCrsr; /* The B-Tree cursor corresponding to pC */
|
||||
@ -4132,7 +4132,7 @@ case OP_SetCookie: {
|
||||
**
|
||||
** See also: OP_OpenRead, OP_ReopenIdx
|
||||
*/
|
||||
case OP_ReopenIdx: {
|
||||
case OP_ReopenIdx: { /* ncycle */
|
||||
int nField;
|
||||
KeyInfo *pKeyInfo;
|
||||
u32 p2;
|
||||
@ -4153,7 +4153,7 @@ case OP_ReopenIdx: {
|
||||
}
|
||||
/* If the cursor is not currently open or is open on a different
|
||||
** index, then fall through into OP_OpenRead to force a reopen */
|
||||
case OP_OpenRead:
|
||||
case OP_OpenRead: /* ncycle */
|
||||
case OP_OpenWrite:
|
||||
|
||||
assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ );
|
||||
@ -4247,7 +4247,7 @@ open_cursor_set_hints:
|
||||
**
|
||||
** Duplicate ephemeral cursors are used for self-joins of materialized views.
|
||||
*/
|
||||
case OP_OpenDup: {
|
||||
case OP_OpenDup: { /* ncycle */
|
||||
VdbeCursor *pOrig; /* The original cursor to be duplicated */
|
||||
VdbeCursor *pCx; /* The new cursor */
|
||||
|
||||
@ -4309,8 +4309,8 @@ case OP_OpenDup: {
|
||||
** by this opcode will be used for automatically created transient
|
||||
** indices in joins.
|
||||
*/
|
||||
case OP_OpenAutoindex:
|
||||
case OP_OpenEphemeral: {
|
||||
case OP_OpenAutoindex: /* ncycle */
|
||||
case OP_OpenEphemeral: { /* ncycle */
|
||||
VdbeCursor *pCx;
|
||||
KeyInfo *pKeyInfo;
|
||||
|
||||
@ -4468,7 +4468,7 @@ case OP_OpenPseudo: {
|
||||
** Close a cursor previously opened as P1. If P1 is not
|
||||
** currently open, this instruction is a no-op.
|
||||
*/
|
||||
case OP_Close: {
|
||||
case OP_Close: { /* ncycle */
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||
sqlite3VdbeFreeCursor(p, p->apCsr[pOp->p1]);
|
||||
p->apCsr[pOp->p1] = 0;
|
||||
@ -4585,10 +4585,10 @@ case OP_ColumnsUsed: {
|
||||
**
|
||||
** See also: Found, NotFound, SeekGt, SeekGe, SeekLt
|
||||
*/
|
||||
case OP_SeekLT: /* jump, in3, group */
|
||||
case OP_SeekLE: /* jump, in3, group */
|
||||
case OP_SeekGE: /* jump, in3, group */
|
||||
case OP_SeekGT: { /* jump, in3, group */
|
||||
case OP_SeekLT: /* jump, in3, group, ncycle */
|
||||
case OP_SeekLE: /* jump, in3, group, ncycle */
|
||||
case OP_SeekGE: /* jump, in3, group, ncycle */
|
||||
case OP_SeekGT: { /* jump, in3, group, ncycle */
|
||||
int res; /* Comparison result */
|
||||
int oc; /* Opcode */
|
||||
VdbeCursor *pC; /* The cursor to seek */
|
||||
@ -4854,7 +4854,7 @@ seek_not_found:
|
||||
** jump to SeekOP.P2 if This.P5==0 or to This.P2 if This.P5>0.
|
||||
** </ol>
|
||||
*/
|
||||
case OP_SeekScan: {
|
||||
case OP_SeekScan: { /* ncycle */
|
||||
VdbeCursor *pC;
|
||||
int res;
|
||||
int nStep;
|
||||
@ -4976,7 +4976,7 @@ case OP_SeekScan: {
|
||||
**
|
||||
** P1 must be a valid b-tree cursor.
|
||||
*/
|
||||
case OP_SeekHit: {
|
||||
case OP_SeekHit: { /* ncycle */
|
||||
VdbeCursor *pC;
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||
pC = p->apCsr[pOp->p1];
|
||||
@ -5108,7 +5108,7 @@ case OP_IfNotOpen: { /* jump */
|
||||
**
|
||||
** See also: NotFound, Found, NotExists
|
||||
*/
|
||||
case OP_IfNoHope: { /* jump, in3 */
|
||||
case OP_IfNoHope: { /* jump, in3, ncycle */
|
||||
VdbeCursor *pC;
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||
pC = p->apCsr[pOp->p1];
|
||||
@ -5122,9 +5122,9 @@ case OP_IfNoHope: { /* jump, in3 */
|
||||
/* Fall through into OP_NotFound */
|
||||
/* no break */ deliberate_fall_through
|
||||
}
|
||||
case OP_NoConflict: /* jump, in3 */
|
||||
case OP_NotFound: /* jump, in3 */
|
||||
case OP_Found: { /* jump, in3 */
|
||||
case OP_NoConflict: /* jump, in3, ncycle */
|
||||
case OP_NotFound: /* jump, in3, ncycle */
|
||||
case OP_Found: { /* jump, in3, ncycle */
|
||||
int alreadyExists;
|
||||
int ii;
|
||||
VdbeCursor *pC;
|
||||
@ -5254,7 +5254,7 @@ case OP_Found: { /* jump, in3 */
|
||||
**
|
||||
** See also: Found, NotFound, NoConflict, SeekRowid
|
||||
*/
|
||||
case OP_SeekRowid: { /* jump, in3 */
|
||||
case OP_SeekRowid: { /* jump, in3, ncycle */
|
||||
VdbeCursor *pC;
|
||||
BtCursor *pCrsr;
|
||||
int res;
|
||||
@ -5279,7 +5279,7 @@ case OP_SeekRowid: { /* jump, in3 */
|
||||
}
|
||||
/* Fall through into OP_NotExists */
|
||||
/* no break */ deliberate_fall_through
|
||||
case OP_NotExists: /* jump, in3 */
|
||||
case OP_NotExists: /* jump, in3, ncycle */
|
||||
pIn3 = &aMem[pOp->p3];
|
||||
assert( (pIn3->flags & MEM_Int)!=0 || pOp->opcode==OP_SeekRowid );
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||
@ -5903,7 +5903,7 @@ case OP_RowData: {
|
||||
** be a separate OP_VRowid opcode for use with virtual tables, but this
|
||||
** one opcode now works for both table types.
|
||||
*/
|
||||
case OP_Rowid: { /* out2 */
|
||||
case OP_Rowid: { /* out2, ncycle */
|
||||
VdbeCursor *pC;
|
||||
i64 v;
|
||||
sqlite3_vtab *pVtab;
|
||||
@ -6002,8 +6002,8 @@ case OP_NullRow: {
|
||||
** from the end toward the beginning. In other words, the cursor is
|
||||
** configured to use Prev, not Next.
|
||||
*/
|
||||
case OP_SeekEnd:
|
||||
case OP_Last: { /* jump */
|
||||
case OP_SeekEnd: /* ncycle */
|
||||
case OP_Last: { /* jump, ncycle */
|
||||
VdbeCursor *pC;
|
||||
BtCursor *pCrsr;
|
||||
int res;
|
||||
@ -6108,7 +6108,7 @@ case OP_Sort: { /* jump */
|
||||
** from the beginning toward the end. In other words, the cursor is
|
||||
** configured to use Next, not Prev.
|
||||
*/
|
||||
case OP_Rewind: { /* jump */
|
||||
case OP_Rewind: { /* jump, ncycle */
|
||||
VdbeCursor *pC;
|
||||
BtCursor *pCrsr;
|
||||
int res;
|
||||
@ -6202,7 +6202,7 @@ case OP_SorterNext: { /* jump */
|
||||
rc = sqlite3VdbeSorterNext(db, pC);
|
||||
goto next_tail;
|
||||
|
||||
case OP_Prev: /* jump */
|
||||
case OP_Prev: /* jump, ncycle */
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||
assert( pOp->p5==0
|
||||
|| pOp->p5==SQLITE_STMTSTATUS_FULLSCAN_STEP
|
||||
@ -6217,7 +6217,7 @@ case OP_Prev: /* jump */
|
||||
rc = sqlite3BtreePrevious(pC->uc.pCursor, pOp->p3);
|
||||
goto next_tail;
|
||||
|
||||
case OP_Next: /* jump */
|
||||
case OP_Next: /* jump, ncycle */
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||
assert( pOp->p5==0
|
||||
|| pOp->p5==SQLITE_STMTSTATUS_FULLSCAN_STEP
|
||||
@ -6409,8 +6409,8 @@ case OP_IdxDelete: {
|
||||
**
|
||||
** See also: Rowid, MakeRecord.
|
||||
*/
|
||||
case OP_DeferredSeek:
|
||||
case OP_IdxRowid: { /* out2 */
|
||||
case OP_DeferredSeek: /* ncycle */
|
||||
case OP_IdxRowid: { /* out2, ncycle */
|
||||
VdbeCursor *pC; /* The P1 index cursor */
|
||||
VdbeCursor *pTabCur; /* The P2 table cursor (OP_DeferredSeek only) */
|
||||
i64 rowid; /* Rowid that P1 current points to */
|
||||
@ -6472,8 +6472,8 @@ case OP_IdxRowid: { /* out2 */
|
||||
** seek operation now, without further delay. If the cursor seek has
|
||||
** already occurred, this instruction is a no-op.
|
||||
*/
|
||||
case OP_FinishSeek: {
|
||||
VdbeCursor *pC; /* The P1 index cursor */
|
||||
case OP_FinishSeek: { /* ncycle */
|
||||
VdbeCursor *pC; /* The P1 index cursor */
|
||||
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||
pC = p->apCsr[pOp->p1];
|
||||
@ -6528,10 +6528,10 @@ case OP_FinishSeek: {
|
||||
** If the P1 index entry is less than or equal to the key value then jump
|
||||
** to P2. Otherwise fall through to the next instruction.
|
||||
*/
|
||||
case OP_IdxLE: /* jump */
|
||||
case OP_IdxGT: /* jump */
|
||||
case OP_IdxLT: /* jump */
|
||||
case OP_IdxGE: { /* jump */
|
||||
case OP_IdxLE: /* jump, ncycle */
|
||||
case OP_IdxGT: /* jump, ncycle */
|
||||
case OP_IdxLT: /* jump, ncycle */
|
||||
case OP_IdxGE: { /* jump, ncycle */
|
||||
VdbeCursor *pC;
|
||||
int res;
|
||||
UnpackedRecord r;
|
||||
@ -7952,7 +7952,7 @@ case OP_VDestroy: {
|
||||
** P1 is a cursor number. This opcode opens a cursor to the virtual
|
||||
** table and stores that cursor in P1.
|
||||
*/
|
||||
case OP_VOpen: {
|
||||
case OP_VOpen: { /* ncycle */
|
||||
VdbeCursor *pCur;
|
||||
sqlite3_vtab_cursor *pVCur;
|
||||
sqlite3_vtab *pVtab;
|
||||
@ -7999,7 +7999,7 @@ case OP_VOpen: {
|
||||
** cursor. Register P3 is used to hold the values returned by
|
||||
** sqlite3_vtab_in_first() and sqlite3_vtab_in_next().
|
||||
*/
|
||||
case OP_VInitIn: { /* out2 */
|
||||
case OP_VInitIn: { /* out2, ncycle */
|
||||
VdbeCursor *pC; /* The cursor containing the RHS values */
|
||||
ValueList *pRhs; /* New ValueList object to put in reg[P2] */
|
||||
|
||||
@ -8036,7 +8036,7 @@ case OP_VInitIn: { /* out2 */
|
||||
**
|
||||
** A jump is made to P2 if the result set after filtering would be empty.
|
||||
*/
|
||||
case OP_VFilter: { /* jump */
|
||||
case OP_VFilter: { /* jump, ncycle */
|
||||
int nArg;
|
||||
int iQuery;
|
||||
const sqlite3_module *pModule;
|
||||
@ -8096,7 +8096,7 @@ case OP_VFilter: { /* jump */
|
||||
** bits (OPFLAG_LENGTHARG or OPFLAG_TYPEOFARG) but those bits are
|
||||
** unused by OP_VColumn.
|
||||
*/
|
||||
case OP_VColumn: {
|
||||
case OP_VColumn: { /* ncycle */
|
||||
sqlite3_vtab *pVtab;
|
||||
const sqlite3_module *pModule;
|
||||
Mem *pDest;
|
||||
@ -8148,7 +8148,7 @@ case OP_VColumn: {
|
||||
** jump to instruction P2. Or, if the virtual table has reached
|
||||
** the end of its result set, then fall through to the next instruction.
|
||||
*/
|
||||
case OP_VNext: { /* jump */
|
||||
case OP_VNext: { /* jump, ncycle */
|
||||
sqlite3_vtab *pVtab;
|
||||
const sqlite3_module *pModule;
|
||||
int res;
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "vdbeInt.h"
|
||||
#include "opcodes.h"
|
||||
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
/*
|
||||
@ -2225,10 +2226,7 @@ int sqlite3_stmt_scanstatus_v2(
|
||||
for(iOp=0; iOp<p->nOp; iOp++){
|
||||
Op *pOp = &p->aOp[iOp];
|
||||
if( pOp->p1!=iEnd ) continue;
|
||||
if( pOp->opcode!=OP_VFilter && pOp->opcode!=OP_VColumn
|
||||
&& pOp->opcode!=OP_Rowid && pOp->opcode!=OP_VOpen
|
||||
&& pOp->opcode!=OP_VNext
|
||||
){
|
||||
if( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_NCYCLE)==0 ){
|
||||
continue;
|
||||
}
|
||||
res += p->anCycle[iOp];
|
||||
|
@ -294,16 +294,26 @@ void sqlite3WhereAddScanStatus(
|
||||
){
|
||||
const char *zObj = 0;
|
||||
WhereLoop *pLoop = pLvl->pWLoop;
|
||||
if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 && pLoop->u.btree.pIndex!=0 ){
|
||||
int wsFlags = pLoop->wsFlags;
|
||||
int viaCoroutine = 0;
|
||||
|
||||
if( (wsFlags & WHERE_VIRTUALTABLE)==0 && pLoop->u.btree.pIndex!=0 ){
|
||||
zObj = pLoop->u.btree.pIndex->zName;
|
||||
}else{
|
||||
zObj = pSrclist->a[pLvl->iFrom].zName;
|
||||
viaCoroutine = pSrclist->a[pLvl->iFrom].fg.viaCoroutine;
|
||||
}
|
||||
sqlite3VdbeScanStatus(
|
||||
v, addrExplain, pLvl->addrBody, pLvl->addrVisit, pLoop->nOut, zObj
|
||||
);
|
||||
if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){
|
||||
sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iTabCur);
|
||||
|
||||
if( viaCoroutine==0 ){
|
||||
if( (wsFlags & (WHERE_MULTI_OR|WHERE_AUTO_INDEX))==0 ){
|
||||
sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iTabCur);
|
||||
}
|
||||
if( wsFlags & WHERE_INDEXED ){
|
||||
sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iIdxCur);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -88,8 +88,8 @@ proc get_graph {stmt} {
|
||||
proc do_graph_test {tn sql res} {
|
||||
db eval $sql
|
||||
set stmt [db version -last-stmt-ptr]
|
||||
|
||||
set graph [string trim [get_graph $stmt]]
|
||||
|
||||
set graph [regsub -all {nCycle=[0-9]+} $graph nCycle=nnn]
|
||||
uplevel [list do_test $tn [list set {} $graph] [string trim $res]]
|
||||
}
|
||||
@ -119,9 +119,9 @@ do_graph_test 1.3 {
|
||||
SELECT (SELECT a FROM t1 WHERE b=x) FROM t2 WHERE y=2
|
||||
} {
|
||||
QUERY (nCycle=nnn)
|
||||
--SCAN t2
|
||||
--SCAN t2 (nCycle=nnn)
|
||||
--CORRELATED SCALAR SUBQUERY 1 (nCycle=nnn)
|
||||
----SCAN t1
|
||||
----SCAN t1 (nCycle=nnn)
|
||||
}
|
||||
|
||||
do_graph_test 1.4 {
|
||||
@ -132,9 +132,9 @@ do_graph_test 1.4 {
|
||||
} {
|
||||
QUERY (nCycle=nnn)
|
||||
--MATERIALIZE v2 (nCycle=nnn)
|
||||
----SCAN t2
|
||||
--SCAN v2
|
||||
--SCAN t1
|
||||
----SCAN t2 (nCycle=nnn)
|
||||
--SCAN v2 (nCycle=nnn)
|
||||
--SCAN t1 (nCycle=nnn)
|
||||
--USE TEMP B-TREE FOR ORDER BY (nCycle=nnn)
|
||||
}
|
||||
|
||||
@ -154,6 +154,25 @@ QUERY (nCycle=nnn)
|
||||
--SCAN ft VIRTUAL TABLE INDEX 0:M1 (nCycle=nnn)
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 3.0 {
|
||||
CREATE TABLE x1(a, b);
|
||||
CREATE TABLE x2(c, d);
|
||||
|
||||
WITH s(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1000)
|
||||
INSERT INTO x1 SELECT i, i FROM s;
|
||||
INSERT INTO x2 SELECT a, b FROM x1;
|
||||
}
|
||||
|
||||
do_graph_test 2.1 {
|
||||
SELECT * FROM x1, x2 WHERE c=+a;
|
||||
} {
|
||||
QUERY (nCycle=nnn)
|
||||
--SCAN x1 (nCycle=nnn)
|
||||
--SEARCH x2 USING AUTOMATIC COVERING INDEX (c=?) (nCycle=nnn)
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
|
@ -86,6 +86,7 @@ while {![eof $in]} {
|
||||
set in3($name) 0
|
||||
set out2($name) 0
|
||||
set out3($name) 0
|
||||
set ncycle($name) 0
|
||||
for {set i 3} {$i<[llength $line]-1} {incr i} {
|
||||
switch [string trim [lindex $line $i] ,] {
|
||||
same {
|
||||
@ -107,6 +108,7 @@ while {![eof $in]} {
|
||||
in3 {set in3($name) 1}
|
||||
out2 {set out2($name) 1}
|
||||
out3 {set out3($name) 1}
|
||||
ncycle {set ncycle($name) 1}
|
||||
}
|
||||
}
|
||||
if {$group($name)} {
|
||||
@ -140,6 +142,7 @@ foreach name {OP_Noop OP_Explain OP_Abortable} {
|
||||
set in3($name) 0
|
||||
set out2($name) 0
|
||||
set out3($name) 0
|
||||
set ncycle($name) 0
|
||||
set op($name) -1
|
||||
set order($nOp) $name
|
||||
incr nOp
|
||||
@ -285,6 +288,7 @@ for {set i 0} {$i<=$max} {incr i} {
|
||||
if {$in3($name)} {incr x 8}
|
||||
if {$out2($name)} {incr x 16}
|
||||
if {$out3($name)} {incr x 32}
|
||||
if {$ncycle($name)} {incr x 64}
|
||||
}
|
||||
set bv($i) $x
|
||||
}
|
||||
@ -299,6 +303,7 @@ puts "#define OPFLG_IN2 0x04 /* in2: P2 is an input */"
|
||||
puts "#define OPFLG_IN3 0x08 /* in3: P3 is an input */"
|
||||
puts "#define OPFLG_OUT2 0x10 /* out2: P2 is an output */"
|
||||
puts "#define OPFLG_OUT3 0x20 /* out3: P3 is an output */"
|
||||
puts "#define OPFLG_NCYCLE 0x40 /* ncycle:Cycles count against P1 */"
|
||||
puts "#define OPFLG_INITIALIZER \173\\"
|
||||
for {set i 0} {$i<=$max} {incr i} {
|
||||
if {$i%8==0} {
|
||||
|
Loading…
x
Reference in New Issue
Block a user