Add the new OP_BeginSubrtn opcode (which is really an alias for OP_Integer)

and make other changes so that the span of a subroutine that implements
a subquery is more readily apparent in bytecode listings.

FossilOrigin-Name: b8226748709de37cfc86414714c20567254e5b320b380e767c322dba69a79d49
This commit is contained in:
drh 2022-03-03 15:00:44 +00:00
parent 5694569591
commit 1902516d16
4 changed files with 35 additions and 16 deletions

View File

@ -1,5 +1,5 @@
C Bloom\sfilter\spull-down\soptimization\sis\sincompatible\swith\sSkip-Scan.\nMake\ssure\sthe\squery\splanner\sdoes\snot\stry\sto\sto\sboth.\n[forum:/info/50a1bbe08ce4c29c|Forum\spost\s50a1bbe08ce4c29c].
D 2022-03-02T21:04:10.291
C Add\sthe\snew\sOP_BeginSubrtn\sopcode\s(which\sis\sreally\san\salias\sfor\sOP_Integer)\nand\smake\sother\schanges\sso\sthat\sthe\sspan\sof\sa\ssubroutine\sthat\simplements\na\ssubquery\sis\smore\sreadily\sapparent\sin\sbytecode\slistings.
D 2022-03-03T15:00:44.258
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@ -503,7 +503,7 @@ F src/date.c 1abbd739ae1d3fc8e0aaff995f57332af10d0b332728e4d3f241c494515495f0
F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d
F src/delete.c b5f1716b4d723db48254ee0f896e362cd029e865e05414139ea7f539f3884e1d
F src/expr.c b90a029105a93a93a0ed5e5f8c5eaed8f19043a3b62e4c4d235a4611d9ada178
F src/expr.c 3cdb00b6c15f815c94836e7b4474b675155d1279e64804f6ab5816188a9b05b6
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c 06e4ac33031b02dde7130c12e79cddf4dc5cfa72b23d8e63a3c26878fc9c1d3c
F src/func.c f801c6bc8b30afea51817d86a6c46259d3cca180c612cfa0a30b18d661e9c8df
@ -624,7 +624,7 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23
F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3
F src/vdbe.c d2cf2ef62b51aedab4d9df4b9980f70f95c7ab294ff6e56478067630b7c5c5eb
F src/vdbe.c 62282c976aedf02603368d8d20d33cb7c8c214a34538f39da028d3e0c2aa6e16
F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e
F src/vdbeInt.h 8dd91427155a38ec06e9ecbde07e33f21bc02e101625191e7613f883e379a363
F src/vdbeapi.c 1c80efbe51118bbecc7279023e75d18edcfa4b3dc441287e1718ee70ad594f58
@ -1944,8 +1944,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 86c5fa2f301e4bdb538099f654b70b6ba0e214778cba2c53c53844e5d7ca129f
R ce130c74174cec9891d61458e25bf794
P ad3ffa1a75a5a032ebb64d8e014ee0a85c5e44b732e4b11bd67f31a59e729b94
R cf617415d744f05eb16874e90dfd5f1d
U drh
Z d775ec6037256eae49bb0d3cd795e9f6
Z c1aa9fa8cb20b2f538a49ebe46b0f2e7
# Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
ad3ffa1a75a5a032ebb64d8e014ee0a85c5e44b732e4b11bd67f31a59e729b94
b8226748709de37cfc86414714c20567254e5b320b380e767c322dba69a79d49

View File

@ -3040,8 +3040,7 @@ void sqlite3CodeRhsOfIN(
assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
pExpr->y.sub.regReturn = ++pParse->nMem;
pExpr->y.sub.iAddr =
sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
VdbeComment((v, "return address"));
sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1;
addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
}
@ -3143,6 +3142,7 @@ void sqlite3CodeRhsOfIN(
** expression we need to rerun this code each time.
*/
if( addrOnce && !sqlite3ExprIsConstant(pE2) ){
sqlite3VdbeChangeToNoop(v, addrOnce-1);
sqlite3VdbeChangeToNoop(v, addrOnce);
ExprClearProperty(pExpr, EP_Subrtn);
addrOnce = 0;
@ -3163,7 +3163,10 @@ void sqlite3CodeRhsOfIN(
sqlite3VdbeJumpHere(v, addrOnce);
/* Subroutine return */
assert( ExprUseYSub(pExpr) );
sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn
|| pParse->nErr );
sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, 0,
pExpr->y.sub.iAddr-1);
sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
sqlite3ClearTempRegCache(pParse);
}
@ -3218,9 +3221,7 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
ExprSetProperty(pExpr, EP_Subrtn);
pExpr->y.sub.regReturn = ++pParse->nMem;
pExpr->y.sub.iAddr =
sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
VdbeComment((v, "return address"));
sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1;
/* The evaluation of the EXISTS/SELECT must be repeated every time it
** is encountered if any of the following is true:
@ -3293,7 +3294,10 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
/* Subroutine return */
assert( ExprUseYSub(pExpr) );
sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn
|| pParse->nErr );
sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, 0,
pExpr->y.sub.iAddr-1);
sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
sqlite3ClearTempRegCache(pParse);
return rReg;

View File

@ -991,10 +991,14 @@ jump_to_p2:
break;
}
/* Opcode: Return P1 * * * *
/* Opcode: Return P1 * P3 * *
**
** Jump to the next instruction after the address in register P1. After
** the jump, register P1 becomes undefined.
**
** P3 is not used by the byte-code engine. However, the code generator
** sets P3 to address of the associated OP_BeginSubrtn opcode, if there is
** one.
*/
case OP_Return: { /* in1 */
pIn1 = &aMem[pOp->p1];
@ -1182,11 +1186,22 @@ case OP_Halt: {
goto vdbe_return;
}
/* Opcode: BeginSubrtn P1 P2 * * *
** Synopsis: r[P2]=P1
**
** Mark the beginning of a subroutine by loading the integer value P1
** into register r[P2]. The P2 register is used to store the return
** address of the subroutine call.
**
** This opcode is identical to OP_Integer. It has a different name
** only to make the byte code easier to read and verify.
*/
/* Opcode: Integer P1 P2 * * *
** Synopsis: r[P2]=P1
**
** The 32-bit integer value P1 is written into register P2.
*/
case OP_BeginSubrtn:
case OP_Integer: { /* out2 */
pOut = out2Prerelease(p, pOp);
pOut->u.i = pOp->p1;