Add a new OP_SeekRowid opcode, that combines the functions of OP_MustBeInt
and OP_NotExists. This makes the code slightly smaller and faster. FossilOrigin-Name: ffe80a1bfa014943a614fc6993c1749b9bfec4c1
This commit is contained in:
parent
ce3c5011d9
commit
eeb9565a3e
18
manifest
18
manifest
@ -1,5 +1,5 @@
|
||||
C Add\sthe\slibvers.c\stool\sin\sthe\stool/\ssubdirectory.
|
||||
D 2016-05-25T18:53:39.049
|
||||
C Add\sa\snew\sOP_SeekRowid\sopcode,\sthat\scombines\sthe\sfunctions\sof\sOP_MustBeInt\nand\sOP_NotExists.\s\sThis\smakes\sthe\scode\sslightly\ssmaller\sand\sfaster.
|
||||
D 2016-05-26T20:56:38.450
|
||||
F Makefile.in f59e0763ff448719fc1bd25513882b0567286317
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc 306d73e854b1a92ea06e5d1e637faa5c44de53c7
|
||||
@ -333,7 +333,7 @@ F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198
|
||||
F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39
|
||||
F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b
|
||||
F src/delete.c 4aba4214a377ce8ddde2d2e609777bcc8235200f
|
||||
F src/expr.c 8796c0739b2ad091e6779253f62aad6e767e2be1
|
||||
F src/expr.c 81bd7d87985746313770211183e900ed1ad28381
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb
|
||||
F src/func.c ef4c18c8a66143413ce41a58d582d2c14ddf78e1
|
||||
@ -372,7 +372,7 @@ F src/parse.y 10eb2f3fb62341291528c7984498054731f9d31e
|
||||
F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df
|
||||
F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490
|
||||
F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d
|
||||
F src/pragma.c 9fdce031ddcb57f0f56e4a8b421b7e7a77de73b0
|
||||
F src/pragma.c d98039af2deb5a4990f6635462b3f61f325a6c75
|
||||
F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c
|
||||
F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e
|
||||
F src/printf.c a5f0ca08ddede803c241266abb46356ec748ded1
|
||||
@ -445,7 +445,7 @@ F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd
|
||||
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
|
||||
F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d
|
||||
F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52
|
||||
F src/vdbe.c f2706d5564d2b2887a27c909e8e1575250029503
|
||||
F src/vdbe.c 45e4da739187028281e342f79fae0f4145055bec
|
||||
F src/vdbe.h 5591b5add447096e31288b5a0a78ec5d7b5c5170
|
||||
F src/vdbeInt.h ddb157974436d87652de7dc641f7191496d9a8cd
|
||||
F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c
|
||||
@ -461,7 +461,7 @@ F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c
|
||||
F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354
|
||||
F src/where.c 0e54a03d11d4e99ad25528f42ff4c9a6fa7a23da
|
||||
F src/whereInt.h 6e18240be400bef8e4dbafea605251707c5dbf49
|
||||
F src/wherecode.c e3f18fcda2d7f8218a09dc33cf495dca0efa6e3e
|
||||
F src/wherecode.c ba71a4e4bada29aa9842200e6299714bf18c812c
|
||||
F src/whereexpr.c eacc0e60d029a082b4fc0cc42ea98544add1319e
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
|
||||
@ -1495,7 +1495,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 41fd46e2962ba9a1e1f6867567499d1f6f5b8372
|
||||
R 871df33bb708dea5ddc1c61eb4854aa7
|
||||
P 2a41f098b2f0523b3d7e6eba6ae91cc0d30752df
|
||||
R 810bd747b437c6e4e76eef1099520866
|
||||
U drh
|
||||
Z b20c30dd356053a2351766a3c882aef8
|
||||
Z 73ea989f24641ac606e6e6c2f5b60872
|
||||
|
@ -1 +1 @@
|
||||
2a41f098b2f0523b3d7e6eba6ae91cc0d30752df
|
||||
ffe80a1bfa014943a614fc6993c1749b9bfec4c1
|
@ -2222,8 +2222,7 @@ static void sqlite3ExprCodeIN(
|
||||
if( eType==IN_INDEX_ROWID ){
|
||||
/* In this case, the RHS is the ROWID of table b-tree
|
||||
*/
|
||||
sqlite3VdbeAddOp2(v, OP_MustBeInt, r1, destIfFalse); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp3(v, OP_NotExists, pExpr->iTable, destIfFalse, r1);
|
||||
sqlite3VdbeAddOp3(v, OP_SeekRowid, pExpr->iTable, destIfFalse, r1);
|
||||
VdbeCoverage(v);
|
||||
}else{
|
||||
/* In this case, the RHS is an index b-tree.
|
||||
|
@ -1334,12 +1334,10 @@ void sqlite3Pragma(
|
||||
sqlite3VdbeAddOp3(v, OP_Column, 0, iKey, regRow);
|
||||
sqlite3ColumnDefault(v, pTab, iKey, regRow);
|
||||
sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_MustBeInt, regRow,
|
||||
sqlite3VdbeCurrentAddr(v)+3); VdbeCoverage(v);
|
||||
}else{
|
||||
sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow);
|
||||
}
|
||||
sqlite3VdbeAddOp3(v, OP_NotExists, i, 0, regRow); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp3(v, OP_SeekRowid, i, 0, regRow); VdbeCoverage(v);
|
||||
sqlite3VdbeGoto(v, addrOk);
|
||||
sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
|
||||
}else{
|
||||
|
50
src/vdbe.c
50
src/vdbe.c
@ -4023,6 +4023,30 @@ case OP_Found: { /* jump, in3 */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: SeekRowid P1 P2 P3 * *
|
||||
** Synopsis: intkey=r[P3]
|
||||
**
|
||||
** P1 is the index of a cursor open on an SQL table btree (with integer
|
||||
** keys). If register P3 does not contain an integer or if P1 does not
|
||||
** contain a record with rowid P3 then jump immediately to P2.
|
||||
** Or, if P2 is 0, raise an SQLITE_CORRUPT error. If P1 does contain
|
||||
** a record with rowid P3 then
|
||||
** leave the cursor pointing at that record and fall through to the next
|
||||
** instruction.
|
||||
**
|
||||
** The OP_NotExists opcode performs the same operation, but with OP_NotExists
|
||||
** the P3 register must be guaranteed to contain an integer value. With this
|
||||
** opcode, register P3 might not contain an integer.
|
||||
**
|
||||
** The OP_NotFound opcode performs the same operation on index btrees
|
||||
** (with arbitrary multi-value keys).
|
||||
**
|
||||
** This opcode leaves the cursor in a state where it cannot be advanced
|
||||
** in either direction. In other words, the Next and Prev opcodes will
|
||||
** not work following this opcode.
|
||||
**
|
||||
** See also: Found, NotFound, NoConflict, SeekRowid
|
||||
*/
|
||||
/* Opcode: NotExists P1 P2 P3 * *
|
||||
** Synopsis: intkey=r[P3]
|
||||
**
|
||||
@ -4033,6 +4057,10 @@ case OP_Found: { /* jump, in3 */
|
||||
** leave the cursor pointing at that record and fall through to the next
|
||||
** instruction.
|
||||
**
|
||||
** The OP_SeekRowid opcode performs the same operation but also allows the
|
||||
** P3 register to contain a non-integer value, in which case the jump is
|
||||
** always taken. This opcode requires that P3 always contain an integer.
|
||||
**
|
||||
** The OP_NotFound opcode performs the same operation on index btrees
|
||||
** (with arbitrary multi-value keys).
|
||||
**
|
||||
@ -4040,14 +4068,21 @@ case OP_Found: { /* jump, in3 */
|
||||
** in either direction. In other words, the Next and Prev opcodes will
|
||||
** not work following this opcode.
|
||||
**
|
||||
** See also: Found, NotFound, NoConflict
|
||||
** See also: Found, NotFound, NoConflict, SeekRowid
|
||||
*/
|
||||
case OP_NotExists: { /* jump, in3 */
|
||||
case OP_SeekRowid: { /* jump, in3 */
|
||||
VdbeCursor *pC;
|
||||
BtCursor *pCrsr;
|
||||
int res;
|
||||
u64 iKey;
|
||||
|
||||
pIn3 = &aMem[pOp->p3];
|
||||
if( (pIn3->flags & MEM_Int)==0 ){
|
||||
applyAffinity(pIn3, SQLITE_AFF_NUMERIC, encoding);
|
||||
if( (pIn3->flags & MEM_Int)==0 ) goto jump_to_p2;
|
||||
}
|
||||
/* Fall through into OP_NotExists */
|
||||
case OP_NotExists: /* jump, in3 */
|
||||
pIn3 = &aMem[pOp->p3];
|
||||
assert( pIn3->flags & MEM_Int );
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||
@ -4250,10 +4285,12 @@ case OP_NewRowid: { /* out2 */
|
||||
** sqlite3_last_insert_rowid() function (otherwise it is unmodified).
|
||||
**
|
||||
** If the OPFLAG_USESEEKRESULT flag of P5 is set and if the result of
|
||||
** the last seek operation (OP_NotExists) was a success, then this
|
||||
** the last seek operation (OP_NotExists or OP_SeekRowid) was a success,
|
||||
** then this
|
||||
** operation will not attempt to find the appropriate row before doing
|
||||
** the insert but will instead overwrite the row that the cursor is
|
||||
** currently pointing to. Presumably, the prior OP_NotExists opcode
|
||||
** currently pointing to. Presumably, the prior OP_NotExists or
|
||||
** OP_SeekRowid opcode
|
||||
** has already positioned the cursor correctly. This is an optimization
|
||||
** that boosts performance by avoiding redundant seeks.
|
||||
**
|
||||
@ -4611,8 +4648,9 @@ case OP_RowData: {
|
||||
pCrsr = pC->uc.pCursor;
|
||||
|
||||
/* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or
|
||||
** OP_Rewind/Op_Next with no intervening instructions that might invalidate
|
||||
** the cursor. If this where not the case, on of the following assert()s
|
||||
** OP_SeekRowid or OP_Rewind/Op_Next with no intervening instructions
|
||||
** that might invalidate the cursor.
|
||||
** If this where not the case, on of the following assert()s
|
||||
** would fail. Should this ever change (because of changes in the code
|
||||
** generator) then the fix would be to insert a call to
|
||||
** sqlite3VdbeCursorMoveto().
|
||||
|
@ -971,8 +971,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
|
||||
if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg);
|
||||
addrNxt = pLevel->addrNxt;
|
||||
sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt); VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg);
|
||||
sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg);
|
||||
VdbeCoverage(v);
|
||||
sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1);
|
||||
sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
|
||||
|
Loading…
Reference in New Issue
Block a user