Do not flatten sub-queries that contain window functions.

FossilOrigin-Name: 236cb75bd1f0d5eb86aa5f52d8d548e7263c34633833dcea9dfc934f142113b8
diff --git a/src/expr.c b/src/expr.c
index 54e9ced..af4201e 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -1182,24 +1182,6 @@
   return nByte;
 }
 
-static Window *winDup(sqlite3 *db, Window *p){
-  Window *pNew = 0;
-  if( p ){
-    pNew = sqlite3DbMallocZero(db, sizeof(Window));
-    if( pNew ){
-      pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
-      pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
-      pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
-      pNew->eType = p->eType;
-      pNew->eEnd = p->eEnd;
-      pNew->eStart = p->eStart;
-      pNew->pStart = sqlite3ExprDup(db, pNew->pStart, 0);
-      pNew->pEnd = sqlite3ExprDup(db, pNew->pEnd, 0);
-    }
-  }
-  return pNew;
-}
-
 /*
 ** This function is similar to sqlite3ExprDup(), except that if pzBuffer 
 ** is not NULL then *pzBuffer is assumed to point to a buffer large enough 
@@ -1289,7 +1271,7 @@
       if( ExprHasProperty(p, EP_Reduced|EP_TokenOnly) ){
         pNew->pWin = 0;
       }else{
-        pNew->pWin = winDup(db, p->pWin);
+        pNew->pWin = sqlite3WindowDup(db, p->pWin);
       }
       if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
         if( pNew->op==TK_SELECT_COLUMN ){
diff --git a/src/select.c b/src/select.c
index 5e99c94..fcafe74 100644
--- a/src/select.c
+++ b/src/select.c
@@ -3712,7 +3712,7 @@
   pSub = pSubitem->pSelect;
   assert( pSub!=0 );
 
-  if( p->pWin ) return 0;
+  if( p->pWin || pSub->pWin ) return 0;
 
   pSubSrc = pSub->pSrc;
   assert( pSubSrc );
@@ -5898,26 +5898,18 @@
     assert( p->pEList==pEList );
     if( pWin ){
       int addrGosub = sqlite3VdbeMakeLabel(v);
+      int iCont = sqlite3VdbeMakeLabel(v);
       int regGosub = ++pParse->nMem;
       int addr = 0;
-      int bLoop = 0;
 
-      sqlite3WindowCodeStep(pParse, p, pWInfo, regGosub, addrGosub, &bLoop);
+      sqlite3WindowCodeStep(pParse, p, pWInfo, regGosub, addrGosub);
 
-      sqlite3VdbeAddOp0(v, OP_Goto);
+      addr = sqlite3VdbeAddOp0(v, OP_Goto);
       sqlite3VdbeResolveLabel(v, addrGosub);
-      if( bLoop ){
-        addr = sqlite3VdbeAddOp1(v, OP_Rewind, pWin->iEphCsr);
-      }else{
-        addr = sqlite3VdbeCurrentAddr(v);
-      }
-      selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest, addr+1, 0);
-      if( bLoop ){
-        sqlite3VdbeAddOp2(v, OP_Next, pWin->iEphCsr, addr+1);
-        sqlite3VdbeJumpHere(v, addr);
-      }
+      selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest, iCont, 0);
+      sqlite3VdbeResolveLabel(v, iCont);
       sqlite3VdbeAddOp1(v, OP_Return, regGosub);
-      sqlite3VdbeJumpHere(v, addr-1);       /* OP_Goto jumps here */
+      sqlite3VdbeJumpHere(v, addr);
 
     }else{
       /* Use the standard inner loop. */
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index d69b569..d2b7730 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -3502,10 +3502,11 @@
 void sqlite3WindowAttach(Parse*, Expr*, Window*);
 int sqlite3WindowCompare(Parse*, Window*, Window*);
 void sqlite3WindowCodeInit(Parse*, Window*);
-void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int, int*);
+void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int);
 int sqlite3WindowRewrite(Parse*, Select*);
 int sqlite3ExpandSubquery(Parse*, struct SrcList_item*);
 void sqlite3WindowUpdate(Parse*, Window*, FuncDef*);
+Window *sqlite3WindowDup(sqlite3 *db, Window *p);
 
 /*
 ** Assuming zIn points to the first byte of a UTF-8 character,
diff --git a/src/window.c b/src/window.c
index 2690747..d2b6e23 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1560,7 +1560,10 @@
       if( addrGoto ) sqlite3VdbeJumpHere(v, addrGoto);
     }
 
+    sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3);
     sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
+    sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1);
+
     sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
     sqlite3VdbeAddOp3(
         v, OP_Copy, reg+pMWin->nBufferCol, pMWin->regPart, nPart+nPeer-1
@@ -1586,9 +1589,28 @@
   sqlite3WhereEnd(pWInfo);
 
   windowAggFinal(pParse, pMWin, 1);
+  sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3);
   sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
+  sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1);
 }
 
+Window *sqlite3WindowDup(sqlite3 *db, Window *p){
+  Window *pNew = 0;
+  if( p ){
+    pNew = sqlite3DbMallocZero(db, sizeof(Window));
+    if( pNew ){
+      pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
+      pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
+      pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
+      pNew->eType = p->eType;
+      pNew->eEnd = p->eEnd;
+      pNew->eStart = p->eStart;
+      pNew->pStart = sqlite3ExprDup(db, pNew->pStart, 0);
+      pNew->pEnd = sqlite3ExprDup(db, pNew->pEnd, 0);
+    }
+  }
+  return pNew;
+}
 
 /*
 ** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
@@ -1649,13 +1671,11 @@
   Select *p,
   WhereInfo *pWInfo,
   int regGosub, 
-  int addrGosub,
-  int *pbLoop
+  int addrGosub
 ){
   Window *pMWin = p->pWin;
   Window *pWin;
 
-  *pbLoop = 0;
   if( (pMWin->eType==TK_ROWS 
    && (pMWin->eStart!=TK_UNBOUNDED||pMWin->eEnd!=TK_CURRENT||!pMWin->pOrderBy))
    || (pMWin->eStart==TK_CURRENT&&pMWin->eEnd==TK_UNBOUNDED&&pMWin->pOrderBy)
@@ -1677,7 +1697,6 @@
     }
   }
 
-  *pbLoop = 1;
   windowCodeDefaultStep(pParse, p, pWInfo, regGosub, addrGosub);
 }