aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2016-05-26 20:56:38 +0000
committerdrh <drh@noemail.net>2016-05-26 20:56:38 +0000
commiteeb9565a3e3397340a4dc79a8b693e35cdecfb7c (patch)
treea054e5793db17e2467c972bebaf97c3a7c72a3d8
parentce3c5011d9325adf3546505c45d40243db6e7eee (diff)
downloadsqlite-eeb9565a3e3397340a4dc79a8b693e35cdecfb7c.tar.gz
sqlite-eeb9565a3e3397340a4dc79a8b693e35cdecfb7c.zip
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
-rw-r--r--manifest18
-rw-r--r--manifest.uuid2
-rw-r--r--src/expr.c3
-rw-r--r--src/pragma.c4
-rw-r--r--src/vdbe.c50
-rw-r--r--src/wherecode.c3
6 files changed, 57 insertions, 23 deletions
diff --git a/manifest b/manifest
index 6e33cdaa4..88f7d0cd5 100644
--- a/manifest
+++ b/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
diff --git a/manifest.uuid b/manifest.uuid
index b182bd8e8..9a103ac06 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-2a41f098b2f0523b3d7e6eba6ae91cc0d30752df \ No newline at end of file
+ffe80a1bfa014943a614fc6993c1749b9bfec4c1 \ No newline at end of file
diff --git a/src/expr.c b/src/expr.c
index 9e3b664e8..156db96fa 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -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.
diff --git a/src/pragma.c b/src/pragma.c
index 330e99909..56823c724 100644
--- a/src/pragma.c
+++ b/src/pragma.c
@@ -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{
diff --git a/src/vdbe.c b/src/vdbe.c
index d512c0bc7..d4392a89d 100644
--- a/src/vdbe.c
+++ b/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,15 +4068,22 @@ 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 );
pC = p->apCsr[pOp->p1];
@@ -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().
diff --git a/src/wherecode.c b/src/wherecode.c
index 054b1b107..83ee48ac6 100644
--- a/src/wherecode.c
+++ b/src/wherecode.c
@@ -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);