]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Clarify the relationship between a Window object and its associated Expr.
authordan <dan@noemail.net>
Mon, 11 Jun 2018 20:50:25 +0000 (20:50 +0000)
committerdan <dan@noemail.net>
Mon, 11 Jun 2018 20:50:25 +0000 (20:50 +0000)
FossilOrigin-Name: 0cd55e98a478740032f5569ddc00fa5b0e063e90db6e00ac7598c9b7c2fffeee

manifest
manifest.uuid
src/expr.c
src/resolve.c
src/sqliteInt.h
src/window.c

index 18f389d9322cad73cb3f935b3fbfb65c28f14faf..c3a8208d5dd33b8a1264f28d7e16b13b7ec1ad79 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\shandling\sof\swindow\sframes\scontaining\snegative\snumber\sof\srows.\se.g.\s"ROWS\sx\nPRECEDING\sAND\sy\sPRECEDING"\swhere\s(x<y).
-D 2018-06-11T18:16:51.622
+C Clarify\sthe\srelationship\sbetween\sa\sWindow\sobject\sand\sits\sassociated\sExpr.
+D 2018-06-11T20:50:25.844
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F Makefile.in 498b77b89a8cb42f2ee20fcd6317f279a45c0d6ff40d27825f94b69884c09bbe
@@ -447,7 +447,7 @@ F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957
 F src/dbpage.c 4aa7f26198934dbd002e69418220eae3dbc71b010bbac32bd78faf86b52ce6c3
 F src/dbstat.c edabb82611143727511a45ca0859b8cd037851ebe756ae3db289859dd18b6f91
 F src/delete.c 4c8c7604277a2041647f96b78f4b9a47858e9217e4fb333d35e7b5ab32c5b57f
-F src/expr.c d6db67ebe0597f87381827513ae168b202956fca35add953e294afc80fa41675
+F src/expr.c 1963827d3ab4aaa006c0b72ff486c537f9690acece2ad5852f65bd6e1336cec7
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
 F src/fkey.c b1da9ef8dc834603bb0d28972378a7ce65897847f9a1e89ab800bbdf24c788ee
 F src/func.c a5ee3864264edea8fea4d2dfdf8296250cff9139343953da78d82837241659a9
@@ -493,14 +493,14 @@ F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324
 F src/prepare.c e966ecc97c3671ff0e96227c8c877b83f2d33ea371ee190bbf1698b36b5605c0
 F src/printf.c 7f6f3cba8e0c49c19e30a1ff4e9aeda6e06814dcbad4b664a69e1b6cb6e7e365
 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
-F src/resolve.c 03791a761ede3a2cd71dffb92aa760d728122dbbdbf26010813da3edd01cb431
+F src/resolve.c a8cf3d6144f6a821f002dad72f80659691e827a96e6da6dedf8b263edefe3a80
 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
 F src/select.c 0b0ce29bd7b8a7232e6f7602ddb447caa954a1fc476ff5e23ce1e5aaa6a0e0ed
 F src/shell.c.in 4d0ddf10c403710d241bf920163dcf032c21119aebb61e70840942c0eafecdf9
 F src/sqlite.h.in 63b07f76731f2b1e55c48fdb9f0508dcc6fbe3971010b8612ffd847c3c56d9a1
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 9887b27e69c01e79c2cbe74ef73bf01af5b5703d6a7f0a4371e386d7249cb1c7
-F src/sqliteInt.h 04c732e9e770d35c12f5e649b7288510f3a2abb238e32eadaf506678717ddb25
+F src/sqliteInt.h 939c1893f7a5fd34cb79e30ecd46d00e81c847e5026c75c213a49938f33e74ba
 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
 F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -583,7 +583,7 @@ F src/where.c fe1a6f97c12cc9472ccce86166ba3f827cf61d6ae770c036a6396b63863baac4
 F src/whereInt.h b90ef9b9707ef750eab2a7a080c48fb4900315033274689def32d0cf5a81ebe4
 F src/wherecode.c 3317f2b083a66d3e65a03edf316ade4ccb0a99c9956273282ebb579b95d4ba96
 F src/whereexpr.c 6f022d6cc9daf56495f191b199352f783aff5cf268ba136b4d8cea3fb62d8c7d
-F src/window.c 0519e5a03ebbcf22ab692410d4b25f28cc2d0e4e37e6288ca1eb0820276d67ba
+F src/window.c a5ebf5b119f50a1c886a900cf817ada2d9e3cf30633471e1444423424443756c
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
 F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
