mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-19 21:43:15 +03:00
Ensure that when code for a scalar SELECT featuring window functions is generated more than once by the planner, separate ephemeral tables are opened for each instance.
FossilOrigin-Name: ce1417325273aba866767349b55d9bbfb61a08e716bebda2122918a9657ee38c
This commit is contained in:
@@ -6177,7 +6177,7 @@ int sqlite3Select(
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
Window *pWin = p->pWin; /* Master window object (or NULL) */
|
||||
if( pWin ){
|
||||
sqlite3WindowCodeInit(pParse, pWin);
|
||||
sqlite3WindowCodeInit(pParse, p);
|
||||
}
|
||||
#endif
|
||||
assert( WHERE_USE_LIMIT==SF_FixedLimit );
|
||||
|
||||
@@ -3727,7 +3727,7 @@ Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*, u8);
|
||||
void sqlite3WindowAttach(Parse*, Expr*, Window*);
|
||||
void sqlite3WindowLink(Select *pSel, Window *pWin);
|
||||
int sqlite3WindowCompare(Parse*, Window*, Window*, int);
|
||||
void sqlite3WindowCodeInit(Parse*, Window*);
|
||||
void sqlite3WindowCodeInit(Parse*, Select*);
|
||||
void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int);
|
||||
int sqlite3WindowRewrite(Parse*, Select*);
|
||||
int sqlite3ExpandSubquery(Parse*, struct SrcList_item*);
|
||||
|
||||
13
src/window.c
13
src/window.c
@@ -1033,10 +1033,6 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
|
||||
p->pSrc->a[0].pTab = pTab;
|
||||
pTab = pTab2;
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, pSublist->nExpr);
|
||||
sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr);
|
||||
sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+2, pMWin->iEphCsr);
|
||||
sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+3, pMWin->iEphCsr);
|
||||
}else{
|
||||
sqlite3SelectDelete(db, pSub);
|
||||
}
|
||||
@@ -1308,10 +1304,17 @@ int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2, int bFilter){
|
||||
** to begin iterating through the sub-query results. It is used to allocate
|
||||
** and initialize registers and cursors used by sqlite3WindowCodeStep().
|
||||
*/
|
||||
void sqlite3WindowCodeInit(Parse *pParse, Window *pMWin){
|
||||
void sqlite3WindowCodeInit(Parse *pParse, Select *pSelect){
|
||||
int nEphExpr = pSelect->pSrc->a[0].pSelect->pEList->nExpr;
|
||||
Window *pMWin = pSelect->pWin;
|
||||
Window *pWin;
|
||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||
|
||||
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, nEphExpr);
|
||||
sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr);
|
||||
sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+2, pMWin->iEphCsr);
|
||||
sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+3, pMWin->iEphCsr);
|
||||
|
||||
/* Allocate registers to use for PARTITION BY values, if any. Initialize
|
||||
** said registers to NULL. */
|
||||
if( pMWin->pPartition ){
|
||||
|
||||
Reference in New Issue
Block a user