aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/expr.c6
-rw-r--r--src/sqliteInt.h1
-rw-r--r--src/window.c23
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