@@ -1740,7 +1740,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P e74f86f271d6ab1ecd17c1ee63ab2aa0885ca56624be7382872f04d46c48ed86
-R a123bfa3a94ae6460114239fab9e1170
+P b6d9c7eda853420ae46a05bd432711e8bf9ebaa448c7d90ccfc0bcc338a87706
+R 118974de7b2e01c35e697f59c5a4477b
 U dan
-Z 6b49a0a9a9265834682b1c9c02ee1753
+Z 1841ea3c1d7c82f1a89ee2ea7c51ae4b
index 0cd6c62cdb8b93cbae332cda30bb20b6b7b3587d..4bf55168e2261ab27302ce688084d2d7997fa1bf 100644 (file)
@@ -1 +1 @@
-b6d9c7eda853420ae46a05bd432711e8bf9ebaa448c7d90ccfc0bcc338a87706
\ No newline at end of file
+0cd55e98a478740032f5569ddc00fa5b0e063e90db6e00ac7598c9b7c2fffeee
\ No newline at end of file
index 819a14bced3f85dc0bb541e7d8063b37282a6777..9431c4c205ccf9135a1d905aaa59e064478833f7 100644 (file)
@@ -1271,7 +1271,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
       if( ExprHasProperty(p, EP_Reduced|EP_TokenOnly) ){
         pNew->pWin = 0;
       }else{
-        pNew->pWin = sqlite3WindowDup(db, p->pWin);
+        pNew->pWin = sqlite3WindowDup(db, pNew, p->pWin);
       }
       if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
         if( pNew->op==TK_SELECT_COLUMN ){
index 0d946681900c3adec9ef98242f6e63f461739ae4..221564f9d36ba9256a9cc409a0e7b04ded5a902f 100644 (file)
@@ -800,8 +800,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
             pExpr->pWin->pNextWin = pSel->pWin;
             pSel->pWin = pExpr->pWin;
           }
