mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-11 01:42:22 +03:00
Get rid of the OP_Undef and OP_IsUndef opcodes in favor of higher-level
OP_InitCoroutine and OP_EndCoroutine. FossilOrigin-Name: 1ec0e9dd4b26d9f597adc8e062317d4866c5a6a6
This commit is contained in:
44
src/insert.c
44
src/insert.c
@@ -373,16 +373,13 @@ void sqlite3AutoincrementEnd(Parse *pParse){
|
||||
** yield X
|
||||
** end loop
|
||||
** cleanup after the SELECT
|
||||
** R <- undefined (signals EOF)
|
||||
** yield X
|
||||
** halt-error
|
||||
** end co-routine R
|
||||
** B:
|
||||
**
|
||||
** To use this subroutine, the caller generates code as follows:
|
||||
**
|
||||
** [ Co-routine generated by this subroutine, shown above ]
|
||||
** S: yield X
|
||||
** if R==undefined goto E
|
||||
** S: yield X, at EOF goto E
|
||||
** if skip this row, goto C
|
||||
** if terminate loop, goto E
|
||||
** deal with this row
|
||||
@@ -399,18 +396,14 @@ int sqlite3CodeCoroutine(Parse *pParse, Select *pSelect, SelectDest *pDest){
|
||||
regYield = ++pParse->nMem;
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
addrTop = sqlite3VdbeCurrentAddr(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, addrTop+1, regYield); /* X <- A */
|
||||
VdbeComment((v, "Co-routine entry point"));
|
||||
sqlite3VdbeAddOp2(v, OP_InitCoroutine, regYield, addrTop+2);
|
||||
sqlite3SelectDestInit(pDest, SRT_Coroutine, regYield);
|
||||
j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
|
||||
rc = sqlite3Select(pParse, pSelect, pDest);
|
||||
assert( pParse->nErr==0 || rc );
|
||||
if( pParse->db->mallocFailed && rc==SQLITE_OK ) rc = SQLITE_NOMEM;
|
||||
if( rc ) return rc;
|
||||
sqlite3VdbeAddOp1(v, OP_Undef, pDest->iSdst); /* Signal EOF */
|
||||
sqlite3VdbeAddOp1(v, OP_Yield, regYield); /* yield X */
|
||||
sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_INTERNAL, OE_Abort);
|
||||
VdbeComment((v, "End of coroutine"));
|
||||
sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield);
|
||||
sqlite3VdbeJumpHere(v, j1); /* label B: */
|
||||
return rc;
|
||||
}
|
||||
@@ -487,12 +480,9 @@ static int xferOptimization(
|
||||
** yield X
|
||||
** end loop
|
||||
** cleanup after the SELECT
|
||||
** R <- undefined (signals EOF)
|
||||
** yield X
|
||||
** goto A
|
||||
** end-coroutine X
|
||||
** B: open write cursor to <table> and its indices
|
||||
** C: yield X
|
||||
** if R=undefined goto D
|
||||
** C: yield X, at EOF goto D
|
||||
** insert the select result into <table> from R..R+n
|
||||
** goto C
|
||||
** D: cleanup
|
||||
@@ -511,12 +501,9 @@ static int xferOptimization(
|
||||
** yield X
|
||||
** end loop
|
||||
** cleanup after the SELECT
|
||||
** R <- undefined (signals EOF)
|
||||
** yield X
|
||||
** halt-error
|
||||
** end co-routine R
|
||||
** B: open temp table
|
||||
** L: yield X
|
||||
** if R=undefined goto M
|
||||
** L: yield X, at EOF goto M
|
||||
** insert row from R..R+n into temp table
|
||||
** goto L
|
||||
** M: open write cursor to <table> and its indices
|
||||
@@ -701,8 +688,7 @@ void sqlite3Insert(
|
||||
** here is from the 4th template:
|
||||
**
|
||||
** B: open temp table
|
||||
** L: yield X
|
||||
** if R=undefined goto M
|
||||
** L: yield X, goto M at EOF
|
||||
** insert row from R..R+n into temp table
|
||||
** goto L
|
||||
** M: ...
|
||||
@@ -710,19 +696,17 @@ void sqlite3Insert(
|
||||
int regRec; /* Register to hold packed record */
|
||||
int regTempRowid; /* Register to hold temp table ROWID */
|
||||
int addrTop; /* Label "L" */
|
||||
int addrIf; /* Address of jump to M */
|
||||
|
||||
srcTab = pParse->nTab++;
|
||||
regRec = sqlite3GetTempReg(pParse);
|
||||
regTempRowid = sqlite3GetTempReg(pParse);
|
||||
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn);
|
||||
addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
|
||||
addrIf = sqlite3VdbeAddOp1(v, OP_IsUndef, regFromSelect);
|
||||
sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec);
|
||||
sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid);
|
||||
sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
|
||||
sqlite3VdbeJumpHere(v, addrIf);
|
||||
sqlite3VdbeJumpHere(v, addrTop);
|
||||
sqlite3ReleaseTempReg(pParse, regRec);
|
||||
sqlite3ReleaseTempReg(pParse, regTempRowid);
|
||||
}
|
||||
@@ -834,7 +818,7 @@ void sqlite3Insert(
|
||||
/* This block codes the top of loop only. The complete loop is the
|
||||
** following pseudocode (template 4):
|
||||
**
|
||||
** rewind temp table
|
||||
** rewind temp table, if empty goto D
|
||||
** C: loop over rows of intermediate table
|
||||
** transfer values form intermediate table into <table>
|
||||
** end loop
|
||||
@@ -846,14 +830,12 @@ void sqlite3Insert(
|
||||
/* This block codes the top of loop only. The complete loop is the
|
||||
** following pseudocode (template 3):
|
||||
**
|
||||
** C: yield X
|
||||
** if R=undefined goto D
|
||||
** C: yield X, at EOF goto D
|
||||
** insert the select result into <table> from R..R+n
|
||||
** goto C
|
||||
** D: ...
|
||||
*/
|
||||
addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
|
||||
addrInsTop = sqlite3VdbeAddOp1(v, OP_IsUndef, dest.iSdst);
|
||||
addrInsTop = addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
|
||||
}
|
||||
|
||||
/* Allocate registers for holding the rowid of the new row,
|
||||
|
||||
Reference in New Issue
Block a user