]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Remove "cache mode" from the window frame code generator. Handle the same cases by...
authordan <dan@noemail.net>
Mon, 11 Mar 2019 19:50:54 +0000 (19:50 +0000)
committerdan <dan@noemail.net>
Mon, 11 Mar 2019 19:50:54 +0000 (19:50 +0000)
FossilOrigin-Name: 081263538332bb9c07e62630629007ccbba31bef5dc890f60b4ba58a355f70ac

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

index 9cce9706fb2bb2b33977b2e57bac8e1becccf1e0..d2f4f74e202e9fe5324a3d9b1e9f4b41b357d306 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Simplify\sthe\swindows\sframe\scode\ssome.\sAdd\sa\scomment\sexplaining\ssome\sof\sthe\sVM\scode\sgenerated\sby\ssqlite3WindowCodeStep().
-D 2019-03-11T18:17:04.702
+C Remove\s"cache\smode"\sfrom\sthe\swindow\sframe\scode\sgenerator.\sHandle\sthe\ssame\scases\sby\sediting\sthe\swindow\sframe\sspecification\sitself.
+D 2019-03-11T19:50:54.722
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F Makefile.in 236d2739dc3e823c3c909bca2d6cef93009bafbefd7018a8f3281074ecb92954
@@ -520,7 +520,7 @@ F src/shell.c.in 01c0cc01391d00d247fdf640052d38c267fc16d975bc4f3154a02277c232dbe
 F src/sqlite.h.in 02be315feaf20c06028aacf3b032b5e7211e9aae066284eef77b081646b43ea0
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 960f1b86c3610fa23cb6a267572a97dcf286e77aa0dd3b9b23292ffaa1ea8683
-F src/sqliteInt.h 24a4818574031facb6ec4fc5fc3b20b8f68c9ec4c85b662a41d1dc4a2ba0524b
+F src/sqliteInt.h 45d85aa38f1148cb7ba514efe39f5d709456c2a5064cb228ead68c59c4628836
 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
 F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -604,7 +604,7 @@ F src/where.c 8a207cb2ca6b99e1edb1e4bbff9b0504385a759cbf66180d1deb34d80ca4b799
 F src/whereInt.h 5f14db426ca46a83eabab1ae9aa6d4b8f27504ad35b64c290916289b1ddb2e88
 F src/wherecode.c ce7b21e1be2b981d62683fc59c4ca73a04a7ff2f1ebec23d41baf2da2349afd6
 F src/whereexpr.c 36b47f7261d6b6f1a72d774c113b74beddf6745aba1018e64b196e29db233442
-F src/window.c ca0d94d256bc52b7815b3c73b00468d0de84021f0d7be1d18588584dc96996b4
+F src/window.c f41e0b36e6c26aa8b858f488498aa8152d6441a09c0e96baa5979269e1f0d199
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
 F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
@@ -1812,7 +1812,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 e7bced731aa071c95bc398cdecd53c939841bf0c52fbcd06e47ba68f8c5cc35a
-R c7a0f784b83bf2fca5c90a7c55a81175
+P 6bd1a07949ff3d394056bfcc813444401ef00806e3f0e0423ff6962541e84bdb
+R 895a04edfc289d379068084b0a252ef5
 U dan
-Z ca63593942babec716fd2593022c4696
+Z ab8b6521d2f2f661581dab04391f3c9a
index 1e36a97868547daa9c3d77a27ecac26a3b2930eb..86b00a9cb0a9cfe9e5737ab1ee84af9a39402f3e 100644 (file)
@@ -1 +1 @@
-6bd1a07949ff3d394056bfcc813444401ef00806e3f0e0423ff6962541e84bdb
\ No newline at end of file
+081263538332bb9c07e62630629007ccbba31bef5dc890f60b4ba58a355f70ac
\ No newline at end of file
index 5c7cac4f25d8c722edb399679de3ba7ac9141f4b..70de5d472520e06fcfd430a615144806457c4097 100644 (file)
@@ -1691,7 +1691,6 @@ struct FuncDestructor {
 #define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */
 #define SQLITE_FUNC_OFFSET   0x8000 /* Built-in sqlite_offset() function */
 #define SQLITE_FUNC_WINDOW   0x00010000 /* Built-in window-only function */
-#define SQLITE_FUNC_WINDOW_SIZE 0x20000 /* Requires partition size as arg. */
 #define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
 
 /*
@@ -3577,9 +3576,7 @@ struct Window {
   Expr *pOwner;           /* Expression object this window is attached to */
   int nBufferCol;         /* Number of columns in buffer table */
   int iArgCol;            /* Offset of first argument for this function */
-
   int regFirst;
-  int regSize;
 };
 
 #ifndef SQLITE_OMIT_WINDOWFUNC
