diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/expr.c | 6 | ||||
-rw-r--r-- | src/sqliteInt.h | 1 | ||||
-rw-r--r-- | src/window.c | 23 |
3 files changed, 26 insertions, 4 deletions
diff --git a/src/expr.c b/src/expr.c index a5a0b7403..196942673 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1116,7 +1116,7 @@ static int exprStructSize(Expr *p){ ** Note that with flags==EXPRDUP_REDUCE, this routines works on full-size ** (unreduced) Expr objects as they or originally constructed by the parser. ** During expression analysis, extra information is computed and moved into -** later parts of teh Expr object and that extra information might get chopped +** later parts of the Expr object and that extra information might get chopped ** off if the expression is reduced. Note also that it does not work to ** make an EXPRDUP_REDUCE copy of a reduced expression. It is only legal ** to reduce a pristine expression tree from the parser. The implementation @@ -1128,7 +1128,7 @@ static int dupedExprStructSize(Expr *p, int flags){ assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */ assert( EXPR_FULLSIZE<=0xfff ); assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 ); - if( 0==flags || p->op==TK_SELECT_COLUMN ){ + if( 0==flags || p->op==TK_SELECT_COLUMN || p->pWin ){ nSize = EXPR_FULLSIZE; }else{ assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); @@ -1480,7 +1480,7 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){ pNew->nSelectRow = p->nSelectRow; pNew->pWith = withDup(db, p->pWith); pNew->pWin = 0; - pNew->pWinDefn = 0; /* TODO!! */ + pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn); sqlite3SelectSetName(pNew, p->zSelName); *pp = pNew; pp = &pNew->pPrior; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 61f4f924a..d297af700 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3528,6 +3528,7 @@ int sqlite3WindowRewrite(Parse*, Select*); int sqlite3ExpandSubquery(Parse*, struct SrcList_item*); void sqlite3WindowUpdate(Parse*, Window*, Window*, FuncDef*); Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p); +Window *sqlite3WindowListDup(sqlite3 *db, Window *p); void sqlite3WindowFunctions(void); /* diff --git a/src/window.c b/src/window.c index a61821847..9d5cadcdd 100644 --- a/src/window.c +++ b/src/window.c @@ -503,7 +503,7 @@ void sqlite3WindowUpdate( Window *pWin, /* Window frame to update */ FuncDef *pFunc /* Window function definition */ ){ - if( pWin->zName ){ + if( pWin->zName && pWin->eType==0 ){ Window *p; for(p=pList; p; p=p->pNextWin){ if( sqlite3StrICmp(p->zName, pWin->zName)==0 ) break; @@ -518,6 +518,7 @@ void sqlite3WindowUpdate( pWin->pEnd = sqlite3ExprDup(pParse->db, p->pEnd, 0); pWin->eStart = p->eStart; pWin->eEnd = p->eEnd; + pWin->eType = p->eType; } if( pFunc->funcFlags & SQLITE_FUNC_WINDOW ){ sqlite3 *db = pParse->db; @@ -800,6 +801,7 @@ Window *sqlite3WindowAlloc( Window *pWin = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); if( pWin ){ + assert( eType ); pWin->eType = eType; pWin->eStart = eStart; pWin->eEnd = eEnd; @@ -1918,6 +1920,7 @@ Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){ if( p ){ pNew = sqlite3DbMallocZero(db, sizeof(Window)); if( pNew ){ + pNew->zName = sqlite3DbStrDup(db, p->zName); pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0); pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0); pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0); @@ -1933,6 +1936,24 @@ Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){ } /* +** Return a copy of the linked list of Window objects passed as the +** second argument. +*/ +Window *sqlite3WindowListDup(sqlite3 *db, Window *p){ + Window *pWin; + Window *pRet = 0; + Window **pp = &pRet; + + for(pWin=p; pWin; pWin=pWin->pNextWin){ + *pp = sqlite3WindowDup(db, 0, pWin); + if( *pp==0 ) break; + pp = &((*pp)->pNextWin); + } + + return pRet; +} + +/* ** sqlite3WhereBegin() has already been called for the SELECT statement ** passed as the second argument when this function is invoked. It generates ** code to populate the Window.regResult register for each window function and |