-          pExpr->pWin->pFunc = pDef;
-          pExpr->pWin->nArg = (pExpr->x.pList ? pExpr->x.pList->nExpr : 0);
         }else{
           NameContext *pNC2 = pNC;
           pExpr->op = TK_AGG_FUNCTION;
index 7d4c3ea713b07cb5e7d35cb01441a338f4f74bc9..cd702cef1d5ee83a4222d0d4c8783e114170ed5f 100644 (file)
@@ -3488,7 +3488,6 @@ struct Window {
 
   Expr *pFilter;
   FuncDef *pFunc;
-  int nArg;
 
   int iEphCsr;            /* Temp table used by this window */
   int regAccum;
@@ -3513,7 +3512,7 @@ void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int);
 int sqlite3WindowRewrite(Parse*, Select*);
 int sqlite3ExpandSubquery(Parse*, struct SrcList_item*);
 void sqlite3WindowUpdate(Parse*, Window*, Window*, FuncDef*);
-Window *sqlite3WindowDup(sqlite3 *db, Window *p);
+Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p);
 
 /*
 ** Assuming zIn points to the first byte of a UTF-8 character,
index 9c633621053e0fc9f2c1e19785c5f0166fe1563f..a627be1bc61bede9882d642c12ebb0c6eed3ab88 100644 (file)
@@ -26,7 +26,7 @@ static void row_numberStepFunc(
   i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p));
   if( p ) (*p)++;
 }
-static void row_numberInverseFunc(
+static void row_numberInvFunc(
   sqlite3_context *pCtx, 
   int nArg,
   sqlite3_value **apArg
@@ -38,7 +38,8 @@ static void row_numberValueFunc(sqlite3_context *pCtx){
 }
 
 /*
-** Context object type used by rank() and dense_rank().
+** Context object type used by rank(), dense_rank(), percent_rank() and
+** cume_dist().
 */
 struct CallCount {
   i64 nValue;
@@ -58,7 +59,7 @@ static void dense_rankStepFunc(
   p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
   if( p ) p->nStep = 1;
 }
-static void dense_rankInverseFunc(
+static void dense_rankInvFunc(
   sqlite3_context *pCtx, 
   int nArg,
   sqlite3_value **apArg
@@ -93,7 +94,7 @@ static void rankStepFunc(
     }
   }
 }
-static void rankInverseFunc(
+static void rankInvFunc(
   sqlite3_context *pCtx, 
   int nArg,
   sqlite3_value **apArg
@@ -130,7 +131,7 @@ static void percent_rankStepFunc(
     }
   }
 }
-static void percent_rankInverseFunc(
+static void percent_rankInvFunc(
   sqlite3_context *pCtx, 
   int nArg,
   sqlite3_value **apArg
@@ -166,7 +167,7 @@ static void cume_distStepFunc(
     p->nStep++;
   }
 }
-static void cume_distInverseFunc(
+static void cume_distInvFunc(
   sqlite3_context *pCtx, 
   int nArg,
   sqlite3_value **apArg
@@ -181,6 +182,9 @@ static void cume_distValueFunc(sqlite3_context *pCtx){
   }
 }
 
+/*
+** Context object for ntile() window function.
+*/
 struct NtileCtx {
   i64 nTotal;                     /* Total rows in partition */
   i64 nParam;                     /* Parameter passed to ntile(N) */
@@ -214,7 +218,7 @@ static void ntileStepFunc(
     p->iRow++;
   }
 }
-static void ntileInverseFunc(
+static void ntileInvFunc(
   sqlite3_context *pCtx, 
   int nArg,
   sqlite3_value **apArg
@@ -243,6 +247,9 @@ static void ntileValueFunc(sqlite3_context *pCtx){
   }
 }
 
+/*
+** Context object for last_value() window function.
+*/
 struct LastValueCtx {
   sqlite3_value *pVal;
   int nVal;
@@ -264,7 +271,7 @@ static void last_valueStepFunc(
     p->nVal++;
   }
 }
-static void last_valueInverseFunc(
+static void last_valueInvFunc(
   sqlite3_context *pCtx, 
   int nArg,
   sqlite3_value **apArg
@@ -296,76 +303,33 @@ static void last_valueFinalizeFunc(sqlite3_context *pCtx){
   }
 }
 
-static void nth_valueStepFunc(
-  sqlite3_context *pCtx, 
-  int nArg,
-  sqlite3_value **apArg
-){
-}
-static void nth_valueInverseFunc(
-  sqlite3_context *pCtx, 
-  int nArg,
-  sqlite3_value **apArg
-){
-}
-static void nth_valueValueFunc(sqlite3_context *pCtx){
-}
-
-static void first_valueStepFunc(
-  sqlite3_context *pCtx, 
-  int nArg,
-  sqlite3_value **apArg
-){
-}
-static void first_valueInverseFunc(
-  sqlite3_context *pCtx, 
-  int nArg,
-  sqlite3_value **apArg
-){
-}
-static void first_valueValueFunc(sqlite3_context *pCtx){
-}
-
-static void leadStepFunc(
-  sqlite3_context *pCtx, 
-  int nArg,
-  sqlite3_value **apArg
-){
-}
-static void leadInverseFunc(
-  sqlite3_context *pCtx, 
-  int nArg,
-  sqlite3_value **apArg
-){
-}
-static void leadValueFunc(sqlite3_context *pCtx){
-}
-
-static void lagStepFunc(
-  sqlite3_context *pCtx, 
-  int nArg,
-  sqlite3_value **apArg
-){
-}
-static void lagInverseFunc(
-  sqlite3_context *pCtx, 
-  int nArg,
-  sqlite3_value **apArg
-){
-}
-static void lagValueFunc(sqlite3_context *pCtx){
-}
+/*
+** No-op implementations of nth_value(), first_value(), lead() and lag().
+** These are all implemented inline using VDBE instructions. 
+*/
+static void nth_valueStepFunc(sqlite3_context *pCtx, int n, sqlite3_value **a){}
+static void nth_valueInvFunc(sqlite3_context *pCtx, int n, sqlite3_value **ap){}
+static void nth_valueValueFunc(sqlite3_context *pCtx){}
+static void first_valueStepFunc(sqlite3_context *p, int n, sqlite3_value **ap){}
+static void first_valueInvFunc(sqlite3_context *p, int n, sqlite3_value **ap){}
+static void first_valueValueFunc(sqlite3_context *pCtx){}
+static void leadStepFunc(sqlite3_context *pCtx, int n, sqlite3_value **ap){}
+static void leadInvFunc(sqlite3_context *pCtx, int n, sqlite3_value **ap){}
+static void leadValueFunc(sqlite3_context *pCtx){}
+static void lagStepFunc(sqlite3_context *pCtx, int n, sqlite3_value **ap){}
+static void lagInvFunc(sqlite3_context *pCtx, int n, sqlite3_value **ap){}
+static void lagValueFunc(sqlite3_context *pCtx){}
 
 #define WINDOWFUNC(name,nArg,extra) {                                      \
   nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0,                      \
   name ## StepFunc, name ## ValueFunc, name ## ValueFunc,                  \
-  name ## InverseFunc, #name                                               \
+  name ## InvFunc, #name                                               \
 }
 
 #define WINDOWFUNCF(name,nArg,extra) {                                     \
   nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0,                      \
   name ## StepFunc, name ## FinalizeFunc, name ## ValueFunc,               \
-  name ## InverseFunc, #name                                               \
+  name ## InvFunc, #name                                               \
 }
 
 /*
@@ -437,6 +401,7 @@ void sqlite3WindowUpdate(
       pWin->eEnd = TK_CURRENT;
     }
   }
+  pWin->pFunc = pFunc;
 }
 
 typedef struct WindowRewrite WindowRewrite;
@@ -462,7 +427,7 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
         Window *pWin;
         for(pWin=p->pWin; pWin; pWin=pWin->pNextWin){
           if( pExpr->pWin==pWin ){
-            pExpr->pWin->pOwner = pExpr;
+            assert( pWin->pOwner==pExpr );
             return WRC_Prune;
           }
         }
@@ -684,6 +649,7 @@ Window *sqlite3WindowAlloc(
 void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
   if( p ){
     p->pWin = pWin;
+    if( pWin ) pWin->pOwner = p;
   }else{
     sqlite3WindowDelete(pParse->db, pWin);
   }
@@ -766,6 +732,11 @@ static void windowCheckFrameValue(Parse *pParse, int reg, int bEnd){
   sqlite3VdbeAppendP4(v, (void*)azErr[bEnd], P4_STATIC);
 }
 
+static int windowArgCount(Window *pWin){
+  ExprList *pList = pWin->pOwner->x.pList;
+  return (pList ? pList->nExpr : 0);
+}
+
 /*
 ** Generate VM code to invoke either xStep() (if bInverse is 0) or 
 ** xInverse (if bInverse is non-zero) for each window function in the 
@@ -784,11 +755,11 @@ static void windowAggStep(
   for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
     int flags = pWin->pFunc->funcFlags;
     int regArg;
-    int nArg = pWin->nArg;
+    int nArg = windowArgCount(pWin);
 
     if( csr>=0 ){
       int i;
-      for(i=0; i<pWin->nArg; i++){
+      for(i=0; i<nArg; i++){
         sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i);
       }
       regArg = reg;
@@ -832,11 +803,12 @@ static void windowAggStep(
       int addrIf = 0;
       if( pWin->pFilter ){
         int regTmp;
+        assert( nArg==pWin->pOwner->x.pList->nExpr );
         if( csr>0 ){
           regTmp = sqlite3GetTempReg(pParse);
-          sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+pWin->nArg,regTmp);
+          sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
         }else{
-          regTmp = regArg + pWin->nArg;
+          regTmp = regArg + nArg;
         }
         addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
         if( csr>0 ){
@@ -876,7 +848,7 @@ static void windowAggFinal(Parse *pParse, Window *pMWin, int bFinal){
       if( bFinal==0 ){
         sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
       }
-      sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, pWin->nArg);
+      sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, windowArgCount(pWin));
       sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
       if( bFinal ){
         sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult);
@@ -975,18 +947,19 @@ static void windowReturnOneRow(
       sqlite3ReleaseTempReg(pParse, tmpReg);
     }
     else if( pFunc->xSFunc==leadStepFunc || pFunc->xSFunc==lagStepFunc ){
+      int nArg = pWin->pOwner->x.pList->nExpr;
       int iEph = pWin->iEphCsr;
       int csr = pWin->csrApp;
       int lbl = sqlite3VdbeMakeLabel(v);
       int tmpReg = sqlite3GetTempReg(pParse);
 
-      if( pWin->nArg<3 ){
+      if( nArg<3 ){
         sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
       }else{
         sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+2, pWin->regResult);
       }
       sqlite3VdbeAddOp2(v, OP_Rowid, iEph, tmpReg);
-      if( pWin->nArg<2 ){
+      if( nArg<2 ){
         int val = (pFunc->xSFunc==leadStepFunc ? 1 : -1);
         sqlite3VdbeAddOp2(v, OP_AddImm, tmpReg, val);
       }else{
@@ -1036,7 +1009,7 @@ static int windowInitAccum(Parse *pParse, Window *pMWin){
   Window *pWin;
   for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
     sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
-    nArg = MAX(nArg, pWin->nArg);
+    nArg = MAX(nArg, windowArgCount(pWin));
     if( pWin->pFunc->xSFunc==nth_valueStepFunc
      || pWin->pFunc->xSFunc==first_valueStepFunc 
     ){
@@ -1663,7 +1636,7 @@ static void windowCodeDefaultStep(
   sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1);
 }
 
-Window *sqlite3WindowDup(sqlite3 *db, Window *p){
+Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
   Window *pNew = 0;
   if( p ){
     pNew = sqlite3DbMallocZero(db, sizeof(Window));
@@ -1676,77 +1649,30 @@ Window *sqlite3WindowDup(sqlite3 *db, Window *p){
       pNew->eStart = p->eStart;
       pNew->pStart = sqlite3ExprDup(db, pNew->pStart, 0);
       pNew->pEnd = sqlite3ExprDup(db, pNew->pEnd, 0);
+      pNew->pOwner = pOwner;
     }
   }
   return pNew;
 }
 
 /*
-** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
-**
-**   As above, except take no action for a "new peer". Invoke
-**   the sub-routine once only for each partition.
-**
-** RANGE BETWEEN CURRENT ROW AND CURRENT ROW
-**
-**   As above, except that the "new peer" condition is handled in the
-**   same way as "new partition" (so there is no "else if" block).
-**
-** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
-**
-**   One way is to just reverse the sort order and do as for BETWEEN 
-**   UNBOUNDED PRECEDING AND CURRENT ROW. But that is not quite the same for
-**   things like group_concat(). And perhaps other user defined aggregates 
-**   as well.
-**
-**   ...
-**     if( new partition ){
-**       Gosub flush_partition;
-**       ResetSorter eph-table
-**     }
-**     AggStep
-**     Insert (record into eph-table)
-**   sqlite3WhereEnd()
-**   Gosub flush_partition
-**
-**  flush_partition:
-**   OpenDup (csr -> csr2)
-**   foreach (record in eph-table) {
-**     if( new peer ){
-**       while( csr2!=csr ){
-**         AggStep (xInverse)
-**         Next (csr2)
-**       }
-**     }
-**     AggFinal (xValue)
-**     Gosub addrGosub
-**   }
-**
-**========================================================================
-**
-** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
-**   ...
-**     if( new partition ){
-**       AggFinal (xFinalize)
-**     }
-**     AggStep
-**     AggFinal (xValue)
-**     Gosub addrGosub
-**   sqlite3WhereEnd()
-**
+** 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
+** invoke the sub-routine at instruction addrGosub once for each row.
+** This function calls sqlite3WhereEnd() before returning. 
 */
 void sqlite3WindowCodeStep(
-  Parse *pParse, 
-  Select *p,
-  WhereInfo *pWInfo,
-  int regGosub, 
-  int addrGosub
+  Parse *pParse,                  /* Parse context */
+  Select *p,                      /* Rewritten SELECT statement */
+  WhereInfo *pWInfo,              /* Context returned by sqlite3WhereBegin() */
+  int regGosub,                   /* Register for OP_Gosub */
+  int addrGosub                   /* OP_Gosub here to return each row */
 ){
   Window *pMWin = p->pWin;
   Window *pWin;
 
-  /*
-  ** Call windowCodeRowExprStep() for all window modes *except*:
+  /* Call windowCodeRowExprStep() for all window modes *except*:
   **
   **   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
   **   RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
@@ -1761,11 +1687,9 @@ void sqlite3WindowCodeStep(
     return;
   }
 
-  /*
-  ** Call windowCodeCacheStep() if there is a window function that requires
+  /* Call windowCodeCacheStep() if there is a window function that requires
   ** that the entire partition be cached in a temp table before any rows
-  ** are returned.
-  */
+  ** are returned.  */
   for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
     FuncDef *pFunc = pWin->pFunc;
     if( (pFunc->funcFlags & SQLITE_FUNC_WINDOW_SIZE)
@@ -1779,6 +1703,7 @@ void sqlite3WindowCodeStep(
     }
   }
 
+  /* Otherwise, call windowCodeDefaultStep().  */
   windowCodeDefaultStep(pParse, p, pWInfo, regGosub, addrGosub);
 }