index 1b66fc0b3f935a6dbea7cd1eb3daa87ad0499a9e..094f6eaa37bf9f4210f2a50c0837c30aa5869e6a 100644 (file)
@@ -233,7 +233,7 @@ static void rankValueFunc(sqlite3_context *pCtx){
 ** Implementation of built-in window function percent_rank(). Assumes that
 ** the window frame has been set to:
 **
-**   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
+**   GROUPS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
 */
 static void percent_rankStepFunc(
   sqlite3_context *pCtx, 
@@ -241,38 +241,42 @@ static void percent_rankStepFunc(
   sqlite3_value **apArg
 ){
   struct CallCount *p;
-  UNUSED_PARAMETER(nArg); assert( nArg==1 );
-
+  UNUSED_PARAMETER(nArg); assert( nArg==0 );
   p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
   if( p ){
-    if( p->nTotal==0 ){
-      p->nTotal = sqlite3_value_int64(apArg[0]);
-    }
-    p->nStep++;
-    if( p->nValue==0 ){
-      p->nValue = p->nStep;
-    }
+    p->nTotal++;
   }
 }
+static void percent_rankInvFunc(
+  sqlite3_context *pCtx, 
+  int nArg,
+  sqlite3_value **apArg
+){
+  struct CallCount *p;
+  UNUSED_PARAMETER(nArg); assert( nArg==0 );
+  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+  p->nStep++;
+}
 static void percent_rankValueFunc(sqlite3_context *pCtx){
   struct CallCount *p;
   p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
   if( p ){
+    p->nValue = p->nStep;
     if( p->nTotal>1 ){
-      double r = (double)(p->nValue-1) / (double)(p->nTotal-1);
+      double r = (double)p->nValue / (double)(p->nTotal-1);
       sqlite3_result_double(pCtx, r);
     }else{
       sqlite3_result_double(pCtx, 0.0);
     }
-    p->nValue = 0;
   }
 }
+#define percent_rankFinalizeFunc percent_rankValueFunc
 
 /*
 ** Implementation of built-in window function cume_dist(). Assumes that
 ** the window frame has been set to:
 **
-**   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
+**   GROUPS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING
 */
 static void cume_distStepFunc(
   sqlite3_context *pCtx, 
@@ -280,16 +284,22 @@ static void cume_distStepFunc(
   sqlite3_value **apArg
 ){
   struct CallCount *p;
-  assert( nArg==1 ); UNUSED_PARAMETER(nArg);
-
+  UNUSED_PARAMETER(nArg); assert( nArg==0 );
   p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
   if( p ){
-    if( p->nTotal==0 ){
-      p->nTotal = sqlite3_value_int64(apArg[0]);
-    }
-    p->nStep++;
+    p->nTotal++;
   }
 }
+static void cume_distInvFunc(
+  sqlite3_context *pCtx, 
+  int nArg,
+  sqlite3_value **apArg
+){
+  struct CallCount *p;
+  UNUSED_PARAMETER(nArg); assert( nArg==0 );
+  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+  p->nStep++;
+}
 static void cume_distValueFunc(sqlite3_context *pCtx){
   struct CallCount *p;
   p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
@@ -298,6 +308,7 @@ static void cume_distValueFunc(sqlite3_context *pCtx){
     sqlite3_result_double(pCtx, r);
   }
 }
+#define cume_distFinalizeFunc cume_distValueFunc
 
 /*
 ** Context object for ntile() window function.
@@ -312,7 +323,7 @@ struct NtileCtx {
 ** Implementation of ntile(). This assumes that the window frame has
 ** been coerced to:
 **
-**   ROWS UNBOUNDED PRECEDING AND CURRENT ROW
+**   ROWS CURRENT ROW AND UNBOUNDED FOLLOWING
 */
 static void ntileStepFunc(
   sqlite3_context *pCtx, 
@@ -320,32 +331,41 @@ static void ntileStepFunc(
   sqlite3_value **apArg
 ){
   struct NtileCtx *p;
-  assert( nArg==2 ); UNUSED_PARAMETER(nArg);
+  assert( nArg==1 ); UNUSED_PARAMETER(nArg);
   p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
   if( p ){
     if( p->nTotal==0 ){
       p->nParam = sqlite3_value_int64(apArg[0]);
-      p->nTotal = sqlite3_value_int64(apArg[1]);
       if( p->nParam<=0 ){
         sqlite3_result_error(
             pCtx, "argument of ntile must be a positive integer", -1
         );
       }
     }
-    p->iRow++;
+    p->nTotal++;
   }
 }
+static void ntileInvFunc(
+  sqlite3_context *pCtx, 
+  int nArg,
+  sqlite3_value **apArg
+){
+  struct NtileCtx *p;
+  assert( nArg==1 ); UNUSED_PARAMETER(nArg);
+  p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+  p->iRow++;
+}
 static void ntileValueFunc(sqlite3_context *pCtx){
   struct NtileCtx *p;
   p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
   if( p && p->nParam>0 ){
     int nSize = (p->nTotal / p->nParam);
     if( nSize==0 ){
-      sqlite3_result_int64(pCtx, p->iRow);
+      sqlite3_result_int64(pCtx, p->iRow+1);
     }else{
       i64 nLarge = p->nTotal - p->nParam*nSize;
       i64 iSmall = nLarge*(nSize+1);
-      i64 iRow = p->iRow-1;
+      i64 iRow = p->iRow;
 
       assert( (nLarge*(nSize+1) + (p->nParam-nLarge)*nSize)==p->nTotal );
 
@@ -357,6 +377,7 @@ static void ntileValueFunc(sqlite3_context *pCtx){
     }
   }
 }
+#define ntileFinalizeFunc ntileValueFunc
 
 /*
 ** Context object for last_value() window function.
@@ -496,9 +517,12 @@ void sqlite3WindowFunctions(void){
     WINDOWFUNCX(row_number, 0, 0),
     WINDOWFUNCX(dense_rank, 0, 0),
     WINDOWFUNCX(rank, 0, 0),
-    WINDOWFUNCX(percent_rank, 0, SQLITE_FUNC_WINDOW_SIZE),
-    WINDOWFUNCX(cume_dist, 0, SQLITE_FUNC_WINDOW_SIZE),
-    WINDOWFUNCX(ntile, 1, SQLITE_FUNC_WINDOW_SIZE),
+    // WINDOWFUNCX(percent_rank, 0, SQLITE_FUNC_WINDOW_SIZE),
+    WINDOWFUNCALL(percent_rank, 0, 0),
+    WINDOWFUNCALL(cume_dist, 0, 0),
+    WINDOWFUNCALL(ntile, 1, 0),
+    // WINDOWFUNCX(cume_dist, 0, SQLITE_FUNC_WINDOW_SIZE),
+    // WINDOWFUNCX(ntile, 1, SQLITE_FUNC_WINDOW_SIZE),
     WINDOWFUNCALL(last_value, 1, 0),
     WINDOWFUNCNOOP(nth_value, 2, 0),
     WINDOWFUNCNOOP(first_value, 1, 0),
@@ -573,25 +597,36 @@ void sqlite3WindowUpdate(
       sqlite3ErrorMsg(pParse, 
           "FILTER clause may only be used with aggregate window functions"
       );
-    }else
-    if( pFunc->zName==row_numberName || pFunc->zName==ntileName ){
-      sqlite3ExprDelete(db, pWin->pStart);
-      sqlite3ExprDelete(db, pWin->pEnd);
-      pWin->pStart = pWin->pEnd = 0;
-      pWin->eType = TK_ROWS;
-      pWin->eStart = TK_UNBOUNDED;
-      pWin->eEnd = TK_CURRENT;
-    }else
-
-    if( pFunc->zName==dense_rankName || pFunc->zName==rankName
-     || pFunc->zName==percent_rankName || pFunc->zName==cume_distName
-    ){
-      sqlite3ExprDelete(db, pWin->pStart);
-      sqlite3ExprDelete(db, pWin->pEnd);
-      pWin->pStart = pWin->pEnd = 0;
-      pWin->eType = TK_RANGE;
-      pWin->eStart = TK_UNBOUNDED;
-      pWin->eEnd = TK_CURRENT;
+    }else{
+      struct WindowUpdate {
+        const char *zFunc;
+        int eType;
+        int eStart;
+        int eEnd;
+      } aUp[] = {
+        { row_numberName,   TK_ROWS,   TK_UNBOUNDED, TK_CURRENT }, 
+        { dense_rankName,   TK_RANGE,  TK_UNBOUNDED, TK_CURRENT }, 
+        { rankName,         TK_RANGE,  TK_UNBOUNDED, TK_CURRENT }, 
+        { percent_rankName, TK_GROUPS, TK_CURRENT,   TK_UNBOUNDED }, 
+        { cume_distName,    TK_GROUPS, TK_FOLLOWING, TK_UNBOUNDED }, 
+        { ntileName,        TK_ROWS,   TK_CURRENT,   TK_UNBOUNDED }, 
+        { leadName,         TK_ROWS,   TK_UNBOUNDED, TK_UNBOUNDED }, 
+      };
+      int i;
+      for(i=0; i<ArraySize(aUp); i++){
+        if( pFunc->zName==aUp[i].zFunc ){
+          sqlite3ExprDelete(db, pWin->pStart);
+          sqlite3ExprDelete(db, pWin->pEnd);
+          pWin->pEnd = pWin->pStart = 0;
+          pWin->eType = aUp[i].eType;
+          pWin->eStart = aUp[i].eStart;
+          pWin->eEnd = aUp[i].eEnd;
+          if( pWin->eStart==TK_FOLLOWING ){
+            pWin->pStart = sqlite3Expr(db, TK_INTEGER, "1");
+          }
+          break;
+        }
+      }
     }
   }
   pWin->pFunc = pFunc;
@@ -1092,8 +1127,6 @@ void sqlite3WindowCodeInit(Parse *pParse, Window *pMWin){
 
   pMWin->regFirst = ++pParse->nMem;
   sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regFirst);
-  pMWin->regSize = ++pParse->nMem;
-  sqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regSize);
 
   for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
     FuncDef *p = pWin->pFunc;
@@ -1206,7 +1239,6 @@ static void windowAggStep(
   Vdbe *v = sqlite3GetVdbe(pParse);
   Window *pWin;
   for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
-    int flags = pWin->pFunc->funcFlags;
     int regArg;
     int nArg = windowArgCount(pWin);
 
@@ -1216,16 +1248,7 @@ static void windowAggStep(
         sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i);
       }
       regArg = reg;
-      if( flags & SQLITE_FUNC_WINDOW_SIZE ){
-        if( nArg==0 ){
-          regArg = regPartSize;
-        }else{
-          sqlite3VdbeAddOp2(v, OP_SCopy, regPartSize, reg+nArg);
-        }
-        nArg++;
-      }
     }else{
-      assert( !(flags & SQLITE_FUNC_WINDOW_SIZE) );
       regArg = reg + pWin->iArgCol;
     }
 
@@ -1440,18 +1463,18 @@ static int windowInitAccum(Parse *pParse, Window *pMWin){
   return regArg;
 }
 
+#if 0
 /* 
-** Return true if the entire partition should be cached in the ephemeral
-** table before processing any rows.
+** Return true if the current frame should be cached in the ephemeral table,
+** even if there are no xInverse() calls required.
 */
-static int windowCachePartition(Window *pMWin){
+static int windowCacheFrame(Window *pMWin){
   Window *pWin;
   for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
     FuncDef *pFunc = pWin->pFunc;
-    if( (pFunc->funcFlags & SQLITE_FUNC_WINDOW_SIZE)
-     || (pFunc->zName==nth_valueName)
+    if( (pFunc->zName==nth_valueName)
      || (pFunc->zName==first_valueName)
-     || (pFunc->zName==leadName)
+     || (pFunc->zName==leadName) */
      || (pFunc->zName==lagName)
     ){
       return 1;
@@ -1459,6 +1482,7 @@ static int windowCachePartition(Window *pMWin){
   }
   return 0;
 }
+#endif
 
 /*
 ** regOld and regNew are each the first register in an array of size
@@ -1659,13 +1683,13 @@ static int windowCodeOp(
     case WINDOW_AGGINVERSE:
       csr = p->start.csr;
       reg = p->start.reg;
-      windowAggStep(pParse, pMWin, csr, 1, p->regArg, pMWin->regSize);
+      windowAggStep(pParse, pMWin, csr, 1, p->regArg, 0);
       break;
 
     case WINDOW_AGGSTEP:
       csr = p->end.csr;
       reg = p->end.reg;
-      windowAggStep(pParse, pMWin, csr, 0, p->regArg, pMWin->regSize);
+      windowAggStep(pParse, pMWin, csr, 0, p->regArg, 0);
       break;
   }
 
@@ -1922,29 +1946,9 @@ Window *sqlite3WindowListDup(sqlite3 *db, Window *p){
 **     while( !eof csrCurrent ){
 **       RETURN_ROW
 **     }
-**
-** Sometimes, this function generates code to run in "cache mode" - meaning
-** the entire partition is cached in the ephemeral table before any of its
-** rows are processed, instead of processing rows as the sub-select delivers
-** them. This is required by certain built-in window functions, for example
-** percent_rank() or lead(). In that case, the relevant pseudo-code above
-** is modified to:
-**
-**     ... loop started by sqlite3WhereBegin() ...
-**     if( new partition ){
-**       Gosub flush
-**     }
-**     Insert new row into eph table.
-**   }
-**   flush:
-**     for each row in eph table {
-**
-** followed immediately by the code that usually follows the "Insert new row
-** into eph table." line.
-**
 */
 void sqlite3WindowCodeStep(
-    Parse *pParse,                  /* Parse context */
+  Parse *pParse,                  /* Parse context */
   Select *p,                      /* Rewritten SELECT statement */
   WhereInfo *pWInfo,              /* Context returned by sqlite3WhereBegin() */
   int regGosub,                   /* Register for OP_Gosub */
@@ -1953,7 +1957,6 @@ void sqlite3WindowCodeStep(
   Window *pMWin = p->pWin;
   ExprList *pOrderBy = pMWin->pOrderBy;
   Vdbe *v = sqlite3GetVdbe(pParse);
-  int bCache;                     /* True if generating "cache-mode" code */
   int regFlushPart;               /* Register for "Gosub flush_partition" */
   int csrWrite;                   /* Cursor used to write to eph. table */
   int csrInput = p->pSrc->a[0].iCursor;     /* Cursor of sub-select */
@@ -1963,8 +1966,6 @@ void sqlite3WindowCodeStep(
   int addrIfNot;                  /* Address of OP_IfNot */
   int addrGosubFlush;             /* Address of OP_Gosub to flush: */
   int addrInteger;                /* Address of OP_Integer */
-  int addrCacheRewind;            /* Address of OP_Rewind used in cache-mode */
-  int addrCacheNext;              /* Jump here for next row in cache-mode */
   int addrShortcut = 0;
   int addrEmpty = 0;              /* Address of OP_Rewind in flush: */
   int addrPeerJump = 0;           /* Address of jump taken if not new peer */
@@ -1986,7 +1987,6 @@ void sqlite3WindowCodeStep(
 
   /* Determine whether or not each partition will be cached before beginning
   ** to process rows within it.  */
-  bCache = windowCachePartition(pMWin);
 
   /* Fill in the context object */
   memset(&s, 0, sizeof(WindowCodeArg));
@@ -2061,19 +2061,8 @@ void sqlite3WindowCodeStep(
   /* Insert the new row into the ephemeral table */
   sqlite3VdbeAddOp2(v, OP_NewRowid, csrWrite, regRowid);
   sqlite3VdbeAddOp3(v, OP_Insert, csrWrite, regRecord, regRowid);
-  sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regSize, 1);
 
-  if( bCache ){
-    sqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regFirst);
-    sqlite3WhereEnd(pWInfo);
-    addrInteger = sqlite3VdbeAddOp2(v, OP_Integer, 0, regFlushPart);
-    if( pMWin->pPartition ){
-      sqlite3VdbeJumpHere(v, addrGosubFlush);
-    }
-    addrCacheRewind = sqlite3VdbeAddOp1(v, OP_Rewind, csrWrite);
-  }else{
-    addrIfNot = sqlite3VdbeAddOp1(v, OP_IfNot, pMWin->regFirst);
-  }
+  addrIfNot = sqlite3VdbeAddOp1(v, OP_IfNot, pMWin->regFirst);
 
   /* This block is run for the first row of each partition */
   s.regArg = windowInitAccum(pParse, pMWin);
@@ -2091,16 +2080,9 @@ void sqlite3WindowCodeStep(
     int op = ((pMWin->eStart==TK_FOLLOWING) ? OP_Ge : OP_Le);
     int addrGe = sqlite3VdbeAddOp3(v, op, regStart, 0, regEnd);
     windowAggFinal(pParse, pMWin, 0);
-    if( bCache ){
-      sqlite3VdbeAddOp2(v, OP_Rowid, csrWrite, regRowid);
-      sqlite3VdbeAddOp3(v, OP_NotExists, s.current.csr, 0, regRowid);
-      windowReturnOneRow(pParse, pMWin, regGosub, addrGosub);
-      sqlite3VdbeAddOp2(v, OP_Next, csrWrite, addrCacheRewind+1);
-    }else{
-      sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1);
-      windowReturnOneRow(pParse, pMWin, regGosub, addrGosub);
-      sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr);
-    }
+    sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1);
+    windowReturnOneRow(pParse, pMWin, regGosub, addrGosub);
+    sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr);
     addrShortcut = sqlite3VdbeAddOp0(v, OP_Goto);
     sqlite3VdbeJumpHere(v, addrGe);
   }
@@ -2115,11 +2097,7 @@ void sqlite3WindowCodeStep(
   sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1);
   sqlite3VdbeAddOp2(v, OP_Rewind, s.end.csr, 1);
   if( regPeer && pOrderBy ){
-    if( bCache ){
-      windowReadPeerValues(&s, csrWrite, regPeer);
-    }else{
-      sqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, pOrderBy->nExpr-1);
-    }
+    sqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, pOrderBy->nExpr-1);
     sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.start.reg, pOrderBy->nExpr-1);
     sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.current.reg, pOrderBy->nExpr-1);
     sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.end.reg, pOrderBy->nExpr-1);
@@ -2130,14 +2108,7 @@ void sqlite3WindowCodeStep(
 
   /* Begin generating SECOND_ROW_CODE */
   VdbeModuleComment((pParse->pVdbe, "Begin WindowCodeStep.SECOND_ROW"));
-  if( bCache ){
-    addrCacheNext = sqlite3VdbeCurrentAddr(v);
-    if( pMWin->eType!=TK_ROWS ){
-      windowReadPeerValues(&s, csrWrite, regNewPeer);
-    }
-  }else{
-    sqlite3VdbeJumpHere(v, addrIfNot);
-  }
+  sqlite3VdbeJumpHere(v, addrIfNot);
   if( regPeer ){
     addrPeerJump = windowIfNewPeer(pParse, pOrderBy, regNewPeer, regPeer);
   }
@@ -2194,16 +2165,11 @@ void sqlite3WindowCodeStep(
 
   /* End of the main input loop */
   sqlite3VdbeJumpHere(v, addrGoto);
-  if( bCache ){
-    sqlite3VdbeAddOp2(v, OP_Next, csrWrite, addrCacheNext);
-    sqlite3VdbeJumpHere(v, addrCacheRewind); 
-  }else{
-    if( addrShortcut>0 ) sqlite3VdbeJumpHere(v, addrShortcut);
-    sqlite3WhereEnd(pWInfo);
-  }
+  if( addrShortcut>0 ) sqlite3VdbeJumpHere(v, addrShortcut);
+  sqlite3WhereEnd(pWInfo);
 
   /* Fall through */
-  if( pMWin->pPartition && bCache==0 ){
+  if( pMWin->pPartition ){
     addrInteger = sqlite3VdbeAddOp2(v, OP_Integer, 0, regFlushPart);
     sqlite3VdbeJumpHere(v, addrGosubFlush);
   }
@@ -2254,10 +2220,8 @@ void sqlite3WindowCodeStep(
 
   sqlite3VdbeJumpHere(v, addrEmpty);
 
-  if( bCache && addrShortcut>0 ) sqlite3VdbeJumpHere(v, addrShortcut);
   sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr);
-  sqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regSize);
-  if( bCache==0 ) sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regFirst);
+  sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regFirst);
   VdbeModuleComment((pParse->pVdbe, "End WindowCodeStep.FLUSH"));
   if( pMWin->pPartition ){
     sqlite3VdbeChangeP1(v, addrInteger, sqlite3VdbeCurrentAddr(v));