diff --git a/manifest b/manifest index 514232a7c7..5543cf3302 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\slocal\svariable\sfrom\sOP_Column,\sfor\sa\ssmall\ssize\nreduction\sand\sperformance\sincrease. -D 2017-08-16T14:16:19.879 +C Avoid\sa\stest\sfor\sCURTYPE_BTREE\sin\ssqlite3VdbeCursorMoveto()\sin\sorder\sto\sreduce\nthe\ssize\sand\simprove\sthe\sperformance\sof\sOP_Column. +D 2017-08-16T19:20:20.392 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -397,9 +397,9 @@ F src/auth.c 79f96c6f33bf0e5da8d1c282cee5ebb1852bb8a6ccca3e485d7c459b035d9c3c F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c d2f5f347e56f8b7ed1bb798087045a3b98cd63f45fde7675fd24b9e88b61304d -F src/btree.h 3edc5329bc59534d2d15b4f069a9f54b779a7e51289e98fa481ae3c0e526a5ca -F src/btreeInt.h f78671f594dafd88cf9a81253da04db81272b382d2dc074bb983d348b95d9d2d +F src/btree.c e1a98bef27d6189df5c5b8b3c9b5e53d6b74bf9a936af97757c21e9ea6a5c6b2 +F src/btree.h 32ef5d3f25dc70ef1ee9cecf84a023c21378f06a57cd701d2e866e141b150f09 +F src/btreeInt.h 55b702efce17e5d1941865464227d3802cfc9c7c832fac81d4c94dced47a71fc F src/build.c f8a85d2ad14c2201e10c2fe7185e1cb3f1db8b0c90d40d1fb99c20b135ab71bc F src/callback.c 930648a084a3adc741c6471adfbdc50ba47ba3542421cb80a26f259f467de65e F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e @@ -522,11 +522,11 @@ F src/update.c 5404be9e840717323a69209190cdbc9d0d34adaedaaf1d1a1069babf2c4171c0 F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5 F src/util.c fc081ec6f63448dcd80d3dfad35baecfa104823254a815b081a4d9fe76e1db23 F src/vacuum.c 90839322fd5f00df9617eb21b68beda9b6e2a2937576b0d65985e4aeb1c53739 -F src/vdbe.c c8e7bec8764b26b8e80fadffab2b9c18e8ed5ab2e92d1be5a7aebeed18ca8be5 +F src/vdbe.c 711a1b2c0a6046483ebf4ac43c4c0ea5bef3e50534a4ab9e1d7e3542635cd009 F src/vdbe.h d50cadf12bcf9fb99117ef392ce1ea283aa429270481426b6e8b0280c101fd97 -F src/vdbeInt.h ff2b7db0968d20e6184aee256d2e535d565f5a172e3588a78adb166a41fc4911 +F src/vdbeInt.h 1fe00770144c12c4913128f35262d11527ef3284561baaab59b947a41c08d0d9 F src/vdbeapi.c 05d6b14ab73952db0d73f6452d6960216997bd966a710266b2fe051f25326abc -F src/vdbeaux.c 1bef372f59f9e1dba5ead70cc5c24bf978bab0b9fdc2f69692afaa3a2d4dd8f3 +F src/vdbeaux.c 1f15018ef7abe22669967f70b02bfe6709be403f126f713dabb091b9d631859a F src/vdbeblob.c db3cf91060f6f4b2f1358a4200e844697990752177784c7c95da00b7ac9f1c7b F src/vdbemem.c b7fac20534c79b7554dab2e8a180c585a8bc1b9c85149d1b2d9746cf314d06ed F src/vdbesort.c fea2bea25f5e9ccd91e0760d7359f0365f9fba1aaeac7216c71cad78765f58e3 @@ -1647,7 +1647,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 dc98a92f32511ee322b0207bd286e967248a8e59b418f11168eb31e34b0fa0fa -R 8dc9658e95fe266a68d077704d4afe1a +P 39543903282409ad3f139f8a0bb376661e7595a33af4f647945b1513a028ccb4 +R 6446f3c323d2c08f3899473bfc8c1574 U drh -Z 4fdaa02107e5a271b3b6d501790c7a7c +Z 68326b6d5ed2188a1ee820e19559d5ac diff --git a/manifest.uuid b/manifest.uuid index e7180c4267..eb2dc719d5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -39543903282409ad3f139f8a0bb376661e7595a33af4f647945b1513a028ccb4 \ No newline at end of file +f078deb25149b7b1881b7f3374b343d0677e82336d8fdd7f1cdd06d926b5dd57 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 50981b0575..ecdbb6d0a3 100644 --- a/src/btree.c +++ b/src/btree.c @@ -838,6 +838,17 @@ int sqlite3BtreeCursorHasMoved(BtCursor *pCur){ return pCur->eState!=CURSOR_VALID; } +/* +** Return a pointer to a fake BtCursor object that will always answer +** false to the sqlite3BtreeCursorHasMoved() routine above. The fake +** cursor returned must not be used with any other Btree interface. +*/ +BtCursor *sqlite3BtreeFakeValidCursor(void){ + static u8 fakeCursor = CURSOR_VALID; + assert( offsetof(BtCursor, eState)==0 ); + return (BtCursor*)&fakeCursor; +} + /* ** This routine restores a cursor back to its original position after it ** has been moved by some outside activity (such as a btree rebalance or diff --git a/src/btree.h b/src/btree.h index b56eb85e68..e2c271cdc5 100644 --- a/src/btree.h +++ b/src/btree.h @@ -230,6 +230,7 @@ int sqlite3BtreeCursor( struct KeyInfo*, /* First argument to compare function */ BtCursor *pCursor /* Space to write cursor structure */ ); +BtCursor *sqlite3BtreeFakeValidCursor(void); int sqlite3BtreeCursorSize(void); void sqlite3BtreeCursorZero(BtCursor*); void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned); diff --git a/src/btreeInt.h b/src/btreeInt.h index f4e5f45fec..ac7a3c0a26 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -499,6 +499,11 @@ struct CellInfo { ** eState==FAULT: Cursor fault with skipNext as error code. */ struct BtCursor { + u8 eState; /* One of the CURSOR_XXX constants (see below) */ + u8 curFlags; /* zero or more BTCF_* flags defined below */ + u8 curPagerFlags; /* Flags to send to sqlite3PagerGet() */ + u8 hints; /* As configured by CursorSetHints() */ + int nOvflAlloc; /* Allocated size of aOverflow[] array */ Btree *pBtree; /* The Btree to which this cursor belongs */ BtShared *pBt; /* The BtShared this cursor points to */ BtCursor *pNext; /* Forms a linked list of all cursors */ @@ -507,13 +512,8 @@ struct BtCursor { i64 nKey; /* Size of pKey, or last integer key */ void *pKey; /* Saved key that was cursor last known position */ Pgno pgnoRoot; /* The root page of this tree */ - int nOvflAlloc; /* Allocated size of aOverflow[] array */ int skipNext; /* Prev() is noop if negative. Next() is noop if positive. ** Error code if eState==CURSOR_FAULT */ - u8 curFlags; /* zero or more BTCF_* flags defined below */ - u8 curPagerFlags; /* Flags to send to sqlite3PagerGet() */ - u8 eState; /* One of the CURSOR_XXX constants (see below) */ - u8 hints; /* As configured by CursorSetHints() */ /* All fields above are zeroed when the cursor is allocated. See ** sqlite3BtreeCursorZero(). Fields that follow must be manually ** initialized. */ diff --git a/src/vdbe.c b/src/vdbe.c index a4665ce79c..3f5d967d2d 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2413,8 +2413,10 @@ case OP_Column: { if( pC->cacheStatus!=p->cacheCtr ){ /*OPTIMIZATION-IF-FALSE*/ if( pC->nullRow ){ if( pC->eCurType==CURTYPE_PSEUDO ){ - assert( pC->uc.pseudoTableReg>0 ); - pReg = &aMem[pC->uc.pseudoTableReg]; + /* For the special case of as pseudo-cursor, the seekResult field + ** identifies the register that holds the record */ + assert( pC->seekResult>0 ); + pReg = &aMem[pC->seekResult]; assert( pReg->flags & MEM_Blob ); assert( memIsValid(pReg) ); pC->payloadSize = pC->szRow = pReg->n; @@ -3628,8 +3630,13 @@ case OP_OpenPseudo: { pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, CURTYPE_PSEUDO); if( pCx==0 ) goto no_mem; pCx->nullRow = 1; - pCx->uc.pseudoTableReg = pOp->p2; + pCx->seekResult = pOp->p2; pCx->isTable = 1; + /* Give this pseudo-cursor a fake BtCursor pointer so that pCx + ** can be safely passed to sqlite3VdbeCursorMoveto(). This avoids a test + ** for pCx->eCurType==CURTYPE_BTREE inside of sqlite3VdbeCursorMoveto() + ** which is a performance optimization */ + pCx->uc.pCursor = sqlite3BtreeFakeValidCursor(); assert( pOp->p5==0 ); break; } diff --git a/src/vdbeInt.h b/src/vdbeInt.h index d8e47be500..cb783653c0 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -96,18 +96,18 @@ struct VdbeCursor { u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ int seekResult; /* Result of previous sqlite3BtreeMoveto() or 0 ** if there have been no prior seeks on the cursor. */ - /* NB: seekResult does not distinguish between "no seeks have ever occurred - ** on this cursor" and "the most recent seek was an exact match". */ + /* seekResult does not distinguish between "no seeks have ever occurred + ** on this cursor" and "the most recent seek was an exact match". + ** For CURTYPE_PSEUDO, seekResult is the register holding the record */ /* When a new VdbeCursor is allocated, only the fields above are zeroed. ** The fields that follow are uninitialized, and must be individually ** initialized prior to first use. */ VdbeCursor *pAltCursor; /* Associated index cursor from which to read */ union { - BtCursor *pCursor; /* CURTYPE_BTREE. Btree cursor */ - sqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB. Vtab cursor */ - int pseudoTableReg; /* CURTYPE_PSEUDO. Reg holding content. */ - VdbeSorter *pSorter; /* CURTYPE_SORTER. Sorter object */ + BtCursor *pCursor; /* CURTYPE_BTREE or _PSEUDO. Btree cursor */ + sqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB. Vtab cursor */ + VdbeSorter *pSorter; /* CURTYPE_SORTER. Sorter object */ } uc; KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ u32 iHdrOffset; /* Offset to next unparsed byte of the header */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 226b2152ed..7f6632bfa4 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3139,19 +3139,18 @@ int sqlite3VdbeCursorRestore(VdbeCursor *p){ */ int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){ VdbeCursor *p = *pp; - if( p->eCurType==CURTYPE_BTREE ){ - if( p->deferredMoveto ){ - int iMap; - if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 ){ - *pp = p->pAltCursor; - *piCol = iMap - 1; - return SQLITE_OK; - } - return handleDeferredMoveto(p); - } - if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ - return handleMovedCursor(p); + assert( p->eCurType==CURTYPE_BTREE || p->eCurType==CURTYPE_PSEUDO ); + if( p->deferredMoveto ){ + int iMap; + if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 ){ + *pp = p->pAltCursor; + *piCol = iMap - 1; + return SQLITE_OK; } + return handleDeferredMoveto(p); + } + if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ + return handleMovedCursor(p); } return SQLITE_OK; }