From 5f61229504bc56387db38fd7194652860b53c772 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 8 Feb 2014 23:20:32 +0000 Subject: [PATCH] Do away with the "multi-register pseudo-table" abstration. Instead, just use an OP_SCopy to load results directory from the result registers of the co-routine. FossilOrigin-Name: 1e64dd782a126f48d78c43a664844a41d0e6334e --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/select.c | 5 +---- src/sqliteInt.h | 1 + src/vdbe.c | 16 +++++----------- src/vdbeInt.h | 1 - src/where.c | 29 ++++++++++++++++++++++++++--- 7 files changed, 44 insertions(+), 30 deletions(-) diff --git a/manifest b/manifest index b0c7343970..d5e1ef9945 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sOP_Found\sopcode\sso\sthat\sit\sexpands\szero-blobs\sprior\sto\scomparing\nthem.\s\sFix\sfor\sticket\s[fccbde530a6583b] -D 2014-02-08T19:12:21.547 +C Do\saway\swith\sthe\s"multi-register\spseudo-table"\sabstration.\s\sInstead,\sjust\nuse\san\sOP_SCopy\sto\sload\sresults\sdirectory\sfrom\sthe\sresult\sregisters\sof\nthe\sco-routine. +D 2014-02-08T23:20:32.439 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -219,12 +219,12 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c b854d23224c44f10a2dbe233c885e208701a5a08 +F src/select.c de28cd6d49e0334a3c693fbcce7cd8dfe5fc3979 F src/shell.c 7dedf7367ee49050b0366bf8dbc8ec2bd15b42c7 F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h ab719053ec9fb58702dd8cdfc4fc9d4870af9979 +F src/sqliteInt.h edee30d57dd287aea523406f53123583ca7f0089 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -280,9 +280,9 @@ F src/update.c a7df6fffce6bfedc578fda6136dd33e34a63f8ee F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 15ac2627f548f5481d0d7e6c4eb67be673027695 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c a5556442eb6ada77eb432c98f22baa51b6abf3a9 +F src/vdbe.c 78b41fd0a3b3ab4647e3bf99905fb65831a1a92a F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 -F src/vdbeInt.h b5d62957a408c4bea649484008e5f98335b09e97 +F src/vdbeInt.h 6714e9eb5c3a481976d32ca767f03ac0469fc9df F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad F src/vdbeaux.c 379343f1d98b60b0771366e5955f3cab34f1a3ca F src/vdbeblob.c 9542e116c1db5ed813977581d506c176e117c0ec @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c 30fd77c349cb97bf737c5a880b88f265b7c66316 +F src/where.c 90fef20dd178db262ecd522a214a4eee6f76a44b F src/whereInt.h 921f935af8b684ffb49705610bda7284db1db138 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1152,7 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 83116ee3e0f2b9110c70a4f73a9badc9c2a56f28 -R a13d7a863184cc3e51d017457c46ee29 +P e2303d1b0c17b6e7494fb7db8264f4c2ac193723 +R eb37dbfa0e5b1c125492efcb100d4ba8 U drh -Z 47328ab39b0e370926e85f5f82006e15 +Z 5d0b8c0ebed26b99f999abde70f4aea6 diff --git a/manifest.uuid b/manifest.uuid index 8d5ca2327f..43ad228af7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e2303d1b0c17b6e7494fb7db8264f4c2ac193723 \ No newline at end of file +1e64dd782a126f48d78c43a664844a41d0e6334e \ No newline at end of file diff --git a/src/select.c b/src/select.c index 28bbcb2eb9..4c426e76b2 100644 --- a/src/select.c +++ b/src/select.c @@ -4541,16 +4541,13 @@ int sqlite3Select( pItem->regReturn = ++pParse->nMem; sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop); VdbeComment((v, "%s", pItem->pTab->zName)); - sqlite3VdbeAddOp1(v, OP_OpenPseudo, pItem->iCursor); - sqlite3VdbeChangeP5(v, 1); pItem->addrFillSub = addrTop; sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn); explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); sqlite3Select(pParse, pSub, &dest); pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow; pItem->viaCoroutine = 1; - sqlite3VdbeChangeP2(v, addrTop, dest.iSdst); - sqlite3VdbeChangeP3(v, addrTop, dest.nSdst); + pItem->regResult = dest.iSdst; sqlite3VdbeAddOp1(v, OP_EndCoroutine, pItem->regReturn); sqlite3VdbeJumpHere(v, addrTop-1); sqlite3ClearTempRegCache(pParse); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 42851ab342..4cfa9d39a5 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2019,6 +2019,7 @@ struct SrcList { Select *pSelect; /* A SELECT statement used in place of a table name */ int addrFillSub; /* Address of subroutine to manifest a subquery */ int regReturn; /* Register holding return address of addrFillSub */ + int regResult; /* Registers holding results of a co-routine */ u8 jointype; /* Type of join between this able and the previous */ unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */ unsigned isCorrelated :1; /* True if sub-query is correlated */ diff --git a/src/vdbe.c b/src/vdbe.c index 334931d7c5..25090e3b31 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2281,11 +2281,6 @@ case OP_Column: { if( pCrsr==0 ){ assert( pC->pseudoTableReg>0 ); pReg = &aMem[pC->pseudoTableReg]; - if( pC->multiPseudo ){ - sqlite3VdbeMemShallowCopy(pDest, pReg+p2, MEM_Ephem); - Deephemeralize(pDest); - goto op_column_out; - } assert( pReg->flags & MEM_Blob ); assert( memIsValid(pReg) ); pC->payloadSize = pC->szRow = avail = pReg->n; @@ -3354,14 +3349,13 @@ case OP_SorterOpen: { break; } -/* Opcode: OpenPseudo P1 P2 P3 * P5 +/* Opcode: OpenPseudo P1 P2 P3 * * ** Synopsis: content in r[P2@P3] ** ** Open a new cursor that points to a fake table that contains a single -** row of data. The content of that one row in the content of memory -** register P2 when P5==0. In other words, cursor P1 becomes an alias for the -** MEM_Blob content contained in register P2. When P5==1, then the -** row is represented by P3 consecutive registers beginning with P2. +** row of data. The content of that one row is the content of memory +** register P2. In other words, cursor P1 becomes an alias for the +** MEM_Blob content contained in register P2. ** ** A pseudo-table created by this opcode is used to hold a single ** row output from the sorter so that the row can be decomposed into @@ -3381,7 +3375,7 @@ case OP_OpenPseudo: { pCx->nullRow = 1; pCx->pseudoTableReg = pOp->p2; pCx->isTable = 1; - pCx->multiPseudo = pOp->p5; + assert( pOp->p5==0 ); break; } diff --git a/src/vdbeInt.h b/src/vdbeInt.h index f1d136a8ef..508b61e95c 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -75,7 +75,6 @@ struct VdbeCursor { Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */ Bool isTable:1; /* True if a table requiring integer keys */ Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */ - Bool multiPseudo:1; /* Multi-register pseudo-cursor */ sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ i64 seqCount; /* Sequence counter */ i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ diff --git a/src/where.c b/src/where.c index 0eeb8df7ab..91b9e0c537 100644 --- a/src/where.c +++ b/src/where.c @@ -5835,12 +5835,38 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ assert( pWInfo->nLevel<=pTabList->nSrc ); for(i=0, pLevel=pWInfo->a; inLevel; i++, pLevel++){ + int k, last; + VdbeOp *pOp; Index *pIdx = 0; struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom]; Table *pTab = pTabItem->pTab; assert( pTab!=0 ); pLoop = pLevel->pWLoop; + /* For a co-routine, change all OP_Column references to the table of + ** the co-routine into OP_SCopy of result contained in a register. + ** OP_Rowid becomes OP_Null. + */ + if( pTabItem->viaCoroutine ){ + last = sqlite3VdbeCurrentAddr(v); + k = pLevel->addrBody; + pOp = sqlite3VdbeGetOp(v, k); + for(; kp1!=pLevel->iTabCur ) continue; + if( pOp->opcode==OP_Column ){ + pOp->opcode = OP_SCopy; + pOp->p1 = pOp->p2 + pTabItem->regResult; + pOp->p2 = pOp->p3; + pOp->p3 = 0; + }else if( pOp->opcode==OP_Rowid ){ + pOp->opcode = OP_Null; + pOp->p1 = 0; + pOp->p3 = 0; + } + } + continue; + } + /* Close all of the cursors that were opened by sqlite3WhereBegin. ** Except, do not close cursors that will be reused by the OR optimization ** (WHERE_OMIT_OPEN_CLOSE). And do not close the OP_OpenWrite cursors @@ -5879,9 +5905,6 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ pIdx = pLevel->u.pCovidx; } if( pIdx && !db->mallocFailed ){ - int k, last; - VdbeOp *pOp; - last = sqlite3VdbeCurrentAddr(v); k = pLevel->addrBody; pOp = sqlite3VdbeGetOp(v, k);