Materialize subqueries using a subroutine and invoke that subroutine
prior to each use of the subqueries manifestation. Fix for ticket [002caede898aee4] FossilOrigin-Name: 4b8357ee3c4ccdbd34e0cd077efd84cca677f496
This commit is contained in:
parent
4327aeaafd
commit
5b6a9ed495
19
manifest
19
manifest
@ -1,5 +1,5 @@
|
||||
C Adding\stest\scase\sfor\sticket\s[002caede898]
|
||||
D 2011-09-15T19:39:42.113
|
||||
C Materialize\ssubqueries\susing\sa\ssubroutine\sand\sinvoke\sthat\ssubroutine\nprior\sto\seach\suse\sof\sthe\ssubqueries\smanifestation.\s\sFix\sfor\nticket\s[002caede898aee4]
|
||||
D 2011-09-15T23:58:14.314
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in d314143fa6be24828021d3f583ad37d9afdce505
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -133,7 +133,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
||||
F src/ctime.c e3132ec65240b2e2f3d50831021eac387f27584d
|
||||
F src/date.c a3c6842bad7ae632281811de112a8ba63ff08ab3
|
||||
F src/delete.c ff68e5ef23aee08c0ff528f699a19397ed8bbed8
|
||||
F src/expr.c cbcd8c2f1588a9862291a081699854c5e1cb28ab
|
||||
F src/expr.c 109de1d4a58d25c062a79d7e84bdbb77b348844e
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c 9f00ea98f6b360d477b5a78b5b59a1fbde82431c
|
||||
F src/func.c 59bb046d7e3df1ab512ac339ccb0a6f996a17cb7
|
||||
@ -179,11 +179,11 @@ F src/printf.c 585a36b6a963df832cfb69505afa3a34ed5ef8a1
|
||||
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
||||
F src/resolve.c 36368f44569208fa074e61f4dd0b6c4fb60ca2b4
|
||||
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
|
||||
F src/select.c bf7b7ea6befb483619da5f597b0864668b828c3c
|
||||
F src/select.c d85d83c334a3842b47d14e0574acb5f531d5579a
|
||||
F src/shell.c bbe7818ff5bc8614105ceb81ad67b8bdc0b671dd
|
||||
F src/sqlite.h.in 0a6c9c23337fd1352c5c75a613ff9533aa7d91cb
|
||||
F src/sqlite3ext.h 1a1a4f784aa9c3b00edd287940197de52487cd93
|
||||
F src/sqliteInt.h c7e37ee49b1a922ddcd18fa98dd750efa4d2db14
|
||||
F src/sqliteInt.h feb4f2b212fe36bbd951e44d2490c6aacf02f689
|
||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||
F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf
|
||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||
@ -961,10 +961,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5
|
||||
F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
|
||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||
F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2
|
||||
P 3fc566ac5dfce314ee414a3fb79daeeed6d0f179
|
||||
R 3df652f1b6c038f8caa8cb1ea6bf4532
|
||||
T *branch * tkt-002caede898
|
||||
T *sym-tkt-002caede898 *
|
||||
T -sym-trunk *
|
||||
P 62dfc51a495be017605cf315d72e2db91bfa28f7
|
||||
R 6d5602e8586fba23bb68456f6fac9e14
|
||||
U drh
|
||||
Z 9197dd7d4afe8679532f19b1e34148bf
|
||||
Z 035be646ae967eef8d7d2956eeb67c86
|
||||
|
@ -1 +1 @@
|
||||
62dfc51a495be017605cf315d72e2db91bfa28f7
|
||||
4b8357ee3c4ccdbd34e0cd077efd84cca677f496
|
@ -901,7 +901,8 @@ SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){
|
||||
pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
|
||||
pNewItem->jointype = pOldItem->jointype;
|
||||
pNewItem->iCursor = pOldItem->iCursor;
|
||||
pNewItem->isPopulated = pOldItem->isPopulated;
|
||||
pNewItem->addrFillSub = pOldItem->addrFillSub;
|
||||
pNewItem->regReturn = pOldItem->regReturn;
|
||||
pNewItem->isCorrelated = pOldItem->isCorrelated;
|
||||
pNewItem->zIndex = sqlite3DbStrDup(db, pOldItem->zIndex);
|
||||
pNewItem->notIndexed = pOldItem->notIndexed;
|
||||
|
32
src/select.c
32
src/select.c
@ -3801,7 +3801,11 @@ int sqlite3Select(
|
||||
Select *pSub = pItem->pSelect;
|
||||
int isAggSub;
|
||||
|
||||
if( pSub==0 || pItem->isPopulated ) continue;
|
||||
if( pSub==0 ) continue;
|
||||
if( pItem->addrFillSub ){
|
||||
sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Increment Parse.nHeight by the height of the largest expression
|
||||
** tree refered to by this, the parent select. The child select
|
||||
@ -3812,21 +3816,41 @@ int sqlite3Select(
|
||||
*/
|
||||
pParse->nHeight += sqlite3SelectExprHeight(p);
|
||||
|
||||
/* Check to see if the subquery can be absorbed into the parent. */
|
||||
isAggSub = (pSub->selFlags & SF_Aggregate)!=0;
|
||||
if( flattenSubquery(pParse, p, i, isAgg, isAggSub) ){
|
||||
/* This subquery can be absorbed into its parent. */
|
||||
if( isAggSub ){
|
||||
isAgg = 1;
|
||||
p->selFlags |= SF_Aggregate;
|
||||
}
|
||||
i = -1;
|
||||
}else{
|
||||
/* Generate a subroutine that will fill an ephemeral table with
|
||||
** the content of this subquery. pItem->addrFillSub will point
|
||||
** to the address of the generated subroutine. pItem->regReturn
|
||||
** is a register allocated to hold the subroutine return address
|
||||
*/
|
||||
int topAddr = sqlite3VdbeAddOp0(v, OP_Goto);
|
||||
int regOnce = 0;
|
||||
assert( pItem->addrFillSub==0 );
|
||||
pItem->addrFillSub = topAddr+1;
|
||||
pItem->regReturn = ++pParse->nMem;
|
||||
if( pItem->isCorrelated==0 && pParse->pTriggerTab==0 ){
|
||||
/* If the subquery is no correlated and if we are not inside of
|
||||
** a trigger, then we only need to compute the value of the subquery
|
||||
** once. */
|
||||
regOnce = ++pParse->nMem;
|
||||
sqlite3VdbeAddOp1(v, OP_If, regOnce);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 1, regOnce);
|
||||
}
|
||||
sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
|
||||
assert( pItem->isPopulated==0 );
|
||||
explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
|
||||
sqlite3Select(pParse, pSub, &dest);
|
||||
pItem->isPopulated = 1;
|
||||
pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow;
|
||||
if( regOnce ) sqlite3VdbeJumpHere(v, topAddr+1);
|
||||
sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
|
||||
sqlite3VdbeJumpHere(v, topAddr);
|
||||
sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, topAddr+1);
|
||||
}
|
||||
if( /*pParse->nErr ||*/ db->mallocFailed ){
|
||||
goto select_end;
|
||||
|
@ -1852,7 +1852,8 @@ struct SrcList {
|
||||
char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */
|
||||
Table *pTab; /* An SQL table corresponding to zName */
|
||||
Select *pSelect; /* A SELECT statement used in place of a table name */
|
||||
u8 isPopulated; /* Temporary table associated with SELECT is populated */
|
||||
int addrFillSub; /* Address of subroutine to manifest a subquery */
|
||||
int regReturn; /* Register holding return address of addrFillSub */
|
||||
u8 jointype; /* Type of join between this able and the previous */
|
||||
u8 notIndexed; /* True if there is a NOT INDEXED clause */
|
||||
u8 isCorrelated; /* True if sub-query is correlated */
|
||||
|
Loading…
x
Reference in New Issue
Block a user