diff options
author | drh <drh@noemail.net> | 2014-02-07 18:27:53 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2014-02-07 18:27:53 +0000 |
commit | 81cf13ec7b271740b6c6b7ccd00206e666c6cdc6 (patch) | |
tree | cb1f84153076d601ded1880f1dd1a92658d35411 /src/insert.c | |
parent | a5750cfe01b8fb83cf7382fc04b288c0b649b023 (diff) | |
download | sqlite-81cf13ec7b271740b6c6b7ccd00206e666c6cdc6.tar.gz sqlite-81cf13ec7b271740b6c6b7ccd00206e666c6cdc6.zip |
Get rid of the OP_Undef and OP_IsUndef opcodes in favor of higher-level
OP_InitCoroutine and OP_EndCoroutine.
FossilOrigin-Name: 1ec0e9dd4b26d9f597adc8e062317d4866c5a6a6
Diffstat (limited to 'src/insert.c')
-rw-r--r-- | src/insert.c | 44 |
1 files changed, 13 insertions, 31 deletions
diff --git a/src/insert.c b/src/insert.c index edf277876..c7e60a478 100644 --- a/src/insert.c +++ b/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, |