/ Check-in [17198a12]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Merge implementation of SQL window functions from the exp-window-functions into trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256:17198a1206e2fbc9e555881468e8c6980b00e25b5b78a6798a6264ca7384f1ca
User & Date: dan 2018-06-30 20:15:58
Context
2018-06-30
20:26
Avoid a warning in fts5.c due to not using generated routine sqlite3Fts5ParserFallback(). check-in: 65ff5144 user: dan tags: trunk
20:15
Merge implementation of SQL window functions from the exp-window-functions into trunk. check-in: 17198a12 user: dan tags: trunk
20:00
Fix a minor problem in the code for determining whether or not an SQL statement is SQLITE_TOOBIG. Closed-Leaf check-in: 763e6c9e user: dan tags: exp-window-functions
2018-06-21
23:53
Improved context for error_log message coming from sqlite3_prepare(). check-in: fea7ade6 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.in.

   186    186            pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
   187    187            random.lo resolve.lo rowset.lo rtree.lo \
   188    188            sqlite3session.lo select.lo sqlite3rbu.lo status.lo stmt.lo \
   189    189            table.lo threads.lo tokenize.lo treeview.lo trigger.lo \
   190    190            update.lo upsert.lo util.lo vacuum.lo \
   191    191            vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \
   192    192            vdbetrace.lo wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \
   193         -         utf.lo vtab.lo
          193  +         window.lo utf.lo vtab.lo
   194    194   
   195    195   # Object files for the amalgamation.
   196    196   #
   197    197   LIBOBJS1 = sqlite3.lo
   198    198   
   199    199   # Determine the real value of LIBOBJ based on the 'configure' script
   200    200   #
................................................................................
   300    300     $(TOP)/src/vxworks.h \
   301    301     $(TOP)/src/wal.c \
   302    302     $(TOP)/src/wal.h \
   303    303     $(TOP)/src/walker.c \
   304    304     $(TOP)/src/where.c \
   305    305     $(TOP)/src/wherecode.c \
   306    306     $(TOP)/src/whereexpr.c \
   307         -  $(TOP)/src/whereInt.h
          307  +  $(TOP)/src/whereInt.h \
          308  +  $(TOP)/src/window.c
   308    309   
   309    310   # Source code for extensions
   310    311   #
   311    312   SRC += \
   312    313     $(TOP)/ext/fts1/fts1.c \
   313    314     $(TOP)/ext/fts1/fts1.h \
   314    315     $(TOP)/ext/fts1/fts1_hash.c \
................................................................................
   414    415     $(TOP)/src/test_superlock.c \
   415    416     $(TOP)/src/test_syscall.c \
   416    417     $(TOP)/src/test_tclsh.c \
   417    418     $(TOP)/src/test_tclvar.c \
   418    419     $(TOP)/src/test_thread.c \
   419    420     $(TOP)/src/test_vfs.c \
   420    421     $(TOP)/src/test_windirent.c \
          422  +  $(TOP)/src/test_window.c \
   421    423     $(TOP)/src/test_wsd.c       \
   422    424     $(TOP)/ext/fts3/fts3_term.c \
   423    425     $(TOP)/ext/fts3/fts3_test.c  \
   424    426     $(TOP)/ext/session/test_session.c \
   425    427     $(TOP)/ext/rbu/test_rbu.c 
   426    428   
   427    429   # Statically linked extensions
................................................................................
   489    491     $(TOP)/src/vdbeaux.c \
   490    492     $(TOP)/src/vdbe.c \
   491    493     $(TOP)/src/vdbemem.c \
   492    494     $(TOP)/src/vdbetrace.c \
   493    495     $(TOP)/src/where.c \
   494    496     $(TOP)/src/wherecode.c \
   495    497     $(TOP)/src/whereexpr.c \
          498  +  $(TOP)/src/window.c \
   496    499     parse.c \
   497    500     $(TOP)/ext/fts3/fts3.c \
   498    501     $(TOP)/ext/fts3/fts3_aux.c \
   499    502     $(TOP)/ext/fts3/fts3_expr.c \
   500    503     $(TOP)/ext/fts3/fts3_term.c \
   501    504     $(TOP)/ext/fts3/fts3_tokenizer.c \
   502    505     $(TOP)/ext/fts3/fts3_write.c \
................................................................................
   963    966   
   964    967   wherecode.lo:	$(TOP)/src/wherecode.c $(HDR)
   965    968   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/wherecode.c
   966    969   
   967    970   whereexpr.lo:	$(TOP)/src/whereexpr.c $(HDR)
   968    971   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/whereexpr.c
   969    972   
          973  +window.lo:	$(TOP)/src/window.c $(HDR)
          974  +	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/window.c
          975  +
   970    976   tclsqlite.lo:	$(TOP)/src/tclsqlite.c $(HDR)
   971    977   	$(LTCOMPILE) -DUSE_TCL_STUBS=1 -c $(TOP)/src/tclsqlite.c
   972    978   
   973    979   tclsqlite-shell.lo:	$(TOP)/src/tclsqlite.c $(HDR)
   974    980   	$(LTCOMPILE) -DTCLSH -o $@ -c $(TOP)/src/tclsqlite.c
   975    981   
   976    982   tclsqlite-stubs.lo:	$(TOP)/src/tclsqlite.c $(HDR)

Changes to Makefile.msc.

  1192   1192            pager.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
  1193   1193            random.lo resolve.lo rowset.lo rtree.lo \
  1194   1194            sqlite3session.lo select.lo sqlite3rbu.lo status.lo \
  1195   1195            table.lo threads.lo tokenize.lo treeview.lo trigger.lo \
  1196   1196            update.lo upsert.lo util.lo vacuum.lo \
  1197   1197            vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \
  1198   1198            vdbetrace.lo wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \
  1199         -         utf.lo vtab.lo
         1199  +         window.lo utf.lo vtab.lo
  1200   1200   # <</mark>>
  1201   1201   
  1202   1202   # Object files for the amalgamation.
  1203   1203   #
  1204   1204   LIBOBJS1 = sqlite3.lo
  1205   1205   
  1206   1206   # Determine the real value of LIBOBJ based on the 'configure' script
................................................................................
  1303   1303     $(TOP)\src\vdbesort.c \
  1304   1304     $(TOP)\src\vdbetrace.c \
  1305   1305     $(TOP)\src\vtab.c \
  1306   1306     $(TOP)\src\wal.c \
  1307   1307     $(TOP)\src\walker.c \
  1308   1308     $(TOP)\src\where.c \
  1309   1309     $(TOP)\src\wherecode.c \
  1310         -  $(TOP)\src\whereexpr.c
         1310  +  $(TOP)\src\whereexpr.c \
         1311  +  $(TOP)\src\window.c
  1311   1312   
  1312   1313   # Core miscellaneous files.
  1313   1314   #
  1314   1315   SRC03 = \
  1315   1316     $(TOP)\src\parse.y
  1316   1317   
  1317   1318   # Core header files, part 1.
................................................................................
  1474   1475     $(TOP)\src\test_superlock.c \
  1475   1476     $(TOP)\src\test_syscall.c \
  1476   1477     $(TOP)\src\test_tclsh.c \
  1477   1478     $(TOP)\src\test_tclvar.c \
  1478   1479     $(TOP)\src\test_thread.c \
  1479   1480     $(TOP)\src\test_vfs.c \
  1480   1481     $(TOP)\src\test_windirent.c \
         1482  +  $(TOP)\src\test_window.c \
  1481   1483     $(TOP)\src\test_wsd.c \
  1482   1484     $(TOP)\ext\fts3\fts3_term.c \
  1483   1485     $(TOP)\ext\fts3\fts3_test.c \
  1484   1486     $(TOP)\ext\rbu\test_rbu.c \
  1485   1487     $(TOP)\ext\session\test_session.c
  1486   1488   
  1487   1489   # Statically linked extensions.
................................................................................
  2042   2044   
  2043   2045   wherecode.lo:	$(TOP)\src\wherecode.c $(HDR)
  2044   2046   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\wherecode.c
  2045   2047   
  2046   2048   whereexpr.lo:	$(TOP)\src\whereexpr.c $(HDR)
  2047   2049   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\whereexpr.c
  2048   2050   
         2051  +window.lo:	$(TOP)\src\window.c $(HDR)
         2052  +	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\window.c
         2053  +
  2049   2054   tclsqlite.lo:	$(TOP)\src\tclsqlite.c $(HDR) $(SQLITE_TCL_DEP)
  2050   2055   	$(LTCOMPILE) $(NO_WARN) -DUSE_TCL_STUBS=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
  2051   2056   
  2052   2057   tclsqlite-shell.lo:	$(TOP)\src\tclsqlite.c $(HDR) $(SQLITE_TCL_DEP)
  2053   2058   	$(LTCOMPILE) $(NO_WARN) -DTCLSH -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
  2054   2059   
  2055   2060   tclsqlite3.exe:	tclsqlite-shell.lo $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS)

Changes to main.mk.

    71     71            pager.o pcache.o pcache1.o pragma.o prepare.o printf.o \
    72     72            random.o resolve.o rowset.o rtree.o \
    73     73            select.o sqlite3rbu.o status.o stmt.o \
    74     74            table.o threads.o tokenize.o treeview.o trigger.o \
    75     75            update.o upsert.o userauth.o util.o vacuum.o \
    76     76            vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o vdbesort.o \
    77     77   	 vdbetrace.o wal.o walker.o where.o wherecode.o whereexpr.o \
    78         -         utf.o vtab.o
           78  +         utf.o vtab.o window.o
    79     79   
    80     80   LIBOBJ += sqlite3session.o
    81     81   
    82     82   # All of the source code files.
    83     83   #
    84     84   SRC = \
    85     85     $(TOP)/src/alter.c \
................................................................................
   178    178     $(TOP)/src/vxworks.h \
   179    179     $(TOP)/src/wal.c \
   180    180     $(TOP)/src/wal.h \
   181    181     $(TOP)/src/walker.c \
   182    182     $(TOP)/src/where.c \
   183    183     $(TOP)/src/wherecode.c \
   184    184     $(TOP)/src/whereexpr.c \
   185         -  $(TOP)/src/whereInt.h
          185  +  $(TOP)/src/whereInt.h \
          186  +  $(TOP)/src/window.c
   186    187   
   187    188   # Source code for extensions
   188    189   #
   189    190   SRC += \
   190    191     $(TOP)/ext/fts1/fts1.c \
   191    192     $(TOP)/ext/fts1/fts1.h \
   192    193     $(TOP)/ext/fts1/fts1_hash.c \
................................................................................
   344    345     $(TOP)/src/test_superlock.c \
   345    346     $(TOP)/src/test_syscall.c \
   346    347     $(TOP)/src/test_tclsh.c \
   347    348     $(TOP)/src/test_tclvar.c \
   348    349     $(TOP)/src/test_thread.c \
   349    350     $(TOP)/src/test_vfs.c \
   350    351     $(TOP)/src/test_windirent.c \
          352  +  $(TOP)/src/test_window.c \
   351    353     $(TOP)/src/test_wsd.c
   352    354   
   353    355   # Extensions to be statically loaded.
   354    356   #
   355    357   TESTSRC += \
   356    358     $(TOP)/ext/misc/amatch.c \
   357    359     $(TOP)/ext/misc/carray.c \

Changes to src/alter.c.

    70     70         /* Advance zCsr to the next token. Store that token type in 'token',
    71     71         ** and its length in 'len' (to be used next iteration of this loop).
    72     72         */
    73     73         do {
    74     74           zCsr += len;
    75     75           len = sqlite3GetToken(zCsr, &token);
    76     76         } while( token==TK_SPACE );
    77         -      assert( len>0 );
           77  +      assert( len>0 || !*zCsr );
    78     78       } while( token!=TK_LP && token!=TK_USING );
    79     79   
    80     80       zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql),
    81     81          zSql, zTableName, tname.z+tname.n);
    82     82       sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
    83     83     }
    84     84   }
................................................................................
   194    194         /* Advance zCsr to the next token. Store that token type in 'token',
   195    195         ** and its length in 'len' (to be used next iteration of this loop).
   196    196         */
   197    197         do {
   198    198           zCsr += len;
   199    199           len = sqlite3GetToken(zCsr, &token);
   200    200         }while( token==TK_SPACE );
   201         -      assert( len>0 );
          201  +      assert( len>0 || !*zCsr );
   202    202   
   203    203         /* Variable 'dist' stores the number of tokens read since the most
   204    204         ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN 
   205    205         ** token is read and 'dist' equals 2, the condition stated above
   206    206         ** to be met.
   207    207         **
   208    208         ** Note that ON cannot be a database, table or column name, so

Changes to src/analyze.c.

   481    481   static const FuncDef statInitFuncdef = {
   482    482     2+IsStat34,      /* nArg */
   483    483     SQLITE_UTF8,     /* funcFlags */
   484    484     0,               /* pUserData */
   485    485     0,               /* pNext */
   486    486     statInit,        /* xSFunc */
   487    487     0,               /* xFinalize */
          488  +  0, 0,            /* xValue, xInverse */
   488    489     "stat_init",     /* zName */
   489    490     {0}
   490    491   };
   491    492   
   492    493   #ifdef SQLITE_ENABLE_STAT4
   493    494   /*
   494    495   ** pNew and pOld are both candidate non-periodic samples selected for 
................................................................................
   797    798   static const FuncDef statPushFuncdef = {
   798    799     2+IsStat34,      /* nArg */
   799    800     SQLITE_UTF8,     /* funcFlags */
   800    801     0,               /* pUserData */
   801    802     0,               /* pNext */
   802    803     statPush,        /* xSFunc */
   803    804     0,               /* xFinalize */
          805  +  0, 0,            /* xValue, xInverse */
   804    806     "stat_push",     /* zName */
   805    807     {0}
   806    808   };
   807    809   
   808    810   #define STAT_GET_STAT1 0          /* "stat" column of stat1 table */
   809    811   #define STAT_GET_ROWID 1          /* "rowid" column of stat[34] entry */
   810    812   #define STAT_GET_NEQ   2          /* "neq" column of stat[34] entry */
................................................................................
   948    950   static const FuncDef statGetFuncdef = {
   949    951     1+IsStat34,      /* nArg */
   950    952     SQLITE_UTF8,     /* funcFlags */
   951    953     0,               /* pUserData */
   952    954     0,               /* pNext */
   953    955     statGet,         /* xSFunc */
   954    956     0,               /* xFinalize */
          957  +  0, 0,            /* xValue, xInverse */
   955    958     "stat_get",      /* zName */
   956    959     {0}
   957    960   };
   958    961   
   959    962   static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){
   960    963     assert( regOut!=regStat4 && regOut!=regStat4+1 );
   961    964   #ifdef SQLITE_ENABLE_STAT3_OR_STAT4

Changes to src/attach.c.

   410    410     static const FuncDef detach_func = {
   411    411       1,                /* nArg */
   412    412       SQLITE_UTF8,      /* funcFlags */
   413    413       0,                /* pUserData */
   414    414       0,                /* pNext */
   415    415       detachFunc,       /* xSFunc */
   416    416       0,                /* xFinalize */
          417  +    0, 0,             /* xValue, xInverse */
   417    418       "sqlite_detach",  /* zName */
   418    419       {0}
   419    420     };
   420    421     codeAttach(pParse, SQLITE_DETACH, &detach_func, pDbname, 0, 0, pDbname);
   421    422   }
   422    423   
   423    424   /*
................................................................................
   429    430     static const FuncDef attach_func = {
   430    431       3,                /* nArg */
   431    432       SQLITE_UTF8,      /* funcFlags */
   432    433       0,                /* pUserData */
   433    434       0,                /* pNext */
   434    435       attachFunc,       /* xSFunc */
   435    436       0,                /* xFinalize */
          437  +    0, 0,             /* xValue, xInverse */
   436    438       "sqlite_attach",  /* zName */
   437    439       {0}
   438    440     };
   439    441     codeAttach(pParse, SQLITE_ATTACH, &attach_func, p, p, pDbname, pKey);
   440    442   }
   441    443   #endif /* SQLITE_OMIT_ATTACH */
   442    444   

Changes to src/btree.c.

  5181   5181       assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
  5182   5182       *pRes = 1;
  5183   5183       rc = SQLITE_OK;
  5184   5184     }
  5185   5185     return rc;
  5186   5186   }
  5187   5187   
         5188  +/*
         5189  +** This function is a no-op if cursor pCur does not point to a valid row.
         5190  +** Otherwise, if pCur is valid, configure it so that the next call to
         5191  +** sqlite3BtreeNext() is a no-op.
         5192  +*/
         5193  +#ifndef SQLITE_OMIT_WINDOWFUNC
         5194  +void sqlite3BtreeSkipNext(BtCursor *pCur){
         5195  +  if( pCur->eState==CURSOR_VALID ){
         5196  +    pCur->eState = CURSOR_SKIPNEXT;
         5197  +    pCur->skipNext = 1;
         5198  +  }
         5199  +}
         5200  +#endif /* SQLITE_OMIT_WINDOWFUNC */
         5201  +
  5188   5202   /* Move the cursor to the last entry in the table.  Return SQLITE_OK
  5189   5203   ** on success.  Set *pRes to 0 if the cursor actually points to something
  5190   5204   ** or set *pRes to 1 if the table is empty.
  5191   5205   */
  5192   5206   int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
  5193   5207     int rc;
  5194   5208    

Changes to src/btree.h.

   297    297     int nData;              /* Size of pData.  0 if none. */
   298    298     int nZero;              /* Extra zero data appended after pData,nData */
   299    299   };
   300    300   
   301    301   int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload,
   302    302                          int flags, int seekResult);
   303    303   int sqlite3BtreeFirst(BtCursor*, int *pRes);
          304  +#ifndef SQLITE_OMIT_WINDOWFUNC
          305  +void sqlite3BtreeSkipNext(BtCursor*);
          306  +#endif
   304    307   int sqlite3BtreeLast(BtCursor*, int *pRes);
   305    308   int sqlite3BtreeNext(BtCursor*, int flags);
   306    309   int sqlite3BtreeEof(BtCursor*);
   307    310   int sqlite3BtreePrevious(BtCursor*, int flags);
   308    311   i64 sqlite3BtreeIntegerKey(BtCursor*);
   309    312   #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
   310    313   i64 sqlite3BtreeOffset(BtCursor*);

Changes to src/expr.c.

  1059   1059       if( p->pRight ){
  1060   1060         sqlite3ExprDeleteNN(db, p->pRight);
  1061   1061       }else if( ExprHasProperty(p, EP_xIsSelect) ){
  1062   1062         sqlite3SelectDelete(db, p->x.pSelect);
  1063   1063       }else{
  1064   1064         sqlite3ExprListDelete(db, p->x.pList);
  1065   1065       }
         1066  +    if( !ExprHasProperty(p, EP_Reduced) ){
         1067  +      sqlite3WindowDelete(db, p->pWin);
         1068  +    }
  1066   1069     }
  1067   1070     if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
  1068   1071     if( !ExprHasProperty(p, EP_Static) ){
  1069   1072       sqlite3DbFreeNN(db, p);
  1070   1073     }
  1071   1074   }
  1072   1075   void sqlite3ExprDelete(sqlite3 *db, Expr *p){
................................................................................
  1107   1110   ** The size of the structure can be found by masking the return value
  1108   1111   ** of this routine with 0xfff.  The flags can be found by masking the
  1109   1112   ** return value with EP_Reduced|EP_TokenOnly.
  1110   1113   **
  1111   1114   ** Note that with flags==EXPRDUP_REDUCE, this routines works on full-size
  1112   1115   ** (unreduced) Expr objects as they or originally constructed by the parser.
  1113   1116   ** During expression analysis, extra information is computed and moved into
  1114         -** later parts of teh Expr object and that extra information might get chopped
         1117  +** later parts of the Expr object and that extra information might get chopped
  1115   1118   ** off if the expression is reduced.  Note also that it does not work to
  1116   1119   ** make an EXPRDUP_REDUCE copy of a reduced expression.  It is only legal
  1117   1120   ** to reduce a pristine expression tree from the parser.  The implementation
  1118   1121   ** of dupedExprStructSize() contain multiple assert() statements that attempt
  1119   1122   ** to enforce this constraint.
  1120   1123   */
  1121   1124   static int dupedExprStructSize(Expr *p, int flags){
  1122   1125     int nSize;
  1123   1126     assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
  1124   1127     assert( EXPR_FULLSIZE<=0xfff );
  1125   1128     assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
  1126         -  if( 0==flags || p->op==TK_SELECT_COLUMN ){
         1129  +  if( 0==flags || p->op==TK_SELECT_COLUMN 
         1130  +#ifndef SQLITE_OMIT_WINDOWFUNC
         1131  +   || p->pWin 
         1132  +#endif
         1133  +  ){
  1127   1134       nSize = EXPR_FULLSIZE;
  1128   1135     }else{
  1129   1136       assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
  1130   1137       assert( !ExprHasProperty(p, EP_FromJoin) ); 
  1131   1138       assert( !ExprHasProperty(p, EP_MemToken) );
  1132   1139       assert( !ExprHasProperty(p, EP_NoReduce) );
  1133   1140       if( p->pLeft || p->x.pList ){
................................................................................
  1259   1266           pNew->pRight = p->pRight ?
  1260   1267                          exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0;
  1261   1268         }
  1262   1269         if( pzBuffer ){
  1263   1270           *pzBuffer = zAlloc;
  1264   1271         }
  1265   1272       }else{
         1273  +#ifndef SQLITE_OMIT_WINDOWFUNC
         1274  +      if( ExprHasProperty(p, EP_Reduced|EP_TokenOnly) ){
         1275  +        pNew->pWin = 0;
         1276  +      }else{
         1277  +        pNew->pWin = sqlite3WindowDup(db, pNew, p->pWin);
         1278  +      }
         1279  +#endif /* SQLITE_OMIT_WINDOWFUNC */
  1266   1280         if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
  1267   1281           if( pNew->op==TK_SELECT_COLUMN ){
  1268   1282             pNew->pLeft = p->pLeft;
  1269   1283             assert( p->iColumn==0 || p->pRight==0 );
  1270   1284             assert( p->pRight==0  || p->pRight==p->pLeft );
  1271   1285           }else{
  1272   1286             pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
................................................................................
  1465   1479       pNew->iLimit = 0;
  1466   1480       pNew->iOffset = 0;
  1467   1481       pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
  1468   1482       pNew->addrOpenEphm[0] = -1;
  1469   1483       pNew->addrOpenEphm[1] = -1;
  1470   1484       pNew->nSelectRow = p->nSelectRow;
  1471   1485       pNew->pWith = withDup(db, p->pWith);
         1486  +#ifndef SQLITE_OMIT_WINDOWFUNC
         1487  +    pNew->pWin = 0;
         1488  +    pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn);
         1489  +#endif
  1472   1490       sqlite3SelectSetName(pNew, p->zSelName);
  1473   1491       *pp = pNew;
  1474   1492       pp = &pNew->pPrior;
  1475   1493       pNext = pNew;
  1476   1494     }
  1477   1495   
  1478   1496     return pRet;
................................................................................
  3783   3801         FuncDef *pDef;         /* The function definition object */
  3784   3802         const char *zId;       /* The function name */
  3785   3803         u32 constMask = 0;     /* Mask of function arguments that are constant */
  3786   3804         int i;                 /* Loop counter */
  3787   3805         sqlite3 *db = pParse->db;  /* The database connection */
  3788   3806         u8 enc = ENC(db);      /* The text encoding used by this database */
  3789   3807         CollSeq *pColl = 0;    /* A collating sequence */
         3808  +
         3809  +#ifndef SQLITE_OMIT_WINDOWFUNC
         3810  +      if( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) && pExpr->pWin ){
         3811  +        return pExpr->pWin->regResult;
         3812  +      }
         3813  +#endif
  3790   3814   
  3791   3815         if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
  3792   3816           /* SQL functions can be expensive. So try to move constant functions
  3793   3817           ** out of the inner loop, even if that means an extra OP_Copy. */
  3794   3818           return sqlite3ExprCodeAtInit(pParse, pExpr, -1);
  3795   3819         }
  3796   3820         assert( !ExprHasProperty(pExpr, EP_xIsSelect) );

Changes to src/func.c.

  1509   1509         }
  1510   1510       }else{
  1511   1511         p->rSum += sqlite3_value_double(argv[0]);
  1512   1512         p->approx = 1;
  1513   1513       }
  1514   1514     }
  1515   1515   }
         1516  +#ifndef SQLITE_OMIT_WINDOWFUNC
         1517  +static void sumInverse(sqlite3_context *context, int argc, sqlite3_value**argv){
         1518  +  SumCtx *p;
         1519  +  int type;
         1520  +  assert( argc==1 );
         1521  +  UNUSED_PARAMETER(argc);
         1522  +  p = sqlite3_aggregate_context(context, sizeof(*p));
         1523  +  type = sqlite3_value_numeric_type(argv[0]);
         1524  +  if( p && type!=SQLITE_NULL ){
         1525  +    p->cnt--;
         1526  +    if( type==SQLITE_INTEGER ){
         1527  +      i64 v = sqlite3_value_int64(argv[0]);
         1528  +      p->rSum -= v;
         1529  +      if( (p->approx|p->overflow)==0 && sqlite3AddInt64(&p->iSum, -1*v) ){
         1530  +        p->overflow = 1;
         1531  +      }
         1532  +    }else{
         1533  +      p->rSum += sqlite3_value_double(argv[0]);
         1534  +      p->approx = 1;
         1535  +    }
         1536  +  }
         1537  +}
         1538  +#else
         1539  +# define sumInverse 0
         1540  +#endif /* SQLITE_OMIT_WINDOWFUNC */
  1516   1541   static void sumFinalize(sqlite3_context *context){
  1517   1542     SumCtx *p;
  1518   1543     p = sqlite3_aggregate_context(context, 0);
  1519   1544     if( p && p->cnt>0 ){
  1520   1545       if( p->overflow ){
  1521   1546         sqlite3_result_error(context,"integer overflow",-1);
  1522   1547       }else if( p->approx ){
................................................................................
  1585   1610     Mem *pArg  = (Mem *)argv[0];
  1586   1611     Mem *pBest;
  1587   1612     UNUSED_PARAMETER(NotUsed);
  1588   1613   
  1589   1614     pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest));
  1590   1615     if( !pBest ) return;
  1591   1616   
  1592         -  if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
         1617  +  if( sqlite3_value_type(pArg)==SQLITE_NULL ){
  1593   1618       if( pBest->flags ) sqlite3SkipAccumulatorLoad(context);
  1594   1619     }else if( pBest->flags ){
  1595   1620       int max;
  1596   1621       int cmp;
  1597   1622       CollSeq *pColl = sqlite3GetFuncCollSeq(context);
  1598   1623       /* This step function is used for both the min() and max() aggregates,
  1599   1624       ** the only difference between the two being that the sense of the
................................................................................
  1611   1636         sqlite3SkipAccumulatorLoad(context);
  1612   1637       }
  1613   1638     }else{
  1614   1639       pBest->db = sqlite3_context_db_handle(context);
  1615   1640       sqlite3VdbeMemCopy(pBest, pArg);
  1616   1641     }
  1617   1642   }
  1618         -static void minMaxFinalize(sqlite3_context *context){
         1643  +static void minMaxValueFinalize(sqlite3_context *context, int bValue){
  1619   1644     sqlite3_value *pRes;
  1620   1645     pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0);
  1621   1646     if( pRes ){
  1622   1647       if( pRes->flags ){
  1623   1648         sqlite3_result_value(context, pRes);
  1624   1649       }
  1625         -    sqlite3VdbeMemRelease(pRes);
         1650  +    if( bValue==0 ) sqlite3VdbeMemRelease(pRes);
  1626   1651     }
  1627   1652   }
         1653  +#ifndef SQLITE_OMIT_WINDOWFUNC
         1654  +static void minMaxValue(sqlite3_context *context){
         1655  +  return minMaxValueFinalize(context, 1);
         1656  +}
         1657  +#else
         1658  +# define minMaxValue 0
         1659  +#endif /* SQLITE_OMIT_WINDOWFUNC */
         1660  +static void minMaxFinalize(sqlite3_context *context){
         1661  +  return minMaxValueFinalize(context, 0);
         1662  +}
  1628   1663   
  1629   1664   /*
  1630   1665   ** group_concat(EXPR, ?SEPARATOR?)
  1631   1666   */
  1632   1667   static void groupConcatStep(
  1633   1668     sqlite3_context *context,
  1634   1669     int argc,
................................................................................
  1657   1692         if( zSep ) sqlite3_str_append(pAccum, zSep, nSep);
  1658   1693       }
  1659   1694       zVal = (char*)sqlite3_value_text(argv[0]);
  1660   1695       nVal = sqlite3_value_bytes(argv[0]);
  1661   1696       if( zVal ) sqlite3_str_append(pAccum, zVal, nVal);
  1662   1697     }
  1663   1698   }
         1699  +#ifndef SQLITE_OMIT_WINDOWFUNC
         1700  +static void groupConcatInverse(
         1701  +  sqlite3_context *context,
         1702  +  int argc,
         1703  +  sqlite3_value **argv
         1704  +){
         1705  +  int n;
         1706  +  assert( argc==1 || argc==2 );
         1707  +  StrAccum *pAccum;
         1708  +  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
         1709  +  pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum));
         1710  +  if( pAccum ){
         1711  +    n = sqlite3_value_bytes(argv[0]);
         1712  +    if( argc==2 ){
         1713  +      n += sqlite3_value_bytes(argv[1]);
         1714  +    }
         1715  +    if( n>=pAccum->nChar ){
         1716  +      pAccum->nChar = 0;
         1717  +    }else{
         1718  +      pAccum->nChar -= n;
         1719  +      memmove(pAccum->zText, &pAccum->zText[n], pAccum->nChar);
         1720  +    }
         1721  +    if( pAccum->nChar==0 ) pAccum->mxAlloc = 0;
         1722  +  }
         1723  +}
         1724  +#else
         1725  +# define groupConcatInverse 0
         1726  +#endif /* SQLITE_OMIT_WINDOWFUNC */
  1664   1727   static void groupConcatFinalize(sqlite3_context *context){
  1665   1728     StrAccum *pAccum;
  1666   1729     pAccum = sqlite3_aggregate_context(context, 0);
  1667   1730     if( pAccum ){
  1668   1731       if( pAccum->accError==SQLITE_TOOBIG ){
  1669   1732         sqlite3_result_error_toobig(context);
  1670   1733       }else if( pAccum->accError==SQLITE_NOMEM ){
................................................................................
  1671   1734         sqlite3_result_error_nomem(context);
  1672   1735       }else{    
  1673   1736         sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1, 
  1674   1737                             sqlite3_free);
  1675   1738       }
  1676   1739     }
  1677   1740   }
         1741  +#ifndef SQLITE_OMIT_WINDOWFUNC
         1742  +static void groupConcatValue(sqlite3_context *context){
         1743  +  sqlite3_str *pAccum;
         1744  +  pAccum = (sqlite3_str*)sqlite3_aggregate_context(context, 0);
         1745  +  if( pAccum ){
         1746  +    if( pAccum->accError==SQLITE_TOOBIG ){
         1747  +      sqlite3_result_error_toobig(context);
         1748  +    }else if( pAccum->accError==SQLITE_NOMEM ){
         1749  +      sqlite3_result_error_nomem(context);
         1750  +    }else{    
         1751  +      const char *zText = sqlite3_str_value(pAccum);
         1752  +      sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT);
         1753  +    }
         1754  +  }
         1755  +}
         1756  +#else
         1757  +# define groupConcatValue 0
         1758  +#endif /* SQLITE_OMIT_WINDOWFUNC */
  1678   1759   
  1679   1760   /*
  1680   1761   ** This routine does per-connection function registration.  Most
  1681   1762   ** of the built-in functions above are part of the global function set.
  1682   1763   ** This routine only deals with those that are not global.
  1683   1764   */
  1684   1765   void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3 *db){
................................................................................
  1708   1789   void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
  1709   1790     struct compareInfo *pInfo;
  1710   1791     if( caseSensitive ){
  1711   1792       pInfo = (struct compareInfo*)&likeInfoAlt;
  1712   1793     }else{
  1713   1794       pInfo = (struct compareInfo*)&likeInfoNorm;
  1714   1795     }
  1715         -  sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0);
  1716         -  sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0);
         1796  +  sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
         1797  +  sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
  1717   1798     sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8, 
  1718         -      (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0);
         1799  +      (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0, 0, 0);
  1719   1800     setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
  1720   1801     setLikeOptFlag(db, "like", 
  1721   1802         caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
  1722   1803   }
  1723   1804   
  1724   1805   /*
  1725   1806   ** pExpr points to an expression which implements a function.  If
................................................................................
  1820   1901       FUNCTION(ltrim,              2, 1, 0, trimFunc         ),
  1821   1902       FUNCTION(rtrim,              1, 2, 0, trimFunc         ),
  1822   1903       FUNCTION(rtrim,              2, 2, 0, trimFunc         ),
  1823   1904       FUNCTION(trim,               1, 3, 0, trimFunc         ),
  1824   1905       FUNCTION(trim,               2, 3, 0, trimFunc         ),
  1825   1906       FUNCTION(min,               -1, 0, 1, minmaxFunc       ),
  1826   1907       FUNCTION(min,                0, 0, 1, 0                ),
  1827         -    AGGREGATE2(min,              1, 0, 1, minmaxStep,      minMaxFinalize,
         1908  +    WAGGREGATE(min, 1, 0, 1, minmaxStep, minMaxFinalize, minMaxValue, 0,
  1828   1909                                             SQLITE_FUNC_MINMAX ),
  1829   1910       FUNCTION(max,               -1, 1, 1, minmaxFunc       ),
  1830   1911       FUNCTION(max,                0, 1, 1, 0                ),
  1831         -    AGGREGATE2(max,              1, 1, 1, minmaxStep,      minMaxFinalize,
         1912  +    WAGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize, minMaxValue, 0,
  1832   1913                                             SQLITE_FUNC_MINMAX ),
  1833   1914       FUNCTION2(typeof,            1, 0, 0, typeofFunc,  SQLITE_FUNC_TYPEOF),
  1834   1915       FUNCTION2(length,            1, 0, 0, lengthFunc,  SQLITE_FUNC_LENGTH),
  1835   1916       FUNCTION(instr,              2, 0, 0, instrFunc        ),
  1836   1917       FUNCTION(printf,            -1, 0, 0, printfFunc       ),
  1837   1918       FUNCTION(unicode,            1, 0, 0, unicodeFunc      ),
  1838   1919       FUNCTION(char,              -1, 0, 0, charFunc         ),
................................................................................
  1855   1936       VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid),
  1856   1937       VFUNCTION(changes,           0, 0, 0, changes          ),
  1857   1938       VFUNCTION(total_changes,     0, 0, 0, total_changes    ),
  1858   1939       FUNCTION(replace,            3, 0, 0, replaceFunc      ),
  1859   1940       FUNCTION(zeroblob,           1, 0, 0, zeroblobFunc     ),
  1860   1941       FUNCTION(substr,             2, 0, 0, substrFunc       ),
  1861   1942       FUNCTION(substr,             3, 0, 0, substrFunc       ),
  1862         -    AGGREGATE(sum,               1, 0, 0, sumStep,         sumFinalize    ),
  1863         -    AGGREGATE(total,             1, 0, 0, sumStep,         totalFinalize    ),
  1864         -    AGGREGATE(avg,               1, 0, 0, sumStep,         avgFinalize    ),
  1865         -    AGGREGATE2(count,            0, 0, 0, countStep,       countFinalize,
  1866         -               SQLITE_FUNC_COUNT  ),
  1867         -    AGGREGATE(count,             1, 0, 0, countStep,       countFinalize  ),
  1868         -    AGGREGATE(group_concat,      1, 0, 0, groupConcatStep, groupConcatFinalize),
  1869         -    AGGREGATE(group_concat,      2, 0, 0, groupConcatStep, groupConcatFinalize),
         1943  +    WAGGREGATE(sum,   1,0,0, sumStep, sumFinalize, sumFinalize, sumInverse, 0),
         1944  +    WAGGREGATE(total, 1,0,0, sumStep,totalFinalize,totalFinalize,sumInverse, 0),
         1945  +    WAGGREGATE(avg,   1,0,0, sumStep, avgFinalize, avgFinalize, sumInverse, 0),
         1946  +    AGGREGATE2(count, 0,0,0, countStep, countFinalize, SQLITE_FUNC_COUNT  ),
         1947  +    WAGGREGATE(count, 1,0,0, countStep, countFinalize, 0, 0, 0 ),
         1948  +    WAGGREGATE(group_concat, 1, 0, 0, groupConcatStep, 
         1949  +        groupConcatFinalize, groupConcatValue, groupConcatInverse, 0),
         1950  +    WAGGREGATE(group_concat, 2, 0, 0, groupConcatStep, 
         1951  +        groupConcatFinalize, groupConcatValue, groupConcatInverse, 0),
  1870   1952     
  1871   1953       LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
  1872   1954   #ifdef SQLITE_CASE_SENSITIVE_LIKE
  1873   1955       LIKEFUNC(like, 2, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
  1874   1956       LIKEFUNC(like, 3, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
  1875   1957   #else
  1876   1958       LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE),
................................................................................
  1882   1964       FUNCTION(coalesce,           1, 0, 0, 0                ),
  1883   1965       FUNCTION(coalesce,           0, 0, 0, 0                ),
  1884   1966       FUNCTION2(coalesce,         -1, 0, 0, noopFunc,  SQLITE_FUNC_COALESCE),
  1885   1967     };
  1886   1968   #ifndef SQLITE_OMIT_ALTERTABLE
  1887   1969     sqlite3AlterFunctions();
  1888   1970   #endif
         1971  +  sqlite3WindowFunctions();
  1889   1972   #if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4)
  1890   1973     sqlite3AnalyzeFunctions();
  1891   1974   #endif
  1892   1975     sqlite3RegisterDateTimeFunctions();
  1893   1976     sqlite3InsertBuiltinFuncs(aBuiltinFunc, ArraySize(aBuiltinFunc));
  1894   1977   
  1895   1978   #if 0  /* Enable to print out how the built-in functions are hashed */

Changes to src/main.c.

  1679   1679     const char *zFunctionName,
  1680   1680     int nArg,
  1681   1681     int enc,
  1682   1682     void *pUserData,
  1683   1683     void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
  1684   1684     void (*xStep)(sqlite3_context*,int,sqlite3_value **),
  1685   1685     void (*xFinal)(sqlite3_context*),
         1686  +  void (*xValue)(sqlite3_context*),
         1687  +  void (*xInverse)(sqlite3_context*,int,sqlite3_value **),
  1686   1688     FuncDestructor *pDestructor
  1687   1689   ){
  1688   1690     FuncDef *p;
  1689   1691     int nName;
  1690   1692     int extraFlags;
  1691   1693   
  1692   1694     assert( sqlite3_mutex_held(db->mutex) );
  1693   1695     if( zFunctionName==0 ||
  1694   1696         (xSFunc && (xFinal || xStep)) || 
  1695   1697         (!xSFunc && (xFinal && !xStep)) ||
  1696   1698         (!xSFunc && (!xFinal && xStep)) ||
         1699  +      ((xValue || xInverse) && (!xStep || !xFinal || !xValue || !xInverse)) ||
  1697   1700         (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) ||
  1698   1701         (255<(nName = sqlite3Strlen30( zFunctionName))) ){
  1699   1702       return SQLITE_MISUSE_BKPT;
  1700   1703     }
  1701   1704   
  1702   1705     assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC );
  1703   1706     extraFlags = enc &  SQLITE_DETERMINISTIC;
................................................................................
  1712   1715     ** to the hash table.
  1713   1716     */
  1714   1717     if( enc==SQLITE_UTF16 ){
  1715   1718       enc = SQLITE_UTF16NATIVE;
  1716   1719     }else if( enc==SQLITE_ANY ){
  1717   1720       int rc;
  1718   1721       rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8|extraFlags,
  1719         -         pUserData, xSFunc, xStep, xFinal, pDestructor);
         1722  +         pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor);
  1720   1723       if( rc==SQLITE_OK ){
  1721   1724         rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE|extraFlags,
  1722         -          pUserData, xSFunc, xStep, xFinal, pDestructor);
         1725  +          pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor);
  1723   1726       }
  1724   1727       if( rc!=SQLITE_OK ){
  1725   1728         return rc;
  1726   1729       }
  1727   1730       enc = SQLITE_UTF16BE;
  1728   1731     }
  1729   1732   #else
................................................................................
  1761   1764       pDestructor->nRef++;
  1762   1765     }
  1763   1766     p->u.pDestructor = pDestructor;
  1764   1767     p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags;
  1765   1768     testcase( p->funcFlags & SQLITE_DETERMINISTIC );
  1766   1769     p->xSFunc = xSFunc ? xSFunc : xStep;
  1767   1770     p->xFinalize = xFinal;
         1771  +  p->xValue = xValue;
         1772  +  p->xInverse = xInverse;
  1768   1773     p->pUserData = pUserData;
  1769   1774     p->nArg = (u16)nArg;
  1770   1775     return SQLITE_OK;
  1771   1776   }
  1772   1777   
  1773   1778   /*
  1774         -** Create new user functions.
         1779  +** Worker function used by utf-8 APIs that create new functions:
         1780  +**
         1781  +**    sqlite3_create_function()
         1782  +**    sqlite3_create_function_v2()
         1783  +**    sqlite3_create_window_function()
  1775   1784   */
  1776         -int sqlite3_create_function(
         1785  +static int createFunctionApi(
  1777   1786     sqlite3 *db,
  1778   1787     const char *zFunc,
  1779   1788     int nArg,
  1780   1789     int enc,
  1781   1790     void *p,
  1782         -  void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
  1783         -  void (*xStep)(sqlite3_context*,int,sqlite3_value **),
  1784         -  void (*xFinal)(sqlite3_context*)
  1785         -){
  1786         -  return sqlite3_create_function_v2(db, zFunc, nArg, enc, p, xSFunc, xStep,
  1787         -                                    xFinal, 0);
  1788         -}
  1789         -
  1790         -int sqlite3_create_function_v2(
  1791         -  sqlite3 *db,
  1792         -  const char *zFunc,
  1793         -  int nArg,
  1794         -  int enc,
  1795         -  void *p,
  1796         -  void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
  1797         -  void (*xStep)(sqlite3_context*,int,sqlite3_value **),
         1791  +  void (*xSFunc)(sqlite3_context*,int,sqlite3_value**),
         1792  +  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
  1798   1793     void (*xFinal)(sqlite3_context*),
  1799         -  void (*xDestroy)(void *)
         1794  +  void (*xValue)(sqlite3_context*),
         1795  +  void (*xInverse)(sqlite3_context*,int,sqlite3_value**),
         1796  +  void(*xDestroy)(void*)
  1800   1797   ){
  1801   1798     int rc = SQLITE_ERROR;
  1802   1799     FuncDestructor *pArg = 0;
  1803   1800   
  1804   1801   #ifdef SQLITE_ENABLE_API_ARMOR
  1805   1802     if( !sqlite3SafetyCheckOk(db) ){
  1806   1803       return SQLITE_MISUSE_BKPT;
................................................................................
  1814   1811         xDestroy(p);
  1815   1812         goto out;
  1816   1813       }
  1817   1814       pArg->nRef = 0;
  1818   1815       pArg->xDestroy = xDestroy;
  1819   1816       pArg->pUserData = p;
  1820   1817     }
  1821         -  rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, xSFunc, xStep, xFinal, pArg);
         1818  +  rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, 
         1819  +      xSFunc, xStep, xFinal, xValue, xInverse, pArg
         1820  +  );
  1822   1821     if( pArg && pArg->nRef==0 ){
  1823   1822       assert( rc!=SQLITE_OK );
  1824   1823       xDestroy(p);
  1825   1824       sqlite3_free(pArg);
  1826   1825     }
  1827   1826   
  1828   1827    out:
  1829   1828     rc = sqlite3ApiExit(db, rc);
  1830   1829     sqlite3_mutex_leave(db->mutex);
  1831   1830     return rc;
  1832   1831   }
         1832  +
         1833  +/*
         1834  +** Create new user functions.
         1835  +*/
         1836  +int sqlite3_create_function(
         1837  +  sqlite3 *db,
         1838  +  const char *zFunc,
         1839  +  int nArg,
         1840  +  int enc,
         1841  +  void *p,
         1842  +  void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
         1843  +  void (*xStep)(sqlite3_context*,int,sqlite3_value **),
         1844  +  void (*xFinal)(sqlite3_context*)
         1845  +){
         1846  +  return createFunctionApi(db, zFunc, nArg, enc, p, xSFunc, xStep,
         1847  +                                    xFinal, 0, 0, 0);
         1848  +}
         1849  +int sqlite3_create_function_v2(
         1850  +  sqlite3 *db,
         1851  +  const char *zFunc,
         1852  +  int nArg,
         1853  +  int enc,
         1854  +  void *p,
         1855  +  void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
         1856  +  void (*xStep)(sqlite3_context*,int,sqlite3_value **),
         1857  +  void (*xFinal)(sqlite3_context*),
         1858  +  void (*xDestroy)(void *)
         1859  +){
         1860  +  return createFunctionApi(db, zFunc, nArg, enc, p, xSFunc, xStep,
         1861  +                                    xFinal, 0, 0, xDestroy);
         1862  +}
         1863  +int sqlite3_create_window_function(
         1864  +  sqlite3 *db,
         1865  +  const char *zFunc,
         1866  +  int nArg,
         1867  +  int enc,
         1868  +  void *p,
         1869  +  void (*xStep)(sqlite3_context*,int,sqlite3_value **),
         1870  +  void (*xFinal)(sqlite3_context*),
         1871  +  void (*xValue)(sqlite3_context*),
         1872  +  void (*xInverse)(sqlite3_context*,int,sqlite3_value **),
         1873  +  void (*xDestroy)(void *)
         1874  +){
         1875  +  return createFunctionApi(db, zFunc, nArg, enc, p, 0, xStep,
         1876  +                                    xFinal, xValue, xInverse, xDestroy);
         1877  +}
  1833   1878   
  1834   1879   #ifndef SQLITE_OMIT_UTF16
  1835   1880   int sqlite3_create_function16(
  1836   1881     sqlite3 *db,
  1837   1882     const void *zFunctionName,
  1838   1883     int nArg,
  1839   1884     int eTextRep,
................................................................................
  1847   1892   
  1848   1893   #ifdef SQLITE_ENABLE_API_ARMOR
  1849   1894     if( !sqlite3SafetyCheckOk(db) || zFunctionName==0 ) return SQLITE_MISUSE_BKPT;
  1850   1895   #endif
  1851   1896     sqlite3_mutex_enter(db->mutex);
  1852   1897     assert( !db->mallocFailed );
  1853   1898     zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE);
  1854         -  rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xSFunc,xStep,xFinal,0);
         1899  +  rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xSFunc,xStep,xFinal,0,0,0);
  1855   1900     sqlite3DbFree(db, zFunc8);
  1856   1901     rc = sqlite3ApiExit(db, rc);
  1857   1902     sqlite3_mutex_leave(db->mutex);
  1858   1903     return rc;
  1859   1904   }
  1860   1905   #endif
  1861   1906   

Changes to src/parse.y.

    95     95   **
    96     96   **      UPDATE ON (a,b,c)
    97     97   **
    98     98   ** Then the "b" IdList records the list "a,b,c".
    99     99   */
   100    100   struct TrigEvent { int a; IdList * b; };
   101    101   
          102  +struct FrameBound     { int eType; Expr *pExpr; };
          103  +
   102    104   /*
   103    105   ** Disable lookaside memory allocation for objects that might be
   104    106   ** shared across database connections.
   105    107   */
   106    108   static void disableLookaside(Parse *pParse){
   107    109     pParse->disableLookaside++;
   108    110     pParse->db->lookaside.bDisable++;
................................................................................
   205    207   // This obviates the need for the "id" nonterminal.
   206    208   //
   207    209   %fallback ID
   208    210     ABORT ACTION AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST COLUMNKW
   209    211     CONFLICT DATABASE DEFERRED DESC DETACH DO
   210    212     EACH END EXCLUSIVE EXPLAIN FAIL FOR
   211    213     IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN
   212         -  QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW
          214  +  QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW ROWS
   213    215     ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT
   214    216   %ifdef SQLITE_OMIT_COMPOUND_SELECT
   215    217     EXCEPT INTERSECT UNION
   216    218   %endif SQLITE_OMIT_COMPOUND_SELECT
          219  +%ifndef SQLITE_OMIT_WINDOWFUNC
          220  +  CURRENT FOLLOWING PARTITION PRECEDING RANGE UNBOUNDED
          221  +%endif SQLITE_OMIT_WINDOWFUNC
   217    222     REINDEX RENAME CTIME_KW IF
   218    223     .
   219    224   %wildcard ANY.
   220    225   
   221    226   // Define operator precedence early so that this is the first occurrence
   222    227   // of the operator tokens in the grammer.  Keeping the operators together
   223    228   // causes them to be assigned integer values that are close together,
................................................................................
   523    528   }
   524    529   %type multiselect_op {int}
   525    530   multiselect_op(A) ::= UNION(OP).             {A = @OP; /*A-overwrites-OP*/}
   526    531   multiselect_op(A) ::= UNION ALL.             {A = TK_ALL;}
   527    532   multiselect_op(A) ::= EXCEPT|INTERSECT(OP).  {A = @OP; /*A-overwrites-OP*/}
   528    533   %endif SQLITE_OMIT_COMPOUND_SELECT
   529    534   oneselect(A) ::= SELECT(S) distinct(D) selcollist(W) from(X) where_opt(Y)
   530         -                 groupby_opt(P) having_opt(Q) orderby_opt(Z) limit_opt(L). {
          535  +                 groupby_opt(P) having_opt(Q) 
          536  +%ifndef SQLITE_OMIT_WINDOWFUNC
          537  +                 windowdefn_opt(R)
          538  +%endif
          539  +                 orderby_opt(Z) limit_opt(L). {
   531    540   #if SELECTTRACE_ENABLED
   532    541     Token s = S; /*A-overwrites-S*/
   533    542   #endif
   534    543     A = sqlite3SelectNew(pParse,W,X,Y,P,Q,Z,D,L);
          544  +#ifndef SQLITE_OMIT_WINDOWFUNC
          545  +  if( A ){
          546  +    A->pWinDefn = R;
          547  +  }else{
          548  +    sqlite3WindowListDelete(pParse->db, R);
          549  +  }
          550  +#endif // SQLITE_OMIT_WINDOWFUNC
   535    551   #if SELECTTRACE_ENABLED
   536    552     /* Populate the Select.zSelName[] string that is used to help with
   537    553     ** query planner debugging, to differentiate between multiple Select
   538    554     ** objects in a complex query.
   539    555     **
   540    556     ** If the SELECT keyword is immediately followed by a C-style comment
   541    557     ** then extract the first few alphanumeric characters from within that
................................................................................
   999   1015   }
  1000   1016   %ifndef SQLITE_OMIT_CAST
  1001   1017   expr(A) ::= CAST LP expr(E) AS typetoken(T) RP. {
  1002   1018     A = sqlite3ExprAlloc(pParse->db, TK_CAST, &T, 1);
  1003   1019     sqlite3ExprAttachSubtrees(pParse->db, A, E, 0);
  1004   1020   }
  1005   1021   %endif  SQLITE_OMIT_CAST
  1006         -expr(A) ::= id(X) LP distinct(D) exprlist(Y) RP. {
         1022  +expr(A) ::= id(X) LP distinct(D) exprlist(Y) RP 
         1023  +%ifndef SQLITE_OMIT_WINDOWFUNC
         1024  +  over_opt(Z)
         1025  +%endif
         1026  +. {
  1007   1027     if( Y && Y->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
  1008   1028       sqlite3ErrorMsg(pParse, "too many arguments on function %T", &X);
  1009   1029     }
  1010   1030     A = sqlite3ExprFunction(pParse, Y, &X);
         1031  +  sqlite3WindowAttach(pParse, A, Z);
  1011   1032     if( D==SF_Distinct && A ){
  1012   1033       A->flags |= EP_Distinct;
  1013   1034     }
  1014   1035   }
  1015         -expr(A) ::= id(X) LP STAR RP. {
         1036  +expr(A) ::= id(X) LP STAR RP
         1037  +%ifndef SQLITE_OMIT_WINDOWFUNC
         1038  +  over_opt(Z)
         1039  +%endif
         1040  +. {
  1016   1041     A = sqlite3ExprFunction(pParse, 0, &X);
         1042  +  sqlite3WindowAttach(pParse, A, Z);
  1017   1043   }
  1018   1044   term(A) ::= CTIME_KW(OP). {
  1019   1045     A = sqlite3ExprFunction(pParse, 0, &OP);
  1020   1046   }
  1021   1047   
  1022   1048   expr(A) ::= LP nexprlist(X) COMMA expr(Y) RP. {
  1023   1049     ExprList *pList = sqlite3ExprListAppend(pParse, X, Y);
................................................................................
  1566   1592   wqlist(A) ::= nm(X) eidlist_opt(Y) AS LP select(Z) RP. {
  1567   1593     A = sqlite3WithAdd(pParse, 0, &X, Y, Z); /*A-overwrites-X*/
  1568   1594   }
  1569   1595   wqlist(A) ::= wqlist(A) COMMA nm(X) eidlist_opt(Y) AS LP select(Z) RP. {
  1570   1596     A = sqlite3WithAdd(pParse, A, &X, Y, Z);
  1571   1597   }
  1572   1598   %endif  SQLITE_OMIT_CTE
         1599  +
         1600  +//////////////////////// WINDOW FUNCTION EXPRESSIONS /////////////////////////
         1601  +// These must be at the end of this file. Specifically, the rules that
         1602  +// introduce tokens WINDOW, OVER and FILTER must appear last. This causes 
         1603  +// the integer values assigned to these tokens to be larger than all other 
         1604  +// tokens that may be output by the tokenizer except TK_SPACE and TK_ILLEGAL.
         1605  +//
         1606  +%ifndef SQLITE_OMIT_WINDOWFUNC
         1607  +%type windowdefn_list {Window*}
         1608  +%destructor windowdefn_list {sqlite3WindowDelete(pParse->db, $$);}
         1609  +windowdefn_list(A) ::= windowdefn(Z). { A = Z; }
         1610  +windowdefn_list(A) ::= windowdefn_list(Y) COMMA windowdefn(Z). {
         1611  +  if( Z ) Z->pNextWin = Y;
         1612  +  A = Z;
         1613  +}
         1614  +
         1615  +%type windowdefn {Window*}
         1616  +%destructor windowdefn {sqlite3WindowDelete(pParse->db, $$);}
         1617  +windowdefn(A) ::= nm(X) AS window(Y). {
         1618  +  if( Y ){
         1619  +    Y->zName = sqlite3DbStrNDup(pParse->db, X.z, X.n);
         1620  +  }
         1621  +  A = Y;
         1622  +}
         1623  +
         1624  +%type window {Window*}
         1625  +%destructor window {sqlite3WindowDelete(pParse->db, $$);}
         1626  +
         1627  +%type frame_opt {Window*}
         1628  +%destructor frame_opt {sqlite3WindowDelete(pParse->db, $$);}
         1629  +
         1630  +%type window_or_nm {Window*}
         1631  +%destructor window_or_nm {
         1632  +sqlite3WindowDelete(pParse->db, $$);}
         1633  +
         1634  +%type part_opt {ExprList*}
         1635  +%destructor part_opt {sqlite3ExprListDelete(pParse->db, $$);}
         1636  +
         1637  +%type filter_opt {Expr*}
         1638  +%destructor filter_opt {sqlite3ExprDelete(pParse->db, $$);}
         1639  +
         1640  +%type range_or_rows {int}
         1641  +
         1642  +%type frame_bound {struct FrameBound}
         1643  +%destructor frame_bound {sqlite3ExprDelete(pParse->db, $$.pExpr);}
         1644  +
         1645  +window_or_nm(A) ::= window(Z). {A = Z;}
         1646  +window_or_nm(A) ::= nm(Z). {
         1647  +  A = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
         1648  +  if( A ){
         1649  +    A->zName = sqlite3DbStrNDup(pParse->db, Z.z, Z.n);
         1650  +  }
         1651  +}
         1652  +
         1653  +window(A) ::= LP part_opt(X) orderby_opt(Y) frame_opt(Z) RP. {
         1654  +  A = Z;
         1655  +  if( A ){
         1656  +    A->pPartition = X;
         1657  +    A->pOrderBy = Y;
         1658  +  }
         1659  +}
         1660  +
         1661  +part_opt(A) ::= PARTITION BY exprlist(X). { A = X; }
         1662  +part_opt(A) ::= .                         { A = 0; }
         1663  +
         1664  +frame_opt(A) ::= .                             { 
         1665  +  A = sqlite3WindowAlloc(pParse, TK_RANGE, TK_UNBOUNDED, 0, TK_CURRENT, 0);
         1666  +}
         1667  +frame_opt(A) ::= range_or_rows(X) frame_bound(Y). { 
         1668  +  A = sqlite3WindowAlloc(pParse, X, Y.eType, Y.pExpr, TK_CURRENT, 0);
         1669  +}
         1670  +frame_opt(A) ::= range_or_rows(X) BETWEEN frame_bound(Y) AND frame_bound(Z). { 
         1671  +  A = sqlite3WindowAlloc(pParse, X, Y.eType, Y.pExpr, Z.eType, Z.pExpr);
         1672  +}
         1673  +
         1674  +range_or_rows(A) ::= RANGE.   { A = TK_RANGE; }
         1675  +range_or_rows(A) ::= ROWS.    { A = TK_ROWS;  }
         1676  +
         1677  +frame_bound(A) ::= UNBOUNDED PRECEDING. { A.eType = TK_UNBOUNDED; A.pExpr = 0; }
         1678  +frame_bound(A) ::= expr(X) PRECEDING.   { A.eType = TK_PRECEDING; A.pExpr = X; }
         1679  +frame_bound(A) ::= CURRENT ROW.         { A.eType = TK_CURRENT  ; A.pExpr = 0; }
         1680  +frame_bound(A) ::= expr(X) FOLLOWING.   { A.eType = TK_FOLLOWING; A.pExpr = X; }
         1681  +frame_bound(A) ::= UNBOUNDED FOLLOWING. { A.eType = TK_UNBOUNDED; A.pExpr = 0; }
         1682  +
         1683  +%type windowdefn_opt {Window*}
         1684  +%destructor windowdefn_opt {sqlite3WindowDelete(pParse->db, $$);}
         1685  +windowdefn_opt(A) ::= . { A = 0; }
         1686  +windowdefn_opt(A) ::= WINDOW windowdefn_list(B). { A = B; }
         1687  +
         1688  +%type over_opt {Window*}
         1689  +%destructor over_opt {sqlite3WindowDelete(pParse->db, $$);}
         1690  +over_opt(A) ::= . { A = 0; }
         1691  +over_opt(A) ::= filter_opt(W) OVER window_or_nm(Z). {
         1692  +  A = Z;
         1693  +  if( A ) A->pFilter = W;
         1694  +}
         1695  +
         1696  +filter_opt(A) ::= .                            { A = 0; }
         1697  +filter_opt(A) ::= FILTER LP WHERE expr(X) RP.  { A = X; }
         1698  +%endif // SQLITE_OMIT_WINDOWFUNC
         1699  +

Changes to src/resolve.c.

   752    752             /* Date/time functions that use 'now', and other functions like
   753    753             ** sqlite_version() that might change over time cannot be used
   754    754             ** in an index. */
   755    755             notValid(pParse, pNC, "non-deterministic functions",
   756    756                      NC_IdxExpr|NC_PartIdx);
   757    757           }
   758    758         }
   759         -      if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
          759  +
          760  +#ifndef SQLITE_OMIT_WINDOWFUNC
          761  +      if( is_agg==0 && pExpr->pWin ){
          762  +        sqlite3ErrorMsg(pParse, 
          763  +            "%.*s() may not be used as a window function", nId, zId
          764  +        );
          765  +        pNC->nErr++;
          766  +      }else if( 
          767  +            (is_agg && (pNC->ncFlags & NC_AllowAgg)==0)
          768  +         || (is_agg && (pDef->funcFlags & SQLITE_FUNC_WINDOW) && !pExpr->pWin)
          769  +         || (is_agg && pExpr->pWin && (pNC->ncFlags & NC_AllowWin)==0)
          770  +      ){
          771  +        const char *zType;
          772  +        if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->pWin ){
          773  +          zType = "window";
          774  +        }else{
          775  +          zType = "aggregate";
          776  +        }
          777  +        sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()", zType, nId,zId);
          778  +        pNC->nErr++;
          779  +        is_agg = 0;
          780  +      }
          781  +#else
          782  +      if( (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) ){
   760    783           sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
   761    784           pNC->nErr++;
   762    785           is_agg = 0;
   763         -      }else if( no_such_func && pParse->db->init.busy==0
          786  +      }
          787  +#endif
          788  +      else if( no_such_func && pParse->db->init.busy==0
   764    789   #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
   765    790                   && pParse->explain==0
   766    791   #endif
   767    792         ){
   768    793           sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
   769    794           pNC->nErr++;
   770    795         }else if( wrong_num_args ){
   771    796           sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()",
   772    797                nId, zId);
   773    798           pNC->nErr++;
   774    799         }
   775         -      if( is_agg ) pNC->ncFlags &= ~NC_AllowAgg;
          800  +      if( is_agg ){
          801  +#ifndef SQLITE_OMIT_WINDOWFUNC
          802  +        pNC->ncFlags &= ~(pExpr->pWin ? NC_AllowWin : NC_AllowAgg);
          803  +#else
          804  +        pNC->ncFlags &= ~NC_AllowAgg;
          805  +#endif
          806  +      }
   776    807         sqlite3WalkExprList(pWalker, pList);
   777    808         if( is_agg ){
   778         -        NameContext *pNC2 = pNC;
   779         -        pExpr->op = TK_AGG_FUNCTION;
   780         -        pExpr->op2 = 0;
   781         -        while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){
   782         -          pExpr->op2++;
   783         -          pNC2 = pNC2->pNext;
   784         -        }
   785         -        assert( pDef!=0 );
   786         -        if( pNC2 ){
   787         -          assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
   788         -          testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
   789         -          pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX);
   790         -
   791         -        }
   792         -        pNC->ncFlags |= NC_AllowAgg;
          809  +#ifndef SQLITE_OMIT_WINDOWFUNC
          810  +        if( pExpr->pWin ){
          811  +          Select *pSel = pNC->pWinSelect;
          812  +          sqlite3WalkExprList(pWalker, pExpr->pWin->pPartition);
          813  +          sqlite3WalkExprList(pWalker, pExpr->pWin->pOrderBy);
          814  +          sqlite3WalkExpr(pWalker, pExpr->pWin->pFilter);
          815  +          sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->pWin, pDef);
          816  +          if( 0==pSel->pWin 
          817  +           || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->pWin) 
          818  +          ){
          819  +            pExpr->pWin->pNextWin = pSel->pWin;
          820  +            pSel->pWin = pExpr->pWin;
          821  +          }
          822  +          pNC->ncFlags |= NC_AllowWin;
          823  +        }else
          824  +#endif /* SQLITE_OMIT_WINDOWFUNC */
          825  +        {
          826  +          NameContext *pNC2 = pNC;
          827  +          pExpr->op = TK_AGG_FUNCTION;
          828  +          pExpr->op2 = 0;
          829  +          while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){
          830  +            pExpr->op2++;
          831  +            pNC2 = pNC2->pNext;
          832  +          }
          833  +          assert( pDef!=0 );
          834  +          if( pNC2 ){
          835  +            assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
          836  +            testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
          837  +            pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX);
          838  +
          839  +          }
          840  +          pNC->ncFlags |= NC_AllowAgg;
          841  +        }
   793    842         }
   794    843         /* FIX ME:  Compute pExpr->affinity based on the expected return
   795    844         ** type of the function 
   796    845         */
   797    846         return WRC_Prune;
   798    847       }
   799    848   #ifndef SQLITE_OMIT_SUBQUERY
................................................................................
  1242   1291       p->selFlags |= SF_Resolved;
  1243   1292   
  1244   1293       /* Resolve the expressions in the LIMIT and OFFSET clauses. These
  1245   1294       ** are not allowed to refer to any names, so pass an empty NameContext.
  1246   1295       */
  1247   1296       memset(&sNC, 0, sizeof(sNC));
  1248   1297       sNC.pParse = pParse;
         1298  +    sNC.pWinSelect = p;
  1249   1299       if( sqlite3ResolveExprNames(&sNC, p->pLimit) ){
  1250   1300         return WRC_Abort;
  1251   1301       }
  1252   1302   
  1253   1303       /* If the SF_Converted flags is set, then this Select object was
  1254   1304       ** was created by the convertCompoundSelectToSubquery() function.
  1255   1305       ** In this case the ORDER BY clause (p->pOrderBy) should be resolved
................................................................................
  1290   1340           pItem->fg.isCorrelated = (nRef!=0);
  1291   1341         }
  1292   1342       }
  1293   1343     
  1294   1344       /* Set up the local name-context to pass to sqlite3ResolveExprNames() to
  1295   1345       ** resolve the result-set expression list.
  1296   1346       */
  1297         -    sNC.ncFlags = NC_AllowAgg;
         1347  +    sNC.ncFlags = NC_AllowAgg|NC_AllowWin;
  1298   1348       sNC.pSrcList = p->pSrc;
  1299   1349       sNC.pNext = pOuterNC;
  1300   1350     
  1301   1351       /* Resolve names in the result set. */
  1302   1352       if( sqlite3ResolveExprListNames(&sNC, p->pEList) ) return WRC_Abort;
         1353  +    sNC.ncFlags &= ~NC_AllowWin;
  1303   1354     
  1304   1355       /* If there are no aggregate functions in the result-set, and no GROUP BY 
  1305   1356       ** expression, do not allow aggregates in any of the other expressions.
  1306   1357       */
  1307   1358       assert( (p->selFlags & SF_Aggregate)==0 );
  1308   1359       pGroupBy = p->pGroupBy;
  1309   1360       if( pGroupBy || (sNC.ncFlags & NC_HasAgg)!=0 ){
................................................................................
  1344   1395         }
  1345   1396       }
  1346   1397   
  1347   1398       /* The ORDER BY and GROUP BY clauses may not refer to terms in
  1348   1399       ** outer queries 
  1349   1400       */
  1350   1401       sNC.pNext = 0;
  1351         -    sNC.ncFlags |= NC_AllowAgg;
         1402  +    sNC.ncFlags |= NC_AllowAgg|NC_AllowWin;
  1352   1403   
  1353   1404       /* If this is a converted compound query, move the ORDER BY clause from 
  1354   1405       ** the sub-query back to the parent query. At this point each term
  1355   1406       ** within the ORDER BY clause has been transformed to an integer value.
  1356   1407       ** These integers will be replaced by copies of the corresponding result
  1357   1408       ** set expressions by the call to resolveOrderGroupBy() below.  */
  1358   1409       if( p->selFlags & SF_Converted ){
................................................................................
  1375   1426        && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER")
  1376   1427       ){
  1377   1428         return WRC_Abort;
  1378   1429       }
  1379   1430       if( db->mallocFailed ){
  1380   1431         return WRC_Abort;
  1381   1432       }
         1433  +    sNC.ncFlags &= ~NC_AllowWin;
  1382   1434     
  1383   1435       /* Resolve the GROUP BY clause.  At the same time, make sure 
  1384   1436       ** the GROUP BY clause does not contain aggregate functions.
  1385   1437       */
  1386   1438       if( pGroupBy ){
  1387   1439         struct ExprList_item *pItem;
  1388   1440       

Changes to src/select.c.

    92     92       sqlite3ExprListDelete(db, p->pEList);
    93     93       sqlite3SrcListDelete(db, p->pSrc);
    94     94       sqlite3ExprDelete(db, p->pWhere);
    95     95       sqlite3ExprListDelete(db, p->pGroupBy);
    96     96       sqlite3ExprDelete(db, p->pHaving);
    97     97       sqlite3ExprListDelete(db, p->pOrderBy);
    98     98       sqlite3ExprDelete(db, p->pLimit);
           99  +#ifndef SQLITE_OMIT_WINDOWFUNC
          100  +    if( OK_IF_ALWAYS_TRUE(p->pWinDefn) ){
          101  +      sqlite3WindowListDelete(db, p->pWinDefn);
          102  +    }
          103  +#endif
    99    104       if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith);
   100    105       if( bFree ) sqlite3DbFreeNN(db, p);
   101    106       p = pPrior;
   102    107       bFree = 1;
   103    108     }
   104    109   }
   105    110   
................................................................................
   158    163     pNew->pGroupBy = pGroupBy;
   159    164     pNew->pHaving = pHaving;
   160    165     pNew->pOrderBy = pOrderBy;
   161    166     pNew->pPrior = 0;
   162    167     pNew->pNext = 0;
   163    168     pNew->pLimit = pLimit;
   164    169     pNew->pWith = 0;
          170  +#ifndef SQLITE_OMIT_WINDOWFUNC
          171  +  pNew->pWin = 0;
          172  +  pNew->pWinDefn = 0;
          173  +#endif
   165    174     if( pParse->db->mallocFailed ) {
   166    175       clearSelect(pParse->db, pNew, pNew!=&standin);
   167    176       pNew = 0;
   168    177     }else{
   169    178       assert( pNew->pSrc!=0 || pParse->nErr>0 );
   170    179     }
   171    180     assert( pNew!=&standin );
................................................................................
   525    534                        isOuter, &p->pWhere);
   526    535         }
   527    536       }
   528    537     }
   529    538     return 0;
   530    539   }
   531    540   
   532         -/* Forward reference */
   533         -static KeyInfo *keyInfoFromExprList(
   534         -  Parse *pParse,       /* Parsing context */
   535         -  ExprList *pList,     /* Form the KeyInfo object from this ExprList */
   536         -  int iStart,          /* Begin with this column of pList */
   537         -  int nExtra           /* Add this many extra columns to the end */
   538         -);
   539         -
   540    541   /*
   541    542   ** An instance of this object holds information (beyond pParse and pSelect)
   542    543   ** needed to load the next result row that is to be added to the sorter.
   543    544   */
   544    545   typedef struct RowLoadInfo RowLoadInfo;
   545    546   struct RowLoadInfo {
   546    547     int regResult;               /* Store results in array of registers here */
................................................................................
   674    675       pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex);
   675    676       if( pParse->db->mallocFailed ) return;
   676    677       pOp->p2 = nKey + nData;
   677    678       pKI = pOp->p4.pKeyInfo;
   678    679       memset(pKI->aSortOrder, 0, pKI->nKeyField); /* Makes OP_Jump testable */
   679    680       sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO);
   680    681       testcase( pKI->nAllField > pKI->nKeyField+2 );
   681         -    pOp->p4.pKeyInfo = keyInfoFromExprList(pParse, pSort->pOrderBy, nOBSat,
          682  +    pOp->p4.pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pSort->pOrderBy,nOBSat,
   682    683                                              pKI->nAllField-pKI->nKeyField-1);
   683    684       addrJmp = sqlite3VdbeCurrentAddr(v);
   684    685       sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v);
   685    686       pSort->labelBkOut = sqlite3VdbeMakeLabel(v);
   686    687       pSort->regReturn = ++pParse->nMem;
   687    688       sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut);
   688    689       sqlite3VdbeAddOp1(v, OP_ResetSorter, pSort->iECursor);
................................................................................
  1344   1345   ** then the KeyInfo structure is appropriate for initializing a virtual
  1345   1346   ** index to implement a DISTINCT test.
  1346   1347   **
  1347   1348   ** Space to hold the KeyInfo structure is obtained from malloc.  The calling
  1348   1349   ** function is responsible for seeing that this structure is eventually
  1349   1350   ** freed.
  1350   1351   */
  1351         -static KeyInfo *keyInfoFromExprList(
         1352  +KeyInfo *sqlite3KeyInfoFromExprList(
  1352   1353     Parse *pParse,       /* Parsing context */
  1353   1354     ExprList *pList,     /* Form the KeyInfo object from this ExprList */
  1354   1355     int iStart,          /* Begin with this column of pList */
  1355   1356     int nExtra           /* Add this many extra columns to the end */
  1356   1357   ){
  1357   1358     int nExpr;
  1358   1359     KeyInfo *pInfo;
................................................................................
  3672   3673   **
  3673   3674   **  (**)  We no longer attempt to flatten aggregate subqueries.  Was:
  3674   3675   **        The subquery may not be an aggregate that uses the built-in min() or 
  3675   3676   **        or max() functions.  (Without this restriction, a query like:
  3676   3677   **        "SELECT x FROM (SELECT max(y), x FROM t1)" would not necessarily
  3677   3678   **        return the value X for which Y was maximal.)
  3678   3679   **
         3680  +**  (25)  If either the subquery or the parent query contains a window
         3681  +**        function in the select list or ORDER BY clause, flattening
         3682  +**        is not attempted.
         3683  +**
  3679   3684   **
  3680   3685   ** In this routine, the "p" parameter is a pointer to the outer query.
  3681   3686   ** The subquery is p->pSrc->a[iFrom].  isAgg is true if the outer query
  3682   3687   ** uses aggregates.
  3683   3688   **
  3684   3689   ** If flattening is not attempted, this routine is a no-op and returns 0.
  3685   3690   ** If flattening is attempted this routine returns 1.
................................................................................
  3714   3719     if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0;
  3715   3720     pSrc = p->pSrc;
  3716   3721     assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
  3717   3722     pSubitem = &pSrc->a[iFrom];
  3718   3723     iParent = pSubitem->iCursor;
  3719   3724     pSub = pSubitem->pSelect;
  3720   3725     assert( pSub!=0 );
         3726  +
         3727  +#ifndef SQLITE_OMIT_WINDOWFUNC
         3728  +  if( p->pWin || pSub->pWin ) return 0;                  /* Restriction (25) */
         3729  +#endif
  3721   3730   
  3722   3731     pSubSrc = pSub->pSrc;
  3723   3732     assert( pSubSrc );
  3724   3733     /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
  3725   3734     ** not arbitrary expressions, we allowed some combining of LIMIT and OFFSET
  3726   3735     ** because they could be computed at compile-time.  But when LIMIT and OFFSET
  3727   3736     ** became arbitrary expressions, we were forced to add restrictions (13)
................................................................................
  4105   4114   **           a GROUP BY clause.  But such a HAVING clause is also harmless
  4106   4115   **           so there does not appear to be any reason to add extra logic
  4107   4116   **           to suppress it. **)
  4108   4117   **
  4109   4118   **   (2) The inner query is the recursive part of a common table expression.
  4110   4119   **
  4111   4120   **   (3) The inner query has a LIMIT clause (since the changes to the WHERE
  4112         -**       close would change the meaning of the LIMIT).
         4121  +**       clause would change the meaning of the LIMIT).
  4113   4122   **
  4114   4123   **   (4) The inner query is the right operand of a LEFT JOIN and the
  4115   4124   **       expression to be pushed down does not come from the ON clause
  4116   4125   **       on that LEFT JOIN.
  4117   4126   **
  4118   4127   **   (5) The WHERE clause expression originates in the ON or USING clause
  4119   4128   **       of a LEFT JOIN where iCursor is not the right-hand table of that
................................................................................
  4123   4132   **           FROM (SELECT 1 AS a1 UNION ALL SELECT 2) AS aa
  4124   4133   **           JOIN (SELECT 1 AS b2 UNION ALL SELECT 2) AS bb ON (a1=b2)
  4125   4134   **           LEFT JOIN (SELECT 8 AS c3 UNION ALL SELECT 9) AS cc ON (b2=2);
  4126   4135   **
  4127   4136   **       The correct answer is three rows:  (1,1,NULL),(2,2,8),(2,2,9).
  4128   4137   **       But if the (b2=2) term were to be pushed down into the bb subquery,
  4129   4138   **       then the (1,1,NULL) row would be suppressed.
         4139  +**
         4140  +**   (6) The inner query features one or more window-functions (since 
         4141  +**       changes to the WHERE clause of the inner query could change the 
         4142  +**       window over which window functions are calculated).
  4130   4143   **
  4131   4144   ** Return 0 if no changes are made and non-zero if one or more WHERE clause
  4132   4145   ** terms are duplicated into the subquery.
  4133   4146   */
  4134   4147   static int pushDownWhereTerms(
  4135   4148     Parse *pParse,        /* Parse context (for malloc() and error reporting) */
  4136   4149     Select *pSubq,        /* The subquery whose WHERE clause is to be augmented */
................................................................................
  4138   4151     int iCursor,          /* Cursor number of the subquery */
  4139   4152     int isLeftJoin        /* True if pSubq is the right term of a LEFT JOIN */
  4140   4153   ){
  4141   4154     Expr *pNew;
  4142   4155     int nChng = 0;
  4143   4156     if( pWhere==0 ) return 0;
  4144   4157     if( pSubq->selFlags & SF_Recursive ) return 0;  /* restriction (2) */
         4158  +
         4159  +#ifndef SQLITE_OMIT_WINDOWFUNC
         4160  +  if( pSubq->pWin ) return 0;
         4161  +#endif
  4145   4162   
  4146   4163   #ifdef SQLITE_DEBUG
  4147   4164     /* Only the first term of a compound can have a WITH clause.  But make
  4148   4165     ** sure no other terms are marked SF_Recursive in case something changes
  4149   4166     ** in the future.
  4150   4167     */
  4151   4168     {
................................................................................
  4583   4600         pParse->pWith = pWith->pOuter;
  4584   4601       }
  4585   4602     }
  4586   4603   }
  4587   4604   #else
  4588   4605   #define selectPopWith 0
  4589   4606   #endif
         4607  +
         4608  +/*
         4609  +** The SrcList_item structure passed as the second argument represents a
         4610  +** sub-query in the FROM clause of a SELECT statement. This function
         4611  +** allocates and populates the SrcList_item.pTab object. If successful,
         4612  +** SQLITE_OK is returned. Otherwise, if an OOM error is encountered,
         4613  +** SQLITE_NOMEM.
         4614  +*/
         4615  +int sqlite3ExpandSubquery(Parse *pParse, struct SrcList_item *pFrom){
         4616  +  Select *pSel = pFrom->pSelect;
         4617  +  Table *pTab;
         4618  +
         4619  +  assert( pSel );
         4620  +  pFrom->pTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table));
         4621  +  if( pTab==0 ) return SQLITE_NOMEM;
         4622  +  pTab->nTabRef = 1;
         4623  +  if( pFrom->zAlias ){
         4624  +    pTab->zName = sqlite3DbStrDup(pParse->db, pFrom->zAlias);
         4625  +  }else{
         4626  +    pTab->zName = sqlite3MPrintf(pParse->db, "subquery_%p", (void*)pTab);
         4627  +  }
         4628  +  while( pSel->pPrior ){ pSel = pSel->pPrior; }
         4629  +  sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol);
         4630  +  pTab->iPKey = -1;
         4631  +  pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
         4632  +  pTab->tabFlags |= TF_Ephemeral;
         4633  +
         4634  +  return SQLITE_OK;
         4635  +}
  4590   4636   
  4591   4637   /*
  4592   4638   ** This routine is a Walker callback for "expanding" a SELECT statement.
  4593   4639   ** "Expanding" means to do the following:
  4594   4640   **
  4595   4641   **    (1)  Make sure VDBE cursor numbers have been assigned to every
  4596   4642   **         element of the FROM clause.
................................................................................
  4656   4702       if( pFrom->zName==0 ){
  4657   4703   #ifndef SQLITE_OMIT_SUBQUERY
  4658   4704         Select *pSel = pFrom->pSelect;
  4659   4705         /* A sub-query in the FROM clause of a SELECT */
  4660   4706         assert( pSel!=0 );
  4661   4707         assert( pFrom->pTab==0 );
  4662   4708         if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort;
  4663         -      pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
  4664         -      if( pTab==0 ) return WRC_Abort;
  4665         -      pTab->nTabRef = 1;
  4666         -      if( pFrom->zAlias ){
  4667         -        pTab->zName = sqlite3DbStrDup(db, pFrom->zAlias);
  4668         -      }else{
  4669         -        pTab->zName = sqlite3MPrintf(db, "subquery_%p", (void*)pTab);
  4670         -      }
  4671         -      while( pSel->pPrior ){ pSel = pSel->pPrior; }
  4672         -      sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol);
  4673         -      pTab->iPKey = -1;
  4674         -      pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
  4675         -      pTab->tabFlags |= TF_Ephemeral;
         4709  +      if( sqlite3ExpandSubquery(pParse, pFrom) ) return WRC_Abort;
  4676   4710   #endif
  4677   4711       }else{
  4678   4712         /* An ordinary table or view name in the FROM clause */
  4679   4713         assert( pFrom->pTab==0 );
  4680   4714         pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom);
  4681   4715         if( pTab==0 ) return WRC_Abort;
  4682   4716         if( pTab->nTabRef>=0xffff ){
................................................................................
  4969   5003   static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
  4970   5004     Parse *pParse;
  4971   5005     int i;
  4972   5006     SrcList *pTabList;
  4973   5007     struct SrcList_item *pFrom;
  4974   5008   
  4975   5009     assert( p->selFlags & SF_Resolved );
  4976         -  assert( (p->selFlags & SF_HasTypeInfo)==0 );
         5010  +  if( p->selFlags & SF_HasTypeInfo ) return;
  4977   5011     p->selFlags |= SF_HasTypeInfo;
  4978   5012     pParse = pWalker->pParse;
  4979   5013     pTabList = p->pSrc;
  4980   5014     for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
  4981   5015       Table *pTab = pFrom->pTab;
  4982   5016       assert( pTab!=0 );
  4983   5017       if( (pTab->tabFlags & TF_Ephemeral)!=0 ){
................................................................................
  5072   5106         Expr *pE = pFunc->pExpr;
  5073   5107         assert( !ExprHasProperty(pE, EP_xIsSelect) );
  5074   5108         if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){
  5075   5109           sqlite3ErrorMsg(pParse, "DISTINCT aggregates must have exactly one "
  5076   5110              "argument");
  5077   5111           pFunc->iDistinct = -1;
  5078   5112         }else{
  5079         -        KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList, 0, 0);
         5113  +        KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pE->x.pList,0,0);
  5080   5114           sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0,
  5081   5115                             (char*)pKeyInfo, P4_KEYINFO);
  5082   5116         }
  5083   5117       }
  5084   5118     }
  5085   5119   }
  5086   5120   
................................................................................
  5446   5480       /* If ORDER BY makes no difference in the output then neither does
  5447   5481       ** DISTINCT so it can be removed too. */
  5448   5482       sqlite3ExprListDelete(db, p->pOrderBy);
  5449   5483       p->pOrderBy = 0;
  5450   5484       p->selFlags &= ~SF_Distinct;
  5451   5485     }
  5452   5486     sqlite3SelectPrep(pParse, p, 0);
  5453         -  memset(&sSort, 0, sizeof(sSort));
  5454         -  sSort.pOrderBy = p->pOrderBy;
  5455         -  pTabList = p->pSrc;
  5456   5487     if( pParse->nErr || db->mallocFailed ){
  5457   5488       goto select_end;
  5458   5489     }
  5459   5490     assert( p->pEList!=0 );
  5460         -  isAgg = (p->selFlags & SF_Aggregate)!=0;
  5461   5491   #if SELECTTRACE_ENABLED
  5462   5492     if( sqlite3SelectTrace & 0x104 ){
  5463   5493       SELECTTRACE(0x104,pParse,p, ("after name resolution:\n"));
  5464   5494       sqlite3TreeViewSelect(0, p, 0);
  5465   5495     }
  5466   5496   #endif
  5467   5497   
  5468   5498     if( pDest->eDest==SRT_Output ){
  5469   5499       generateColumnNames(pParse, p);
  5470   5500     }
  5471   5501   
         5502  +#ifndef SQLITE_OMIT_WINDOWFUNC
         5503  +  if( sqlite3WindowRewrite(pParse, p) ){
         5504  +    goto select_end;
         5505  +  }
         5506  +#if SELECTTRACE_ENABLED
         5507  +  if( sqlite3SelectTrace & 0x108 ){
         5508  +    SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n"));
         5509  +    sqlite3TreeViewSelect(0, p, 0);
         5510  +  }
         5511  +#endif
         5512  +#endif /* SQLITE_OMIT_WINDOWFUNC */
         5513  +  pTabList = p->pSrc;
         5514  +  isAgg = (p->selFlags & SF_Aggregate)!=0;
         5515  +  memset(&sSort, 0, sizeof(sSort));
         5516  +  sSort.pOrderBy = p->pOrderBy;
         5517  +
  5472   5518     /* Try to various optimizations (flattening subqueries, and strength
  5473   5519     ** reduction of join operators) in the FROM clause up into the main query
  5474   5520     */
  5475   5521   #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
  5476   5522     for(i=0; !p->pPrior && i<pTabList->nSrc; i++){
  5477   5523       struct SrcList_item *pItem = &pTabList->a[i];
  5478   5524       Select *pSub = pItem->pSelect;
................................................................................
  5794   5840     ** If that is the case, then the OP_OpenEphemeral instruction will be
  5795   5841     ** changed to an OP_Noop once we figure out that the sorting index is
  5796   5842     ** not needed.  The sSort.addrSortIndex variable is used to facilitate
  5797   5843     ** that change.
  5798   5844     */
  5799   5845     if( sSort.pOrderBy ){
  5800   5846       KeyInfo *pKeyInfo;
  5801         -    pKeyInfo = keyInfoFromExprList(pParse, sSort.pOrderBy, 0, pEList->nExpr);
         5847  +    pKeyInfo = sqlite3KeyInfoFromExprList(
         5848  +        pParse, sSort.pOrderBy, 0, pEList->nExpr);
  5802   5849       sSort.iECursor = pParse->nTab++;
  5803   5850       sSort.addrSortIndex =
  5804   5851         sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
  5805   5852             sSort.iECursor, sSort.pOrderBy->nExpr+1+pEList->nExpr, 0,
  5806   5853             (char*)pKeyInfo, P4_KEYINFO
  5807   5854         );
  5808   5855     }else{
................................................................................
  5828   5875     }
  5829   5876   
  5830   5877     /* Open an ephemeral index to use for the distinct set.
  5831   5878     */
  5832   5879     if( p->selFlags & SF_Distinct ){
  5833   5880       sDistinct.tabTnct = pParse->nTab++;
  5834   5881       sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
  5835         -                             sDistinct.tabTnct, 0, 0,
  5836         -                             (char*)keyInfoFromExprList(pParse, p->pEList,0,0),
  5837         -                             P4_KEYINFO);
         5882  +                       sDistinct.tabTnct, 0, 0,
         5883  +                       (char*)sqlite3KeyInfoFromExprList(pParse, p->pEList,0,0),
         5884  +                       P4_KEYINFO);
  5838   5885       sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
  5839   5886       sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED;
  5840   5887     }else{
  5841   5888       sDistinct.eTnctType = WHERE_DISTINCT_NOOP;
  5842   5889     }
  5843   5890   
  5844   5891     if( !isAgg && pGroupBy==0 ){
  5845   5892       /* No aggregate functions and no GROUP BY clause */
  5846         -    u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0);
         5893  +    u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0)
         5894  +                   | (p->selFlags & SF_FixedLimit);
         5895  +#ifndef SQLITE_OMIT_WINDOWFUNC
         5896  +    Window *pWin = p->pWin;      /* Master window object (or NULL) */
         5897  +    if( pWin ){
         5898  +      sqlite3WindowCodeInit(pParse, pWin);
         5899  +    }
         5900  +#endif
  5847   5901       assert( WHERE_USE_LIMIT==SF_FixedLimit );
  5848         -    wctrlFlags |= p->selFlags & SF_FixedLimit;
         5902  +
  5849   5903   
  5850   5904       /* Begin the database scan. */
  5851   5905       SELECTTRACE(1,pParse,p,("WhereBegin\n"));
  5852   5906       pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy,
  5853   5907                                  p->pEList, wctrlFlags, p->nSelectRow);
  5854   5908       if( pWInfo==0 ) goto select_end;
  5855   5909       if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){
................................................................................
  5870   5924       ** instruction ended up not being needed, then change the OP_OpenEphemeral
  5871   5925       ** into an OP_Noop.
  5872   5926       */
  5873   5927       if( sSort.addrSortIndex>=0 && sSort.pOrderBy==0 ){
  5874   5928         sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex);
  5875   5929       }
  5876   5930   
  5877         -    /* Use the standard inner loop. */
  5878   5931       assert( p->pEList==pEList );
  5879         -    selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest,
  5880         -                    sqlite3WhereContinueLabel(pWInfo),
  5881         -                    sqlite3WhereBreakLabel(pWInfo));
         5932  +#ifndef SQLITE_OMIT_WINDOWFUNC
         5933  +    if( pWin ){
         5934  +      int addrGosub = sqlite3VdbeMakeLabel(v);
         5935  +      int iCont = sqlite3VdbeMakeLabel(v);
         5936  +      int iBreak = sqlite3VdbeMakeLabel(v);
         5937  +      int regGosub = ++pParse->nMem;
  5882   5938   
  5883         -    /* End the database scan loop.
  5884         -    */
  5885         -    sqlite3WhereEnd(pWInfo);
         5939  +      sqlite3WindowCodeStep(pParse, p, pWInfo, regGosub, addrGosub);
         5940  +
         5941  +      sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak);
         5942  +      sqlite3VdbeResolveLabel(v, addrGosub);
         5943  +      selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest, iCont, iBreak);
         5944  +      sqlite3VdbeResolveLabel(v, iCont);
         5945  +      sqlite3VdbeAddOp1(v, OP_Return, regGosub);
         5946  +      sqlite3VdbeResolveLabel(v, iBreak);
         5947  +    }else
         5948  +#endif /* SQLITE_OMIT_WINDOWFUNC */
         5949  +    {
         5950  +      /* Use the standard inner loop. */
         5951  +      selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest,
         5952  +          sqlite3WhereContinueLabel(pWInfo),
         5953  +          sqlite3WhereBreakLabel(pWInfo));
         5954  +
         5955  +      /* End the database scan loop.
         5956  +      */
         5957  +      sqlite3WhereEnd(pWInfo);
         5958  +    }
  5886   5959     }else{
  5887   5960       /* This case when there exist aggregate functions or a GROUP BY clause
  5888   5961       ** or both */
  5889   5962       NameContext sNC;    /* Name context for processing aggregate information */
  5890   5963       int iAMem;          /* First Mem address for storing current GROUP BY */
  5891   5964       int iBMem;          /* First Mem address for previous GROUP BY */
  5892   5965       int iUseFlag;       /* Mem address holding flag indicating that at least
................................................................................
  6007   6080   
  6008   6081         /* If there is a GROUP BY clause we might need a sorting index to
  6009   6082         ** implement it.  Allocate that sorting index now.  If it turns out
  6010   6083         ** that we do not need it after all, the OP_SorterOpen instruction
  6011   6084         ** will be converted into a Noop.  
  6012   6085         */
  6013   6086         sAggInfo.sortingIdx = pParse->nTab++;
  6014         -      pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0, sAggInfo.nColumn);
         6087  +      pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pGroupBy,0,sAggInfo.nColumn);
  6015   6088         addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, 
  6016   6089             sAggInfo.sortingIdx, sAggInfo.nSortingColumn, 
  6017   6090             0, (char*)pKeyInfo, P4_KEYINFO);
  6018   6091   
  6019   6092         /* Initialize memory locations used by GROUP BY aggregate processing
  6020   6093         */
  6021   6094         iUseFlag = ++pParse->nMem;

Changes to src/sqlite.h.in.

  4617   4617   ** KEYWORDS: {function creation routines}
  4618   4618   ** KEYWORDS: {application-defined SQL function}
  4619   4619   ** KEYWORDS: {application-defined SQL functions}
  4620   4620   ** METHOD: sqlite3
  4621   4621   **
  4622   4622   ** ^These functions (collectively known as "function creation routines")
  4623   4623   ** are used to add SQL functions or aggregates or to redefine the behavior
  4624         -** of existing SQL functions or aggregates.  The only differences between
  4625         -** these routines are the text encoding expected for
  4626         -** the second parameter (the name of the function being created)
  4627         -** and the presence or absence of a destructor callback for
  4628         -** the application data pointer.
         4624  +** of existing SQL functions or aggregates. The only differences between
         4625  +** the three "sqlite3_create_function*" routines are the text encoding 
         4626  +** expected for the second parameter (the name of the function being 
         4627  +** created) and the presence or absence of a destructor callback for
         4628  +** the application data pointer. Function sqlite3_create_window_function()
         4629  +** is similar, but allows the user to supply the extra callback functions
         4630  +** needed by [aggregate window functions].
  4629   4631   **
  4630   4632   ** ^The first parameter is the [database connection] to which the SQL
  4631   4633   ** function is to be added.  ^If an application uses more than one database
  4632   4634   ** connection then application-defined SQL functions must be added
  4633   4635   ** to each database connection separately.
  4634   4636   **
  4635   4637   ** ^The second parameter is the name of the SQL function to be created or
................................................................................
  4667   4669   ** function that is not deterministic.  The SQLite query planner is able to
  4668   4670   ** perform additional optimizations on deterministic functions, so use
  4669   4671   ** of the [SQLITE_DETERMINISTIC] flag is recommended where possible.
  4670   4672   **
  4671   4673   ** ^(The fifth parameter is an arbitrary pointer.  The implementation of the
  4672   4674   ** function can gain access to this pointer using [sqlite3_user_data()].)^
  4673   4675   **
  4674         -** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are
         4676  +** ^The sixth, seventh and eighth parameters passed to the three
         4677  +** "sqlite3_create_function*" functions, xFunc, xStep and xFinal, are
  4675   4678   ** pointers to C-language functions that implement the SQL function or
  4676   4679   ** aggregate. ^A scalar SQL function requires an implementation of the xFunc
  4677   4680   ** callback only; NULL pointers must be passed as the xStep and xFinal
  4678   4681   ** parameters. ^An aggregate SQL function requires an implementation of xStep
  4679   4682   ** and xFinal and NULL pointer must be passed for xFunc. ^To delete an existing
  4680   4683   ** SQL function or aggregate, pass NULL pointers for all three function
  4681   4684   ** callbacks.
  4682   4685   **
  4683         -** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL,
  4684         -** then it is destructor for the application data pointer. 
  4685         -** The destructor is invoked when the function is deleted, either by being
  4686         -** overloaded or when the database connection closes.)^
  4687         -** ^The destructor is also invoked if the call to
  4688         -** sqlite3_create_function_v2() fails.
  4689         -** ^When the destructor callback of the tenth parameter is invoked, it
  4690         -** is passed a single argument which is a copy of the application data 
  4691         -** pointer which was the fifth parameter to sqlite3_create_function_v2().
         4686  +** ^The sixth, seventh, eighth and ninth parameters (xStep, xFinal, xValue 
         4687  +** and xInverse) passed to sqlite3_create_window_function are pointers to
         4688  +** C-lanugage callbacks that implement the new function. xStep and xFinal
         4689  +** must both be non-NULL. xValue and xInverse may either both be NULL, in
         4690  +** which case a regular aggregate function is created, or must both be 
         4691  +** non-NULL, in which case the new function may be used as either an aggregate
         4692  +** or aggregate window function. More details regarding the implementation
         4693  +** of aggregate window functions are 
         4694  +** [user-defined window functions|available here].
         4695  +**
         4696  +** ^(If the final parameter to sqlite3_create_function_v2() or
         4697  +** sqlite3_create_window_function() is not NULL, then it is destructor for
         4698  +** the application data pointer. The destructor is invoked when the function 
         4699  +** is deleted, either by being overloaded or when the database connection 
         4700  +** closes.)^ ^The destructor is also invoked if the call to 
         4701  +** sqlite3_create_function_v2() fails.  ^When the destructor callback is
         4702  +** invoked, it is passed a single argument which is a copy of the application
         4703  +** data pointer which was the fifth parameter to sqlite3_create_function_v2().
  4692   4704   **
  4693   4705   ** ^It is permitted to register multiple implementations of the same
  4694   4706   ** functions with the same name but with either differing numbers of
  4695   4707   ** arguments or differing preferred text encodings.  ^SQLite will use
  4696   4708   ** the implementation that most closely matches the way in which the
  4697   4709   ** SQL function is used.  ^A function implementation with a non-negative
  4698   4710   ** nArg parameter is a better match than a function implementation with
................................................................................
  4736   4748     int nArg,
  4737   4749     int eTextRep,
  4738   4750     void *pApp,
  4739   4751     void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
  4740   4752     void (*xStep)(sqlite3_context*,int,sqlite3_value**),
  4741   4753     void (*xFinal)(sqlite3_context*),
  4742   4754     void(*xDestroy)(void*)
         4755  +);
         4756  +int sqlite3_create_window_function(
         4757  +  sqlite3 *db,
         4758  +  const char *zFunctionName,
         4759  +  int nArg,
         4760  +  int eTextRep,
         4761  +  void *pApp,
         4762  +  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
         4763  +  void (*xFinal)(sqlite3_context*),
         4764  +  void (*xValue)(sqlite3_context*),
         4765  +  void (*xInverse)(sqlite3_context*,int,sqlite3_value**),
         4766  +  void(*xDestroy)(void*)
  4743   4767   );
  4744   4768   
  4745   4769   /*
  4746   4770   ** CAPI3REF: Text Encodings
  4747   4771   **
  4748   4772   ** These constant define integer codes that represent the various
  4749   4773   ** text encodings supported by SQLite.

Changes to src/sqliteInt.h.

  1114   1114   typedef struct TriggerStep TriggerStep;
  1115   1115   typedef struct UnpackedRecord UnpackedRecord;
  1116   1116   typedef struct Upsert Upsert;
  1117   1117   typedef struct VTable VTable;
  1118   1118   typedef struct VtabCtx VtabCtx;
  1119   1119   typedef struct Walker Walker;
  1120   1120   typedef struct WhereInfo WhereInfo;
         1121  +typedef struct Window Window;
  1121   1122   typedef struct With With;
  1122   1123   
  1123   1124   
  1124   1125   /*
  1125   1126   ** The bitmask datatype defined below is used for various optimizations.
  1126   1127   **
  1127   1128   ** Changing this from a 64-bit to a 32-bit type limits the number of
................................................................................
  1616   1617   ** structure is held in the db->aHash hash table.
  1617   1618   **
  1618   1619   ** The u.pHash field is used by the global built-ins.  The u.pDestructor
  1619   1620   ** field is used by per-connection app-def functions.
  1620   1621   */
  1621   1622   struct FuncDef {
  1622   1623     i8 nArg;             /* Number of arguments.  -1 means unlimited */
  1623         -  u16 funcFlags;       /* Some combination of SQLITE_FUNC_* */
         1624  +  u32 funcFlags;       /* Some combination of SQLITE_FUNC_* */
  1624   1625     void *pUserData;     /* User data parameter */
  1625   1626     FuncDef *pNext;      /* Next function with same name */
  1626   1627     void (*xSFunc)(sqlite3_context*,int,sqlite3_value**); /* func or agg-step */
  1627   1628     void (*xFinalize)(sqlite3_context*);                  /* Agg finalizer */
         1629  +  void (*xValue)(sqlite3_context*);                     /* Current agg value */
         1630  +  void (*xInverse)(sqlite3_context*,int,sqlite3_value**); /* inverse agg-step */
  1628   1631     const char *zName;   /* SQL name of the function. */
  1629   1632     union {
  1630   1633       FuncDef *pHash;      /* Next with a different name but the same hash */
  1631   1634       FuncDestructor *pDestructor;   /* Reference counted destructor function */
  1632   1635     } u;
  1633   1636   };
  1634   1637   
................................................................................
  1677   1680   #define SQLITE_FUNC_UNLIKELY 0x0400 /* Built-in unlikely() function */
  1678   1681   #define SQLITE_FUNC_CONSTANT 0x0800 /* Constant inputs give a constant output */
  1679   1682   #define SQLITE_FUNC_MINMAX   0x1000 /* True for min() and max() aggregates */
  1680   1683   #define SQLITE_FUNC_SLOCHNG  0x2000 /* "Slow Change". Value constant during a
  1681   1684                                       ** single query - might change over time */
  1682   1685   #define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */
  1683   1686   #define SQLITE_FUNC_OFFSET   0x8000 /* Built-in sqlite_offset() function */
         1687  +#define SQLITE_FUNC_WINDOW  0x10000 /* Built-in window-only function */
         1688  +#define SQLITE_FUNC_WINDOW_SIZE  0x20000  /* Requires partition size as arg. */
  1684   1689   
  1685   1690   /*
  1686   1691   ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
  1687   1692   ** used to create the initializers for the FuncDef structures.
  1688   1693   **
  1689   1694   **   FUNCTION(zName, nArg, iArg, bNC, xFunc)
  1690   1695   **     Used to create a scalar function definition of a function zName
................................................................................
  1710   1715   **     arbitrary non-NULL pointer.  The bNC parameter is not used.
  1711   1716   **
  1712   1717   **   AGGREGATE(zName, nArg, iArg, bNC, xStep, xFinal)
  1713   1718   **     Used to create an aggregate function definition implemented by
  1714   1719   **     the C functions xStep and xFinal. The first four parameters
  1715   1720   **     are interpreted in the same way as the first 4 parameters to
  1716   1721   **     FUNCTION().
         1722  +**
         1723  +**   WFUNCTION(zName, nArg, iArg, xStep, xFinal, xValue, xInverse)
         1724  +**     Used to create an aggregate function definition implemented by
         1725  +**     the C functions xStep and xFinal. The first four parameters
         1726  +**     are interpreted in the same way as the first 4 parameters to
         1727  +**     FUNCTION().
  1717   1728   **
  1718   1729   **   LIKEFUNC(zName, nArg, pArg, flags)
  1719   1730   **     Used to create a scalar function definition of a function zName
  1720   1731   **     that accepts nArg arguments and is implemented by a call to C
  1721   1732   **     function likeFunc. Argument pArg is cast to a (void *) and made
  1722   1733   **     available as the function user-data (sqlite3_user_data()). The
  1723   1734   **     FuncDef.flags variable is set to the value passed as the flags
  1724   1735   **     parameter.
  1725   1736   */
  1726   1737   #define FUNCTION(zName, nArg, iArg, bNC, xFunc) \
  1727   1738     {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
  1728         -   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
         1739  +   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
  1729   1740   #define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \
  1730   1741     {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
  1731         -   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
         1742  +   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
  1732   1743   #define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \
  1733   1744     {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8, \
  1734         -   0, 0, xFunc, 0, #zName, {0} }
         1745  +   0, 0, xFunc, 0, 0, 0, #zName, {0} }
  1735   1746   #define PURE_DATE(zName, nArg, iArg, bNC, xFunc) \
  1736   1747     {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \
  1737         -   (void*)&sqlite3Config, 0, xFunc, 0, #zName, {0} }
         1748  +   (void*)&sqlite3Config, 0, xFunc, 0, 0, 0, #zName, {0} }
  1738   1749   #define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \
  1739   1750     {nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\
  1740         -   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
         1751  +   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
  1741   1752   #define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \
  1742   1753     {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
  1743         -   pArg, 0, xFunc, 0, #zName, }
         1754  +   pArg, 0, xFunc, 0, 0, 0, #zName, }
  1744   1755   #define LIKEFUNC(zName, nArg, arg, flags) \
  1745   1756     {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \
  1746         -   (void *)arg, 0, likeFunc, 0, #zName, {0} }
  1747         -#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \
         1757  +   (void *)arg, 0, likeFunc, 0, 0, 0, #zName, {0} }
         1758  +#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue) \
  1748   1759     {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \
  1749         -   SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName, {0}}
         1760  +   SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,0,#zName, {0}}
  1750   1761   #define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \
  1751   1762     {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \
  1752         -   SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName, {0}}
         1763  +   SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xFinal,0,#zName, {0}}
         1764  +
         1765  +#define WAGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue, xInverse, f) \
         1766  +  {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \
         1767  +   SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,xInverse,#zName, {0}}
  1753   1768   
  1754   1769   /*
  1755   1770   ** All current savepoints are stored in a linked list starting at
  1756   1771   ** sqlite3.pSavepoint. The first element in the list is the most recently
  1757   1772   ** opened savepoint. Savepoints are added to the list by the vdbe
  1758   1773   ** OP_Savepoint instruction.
  1759   1774   */
................................................................................
  2447   2462     i16 iRightJoinTable;   /* If EP_FromJoin, the right table of the join */
  2448   2463     u8 op2;                /* TK_REGISTER: original value of Expr.op
  2449   2464                            ** TK_COLUMN: the value of p5 for OP_Column
  2450   2465                            ** TK_AGG_FUNCTION: nesting depth */
  2451   2466     AggInfo *pAggInfo;     /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
  2452   2467     Table *pTab;           /* Table for TK_COLUMN expressions.  Can be NULL
  2453   2468                            ** for a column of an index on an expression */
         2469  +#ifndef SQLITE_OMIT_WINDOWFUNC
         2470  +  Window *pWin;          /* Window definition for window functions */
         2471  +#endif
  2454   2472   };
  2455   2473   
  2456   2474   /*
  2457   2475   ** The following are the meanings of bits in the Expr.flags field.
  2458   2476   */
  2459   2477   #define EP_FromJoin  0x000001 /* Originates in ON/USING clause of outer join */
  2460   2478   #define EP_Agg       0x000002 /* Contains one or more aggregate functions */
................................................................................
  2708   2726       AggInfo *pAggInfo;   /* Information about aggregates at this level */
  2709   2727       Upsert *pUpsert;     /* ON CONFLICT clause information from an upsert */
  2710   2728     } uNC;
  2711   2729     NameContext *pNext;  /* Next outer name context.  NULL for outermost */
  2712   2730     int nRef;            /* Number of names resolved by this context */
  2713   2731     int nErr;            /* Number of errors encountered while resolving names */
  2714   2732     u16 ncFlags;         /* Zero or more NC_* flags defined below */
         2733  +  Select *pWinSelect;  /* SELECT statement for any window functions */
  2715   2734   };
  2716   2735   
  2717   2736   /*
  2718   2737   ** Allowed values for the NameContext, ncFlags field.
  2719   2738   **
  2720   2739   ** Value constraints (all checked via assert()):
  2721   2740   **    NC_HasAgg    == SF_HasAgg
................................................................................
  2730   2749   #define NC_IdxExpr   0x0020  /* True if resolving columns of CREATE INDEX */
  2731   2750   #define NC_VarSelect 0x0040  /* A correlated subquery has been seen */
  2732   2751   #define NC_UEList    0x0080  /* True if uNC.pEList is used */
  2733   2752   #define NC_UAggInfo  0x0100  /* True if uNC.pAggInfo is used */
  2734   2753   #define NC_UUpsert   0x0200  /* True if uNC.pUpsert is used */
  2735   2754   #define NC_MinMaxAgg 0x1000  /* min/max aggregates seen.  See note above */
  2736   2755   #define NC_Complex   0x2000  /* True if a function or subquery seen */
         2756  +#define NC_AllowWin  0x4000  /* Window functions are allowed here */
  2737   2757   
  2738   2758   /*
  2739   2759   ** An instance of the following object describes a single ON CONFLICT
  2740   2760   ** clause in an upsert.
  2741   2761   **
  2742   2762   ** The pUpsertTarget field is only set if the ON CONFLICT clause includes
  2743   2763   ** conflict-target clause.  (In "ON CONFLICT(a,b)" the "(a,b)" is the
................................................................................
  2797   2817     ExprList *pGroupBy;    /* The GROUP BY clause */
  2798   2818     Expr *pHaving;         /* The HAVING clause */
  2799   2819     ExprList *pOrderBy;    /* The ORDER BY clause */
  2800   2820     Select *pPrior;        /* Prior select in a compound select statement */
  2801   2821     Select *pNext;         /* Next select to the left in a compound */
  2802   2822     Expr *pLimit;          /* LIMIT expression. NULL means not used. */
  2803   2823     With *pWith;           /* WITH clause attached to this select. Or NULL. */
         2824  +#ifndef SQLITE_OMIT_WINDOWFUNC
         2825  +  Window *pWin;          /* List of window functions */
         2826  +  Window *pWinDefn;      /* List of named window definitions */
         2827  +#endif
  2804   2828   };
  2805   2829   
  2806   2830   /*
  2807   2831   ** Allowed values for Select.selFlags.  The "SF" prefix stands for
  2808   2832   ** "Select Flag".
  2809   2833   **
  2810   2834   ** Value constraints (all checked via assert())
................................................................................
  3410   3434       struct SrcCount *pSrcCount;               /* Counting column references */
  3411   3435       struct CCurHint *pCCurHint;               /* Used by codeCursorHint() */
  3412   3436       int *aiCol;                               /* array of column indexes */
  3413   3437       struct IdxCover *pIdxCover;               /* Check for index coverage */
  3414   3438       struct IdxExprTrans *pIdxTrans;           /* Convert idxed expr to column */
  3415   3439       ExprList *pGroupBy;                       /* GROUP BY clause */
  3416   3440       Select *pSelect;                          /* HAVING to WHERE clause ctx */
         3441  +    struct WindowRewrite *pRewrite;           /* Window rewrite context */
  3417   3442     } u;
  3418   3443   };
  3419   3444   
  3420   3445   /* Forward declarations */
  3421   3446   int sqlite3WalkExpr(Walker*, Expr*);
  3422   3447   int sqlite3WalkExprList(Walker*, ExprList*);
  3423   3448   int sqlite3WalkSelect(Walker*, Select*);
................................................................................
  3460   3485   */
  3461   3486   struct TreeView {
  3462   3487     int iLevel;             /* Which level of the tree we are on */
  3463   3488     u8  bLine[100];         /* Draw vertical in column i if bLine[i] is true */
  3464   3489   };
  3465   3490   #endif /* SQLITE_DEBUG */
  3466   3491   
         3492  +/*
         3493  +** Object used to encode the OVER() clause attached to a window-function
         3494  +** invocation. And some fields used while generating VM code for the same.
         3495  +*/
         3496  +struct Window {
         3497  +  char *zName;            /* Name of window (may be NULL) */
         3498  +  ExprList *pPartition;   /* PARTITION BY clause */
         3499  +  ExprList *pOrderBy;     /* ORDER BY clause */
         3500  +  u8 eType;               /* TK_RANGE or TK_ROWS */
         3501  +  u8 eStart;              /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */
         3502  +  u8 eEnd;                /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */
         3503  +  Expr *pStart;           /* Expression for "<expr> PRECEDING" */
         3504  +  Expr *pEnd;             /* Expression for "<expr> FOLLOWING" */
         3505  +
         3506  +  Window *pNextWin;       /* Next window function belonging to this SELECT */
         3507  +
         3508  +  Expr *pFilter;
         3509  +  FuncDef *pFunc;
         3510  +
         3511  +  int iEphCsr;            /* Temp table used by this window */
         3512  +  int regAccum;
         3513  +  int regResult;
         3514  +
         3515  +  int csrApp;             /* Function cursor (used by min/max) */
         3516  +  int regApp;             /* Function register (also used by min/max) */
         3517  +
         3518  +  int regPart;
         3519  +  Expr *pOwner;           /* Expression object this window is attached to */
         3520  +  int nBufferCol;         /* Number of columns in buffer table */
         3521  +  int iArgCol;            /* Offset of first argument for this function */
         3522  +};
         3523  +
         3524  +#ifndef SQLITE_OMIT_WINDOWFUNC
         3525  +void sqlite3WindowDelete(sqlite3*, Window*);
         3526  +void sqlite3WindowListDelete(sqlite3 *db, Window *p);
         3527  +Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*);
         3528  +void sqlite3WindowAttach(Parse*, Expr*, Window*);
         3529  +int sqlite3WindowCompare(Parse*, Window*, Window*);
         3530  +void sqlite3WindowCodeInit(Parse*, Window*);
         3531  +void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int);
         3532  +int sqlite3WindowRewrite(Parse*, Select*);
         3533  +int sqlite3ExpandSubquery(Parse*, struct SrcList_item*);
         3534  +void sqlite3WindowUpdate(Parse*, Window*, Window*, FuncDef*);
         3535  +Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p);
         3536  +Window *sqlite3WindowListDup(sqlite3 *db, Window *p);
         3537  +void sqlite3WindowFunctions(void);
         3538  +#else
         3539  +# define sqlite3WindowDelete(a,b)
         3540  +# define sqlite3WindowFunctions()
         3541  +# define sqlite3WindowAttach(a,b,c)
         3542  +#endif
         3543  +
  3467   3544   /*
  3468   3545   ** Assuming zIn points to the first byte of a UTF-8 character,
  3469   3546   ** advance zIn to point to the first byte of the next UTF-8 character.
  3470   3547   */
  3471   3548   #define SQLITE_SKIP_UTF8(zIn) {                        \
  3472   3549     if( (*(zIn++))>=0xc0 ){                              \
  3473   3550       while( (*zIn & 0xc0)==0x80 ){ zIn++; }             \
................................................................................
  4167   4244   void sqlite3SchemaClear(void *);
  4168   4245   Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
  4169   4246   int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
  4170   4247   KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int);
  4171   4248   void sqlite3KeyInfoUnref(KeyInfo*);
  4172   4249   KeyInfo *sqlite3KeyInfoRef(KeyInfo*);
  4173   4250   KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*);
         4251  +KeyInfo *sqlite3KeyInfoFromExprList(Parse*, ExprList*, int, int);
         4252  +
  4174   4253   #ifdef SQLITE_DEBUG
  4175   4254   int sqlite3KeyInfoIsWriteable(KeyInfo*);
  4176   4255   #endif
  4177   4256   int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
  4178   4257     void (*)(sqlite3_context*,int,sqlite3_value **),
  4179         -  void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*),
         4258  +  void (*)(sqlite3_context*,int,sqlite3_value **), 
         4259  +  void (*)(sqlite3_context*),
         4260  +  void (*)(sqlite3_context*),
         4261  +  void (*)(sqlite3_context*,int,sqlite3_value **), 
  4180   4262     FuncDestructor *pDestructor
  4181   4263   );
  4182   4264   void sqlite3NoopDestructor(void*);
  4183   4265   void sqlite3OomFault(sqlite3*);
  4184   4266   void sqlite3OomClear(sqlite3*);
  4185   4267   int sqlite3ApiExit(sqlite3 *db, int);
  4186   4268   int sqlite3OpenTempDatabase(Parse *);
................................................................................
  4213   4295   ** The interface to the LEMON-generated parser
  4214   4296   */
  4215   4297   #ifndef SQLITE_AMALGAMATION
  4216   4298     void *sqlite3ParserAlloc(void*(*)(u64), Parse*);
  4217   4299     void sqlite3ParserFree(void*, void(*)(void*));
  4218   4300   #endif
  4219   4301   void sqlite3Parser(void*, int, Token);
         4302  +int sqlite3ParserFallback(int);
  4220   4303   #ifdef YYTRACKMAXSTACKDEPTH
  4221   4304     int sqlite3ParserStackPeak(void*);
  4222   4305   #endif
  4223   4306   
  4224   4307   void sqlite3AutoLoadExtensions(sqlite3*);
  4225   4308   #ifndef SQLITE_OMIT_LOAD_EXTENSION
  4226   4309     void sqlite3CloseExtensions(sqlite3*);

Changes to src/test1.c.

  7795   7795     extern int sqlite3WalTrace;
  7796   7796   #endif
  7797   7797   #ifdef SQLITE_TEST
  7798   7798   #ifdef SQLITE_ENABLE_FTS3
  7799   7799     extern int sqlite3_fts3_enable_parentheses;
  7800   7800   #endif
  7801   7801   #endif
         7802  +#if defined(SQLITE_ENABLE_SELECTTRACE)
         7803  +  extern int sqlite3SelectTrace;
         7804  +#endif
  7802   7805   
  7803   7806     for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
  7804   7807       Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  7805   7808     }
  7806   7809     for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
  7807   7810       Tcl_CreateObjCommand(interp, aObjCmd[i].zName, 
  7808   7811           aObjCmd[i].xProc, aObjCmd[i].clientData, 0);
................................................................................
  7880   7883         (char*)&bitmask_size, TCL_LINK_INT|TCL_LINK_READ_ONLY);
  7881   7884     Tcl_LinkVar(interp, "longdouble_size",
  7882   7885         (char*)&longdouble_size, TCL_LINK_INT|TCL_LINK_READ_ONLY);
  7883   7886     Tcl_LinkVar(interp, "sqlite_sync_count",
  7884   7887         (char*)&sqlite3_sync_count, TCL_LINK_INT);
  7885   7888     Tcl_LinkVar(interp, "sqlite_fullsync_count",
  7886   7889         (char*)&sqlite3_fullsync_count, TCL_LINK_INT);
         7890  +#if defined(SQLITE_ENABLE_SELECTTRACE)
         7891  +  Tcl_LinkVar(interp, "sqlite3SelectTrace",
         7892  +      (char*)&sqlite3SelectTrace, TCL_LINK_INT);
         7893  +#endif
  7887   7894   #if defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_TEST)
  7888   7895     Tcl_LinkVar(interp, "sqlite_fts3_enable_parentheses",
  7889   7896         (char*)&sqlite3_fts3_enable_parentheses, TCL_LINK_INT);
  7890   7897   #endif
  7891   7898     return TCL_OK;
  7892   7899   }

Changes to src/test_config.c.

   757    757   #endif
   758    758   
   759    759   #ifdef SQLITE_ENABLE_URI_00_ERROR
   760    760     Tcl_SetVar2(interp, "sqlite_options", "uri_00_error", "1", TCL_GLOBAL_ONLY);
   761    761   #else
   762    762     Tcl_SetVar2(interp, "sqlite_options", "uri_00_error", "0", TCL_GLOBAL_ONLY);
   763    763   #endif
          764  +
          765  +#ifdef SQLITE_OMIT_WINDOWFUNC
          766  +  Tcl_SetVar2(interp, "sqlite_options", "windowfunc", "0", TCL_GLOBAL_ONLY);
          767  +#else
          768  +  Tcl_SetVar2(interp, "sqlite_options", "windowfunc", "1", TCL_GLOBAL_ONLY);
          769  +#endif
   764    770   
   765    771   #define LINKVAR(x) { \
   766    772       static const int cv_ ## x = SQLITE_ ## x; \
   767    773       Tcl_LinkVar(interp, "SQLITE_" #x, (char *)&(cv_ ## x), \
   768    774                   TCL_LINK_INT | TCL_LINK_READ_ONLY); }
   769    775   
   770    776     LINKVAR( MAX_LENGTH );

Changes to src/test_tclsh.c.

   101    101   #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
   102    102     extern int Sqlitetestfts3_Init(Tcl_Interp *interp);
   103    103   #endif
   104    104   #ifdef SQLITE_ENABLE_ZIPVFS
   105    105     extern int Zipvfs_Init(Tcl_Interp*);
   106    106   #endif
   107    107     extern int TestExpert_Init(Tcl_Interp*);
          108  +  extern int Sqlitetest_window_Init(Tcl_Interp *);
   108    109   
   109    110     Tcl_CmdInfo cmdInfo;
   110    111   
   111    112     /* Since the primary use case for this binary is testing of SQLite,
   112    113     ** be sure to generate core files if we crash */
   113    114   #if defined(unix)
   114    115     { struct rlimit x;
................................................................................
   165    166     SqliteRbu_Init(interp);
   166    167     Sqlitetesttcl_Init(interp);
   167    168   
   168    169   #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
   169    170     Sqlitetestfts3_Init(interp);
   170    171   #endif
   171    172     TestExpert_Init(interp);
          173  +  Sqlitetest_window_Init(interp);
   172    174   
   173    175     Tcl_CreateObjCommand(
   174    176         interp, "load_testfixture_extensions", load_testfixture_extensions,0,0
   175    177     );
   176    178     return 0;
   177    179   }
   178    180   

Added src/test_window.c.

            1  +/*
            2  +** 2018 June 17
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +*/
           13  +
           14  +#include "sqlite3.h"
           15  +
           16  +#ifdef SQLITE_TEST
           17  +
           18  +#include "sqliteInt.h"
           19  +#include <tcl.h>
           20  +
           21  +extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb);
           22  +extern const char *sqlite3ErrName(int);
           23  +
           24  +typedef struct TestWindow TestWindow;
           25  +struct TestWindow {
           26  +  Tcl_Obj *xStep;
           27  +  Tcl_Obj *xFinal;
           28  +  Tcl_Obj *xValue;
           29  +  Tcl_Obj *xInverse;
           30  +  Tcl_Interp *interp;
           31  +};
           32  +
           33  +typedef struct TestWindowCtx TestWindowCtx;
           34  +struct TestWindowCtx {
           35  +  Tcl_Obj *pVal;
           36  +};
           37  +
           38  +static void doTestWindowStep(
           39  +  int bInverse,
           40  +  sqlite3_context *ctx, 
           41  +  int nArg, 
           42  +  sqlite3_value **apArg
           43  +){
           44  +  int i;
           45  +  TestWindow *p = (TestWindow*)sqlite3_user_data(ctx);
           46  +  Tcl_Obj *pEval = Tcl_DuplicateObj(bInverse ? p->xInverse : p->xStep);
           47  +  TestWindowCtx *pCtx = sqlite3_aggregate_context(ctx, sizeof(TestWindowCtx));
           48  +
           49  +  Tcl_IncrRefCount(pEval);
           50  +  if( pCtx ){
           51  +    const char *zResult;
           52  +    int rc;
           53  +    if( pCtx->pVal ){
           54  +      Tcl_ListObjAppendElement(p->interp, pEval, Tcl_DuplicateObj(pCtx->pVal));
           55  +    }else{
           56  +      Tcl_ListObjAppendElement(p->interp, pEval, Tcl_NewStringObj("", -1));
           57  +    }
           58  +    for(i=0; i<nArg; i++){
           59  +      Tcl_Obj *pArg;
           60  +      pArg = Tcl_NewStringObj((const char*)sqlite3_value_text(apArg[i]), -1);
           61  +      Tcl_ListObjAppendElement(p->interp, pEval, pArg);
           62  +    }
           63  +    rc = Tcl_EvalObjEx(p->interp, pEval, TCL_EVAL_GLOBAL);
           64  +    if( rc!=TCL_OK ){
           65  +      zResult = Tcl_GetStringResult(p->interp);
           66  +      sqlite3_result_error(ctx, zResult, -1);
           67  +    }else{
           68  +      if( pCtx->pVal ) Tcl_DecrRefCount(pCtx->pVal);
           69  +      pCtx->pVal = Tcl_DuplicateObj(Tcl_GetObjResult(p->interp));
           70  +      Tcl_IncrRefCount(pCtx->pVal);
           71  +    }
           72  +  }
           73  +  Tcl_DecrRefCount(pEval);
           74  +}
           75  +
           76  +static void doTestWindowFinalize(int bValue, sqlite3_context *ctx){
           77  +  TestWindow *p = (TestWindow*)sqlite3_user_data(ctx);
           78  +  Tcl_Obj *pEval = Tcl_DuplicateObj(bValue ? p->xValue : p->xFinal);
           79  +  TestWindowCtx *pCtx = sqlite3_aggregate_context(ctx, sizeof(TestWindowCtx));
           80  +
           81  +  Tcl_IncrRefCount(pEval);
           82  +  if( pCtx ){
           83  +    const char *zResult;
           84  +    int rc;
           85  +    if( pCtx->pVal ){
           86  +      Tcl_ListObjAppendElement(p->interp, pEval, Tcl_DuplicateObj(pCtx->pVal));
           87  +    }else{
           88  +      Tcl_ListObjAppendElement(p->interp, pEval, Tcl_NewStringObj("", -1));
           89  +    }
           90  +
           91  +    rc = Tcl_EvalObjEx(p->interp, pEval, TCL_EVAL_GLOBAL);
           92  +    zResult = Tcl_GetStringResult(p->interp);
           93  +    if( rc!=TCL_OK ){
           94  +      sqlite3_result_error(ctx, zResult, -1);
           95  +    }else{
           96  +      sqlite3_result_text(ctx, zResult, -1, SQLITE_TRANSIENT);
           97  +    }
           98  +
           99  +    if( bValue==0 ){
          100  +      if( pCtx->pVal ) Tcl_DecrRefCount(pCtx->pVal);
          101  +      pCtx->pVal = 0;
          102  +    }
          103  +  }
          104  +  Tcl_DecrRefCount(pEval);
          105  +}
          106  +
          107  +static void testWindowStep(
          108  +  sqlite3_context *ctx, 
          109  +  int nArg, 
          110  +  sqlite3_value **apArg
          111  +){
          112  +  doTestWindowStep(0, ctx, nArg, apArg);
          113  +}
          114  +static void testWindowInverse(
          115  +  sqlite3_context *ctx, 
          116  +  int nArg, 
          117  +  sqlite3_value **apArg
          118  +){
          119  +  doTestWindowStep(1, ctx, nArg, apArg);
          120  +}
          121  +
          122  +static void testWindowFinal(sqlite3_context *ctx){
          123  +  doTestWindowFinalize(0, ctx);
          124  +}
          125  +static void testWindowValue(sqlite3_context *ctx){
          126  +  doTestWindowFinalize(1, ctx);
          127  +}
          128  +
          129  +static void testWindowDestroy(void *pCtx){
          130  +  ckfree(pCtx);
          131  +}
          132  +
          133  +/*
          134  +** Usage: sqlite3_create_window_function DB NAME XSTEP XFINAL XVALUE XINVERSE
          135  +*/
          136  +static int SQLITE_TCLAPI test_create_window(
          137  +  void * clientData,
          138  +  Tcl_Interp *interp,
          139  +  int objc,
          140  +  Tcl_Obj *CONST objv[]
          141  +){
          142  +  TestWindow *pNew;
          143  +  sqlite3 *db;
          144  +  const char *zName;
          145  +  int rc;
          146  +
          147  +  if( objc!=7 ){
          148  +    Tcl_WrongNumArgs(interp, 1, objv, "DB NAME XSTEP XFINAL XVALUE XINVERSE");
          149  +    return TCL_ERROR;
          150  +  }
          151  +
          152  +  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
          153  +  zName = Tcl_GetString(objv[2]);
          154  +  pNew = ckalloc(sizeof(TestWindow));
          155  +  memset(pNew, 0, sizeof(TestWindow));
          156  +  pNew->xStep = Tcl_DuplicateObj(objv[3]);
          157  +  pNew->xFinal = Tcl_DuplicateObj(objv[4]);
          158  +  pNew->xValue = Tcl_DuplicateObj(objv[5]);
          159  +  pNew->xInverse = Tcl_DuplicateObj(objv[6]);
          160  +  pNew->interp = interp;
          161  +
          162  +  Tcl_IncrRefCount(pNew->xStep);
          163  +  Tcl_IncrRefCount(pNew->xFinal);
          164  +  Tcl_IncrRefCount(pNew->xValue);
          165  +  Tcl_IncrRefCount(pNew->xInverse);
          166  +
          167  +  rc = sqlite3_create_window_function(db, zName, -1, SQLITE_UTF8, (void*)pNew,
          168  +      testWindowStep, testWindowFinal, testWindowValue, testWindowInverse,
          169  +      testWindowDestroy
          170  +  );
          171  +  if( rc!=SQLITE_OK ){
          172  +    Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
          173  +    return TCL_ERROR;
          174  +  }
          175  +
          176  +  return TCL_OK;
          177  +}
          178  +
          179  +static int SQLITE_TCLAPI test_create_window_misuse(
          180  +  void * clientData,
          181  +  Tcl_Interp *interp,
          182  +  int objc,
          183  +  Tcl_Obj *CONST objv[]
          184  +){
          185  +  sqlite3 *db;
          186  +  int rc;
          187  +
          188  +  if( objc!=2 ){
          189  +    Tcl_WrongNumArgs(interp, 1, objv, "DB");
          190  +    return TCL_ERROR;
          191  +  }
          192  +  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
          193  +
          194  +  rc = sqlite3_create_window_function(db, "fff", -1, SQLITE_UTF8, 0,
          195  +      0, testWindowFinal, testWindowValue, testWindowInverse,
          196  +      0
          197  +  );
          198  +  if( rc!=SQLITE_MISUSE ) goto error;
          199  +  rc = sqlite3_create_window_function(db, "fff", -1, SQLITE_UTF8, 0,
          200  +      testWindowStep, 0, testWindowValue, testWindowInverse,
          201  +      0
          202  +  );
          203  +  if( rc!=SQLITE_MISUSE ) goto error;
          204  +  rc = sqlite3_create_window_function(db, "fff", -1, SQLITE_UTF8, 0,
          205  +      testWindowStep, testWindowFinal, 0, testWindowInverse,
          206  +      0
          207  +  );
          208  +  if( rc!=SQLITE_MISUSE ) goto error;
          209  +  rc = sqlite3_create_window_function(db, "fff", -1, SQLITE_UTF8, 0,
          210  +      testWindowStep, testWindowFinal, testWindowValue, 0,
          211  +      0
          212  +  );
          213  +  if( rc!=SQLITE_MISUSE ) goto error;
          214  +
          215  +  return TCL_OK;
          216  +
          217  + error:
          218  +  Tcl_SetObjResult(interp, Tcl_NewStringObj("misuse test error", -1));
          219  +  return TCL_ERROR;
          220  +}
          221  +
          222  +/*
          223  +** xStep for sumint().
          224  +*/
          225  +static void sumintStep(
          226  +  sqlite3_context *ctx, 
          227  +  int nArg, 
          228  +  sqlite3_value *apArg[]
          229  +){
          230  +  sqlite3_int64 *pInt;
          231  +
          232  +  assert( nArg==1 );
          233  +  if( sqlite3_value_type(apArg[0])!=SQLITE_INTEGER ){
          234  +    sqlite3_result_error(ctx, "invalid argument", -1);
          235  +    return;
          236  +  }
          237  +  pInt = (sqlite3_int64*)sqlite3_aggregate_context(ctx, sizeof(sqlite3_int64));
          238  +  if( pInt ){
          239  +    *pInt += sqlite3_value_int64(apArg[0]);
          240  +  }
          241  +}
          242  +
          243  +/*
          244  +** xInverse for sumint().
          245  +*/
          246  +static void sumintInverse(
          247  +  sqlite3_context *ctx, 
          248  +  int nArg, 
          249  +  sqlite3_value *apArg[]
          250  +){
          251  +  sqlite3_int64 *pInt;
          252  +  pInt = (sqlite3_int64*)sqlite3_aggregate_context(ctx, sizeof(sqlite3_int64));
          253  +  *pInt -= sqlite3_value_int64(apArg[0]);
          254  +}
          255  +
          256  +/*
          257  +** xFinal for sumint().
          258  +*/
          259  +static void sumintFinal(sqlite3_context *ctx){
          260  +  sqlite3_int64 res = 0;
          261  +  sqlite3_int64 *pInt;
          262  +  pInt = (sqlite3_int64*)sqlite3_aggregate_context(ctx, 0);
          263  +  if( pInt ) res = *pInt;
          264  +  sqlite3_result_int64(ctx, res);
          265  +}
          266  +
          267  +/*
          268  +** xValue for sumint().
          269  +*/
          270  +static void sumintValue(sqlite3_context *ctx){
          271  +  sqlite3_int64 res = 0;
          272  +  sqlite3_int64 *pInt;
          273  +  pInt = (sqlite3_int64*)sqlite3_aggregate_context(ctx, 0);
          274  +  if( pInt ) res = *pInt;
          275  +  sqlite3_result_int64(ctx, res);
          276  +}
          277  +
          278  +static int SQLITE_TCLAPI test_create_sumint(
          279  +  void * clientData,
          280  +  Tcl_Interp *interp,
          281  +  int objc,
          282  +  Tcl_Obj *CONST objv[]
          283  +){
          284  +  sqlite3 *db;
          285  +  int rc;
          286  +
          287  +  if( objc!=2 ){
          288  +    Tcl_WrongNumArgs(interp, 1, objv, "DB");
          289  +    return TCL_ERROR;
          290  +  }
          291  +  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
          292  +
          293  +  rc = sqlite3_create_window_function(db, "sumint", 1, SQLITE_UTF8, 0,
          294  +      sumintStep, sumintFinal, sumintValue, sumintInverse,
          295  +      0
          296  +  );
          297  +
          298  +  if( rc!=SQLITE_OK ){
          299  +    Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
          300  +    return TCL_ERROR;
          301  +  }
          302  +  return TCL_OK;
          303  +}
          304  +
          305  +int Sqlitetest_window_Init(Tcl_Interp *interp){
          306  +  static struct {
          307  +     char *zName;
          308  +     Tcl_ObjCmdProc *xProc;
          309  +     int clientData;
          310  +  } aObjCmd[] = {
          311  +     { "sqlite3_create_window_function", test_create_window, 0 },
          312  +     { "test_create_window_function_misuse", test_create_window_misuse, 0 },
          313  +     { "test_create_sumint", test_create_sumint, 0 },
          314  +  };
          315  +  int i;
          316  +  for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
          317  +    ClientData c = (ClientData)SQLITE_INT_TO_PTR(aObjCmd[i].clientData);
          318  +    Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, c, 0);
          319  +  }
          320  +  return TCL_OK;
          321  +}
          322  +#endif

Changes to src/tokenize.c.

    50     50   #define CC_STAR      21    /* '*' */
    51     51   #define CC_PERCENT   22    /* '%' */
    52     52   #define CC_COMMA     23    /* ',' */
    53     53   #define CC_AND       24    /* '&' */
    54     54   #define CC_TILDA     25    /* '~' */
    55     55   #define CC_DOT       26    /* '.' */
    56     56   #define CC_ILLEGAL   27    /* Illegal character */
           57  +#define CC_NUL       28    /* 0x00 */
    57     58   
    58     59   static const unsigned char aiClass[] = {
    59     60   #ifdef SQLITE_ASCII
    60     61   /*         x0  x1  x2  x3  x4  x5  x6  x7  x8  x9  xa  xb  xc  xd  xe  xf */
    61         -/* 0x */   27, 27, 27, 27, 27, 27, 27, 27, 27,  7,  7, 27,  7,  7, 27, 27,
           62  +/* 0x */   28, 27, 27, 27, 27, 27, 27, 27, 27,  7,  7, 27,  7,  7, 27, 27,
    62     63   /* 1x */   27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
    63     64   /* 2x */    7, 15,  8,  5,  4, 22, 24,  8, 17, 18, 21, 20, 23, 11, 26, 16,
    64     65   /* 3x */    3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  5, 19, 12, 14, 13,  6,
    65     66   /* 4x */    5,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
    66     67   /* 5x */    1,  1,  1,  1,  1,  1,  1,  1,  0,  1,  1,  9, 27, 27, 27,  1,
    67     68   /* 6x */    8,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
    68     69   /* 7x */    1,  1,  1,  1,  1,  1,  1,  1,  0,  1,  1, 27, 10, 27, 25, 27,
................................................................................
   184    185   #endif
   185    186   
   186    187   /* Make the IdChar function accessible from ctime.c */
   187    188   #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
   188    189   int sqlite3IsIdChar(u8 c){ return IdChar(c); }
   189    190   #endif
   190    191   
          192  +#ifndef SQLITE_OMIT_WINDOWFUNC
          193  +/*
          194  +** Return the id of the next token in string (*pz). Before returning, set
          195  +** (*pz) to point to the byte following the parsed token.
          196  +*/
          197  +static int getToken(const unsigned char **pz){
          198  +  const unsigned char *z = *pz;
          199  +  int t;                          /* Token type to return */
          200  +  do {
          201  +    z += sqlite3GetToken(z, &t);
          202  +  }while( t==TK_SPACE );
          203  +  if( t==TK_ID 
          204  +   || t==TK_STRING 
          205  +   || t==TK_JOIN_KW 
          206  +   || t==TK_WINDOW 
          207  +   || t==TK_OVER 
          208  +   || sqlite3ParserFallback(t)==TK_ID 
          209  +  ){
          210  +    t = TK_ID;
          211  +  }
          212  +  *pz = z;
          213  +  return t;
          214  +}
          215  +
          216  +/*
          217  +** The following three functions are called immediately after the tokenizer
          218  +** reads the keywords WINDOW, OVER and FILTER, respectively, to determine
          219  +** whether the token should be treated as a keyword or an SQL identifier.
          220  +** This cannot be handled by the usual lemon %fallback method, due to
          221  +** the ambiguity in some constructions. e.g.
          222  +**
          223  +**   SELECT sum(x) OVER ...
          224  +**
          225  +** In the above, "OVER" might be a keyword, or it might be an alias for the 
          226  +** sum(x) expression. If a "%fallback ID OVER" directive were added to 
          227  +** grammar, then SQLite would always treat "OVER" as an alias, making it
          228  +** impossible to call a window-function without a FILTER clause.
          229  +**
          230  +** WINDOW is treated as a keyword if:
          231  +**
          232  +**   * the following token is an identifier, or a keyword that can fallback
          233  +**     to being an identifier, and
          234  +**   * the token after than one is TK_AS.
          235  +**
          236  +** OVER is a keyword if:
          237  +**
          238  +**   * the previous token was TK_RP, and
          239  +**   * the next token is either TK_LP or an identifier.
          240  +**
          241  +** FILTER is a keyword if:
          242  +**
          243  +**   * the previous token was TK_RP, and
          244  +**   * the next token is TK_LP.
          245  +*/
          246  +static int analyzeWindowKeyword(const unsigned char *z){
          247  +  int t;
          248  +  t = getToken(&z);
          249  +  if( t!=TK_ID ) return TK_ID;
          250  +  t = getToken(&z);
          251  +  if( t!=TK_AS ) return TK_ID;
          252  +  return TK_WINDOW;
          253  +}
          254  +static int analyzeOverKeyword(const unsigned char *z, int lastToken){
          255  +  if( lastToken==TK_RP ){
          256  +    int t = getToken(&z);
          257  +    if( t==TK_LP || t==TK_ID ) return TK_OVER;
          258  +  }
          259  +  return TK_ID;
          260  +}
          261  +static int analyzeFilterKeyword(const unsigned char *z, int lastToken){
          262  +  if( lastToken==TK_RP && getToken(&z)==TK_LP ){
          263  +    return TK_FILTER;
          264  +  }
          265  +  return TK_ID;
          266  +}
          267  +#endif // SQLITE_OMIT_WINDOWFUNC
   191    268   
   192    269   /*
   193    270   ** Return the length (in bytes) of the token that begins at z[0]. 
   194    271   ** Store the token type in *tokenType before returning.
   195    272   */
   196    273   int sqlite3GetToken(const unsigned char *z, int *tokenType){
   197    274     int i, c;
................................................................................
   452    529         /* If it is not a BLOB literal, then it must be an ID, since no
   453    530         ** SQL keywords start with the letter 'x'.  Fall through */
   454    531       }
   455    532       case CC_ID: {
   456    533         i = 1;
   457    534         break;
   458    535       }
          536  +    case CC_NUL: {
          537  +      *tokenType = TK_ILLEGAL;
          538  +      return 0;
          539  +    }
   459    540       default: {
   460    541         *tokenType = TK_ILLEGAL;
   461    542         return 1;
   462    543       }
   463    544     }
   464    545     while( IdChar(z[i]) ){ i++; }
   465    546     *tokenType = TK_ID;
................................................................................
   505    586     }
   506    587   #endif
   507    588     assert( pParse->pNewTable==0 );
   508    589     assert( pParse->pNewTrigger==0 );
   509    590     assert( pParse->nVar==0 );
   510    591     assert( pParse->pVList==0 );
   511    592     while( 1 ){
   512         -    if( zSql[0]!=0 ){
   513         -      n = sqlite3GetToken((u8*)zSql, &tokenType);
   514         -      mxSqlLen -= n;
   515         -      if( mxSqlLen<0 ){
   516         -        pParse->rc = SQLITE_TOOBIG;
   517         -        break;
   518         -      }
   519         -    }else{
   520         -      /* Upon reaching the end of input, call the parser two more times
   521         -      ** with tokens TK_SEMI and 0, in that order. */
   522         -      if( lastTokenParsed==TK_SEMI ){
   523         -        tokenType = 0;
   524         -      }else if( lastTokenParsed==0 ){
   525         -        break;
   526         -      }else{
   527         -        tokenType = TK_SEMI;
   528         -      }
   529         -      n = 0;
          593  +    n = sqlite3GetToken((u8*)zSql, &tokenType);
          594  +    mxSqlLen -= n;
          595  +    if( mxSqlLen<0 ){
          596  +      pParse->rc = SQLITE_TOOBIG;
          597  +      break;
   530    598       }
          599  +#ifndef SQLITE_OMIT_WINDOWFUNC
          600  +    if( tokenType>=TK_WINDOW ){
          601  +      assert( tokenType==TK_SPACE || tokenType==TK_OVER || tokenType==TK_FILTER
          602  +           || tokenType==TK_ILLEGAL || tokenType==TK_WINDOW 
          603  +      );
          604  +#else
   531    605       if( tokenType>=TK_SPACE ){
   532    606         assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL );
          607  +#endif // SQLITE_OMIT_WINDOWFUNC
   533    608         if( db->u1.isInterrupted ){
   534    609           pParse->rc = SQLITE_INTERRUPT;
   535    610           break;
   536    611         }
   537         -      if( tokenType==TK_ILLEGAL ){
          612  +      if( tokenType==TK_SPACE ){
          613  +        zSql += n;
          614  +        continue;
          615  +      }
          616  +      if( zSql[0]==0 ){
          617  +        /* Upon reaching the end of input, call the parser two more times
          618  +        ** with tokens TK_SEMI and 0, in that order. */
          619  +        if( lastTokenParsed==TK_SEMI ){
          620  +          tokenType = 0;
          621  +        }else if( lastTokenParsed==0 ){
          622  +          break;
          623  +        }else{
          624  +          tokenType = TK_SEMI;
          625  +        }
          626  +        n = 0;
          627  +#ifndef SQLITE_OMIT_WINDOWFUNC
          628  +      }else if( tokenType==TK_WINDOW ){
          629  +        assert( n==6 );
          630  +        tokenType = analyzeWindowKeyword((const u8*)&zSql[6]);
          631  +      }else if( tokenType==TK_OVER ){
          632  +        assert( n==4 );
          633  +        tokenType = analyzeOverKeyword((const u8*)&zSql[4], lastTokenParsed);
          634  +      }else if( tokenType==TK_FILTER ){
          635  +        assert( n==6 );
          636  +        tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed);
          637  +#endif // SQLITE_OMIT_WINDOWFUNC
          638  +      }else{
   538    639           sqlite3ErrorMsg(pParse, "unrecognized token: \"%.*s\"", n, zSql);
   539    640           break;
   540    641         }
   541         -      zSql += n;
   542         -    }else{
   543         -      pParse->sLastToken.z = zSql;
   544         -      pParse->sLastToken.n = n;
   545         -      sqlite3Parser(pEngine, tokenType, pParse->sLastToken);
   546         -      lastTokenParsed = tokenType;
   547         -      zSql += n;
   548         -      if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break;
   549    642       }
          643  +    pParse->sLastToken.z = zSql;
          644  +    pParse->sLastToken.n = n;
          645  +    sqlite3Parser(pEngine, tokenType, pParse->sLastToken);
          646  +    lastTokenParsed = tokenType;
          647  +    zSql += n;
          648  +    if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break;
   550    649     }
   551    650     assert( nErr==0 );
   552    651   #ifdef YYTRACKMAXSTACKDEPTH
   553    652     sqlite3_mutex_enter(sqlite3MallocMutex());
   554    653     sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK,
   555    654         sqlite3ParserStackPeak(pEngine)
   556    655     );

Changes to src/vdbe.c.

  5078   5078   #ifdef SQLITE_TEST
  5079   5079     sqlite3_sort_count++;
  5080   5080     sqlite3_search_count--;
  5081   5081   #endif
  5082   5082     p->aCounter[SQLITE_STMTSTATUS_SORT]++;
  5083   5083     /* Fall through into OP_Rewind */
  5084   5084   }
  5085         -/* Opcode: Rewind P1 P2 * * *
         5085  +/* Opcode: Rewind P1 P2 * * P5
  5086   5086   **
  5087   5087   ** The next use of the Rowid or Column or Next instruction for P1 
  5088   5088   ** will refer to the first entry in the database table or index.
  5089   5089   ** If the table or index is empty, jump immediately to P2.
  5090   5090   ** If the table or index is not empty, fall through to the following 
  5091   5091   ** instruction.
         5092  +**
         5093  +** If P5 is non-zero and the table is not empty, then the "skip-next"
         5094  +** flag is set on the cursor so that the next OP_Next instruction 
         5095  +** executed on it is a no-op.
  5092   5096   **
  5093   5097   ** This opcode leaves the cursor configured to move in forward order,
  5094   5098   ** from the beginning toward the end.  In other words, the cursor is
  5095   5099   ** configured to use Next, not Prev.
  5096   5100   */
  5097   5101   case OP_Rewind: {        /* jump */
  5098   5102     VdbeCursor *pC;
................................................................................
  5110   5114     if( isSorter(pC) ){
  5111   5115       rc = sqlite3VdbeSorterRewind(pC, &res);
  5112   5116     }else{
  5113   5117       assert( pC->eCurType==CURTYPE_BTREE );
  5114   5118       pCrsr = pC->uc.pCursor;
  5115   5119       assert( pCrsr );
  5116   5120       rc = sqlite3BtreeFirst(pCrsr, &res);
         5121  +#ifndef SQLITE_OMIT_WINDOWFUNC
         5122  +    if( pOp->p5 ) sqlite3BtreeSkipNext(pCrsr);
         5123  +#endif
  5117   5124       pC->deferredMoveto = 0;
  5118   5125       pC->cacheStatus = CACHE_STALE;
  5119   5126     }
  5120   5127     if( rc ) goto abort_due_to_error;
  5121   5128     pC->nullRow = (u8)res;
  5122   5129     assert( pOp->p2>0 && pOp->p2<p->nOp );
  5123   5130     VdbeBranchTaken(res!=0,2);
................................................................................
  6277   6284     if( pIn1->u.i>SMALLEST_INT64 ) pIn1->u.i--;
  6278   6285     VdbeBranchTaken(pIn1->u.i==0, 2);
  6279   6286     if( pIn1->u.i==0 ) goto jump_to_p2;
  6280   6287     break;
  6281   6288   }
  6282   6289   
  6283   6290   
  6284         -/* Opcode: AggStep0 * P2 P3 P4 P5
         6291  +/* Opcode: AggStep0 P1 P2 P3 P4 P5
  6285   6292   ** Synopsis: accum=r[P3] step(r[P2@P5])
  6286   6293   **
  6287         -** Execute the step function for an aggregate.  The
  6288         -** function has P5 arguments.   P4 is a pointer to the FuncDef
  6289         -** structure that specifies the function.  Register P3 is the
         6294  +** Execute the xStep (if P1==0) or xInverse (if P1!=0) function for an
         6295  +** aggregate.  The function has P5 arguments.  P4 is a pointer to the 
         6296  +** FuncDef structure that specifies the function.  Register P3 is the
  6290   6297   ** accumulator.
  6291   6298   **
  6292   6299   ** The P5 arguments are taken from register P2 and its
  6293   6300   ** successors.
  6294   6301   */
  6295         -/* Opcode: AggStep * P2 P3 P4 P5
         6302  +/* Opcode: AggStep P1 P2 P3 P4 P5
  6296   6303   ** Synopsis: accum=r[P3] step(r[P2@P5])
  6297   6304   **
  6298         -** Execute the step function for an aggregate.  The
  6299         -** function has P5 arguments.   P4 is a pointer to an sqlite3_context
  6300         -** object that is used to run the function.  Register P3 is
  6301         -** as the accumulator.
         6305  +** Execute the xStep (if P1==0) or xInverse (if P1!=0) function for an
         6306  +** aggregate.  The function has P5 arguments.  P4 is a pointer to the 
         6307  +** FuncDef structure that specifies the function.  Register P3 is the
         6308  +** accumulator.
  6302   6309   **
  6303   6310   ** The P5 arguments are taken from register P2 and its
  6304   6311   ** successors.
  6305   6312   **
  6306   6313   ** This opcode is initially coded as OP_AggStep0.  On first evaluation,
  6307   6314   ** the FuncDef stored in P4 is converted into an sqlite3_context and
  6308   6315   ** the opcode is changed.  In this way, the initialization of the
................................................................................
  6360   6367     }
  6361   6368   #endif
  6362   6369   
  6363   6370     pMem->n++;
  6364   6371     assert( pCtx->pOut->flags==MEM_Null );
  6365   6372     assert( pCtx->isError==0 );
  6366   6373     assert( pCtx->skipFlag==0 );
         6374  +#ifndef SQLITE_OMIT_WINDOWFUNC
         6375  +  if( pOp->p1 ){
         6376  +    (pCtx->pFunc->xInverse)(pCtx,pCtx->argc,pCtx->argv);
         6377  +  }else
         6378  +#endif
  6367   6379     (pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */
         6380  +
  6368   6381     if( pCtx->isError ){
  6369   6382       if( pCtx->isError>0 ){
  6370   6383         sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut));
  6371   6384         rc = pCtx->isError;
  6372   6385       }
  6373   6386       if( pCtx->skipFlag ){
  6374   6387         assert( pOp[-1].opcode==OP_CollSeq );
................................................................................
  6382   6395       if( rc ) goto abort_due_to_error;
  6383   6396     }
  6384   6397     assert( pCtx->pOut->flags==MEM_Null );
  6385   6398     assert( pCtx->skipFlag==0 );
  6386   6399     break;
  6387   6400   }
  6388   6401   
  6389         -/* Opcode: AggFinal P1 P2 * P4 *
         6402  +/* Opcode: AggFinal P1 P2 P3 P4 *
  6390   6403   ** Synopsis: accum=r[P1] N=P2
  6391   6404   **
  6392         -** Execute the finalizer function for an aggregate.  P1 is
  6393         -** the memory location that is the accumulator for the aggregate.
         6405  +** P1 is the memory location that is the accumulator for an aggregate
         6406  +** or window function. If P3 is zero, then execute the finalizer function 
         6407  +** for an aggregate and store the result in P1. Or, if P3 is non-zero,
         6408  +** invoke the xValue() function and store the result in register P3.
  6394   6409   **
  6395   6410   ** P2 is the number of arguments that the step function takes and
  6396   6411   ** P4 is a pointer to the FuncDef for this function.  The P2
  6397   6412   ** argument is not used by this opcode.  It is only there to disambiguate
  6398   6413   ** functions that can take varying numbers of arguments.  The
  6399   6414   ** P4 argument is only needed for the degenerate case where
  6400   6415   ** the step function was not previously called.
  6401   6416   */
  6402   6417   case OP_AggFinal: {
  6403   6418     Mem *pMem;
  6404   6419     assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
  6405   6420     pMem = &aMem[pOp->p1];
  6406   6421     assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
         6422  +#ifndef SQLITE_OMIT_WINDOWFUNC
         6423  +  if( pOp->p3 ){
         6424  +    rc = sqlite3VdbeMemAggValue(pMem, &aMem[pOp->p3], pOp->p4.pFunc);
         6425  +    pMem = &aMem[pOp->p3];
         6426  +  }else
         6427  +#endif
  6407   6428     rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
         6429  +  
  6408   6430     if( rc ){
  6409   6431       sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem));
  6410   6432       goto abort_due_to_error;
  6411   6433     }
  6412   6434     sqlite3VdbeChangeEncoding(pMem, encoding);
  6413   6435     UPDATE_MAX_BLOBSIZE(pMem);
  6414   6436     if( sqlite3VdbeMemTooBig(pMem) ){

Changes to src/vdbe.h.

   239    239   void sqlite3VdbeResolveLabel(Vdbe*, int);
   240    240   #ifdef SQLITE_COVERAGE_TEST
   241    241     int sqlite3VdbeLabelHasBeenResolved(Vdbe*,int);
   242    242   #endif
   243    243   int sqlite3VdbeCurrentAddr(Vdbe*);
   244    244   #ifdef SQLITE_DEBUG
   245    245     int sqlite3VdbeAssertMayAbort(Vdbe *, int);
          246  +  int sqlite3VdbeAssertAggContext(sqlite3_context*);
   246    247   #endif
   247    248   void sqlite3VdbeResetStepResult(Vdbe*);
   248    249   void sqlite3VdbeRewind(Vdbe*);
   249    250   int sqlite3VdbeReset(Vdbe*);
   250    251   void sqlite3VdbeSetNumCols(Vdbe*,int);
   251    252   int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*));
   252    253   void sqlite3VdbeCountChanges(Vdbe*);

Changes to src/vdbeInt.h.

   493    493   void sqlite3VdbeIntegerAffinity(Mem*);
   494    494   int sqlite3VdbeMemRealify(Mem*);
   495    495   int sqlite3VdbeMemNumerify(Mem*);
   496    496   void sqlite3VdbeMemCast(Mem*,u8,u8);
   497    497   int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*);
   498    498   void sqlite3VdbeMemRelease(Mem *p);
   499    499   int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
          500  +#ifndef SQLITE_OMIT_WINDOWFUNC
          501  +int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*);
          502  +#endif
   500    503   const char *sqlite3OpcodeName(int);
   501    504   int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
   502    505   int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
   503    506   int sqlite3VdbeCloseStatement(Vdbe *, int);
   504    507   void sqlite3VdbeFrameDelete(VdbeFrame*);
   505    508   int sqlite3VdbeFrameRestore(VdbeFrame *);
   506    509   #ifdef SQLITE_ENABLE_PREUPDATE_HOOK

Changes to src/vdbeapi.c.

   820    820     if( (p->pMem->flags & MEM_Agg)==0 ){
   821    821       return createAggContext(p, nByte);
   822    822     }else{
   823    823       return (void*)p->pMem->z;
   824    824     }
   825    825   }
   826    826   
          827  +/*
          828  +** This function is only used within assert() statements to check that the
          829  +** aggregate context has already been allocated. i.e.:
          830  +**
          831  +**   assert( sqlite3VdbeAssertAggContext(p) );
          832  +*/
          833  +#ifdef SQLITE_DEBUG
          834  +int sqlite3VdbeAssertAggContext(sqlite3_context *p){
          835  +  return ((p->pMem->flags & MEM_Agg)!=0);
          836  +}
          837  +#endif /* SQLITE_DEBUG */
          838  +
   827    839   /*
   828    840   ** Return the auxiliary data pointer, if any, for the iArg'th argument to
   829    841   ** the user-function defined by pCtx.
   830    842   **
   831    843   ** The left-most argument is 0.
   832    844   **
   833    845   ** Undocumented behavior:  If iArg is negative then access a cache of

Changes to src/vdbemem.c.

   411    411     pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */
   412    412     assert( (pMem->flags & MEM_Dyn)==0 );
   413    413     if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
   414    414     memcpy(pMem, &t, sizeof(t));
   415    415     return ctx.isError;
   416    416   }
   417    417   
          418  +/*
          419  +** Memory cell pAccum contains the context of an aggregate function.
          420  +** This routine calls the xValue method for that function and stores
          421  +** the results in memory cell pMem.
          422  +**
          423  +** SQLITE_ERROR is returned if xValue() reports an error. SQLITE_OK 
          424  +** otherwise.
          425  +*/
          426  +#ifndef SQLITE_OMIT_WINDOWFUNC
          427  +int sqlite3VdbeMemAggValue(Mem *pAccum, Mem *pOut, FuncDef *pFunc){
          428  +  sqlite3_context ctx;
          429  +  Mem t;
          430  +  assert( pFunc!=0 );
          431  +  assert( pFunc->xValue!=0 );
          432  +  assert( (pAccum->flags & MEM_Null)!=0 || pFunc==pAccum->u.pDef );
          433  +  assert( pAccum->db==0 || sqlite3_mutex_held(pAccum->db->mutex) );
          434  +  memset(&ctx, 0, sizeof(ctx));
          435  +  memset(&t, 0, sizeof(t));
          436  +  t.flags = MEM_Null;
          437  +  t.db = pAccum->db;
          438  +  ctx.pOut = pOut;
          439  +  ctx.pMem = pAccum;
          440  +  ctx.pFunc = pFunc;
          441  +  pFunc->xValue(&ctx);
          442  +  return ctx.isError;
          443  +}
          444  +#endif /* SQLITE_OMIT_WINDOWFUNC */
          445  +
   418    446   /*
   419    447   ** If the memory cell contains a value that must be freed by
   420    448   ** invoking the external callback in Mem.xDel, then this routine
   421    449   ** will free that value.  It also sets Mem.flags to MEM_Null.
   422    450   **
   423    451   ** This is a helper routine for sqlite3VdbeMemSetNull() and
   424    452   ** for sqlite3VdbeMemRelease().  Use those other routines as the

Changes to src/walker.c.

    50     50           pExpr = pExpr->pRight;
    51     51           continue;
    52     52         }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
    53     53           if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
    54     54         }else if( pExpr->x.pList ){
    55     55           if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
    56     56         }
           57  +#ifndef SQLITE_OMIT_WINDOWFUNC
           58  +      if( !ExprHasProperty(pExpr, EP_Reduced) && pExpr->pWin ){
           59  +        Window *pWin = pExpr->pWin;
           60  +        if( sqlite3WalkExprList(pWalker, pWin->pPartition) ) return WRC_Abort;
           61  +        if( sqlite3WalkExprList(pWalker, pWin->pOrderBy) ) return WRC_Abort;
           62  +        if( sqlite3WalkExpr(pWalker, pWin->pFilter) ) return WRC_Abort;
           63  +      }
           64  +#endif
    57     65       }
    58     66       break;
    59     67     }
    60     68     return WRC_Continue;
    61     69   }
    62     70   int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){
    63     71     return pExpr ? walkExpr(pWalker,pExpr) : WRC_Continue;

Added src/window.c.

            1  +/*
            2  +** 2018 May 08
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +*/
           13  +#include "sqliteInt.h"
           14  +
           15  +#ifndef SQLITE_OMIT_WINDOWFUNC
           16  +
           17  +/*
           18  +** SELECT REWRITING
           19  +**
           20  +**   Any SELECT statement that contains one or more window functions in
           21  +**   either the select list or ORDER BY clause (the only two places window
           22  +**   functions may be used) is transformed by function sqlite3WindowRewrite()
           23  +**   in order to support window function processing. For example, with the
           24  +**   schema:
           25  +**
           26  +**     CREATE TABLE t1(a, b, c, d, e, f, g);
           27  +**
           28  +**   the statement:
           29  +**
           30  +**     SELECT a+1, max(b) OVER (PARTITION BY c ORDER BY d) FROM t1 ORDER BY e;
           31  +**
           32  +**   is transformed to:
           33  +**
           34  +**     SELECT a+1, max(b) OVER (PARTITION BY c ORDER BY d) FROM (
           35  +**         SELECT a, e, c, d, b FROM t1 ORDER BY c, d
           36  +**     ) ORDER BY e;
           37  +**
           38  +**   The flattening optimization is disabled when processing this transformed
           39  +**   SELECT statement. This allows the implementation of the window function
           40  +**   (in this case max()) to process rows sorted in order of (c, d), which
           41  +**   makes things easier for obvious reasons. More generally:
           42  +**
           43  +**     * FROM, WHERE, GROUP BY and HAVING clauses are all moved to 
           44  +**       the sub-query.
           45  +**
           46  +**     * ORDER BY, LIMIT and OFFSET remain part of the parent query.
           47  +**
           48  +**     * Terminals from each of the expression trees that make up the 
           49  +**       select-list and ORDER BY expressions in the parent query are
           50  +**       selected by the sub-query. For the purposes of the transformation,
           51  +**       terminals are column references and aggregate functions.
           52  +**
           53  +**   If there is more than one window function in the SELECT that uses
           54  +**   the same window declaration (the OVER bit), then a single scan may
           55  +**   be used to process more than one window function. For example:
           56  +**
           57  +**     SELECT max(b) OVER (PARTITION BY c ORDER BY d), 
           58  +**            min(e) OVER (PARTITION BY c ORDER BY d) 
           59  +**     FROM t1;
           60  +**
           61  +**   is transformed in the same way as the example above. However:
           62  +**
           63  +**     SELECT max(b) OVER (PARTITION BY c ORDER BY d), 
           64  +**            min(e) OVER (PARTITION BY a ORDER BY b) 
           65  +**     FROM t1;
           66  +**
           67  +**   Must be transformed to:
           68  +**
           69  +**     SELECT max(b) OVER (PARTITION BY c ORDER BY d) FROM (
           70  +**         SELECT e, min(e) OVER (PARTITION BY a ORDER BY b), c, d, b FROM
           71  +**           SELECT a, e, c, d, b FROM t1 ORDER BY a, b
           72  +**         ) ORDER BY c, d
           73  +**     ) ORDER BY e;
           74  +**
           75  +**   so that both min() and max() may process rows in the order defined by
           76  +**   their respective window declarations.
           77  +**
           78  +** INTERFACE WITH SELECT.C
           79  +**
           80  +**   When processing the rewritten SELECT statement, code in select.c calls
           81  +**   sqlite3WhereBegin() to begin iterating through the results of the
           82  +**   sub-query, which is always implemented as a co-routine. It then calls
           83  +**   sqlite3WindowCodeStep() to process rows and finish the scan by calling
           84  +**   sqlite3WhereEnd().
           85  +**
           86  +**   sqlite3WindowCodeStep() generates VM code so that, for each row returned
           87  +**   by the sub-query a sub-routine (OP_Gosub) coded by select.c is invoked.
           88  +**   When the sub-routine is invoked:
           89  +**
           90  +**     * The results of all window-functions for the row are stored
           91  +**       in the associated Window.regResult registers.
           92  +**
           93  +**     * The required terminal values are stored in the current row of
           94  +**       temp table Window.iEphCsr.
           95  +**
           96  +**   In some cases, depending on the window frame and the specific window
           97  +**   functions invoked, sqlite3WindowCodeStep() caches each entire partition
           98  +**   in a temp table before returning any rows. In other cases it does not.
           99  +**   This detail is encapsulated within this file, the code generated by
          100  +**   select.c is the same in either case.
          101  +**
          102  +** BUILT-IN WINDOW FUNCTIONS
          103  +**
          104  +**   This implementation features the following built-in window functions:
          105  +**
          106  +**     row_number()
          107  +**     rank()
          108  +**     dense_rank()
          109  +**     percent_rank()
          110  +**     cume_dist()
          111  +**     ntile(N)
          112  +**     lead(expr [, offset [, default]])
          113  +**     lag(expr [, offset [, default]])
          114  +**     first_value(expr)
          115  +**     last_value(expr)
          116  +**     nth_value(expr, N)
          117  +**   
          118  +**   These are the same built-in window functions supported by Postgres. 
          119  +**   Although the behaviour of aggregate window functions (functions that
          120  +**   can be used as either aggregates or window funtions) allows them to
          121  +**   be implemented using an API, built-in window functions are much more
          122  +**   esoteric. Additionally, some window functions (e.g. nth_value()) 
          123  +**   may only be implemented by caching the entire partition in memory.
          124  +**   As such, some built-in window functions use the same API as aggregate
          125  +**   window functions and some are implemented directly using VDBE 
          126  +**   instructions. Additionally, for those functions that use the API, the
          127  +**   window frame is sometimes modified before the SELECT statement is
          128  +**   rewritten. For example, regardless of the specified window frame, the
          129  +**   row_number() function always uses:
          130  +**
          131  +**     ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
          132  +**
          133  +**   See sqlite3WindowUpdate() for details.
          134  +**
          135  +**   As well as some of the built-in window functions, aggregate window
          136  +**   functions min() and max() are implemented using VDBE instructions if
          137  +**   the start of the window frame is declared as anything other than 
          138  +**   UNBOUNDED PRECEDING.
          139  +*/
          140  +
          141  +/*
          142  +** Implementation of built-in window function row_number(). Assumes that the
          143  +** window frame has been coerced to:
          144  +**
          145  +**   ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
          146  +*/
          147  +static void row_numberStepFunc(
          148  +  sqlite3_context *pCtx, 
          149  +  int nArg,
          150  +  sqlite3_value **apArg
          151  +){
          152  +  i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          153  +  if( p ) (*p)++;
          154  +}
          155  +static void row_numberInvFunc(
          156  +  sqlite3_context *pCtx, 
          157  +  int nArg,
          158  +  sqlite3_value **apArg
          159  +){
          160  +}
          161  +static void row_numberValueFunc(sqlite3_context *pCtx){
          162  +  i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          163  +  sqlite3_result_int64(pCtx, (p ? *p : 0));
          164  +}
          165  +
          166  +/*
          167  +** Context object type used by rank(), dense_rank(), percent_rank() and
          168  +** cume_dist().
          169  +*/
          170  +struct CallCount {
          171  +  i64 nValue;
          172  +  i64 nStep;
          173  +  i64 nTotal;
          174  +};
          175  +
          176  +/*
          177  +** Implementation of built-in window function dense_rank(). Assumes that
          178  +** the window frame has been set to:
          179  +**
          180  +**   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
          181  +*/
          182  +static void dense_rankStepFunc(
          183  +  sqlite3_context *pCtx, 
          184  +  int nArg,
          185  +  sqlite3_value **apArg
          186  +){
          187  +  struct CallCount *p;
          188  +  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          189  +  if( p ) p->nStep = 1;
          190  +}
          191  +static void dense_rankInvFunc(
          192  +  sqlite3_context *pCtx, 
          193  +  int nArg,
          194  +  sqlite3_value **apArg
          195  +){
          196  +}
          197  +static void dense_rankValueFunc(sqlite3_context *pCtx){
          198  +  struct CallCount *p;
          199  +  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          200  +  if( p ){
          201  +    if( p->nStep ){
          202  +      p->nValue++;
          203  +      p->nStep = 0;
          204  +    }
          205  +    sqlite3_result_int64(pCtx, p->nValue);
          206  +  }
          207  +}
          208  +
          209  +/*
          210  +** Implementation of built-in window function rank(). Assumes that
          211  +** the window frame has been set to:
          212  +**
          213  +**   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
          214  +*/
          215  +static void rankStepFunc(
          216  +  sqlite3_context *pCtx, 
          217  +  int nArg,
          218  +  sqlite3_value **apArg
          219  +){
          220  +  struct CallCount *p;
          221  +  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          222  +  if( p ){
          223  +    p->nStep++;
          224  +    if( p->nValue==0 ){
          225  +      p->nValue = p->nStep;
          226  +    }
          227  +  }
          228  +}
          229  +static void rankInvFunc(
          230  +  sqlite3_context *pCtx, 
          231  +  int nArg,
          232  +  sqlite3_value **apArg
          233  +){
          234  +}
          235  +static void rankValueFunc(sqlite3_context *pCtx){
          236  +  struct CallCount *p;
          237  +  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          238  +  if( p ){
          239  +    sqlite3_result_int64(pCtx, p->nValue);
          240  +    p->nValue = 0;
          241  +  }
          242  +}
          243  +
          244  +/*
          245  +** Implementation of built-in window function percent_rank(). Assumes that
          246  +** the window frame has been set to:
          247  +**
          248  +**   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
          249  +*/
          250  +static void percent_rankStepFunc(
          251  +  sqlite3_context *pCtx, 
          252  +  int nArg,
          253  +  sqlite3_value **apArg
          254  +){
          255  +  struct CallCount *p;
          256  +  assert( nArg==1 );
          257  +
          258  +  assert( sqlite3VdbeAssertAggContext(pCtx) );
          259  +  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          260  +  if( ALWAYS(p) ){
          261  +    if( p->nTotal==0 ){
          262  +      p->nTotal = sqlite3_value_int64(apArg[0]);
          263  +    }
          264  +    p->nStep++;
          265  +    if( p->nValue==0 ){
          266  +      p->nValue = p->nStep;
          267  +    }
          268  +  }
          269  +}
          270  +static void percent_rankInvFunc(
          271  +  sqlite3_context *pCtx, 
          272  +  int nArg,
          273  +  sqlite3_value **apArg
          274  +){
          275  +}
          276  +static void percent_rankValueFunc(sqlite3_context *pCtx){
          277  +  struct CallCount *p;
          278  +  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          279  +  if( p ){
          280  +    if( p->nTotal>1 ){
          281  +      double r = (double)(p->nValue-1) / (double)(p->nTotal-1);
          282  +      sqlite3_result_double(pCtx, r);
          283  +    }else{
          284  +      sqlite3_result_double(pCtx, 0.0);
          285  +    }
          286  +    p->nValue = 0;
          287  +  }
          288  +}
          289  +
          290  +/*
          291  +** Implementation of built-in window function cume_dist(). Assumes that
          292  +** the window frame has been set to:
          293  +**
          294  +**   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
          295  +*/
          296  +static void cume_distStepFunc(
          297  +  sqlite3_context *pCtx, 
          298  +  int nArg,
          299  +  sqlite3_value **apArg
          300  +){
          301  +  struct CallCount *p;
          302  +  assert( nArg==1 );
          303  +
          304  +  assert( sqlite3VdbeAssertAggContext(pCtx) );
          305  +  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          306  +  if( ALWAYS(p) ){
          307  +    if( p->nTotal==0 ){
          308  +      p->nTotal = sqlite3_value_int64(apArg[0]);
          309  +    }
          310  +    p->nStep++;
          311  +  }
          312  +}
          313  +static void cume_distInvFunc(
          314  +  sqlite3_context *pCtx, 
          315  +  int nArg,
          316  +  sqlite3_value **apArg
          317  +){
          318  +}
          319  +static void cume_distValueFunc(sqlite3_context *pCtx){
          320  +  struct CallCount *p;
          321  +  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          322  +  if( p && p->nTotal ){
          323  +    double r = (double)(p->nStep) / (double)(p->nTotal);
          324  +    sqlite3_result_double(pCtx, r);
          325  +  }
          326  +}
          327  +
          328  +/*
          329  +** Context object for ntile() window function.
          330  +*/
          331  +struct NtileCtx {
          332  +  i64 nTotal;                     /* Total rows in partition */
          333  +  i64 nParam;                     /* Parameter passed to ntile(N) */
          334  +  i64 iRow;                       /* Current row */
          335  +};
          336  +
          337  +/*
          338  +** Implementation of ntile(). This assumes that the window frame has
          339  +** been coerced to:
          340  +**
          341  +**   ROWS UNBOUNDED PRECEDING AND CURRENT ROW
          342  +*/
          343  +static void ntileStepFunc(
          344  +  sqlite3_context *pCtx, 
          345  +  int nArg,
          346  +  sqlite3_value **apArg
          347  +){
          348  +  struct NtileCtx *p;
          349  +  assert( nArg==2 );
          350  +  p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          351  +  if( p ){
          352  +    if( p->nTotal==0 ){
          353  +      p->nParam = sqlite3_value_int64(apArg[0]);
          354  +      p->nTotal = sqlite3_value_int64(apArg[1]);
          355  +      if( p->nParam<=0 ){
          356  +        sqlite3_result_error(
          357  +            pCtx, "argument of ntile must be a positive integer", -1
          358  +        );
          359  +      }
          360  +    }
          361  +    p->iRow++;
          362  +  }
          363  +}
          364  +static void ntileInvFunc(
          365  +  sqlite3_context *pCtx, 
          366  +  int nArg,
          367  +  sqlite3_value **apArg
          368  +){
          369  +}
          370  +static void ntileValueFunc(sqlite3_context *pCtx){
          371  +  struct NtileCtx *p;
          372  +  p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          373  +  if( p && p->nParam>0 ){
          374  +    int nSize = (p->nTotal / p->nParam);
          375  +    if( nSize==0 ){
          376  +      sqlite3_result_int64(pCtx, p->iRow);
          377  +    }else{
          378  +      i64 nLarge = p->nTotal - p->nParam*nSize;
          379  +      i64 iSmall = nLarge*(nSize+1);
          380  +      i64 iRow = p->iRow-1;
          381  +
          382  +      assert( (nLarge*(nSize+1) + (p->nParam-nLarge)*nSize)==p->nTotal );
          383  +
          384  +      if( iRow<iSmall ){
          385  +        sqlite3_result_int64(pCtx, 1 + iRow/(nSize+1));
          386  +      }else{
          387  +        sqlite3_result_int64(pCtx, 1 + nLarge + (iRow-iSmall)/nSize);
          388  +      }
          389  +    }
          390  +  }
          391  +}
          392  +
          393  +/*
          394  +** Context object for last_value() window function.
          395  +*/
          396  +struct LastValueCtx {
          397  +  sqlite3_value *pVal;
          398  +  int nVal;
          399  +};
          400  +
          401  +/*
          402  +** Implementation of last_value().
          403  +*/
          404  +static void last_valueStepFunc(
          405  +  sqlite3_context *pCtx, 
          406  +  int nArg,
          407  +  sqlite3_value **apArg
          408  +){
          409  +  struct LastValueCtx *p;
          410  +  p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          411  +  if( p ){
          412  +    sqlite3_value_free(p->pVal);
          413  +    p->pVal = sqlite3_value_dup(apArg[0]);
          414  +    if( p->pVal==0 ){
          415  +      sqlite3_result_error_nomem(pCtx);
          416  +    }else{
          417  +      p->nVal++;
          418  +    }
          419  +  }
          420  +}
          421  +static void last_valueInvFunc(
          422  +  sqlite3_context *pCtx, 
          423  +  int nArg,
          424  +  sqlite3_value **apArg
          425  +){
          426  +  struct LastValueCtx *p;
          427  +  p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          428  +  if( ALWAYS(p) ){
          429  +    p->nVal--;
          430  +    if( p->nVal==0 ){
          431  +      sqlite3_value_free(p->pVal);
          432  +      p->pVal = 0;
          433  +    }
          434  +  }
          435  +}
          436  +static void last_valueValueFunc(sqlite3_context *pCtx){
          437  +  struct LastValueCtx *p;
          438  +  p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          439  +  if( p && p->pVal ){
          440  +    sqlite3_result_value(pCtx, p->pVal);
          441  +  }
          442  +}
          443  +static void last_valueFinalizeFunc(sqlite3_context *pCtx){
          444  +  struct LastValueCtx *p;
          445  +  p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          446  +  if( p && p->pVal ){
          447  +    sqlite3_result_value(pCtx, p->pVal);
          448  +    sqlite3_value_free(p->pVal);
          449  +    p->pVal = 0;
          450  +  }
          451  +}
          452  +
          453  +/*
          454  +** No-op implementations of nth_value(), first_value(), lead() and lag().
          455  +** These are all implemented inline using VDBE instructions. 
          456  +*/
          457  +static void nth_valueStepFunc(sqlite3_context *pCtx, int n, sqlite3_value **a){}
          458  +static void nth_valueInvFunc(sqlite3_context *pCtx, int n, sqlite3_value **ap){}
          459  +static void nth_valueValueFunc(sqlite3_context *pCtx){}
          460  +static void first_valueStepFunc(sqlite3_context *p, int n, sqlite3_value **ap){}
          461  +static void first_valueInvFunc(sqlite3_context *p, int n, sqlite3_value **ap){}
          462  +static void first_valueValueFunc(sqlite3_context *pCtx){}
          463  +static void leadStepFunc(sqlite3_context *pCtx, int n, sqlite3_value **ap){}
          464  +static void leadInvFunc(sqlite3_context *pCtx, int n, sqlite3_value **ap){}
          465  +static void leadValueFunc(sqlite3_context *pCtx){}
          466  +static void lagStepFunc(sqlite3_context *pCtx, int n, sqlite3_value **ap){}
          467  +static void lagInvFunc(sqlite3_context *pCtx, int n, sqlite3_value **ap){}
          468  +static void lagValueFunc(sqlite3_context *pCtx){}
          469  +
          470  +#define WINDOWFUNC(name,nArg,extra) {                                      \
          471  +  nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0,                      \
          472  +  name ## StepFunc, name ## ValueFunc, name ## ValueFunc,                  \
          473  +  name ## InvFunc, #name                                               \
          474  +}
          475  +
          476  +#define WINDOWFUNCF(name,nArg,extra) {                                     \
          477  +  nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0,                      \
          478  +  name ## StepFunc, name ## FinalizeFunc, name ## ValueFunc,               \
          479  +  name ## InvFunc, #name                                               \
          480  +}
          481  +
          482  +/*
          483  +** Register those built-in window functions that are not also aggregates.
          484  +*/
          485  +void sqlite3WindowFunctions(void){
          486  +  static FuncDef aWindowFuncs[] = {
          487  +    WINDOWFUNC(row_number, 0, 0),
          488  +    WINDOWFUNC(dense_rank, 0, 0),
          489  +    WINDOWFUNC(rank, 0, 0),
          490  +    WINDOWFUNC(percent_rank, 0, SQLITE_FUNC_WINDOW_SIZE),
          491  +    WINDOWFUNC(cume_dist, 0, SQLITE_FUNC_WINDOW_SIZE),
          492  +    WINDOWFUNC(ntile, 1, SQLITE_FUNC_WINDOW_SIZE),
          493  +    WINDOWFUNCF(last_value, 1, 0),
          494  +    WINDOWFUNC(nth_value, 2, 0),
          495  +    WINDOWFUNC(first_value, 1, 0),
          496  +    WINDOWFUNC(lead, 1, 0), WINDOWFUNC(lead, 2, 0), WINDOWFUNC(lead, 3, 0),
          497  +    WINDOWFUNC(lag, 1, 0),  WINDOWFUNC(lag, 2, 0),  WINDOWFUNC(lag, 3, 0),
          498  +  };
          499  +  sqlite3InsertBuiltinFuncs(aWindowFuncs, ArraySize(aWindowFuncs));
          500  +}
          501  +
          502  +/*
          503  +** This function is called immediately after resolving the function name
          504  +** for a window function within a SELECT statement. Argument pList is a
          505  +** linked list of WINDOW definitions for the current SELECT statement.
          506  +** Argument pFunc is the function definition just resolved and pWin
          507  +** is the Window object representing the associated OVER clause. This
          508  +** function updates the contents of pWin as follows:
          509  +**
          510  +**   * If the OVER clause refered to a named window (as in "max(x) OVER win"),
          511  +**     search list pList for a matching WINDOW definition, and update pWin
          512  +**     accordingly. If no such WINDOW clause can be found, leave an error
          513  +**     in pParse.
          514  +**
          515  +**   * If the function is a built-in window function that requires the
          516  +**     window to be coerced (see "BUILT-IN WINDOW FUNCTIONS" at the top
          517  +**     of this file), pWin is updated here.
          518  +*/
          519  +void sqlite3WindowUpdate(
          520  +  Parse *pParse, 
          521  +  Window *pList,                  /* List of named windows for this SELECT */
          522  +  Window *pWin,                   /* Window frame to update */
          523  +  FuncDef *pFunc                  /* Window function definition */
          524  +){
          525  +  if( pWin->zName && pWin->eType==0 ){
          526  +    Window *p;
          527  +    for(p=pList; p; p=p->pNextWin){
          528  +      if( sqlite3StrICmp(p->zName, pWin->zName)==0 ) break;
          529  +    }
          530  +    if( p==0 ){
          531  +      sqlite3ErrorMsg(pParse, "no such window: %s", pWin->zName);
          532  +      return;
          533  +    }
          534  +    pWin->pPartition = sqlite3ExprListDup(pParse->db, p->pPartition, 0);
          535  +    pWin->pOrderBy = sqlite3ExprListDup(pParse->db, p->pOrderBy, 0);
          536  +    pWin->pStart = sqlite3ExprDup(pParse->db, p->pStart, 0);
          537  +    pWin->pEnd = sqlite3ExprDup(pParse->db, p->pEnd, 0);
          538  +    pWin->eStart = p->eStart;
          539  +    pWin->eEnd = p->eEnd;
          540  +    pWin->eType = p->eType;
          541  +  }
          542  +  if( pFunc->funcFlags & SQLITE_FUNC_WINDOW ){
          543  +    sqlite3 *db = pParse->db;
          544  +    if( pWin->pFilter ){
          545  +      sqlite3ErrorMsg(pParse, 
          546  +          "FILTER clause may only be used with aggregate window functions"
          547  +      );
          548  +    }else
          549  +    if( pFunc->xSFunc==row_numberStepFunc || pFunc->xSFunc==ntileStepFunc ){
          550  +      sqlite3ExprDelete(db, pWin->pStart);
          551  +      sqlite3ExprDelete(db, pWin->pEnd);
          552  +      pWin->pStart = pWin->pEnd = 0;
          553  +      pWin->eType = TK_ROWS;
          554  +      pWin->eStart = TK_UNBOUNDED;
          555  +      pWin->eEnd = TK_CURRENT;
          556  +    }else
          557  +
          558  +    if( pFunc->xSFunc==dense_rankStepFunc || pFunc->xSFunc==rankStepFunc
          559  +     || pFunc->xSFunc==percent_rankStepFunc || pFunc->xSFunc==cume_distStepFunc
          560  +    ){
          561  +      sqlite3ExprDelete(db, pWin->pStart);
          562  +      sqlite3ExprDelete(db, pWin->pEnd);
          563  +      pWin->pStart = pWin->pEnd = 0;
          564  +      pWin->eType = TK_RANGE;
          565  +      pWin->eStart = TK_UNBOUNDED;
          566  +      pWin->eEnd = TK_CURRENT;
          567  +    }
          568  +  }
          569  +  pWin->pFunc = pFunc;
          570  +}
          571  +
          572  +/*
          573  +** Context object passed through sqlite3WalkExprList() to
          574  +** selectWindowRewriteExprCb() by selectWindowRewriteEList().
          575  +*/
          576  +typedef struct WindowRewrite WindowRewrite;
          577  +struct WindowRewrite {
          578  +  Window *pWin;
          579  +  ExprList *pSub;
          580  +};
          581  +
          582  +/*
          583  +** Callback function used by selectWindowRewriteEList(). If necessary,
          584  +** this function appends to the output expression-list and updates 
          585  +** expression (*ppExpr) in place.
          586  +*/
          587  +static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
          588  +  struct WindowRewrite *p = pWalker->u.pRewrite;
          589  +  Parse *pParse = pWalker->pParse;
          590  +
          591  +  switch( pExpr->op ){
          592  +
          593  +    case TK_FUNCTION:
          594  +      if( pExpr->pWin==0 ){
          595  +        break;
          596  +      }else{
          597  +        Window *pWin;
          598  +        for(pWin=p->pWin; pWin; pWin=pWin->pNextWin){
          599  +          if( pExpr->pWin==pWin ){
          600  +            assert( pWin->pOwner==pExpr );
          601  +            return WRC_Prune;
          602  +          }
          603  +        }
          604  +      }
          605  +      /* Fall through.  */
          606  +
          607  +    case TK_AGG_FUNCTION:
          608  +    case TK_COLUMN: {
          609  +      Expr *pDup = sqlite3ExprDup(pParse->db, pExpr, 0);
          610  +      p->pSub = sqlite3ExprListAppend(pParse, p->pSub, pDup);
          611  +      if( p->pSub ){
          612  +        assert( ExprHasProperty(pExpr, EP_Static)==0 );
          613  +        ExprSetProperty(pExpr, EP_Static);
          614  +        sqlite3ExprDelete(pParse->db, pExpr);
          615  +        ExprClearProperty(pExpr, EP_Static);
          616  +        memset(pExpr, 0, sizeof(Expr));
          617  +
          618  +        pExpr->op = TK_COLUMN;
          619  +        pExpr->iColumn = p->pSub->nExpr-1;
          620  +        pExpr->iTable = p->pWin->iEphCsr;
          621  +      }
          622  +
          623  +      break;
          624  +    }
          625  +
          626  +    default: /* no-op */
          627  +      break;
          628  +  }
          629  +
          630  +  return WRC_Continue;
          631  +}
          632  +static int selectWindowRewriteSelectCb(Walker *pWalker, Select *pSelect){
          633  +  return WRC_Prune;
          634  +}
          635  +
          636  +
          637  +/*
          638  +** Iterate through each expression in expression-list pEList. For each:
          639  +**
          640  +**   * TK_COLUMN,
          641  +**   * aggregate function, or
          642  +**   * window function with a Window object that is not a member of the 
          643  +**     linked list passed as the second argument (pWin)
          644  +**
          645  +** Append the node to output expression-list (*ppSub). And replace it
          646  +** with a TK_COLUMN that reads the (N-1)th element of table 
          647  +** pWin->iEphCsr, where N is the number of elements in (*ppSub) after
          648  +** appending the new one.
          649  +*/
          650  +static void selectWindowRewriteEList(
          651  +  Parse *pParse, 
          652  +  Window *pWin,
          653  +  ExprList *pEList,               /* Rewrite expressions in this list */
          654  +  ExprList **ppSub                /* IN/OUT: Sub-select expression-list */
          655  +){
          656  +  Walker sWalker;
          657  +  WindowRewrite sRewrite;
          658  +
          659  +  memset(&sWalker, 0, sizeof(Walker));
          660  +  memset(&sRewrite, 0, sizeof(WindowRewrite));
          661  +
          662  +  sRewrite.pSub = *ppSub;
          663  +  sRewrite.pWin = pWin;
          664  +
          665  +  sWalker.pParse = pParse;
          666  +  sWalker.xExprCallback = selectWindowRewriteExprCb;
          667  +  sWalker.xSelectCallback = selectWindowRewriteSelectCb;
          668  +  sWalker.u.pRewrite = &sRewrite;
          669  +
          670  +  (void)sqlite3WalkExprList(&sWalker, pEList);
          671  +
          672  +  *ppSub = sRewrite.pSub;
          673  +}
          674  +
          675  +/*
          676  +** Append a copy of each expression in expression-list pAppend to
          677  +** expression list pList. Return a pointer to the result list.
          678  +*/
          679  +static ExprList *exprListAppendList(
          680  +  Parse *pParse,          /* Parsing context */
          681  +  ExprList *pList,        /* List to which to append. Might be NULL */
          682  +  ExprList *pAppend       /* List of values to append. Might be NULL */
          683  +){
          684  +  if( pAppend ){
          685  +    int i;
          686  +    int nInit = pList ? pList->nExpr : 0;
          687  +    for(i=0; i<pAppend->nExpr; i++){
          688  +      Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0);
          689  +      pList = sqlite3ExprListAppend(pParse, pList, pDup);
          690  +      if( pList ) pList->a[nInit+i].sortOrder = pAppend->a[i].sortOrder;
          691  +    }
          692  +  }
          693  +  return pList;
          694  +}
          695  +
          696  +/*
          697  +** If the SELECT statement passed as the second argument does not invoke
          698  +** any SQL window functions, this function is a no-op. Otherwise, it 
          699  +** rewrites the SELECT statement so that window function xStep functions
          700  +** are invoked in the correct order as described under "SELECT REWRITING"
          701  +** at the top of this file.
          702  +*/
          703  +int sqlite3WindowRewrite(Parse *pParse, Select *p){
          704  +  int rc = SQLITE_OK;
          705  +  if( p->pWin ){
          706  +    Vdbe *v = sqlite3GetVdbe(pParse);
          707  +    sqlite3 *db = pParse->db;
          708  +    Select *pSub = 0;             /* The subquery */
          709  +    SrcList *pSrc = p->pSrc;
          710  +    Expr *pWhere = p->pWhere;
          711  +    ExprList *pGroupBy = p->pGroupBy;
          712  +    Expr *pHaving = p->pHaving;
          713  +    ExprList *pSort = 0;
          714  +
          715  +    ExprList *pSublist = 0;       /* Expression list for sub-query */
          716  +    Window *pMWin = p->pWin;      /* Master window object */
          717  +    Window *pWin;                 /* Window object iterator */
          718  +
          719  +    p->pSrc = 0;
          720  +    p->pWhere = 0;
          721  +    p->pGroupBy = 0;
          722  +    p->pHaving = 0;
          723  +
          724  +    /* Create the ORDER BY clause for the sub-select. This is the concatenation
          725  +    ** of the window PARTITION and ORDER BY clauses. Then, if this makes it
          726  +    ** redundant, remove the ORDER BY from the parent SELECT.  */
          727  +    pSort = sqlite3ExprListDup(db, pMWin->pPartition, 0);
          728  +    pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy);
          729  +    if( pSort && p->pOrderBy ){
          730  +      if( sqlite3ExprListCompare(pSort, p->pOrderBy, -1)==0 ){
          731  +        sqlite3ExprListDelete(db, p->pOrderBy);
          732  +        p->pOrderBy = 0;
          733  +      }
          734  +    }
          735  +
          736  +    /* Assign a cursor number for the ephemeral table used to buffer rows.
          737  +    ** The OpenEphemeral instruction is coded later, after it is known how
          738  +    ** many columns the table will have.  */
          739  +    pMWin->iEphCsr = pParse->nTab++;
          740  +
          741  +    selectWindowRewriteEList(pParse, pMWin, p->pEList, &pSublist);
          742  +    selectWindowRewriteEList(pParse, pMWin, p->pOrderBy, &pSublist);
          743  +    pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0);
          744  +
          745  +    /* Append the PARTITION BY and ORDER BY expressions to the to the 
          746  +    ** sub-select expression list. They are required to figure out where 
          747  +    ** boundaries for partitions and sets of peer rows lie.  */
          748  +    pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition);
          749  +    pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy);
          750  +
          751  +    /* Append the arguments passed to each window function to the
          752  +    ** sub-select expression list. Also allocate two registers for each
          753  +    ** window function - one for the accumulator, another for interim
          754  +    ** results.  */
          755  +    for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
          756  +      pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
          757  +      pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList);
          758  +      if( pWin->pFilter ){
          759  +        Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0);
          760  +        pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter);
          761  +      }
          762  +      pWin->regAccum = ++pParse->nMem;
          763  +      pWin->regResult = ++pParse->nMem;
          764  +      sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
          765  +    }
          766  +
          767  +    /* If there is no ORDER BY or PARTITION BY clause, and the window
          768  +    ** function accepts zero arguments, and there are no other columns
          769  +    ** selected (e.g. "SELECT row_number() OVER () FROM t1"), it is possible
          770  +    ** that pSublist is still NULL here. Add a constant expression here to 
          771  +    ** keep everything legal in this case. 
          772  +    */
          773  +    if( pSublist==0 ){
          774  +      pSublist = sqlite3ExprListAppend(pParse, 0, 
          775  +          sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0)
          776  +      );
          777  +    }
          778  +
          779  +    pSub = sqlite3SelectNew(
          780  +        pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0
          781  +    );
          782  +    p->pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
          783  +    assert( p->pSrc || db->mallocFailed );
          784  +    if( p->pSrc ){
          785  +      p->pSrc->a[0].pSelect = pSub;
          786  +      sqlite3SrcListAssignCursors(pParse, p->pSrc);
          787  +      if( sqlite3ExpandSubquery(pParse, &p->pSrc->a[0]) ){
          788  +        rc = SQLITE_NOMEM;
          789  +      }else{
          790  +        pSub->selFlags |= SF_Expanded;
          791  +        p->selFlags &= ~SF_Aggregate;
          792  +        sqlite3SelectPrep(pParse, pSub, 0);
          793  +      }
          794  +
          795  +      sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, pSublist->nExpr);
          796  +    }else{
          797  +      sqlite3SelectDelete(db, pSub);
          798  +    }
          799  +    if( db->mallocFailed ) rc = SQLITE_NOMEM;
          800  +  }
          801  +
          802  +  return rc;
          803  +}
          804  +
          805  +/*
          806  +** Free the Window object passed as the second argument.
          807  +*/
          808  +void sqlite3WindowDelete(sqlite3 *db, Window *p){
          809  +  if( p ){
          810  +    sqlite3ExprDelete(db, p->pFilter);
          811  +    sqlite3ExprListDelete(db, p->pPartition);
          812  +    sqlite3ExprListDelete(db, p->pOrderBy);
          813  +    sqlite3ExprDelete(db, p->pEnd);
          814  +    sqlite3ExprDelete(db, p->pStart);
          815  +    sqlite3DbFree(db, p->zName);
          816  +    sqlite3DbFree(db, p);
          817  +  }
          818  +}
          819  +
          820  +/*
          821  +** Free the linked list of Window objects starting at the second argument.
          822  +*/
          823  +void sqlite3WindowListDelete(sqlite3 *db, Window *p){
          824  +  while( p ){
          825  +    Window *pNext = p->pNextWin;
          826  +    sqlite3WindowDelete(db, p);
          827  +    p = pNext;
          828  +  }
          829  +}
          830  +
          831  +/*
          832  +** Allocate and return a new Window object.
          833  +*/
          834  +Window *sqlite3WindowAlloc(
          835  +  Parse *pParse, 
          836  +  int eType,
          837  +  int eStart, Expr *pStart,
          838  +  int eEnd, Expr *pEnd
          839  +){
          840  +  Window *pWin = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
          841  +
          842  +  if( pWin ){
          843  +    assert( eType );
          844  +    pWin->eType = eType;
          845  +    pWin->eStart = eStart;
          846  +    pWin->eEnd = eEnd;
          847  +    pWin->pEnd = pEnd;
          848  +    pWin->pStart = pStart;
          849  +  }else{
          850  +    sqlite3ExprDelete(pParse->db, pEnd);
          851  +    sqlite3ExprDelete(pParse->db, pStart);
          852  +  }
          853  +
          854  +  return pWin;
          855  +}
          856  +
          857  +/*
          858  +** Attach window object pWin to expression p.
          859  +*/
          860  +void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
          861  +  if( p ){
          862  +    p->pWin = pWin;
          863  +    if( pWin ) pWin->pOwner = p;
          864  +  }else{
          865  +    sqlite3WindowDelete(pParse->db, pWin);
          866  +  }
          867  +}
          868  +
          869  +/*
          870  +** Return 0 if the two window objects are identical, or non-zero otherwise.
          871  +** Identical window objects can be processed in a single scan.
          872  +*/
          873  +int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2){
          874  +  if( p1->eType!=p2->eType ) return 1;
          875  +  if( p1->eStart!=p2->eStart ) return 1;
          876  +  if( p1->eEnd!=p2->eEnd ) return 1;
          877  +  if( sqlite3ExprCompare(pParse, p1->pStart, p2->pStart, -1) ) return 1;
          878  +  if( sqlite3ExprCompare(pParse, p1->pEnd, p2->pEnd, -1) ) return 1;
          879  +  if( sqlite3ExprListCompare(p1->pPartition, p2->pPartition, -1) ) return 1;
          880  +  if( sqlite3ExprListCompare(p1->pOrderBy, p2->pOrderBy, -1) ) return 1;
          881  +  return 0;
          882  +}
          883  +
          884  +
          885  +/*
          886  +** This is called by code in select.c before it calls sqlite3WhereBegin()
          887  +** to begin iterating through the sub-query results. It is used to allocate
          888  +** and initialize registers and cursors used by sqlite3WindowCodeStep().
          889  +*/
          890  +void sqlite3WindowCodeInit(Parse *pParse, Window *pMWin){
          891  +  Window *pWin;
          892  +  Vdbe *v = sqlite3GetVdbe(pParse);
          893  +  int nPart = (pMWin->pPartition ? pMWin->pPartition->nExpr : 0);
          894  +  nPart += (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);
          895  +  if( nPart ){
          896  +    pMWin->regPart = pParse->nMem+1;
          897  +    pParse->nMem += nPart;
          898  +    sqlite3VdbeAddOp3(v, OP_Null, 0, pMWin->regPart, pMWin->regPart+nPart-1);
          899  +  }
          900  +
          901  +  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
          902  +    FuncDef *p = pWin->pFunc;
          903  +    if( (p->funcFlags & SQLITE_FUNC_MINMAX) && pWin->eStart!=TK_UNBOUNDED ){
          904  +      /* The inline versions of min() and max() require a single ephemeral
          905  +      ** table and 3 registers. The registers are used as follows:
          906  +      **
          907  +      **   regApp+0: slot to copy min()/max() argument to for MakeRecord
          908  +      **   regApp+1: integer value used to ensure keys are unique
          909  +      **   regApp+2: output of MakeRecord
          910  +      */
          911  +      ExprList *pList = pWin->pOwner->x.pList;
          912  +      KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0);
          913  +      pWin->csrApp = pParse->nTab++;
          914  +      pWin->regApp = pParse->nMem+1;
          915  +      pParse->nMem += 3;
          916  +      if( pKeyInfo && pWin->pFunc->zName[1]=='i' ){
          917  +        assert( pKeyInfo->aSortOrder[0]==0 );
          918  +        pKeyInfo->aSortOrder[0] = 1;
          919  +      }
          920  +      sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2);
          921  +      sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);
          922  +      sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
          923  +    }
          924  +    else if( p->xSFunc==nth_valueStepFunc || p->xSFunc==first_valueStepFunc ){
          925  +      /* Allocate two registers at pWin->regApp. These will be used to
          926  +      ** store the start and end index of the current frame.  */
          927  +      assert( pMWin->iEphCsr );
          928  +      pWin->regApp = pParse->nMem+1;
          929  +      pWin->csrApp = pParse->nTab++;
          930  +      pParse->nMem += 2;
          931  +      sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);
          932  +    }
          933  +    else if( p->xSFunc==leadStepFunc || p->xSFunc==lagStepFunc ){
          934  +      assert( pMWin->iEphCsr );
          935  +      pWin->csrApp = pParse->nTab++;
          936  +      sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);
          937  +    }
          938  +  }
          939  +}
          940  +
          941  +/*
          942  +** A "PRECEDING <expr>" (bEnd==0) or "FOLLOWING <expr>" (bEnd==1) has just 
          943  +** been evaluated and the result left in register reg. This function generates
          944  +** VM code to check that the value is a non-negative integer and throws
          945  +** an exception if it is not.
          946  +*/
          947  +static void windowCheckFrameValue(Parse *pParse, int reg, int bEnd){
          948  +  static const char *azErr[] = {
          949  +    "frame starting offset must be a non-negative integer",
          950  +    "frame ending offset must be a non-negative integer"
          951  +  };
          952  +  Vdbe *v = sqlite3GetVdbe(pParse);
          953  +  int regZero = sqlite3GetTempReg(pParse);
          954  +  sqlite3VdbeAddOp2(v, OP_Integer, 0, regZero);
          955  +  sqlite3VdbeAddOp2(v, OP_MustBeInt, reg, sqlite3VdbeCurrentAddr(v)+2);
          956  +  sqlite3VdbeAddOp3(v, OP_Ge, regZero, sqlite3VdbeCurrentAddr(v)+2, reg);
          957  +  VdbeCoverage(v);
          958  +  sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_ERROR, OE_Abort);
          959  +  sqlite3VdbeAppendP4(v, (void*)azErr[bEnd], P4_STATIC);
          960  +  sqlite3ReleaseTempReg(pParse, regZero);
          961  +}
          962  +
          963  +/*
          964  +** Return the number of arguments passed to the window-function associated
          965  +** with the object passed as the only argument to this function.
          966  +*/
          967  +static int windowArgCount(Window *pWin){
          968  +  ExprList *pList = pWin->pOwner->x.pList;
          969  +  return (pList ? pList->nExpr : 0);
          970  +}
          971  +
          972  +/*
          973  +** Generate VM code to invoke either xStep() (if bInverse is 0) or 
          974  +** xInverse (if bInverse is non-zero) for each window function in the 
          975  +** linked list starting at pMWin. Or, for built-in window functions
          976  +** that do not use the standard function API, generate the required
          977  +** inline VM code.
          978  +**
          979  +** If argument csr is greater than or equal to 0, then argument reg is
          980  +** the first register in an array of registers guaranteed to be large
          981  +** enough to hold the array of arguments for each function. In this case
          982  +** the arguments are extracted from the current row of csr into the
          983  +** array of registers before invoking OP_AggStep.
          984  +**
          985  +** Or, if csr is less than zero, then the array of registers at reg is
          986  +** already populated with all columns from the current row of the sub-query.
          987  +**
          988  +** If argument regPartSize is non-zero, then it is a register containing the
          989  +** number of rows in the current partition.
          990  +*/
          991  +static void windowAggStep(
          992  +  Parse *pParse, 
          993  +  Window *pMWin,                  /* Linked list of window functions */
          994  +  int csr,                        /* Read arguments from this cursor */
          995  +  int bInverse,                   /* True to invoke xInverse instead of xStep */
          996  +  int reg,                        /* Array of registers */
          997  +  int regPartSize                 /* Register containing size of partition */
          998  +){
          999  +  Vdbe *v = sqlite3GetVdbe(pParse);
         1000  +  Window *pWin;
         1001  +  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
         1002  +    int flags = pWin->pFunc->funcFlags;
         1003  +    int regArg;
         1004  +    int nArg = windowArgCount(pWin);
         1005  +
         1006  +    if( csr>=0 ){
         1007  +      int i;
         1008  +      for(i=0; i<nArg; i++){
         1009  +        sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i);
         1010  +      }
         1011  +      regArg = reg;
         1012  +      if( flags & SQLITE_FUNC_WINDOW_SIZE ){
         1013  +        if( nArg==0 ){
         1014  +          regArg = regPartSize;
         1015  +        }else{
         1016  +          sqlite3VdbeAddOp2(v, OP_SCopy, regPartSize, reg+nArg);
         1017  +        }
         1018  +        nArg++;
         1019  +      }
         1020  +    }else{
         1021  +      assert( !(flags & SQLITE_FUNC_WINDOW_SIZE) );
         1022  +      regArg = reg + pWin->iArgCol;
         1023  +    }
         1024  +
         1025  +    if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX) 
         1026  +      && pWin->eStart!=TK_UNBOUNDED 
         1027  +    ){
         1028  +      if( bInverse==0 ){
         1029  +        sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1, 1);
         1030  +        sqlite3VdbeAddOp2(v, OP_SCopy, regArg, pWin->regApp);
         1031  +        sqlite3VdbeAddOp3(v, OP_MakeRecord, pWin->regApp, 2, pWin->regApp+2);
         1032  +        sqlite3VdbeAddOp2(v, OP_IdxInsert, pWin->csrApp, pWin->regApp+2);
         1033  +      }else{
         1034  +        sqlite3VdbeAddOp4Int(v, OP_SeekGE, pWin->csrApp, 0, regArg, 1);
         1035  +        VdbeCoverage(v);
         1036  +        sqlite3VdbeAddOp1(v, OP_Delete, pWin->csrApp);
         1037  +        sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
         1038  +      }
         1039  +    }else if( pWin->regApp ){
         1040  +      assert( pWin->pFunc->xSFunc==nth_valueStepFunc 
         1041  +           || pWin->pFunc->xSFunc==first_valueStepFunc 
         1042  +      );
         1043  +      assert( bInverse==0 || bInverse==1 );
         1044  +      sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1);
         1045  +    }else if( pWin->pFunc->xSFunc==leadStepFunc 
         1046  +           || pWin->pFunc->xSFunc==lagStepFunc 
         1047  +    ){
         1048  +      /* no-op */
         1049  +    }else{
         1050  +      int addrIf = 0;
         1051  +      if( pWin->pFilter ){
         1052  +        int regTmp;
         1053  +        assert( nArg==pWin->pOwner->x.pList->nExpr );
         1054  +        if( csr>0 ){
         1055  +          regTmp = sqlite3GetTempReg(pParse);
         1056  +          sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
         1057  +        }else{
         1058  +          regTmp = regArg + nArg;
         1059  +        }
         1060  +        addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
         1061  +        VdbeCoverage(v);
         1062  +        if( csr>0 ){
         1063  +          sqlite3ReleaseTempReg(pParse, regTmp);
         1064  +        }
         1065  +      }
         1066  +      if( pWin->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
         1067  +        CollSeq *pColl;
         1068  +        pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr);
         1069  +        sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ);
         1070  +      }
         1071  +      sqlite3VdbeAddOp3(v, OP_AggStep0, bInverse, regArg, pWin->regAccum);
         1072  +      sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
         1073  +      sqlite3VdbeChangeP5(v, (u8)nArg);
         1074  +      if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
         1075  +    }
         1076  +  }
         1077  +}
         1078  +
         1079  +/*
         1080  +** Generate VM code to invoke either xValue() (bFinal==0) or xFinalize()
         1081  +** (bFinal==1) for each window function in the linked list starting at
         1082  +** pMWin. Or, for built-in window-functions that do not use the standard
         1083  +** API, generate the equivalent VM code.
         1084  +*/
         1085  +static void windowAggFinal(Parse *pParse, Window *pMWin, int bFinal){
         1086  +  Vdbe *v = sqlite3GetVdbe(pParse);
         1087  +  Window *pWin;
         1088  +
         1089  +  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
         1090  +    if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX) 
         1091  +     && pWin->eStart!=TK_UNBOUNDED 
         1092  +    ){
         1093  +      sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
         1094  +      sqlite3VdbeAddOp1(v, OP_Last, pWin->csrApp);
         1095  +      VdbeCoverage(v);
         1096  +      sqlite3VdbeAddOp3(v, OP_Column, pWin->csrApp, 0, pWin->regResult);
         1097  +      sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
         1098  +      if( bFinal ){
         1099  +        sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp);
         1100  +      }
         1101  +    }else if( pWin->regApp ){
         1102  +    }else{
         1103  +      if( bFinal==0 ){
         1104  +        sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
         1105  +      }
         1106  +      sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, windowArgCount(pWin));
         1107  +      sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
         1108  +      if( bFinal ){
         1109  +        sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult);
         1110  +        sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
         1111  +      }else{
         1112  +        sqlite3VdbeChangeP3(v, -1, pWin->regResult);
         1113  +      }
         1114  +    }
         1115  +  }
         1116  +}
         1117  +
         1118  +/*
         1119  +** This function generates VM code to invoke the sub-routine at address
         1120  +** lblFlushPart once for each partition with the entire partition cached in
         1121  +** the Window.iEphCsr temp table.
         1122  +*/
         1123  +static void windowPartitionCache(
         1124  +  Parse *pParse,
         1125  +  Select *p,                      /* The rewritten SELECT statement */
         1126  +  WhereInfo *pWInfo,              /* WhereInfo to call WhereEnd() on */
         1127  +  int regFlushPart,               /* Register to use with Gosub lblFlushPart */
         1128  +  int lblFlushPart,               /* Subroutine to Gosub to */
         1129  +  int *pRegSize                   /* OUT: Register containing partition size */
         1130  +){
         1131  +  Window *pMWin = p->pWin;
         1132  +  Vdbe *v = sqlite3GetVdbe(pParse);
         1133  +  int iSubCsr = p->pSrc->a[0].iCursor;
         1134  +  int nSub = p->pSrc->a[0].pTab->nCol;
         1135  +  int k;
         1136  +
         1137  +  int reg = pParse->nMem+1;
         1138  +  int regRecord = reg+nSub;
         1139  +  int regRowid = regRecord+1;
         1140  +
         1141  +  *pRegSize = regRowid;
         1142  +  pParse->nMem += nSub + 2;
         1143  +
         1144  +  /* Martial the row returned by the sub-select into an array of 
         1145  +  ** registers. */
         1146  +  for(k=0; k<nSub; k++){
         1147  +    sqlite3VdbeAddOp3(v, OP_Column, iSubCsr, k, reg+k);
         1148  +  }
         1149  +  sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, nSub, regRecord);
         1150  +
         1151  +  /* Check if this is the start of a new partition. If so, call the
         1152  +  ** flush_partition sub-routine.  */
         1153  +  if( pMWin->pPartition ){
         1154  +    int addr;
         1155  +    ExprList *pPart = pMWin->pPartition;
         1156  +    int nPart = pPart->nExpr;
         1157  +    int regNewPart = reg + pMWin->nBufferCol;
         1158  +    KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
         1159  +
         1160  +    addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart,nPart);
         1161  +    sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
         1162  +    sqlite3VdbeAddOp3(v, OP_Jump, addr+2, addr+4, addr+2);
         1163  +    VdbeCoverage(v);
         1164  +    sqlite3VdbeAddOp3(v, OP_Copy, regNewPart, pMWin->regPart, nPart-1);
         1165  +    sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart);
         1166  +  }
         1167  +
         1168  +  /* Buffer the current row in the ephemeral table. */
         1169  +  sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid);
         1170  +  sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid);
         1171  +
         1172  +  /* End of the input loop */
         1173  +  sqlite3WhereEnd(pWInfo);
         1174  +
         1175  +  /* Invoke "flush_partition" to deal with the final (or only) partition */
         1176  +  sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart);
         1177  +}
         1178  +
         1179  +/*
         1180  +** Invoke the sub-routine at regGosub (generated by code in select.c) to
         1181  +** return the current row of Window.iEphCsr. If all window functions are
         1182  +** aggregate window functions that use the standard API, a single
         1183  +** OP_Gosub instruction is all that this routine generates. Extra VM code
         1184  +** for per-row processing is only generated for the following built-in window
         1185  +** functions:
         1186  +**
         1187  +**   nth_value()
         1188  +**   first_value()
         1189  +**   lag()
         1190  +**   lead()
         1191  +*/
         1192  +static void windowReturnOneRow(
         1193  +  Parse *pParse,
         1194  +  Window *pMWin,
         1195  +  int regGosub,
         1196  +  int addrGosub
         1197  +){
         1198  +  Vdbe *v = sqlite3GetVdbe(pParse);
         1199  +  Window *pWin;
         1200  +  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
         1201  +    FuncDef *pFunc = pWin->pFunc;
         1202  +    if( pFunc->xSFunc==nth_valueStepFunc 
         1203  +     || pFunc->xSFunc==first_valueStepFunc 
         1204  +    ){
         1205  +      int csr = pWin->csrApp;
         1206  +      int lbl = sqlite3VdbeMakeLabel(v);
         1207  +      int tmpReg = sqlite3GetTempReg(pParse);
         1208  +      sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
         1209  +
         1210  +      if( pFunc->xSFunc==nth_valueStepFunc ){
         1211  +        sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+1,tmpReg);
         1212  +      }else{
         1213  +        sqlite3VdbeAddOp2(v, OP_Integer, 1, tmpReg);
         1214  +      }
         1215  +      sqlite3VdbeAddOp3(v, OP_Add, tmpReg, pWin->regApp, tmpReg);
         1216  +      sqlite3VdbeAddOp3(v, OP_Gt, pWin->regApp+1, lbl, tmpReg);
         1217  +      VdbeCoverage(v);
         1218  +      sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, lbl, tmpReg);
         1219  +      VdbeCoverage(v);
         1220  +      sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
         1221  +      sqlite3VdbeResolveLabel(v, lbl);
         1222  +      sqlite3ReleaseTempReg(pParse, tmpReg);
         1223  +    }
         1224  +    else if( pFunc->xSFunc==leadStepFunc || pFunc->xSFunc==lagStepFunc ){
         1225  +      int nArg = pWin->pOwner->x.pList->nExpr;
         1226  +      int iEph = pMWin->iEphCsr;
         1227  +      int csr = pWin->csrApp;
         1228  +      int lbl = sqlite3VdbeMakeLabel(v);
         1229  +      int tmpReg = sqlite3GetTempReg(pParse);
         1230  +
         1231  +      if( nArg<3 ){
         1232  +        sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
         1233  +      }else{
         1234  +        sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+2, pWin->regResult);
         1235  +      }
         1236  +      sqlite3VdbeAddOp2(v, OP_Rowid, iEph, tmpReg);
         1237  +      if( nArg<2 ){
         1238  +        int val = (pFunc->xSFunc==leadStepFunc ? 1 : -1);
         1239  +        sqlite3VdbeAddOp2(v, OP_AddImm, tmpReg, val);
         1240  +      }else{
         1241  +        int op = (pFunc->xSFunc==leadStepFunc ? OP_Add : OP_Subtract);
         1242  +        int tmpReg2 = sqlite3GetTempReg(pParse);
         1243  +        sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+1, tmpReg2);
         1244  +        sqlite3VdbeAddOp3(v, op, tmpReg2, tmpReg, tmpReg);
         1245  +        sqlite3ReleaseTempReg(pParse, tmpReg2);
         1246  +      }
         1247  +
         1248  +      sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, lbl, tmpReg);
         1249  +      VdbeCoverage(v);
         1250  +      sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
         1251  +      sqlite3VdbeResolveLabel(v, lbl);
         1252  +      sqlite3ReleaseTempReg(pParse, tmpReg);
         1253  +    }
         1254  +  }
         1255  +  sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
         1256  +}
         1257  +
         1258  +/*
         1259  +** Invoke the code generated by windowReturnOneRow() and, optionally, the
         1260  +** xInverse() function for each window function, for one or more rows
         1261  +** from the Window.iEphCsr temp table. This routine generates VM code
         1262  +** similar to:
         1263  +**
         1264  +**   while( regCtr>0 ){
         1265  +**     regCtr--;
         1266  +**     windowReturnOneRow()
         1267  +**     if( bInverse ){
         1268  +**       AggStep (xInverse)
         1269  +**     }
         1270  +**     Next (Window.iEphCsr)
         1271  +**   }
         1272  +*/
         1273  +static void windowReturnRows(
         1274  +  Parse *pParse,
         1275  +  Window *pMWin,                  /* List of window functions */
         1276  +  int regCtr,                     /* Register containing number of rows */
         1277  +  int regGosub,                   /* Register for Gosub addrGosub */
         1278  +  int addrGosub,                  /* Address of sub-routine for ReturnOneRow */
         1279  +  int regInvArg,                  /* Array of registers for xInverse args */
         1280  +  int regInvSize                  /* Register containing size of partition */
         1281  +){
         1282  +  int addr;
         1283  +  Vdbe *v = sqlite3GetVdbe(pParse);
         1284  +  windowAggFinal(pParse, pMWin, 0);
         1285  +  addr = sqlite3VdbeAddOp3(v, OP_IfPos, regCtr, sqlite3VdbeCurrentAddr(v)+2 ,1);
         1286  +  VdbeCoverage(v);
         1287  +  sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
         1288  +  windowReturnOneRow(pParse, pMWin, regGosub, addrGosub);
         1289  +  if( regInvArg ){
         1290  +    windowAggStep(pParse, pMWin, pMWin->iEphCsr, 1, regInvArg, regInvSize);
         1291  +  }
         1292  +  sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, addr);
         1293  +  VdbeCoverage(v);
         1294  +  sqlite3VdbeJumpHere(v, addr+1);   /* The OP_Goto */
         1295  +}
         1296  +
         1297  +/*
         1298  +** Generate code to set the accumulator register for each window function
         1299  +** in the linked list passed as the second argument to NULL. And perform
         1300  +** any equivalent initialization required by any built-in window functions
         1301  +** in the list.
         1302  +*/
         1303  +static int windowInitAccum(Parse *pParse, Window *pMWin){
         1304  +  Vdbe *v = sqlite3GetVdbe(pParse);
         1305  +  int regArg;
         1306  +  int nArg = 0;
         1307  +  Window *pWin;
         1308  +  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
         1309  +    FuncDef *pFunc = pWin->pFunc;
         1310  +    sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
         1311  +    nArg = MAX(nArg, windowArgCount(pWin));
         1312  +    if( pFunc->xSFunc==nth_valueStepFunc
         1313  +     || pFunc->xSFunc==first_valueStepFunc 
         1314  +    ){
         1315  +      sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp);
         1316  +      sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
         1317  +    }
         1318  +
         1319  +    if( (pFunc->funcFlags & SQLITE_FUNC_MINMAX) && pWin->csrApp ){
         1320  +      assert( pWin->eStart!=TK_UNBOUNDED );
         1321  +      sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp);
         1322  +      sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
         1323  +    }
         1324  +  }
         1325  +  regArg = pParse->nMem+1;
         1326  +  pParse->nMem += nArg;
         1327  +  return regArg;
         1328  +}
         1329  +
         1330  +
         1331  +/*
         1332  +** This function does the work of sqlite3WindowCodeStep() for all "ROWS"
         1333  +** window frame types except for "BETWEEN UNBOUNDED PRECEDING AND CURRENT
         1334  +** ROW". Pseudo-code for each follows.
         1335  +**
         1336  +** ROWS BETWEEN <expr1> PRECEDING AND <expr2> FOLLOWING
         1337  +**
         1338  +**     ...
         1339  +**       if( new partition ){
         1340  +**         Gosub flush_partition
         1341  +**       }
         1342  +**       Insert (record in eph-table)
         1343  +**     sqlite3WhereEnd()
         1344  +**     Gosub flush_partition
         1345  +**  
         1346  +**   flush_partition:
         1347  +**     Once {
         1348  +**       OpenDup (iEphCsr -> csrStart)
         1349  +**       OpenDup (iEphCsr -> csrEnd)
         1350  +**     }
         1351  +**     regStart = <expr1>                // PRECEDING expression
         1352  +**     regEnd = <expr2>                  // FOLLOWING expression
         1353  +**     if( regStart<0 || regEnd<0 ){ error! }
         1354  +**     Rewind (csr,csrStart,csrEnd)      // if EOF goto flush_partition_done
         1355  +**       Next(csrEnd)                    // if EOF skip Aggstep
         1356  +**       Aggstep (csrEnd)
         1357  +**       if( (regEnd--)<=0 ){
         1358  +**         AggFinal (xValue)
         1359  +**         Gosub addrGosub
         1360  +**         Next(csr)                // if EOF goto flush_partition_done
         1361  +**         if( (regStart--)<=0 ){
         1362  +**           AggStep (csrStart, xInverse)
         1363  +**           Next(csrStart)
         1364  +**         }
         1365  +**       }
         1366  +**   flush_partition_done:
         1367  +**     ResetSorter (csr)
         1368  +**     Return
         1369  +**
         1370  +** ROWS BETWEEN <expr> PRECEDING    AND CURRENT ROW
         1371  +** ROWS BETWEEN CURRENT ROW         AND <expr> FOLLOWING
         1372  +** ROWS BETWEEN UNBOUNDED PRECEDING AND <expr> FOLLOWING
         1373  +**
         1374  +**   These are similar to the above. For "CURRENT ROW", intialize the
         1375  +**   register to 0. For "UNBOUNDED PRECEDING" to infinity.
         1376  +**
         1377  +** ROWS BETWEEN <expr> PRECEDING    AND UNBOUNDED FOLLOWING
         1378  +** ROWS BETWEEN CURRENT ROW         AND UNBOUNDED FOLLOWING
         1379  +**
         1380  +**     Rewind (csr,csrStart,csrEnd)    // if EOF goto flush_partition_done
         1381  +**     while( 1 ){
         1382  +**       Next(csrEnd)                  // Exit while(1) at EOF
         1383  +**       Aggstep (csrEnd)
         1384  +**     }
         1385  +**     while( 1 ){
         1386  +**       AggFinal (xValue)
         1387  +**       Gosub addrGosub
         1388  +**       Next(csr)                     // if EOF goto flush_partition_done
         1389  +**       if( (regStart--)<=0 ){
         1390  +**         AggStep (csrStart, xInverse)
         1391  +**         Next(csrStart)
         1392  +**       }
         1393  +**     }
         1394  +**
         1395  +**   For the "CURRENT ROW AND UNBOUNDED FOLLOWING" case, the final if() 
         1396  +**   condition is always true (as if regStart were initialized to 0).
         1397  +**
         1398  +** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
         1399  +** 
         1400  +**   This is the only RANGE case handled by this routine. It modifies the
         1401  +**   second while( 1 ) loop in "ROWS BETWEEN CURRENT ... UNBOUNDED..." to
         1402  +**   be:
         1403  +**
         1404  +**     while( 1 ){
         1405  +**       AggFinal (xValue)
         1406  +**       while( 1 ){
         1407  +**         regPeer++
         1408  +**         Gosub addrGosub
         1409  +**         Next(csr)                     // if EOF goto flush_partition_done
         1410  +**         if( new peer ) break;
         1411  +**       }
         1412  +**       while( (regPeer--)>0 ){
         1413  +**         AggStep (csrStart, xInverse)
         1414  +**         Next(csrStart)
         1415  +**       }
         1416  +**     }
         1417  +**
         1418  +** ROWS BETWEEN <expr> FOLLOWING    AND <expr> FOLLOWING
         1419  +**
         1420  +**   regEnd = regEnd - regStart
         1421  +**   Rewind (csr,csrStart,csrEnd)   // if EOF goto flush_partition_done
         1422  +**     Aggstep (csrEnd)
         1423  +**     Next(csrEnd)                 // if EOF fall-through
         1424  +**     if( (regEnd--)<=0 ){
         1425  +**       if( (regStart--)<=0 ){
         1426  +**         AggFinal (xValue)
         1427  +**         Gosub addrGosub
         1428  +**         Next(csr)              // if EOF goto flush_partition_done
         1429  +**       }
         1430  +**       AggStep (csrStart, xInverse)
         1431  +**       Next (csrStart)
         1432  +**     }
         1433  +**
         1434  +** ROWS BETWEEN <expr> PRECEDING    AND <expr> PRECEDING
         1435  +**
         1436  +**   Replace the bit after "Rewind" in the above with:
         1437  +**
         1438  +**     if( (regEnd--)<=0 ){
         1439  +**       AggStep (csrEnd)
         1440  +**       Next (csrEnd)
         1441  +**     }
         1442  +**     AggFinal (xValue)
         1443  +**     Gosub addrGosub
         1444  +**     Next(csr)                  // if EOF goto flush_partition_done
         1445  +**     if( (regStart--)<=0 ){
         1446  +**       AggStep (csr2, xInverse)
         1447  +**       Next (csr2)
         1448  +**     }
         1449  +**
         1450  +*/
         1451  +static void windowCodeRowExprStep(
         1452  +  Parse *pParse, 
         1453  +  Select *p,
         1454  +  WhereInfo *pWInfo,
         1455  +  int regGosub, 
         1456  +  int addrGosub
         1457  +){
         1458  +  Window *pMWin = p->pWin;
         1459  +  Vdbe *v = sqlite3GetVdbe(pParse);
         1460  +  int regFlushPart;               /* Register for "Gosub flush_partition" */
         1461  +  int lblFlushPart;               /* Label for "Gosub flush_partition" */
         1462  +  int lblFlushDone;               /* Label for "Gosub flush_partition_done" */
         1463  +
         1464  +  int regArg;
         1465  +  int addr;
         1466  +  int csrStart = pParse->nTab++;
         1467  +  int csrEnd = pParse->nTab++;
         1468  +  int regStart;                    /* Value of <expr> PRECEDING */
         1469  +  int regEnd;                      /* Value of <expr> FOLLOWING */
         1470  +  int addrGoto;
         1471  +  int addrTop;
         1472  +  int addrIfPos1;
         1473  +  int addrIfPos2;
         1474  +  int regSize = 0;
         1475  +
         1476  +  assert( pMWin->eStart==TK_PRECEDING 
         1477  +       || pMWin->eStart==TK_CURRENT 
         1478  +       || pMWin->eStart==TK_FOLLOWING 
         1479  +       || pMWin->eStart==TK_UNBOUNDED 
         1480  +  );
         1481  +  assert( pMWin->eEnd==TK_FOLLOWING 
         1482  +       || pMWin->eEnd==TK_CURRENT 
         1483  +       || pMWin->eEnd==TK_UNBOUNDED 
         1484  +       || pMWin->eEnd==TK_PRECEDING 
         1485  +  );
         1486  +
         1487  +  /* Allocate register and label for the "flush_partition" sub-routine. */
         1488  +  regFlushPart = ++pParse->nMem;
         1489  +  lblFlushPart = sqlite3VdbeMakeLabel(v);
         1490  +  lblFlushDone = sqlite3VdbeMakeLabel(v);
         1491  +
         1492  +  regStart = ++pParse->nMem;
         1493  +  regEnd = ++pParse->nMem;
         1494  +
         1495  +  windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, &regSize);
         1496  +
         1497  +  addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
         1498  +
         1499  +  /* Start of "flush_partition" */
         1500  +  sqlite3VdbeResolveLabel(v, lblFlushPart);
         1501  +  sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+3);
         1502  +  VdbeCoverage(v);
         1503  +  sqlite3VdbeAddOp2(v, OP_OpenDup, csrStart, pMWin->iEphCsr);
         1504  +  sqlite3VdbeAddOp2(v, OP_OpenDup, csrEnd, pMWin->iEphCsr);
         1505  +
         1506  +  /* If either regStart or regEnd are not non-negative integers, throw 
         1507  +  ** an exception.  */
         1508  +  if( pMWin->pStart ){
         1509  +    sqlite3ExprCode(pParse, pMWin->pStart, regStart);
         1510  +    windowCheckFrameValue(pParse, regStart, 0);
         1511  +  }
         1512  +  if( pMWin->pEnd ){
         1513  +    sqlite3ExprCode(pParse, pMWin->pEnd, regEnd);
         1514  +    windowCheckFrameValue(pParse, regEnd, 1);
         1515  +  }
         1516  +
         1517  +  /* If this is "ROWS <expr1> FOLLOWING AND ROWS <expr2> FOLLOWING", do:
         1518  +  **
         1519  +  **   if( regEnd<regStart ){
         1520  +  **     // The frame always consists of 0 rows
         1521  +  **     regStart = regSize;
         1522  +  **   }
         1523  +  **   regEnd = regEnd - regStart;
         1524  +  */
         1525  +  if( pMWin->pEnd && pMWin->pStart && pMWin->eStart==TK_FOLLOWING ){
         1526  +    assert( pMWin->eEnd==TK_FOLLOWING );
         1527  +    sqlite3VdbeAddOp3(v, OP_Ge, regStart, sqlite3VdbeCurrentAddr(v)+2, regEnd);
         1528  +    VdbeCoverage(v);
         1529  +    sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart);
         1530  +    sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regEnd);
         1531  +  }
         1532  +
         1533  +  if( pMWin->pEnd && pMWin->pStart && pMWin->eEnd==TK_PRECEDING ){
         1534  +    assert( pMWin->eStart==TK_PRECEDING );
         1535  +    sqlite3VdbeAddOp3(v, OP_Le, regStart, sqlite3VdbeCurrentAddr(v)+3, regEnd);
         1536  +    VdbeCoverage(v);
         1537  +    sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart);
         1538  +    sqlite3VdbeAddOp2(v, OP_Copy, regSize, regEnd);
         1539  +  }
         1540  +
         1541  +  /* Initialize the accumulator register for each window function to NULL */
         1542  +  regArg = windowInitAccum(pParse, pMWin);
         1543  +
         1544  +  sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr, lblFlushDone);
         1545  +  VdbeCoverage(v);
         1546  +  sqlite3VdbeAddOp2(v, OP_Rewind, csrStart, lblFlushDone);
         1547  +  VdbeCoverageNeverTaken(v);
         1548  +  sqlite3VdbeChangeP5(v, 1);
         1549  +  sqlite3VdbeAddOp2(v, OP_Rewind, csrEnd, lblFlushDone);
         1550  +  VdbeCoverageNeverTaken(v);
         1551  +  sqlite3VdbeChangeP5(v, 1);
         1552  +
         1553  +  /* Invoke AggStep function for each window function using the row that
         1554  +  ** csrEnd currently points to. Or, if csrEnd is already at EOF,
         1555  +  ** do nothing.  */
         1556  +  addrTop = sqlite3VdbeCurrentAddr(v);
         1557  +  if( pMWin->eEnd==TK_PRECEDING ){
         1558  +    addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1);
         1559  +    VdbeCoverage(v);
         1560  +  }
         1561  +  sqlite3VdbeAddOp2(v, OP_Next, csrEnd, sqlite3VdbeCurrentAddr(v)+2);
         1562  +  VdbeCoverage(v);
         1563  +  addr = sqlite3VdbeAddOp0(v, OP_Goto);
         1564  +  windowAggStep(pParse, pMWin, csrEnd, 0, regArg, regSize);
         1565  +  if( pMWin->eEnd==TK_UNBOUNDED ){
         1566  +    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
         1567  +    sqlite3VdbeJumpHere(v, addr);
         1568  +    addrTop = sqlite3VdbeCurrentAddr(v);
         1569  +  }else{
         1570  +    sqlite3VdbeJumpHere(v, addr);
         1571  +    if( pMWin->eEnd==TK_PRECEDING ){
         1572  +      sqlite3VdbeJumpHere(v, addrIfPos1);
         1573  +    }
         1574  +  }
         1575  +
         1576  +  if( pMWin->eEnd==TK_FOLLOWING ){
         1577  +    addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1);
         1578  +    VdbeCoverage(v);
         1579  +  }
         1580  +  if( pMWin->eStart==TK_FOLLOWING ){
         1581  +    addrIfPos2 = sqlite3VdbeAddOp3(v, OP_IfPos, regStart, 0 , 1);
         1582  +    VdbeCoverage(v);
         1583  +  }
         1584  +  windowAggFinal(pParse, pMWin, 0);
         1585  +  windowReturnOneRow(pParse, pMWin, regGosub, addrGosub);
         1586  +  sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)+2);
         1587  +  VdbeCoverage(v);
         1588  +  sqlite3VdbeAddOp2(v, OP_Goto, 0, lblFlushDone);
         1589  +  if( pMWin->eStart==TK_FOLLOWING ){
         1590  +    sqlite3VdbeJumpHere(v, addrIfPos2);
         1591  +  }
         1592  +
         1593  +  if( pMWin->eStart==TK_CURRENT 
         1594  +   || pMWin->eStart==TK_PRECEDING 
         1595  +   || pMWin->eStart==TK_FOLLOWING 
         1596  +  ){
         1597  +    int addrJumpHere = 0;
         1598  +    if( pMWin->eStart==TK_PRECEDING ){
         1599  +      addrJumpHere = sqlite3VdbeAddOp3(v, OP_IfPos, regStart, 0 , 1);
         1600  +      VdbeCoverage(v);
         1601  +    }
         1602  +    sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+1);
         1603  +    VdbeCoverage(v);
         1604  +    windowAggStep(pParse, pMWin, csrStart, 1, regArg, regSize);
         1605  +    if( addrJumpHere ){
         1606  +      sqlite3VdbeJumpHere(v, addrJumpHere);
         1607  +    }
         1608  +  }
         1609  +  if( pMWin->eEnd==TK_FOLLOWING ){
         1610  +    sqlite3VdbeJumpHere(v, addrIfPos1);
         1611  +  }
         1612  +  sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
         1613  +
         1614  +  /* flush_partition_done: */
         1615  +  sqlite3VdbeResolveLabel(v, lblFlushDone);
         1616  +  sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
         1617  +  sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);
         1618  +
         1619  +  /* Jump to here to skip over flush_partition */
         1620  +  sqlite3VdbeJumpHere(v, addrGoto);
         1621  +}
         1622  +
         1623  +/*
         1624  +** This function does the work of sqlite3WindowCodeStep() for cases that
         1625  +** would normally be handled by windowCodeDefaultStep() when there are
         1626  +** one or more built-in window-functions that require the entire partition
         1627  +** to be cached in a temp table before any rows can be returned. Additionally.
         1628  +** "RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING" is always handled by
         1629  +** this function.
         1630  +**
         1631  +** Pseudo-code corresponding to the VM code generated by this function
         1632  +** for each type of window follows.
         1633  +**
         1634  +** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
         1635  +**
         1636  +**   flush_partition:
         1637  +**     Once {
         1638  +**       OpenDup (iEphCsr -> csrLead)
         1639  +**     }
         1640  +**     Integer ctr 0
         1641  +**     foreach row (csrLead){
         1642  +**       if( new peer ){
         1643  +**         AggFinal (xValue)
         1644  +**         for(i=0; i<ctr; i++){
         1645  +**           Gosub addrGosub
         1646  +**           Next iEphCsr
         1647  +**         }
         1648  +**         Integer ctr 0
         1649  +**       }
         1650  +**       AggStep (csrLead)
         1651  +**       Incr ctr
         1652  +**     }
         1653  +**
         1654  +**     AggFinal (xFinalize)
         1655  +**     for(i=0; i<ctr; i++){
         1656  +**       Gosub addrGosub
         1657  +**       Next iEphCsr
         1658  +**     }
         1659  +**
         1660  +**     ResetSorter (csr)
         1661  +**     Return
         1662  +**
         1663  +** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
         1664  +**
         1665  +**   As above, except that the "if( new peer )" branch is always taken.
         1666  +**
         1667  +** RANGE BETWEEN CURRENT ROW AND CURRENT ROW 
         1668  +**
         1669  +**   As above, except that each of the for() loops becomes:
         1670  +**
         1671  +**         for(i=0; i<ctr; i++){
         1672  +**           Gosub addrGosub
         1673  +**           AggStep (xInverse, iEphCsr)
         1674  +**           Next iEphCsr
         1675  +**         }
         1676  +**
         1677  +** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
         1678  +**
         1679  +**   flush_partition:
         1680  +**     Once {
         1681  +**       OpenDup (iEphCsr -> csrLead)
         1682  +**     }
         1683  +**     foreach row (csrLead) {
         1684  +**       AggStep (csrLead)
         1685  +**     }
         1686  +**     foreach row (iEphCsr) {
         1687  +**       Gosub addrGosub
         1688  +**     }
         1689  +** 
         1690  +** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
         1691  +**
         1692  +**   flush_partition:
         1693  +**     Once {
         1694  +**       OpenDup (iEphCsr -> csrLead)
         1695  +**     }
         1696  +**     foreach row (csrLead){
         1697  +**       AggStep (csrLead)
         1698  +**     }
         1699  +**     Rewind (csrLead)
         1700  +**     Integer ctr 0
         1701  +**     foreach row (csrLead){
         1702  +**       if( new peer ){
         1703  +**         AggFinal (xValue)
         1704  +**         for(i=0; i<ctr; i++){
         1705  +**           Gosub addrGosub
         1706  +**           AggStep (xInverse, iEphCsr)
         1707  +**           Next iEphCsr
         1708  +**         }
         1709  +**         Integer ctr 0
         1710  +**       }
         1711  +**       Incr ctr
         1712  +**     }
         1713  +**
         1714  +**     AggFinal (xFinalize)
         1715  +**     for(i=0; i<ctr; i++){
         1716  +**       Gosub addrGosub
         1717  +**       Next iEphCsr
         1718  +**     }
         1719  +**
         1720  +**     ResetSorter (csr)
         1721  +**     Return
         1722  +*/
         1723  +static void windowCodeCacheStep(
         1724  +  Parse *pParse, 
         1725  +  Select *p,
         1726  +  WhereInfo *pWInfo,
         1727  +  int regGosub, 
         1728  +  int addrGosub
         1729  +){
         1730  +  Window *pMWin = p->pWin;
         1731  +  Vdbe *v = sqlite3GetVdbe(pParse);
         1732  +  int k;
         1733  +  int addr;
         1734  +  ExprList *pPart = pMWin->pPartition;
         1735  +  ExprList *pOrderBy = pMWin->pOrderBy;
         1736  +  int nPeer = pOrderBy ? pOrderBy->nExpr : 0;
         1737  +  int regNewPeer;
         1738  +
         1739  +  int addrGoto;                   /* Address of Goto used to jump flush_par.. */
         1740  +  int addrNext;                   /* Jump here for next iteration of loop */
         1741  +  int regFlushPart;
         1742  +  int lblFlushPart;
         1743  +  int csrLead;
         1744  +  int regCtr;
         1745  +  int regArg;                     /* Register array to martial function args */
         1746  +  int regSize;
         1747  +  int lblEmpty;
         1748  +  int bReverse = pMWin->pOrderBy && pMWin->eStart==TK_CURRENT 
         1749  +          && pMWin->eEnd==TK_UNBOUNDED;
         1750  +
         1751  +  assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT) 
         1752  +       || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED) 
         1753  +       || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT) 
         1754  +       || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED) 
         1755  +  );
         1756  +
         1757  +  lblEmpty = sqlite3VdbeMakeLabel(v);
         1758  +  regNewPeer = pParse->nMem+1;
         1759  +  pParse->nMem += nPeer;
         1760  +
         1761  +  /* Allocate register and label for the "flush_partition" sub-routine. */
         1762  +  regFlushPart = ++pParse->nMem;
         1763  +  lblFlushPart = sqlite3VdbeMakeLabel(v);
         1764  +
         1765  +  csrLead = pParse->nTab++;
         1766  +  regCtr = ++pParse->nMem;
         1767  +
         1768  +  windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, &regSize);
         1769  +  addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
         1770  +
         1771  +  /* Start of "flush_partition" */
         1772  +  sqlite3VdbeResolveLabel(v, lblFlushPart);
         1773  +  sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+2);
         1774  +  VdbeCoverage(v);
         1775  +  sqlite3VdbeAddOp2(v, OP_OpenDup, csrLead, pMWin->iEphCsr);
         1776  +
         1777  +  /* Initialize the accumulator register for each window function to NULL */
         1778  +  regArg = windowInitAccum(pParse, pMWin);
         1779  +
         1780  +  sqlite3VdbeAddOp2(v, OP_Integer, 0, regCtr);
         1781  +  sqlite3VdbeAddOp2(v, OP_Rewind, csrLead, lblEmpty);
         1782  +  VdbeCoverage(v);
         1783  +  sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr, lblEmpty);
         1784  +  VdbeCoverageNeverTaken(v);
         1785  +
         1786  +  if( bReverse ){
         1787  +    int addr = sqlite3VdbeCurrentAddr(v);
         1788  +    windowAggStep(pParse, pMWin, csrLead, 0, regArg, regSize);
         1789  +    sqlite3VdbeAddOp2(v, OP_Next, csrLead, addr);
         1790  +    VdbeCoverage(v);
         1791  +    sqlite3VdbeAddOp2(v, OP_Rewind, csrLead, lblEmpty);
         1792  +    VdbeCoverageNeverTaken(v);
         1793  +  }
         1794  +  addrNext = sqlite3VdbeCurrentAddr(v);
         1795  +
         1796  +  if( pOrderBy && (pMWin->eEnd==TK_CURRENT || pMWin->eStart==TK_CURRENT) ){
         1797  +    int bCurrent = (pMWin->eStart==TK_CURRENT);
         1798  +    int addrJump = 0;             /* Address of OP_Jump below */
         1799  +    if( pMWin->eType==TK_RANGE ){
         1800  +      int iOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0);
         1801  +      int regPeer = pMWin->regPart + (pPart ? pPart->nExpr : 0);
         1802  +      KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);
         1803  +      for(k=0; k<nPeer; k++){
         1804  +        sqlite3VdbeAddOp3(v, OP_Column, csrLead, iOff+k, regNewPeer+k);
         1805  +      }
         1806  +      addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPeer, regPeer, nPeer);
         1807  +      sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
         1808  +      addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
         1809  +      VdbeCoverage(v);
         1810  +      sqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, nPeer-1);
         1811  +    }
         1812  +
         1813  +    windowReturnRows(pParse, pMWin, regCtr, regGosub, addrGosub, 
         1814  +        (bCurrent ? regArg : 0), (bCurrent ? regSize : 0)
         1815  +    );
         1816  +    if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
         1817  +  }
         1818  +
         1819  +  if( bReverse==0 ){
         1820  +    windowAggStep(pParse, pMWin, csrLead, 0, regArg, regSize);
         1821  +  }
         1822  +  sqlite3VdbeAddOp2(v, OP_AddImm, regCtr, 1);
         1823  +  sqlite3VdbeAddOp2(v, OP_Next, csrLead, addrNext);
         1824  +  VdbeCoverage(v);
         1825  +
         1826  +  windowReturnRows(pParse, pMWin, regCtr, regGosub, addrGosub, 0, 0);
         1827  +
         1828  +  sqlite3VdbeResolveLabel(v, lblEmpty);
         1829  +  sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
         1830  +  sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);
         1831  +
         1832  +  /* Jump to here to skip over flush_partition */
         1833  +  sqlite3VdbeJumpHere(v, addrGoto);
         1834  +}
         1835  +
         1836  +
         1837  +/*
         1838  +** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
         1839  +**
         1840  +**   ...
         1841  +**     if( new partition ){
         1842  +**       AggFinal (xFinalize)
         1843  +**       Gosub addrGosub
         1844  +**       ResetSorter eph-table
         1845  +**     }
         1846  +**     else if( new peer ){
         1847  +**       AggFinal (xValue)
         1848  +**       Gosub addrGosub
         1849  +**       ResetSorter eph-table
         1850  +**     }
         1851  +**     AggStep
         1852  +**     Insert (record into eph-table)
         1853  +**   sqlite3WhereEnd()
         1854  +**   AggFinal (xFinalize)
         1855  +**   Gosub addrGosub
         1856  +**
         1857  +** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
         1858  +**
         1859  +**   As above, except take no action for a "new peer". Invoke
         1860  +**   the sub-routine once only for each partition.
         1861  +**
         1862  +** RANGE BETWEEN CURRENT ROW AND CURRENT ROW
         1863  +**
         1864  +**   As above, except that the "new peer" condition is handled in the
         1865  +**   same way as "new partition" (so there is no "else if" block).
         1866  +**
         1867  +** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
         1868  +** 
         1869  +**   As above, except assume every row is a "new peer".
         1870  +*/
         1871  +static void windowCodeDefaultStep(
         1872  +  Parse *pParse, 
         1873  +  Select *p,
         1874  +  WhereInfo *pWInfo,
         1875  +  int regGosub, 
         1876  +  int addrGosub
         1877  +){
         1878  +  Window *pMWin = p->pWin;
         1879  +  Vdbe *v = sqlite3GetVdbe(pParse);
         1880  +  int k;
         1881  +  int iSubCsr = p->pSrc->a[0].iCursor;
         1882  +  int nSub = p->pSrc->a[0].pTab->nCol;
         1883  +  int reg = pParse->nMem+1;
         1884  +  int regRecord = reg+nSub;
         1885  +  int regRowid = regRecord+1;
         1886  +  int addr;
         1887  +  ExprList *pPart = pMWin->pPartition;
         1888  +  ExprList *pOrderBy = pMWin->pOrderBy;
         1889  +
         1890  +  assert( pMWin->eType==TK_RANGE 
         1891  +      || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT)
         1892  +  );
         1893  +
         1894  +  assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT)
         1895  +       || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED)
         1896  +       || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT)
         1897  +       || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED && !pOrderBy)
         1898  +  );
         1899  +
         1900  +  if( pMWin->eEnd==TK_UNBOUNDED ){
         1901  +    pOrderBy = 0;
         1902  +  }
         1903  +
         1904  +  pParse->nMem += nSub + 2;
         1905  +
         1906  +  /* Martial the row returned by the sub-select into an array of 
         1907  +  ** registers. */
         1908  +  for(k=0; k<nSub; k++){
         1909  +    sqlite3VdbeAddOp3(v, OP_Column, iSubCsr, k, reg+k);
         1910  +  }
         1911  +
         1912  +  /* Check if this is the start of a new partition or peer group. */
         1913  +  if( pPart || pOrderBy ){
         1914  +    int nPart = (pPart ? pPart->nExpr : 0);
         1915  +    int addrGoto = 0;
         1916  +    int addrJump = 0;
         1917  +    int nPeer = (pOrderBy ? pOrderBy->nExpr : 0);
         1918  +
         1919  +    if( pPart ){
         1920  +      int regNewPart = reg + pMWin->nBufferCol;
         1921  +      KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
         1922  +      addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart,nPart);
         1923  +      sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
         1924  +      addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
         1925  +      VdbeCoverage(v);
         1926  +      windowAggFinal(pParse, pMWin, 1);
         1927  +      if( pOrderBy ){
         1928  +        addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
         1929  +      }
         1930  +    }
         1931  +
         1932  +    if( pOrderBy ){
         1933  +      int regNewPeer = reg + pMWin->nBufferCol + nPart;
         1934  +      int regPeer = pMWin->regPart + nPart;
         1935  +
         1936  +      if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
         1937  +      if( pMWin->eType==TK_RANGE ){
         1938  +        KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);
         1939  +        addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPeer, regPeer, nPeer);
         1940  +        sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
         1941  +        addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
         1942  +        VdbeCoverage(v);
         1943  +      }else{
         1944  +        addrJump = 0;
         1945  +      }
         1946  +      windowAggFinal(pParse, pMWin, pMWin->eStart==TK_CURRENT);
         1947  +      if( addrGoto ) sqlite3VdbeJumpHere(v, addrGoto);
         1948  +    }
         1949  +
         1950  +    sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3);
         1951  +    VdbeCoverage(v);
         1952  +    sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
         1953  +    sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1);
         1954  +    VdbeCoverage(v);
         1955  +
         1956  +    sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
         1957  +    sqlite3VdbeAddOp3(
         1958  +        v, OP_Copy, reg+pMWin->nBufferCol, pMWin->regPart, nPart+nPeer-1
         1959  +    );
         1960  +
         1961  +    if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
         1962  +  }
         1963  +
         1964  +  /* Invoke step function for window functions */
         1965  +  windowAggStep(pParse, pMWin, -1, 0, reg, 0);
         1966  +
         1967  +  /* Buffer the current row in the ephemeral table. */
         1968  +  if( pMWin->nBufferCol>0 ){
         1969  +    sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, pMWin->nBufferCol, regRecord);
         1970  +  }else{
         1971  +    sqlite3VdbeAddOp2(v, OP_Blob, 0, regRecord);
         1972  +    sqlite3VdbeAppendP4(v, (void*)"", 0);
         1973  +  }
         1974  +  sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid);
         1975  +  sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid);
         1976  +
         1977  +  /* End the database scan loop. */
         1978  +  sqlite3WhereEnd(pWInfo);
         1979  +
         1980  +  windowAggFinal(pParse, pMWin, 1);
         1981  +  sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3);
         1982  +  VdbeCoverage(v);
         1983  +  sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
         1984  +  sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1);
         1985  +  VdbeCoverage(v);
         1986  +}
         1987  +
         1988  +/*
         1989  +** Allocate and return a duplicate of the Window object indicated by the
         1990  +** third argument. Set the Window.pOwner field of the new object to
         1991  +** pOwner.
         1992  +*/
         1993  +Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
         1994  +  Window *pNew = 0;
         1995  +  if( p ){
         1996  +    pNew = sqlite3DbMallocZero(db, sizeof(Window));
         1997  +    if( pNew ){
         1998  +      pNew->zName = sqlite3DbStrDup(db, p->zName);
         1999  +      pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
         2000  +      pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
         2001  +      pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
         2002  +      pNew->eType = p->eType;
         2003  +      pNew->eEnd = p->eEnd;
         2004  +      pNew->eStart = p->eStart;
         2005  +      pNew->pStart = sqlite3ExprDup(db, p->pStart, 0);
         2006  +      pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0);
         2007  +      pNew->pOwner = pOwner;
         2008  +    }
         2009  +  }
         2010  +  return pNew;
         2011  +}
         2012  +
         2013  +/*
         2014  +** Return a copy of the linked list of Window objects passed as the
         2015  +** second argument.
         2016  +*/
         2017  +Window *sqlite3WindowListDup(sqlite3 *db, Window *p){
         2018  +  Window *pWin;
         2019  +  Window *pRet = 0;
         2020  +  Window **pp = &pRet;
         2021  +
         2022  +  for(pWin=p; pWin; pWin=pWin->pNextWin){
         2023  +    *pp = sqlite3WindowDup(db, 0, pWin);
         2024  +    if( *pp==0 ) break;
         2025  +    pp = &((*pp)->pNextWin);
         2026  +  }
         2027  +
         2028  +  return pRet;
         2029  +}
         2030  +
         2031  +/*
         2032  +** sqlite3WhereBegin() has already been called for the SELECT statement 
         2033  +** passed as the second argument when this function is invoked. It generates
         2034  +** code to populate the Window.regResult register for each window function and
         2035  +** invoke the sub-routine at instruction addrGosub once for each row.
         2036  +** This function calls sqlite3WhereEnd() before returning. 
         2037  +*/
         2038  +void sqlite3WindowCodeStep(
         2039  +  Parse *pParse,                  /* Parse context */
         2040  +  Select *p,                      /* Rewritten SELECT statement */
         2041  +  WhereInfo *pWInfo,              /* Context returned by sqlite3WhereBegin() */
         2042  +  int regGosub,                   /* Register for OP_Gosub */
         2043  +  int addrGosub                   /* OP_Gosub here to return each row */
         2044  +){
         2045  +  Window *pMWin = p->pWin;
         2046  +
         2047  +  /* There are three different functions that may be used to do the work
         2048  +  ** of this one, depending on the window frame and the specific built-in
         2049  +  ** window functions used (if any).
         2050  +  **
         2051  +  ** windowCodeRowExprStep() handles all "ROWS" window frames, except for:
         2052  +  **
         2053  +  **   ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
         2054  +  **
         2055  +  ** The exception is because windowCodeRowExprStep() implements all window
         2056  +  ** frame types by caching the entire partition in a temp table, and
         2057  +  ** "ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW" is easy enough to
         2058  +  ** implement without such a cache.
         2059  +  **
         2060  +  ** windowCodeCacheStep() is used for:
         2061  +  **
         2062  +  **   RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
         2063  +  **
         2064  +  ** It is also used for anything not handled by windowCodeRowExprStep() 
         2065  +  ** that invokes a built-in window function that requires the entire 
         2066  +  ** partition to be cached in a temp table before any rows are returned
         2067  +  ** (e.g. nth_value() or percent_rank()).
         2068  +  **
         2069  +  ** Finally, assuming there is no built-in window function that requires
         2070  +  ** the partition to be cached, windowCodeDefaultStep() is used for:
         2071  +  **
         2072  +  **   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
         2073  +  **   RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
         2074  +  **   RANGE BETWEEN CURRENT ROW AND CURRENT ROW 
         2075  +  **   ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
         2076  +  **
         2077  +  ** windowCodeDefaultStep() is the only one of the three functions that
         2078  +  ** does not cache each partition in a temp table before beginning to
         2079  +  ** return rows.
         2080  +  */
         2081  +  if( pMWin->eType==TK_ROWS 
         2082  +   && (pMWin->eStart!=TK_UNBOUNDED||pMWin->eEnd!=TK_CURRENT||!pMWin->pOrderBy)
         2083  +  ){
         2084  +    windowCodeRowExprStep(pParse, p, pWInfo, regGosub, addrGosub);
         2085  +  }else{
         2086  +    Window *pWin;
         2087  +    int bCache = 0;               /* True to use CacheStep() */
         2088  +
         2089  +    if( pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED ){
         2090  +      bCache = 1;
         2091  +    }else{
         2092  +      for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
         2093  +        FuncDef *pFunc = pWin->pFunc;
         2094  +        if( (pFunc->funcFlags & SQLITE_FUNC_WINDOW_SIZE)
         2095  +         || (pFunc->xSFunc==nth_valueStepFunc)
         2096  +         || (pFunc->xSFunc==first_valueStepFunc)
         2097  +         || (pFunc->xSFunc==leadStepFunc)
         2098  +         || (pFunc->xSFunc==lagStepFunc)
         2099  +        ){
         2100  +          bCache = 1;
         2101  +          break;
         2102  +        }
         2103  +      }
         2104  +    }
         2105  +
         2106  +    /* Otherwise, call windowCodeDefaultStep().  */
         2107  +    if( bCache ){
         2108  +      windowCodeCacheStep(pParse, p, pWInfo, regGosub, addrGosub);
         2109  +    }else{
         2110  +      windowCodeDefaultStep(pParse, p, pWInfo, regGosub, addrGosub);
         2111  +    }
         2112  +  }
         2113  +}
         2114  +
         2115  +#endif /* SQLITE_OMIT_WINDOWFUNC */

Changes to test/permutations.test.

   278    278   test_suite "fts5-light" -prefix "" -description {
   279    279     All FTS5 tests.
   280    280   } -files [
   281    281     test_set \
   282    282         [glob -nocomplain $::testdir/../ext/fts5/test/*.test] \
   283    283         -exclude *corrupt* *fault* *big* *fts5aj*
   284    284   ]
          285  +
          286  +test_suite "window" -prefix "" -description {
          287  +  All window function related tests .
          288  +} -files [
          289  +  test_set [glob -nocomplain $::testdir/window*.test]
          290  +]
   285    291   
   286    292   test_suite "lsm1" -prefix "" -description {
   287    293     All LSM1 tests.
   288    294   } -files [glob -nocomplain $::testdir/../ext/lsm1/test/*.test]
   289    295   
   290    296   test_suite "nofaultsim" -prefix "" -description {
   291    297     "Very" quick test suite. Runs in less than 5 minutes on a workstation. 

Added test/pg_common.tcl.

            1  +# 2018 May 19
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +
           13  +package require sqlite3
           14  +package require Pgtcl
           15  +
           16  +set db [pg_connect -conninfo "dbname=postgres user=postgres password=postgres"]
           17  +sqlite3 sqlite ""
           18  +
           19  +proc execsql {sql} {
           20  +
           21  +  set lSql [list]
           22  +  set frag ""
           23  +  while {[string length $sql]>0} {
           24  +    set i [string first ";" $sql]
           25  +    if {$i>=0} {
           26  +      append frag [string range $sql 0 $i]
           27  +      set sql [string range $sql $i+1 end]
           28  +      if {[sqlite complete $frag]} {
           29  +        lappend lSql $frag
           30  +        set frag ""
           31  +      }
           32  +    } else {
           33  +      set frag $sql
           34  +      set sql ""
           35  +    }
           36  +  }
           37  +  if {$frag != ""} {
           38  +    lappend lSql $frag
           39  +  }
           40  +  #puts $lSql
           41  +
           42  +  set ret ""
           43  +  foreach stmt $lSql {
           44  +    set res [pg_exec $::db $stmt]
           45  +    set err [pg_result $res -error]
           46  +    if {$err!=""} { error $err }
           47  +    for {set i 0} {$i < [pg_result $res -numTuples]} {incr i} {
           48  +      if {$i==0} {
           49  +        set ret [pg_result $res -getTuple 0]
           50  +      } else {
           51  +        append ret "   [pg_result $res -getTuple $i]"
           52  +      }
           53  +      # lappend ret {*}[pg_result $res -getTuple $i]
           54  +    }
           55  +    pg_result $res -clear
           56  +  }
           57  +
           58  +  set ret
           59  +}
           60  +
           61  +proc execsql_test {tn sql} {
           62  +  set res [execsql $sql]
           63  +  set sql [string map {string_agg group_concat} $sql]
           64  +  puts $::fd "do_execsql_test $tn {"
           65  +  puts $::fd "  [string trim $sql]"
           66  +  puts $::fd "} {$res}"
           67  +  puts $::fd ""
           68  +}
           69  +
           70  +# Same as [execsql_test], except coerce all results to floating point values
           71  +# with two decimal points.
           72  +#
           73  +proc execsql_float_test {tn sql} {
           74  +  set F "%.2f"
           75  +  set res [execsql $sql]
           76  +  set res2 [list]
           77  +  foreach r $res { 
           78  +    if {$r != ""} { set r [format $F $r] }
           79  +    lappend res2 $r
           80  +  }
           81  +
           82  +  puts $::fd "do_test $tn {"
           83  +  puts $::fd "  set myres {}"
           84  +  puts $::fd "  foreach r \[db eval {[string trim $sql]}\] {"
           85  +  puts $::fd "    lappend myres \[format $F \[set r\]\]"
           86  +  puts $::fd "  }"
           87  +  puts $::fd "  set myres"
           88  +  puts $::fd "} {$res2}"
           89  +  puts $::fd ""
           90  +}
           91  +
           92  +proc start_test {name date} {
           93  +  set dir [file dirname $::argv0]
           94  +  set output [file join $dir $name.test]
           95  +  set ::fd [open $output w]
           96  +puts $::fd [string trimleft "
           97  +# $date
           98  +#
           99  +# The author disclaims copyright to this source code.  In place of
          100  +# a legal notice, here is a blessing:
          101  +#
          102  +#    May you do good and not evil.
          103  +#    May you find forgiveness for yourself and forgive others.
          104  +#    May you share freely, never taking more than you give.
          105  +#
          106  +#***********************************************************************
          107  +# This file implements regression tests for SQLite library.
          108  +#
          109  +
          110  +####################################################
          111  +# DO NOT EDIT! THIS FILE IS AUTOMATICALLY GENERATED!
          112  +####################################################
          113  +"]
          114  +  puts $::fd {set testdir [file dirname $argv0]}
          115  +  puts $::fd {source $testdir/tester.tcl}
          116  +  puts $::fd "set testprefix $name"
          117  +  puts $::fd ""
          118  +}
          119  +
          120  +proc -- {args} {
          121  +  puts $::fd "# $args"
          122  +}
          123  +
          124  +proc ========== {args} {
          125  +  puts $::fd "#[string repeat = 74]"
          126  +  puts $::fd ""
          127  +}
          128  +
          129  +proc finish_test {} {
          130  +  puts $::fd finish_test
          131  +  close $::fd
          132  +}
          133  +
          134  +proc ifcapable {arg} {
          135  +   puts $::fd "ifcapable $arg { finish_test ; return }"
          136  +}
          137  +

Added test/window1.test.

            1  +# 2018 May 8
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +# This file implements regression tests for SQLite library.
           12  +#
           13  +
           14  +set testdir [file dirname $argv0]
           15  +source $testdir/tester.tcl
           16  +set testprefix window1
           17  +
           18  +ifcapable !windowfunc {
           19  +  finish_test
           20  +  return
           21  +}
           22  +
           23  +do_execsql_test 1.0 {
           24  +  CREATE TABLE t1(a, b, c, d);
           25  +  INSERT INTO t1 VALUES(1, 2, 3, 4);
           26  +  INSERT INTO t1 VALUES(5, 6, 7, 8);
           27  +  INSERT INTO t1 VALUES(9, 10, 11, 12);
           28  +}
           29  +
           30  +do_execsql_test 1.1 {
           31  +  SELECT sum(b) OVER () FROM t1
           32  +} {18 18 18}
           33  +
           34  +do_execsql_test 1.2 {
           35  +  SELECT a, sum(b) OVER () FROM t1
           36  +} {1 18 5 18 9 18}
           37  +
           38  +do_execsql_test 1.3 {
           39  +  SELECT a, 4 + sum(b) OVER () FROM t1
           40  +} {1 22 5 22 9 22}
           41  +
           42  +do_execsql_test 1.4 {
           43  +  SELECT a + 4 + sum(b) OVER () FROM t1
           44  +} {23 27 31}
           45  +
           46  +do_execsql_test 1.5 {
           47  +  SELECT a, sum(b) OVER (PARTITION BY c) FROM t1
           48  +} {1 2 5 6 9 10}
           49  +
           50  +foreach {tn sql} {
           51  +  1 "SELECT sum(b) OVER () FROM t1"
           52  +  2 "SELECT sum(b) OVER (PARTITION BY c) FROM t1"
           53  +  3 "SELECT sum(b) OVER (ORDER BY c) FROM t1"
           54  +  4 "SELECT sum(b) OVER (PARTITION BY d ORDER BY c) FROM t1"
           55  +  5 "SELECT sum(b) FILTER (WHERE a>0) OVER (PARTITION BY d ORDER BY c) FROM t1"
           56  +  6 "SELECT sum(b) OVER (ORDER BY c RANGE UNBOUNDED PRECEDING) FROM t1"
           57  +  7 "SELECT sum(b) OVER (ORDER BY c ROWS 45 PRECEDING) FROM t1"
           58  +  8 "SELECT sum(b) OVER (ORDER BY c RANGE CURRENT ROW) FROM t1"
           59  +  9 "SELECT sum(b) OVER (ORDER BY c RANGE BETWEEN UNBOUNDED PRECEDING 
           60  +     AND CURRENT ROW) FROM t1"
           61  + 10 "SELECT sum(b) OVER (ORDER BY c ROWS BETWEEN UNBOUNDED PRECEDING 
           62  +     AND UNBOUNDED FOLLOWING) FROM t1"
           63  +} {
           64  +  do_test 2.$tn { lindex [catchsql $sql] 0 } 0
           65  +}
           66  +
           67  +foreach {tn sql} {
           68  +  1 "SELECT * FROM t1 WHERE sum(b) OVER ()"
           69  +  2 "SELECT * FROM t1 GROUP BY sum(b) OVER ()"
           70  +  3 "SELECT * FROM t1 GROUP BY a HAVING sum(b) OVER ()"
           71  +} {
           72  +  do_catchsql_test 3.$tn $sql {1 {misuse of window function sum()}}
           73  +}
           74  +
           75  +do_execsql_test 4.0 {
           76  +  CREATE TABLE t2(a, b, c);
           77  +  INSERT INTO t2 VALUES(0, 0, 0);
           78  +  INSERT INTO t2 VALUES(1, 1, 1);
           79  +  INSERT INTO t2 VALUES(2, 0, 2);
           80  +  INSERT INTO t2 VALUES(3, 1, 0);
           81  +  INSERT INTO t2 VALUES(4, 0, 1);
           82  +  INSERT INTO t2 VALUES(5, 1, 2);
           83  +  INSERT INTO t2 VALUES(6, 0, 0);
           84  +}
           85  +
           86  +do_execsql_test 4.1 {
           87  +  SELECT a, sum(a) OVER (PARTITION BY b) FROM t2;
           88  +} {
           89  +  0 12  2 12  4 12  6 12   1  9  3  9  5  9 
           90  +}
           91  +
           92  +do_execsql_test 4.2 {
           93  +  SELECT a, sum(a) OVER (PARTITION BY b) FROM t2 ORDER BY a;
           94  +} {
           95  +  0 12  1  9  2 12  3  9  4 12  5  9 6 12   
           96  +}
           97  +
           98  +do_execsql_test 4.3 {
           99  +  SELECT a, sum(a) OVER () FROM t2 ORDER BY a;
          100  +} {
          101  +  0 21  1  21  2 21  3  21  4 21  5  21 6 21   
          102  +}
          103  +
          104  +do_execsql_test 4.4 {
          105  +  SELECT a, sum(a) OVER (ORDER BY a) FROM t2;
          106  +} {
          107  +  0 0  1 1  2 3  3 6  4 10  5 15  6 21
          108  +}
          109  +
          110  +do_execsql_test 4.5 {
          111  +  SELECT a, sum(a) OVER (PARTITION BY b ORDER BY a) FROM t2 ORDER BY a
          112  +} {
          113  +  0 0  1 1  2 2  3 4  4 6  5 9  6 12
          114  +}
          115  +
          116  +do_execsql_test 4.6 {
          117  +  SELECT a, sum(a) OVER (PARTITION BY c ORDER BY a) FROM t2 ORDER BY a
          118  +} {
          119  +  0 0  1 1  2 2  3 3  4 5  5 7  6 9
          120  +}
          121  +
          122  +do_execsql_test 4.7 {
          123  +  SELECT a, sum(a) OVER (PARTITION BY b ORDER BY a DESC) FROM t2 ORDER BY a
          124  +} {
          125  +  0 12  1 9  2 12  3 8  4 10  5 5  6 6
          126  +}
          127  +
          128  +do_execsql_test 4.8 {
          129  +  SELECT a, 
          130  +    sum(a) OVER (PARTITION BY b ORDER BY a DESC),
          131  +    sum(a) OVER (PARTITION BY c ORDER BY a) 
          132  +  FROM t2 ORDER BY a
          133  +} {
          134  +  0  12  0
          135  +  1   9  1 
          136  +  2  12  2 
          137  +  3   8  3 
          138  +  4  10  5 
          139  +  5   5  7 
          140  +  6   6  9
          141  +}
          142  +
          143  +do_execsql_test 4.9 {
          144  +  SELECT a, 
          145  +    sum(a) OVER (ORDER BY a), 
          146  +    avg(a) OVER (ORDER BY a) 
          147  +  FROM t2 ORDER BY a
          148  +} {
          149  +  0  0       0.0
          150  +  1  1       0.5
          151  +  2  3       1.0
          152  +  3  6       1.5
          153  +  4  10      2.0
          154  +  5  15      2.5
          155  +  6  21      3.0
          156  +}
          157  +
          158  +do_execsql_test 4.10.1 {
          159  +  SELECT a, 
          160  +    count() OVER (ORDER BY a DESC),
          161  +    group_concat(a, '.') OVER (ORDER BY a DESC) 
          162  +  FROM t2 ORDER BY a DESC
          163  +} {
          164  +  6 1 6
          165  +  5 2 6.5
          166  +  4 3 6.5.4
          167  +  3 4 6.5.4.3
          168  +  2 5 6.5.4.3.2
          169  +  1 6 6.5.4.3.2.1
          170  +  0 7 6.5.4.3.2.1.0
          171  +}
          172  +
          173  +do_execsql_test 4.10.2 {
          174  +  SELECT a, 
          175  +    count(*) OVER (ORDER BY a DESC),
          176  +    group_concat(a, '.') OVER (ORDER BY a DESC) 
          177  +  FROM t2 ORDER BY a DESC
          178  +} {
          179  +  6 1 6
          180  +  5 2 6.5
          181  +  4 3 6.5.4
          182  +  3 4 6.5.4.3
          183  +  2 5 6.5.4.3.2
          184  +  1 6 6.5.4.3.2.1
          185  +  0 7 6.5.4.3.2.1.0
          186  +}
          187  +
          188  +do_catchsql_test 5.1 {
          189  +  SELECT ntile(0) OVER (ORDER BY a) FROM t2;
          190  +} {1 {argument of ntile must be a positive integer}}
          191  +do_catchsql_test 5.2 {
          192  +  SELECT ntile(-1) OVER (ORDER BY a) FROM t2;
          193  +} {1 {argument of ntile must be a positive integer}}
          194  +do_catchsql_test 5.3 {
          195  +  SELECT ntile('zbc') OVER (ORDER BY a) FROM t2;
          196  +} {1 {argument of ntile must be a positive integer}}
          197  +do_execsql_test 5.4 {
          198  +  CREATE TABLE t4(a, b);
          199  +  SELECT ntile(1) OVER (ORDER BY a) FROM t4;
          200  +} {}
          201  +
          202  +#-------------------------------------------------------------------------
          203  +reset_db
          204  +do_execsql_test 6.1 {
          205  +  CREATE TABLE t1(x);
          206  +  INSERT INTO t1 VALUES(7), (6), (5), (4), (3), (2), (1);
          207  +
          208  +  CREATE TABLE t2(x);
          209  +  INSERT INTO t2 VALUES('b'), ('a');
          210  +
          211  +  SELECT x, count(*) OVER (ORDER BY x) FROM t1;
          212  +} {1 1 2 2 3 3 4 4 5 5 6 6 7 7}
          213  +
          214  +do_execsql_test 6.2 {
          215  +  SELECT * FROM t2, (SELECT x, count(*) OVER (ORDER BY x) FROM t1);
          216  +} {
          217  +  b 1 1 b 2 2 b 3 3 b 4 4 b 5 5 b 6 6 b 7 7
          218  +  a 1 1 a 2 2 a 3 3 a 4 4 a 5 5 a 6 6 a 7 7
          219  +}
          220  +
          221  +do_catchsql_test 6.3 {
          222  +  SELECT x, lag(x) FILTER (WHERE (x%2)=0) OVER w FROM t1 
          223  +  WINDOW w AS (ORDER BY x)
          224  +} {1 {FILTER clause may only be used with aggregate window functions}}
          225  + 
          226  +#-------------------------------------------------------------------------
          227  +# Attempt to use a window function as an aggregate. And other errors.
          228  +#
          229  +reset_db
          230  +do_execsql_test 7.0 {
          231  +  CREATE TABLE t1(x, y);
          232  +  INSERT INTO t1 VALUES(1, 2);
          233  +  INSERT INTO t1 VALUES(3, 4);
          234  +  INSERT INTO t1 VALUES(5, 6);
          235  +  INSERT INTO t1 VALUES(7, 8);
          236  +  INSERT INTO t1 VALUES(9, 10);
          237  +}
          238  +
          239  +do_catchsql_test 7.1.1 {
          240  +  SELECT nth_value(x, 1) FROM t1;
          241  +} {1 {misuse of window function nth_value()}}
          242  +do_catchsql_test 7.1.2 {
          243  +  SELECT * FROM t1 WHERE nth_value(x, 1) OVER (ORDER BY y);
          244  +} {1 {misuse of window function nth_value()}}
          245  +do_catchsql_test 7.1.3 {
          246  +  SELECT count(*) FROM t1 GROUP BY y HAVING nth_value(x, 1) OVER (ORDER BY y);
          247  +} {1 {misuse of window function nth_value()}}
          248  +do_catchsql_test 7.1.4 {
          249  +  SELECT count(*) FROM t1 GROUP BY nth_value(x, 1) OVER (ORDER BY y);
          250  +} {1 {misuse of window function nth_value()}}
          251  +do_catchsql_test 7.1.5 {
          252  +  SELECT count(*) FROM t1 LIMIT nth_value(x, 1) OVER ();
          253  +} {1 {no such column: x}}
          254  +do_catchsql_test 7.1.6 {
          255  +  SELECT trim(x) OVER (ORDER BY y) FROM t1;
          256  +} {1 {trim() may not be used as a window function}}
          257  +do_catchsql_test 7.1.7 {
          258  +  SELECT max(x) OVER abc FROM t1 WINDOW def AS (ORDER BY y);
          259  +} {1 {no such window: abc}}
          260  +
          261  +do_execsql_test 7.2 {
          262  +  SELECT 
          263  +    lead(y) OVER win, 
          264  +    lead(y, 2) OVER win, 
          265  +    lead(y, 3, 'default') OVER win
          266  +  FROM t1
          267  +  WINDOW win AS (ORDER BY x)
          268  +} {
          269  +  4 6 8   6 8 10   8 10 default   10 {} default   {} {} default
          270  +}
          271  +
          272  +do_execsql_test 7.3 {
          273  +  SELECT row_number() OVER (ORDER BY x) FROM t1
          274  +} {1 2 3 4 5}
          275  +
          276  +do_execsql_test 7.4 {
          277  +  SELECT 
          278  +    row_number() OVER win,
          279  +    lead(x) OVER win
          280  +  FROM t1
          281  +  WINDOW win AS (ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          282  +} {1 3  2 5  3 7  4 9   5 {}}
          283  +
          284  +#-------------------------------------------------------------------------
          285  +# Attempt to use a window function in a view.
          286  +#
          287  +do_execsql_test 8.0 {
          288  +  CREATE TABLE t3(a, b, c);
          289  +
          290  +  WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<6 )
          291  +  INSERT INTO t3 SELECT i, i, i FROM s;
          292  +
          293  +  CREATE VIEW v1 AS SELECT
          294  +    sum(b) OVER (ORDER BY c),
          295  +    min(b) OVER (ORDER BY c),
          296  +    max(b) OVER (ORDER BY c)
          297  +  FROM t3;
          298  +
          299  +  CREATE VIEW v2 AS SELECT
          300  +    sum(b) OVER win,
          301  +    min(b) OVER win,
          302  +    max(b) OVER win
          303  +  FROM t3
          304  +  WINDOW win AS (ORDER BY c);
          305  +}
          306  +
          307  +do_execsql_test 8.1.1 {
          308  +  SELECT * FROM v1
          309  +} {1 1 1  3 1 2  6 1 3  10 1 4  15 1 5  21 1 6}
          310  +do_execsql_test 8.1.2 {
          311  +  SELECT * FROM v2
          312  +} {1 1 1  3 1 2  6 1 3  10 1 4  15 1 5  21 1 6}
          313  +
          314  +db close
          315  +sqlite3 db test.db
          316  +do_execsql_test 8.2.1 {
          317  +  SELECT * FROM v1
          318  +} {1 1 1  3 1 2  6 1 3  10 1 4  15 1 5  21 1 6}
          319  +do_execsql_test 8.2.2 {
          320  +  SELECT * FROM v2
          321  +} {1 1 1  3 1 2  6 1 3  10 1 4  15 1 5  21 1 6}
          322  +
          323  +#-------------------------------------------------------------------------
          324  +# Attempt to use a window function in a trigger.
          325  +#
          326  +do_execsql_test 9.0 {
          327  +  CREATE TABLE t4(x, y);
          328  +  INSERT INTO t4 VALUES(1, 'g');
          329  +  INSERT INTO t4 VALUES(2, 'i');
          330  +  INSERT INTO t4 VALUES(3, 'l');
          331  +  INSERT INTO t4 VALUES(4, 'g');
          332  +  INSERT INTO t4 VALUES(5, 'a');
          333  +
          334  +  CREATE TABLE t5(x, y, m);
          335  +  CREATE TRIGGER t4i AFTER INSERT ON t4 BEGIN
          336  +    DELETE FROM t5;
          337  +    INSERT INTO t5 
          338  +      SELECT x, y, max(y) OVER xyz FROM t4
          339  +      WINDOW xyz AS (PARTITION BY (x%2) ORDER BY x);
          340  +  END;
          341  +}
          342  +
          343  +do_execsql_test 9.1.1 {
          344  +  SELECT x, y, max(y) OVER xyz FROM t4
          345  +      WINDOW xyz AS (PARTITION BY (x%2) ORDER BY x) ORDER BY 1
          346  +} {1 g g   2 i i   3 l l   4 g i   5 a l}
          347  +
          348  +do_execsql_test 9.1.2 {
          349  +  INSERT INTO t4 VALUES(6, 'm');
          350  +  SELECT x, y, max(y) OVER xyz FROM t4
          351  +      WINDOW xyz AS (PARTITION BY (x%2) ORDER BY x) ORDER BY 1
          352  +} {1 g g   2 i i   3 l l   4 g i   5 a l   6 m m}
          353  +
          354  +do_execsql_test 9.1.3 {
          355  +  SELECT * FROM t5 ORDER BY 1
          356  +} {1 g g   2 i i   3 l l   4 g i   5 a l   6 m m}
          357  +
          358  +do_execsql_test 9.2 {
          359  +  WITH aaa(x, y, z) AS (
          360  +    SELECT x, y, max(y) OVER xyz FROM t4
          361  +    WINDOW xyz AS (PARTITION BY (x%2) ORDER BY x)
          362  +  )
          363  +  SELECT * FROM aaa ORDER BY 1;
          364  +} {1 g g   2 i i   3 l l   4 g i   5 a l   6 m m}
          365  +
          366  +do_execsql_test 9.3 {
          367  +  WITH aaa(x, y, z) AS (
          368  +    SELECT x, y, max(y) OVER xyz FROM t4
          369  +    WINDOW xyz AS (ORDER BY x)
          370  +  )
          371  +  SELECT *, min(z) OVER (ORDER BY x) FROM aaa ORDER BY 1;
          372  +} {1 g g g   2 i i g   3 l l g   4 g l g   5 a l g   6 m m g}
          373  +
          374  +#-------------------------------------------------------------------------
          375  +#
          376  +do_execsql_test 10.0 {
          377  +  CREATE TABLE sales(emp TEXT PRIMARY KEY, region, total);
          378  +  INSERT INTO sales VALUES
          379  +      ('Alice',     'North', 34),
          380  +      ('Frank',     'South', 22),
          381  +      ('Charles',   'North', 45),
          382  +      ('Darrell',   'South', 8),
          383  +      ('Grant',     'South', 23),
          384  +      ('Brad' ,     'North', 22),
          385  +      ('Elizabeth', 'South', 99),
          386  +      ('Horace',    'East',   1);
          387  +}
          388  +
          389  +# Best two salespeople from each region
          390  +#
          391  +do_execsql_test 10.1 {
          392  +  SELECT emp, region, total FROM (
          393  +    SELECT 
          394  +      emp, region, total,
          395  +      row_number() OVER (PARTITION BY region ORDER BY total DESC) AS rank
          396  +    FROM sales
          397  +  ) WHERE rank<=2 ORDER BY region, total DESC
          398  +} {
          399  +  Horace      East     1
          400  +  Charles     North   45
          401  +  Alice       North   34
          402  +  Elizabeth   South   99
          403  +  Grant       South   23
          404  +}
          405  +
          406  +do_execsql_test 10.2 {
          407  +  SELECT emp, region, sum(total) OVER win FROM sales
          408  +  WINDOW win AS (PARTITION BY region ORDER BY total)
          409  +} {
          410  +  Horace East       1  
          411  +  Brad North       22 
          412  +  Alice North      56 
          413  +  Charles North   101 
          414  +  Darrell South     8 
          415  +  Frank South      30 
          416  +  Grant South      53 
          417  +  Elizabeth South 152
          418  +}
          419  +
          420  +do_execsql_test 10.3 {
          421  +  SELECT emp, region, sum(total) OVER win FROM sales
          422  +  WINDOW win AS (PARTITION BY region ORDER BY total)
          423  +  LIMIT 5
          424  +} {
          425  +  Horace East       1  
          426  +  Brad North       22 
          427  +  Alice North      56 
          428  +  Charles North   101 
          429  +  Darrell South     8 
          430  +}
          431  +
          432  +do_execsql_test 10.4 {
          433  +  SELECT emp, region, sum(total) OVER win FROM sales
          434  +  WINDOW win AS (PARTITION BY region ORDER BY total)
          435  +  LIMIT 5 OFFSET 2
          436  +} {
          437  +  Alice North      56 
          438  +  Charles North   101 
          439  +  Darrell South     8 
          440  +  Frank South      30 
          441  +  Grant South      53 
          442  +}
          443  +
          444  +do_execsql_test 10.5 {
          445  +  SELECT emp, region, sum(total) OVER win FROM sales
          446  +  WINDOW win AS (
          447  +    PARTITION BY region ORDER BY total 
          448  +    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
          449  +  )
          450  +} {
          451  +  Horace East       1  
          452  +  Brad North      101
          453  +  Alice North      79 
          454  +  Charles North    45 
          455  +  Darrell South   152
          456  +  Frank South     144 
          457  +  Grant South     122 
          458  +  Elizabeth South  99
          459  +}
          460  +
          461  +do_execsql_test 10.6 {
          462  +  SELECT emp, region, sum(total) OVER win FROM sales
          463  +  WINDOW win AS (
          464  +    PARTITION BY region ORDER BY total 
          465  +    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
          466  +  ) LIMIT 5 OFFSET 2
          467  +} {
          468  +  Alice North      79 
          469  +  Charles North    45 
          470  +  Darrell South   152
          471  +  Frank South     144 
          472  +  Grant South     122 
          473  +}
          474  +
          475  +do_execsql_test 10.7 {
          476  +  SELECT emp, region, (
          477  +    SELECT sum(total) OVER (
          478  +      ORDER BY total RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
          479  +    ) || outer.emp FROM sales
          480  +  ) FROM sales AS outer;
          481  +} {
          482  +  Alice North 254Alice 
          483  +  Frank South 254Frank 
          484  +  Charles North 254Charles 
          485  +  Darrell South 254Darrell 
          486  +  Grant South 254Grant 
          487  +  Brad North 254Brad 
          488  +  Elizabeth South 254Elizabeth 
          489  +  Horace East 254Horace
          490  +}
          491  +
          492  +do_execsql_test 10.8 {
          493  +  SELECT emp, region, (
          494  +    SELECT sum(total) FILTER (WHERE sales.emp!=outer.emp) OVER (
          495  +      ORDER BY total RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
          496  +    ) FROM sales
          497  +  ) FROM sales AS outer;
          498  +} {
          499  +  Alice North 220 
          500  +  Frank South 232 
          501  +  Charles North 209 
          502  +  Darrell South 246
          503  +  Grant South 231 
          504  +  Brad North 232 
          505  +  Elizabeth South 155 
          506  +  Horace East 253
          507  +}
          508  +
          509  +#-------------------------------------------------------------------------
          510  +# Check that it is not possible to use a window function in a CREATE INDEX
          511  +# statement.
          512  +#
          513  +do_execsql_test 11.0 { CREATE TABLE t6(a, b, c); }
          514  +
          515  +do_catchsql_test 11.1 {
          516  +  CREATE INDEX t6i ON t6(a) WHERE sum(b) OVER ();
          517  +} {1 {misuse of window function sum()}}
          518  +do_catchsql_test 11.2 {
          519  +  CREATE INDEX t6i ON t6(a) WHERE lead(b) OVER ();
          520  +} {1 {misuse of window function lead()}}
          521  +
          522  +do_catchsql_test 11.3 {
          523  +  CREATE INDEX t6i ON t6(sum(b) OVER ());
          524  +} {1 {misuse of window function sum()}}
          525  +do_catchsql_test 11.4 {
          526  +  CREATE INDEX t6i ON t6(lead(b) OVER ());
          527  +} {1 {misuse of window function lead()}}
          528  +
          529  +finish_test
          530  +

Added test/window2.tcl.

            1  +# 2018 May 19
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +
           13  +source [file join [file dirname $argv0] pg_common.tcl]
           14  +
           15  +#=========================================================================
           16  +
           17  +
           18  +start_test window2 "2018 May 19"
           19  +
           20  +ifcapable !windowfunc
           21  +
           22  +execsql_test 1.0 {
           23  +  DROP TABLE IF EXISTS t1;
           24  +  CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c TEXT, d INTEGER);
           25  +  INSERT INTO t1 VALUES(1, 'odd',  'one',   1);
           26  +  INSERT INTO t1 VALUES(2, 'even', 'two',   2);
           27  +  INSERT INTO t1 VALUES(3, 'odd',  'three', 3);
           28  +  INSERT INTO t1 VALUES(4, 'even', 'four',  4);
           29  +  INSERT INTO t1 VALUES(5, 'odd',  'five',  5);
           30  +  INSERT INTO t1 VALUES(6, 'even', 'six',   6);
           31  +}
           32  +
           33  +execsql_test 1.1 {
           34  +  SELECT c, sum(d) OVER (PARTITION BY b ORDER BY c) FROM t1;
           35  +}
           36  +
           37  +execsql_test 1.2 {
           38  +  SELECT sum(d) OVER () FROM t1;
           39  +}
           40  +
           41  +execsql_test 1.3 {
           42  +  SELECT sum(d) OVER (PARTITION BY b) FROM t1;
           43  +}
           44  +
           45  +==========
           46  +execsql_test 2.1 {
           47  +  SELECT a, sum(d) OVER (
           48  +    ORDER BY d
           49  +    ROWS BETWEEN 1000 PRECEDING AND 1 FOLLOWING
           50  +  ) FROM t1
           51  +}
           52  +execsql_test 2.2 {
           53  +  SELECT a, sum(d) OVER (
           54  +    ORDER BY d
           55  +    ROWS BETWEEN 1000 PRECEDING AND 1000 FOLLOWING
           56  +  ) FROM t1
           57  +}
           58  +execsql_test 2.3 {
           59  +  SELECT a, sum(d) OVER (
           60  +    ORDER BY d
           61  +    ROWS BETWEEN 1 PRECEDING AND 1000 FOLLOWING
           62  +  ) FROM t1
           63  +}
           64  +execsql_test 2.4 {
           65  +  SELECT a, sum(d) OVER (
           66  +    ORDER BY d
           67  +    ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
           68  +  ) FROM t1
           69  +}
           70  +execsql_test 2.5 {
           71  +  SELECT a, sum(d) OVER (
           72  +    ORDER BY d
           73  +    ROWS BETWEEN 1 PRECEDING AND 0 FOLLOWING
           74  +  ) FROM t1
           75  +}
           76  +
           77  +execsql_test 2.6 {
           78  +  SELECT a, sum(d) OVER (
           79  +    PARTITION BY b
           80  +    ORDER BY d 
           81  +    ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
           82  +  ) FROM t1
           83  +}
           84  +
           85  +execsql_test 2.7 {
           86  +  SELECT a, sum(d) OVER (
           87  +    PARTITION BY b
           88  +    ORDER BY d 
           89  +    ROWS BETWEEN 0 PRECEDING AND 0 FOLLOWING
           90  +  ) FROM t1
           91  +}
           92  +
           93  +execsql_test 2.8 {
           94  +  SELECT a, sum(d) OVER (
           95  +    ORDER BY d 
           96  +    ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING
           97  +  ) FROM t1
           98  +}
           99  +
          100  +execsql_test 2.9 {
          101  +  SELECT a, sum(d) OVER (
          102  +    ORDER BY d 
          103  +    ROWS BETWEEN UNBOUNDED PRECEDING AND 2 FOLLOWING
          104  +  ) FROM t1
          105  +}
          106  +
          107  +execsql_test 2.10 {
          108  +  SELECT a, sum(d) OVER (
          109  +    ORDER BY d 
          110  +    ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING
          111  +  ) FROM t1
          112  +}
          113  +
          114  +execsql_test 2.11 {
          115  +  SELECT a, sum(d) OVER (
          116  +    ORDER BY d 
          117  +    ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
          118  +  ) FROM t1
          119  +}
          120  +
          121  +execsql_test 2.13 {
          122  +  SELECT a, sum(d) OVER (
          123  +    ORDER BY d 
          124  +    ROWS BETWEEN 2 PRECEDING AND UNBOUNDED FOLLOWING
          125  +  ) FROM t1
          126  +}
          127  +
          128  +execsql_test 2.14 {
          129  +  SELECT a, sum(d) OVER (
          130  +    ORDER BY d 
          131  +    ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING
          132  +  ) FROM t1
          133  +}
          134  +
          135  +execsql_test 2.15 {
          136  +  SELECT a, sum(d) OVER (
          137  +    PARTITION BY b
          138  +    ORDER BY d 
          139  +    ROWS BETWEEN 1 PRECEDING AND 0 PRECEDING
          140  +  ) FROM t1
          141  +}
          142  +
          143  +execsql_test 2.16 {
          144  +  SELECT a, sum(d) OVER (
          145  +    PARTITION BY b
          146  +    ORDER BY d 
          147  +    ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING
          148  +  ) FROM t1
          149  +}
          150  +
          151  +execsql_test 2.17 {
          152  +  SELECT a, sum(d) OVER (
          153  +    PARTITION BY b
          154  +    ORDER BY d 
          155  +    ROWS BETWEEN 1 PRECEDING AND 2 PRECEDING
          156  +  ) FROM t1
          157  +}
          158  +
          159  +execsql_test 2.18 {
          160  +  SELECT a, sum(d) OVER (
          161  +    PARTITION BY b
          162  +    ORDER BY d 
          163  +    ROWS BETWEEN UNBOUNDED PRECEDING AND 2 PRECEDING
          164  +  ) FROM t1
          165  +}
          166  +
          167  +execsql_test 2.19 {
          168  +  SELECT a, sum(d) OVER (
          169  +    PARTITION BY b
          170  +    ORDER BY d 
          171  +    ROWS BETWEEN 1 FOLLOWING AND 3 FOLLOWING
          172  +  ) FROM t1
          173  +}
          174  +
          175  +execsql_test 2.20 {
          176  +  SELECT a, sum(d) OVER (
          177  +    ORDER BY d 
          178  +    ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING
          179  +  ) FROM t1
          180  +}
          181  +
          182  +execsql_test 2.21 {
          183  +  SELECT a, sum(d) OVER (
          184  +    ORDER BY d 
          185  +    ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING
          186  +  ) FROM t1
          187  +}
          188  +
          189  +execsql_test 2.22 {
          190  +  SELECT a, sum(d) OVER (
          191  +    PARTITION BY b
          192  +    ORDER BY d 
          193  +    ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING
          194  +  ) FROM t1
          195  +}
          196  +
          197  +execsql_test 2.23 {
          198  +  SELECT a, sum(d) OVER (
          199  +    ORDER BY d 
          200  +    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
          201  +  ) FROM t1
          202  +}
          203  +
          204  +execsql_test 2.24 {
          205  +  SELECT a, sum(d) OVER (
          206  +    PARTITION BY a%2
          207  +    ORDER BY d 
          208  +    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
          209  +  ) FROM t1
          210  +}
          211  +
          212  +execsql_test 2.25 {
          213  +  SELECT a, sum(d) OVER (
          214  +    ORDER BY d 
          215  +    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
          216  +  ) FROM t1
          217  +}
          218  +
          219  +execsql_test 2.26 {
          220  +  SELECT a, sum(d) OVER (
          221  +    PARTITION BY b
          222  +    ORDER BY d 
          223  +    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
          224  +  ) FROM t1
          225  +}
          226  +
          227  +execsql_test 2.27 {
          228  +  SELECT a, sum(d) OVER (
          229  +    ORDER BY d 
          230  +    ROWS BETWEEN CURRENT ROW AND CURRENT ROW
          231  +  ) FROM t1
          232  +}
          233  +
          234  +execsql_test 2.28 {
          235  +  SELECT a, sum(d) OVER (
          236  +    PARTITION BY b
          237  +    ORDER BY d 
          238  +    ROWS BETWEEN CURRENT ROW AND CURRENT ROW
          239  +  ) FROM t1
          240  +}
          241  +
          242  +execsql_test 2.29 {
          243  +  SELECT a, sum(d) OVER (
          244  +    ORDER BY d 
          245  +    RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
          246  +  ) FROM t1
          247  +}
          248  +execsql_test 2.30 {
          249  +  SELECT a, sum(d) OVER (
          250  +    ORDER BY b 
          251  +    RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
          252  +  ) FROM t1
          253  +}
          254  +
          255  +execsql_test 3.1 {
          256  +  SELECT a, sum(d) OVER (
          257  +    PARTITION BY b ORDER BY d
          258  +    RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
          259  +  ) FROM t1
          260  +}
          261  +
          262  +execsql_test 3.2 {
          263  +  SELECT a, sum(d) OVER (
          264  +    ORDER BY b
          265  +    RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
          266  +  ) FROM t1
          267  +}
          268  +
          269  +execsql_test 3.3 {
          270  +  SELECT a, sum(d) OVER (
          271  +    ORDER BY d
          272  +    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
          273  +  ) FROM t1
          274  +}
          275  +
          276  +execsql_test 3.4 {
          277  +  SELECT a, sum(d) OVER (
          278  +    ORDER BY d/2
          279  +    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
          280  +  ) FROM t1
          281  +}
          282  +
          283  +#puts $::fd finish_test
          284  +
          285  +==========
          286  +
          287  +execsql_test 4.0 {
          288  +  DROP TABLE IF EXISTS t2;
          289  +  CREATE TABLE t2(a INTEGER PRIMARY KEY, b INTEGER);
          290  +  INSERT INTO t2(a, b) VALUES
          291  +  (1,0), (2,74), (3,41), (4,74), (5,23), (6,99), (7,26), (8,33), (9,2),
          292  +  (10,89), (11,81), (12,96), (13,59), (14,38), (15,68), (16,39), (17,62),
          293  +  (18,91), (19,46), (20,6), (21,99), (22,97), (23,27), (24,46), (25,78),
          294  +  (26,54), (27,97), (28,8), (29,67), (30,29), (31,93), (32,84), (33,77),
          295  +  (34,23), (35,16), (36,16), (37,93), (38,65), (39,35), (40,47), (41,7),
          296  +  (42,86), (43,74), (44,61), (45,91), (46,85), (47,24), (48,85), (49,43),
          297  +  (50,59), (51,12), (52,32), (53,56), (54,3), (55,91), (56,22), (57,90),
          298  +  (58,55), (59,15), (60,28), (61,89), (62,25), (63,47), (64,1), (65,56),
          299  +  (66,40), (67,43), (68,56), (69,16), (70,75), (71,36), (72,89), (73,98),
          300  +  (74,76), (75,81), (76,4), (77,94), (78,42), (79,30), (80,78), (81,33),
          301  +  (82,29), (83,53), (84,63), (85,2), (86,87), (87,37), (88,80), (89,84),
          302  +  (90,72), (91,41), (92,9), (93,61), (94,73), (95,95), (96,65), (97,13),
          303  +  (98,58), (99,96), (100,98), (101,1), (102,21), (103,74), (104,65), (105,35),
          304  +  (106,5), (107,73), (108,11), (109,51), (110,87), (111,41), (112,12), (113,8),
          305  +  (114,20), (115,31), (116,31), (117,15), (118,95), (119,22), (120,73), 
          306  +  (121,79), (122,88), (123,34), (124,8), (125,11), (126,49), (127,34), 
          307  +  (128,90), (129,59), (130,96), (131,60), (132,55), (133,75), (134,77),
          308  +  (135,44), (136,2), (137,7), (138,85), (139,57), (140,74), (141,29), (142,70),
          309  +  (143,59), (144,19), (145,39), (146,26), (147,26), (148,47), (149,80),
          310  +  (150,90), (151,36), (152,58), (153,47), (154,9), (155,72), (156,72), (157,66),
          311  +  (158,33), (159,93), (160,75), (161,64), (162,81), (163,9), (164,23), (165,37),
          312  +  (166,13), (167,12), (168,14), (169,62), (170,91), (171,36), (172,91),
          313  +  (173,33), (174,15), (175,34), (176,36), (177,99), (178,3), (179,95), (180,69),
          314  +  (181,58), (182,52), (183,30), (184,50), (185,84), (186,10), (187,84),
          315  +  (188,33), (189,21), (190,39), (191,44), (192,58), (193,30), (194,38),
          316  +  (195,34), (196,83), (197,27), (198,82), (199,17), (200,7);
          317  +}
          318  +
          319  +execsql_test 4.1 {
          320  +  SELECT a, sum(b) OVER (
          321  +    PARTITION BY (b%10)
          322  +    ORDER BY b
          323  +  ) FROM t2 ORDER BY a;
          324  +}
          325  +
          326  +execsql_test 4.2 {
          327  +  SELECT a, sum(b) OVER (
          328  +    PARTITION BY (b%10)
          329  +    ORDER BY b
          330  +    RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
          331  +  ) FROM t2 ORDER BY a;
          332  +}
          333  +
          334  +execsql_test 4.3 {
          335  +  SELECT b, sum(b) OVER (
          336  +    ORDER BY b
          337  +    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
          338  +  ) FROM t2 ORDER BY b;
          339  +}
          340  +
          341  +execsql_test 4.4 {
          342  +  SELECT b, sum(b) OVER (
          343  +    ORDER BY b
          344  +    RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
          345  +  ) FROM t2 ORDER BY b;
          346  +}
          347  +
          348  +execsql_test 4.5 {
          349  +  SELECT b, sum(b) OVER (
          350  +    ORDER BY b
          351  +    RANGE BETWEEN CURRENT ROW AND CURRENT ROW
          352  +  ) FROM t2 ORDER BY b;
          353  +}
          354  +
          355  +execsql_test 4.6.1 {
          356  +  SELECT b, sum(b) OVER (
          357  +    RANGE BETWEEN CURRENT ROW AND CURRENT ROW
          358  +  ) FROM t2 ORDER BY b;
          359  +}
          360  +execsql_test 4.6.2 {
          361  +  SELECT b, sum(b) OVER () FROM t2 ORDER BY b;
          362  +}
          363  +execsql_test 4.6.3 {
          364  +  SELECT b, sum(b) OVER (
          365  +    RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
          366  +  ) FROM t2 ORDER BY b;
          367  +}
          368  +execsql_test 4.6.4 {
          369  +  SELECT b, sum(b) OVER (
          370  +    RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
          371  +  ) FROM t2 ORDER BY b;
          372  +}
          373  +
          374  +execsql_test 4.7.1 {
          375  +  SELECT b, sum(b) OVER (
          376  +    ROWS BETWEEN CURRENT ROW AND CURRENT ROW
          377  +  ) FROM t2 ORDER BY 1, 2;
          378  +}
          379  +execsql_test 4.7.2 {
          380  +  SELECT b, sum(b) OVER (
          381  +    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
          382  +  ) FROM t2 ORDER BY 1, 2;
          383  +}
          384  +execsql_test 4.7.3 {
          385  +  SELECT b, sum(b) OVER (
          386  +    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
          387  +  ) FROM t2 ORDER BY 1, 2;
          388  +}
          389  +execsql_test 4.7.4 {
          390  +  SELECT b, sum(b) OVER (
          391  +    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
          392  +  ) FROM t2 ORDER BY 1, 2;
          393  +}
          394  +
          395  +execsql_test 4.8.1 {
          396  +  SELECT b, sum(b) OVER (
          397  +    ORDER BY a
          398  +    ROWS BETWEEN CURRENT ROW AND CURRENT ROW
          399  +  ) FROM t2 ORDER BY 1, 2;
          400  +}
          401  +execsql_test 4.8.2 {
          402  +  SELECT b, sum(b) OVER (
          403  +    ORDER BY a
          404  +    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
          405  +  ) FROM t2 ORDER BY 1, 2;
          406  +}
          407  +execsql_test 4.8.3 {
          408  +  SELECT b, sum(b) OVER (
          409  +    ORDER BY a
          410  +    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
          411  +  ) FROM t2 ORDER BY 1, 2;
          412  +}
          413  +execsql_test 4.8.4 {
          414  +  SELECT b, sum(b) OVER (
          415  +    ORDER BY a
          416  +    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
          417  +  ) FROM t2 ORDER BY 1, 2;
          418  +}
          419  +
          420  +
          421  +
          422  +finish_test
          423  +
          424  +

Added test/window2.test.

            1  +# 2018 May 19
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +# This file implements regression tests for SQLite library.
           12  +#
           13  +
           14  +####################################################
           15  +# DO NOT EDIT! THIS FILE IS AUTOMATICALLY GENERATED!
           16  +####################################################
           17  +
           18  +set testdir [file dirname $argv0]
           19  +source $testdir/tester.tcl
           20  +set testprefix window2
           21  +
           22  +ifcapable !windowfunc { finish_test ; return }
           23  +do_execsql_test 1.0 {
           24  +  DROP TABLE IF EXISTS t1;
           25  +  CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c TEXT, d INTEGER);
           26  +  INSERT INTO t1 VALUES(1, 'odd',  'one',   1);
           27  +  INSERT INTO t1 VALUES(2, 'even', 'two',   2);
           28  +  INSERT INTO t1 VALUES(3, 'odd',  'three', 3);
           29  +  INSERT INTO t1 VALUES(4, 'even', 'four',  4);
           30  +  INSERT INTO t1 VALUES(5, 'odd',  'five',  5);
           31  +  INSERT INTO t1 VALUES(6, 'even', 'six',   6);
           32  +} {}
           33  +
           34  +do_execsql_test 1.1 {
           35  +  SELECT c, sum(d) OVER (PARTITION BY b ORDER BY c) FROM t1;
           36  +} {four 4   six 10   two 12   five 5   one 6   three 9}
           37  +
           38  +do_execsql_test 1.2 {
           39  +  SELECT sum(d) OVER () FROM t1;
           40  +} {21   21   21   21   21   21}
           41  +
           42  +do_execsql_test 1.3 {
           43  +  SELECT sum(d) OVER (PARTITION BY b) FROM t1;
           44  +} {12   12   12   9   9   9}
           45  +
           46  +#==========================================================================
           47  +
           48  +do_execsql_test 2.1 {
           49  +  SELECT a, sum(d) OVER (
           50  +    ORDER BY d
           51  +    ROWS BETWEEN 1000 PRECEDING AND 1 FOLLOWING
           52  +  ) FROM t1
           53  +} {1 3   2 6   3 10   4 15   5 21   6 21}
           54  +
           55  +do_execsql_test 2.2 {
           56  +  SELECT a, sum(d) OVER (
           57  +    ORDER BY d
           58  +    ROWS BETWEEN 1000 PRECEDING AND 1000 FOLLOWING
           59  +  ) FROM t1
           60  +} {1 21   2 21   3 21   4 21   5 21   6 21}
           61  +
           62  +do_execsql_test 2.3 {
           63  +  SELECT a, sum(d) OVER (
           64  +    ORDER BY d
           65  +    ROWS BETWEEN 1 PRECEDING AND 1000 FOLLOWING
           66  +  ) FROM t1
           67  +} {1 21   2 21   3 20   4 18   5 15   6 11}
           68  +
           69  +do_execsql_test 2.4 {
           70  +  SELECT a, sum(d) OVER (
           71  +    ORDER BY d
           72  +    ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
           73  +  ) FROM t1
           74  +} {1 3   2 6   3 9   4 12   5 15   6 11}
           75  +
           76  +do_execsql_test 2.5 {
           77  +  SELECT a, sum(d) OVER (
           78  +    ORDER BY d
           79  +    ROWS BETWEEN 1 PRECEDING AND 0 FOLLOWING
           80  +  ) FROM t1
           81  +} {1 1   2 3   3 5   4 7   5 9   6 11}
           82  +
           83  +do_execsql_test 2.6 {
           84  +  SELECT a, sum(d) OVER (
           85  +    PARTITION BY b
           86  +    ORDER BY d 
           87  +    ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
           88  +  ) FROM t1
           89  +} {2 6   4 12   6 10   1 4   3 9   5 8}
           90  +
           91  +do_execsql_test 2.7 {
           92  +  SELECT a, sum(d) OVER (
           93  +    PARTITION BY b
           94  +    ORDER BY d 
           95  +    ROWS BETWEEN 0 PRECEDING AND 0 FOLLOWING
           96  +  ) FROM t1
           97  +} {2 2   4 4   6 6   1 1   3 3   5 5}
           98  +
           99  +do_execsql_test 2.8 {
          100  +  SELECT a, sum(d) OVER (
          101  +    ORDER BY d 
          102  +    ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING
          103  +  ) FROM t1
          104  +} {1 6   2 9   3 12   4 15   5 11   6 6}
          105  +
          106  +do_execsql_test 2.9 {
          107  +  SELECT a, sum(d) OVER (
          108  +    ORDER BY d 
          109  +    ROWS BETWEEN UNBOUNDED PRECEDING AND 2 FOLLOWING
          110  +  ) FROM t1
          111  +} {1 6   2 10   3 15   4 21   5 21   6 21}
          112  +
          113  +do_execsql_test 2.10 {
          114  +  SELECT a, sum(d) OVER (
          115  +    ORDER BY d 
          116  +    ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING
          117  +  ) FROM t1
          118  +} {1 6   2 9   3 12   4 15   5 11   6 6}
          119  +
          120  +do_execsql_test 2.11 {
          121  +  SELECT a, sum(d) OVER (
          122  +    ORDER BY d 
          123  +    ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
          124  +  ) FROM t1
          125  +} {1 1   2 3   3 6   4 9   5 12   6 15}
          126  +
          127  +do_execsql_test 2.13 {
          128  +  SELECT a, sum(d) OVER (
          129  +    ORDER BY d 
          130  +    ROWS BETWEEN 2 PRECEDING AND UNBOUNDED FOLLOWING
          131  +  ) FROM t1
          132  +} {1 21   2 21   3 21   4 20   5 18   6 15}
          133  +
          134  +do_execsql_test 2.14 {
          135  +  SELECT a, sum(d) OVER (
          136  +    ORDER BY d 
          137  +    ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING
          138  +  ) FROM t1
          139  +} {1 {}   2 1   3 3   4 6   5 9   6 12}
          140  +
          141  +do_execsql_test 2.15 {
          142  +  SELECT a, sum(d) OVER (
          143  +    PARTITION BY b
          144  +    ORDER BY d 
          145  +    ROWS BETWEEN 1 PRECEDING AND 0 PRECEDING
          146  +  ) FROM t1
          147  +} {2 2   4 6   6 10   1 1   3 4   5 8}
          148  +
          149  +do_execsql_test 2.16 {
          150  +  SELECT a, sum(d) OVER (
          151  +    PARTITION BY b
          152  +    ORDER BY d 
          153  +    ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING
          154  +  ) FROM t1
          155  +} {2 {}   4 2   6 4   1 {}   3 1   5 3}
          156  +
          157  +do_execsql_test 2.17 {
          158  +  SELECT a, sum(d) OVER (
          159  +    PARTITION BY b
          160  +    ORDER BY d 
          161  +    ROWS BETWEEN 1 PRECEDING AND 2 PRECEDING
          162  +  ) FROM t1
          163  +} {2 {}   4 {}   6 {}   1 {}   3 {}   5 {}}
          164  +
          165  +do_execsql_test 2.18 {
          166  +  SELECT a, sum(d) OVER (
          167  +    PARTITION BY b
          168  +    ORDER BY d 
          169  +    ROWS BETWEEN UNBOUNDED PRECEDING AND 2 PRECEDING
          170  +  ) FROM t1
          171  +} {2 {}   4 {}   6 2   1 {}   3 {}   5 1}
          172  +
          173  +do_execsql_test 2.19 {
          174  +  SELECT a, sum(d) OVER (
          175  +    PARTITION BY b
          176  +    ORDER BY d 
          177  +    ROWS BETWEEN 1 FOLLOWING AND 3 FOLLOWING
          178  +  ) FROM t1
          179  +} {2 10   4 6   6 {}   1 8   3 5   5 {}}
          180  +
          181  +do_execsql_test 2.20 {
          182  +  SELECT a, sum(d) OVER (
          183  +    ORDER BY d 
          184  +    ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING
          185  +  ) FROM t1
          186  +} {1 5   2 7   3 9   4 11   5 6   6 {}}
          187  +
          188  +do_execsql_test 2.21 {
          189  +  SELECT a, sum(d) OVER (
          190  +    ORDER BY d 
          191  +    ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING
          192  +  ) FROM t1
          193  +} {1 20   2 18   3 15   4 11   5 6   6 {}}
          194  +
          195  +do_execsql_test 2.22 {
          196  +  SELECT a, sum(d) OVER (
          197  +    PARTITION BY b
          198  +    ORDER BY d 
          199  +    ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING
          200  +  ) FROM t1
          201  +} {2 10   4 6   6 {}   1 8   3 5   5 {}}
          202  +
          203  +do_execsql_test 2.23 {
          204  +  SELECT a, sum(d) OVER (
          205  +    ORDER BY d 
          206  +    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
          207  +  ) FROM t1
          208  +} {1 21   2 20   3 18   4 15   5 11   6 6}
          209  +
          210  +do_execsql_test 2.24 {
          211  +  SELECT a, sum(d) OVER (
          212  +    PARTITION BY a%2
          213  +    ORDER BY d 
          214  +    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
          215  +  ) FROM t1
          216  +} {2 12   4 10   6 6   1 9   3 8   5 5}
          217  +
          218  +do_execsql_test 2.25 {
          219  +  SELECT a, sum(d) OVER (
          220  +    ORDER BY d 
          221  +    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
          222  +  ) FROM t1
          223  +} {1 21   2 21   3 21   4 21   5 21   6 21}
          224  +
          225  +do_execsql_test 2.26 {
          226  +  SELECT a, sum(d) OVER (
          227  +    PARTITION BY b
          228  +    ORDER BY d 
          229  +    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
          230  +  ) FROM t1
          231  +} {2 12   4 12   6 12   1 9   3 9   5 9}
          232  +
          233  +do_execsql_test 2.27 {
          234  +  SELECT a, sum(d) OVER (
          235  +    ORDER BY d 
          236  +    ROWS BETWEEN CURRENT ROW AND CURRENT ROW
          237  +  ) FROM t1
          238  +} {1 1   2 2   3 3   4 4   5 5   6 6}
          239  +
          240  +do_execsql_test 2.28 {
          241  +  SELECT a, sum(d) OVER (
          242  +    PARTITION BY b
          243  +    ORDER BY d 
          244  +    ROWS BETWEEN CURRENT ROW AND CURRENT ROW
          245  +  ) FROM t1
          246  +} {2 2   4 4   6 6   1 1   3 3   5 5}
          247  +
          248  +do_execsql_test 2.29 {
          249  +  SELECT a, sum(d) OVER (
          250  +    ORDER BY d 
          251  +    RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
          252  +  ) FROM t1
          253  +} {1 21   2 20   3 18   4 15   5 11   6 6}
          254  +
          255  +do_execsql_test 2.30 {
          256  +  SELECT a, sum(d) OVER (
          257  +    ORDER BY b 
          258  +    RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
          259  +  ) FROM t1
          260  +} {2 21   4 21   6 21   1 9   3 9   5 9}
          261  +
          262  +do_execsql_test 3.1 {
          263  +  SELECT a, sum(d) OVER (
          264  +    PARTITION BY b ORDER BY d
          265  +    RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
          266  +  ) FROM t1
          267  +} {2 12   4 10   6 6   1 9   3 8   5 5}
          268  +
          269  +do_execsql_test 3.2 {
          270  +  SELECT a, sum(d) OVER (
          271  +    ORDER BY b
          272  +    RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
          273  +  ) FROM t1
          274  +} {2 21   4 21   6 21   1 9   3 9   5 9}
          275  +
          276  +do_execsql_test 3.3 {
          277  +  SELECT a, sum(d) OVER (
          278  +    ORDER BY d
          279  +    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
          280  +  ) FROM t1
          281  +} {1 21   2 21   3 21   4 21   5 21   6 21}
          282  +
          283  +do_execsql_test 3.4 {
          284  +  SELECT a, sum(d) OVER (
          285  +    ORDER BY d/2
          286  +    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
          287  +  ) FROM t1
          288  +} {1 1   2 3   3 6   4 10   5 15   6 21}
          289  +
          290  +#==========================================================================
          291  +
          292  +do_execsql_test 4.0 {
          293  +  DROP TABLE IF EXISTS t2;
          294  +  CREATE TABLE t2(a INTEGER PRIMARY KEY, b INTEGER);
          295  +  INSERT INTO t2(a, b) VALUES
          296  +  (1,0), (2,74), (3,41), (4,74), (5,23), (6,99), (7,26), (8,33), (9,2),
          297  +  (10,89), (11,81), (12,96), (13,59), (14,38), (15,68), (16,39), (17,62),
          298  +  (18,91), (19,46), (20,6), (21,99), (22,97), (23,27), (24,46), (25,78),
          299  +  (26,54), (27,97), (28,8), (29,67), (30,29), (31,93), (32,84), (33,77),
          300  +  (34,23), (35,16), (36,16), (37,93), (38,65), (39,35), (40,47), (41,7),
          301  +  (42,86), (43,74), (44,61), (45,91), (46,85), (47,24), (48,85), (49,43),
          302  +  (50,59), (51,12), (52,32), (53,56), (54,3), (55,91), (56,22), (57,90),
          303  +  (58,55), (59,15), (60,28), (61,89), (62,25), (63,47), (64,1), (65,56),
          304  +  (66,40), (67,43), (68,56), (69,16), (70,75), (71,36), (72,89), (73,98),
          305  +  (74,76), (75,81), (76,4), (77,94), (78,42), (79,30), (80,78), (81,33),
          306  +  (82,29), (83,53), (84,63), (85,2), (86,87), (87,37), (88,80), (89,84),
          307  +  (90,72), (91,41), (92,9), (93,61), (94,73), (95,95), (96,65), (97,13),
          308  +  (98,58), (99,96), (100,98), (101,1), (102,21), (103,74), (104,65), (105,35),
          309  +  (106,5), (107,73), (108,11), (109,51), (110,87), (111,41), (112,12), (113,8),
          310  +  (114,20), (115,31), (116,31), (117,15), (118,95), (119,22), (120,73), 
          311  +  (121,79), (122,88), (123,34), (124,8), (125,11), (126,49), (127,34), 
          312  +  (128,90), (129,59), (130,96), (131,60), (132,55), (133,75), (134,77),
          313  +  (135,44), (136,2), (137,7), (138,85), (139,57), (140,74), (141,29), (142,70),
          314  +  (143,59), (144,19), (145,39), (146,26), (147,26), (148,47), (149,80),
          315  +  (150,90), (151,36), (152,58), (153,47), (154,9), (155,72), (156,72), (157,66),
          316  +  (158,33), (159,93), (160,75), (161,64), (162,81), (163,9), (164,23), (165,37),
          317  +  (166,13), (167,12), (168,14), (169,62), (170,91), (171,36), (172,91),
          318  +  (173,33), (174,15), (175,34), (176,36), (177,99), (178,3), (179,95), (180,69),
          319  +  (181,58), (182,52), (183,30), (184,50), (185,84), (186,10), (187,84),
          320  +  (188,33), (189,21), (190,39), (191,44), (192,58), (193,30), (194,38),
          321  +  (195,34), (196,83), (197,27), (198,82), (199,17), (200,7);
          322  +} {}
          323  +
          324  +do_execsql_test 4.1 {
          325  +  SELECT a, sum(b) OVER (
          326  +    PARTITION BY (b%10)
          327  +    ORDER BY b
          328  +  ) FROM t2 ORDER BY a;
          329  +} {1 0   2 754   3 251   4 754   5 101   6 1247   7 132   8 266   9 6   10 950   11 667   12 1052   13 535   14 128   15 428   16 250   17 336   18 1122   19 368   20 6   21 1247   22 1000   23 92   24 368   25 584   26 320   27 1000   28 24   29 478   30 133   31 1049   32 1090   33 632   34 101   35 54   36 54   37 1049   38 450   39 145   40 354   41 21   42 764   43 754   44 424   45 1122   46 930   47 42   48 930   49 352   50 535   51 42   52 118   53 536   54 6   55 1122   56 86   57 770   58 255   59 50   60 52   61 950   62 75   63 354   64 2   65 536   66 160   67 352   68 536   69 54   70 675   71 276   72 950   73 868   74 678   75 667   76 4   77 1184   78 160   79 120   80 584   81 266   82 133   83 405   84 468   85 6   86 806   87 166   88 500   89 1090   90 552   91 251   92 27   93 424   94 687   95 1215   96 450   97 32   98 360   99 1052   100 868   101 2   102 66   103 754   104 450   105 145   106 5   107 687   108 24   109 302   110 806   111 251   112 42   113 24   114 30   115 128   116 128   117 50   118 1215   119 86   120 687   121 683   122 672   123 178   124 24   125 24   126 299   127 178   128 770   129 535   130 1052   131 270   132 255   133 675   134 632   135 266   136 6   137 21   138 930   139 411   140 754   141 133   142 340   143 535   144 46   145 250   146 132   147 132   148 354   149 500   150 770   151 276   152 360   153 354   154 27   155 552   156 552   157 602   158 266   159 1049   160 675   161 384   162 667   163 27   164 101   165 166   166 32   167 42   168 18   169 336   170 1122   171 276   172 1122   173 266   174 50   175 178   176 276   177 1247   178 6   179 1215   180 604   181 360   182 212   183 120   184 210   185 1090   186 10   187 1090   188 266   189 66   190 250   191 266   192 360   193 120   194 128   195 178   196 770   197 92   198 634   199 38   200 21}
          330  +
          331  +do_execsql_test 4.2 {
          332  +  SELECT a, sum(b) OVER (
          333  +    PARTITION BY (b%10)
          334  +    ORDER BY b
          335  +    RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
          336  +  ) FROM t2 ORDER BY a;
          337  +} {1 0   2 754   3 251   4 754   5 101   6 1247   7 132   8 266   9 6   10 950   11 667   12 1052   13 535   14 128   15 428   16 250   17 336   18 1122   19 368   20 6   21 1247   22 1000   23 92   24 368   25 584   26 320   27 1000   28 24   29 478   30 133   31 1049   32 1090   33 632   34 101   35 54   36 54   37 1049   38 450   39 145   40 354   41 21   42 764   43 754   44 424   45 1122   46 930   47 42   48 930   49 352   50 535   51 42   52 118   53 536   54 6   55 1122   56 86   57 770   58 255   59 50   60 52   61 950   62 75   63 354   64 2   65 536   66 160   67 352   68 536   69 54   70 675   71 276   72 950   73 868   74 678   75 667   76 4   77 1184   78 160   79 120   80 584   81 266   82 133   83 405   84 468   85 6   86 806   87 166   88 500   89 1090   90 552   91 251   92 27   93 424   94 687   95 1215   96 450   97 32   98 360   99 1052   100 868   101 2   102 66   103 754   104 450   105 145   106 5   107 687   108 24   109 302   110 806   111 251   112 42   113 24   114 30   115 128   116 128   117 50   118 1215   119 86   120 687   121 683   122 672   123 178   124 24   125 24   126 299   127 178   128 770   129 535   130 1052   131 270   132 255   133 675   134 632   135 266   136 6   137 21   138 930   139 411   140 754   141 133   142 340   143 535   144 46   145 250   146 132   147 132   148 354   149 500   150 770   151 276   152 360   153 354   154 27   155 552   156 552   157 602   158 266   159 1049   160 675   161 384   162 667   163 27   164 101   165 166   166 32   167 42   168 18   169 336   170 1122   171 276   172 1122   173 266   174 50   175 178   176 276   177 1247   178 6   179 1215   180 604   181 360   182 212   183 120   184 210   185 1090   186 10   187 1090   188 266   189 66   190 250   191 266   192 360   193 120   194 128   195 178   196 770   197 92   198 634   199 38   200 21}
          338  +
          339  +do_execsql_test 4.3 {
          340  +  SELECT b, sum(b) OVER (
          341  +    ORDER BY b
          342  +    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
          343  +  ) FROM t2 ORDER BY b;
          344  +} {0 0   1 1   1 2   2 4   2 6   2 8   3 11   3 14   4 18   5 23   6 29   7 36   7 43   7 50   8 58   8 66   8 74   9 83   9 92   9 101   10 111   11 122   11 133   12 145   12 157   12 169   13 182   13 195   14 209   15 224   15 239   15 254   16 270   16 286   16 302   17 319   19 338   20 358   21 379   21 400   22 422   22 444   23 467   23 490   23 513   24 537   25 562   26 588   26 614   26 640   27 667   27 694   28 722   29 751   29 780   29 809   30 839   30 869   30 899   31 930   31 961   32 993   33 1026   33 1059   33 1092   33 1125   33 1158   34 1192   34 1226   34 1260   34 1294   35 1329   35 1364   36 1400   36 1436   36 1472   36 1508   37 1545   37 1582   38 1620   38 1658   39 1697   39 1736   39 1775   40 1815   41 1856   41 1897   41 1938   42 1980   43 2023   43 2066   44 2110   44 2154   46 2200   46 2246   47 2293   47 2340   47 2387   47 2434   49 2483   50 2533   51 2584   52 2636   53 2689   54 2743   55 2798   55 2853   56 2909   56 2965   56 3021   57 3078   58 3136   58 3194   58 3252   58 3310   59 3369   59 3428   59 3487   59 3546   60 3606   61 3667   61 3728   62 3790   62 3852   63 3915   64 3979   65 4044   65 4109   65 4174   66 4240   67 4307   68 4375   69 4444   70 4514   72 4586   72 4658   72 4730   73 4803   73 4876   73 4949   74 5023   74 5097   74 5171   74 5245   74 5319   75 5394   75 5469   75 5544   76 5620   77 5697   77 5774   78 5852   78 5930   79 6009   80 6089   80 6169   81 6250   81 6331   81 6412   82 6494   83 6577   84 6661   84 6745   84 6829   84 6913   85 6998   85 7083   85 7168   86 7254   87 7341   87 7428   88 7516   89 7605   89 7694   89 7783   90 7873   90 7963   90 8053   91 8144   91 8235   91 8326   91 8417   91 8508   93 8601   93 8694   93 8787   94 8881   95 8976   95 9071   95 9166   96 9262   96 9358   96 9454   97 9551   97 9648   98 9746   98 9844   99 9943   99 10042   99 10141}
          345  +
          346  +do_execsql_test 4.4 {
          347  +  SELECT b, sum(b) OVER (
          348  +    ORDER BY b
          349  +    RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
          350  +  ) FROM t2 ORDER BY b;
          351  +} {0 10141   1 10141   1 10141   2 10141   2 10141   2 10141   3 10141   3 10141   4 10141   5 10141   6 10141   7 10141   7 10141   7 10141   8 10141   8 10141   8 10141   9 10141   9 10141   9 10141   10 10141   11 10141   11 10141   12 10141   12 10141   12 10141   13 10141   13 10141   14 10141   15 10141   15 10141   15 10141   16 10141   16 10141   16 10141   17 10141   19 10141   20 10141   21 10141   21 10141   22 10141   22 10141   23 10141   23 10141   23 10141   24 10141   25 10141   26 10141   26 10141   26 10141   27 10141   27 10141   28 10141   29 10141   29 10141   29 10141   30 10141   30 10141   30 10141   31 10141   31 10141   32 10141   33 10141   33 10141   33 10141   33 10141   33 10141   34 10141   34 10141   34 10141   34 10141   35 10141   35 10141   36 10141   36 10141   36 10141   36 10141   37 10141   37 10141   38 10141   38 10141   39 10141   39 10141   39 10141   40 10141   41 10141   41 10141   41 10141   42 10141   43 10141   43 10141   44 10141   44 10141   46 10141   46 10141   47 10141   47 10141   47 10141   47 10141   49 10141   50 10141   51 10141   52 10141   53 10141   54 10141   55 10141   55 10141   56 10141   56 10141   56 10141   57 10141   58 10141   58 10141   58 10141   58 10141   59 10141   59 10141   59 10141   59 10141   60 10141   61 10141   61 10141   62 10141   62 10141   63 10141   64 10141   65 10141   65 10141   65 10141   66 10141   67 10141   68 10141   69 10141   70 10141   72 10141   72 10141   72 10141   73 10141   73 10141   73 10141   74 10141   74 10141   74 10141   74 10141   74 10141   75 10141   75 10141   75 10141   76 10141   77 10141   77 10141   78 10141   78 10141   79 10141   80 10141   80 10141   81 10141   81 10141   81 10141   82 10141   83 10141   84 10141   84 10141   84 10141   84 10141   85 10141   85 10141   85 10141   86 10141   87 10141   87 10141   88 10141   89 10141   89 10141   89 10141   90 10141   90 10141   90 10141   91 10141   91 10141   91 10141   91 10141   91 10141   93 10141   93 10141   93 10141   94 10141   95 10141   95 10141   95 10141   96 10141   96 10141   96 10141   97 10141   97 10141   98 10141   98 10141   99 10141   99 10141   99 10141}
          352  +
          353  +do_execsql_test 4.5 {
          354  +  SELECT b, sum(b) OVER (
          355  +    ORDER BY b
          356  +    RANGE BETWEEN CURRENT ROW AND CURRENT ROW
          357  +  ) FROM t2 ORDER BY b;
          358  +} {0 0   1 2   1 2   2 6   2 6   2 6   3 6   3 6   4 4   5 5   6 6   7 21   7 21   7 21   8 24   8 24   8 24   9 27   9 27   9 27   10 10   11 22   11 22   12 36   12 36   12 36   13 26   13 26   14 14   15 45   15 45   15 45   16 48   16 48   16 48   17 17   19 19   20 20   21 42   21 42   22 44   22 44   23 69   23 69   23 69   24 24   25 25   26 78   26 78   26 78   27 54   27 54   28 28   29 87   29 87   29 87   30 90   30 90   30 90   31 62   31 62   32 32   33 165   33 165   33 165   33 165   33 165   34 136   34 136   34 136   34 136   35 70   35 70   36 144   36 144   36 144   36 144   37 74   37 74   38 76   38 76   39 117   39 117   39 117   40 40   41 123   41 123   41 123   42 42   43 86   43 86   44 88   44 88   46 92   46 92   47 188   47 188   47 188   47 188   49 49   50 50   51 51   52 52   53 53   54 54   55 110   55 110   56 168   56 168   56 168   57 57   58 232   58 232   58 232   58 232   59 236   59 236   59 236   59 236   60 60   61 122   61 122   62 124   62 124   63 63   64 64   65 195   65 195   65 195   66 66   67 67   68 68   69 69   70 70   72 216   72 216   72 216   73 219   73 219   73 219   74 370   74 370   74 370   74 370   74 370   75 225   75 225   75 225   76 76   77 154   77 154   78 156   78 156   79 79   80 160   80 160   81 243   81 243   81 243   82 82   83 83   84 336   84 336   84 336   84 336   85 255   85 255   85 255   86 86   87 174   87 174   88 88   89 267   89 267   89 267   90 270   90 270   90 270   91 455   91 455   91 455   91 455   91 455   93 279   93 279   93 279   94 94   95 285   95 285   95 285   96 288   96 288   96 288   97 194   97 194   98 196   98 196   99 297   99 297   99 297}
          359  +
          360  +do_execsql_test 4.6.1 {
          361  +  SELECT b, sum(b) OVER (
          362  +    RANGE BETWEEN CURRENT ROW AND CURRENT ROW
          363  +  ) FROM t2 ORDER BY b;
          364  +} {0 10141   1 10141   1 10141   2 10141   2 10141   2 10141   3 10141   3 10141   4 10141   5 10141   6 10141   7 10141   7 10141   7 10141   8 10141   8 10141   8 10141   9 10141   9 10141   9 10141   10 10141   11 10141   11 10141   12 10141   12 10141   12 10141   13 10141   13 10141   14 10141   15 10141   15 10141   15 10141   16 10141   16 10141   16 10141   17 10141   19 10141   20 10141   21 10141   21 10141   22 10141   22 10141   23 10141   23 10141   23 10141   24 10141   25 10141   26 10141   26 10141   26 10141   27 10141   27 10141   28 10141   29 10141   29 10141   29 10141   30 10141   30 10141   30 10141   31 10141   31 10141   32 10141   33 10141   33 10141   33 10141   33 10141   33 10141   34 10141   34 10141   34 10141   34 10141   35 10141   35 10141   36 10141   36 10141   36 10141   36 10141   37 10141   37 10141   38 10141   38 10141   39 10141   39 10141   39 10141   40 10141   41 10141   41 10141   41 10141   42 10141   43 10141   43 10141   44 10141   44 10141   46 10141   46 10141   47 10141   47 10141   47 10141   47 10141   49 10141   50 10141   51 10141   52 10141   53 10141   54 10141   55 10141   55 10141   56 10141   56 10141   56 10141   57 10141   58 10141   58 10141   58 10141   58 10141   59 10141   59 10141   59 10141   59 10141   60 10141   61 10141   61 10141   62 10141   62 10141   63 10141   64 10141   65 10141   65 10141   65 10141   66 10141   67 10141   68 10141   69 10141   70 10141   72 10141   72 10141   72 10141   73 10141   73 10141   73 10141   74 10141   74 10141   74 10141   74 10141   74 10141   75 10141   75 10141   75 10141   76 10141   77 10141   77 10141   78 10141   78 10141   79 10141   80 10141   80 10141   81 10141   81 10141   81 10141   82 10141   83 10141   84 10141   84 10141   84 10141   84 10141   85 10141   85 10141   85 10141   86 10141   87 10141   87 10141   88 10141   89 10141   89 10141   89 10141   90 10141   90 10141   90 10141   91 10141   91 10141   91 10141   91 10141   91 10141   93 10141   93 10141   93 10141   94 10141   95 10141   95 10141   95 10141   96 10141   96 10141   96 10141   97 10141   97 10141   98 10141   98 10141   99 10141   99 10141   99 10141}
          365  +
          366  +do_execsql_test 4.6.2 {
          367  +  SELECT b, sum(b) OVER () FROM t2 ORDER BY b;
          368  +} {0 10141   1 10141   1 10141   2 10141   2 10141   2 10141   3 10141   3 10141   4 10141   5 10141   6 10141   7 10141   7 10141   7 10141   8 10141   8 10141   8 10141   9 10141   9 10141   9 10141   10 10141   11 10141   11 10141   12 10141   12 10141   12 10141   13 10141   13 10141   14 10141   15 10141   15 10141   15 10141   16 10141   16 10141   16 10141   17 10141   19 10141   20 10141   21 10141   21 10141   22 10141   22 10141   23 10141   23 10141   23 10141   24 10141   25 10141   26 10141   26 10141   26 10141   27 10141   27 10141   28 10141   29 10141   29 10141   29 10141   30 10141   30 10141   30 10141   31 10141   31 10141   32 10141   33 10141   33 10141   33 10141   33 10141   33 10141   34 10141   34 10141   34 10141   34 10141   35 10141   35 10141   36 10141   36 10141   36 10141   36 10141   37 10141   37 10141   38 10141   38 10141   39 10141   39 10141   39 10141   40 10141   41 10141   41 10141   41 10141   42 10141   43 10141   43 10141   44 10141   44 10141   46 10141   46 10141   47 10141   47 10141   47 10141   47 10141   49 10141   50 10141   51 10141   52 10141   53 10141   54 10141   55 10141   55 10141   56 10141   56 10141   56 10141   57 10141   58 10141   58 10141   58 10141   58 10141   59 10141   59 10141   59 10141   59 10141   60 10141   61 10141   61 10141   62 10141   62 10141   63 10141   64 10141   65 10141   65 10141   65 10141   66 10141   67 10141   68 10141   69 10141   70 10141   72 10141   72 10141   72 10141   73 10141   73 10141   73 10141   74 10141   74 10141   74 10141   74 10141   74 10141   75 10141   75 10141   75 10141   76 10141   77 10141   77 10141   78 10141   78 10141   79 10141   80 10141   80 10141   81 10141   81 10141   81 10141   82 10141   83 10141   84 10141   84 10141   84 10141   84 10141   85 10141   85 10141   85 10141   86 10141   87 10141   87 10141   88 10141   89 10141   89 10141   89 10141   90 10141   90 10141   90 10141   91 10141   91 10141   91 10141   91 10141   91 10141   93 10141   93 10141   93 10141   94 10141   95 10141   95 10141   95 10141   96 10141   96 10141   96 10141   97 10141   97 10141   98 10141   98 10141   99 10141   99 10141   99 10141}
          369  +
          370  +do_execsql_test 4.6.3 {
          371  +  SELECT b, sum(b) OVER (
          372  +    RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
          373  +  ) FROM t2 ORDER BY b;
          374  +} {0 10141   1 10141   1 10141   2 10141   2 10141   2 10141   3 10141   3 10141   4 10141   5 10141   6 10141   7 10141   7 10141   7 10141   8 10141   8 10141   8 10141   9 10141   9 10141   9 10141   10 10141   11 10141   11 10141   12 10141   12 10141   12 10141   13 10141   13 10141   14 10141   15 10141   15 10141   15 10141   16 10141   16 10141   16 10141   17 10141   19 10141   20 10141   21 10141   21 10141   22 10141   22 10141   23 10141   23 10141   23 10141   24 10141   25 10141   26 10141   26 10141   26 10141   27 10141   27 10141   28 10141   29 10141   29 10141   29 10141   30 10141   30 10141   30 10141   31 10141   31 10141   32 10141   33 10141   33 10141   33 10141   33 10141   33 10141   34 10141   34 10141   34 10141   34 10141   35 10141   35 10141   36 10141   36 10141   36 10141   36 10141   37 10141   37 10141   38 10141   38 10141   39 10141   39 10141   39 10141   40 10141   41 10141   41 10141   41 10141   42 10141   43 10141   43 10141   44 10141   44 10141   46 10141   46 10141   47 10141   47 10141   47 10141   47 10141   49 10141   50 10141   51 10141   52 10141   53 10141   54 10141   55 10141   55 10141   56 10141   56 10141   56 10141   57 10141   58 10141   58 10141   58 10141   58 10141   59 10141   59 10141   59 10141   59 10141   60 10141   61 10141   61 10141   62 10141   62 10141   63 10141   64 10141   65 10141   65 10141   65 10141   66 10141   67 10141   68 10141   69 10141   70 10141   72 10141   72 10141   72 10141   73 10141   73 10141   73 10141   74 10141   74 10141   74 10141   74 10141   74 10141   75 10141   75 10141   75 10141   76 10141   77 10141   77 10141   78 10141   78 10141   79 10141   80 10141   80 10141   81 10141   81 10141   81 10141   82 10141   83 10141   84 10141   84 10141   84 10141   84 10141   85 10141   85 10141   85 10141   86 10141   87 10141   87 10141   88 10141   89 10141   89 10141   89 10141   90 10141   90 10141   90 10141   91 10141   91 10141   91 10141   91 10141   91 10141   93 10141   93 10141   93 10141   94 10141   95 10141   95 10141   95 10141   96 10141   96 10141   96 10141   97 10141   97 10141   98 10141   98 10141   99 10141   99 10141   99 10141}
          375  +
          376  +do_execsql_test 4.6.4 {
          377  +  SELECT b, sum(b) OVER (
          378  +    RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
          379  +  ) FROM t2 ORDER BY b;
          380  +} {0 10141   1 10141   1 10141   2 10141   2 10141   2 10141   3 10141   3 10141   4 10141   5 10141   6 10141   7 10141   7 10141   7 10141   8 10141   8 10141   8 10141   9 10141   9 10141   9 10141   10 10141   11 10141   11 10141   12 10141   12 10141   12 10141   13 10141   13 10141   14 10141   15 10141   15 10141   15 10141   16 10141   16 10141   16 10141   17 10141   19 10141   20 10141   21 10141   21 10141   22 10141   22 10141   23 10141   23 10141   23 10141   24 10141   25 10141   26 10141   26 10141   26 10141   27 10141   27 10141   28 10141   29 10141   29 10141   29 10141   30 10141   30 10141   30 10141   31 10141   31 10141   32 10141   33 10141   33 10141   33 10141   33 10141   33 10141   34 10141   34 10141   34 10141   34 10141   35 10141   35 10141   36 10141   36 10141   36 10141   36 10141   37 10141   37 10141   38 10141   38 10141   39 10141   39 10141   39 10141   40 10141   41 10141   41 10141   41 10141   42 10141   43 10141   43 10141   44 10141   44 10141   46 10141   46 10141   47 10141   47 10141   47 10141   47 10141   49 10141   50 10141   51 10141   52 10141   53 10141   54 10141   55 10141   55 10141   56 10141   56 10141   56 10141   57 10141   58 10141   58 10141   58 10141   58 10141   59 10141   59 10141   59 10141   59 10141   60 10141   61 10141   61 10141   62 10141   62 10141   63 10141   64 10141   65 10141   65 10141   65 10141   66 10141   67 10141   68 10141   69 10141   70 10141   72 10141   72 10141   72 10141   73 10141   73 10141   73 10141   74 10141   74 10141   74 10141   74 10141   74 10141   75 10141   75 10141   75 10141   76 10141   77 10141   77 10141   78 10141   78 10141   79 10141   80 10141   80 10141   81 10141   81 10141   81 10141   82 10141   83 10141   84 10141   84 10141   84 10141   84 10141   85 10141   85 10141   85 10141   86 10141   87 10141   87 10141   88 10141   89 10141   89 10141   89 10141   90 10141   90 10141   90 10141   91 10141   91 10141   91 10141   91 10141   91 10141   93 10141   93 10141   93 10141   94 10141   95 10141   95 10141   95 10141   96 10141   96 10141   96 10141   97 10141   97 10141   98 10141   98 10141   99 10141   99 10141   99 10141}
          381  +
          382  +do_execsql_test 4.7.1 {
          383  +  SELECT b, sum(b) OVER (
          384  +    ROWS BETWEEN CURRENT ROW AND CURRENT ROW
          385  +  ) FROM t2 ORDER BY 1, 2;
          386  +} {0 0   1 1   1 1   2 2   2 2   2 2   3 3   3 3   4 4   5 5   6 6   7 7   7 7   7 7   8 8   8 8   8 8   9 9   9 9   9 9   10 10   11 11   11 11   12 12   12 12   12 12   13 13   13 13   14 14   15 15   15 15   15 15   16 16   16 16   16 16   17 17   19 19   20 20   21 21   21 21   22 22   22 22   23 23   23 23   23 23   24 24   25 25   26 26   26 26   26 26   27 27   27 27   28 28   29 29   29 29   29 29   30 30   30 30   30 30   31 31   31 31   32 32   33 33   33 33   33 33   33 33   33 33   34 34   34 34   34 34   34 34   35 35   35 35   36 36   36 36   36 36   36 36   37 37   37 37   38 38   38 38   39 39   39 39   39 39   40 40   41 41   41 41   41 41   42 42   43 43   43 43   44 44   44 44   46 46   46 46   47 47   47 47   47 47   47 47   49 49   50 50   51 51   52 52   53 53   54 54   55 55   55 55   56 56   56 56   56 56   57 57   58 58   58 58   58 58   58 58   59 59   59 59   59 59   59 59   60 60   61 61   61 61   62 62   62 62   63 63   64 64   65 65   65 65   65 65   66 66   67 67   68 68   69 69   70 70   72 72   72 72   72 72   73 73   73 73   73 73   74 74   74 74   74 74   74 74   74 74   75 75   75 75   75 75   76 76   77 77   77 77   78 78   78 78   79 79   80 80   80 80   81 81   81 81   81 81   82 82   83 83   84 84   84 84   84 84   84 84   85 85   85 85   85 85   86 86   87 87   87 87   88 88   89 89   89 89   89 89   90 90   90 90   90 90   91 91   91 91   91 91   91 91   91 91   93 93   93 93   93 93   94 94   95 95   95 95   95 95   96 96   96 96   96 96   97 97   97 97   98 98   98 98   99 99   99 99   99 99}
          387  +
          388  +do_execsql_test 4.7.2 {
          389  +  SELECT b, sum(b) OVER (
          390  +    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
          391  +  ) FROM t2 ORDER BY 1, 2;
          392  +} {0 0   1 3379   1 5443   2 372   2 4473   2 7074   3 2916   3 9096   4 4049   5 5643   6 1047   7 2205   7 7081   7 10141   8 1553   8 5926   8 6422   9 4883   9 7932   9 8497   10 9544   11 5727   11 6433   12 2825   12 5918   12 8582   13 5190   13 8570   14 8596   15 3189   15 6023   15 8924   16 1942   16 1958   16 3590   17 10134   19 7474   20 5946   21 5464   21 9682   22 3029   22 6140   23 212   23 1926   23 8520   24 2626   25 3331   26 337   26 7539   26 7565   27 1270   27 10035   28 3217   29 1649   29 4355   29 7326   30 4215   30 9400   30 9853   31 5977   31 6008   32 2857   33 370   33 4326   33 8175   33 8909   33 9661   34 6414   34 6516   34 8958   34 9925   35 2151   35 5638   36 3701   36 7818   36 8785   36 8994   37 4597   37 8557   38 735   38 9891   39 842   39 7513   39 9721   40 3475   41 115   41 4874   41 5906   42 4185   43 2754   43 3518   44 7072   44 9765   46 1041   46 1316   47 2198   47 3378   47 7612   47 7923   49 6482   50 9450   51 5778   52 9370   53 4408   54 1448   55 3174   55 6876   56 2913   56 3435   56 3574   57 7223   58 5248   58 7876   58 9318   58 9823   59 697   59 2813   59 6665   59 7455   60 6821   61 2426   61 4944   62 904   62 8658   63 4471   64 8407   65 2116   65 5177   65 5603   66 8142   67 1620   68 803   69 9260   70 7396   72 4833   72 8004   72 8076   73 5017   73 5716   73 6213   74 74   74 189   74 2365   74 5538   74 7297   75 3665   75 6951   75 8343   76 3964   77 1903   77 7028   78 1394   78 4293   79 6292   80 4677   80 7692   81 542   81 4045   81 8488   82 10117   83 10008   84 1826   84 4761   84 9534   84 9628   85 2602   85 2711   85 7166   86 2291   87 4560   87 5865   88 6380   89 461   89 3306   89 3790   90 3119   90 6606   90 7782   91 995   91 2517   91 3007   91 8749   91 8876   93 1742   93 2051   93 8268   94 4143   95 5112   95 6118   95 9191   96 638   96 5344   96 6761   97 1243   97 1545   98 3888   98 5442   99 311   99 1146   99 9093}
          393  +
          394  +do_execsql_test 4.7.3 {
          395  +  SELECT b, sum(b) OVER (
          396  +    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
          397  +  ) FROM t2 ORDER BY 1, 2;
          398  +} {0 10141   1 10141   1 10141   2 10141   2 10141   2 10141   3 10141   3 10141   4 10141   5 10141   6 10141   7 10141   7 10141   7 10141   8 10141   8 10141   8 10141   9 10141   9 10141   9 10141   10 10141   11 10141   11 10141   12 10141   12 10141   12 10141   13 10141   13 10141   14 10141   15 10141   15 10141   15 10141   16 10141   16 10141   16 10141   17 10141   19 10141   20 10141   21 10141   21 10141   22 10141   22 10141   23 10141   23 10141   23 10141   24 10141   25 10141   26 10141   26 10141   26 10141   27 10141   27 10141   28 10141   29 10141   29 10141   29 10141   30 10141   30 10141   30 10141   31 10141   31 10141   32 10141   33 10141   33 10141   33 10141   33 10141   33 10141   34 10141   34 10141   34 10141   34 10141   35 10141   35 10141   36 10141   36 10141   36 10141   36 10141   37 10141   37 10141   38 10141   38 10141   39 10141   39 10141   39 10141   40 10141   41 10141   41 10141   41 10141   42 10141   43 10141   43 10141   44 10141   44 10141   46 10141   46 10141   47 10141   47 10141   47 10141   47 10141   49 10141   50 10141   51 10141   52 10141   53 10141   54 10141   55 10141   55 10141   56 10141   56 10141   56 10141   57 10141   58 10141   58 10141   58 10141   58 10141   59 10141   59 10141   59 10141   59 10141   60 10141   61 10141   61 10141   62 10141   62 10141   63 10141   64 10141   65 10141   65 10141   65 10141   66 10141   67 10141   68 10141   69 10141   70 10141   72 10141   72 10141   72 10141   73 10141   73 10141   73 10141   74 10141   74 10141   74 10141   74 10141   74 10141   75 10141   75 10141   75 10141   76 10141   77 10141   77 10141   78 10141   78 10141   79 10141   80 10141   80 10141   81 10141   81 10141   81 10141   82 10141   83 10141   84 10141   84 10141   84 10141   84 10141   85 10141   85 10141   85 10141   86 10141   87 10141   87 10141   88 10141   89 10141   89 10141   89 10141   90 10141   90 10141   90 10141   91 10141   91 10141   91 10141   91 10141   91 10141   93 10141   93 10141   93 10141   94 10141   95 10141   95 10141   95 10141   96 10141   96 10141   96 10141   97 10141   97 10141   98 10141   98 10141   99 10141   99 10141   99 10141}
          399  +
          400  +do_execsql_test 4.7.4 {
          401  +  SELECT b, sum(b) OVER (
          402  +    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
          403  +  ) FROM t2 ORDER BY 1, 2;
          404  +} {0 10141   1 4699   1 6763   2 3069   2 5670   2 9771   3 1048   3 7228   4 6096   5 4503   6 9100   7 7   7 3067   7 7943   8 3727   8 4223   8 8596   9 1653   9 2218   9 5267   10 607   11 3719   11 4425   12 1571   12 4235   12 7328   13 1584   13 4964   14 1559   15 1232   15 4133   15 6967   16 6567   16 8199   16 8215   17 24   19 2686   20 4215   21 480   21 4698   22 4023   22 7134   23 1644   23 8238   23 9952   24 7539   25 6835   26 2602   26 2628   26 9830   27 133   27 8898   28 6952   29 2844   29 5815   29 8521   30 318   30 771   30 5956   31 4164   31 4195   32 7316   33 513   33 1265   33 1999   33 5848   33 9804   34 250   34 1217   34 3659   34 3761   35 4538   35 8025   36 1183   36 1392   36 2359   36 6476   37 1621   37 5581   38 288   38 9444   39 459   39 2667   39 9338   40 6706   41 4276   41 5308   41 10067   42 5998   43 6666   43 7430   44 420   44 3113   46 8871   46 9146   47 2265   47 2576   47 6810   47 7990   49 3708   50 741   51 4414   52 823   53 5786   54 8747   55 3320   55 7022   56 6623   56 6762   56 7284   57 2975   58 376   58 881   58 2323   58 4951   59 2745   59 3535   59 7387   59 9503   60 3380   61 5258   61 7776   62 1545   62 9299   63 5733   64 1798   65 4603   65 5029   65 8090   66 2065   67 8588   68 9406   69 950   70 2815   72 2137   72 2209   72 5380   73 4001   73 4498   73 5197   74 2918   74 4677   74 7850   74 10026   74 10141   75 1873   75 3265   75 6551   76 6253   77 3190   77 8315   78 5926   78 8825   79 3928   80 2529   80 5544   81 1734   81 6177   81 9680   82 106   83 216   84 597   84 691   84 5464   84 8399   85 3060   85 7515   85 7624   86 7936   87 4363   87 5668   88 3849   89 6440   89 6924   89 9769   90 2449   90 3625   90 7112   91 1356   91 1483   91 7225   91 7715   91 9237   93 1966   93 8183   93 8492   94 6092   95 1045   95 4118   95 5124   96 3476   96 4893   96 9599   97 8693   97 8995   98 4797   98 6351   99 1147   99 9094   99 9929}
          405  +
          406  +do_execsql_test 4.8.1 {
          407  +  SELECT b, sum(b) OVER (
          408  +    ORDER BY a
          409  +    ROWS BETWEEN CURRENT ROW AND CURRENT ROW
          410  +  ) FROM t2 ORDER BY 1, 2;
          411  +} {0 0   1 1   1 1   2 2   2 2   2 2   3 3   3 3   4 4   5 5   6 6   7 7   7 7   7 7   8 8   8 8   8 8   9 9   9 9   9 9   10 10   11 11   11 11   12 12   12 12   12 12   13 13   13 13   14 14   15 15   15 15   15 15   16 16   16 16   16 16   17 17   19 19   20 20   21 21   21 21   22 22   22 22   23 23   23 23   23 23   24 24   25 25   26 26   26 26   26 26   27 27   27 27   28 28   29 29   29 29   29 29   30 30   30 30   30 30   31 31   31 31   32 32   33 33   33 33   33 33   33 33   33 33   34 34   34 34   34 34   34 34   35 35   35 35   36 36   36 36   36 36   36 36   37 37   37 37   38 38   38 38   39 39   39 39   39 39   40 40   41 41   41 41   41 41   42 42   43 43   43 43   44 44   44 44   46 46   46 46   47 47   47 47   47 47   47 47   49 49   50 50   51 51   52 52   53 53   54 54   55 55   55 55   56 56   56 56   56 56   57 57   58 58   58 58   58 58   58 58   59 59   59 59   59 59   59 59   60 60   61 61   61 61   62 62   62 62   63 63   64 64   65 65   65 65   65 65   66 66   67 67   68 68   69 69   70 70   72 72   72 72   72 72   73 73   73 73   73 73   74 74   74 74   74 74   74 74   74 74   75 75   75 75   75 75   76 76   77 77   77 77   78 78   78 78   79 79   80 80   80 80   81 81   81 81   81 81   82 82   83 83   84 84   84 84   84 84   84 84   85 85   85 85   85 85   86 86   87 87   87 87   88 88   89 89   89 89   89 89   90 90   90 90   90 90   91 91   91 91   91 91   91 91   91 91   93 93   93 93   93 93   94 94   95 95   95 95   95 95   96 96   96 96   96 96   97 97   97 97   98 98   98 98   99 99   99 99   99 99}
          412  +
          413  +do_execsql_test 4.8.2 {
          414  +  SELECT b, sum(b) OVER (
          415  +    ORDER BY a
          416  +    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
          417  +  ) FROM t2 ORDER BY 1, 2;
          418  +} {0 0   1 3379   1 5443   2 372   2 4473   2 7074   3 2916   3 9096   4 4049   5 5643   6 1047   7 2205   7 7081   7 10141   8 1553   8 5926   8 6422   9 4883   9 7932   9 8497   10 9544   11 5727   11 6433   12 2825   12 5918   12 8582   13 5190   13 8570   14 8596   15 3189   15 6023   15 8924   16 1942   16 1958   16 3590   17 10134   19 7474   20 5946   21 5464   21 9682   22 3029   22 6140   23 212   23 1926   23 8520   24 2626   25 3331   26 337   26 7539   26 7565   27 1270   27 10035   28 3217   29 1649   29 4355   29 7326   30 4215   30 9400   30 9853   31 5977   31 6008   32 2857   33 370   33 4326   33 8175   33 8909   33 9661   34 6414   34 6516   34 8958   34 9925   35 2151   35 5638   36 3701   36 7818   36 8785   36 8994   37 4597   37 8557   38 735   38 9891   39 842   39 7513   39 9721   40 3475   41 115   41 4874   41 5906   42 4185   43 2754   43 3518   44 7072   44 9765   46 1041   46 1316   47 2198   47 3378   47 7612   47 7923   49 6482   50 9450   51 5778   52 9370   53 4408   54 1448   55 3174   55 6876   56 2913   56 3435   56 3574   57 7223   58 5248   58 7876   58 9318   58 9823   59 697   59 2813   59 6665   59 7455   60 6821   61 2426   61 4944   62 904   62 8658   63 4471   64 8407   65 2116   65 5177   65 5603   66 8142   67 1620   68 803   69 9260   70 7396   72 4833   72 8004   72 8076   73 5017   73 5716   73 6213   74 74   74 189   74 2365   74 5538   74 7297   75 3665   75 6951   75 8343   76 3964   77 1903   77 7028   78 1394   78 4293   79 6292   80 4677   80 7692   81 542   81 4045   81 8488   82 10117   83 10008   84 1826   84 4761   84 9534   84 9628   85 2602   85 2711   85 7166   86 2291   87 4560   87 5865   88 6380   89 461   89 3306   89 3790   90 3119   90 6606   90 7782   91 995   91 2517   91 3007   91 8749   91 8876   93 1742   93 2051   93 8268   94 4143   95 5112   95 6118   95 9191   96 638   96 5344   96 6761   97 1243   97 1545   98 3888   98 5442   99 311   99 1146   99 9093}
          419  +
          420  +do_execsql_test 4.8.3 {
          421  +  SELECT b, sum(b) OVER (
          422  +    ORDER BY a
          423  +    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
          424  +  ) FROM t2 ORDER BY 1, 2;
          425  +} {0 10141   1 10141   1 10141   2 10141   2 10141   2 10141   3 10141   3 10141   4 10141   5 10141   6 10141   7 10141   7 10141   7 10141   8 10141   8 10141   8 10141   9 10141   9 10141   9 10141   10 10141   11 10141   11 10141   12 10141   12 10141   12 10141   13 10141   13 10141   14 10141   15 10141   15 10141   15 10141   16 10141   16 10141   16 10141   17 10141   19 10141   20 10141   21 10141   21 10141   22 10141   22 10141   23 10141   23 10141   23 10141   24 10141   25 10141   26 10141   26 10141   26 10141   27 10141   27 10141   28 10141   29 10141   29 10141   29 10141   30 10141   30 10141   30 10141   31 10141   31 10141   32 10141   33 10141   33 10141   33 10141   33 10141   33 10141   34 10141   34 10141   34 10141   34 10141   35 10141   35 10141   36 10141   36 10141   36 10141   36 10141   37 10141   37 10141   38 10141   38 10141   39 10141   39 10141   39 10141   40 10141   41 10141   41 10141   41 10141   42 10141   43 10141   43 10141   44 10141   44 10141   46 10141   46 10141   47 10141   47 10141   47 10141   47 10141   49 10141   50 10141   51 10141   52 10141   53 10141   54 10141   55 10141   55 10141   56 10141   56 10141   56 10141   57 10141   58 10141   58 10141   58 10141   58 10141   59 10141   59 10141   59 10141   59 10141   60 10141   61 10141   61 10141   62 10141   62 10141   63 10141   64 10141   65 10141   65 10141   65 10141   66 10141   67 10141   68 10141   69 10141   70 10141   72 10141   72 10141   72 10141   73 10141   73 10141   73 10141   74 10141   74 10141   74 10141   74 10141   74 10141   75 10141   75 10141   75 10141   76 10141   77 10141   77 10141   78 10141   78 10141   79 10141   80 10141   80 10141   81 10141   81 10141   81 10141   82 10141   83 10141   84 10141   84 10141   84 10141   84 10141   85 10141   85 10141   85 10141   86 10141   87 10141   87 10141   88 10141   89 10141   89 10141   89 10141   90 10141   90 10141   90 10141   91 10141   91 10141   91 10141   91 10141   91 10141   93 10141   93 10141   93 10141   94 10141   95 10141   95 10141   95 10141   96 10141   96 10141   96 10141   97 10141   97 10141   98 10141   98 10141   99 10141   99 10141   99 10141}
          426  +
          427  +do_execsql_test 4.8.4 {
          428  +  SELECT b, sum(b) OVER (
          429  +    ORDER BY a
          430  +    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
          431  +  ) FROM t2 ORDER BY 1, 2;
          432  +} {0 10141   1 4699   1 6763   2 3069   2 5670   2 9771   3 1048   3 7228   4 6096   5 4503   6 9100   7 7   7 3067   7 7943   8 3727   8 4223   8 8596   9 1653   9 2218   9 5267   10 607   11 3719   11 4425   12 1571   12 4235   12 7328   13 1584   13 4964   14 1559   15 1232   15 4133   15 6967   16 6567   16 8199   16 8215   17 24   19 2686   20 4215   21 480   21 4698   22 4023   22 7134   23 1644   23 8238   23 9952   24 7539   25 6835   26 2602   26 2628   26 9830   27 133   27 8898   28 6952   29 2844   29 5815   29 8521   30 318   30 771   30 5956   31 4164   31 4195   32 7316   33 513   33 1265   33 1999   33 5848   33 9804   34 250   34 1217   34 3659   34 3761   35 4538   35 8025   36 1183   36 1392   36 2359   36 6476   37 1621   37 5581   38 288   38 9444   39 459   39 2667   39 9338   40 6706   41 4276   41 5308   41 10067   42 5998   43 6666   43 7430   44 420   44 3113   46 8871   46 9146   47 2265   47 2576   47 6810   47 7990   49 3708   50 741   51 4414   52 823   53 5786   54 8747   55 3320   55 7022   56 6623   56 6762   56 7284   57 2975   58 376   58 881   58 2323   58 4951   59 2745   59 3535   59 7387   59 9503   60 3380   61 5258   61 7776   62 1545   62 9299   63 5733   64 1798   65 4603   65 5029   65 8090   66 2065   67 8588   68 9406   69 950   70 2815   72 2137   72 2209   72 5380   73 4001   73 4498   73 5197   74 2918   74 4677   74 7850   74 10026   74 10141   75 1873   75 3265   75 6551   76 6253   77 3190   77 8315   78 5926   78 8825   79 3928   80 2529   80 5544   81 1734   81 6177   81 9680   82 106   83 216   84 597   84 691   84 5464   84 8399   85 3060   85 7515   85 7624   86 7936   87 4363   87 5668   88 3849   89 6440   89 6924   89 9769   90 2449   90 3625   90 7112   91 1356   91 1483   91 7225   91 7715   91 9237   93 1966   93 8183   93 8492   94 6092   95 1045   95 4118   95 5124   96 3476   96 4893   96 9599   97 8693   97 8995   98 4797   98 6351   99 1147   99 9094   99 9929}
          433  +
          434  +finish_test

Added test/window3.tcl.

            1  +# 2018 May 19
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +
           13  +source [file join [file dirname $argv0] pg_common.tcl]
           14  +
           15  +#=========================================================================
           16  +
           17  +start_test window3 "2018 May 31"
           18  +ifcapable !windowfunc
           19  +
           20  +execsql_test 1.0 {
           21  +  DROP TABLE IF EXISTS t2;
           22  +  CREATE TABLE t2(a INTEGER PRIMARY KEY, b INTEGER);
           23  +  INSERT INTO t2(a, b) VALUES
           24  +  (1,0), (2,74), (3,41), (4,74), (5,23), (6,99), (7,26), (8,33), (9,2),
           25  +  (10,89), (11,81), (12,96), (13,59), (14,38), (15,68), (16,39), (17,62),
           26  +  (18,91), (19,46), (20,6), (21,99), (22,97), (23,27), (24,46), (25,78),
           27  +  (26,54), (27,97), (28,8), (29,67), (30,29), (31,93), (32,84), (33,77),
           28  +  (34,23), (35,16), (36,16), (37,93), (38,65), (39,35), (40,47), (41,7),
           29  +  (42,86), (43,74), (44,61), (45,91), (46,85), (47,24), (48,85), (49,43),
           30  +  (50,59), (51,12), (52,32), (53,56), (54,3), (55,91), (56,22), (57,90),
           31  +  (58,55), (59,15), (60,28), (61,89), (62,25), (63,47), (64,1), (65,56),
           32  +  (66,40), (67,43), (68,56), (69,16), (70,75), (71,36), (72,89), (73,98),
           33  +  (74,76), (75,81), (76,4), (77,94), (78,42), (79,30), (80,78), (81,33),
           34  +  (82,29), (83,53), (84,63), (85,2), (86,87), (87,37), (88,80), (89,84),
           35  +  (90,72), (91,41), (92,9), (93,61), (94,73), (95,95), (96,65), (97,13),
           36  +  (98,58), (99,96), (100,98), (101,1), (102,21), (103,74), (104,65), (105,35),
           37  +  (106,5), (107,73), (108,11), (109,51), (110,87), (111,41), (112,12), (113,8),
           38  +  (114,20), (115,31), (116,31), (117,15), (118,95), (119,22), (120,73), 
           39  +  (121,79), (122,88), (123,34), (124,8), (125,11), (126,49), (127,34), 
           40  +  (128,90), (129,59), (130,96), (131,60), (132,55), (133,75), (134,77),
           41  +  (135,44), (136,2), (137,7), (138,85), (139,57), (140,74), (141,29), (142,70),
           42  +  (143,59), (144,19), (145,39), (146,26), (147,26), (148,47), (149,80),
           43  +  (150,90), (151,36), (152,58), (153,47), (154,9), (155,72), (156,72), (157,66),
           44  +  (158,33), (159,93), (160,75), (161,64), (162,81), (163,9), (164,23), (165,37),
           45  +  (166,13), (167,12), (168,14), (169,62), (170,91), (171,36), (172,91),
           46  +  (173,33), (174,15), (175,34), (176,36), (177,99), (178,3), (179,95), (180,69),
           47  +  (181,58), (182,52), (183,30), (184,50), (185,84), (186,10), (187,84),
           48  +  (188,33), (189,21), (190,39), (191,44), (192,58), (193,30), (194,38),
           49  +  (195,34), (196,83), (197,27), (198,82), (199,17), (200,7);
           50  +}
           51  +
           52  +execsql_test 1.1 {
           53  +  SELECT max(b) OVER (
           54  +    ORDER BY a
           55  +  ) FROM t2
           56  +}
           57  +
           58  +foreach {tn window} {
           59  +   1 "RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"
           60  +   2 "RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING"
           61  +   3 "RANGE BETWEEN CURRENT ROW         AND CURRENT ROW"
           62  +   4 "RANGE BETWEEN CURRENT ROW         AND UNBOUNDED FOLLOWING"
           63  +   5 "ROWS BETWEEN UNBOUNDED PRECEDING AND 4 PRECEDING"
           64  +   6 "ROWS BETWEEN 4 PRECEDING    AND 2 PRECEDING"
           65  +   7 "ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"
           66  +   8 "ROWS BETWEEN 4 PRECEDING    AND CURRENT ROW"
           67  +   9 "ROWS BETWEEN CURRENT ROW         AND CURRENT ROW"
           68  +  10 "ROWS BETWEEN UNBOUNDED PRECEDING AND 4 FOLLOWING"
           69  +  11 "ROWS BETWEEN 4 PRECEDING    AND 2 FOLLOWING"
           70  +  12 "ROWS BETWEEN CURRENT ROW         AND 4 FOLLOWING"
           71  +  13 "ROWS BETWEEN 2 FOLLOWING    AND 4 FOLLOWING"
           72  +  14 "ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING"
           73  +  15 "ROWS BETWEEN 4 PRECEDING    AND UNBOUNDED FOLLOWING"
           74  +  16 "ROWS BETWEEN CURRENT ROW         AND UNBOUNDED FOLLOWING"
           75  +  17 "ROWS BETWEEN 4 FOLLOWING    AND UNBOUNDED FOLLOWING"
           76  +} {
           77  +  execsql_test 1.$tn.2.1 "SELECT max(b) OVER ( ORDER BY a $window ) FROM t2"
           78  +  execsql_test 1.$tn.2.2 "SELECT min(b) OVER ( ORDER BY a $window ) FROM t2"
           79  +
           80  +  execsql_test 1.$tn.3.1 "
           81  +    SELECT row_number() OVER ( ORDER BY a $window ) FROM t2
           82  +  "
           83  +  execsql_test 1.$tn.3.2 "
           84  +    SELECT row_number() OVER ( PARTITION BY b%10 ORDER BY a $window ) FROM t2
           85  +  "
           86  +  execsql_test 1.$tn.3.3 "
           87  +    SELECT row_number() OVER ( $window ) FROM t2
           88  +  "
           89  +
           90  +  execsql_test 1.$tn.4.1 "
           91  +    SELECT dense_rank() OVER ( ORDER BY a $window ) FROM t2
           92  +  "
           93  +  execsql_test 1.$tn.4.2 "
           94  +    SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY a $window ) FROM t2
           95  +  "
           96  +  execsql_test 1.$tn.4.3 "
           97  +    SELECT dense_rank() OVER ( ORDER BY b $window ) FROM t2
           98  +  "
           99  +  execsql_test 1.$tn.4.4 "
          100  +    SELECT dense_rank() OVER ( PARTITION BY b%10 ORDER BY b $window ) FROM t2
          101  +  "
          102  +  execsql_test 1.$tn.4.5 "
          103  +    SELECT dense_rank() OVER ( ORDER BY b%10 $window ) FROM t2
          104  +  "
          105  +  execsql_test 1.$tn.4.6 "
          106  +    SELECT dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 $window ) FROM t2
          107  +  "
          108  +
          109  +  execsql_test 1.$tn.5.1 "
          110  +    SELECT rank() OVER ( ORDER BY a $window ) FROM t2
          111  +  "
          112  +  execsql_test 1.$tn.5.2 "
          113  +    SELECT rank() OVER ( PARTITION BY b%10 ORDER BY a $window ) FROM t2
          114  +  "
          115  +  execsql_test 1.$tn.5.3 "
          116  +    SELECT rank() OVER ( ORDER BY b $window ) FROM t2
          117  +  "
          118  +  execsql_test 1.$tn.5.4 "
          119  +    SELECT rank() OVER ( PARTITION BY b%10 ORDER BY b $window ) FROM t2
          120  +  "
          121  +  execsql_test 1.$tn.5.5 "
          122  +    SELECT rank() OVER ( ORDER BY b%10 $window ) FROM t2
          123  +  "
          124  +  execsql_test 1.$tn.5.6 "
          125  +    SELECT rank() OVER ( PARTITION BY b%2 ORDER BY b%10 $window ) FROM t2
          126  +  "
          127  +
          128  +  execsql_test 1.$tn.6.1 "
          129  +    SELECT 
          130  +      row_number() OVER ( PARTITION BY b%2 ORDER BY b%10 $window ),
          131  +      rank() OVER ( PARTITION BY b%2 ORDER BY b%10 $window ),
          132  +      dense_rank() OVER ( PARTITION BY b%2 ORDER BY b%10 $window )
          133  +    FROM t2
          134  +  "
          135  +
          136  +  execsql_float_test 1.$tn.7.1 "
          137  +    SELECT percent_rank() OVER ( ORDER BY a $window ) FROM t2
          138  +  "
          139  +  execsql_float_test 1.$tn.7.2 "
          140  +    SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY a $window ) FROM t2
          141  +  "
          142  +  execsql_float_test 1.$tn.7.3 "
          143  +    SELECT percent_rank() OVER ( ORDER BY b $window ) FROM t2
          144  +  "
          145  +  execsql_float_test 1.$tn.7.4 "
          146  +    SELECT percent_rank() OVER ( PARTITION BY b%10 ORDER BY b $window ) FROM t2
          147  +  "
          148  +  execsql_float_test 1.$tn.7.5 "
          149  +    SELECT percent_rank() OVER ( ORDER BY b%10 $window ) FROM t2
          150  +  "
          151  +  execsql_float_test 1.$tn.7.6 "
          152  +    SELECT percent_rank() OVER (PARTITION BY b%2 ORDER BY b%10 $window) FROM t2
          153  +  "
          154  +
          155  +  execsql_float_test 1.$tn.8.1 "
          156  +    SELECT cume_dist() OVER ( ORDER BY a $window ) FROM t2
          157  +  "
          158  +  execsql_float_test 1.$tn.8.2 "
          159  +    SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY a $window ) FROM t2
          160  +  "
          161  +  execsql_float_test 1.$tn.8.3 "
          162  +    SELECT cume_dist() OVER ( ORDER BY b $window ) FROM t2
          163  +  "
          164  +  execsql_float_test 1.$tn.8.4 "
          165  +    SELECT cume_dist() OVER ( PARTITION BY b%10 ORDER BY b $window ) FROM t2
          166  +  "
          167  +  execsql_float_test 1.$tn.8.5 "
          168  +    SELECT cume_dist() OVER ( ORDER BY b%10 $window ) FROM t2
          169  +  "
          170  +  execsql_float_test 1.$tn.8.6 "
          171  +    SELECT cume_dist() OVER ( PARTITION BY b%2 ORDER BY b%10 $window ) FROM t2
          172  +  "
          173  +
          174  +  execsql_float_test 1.$tn.8.1 "
          175  +    SELECT ntile(100) OVER ( ORDER BY a $window ) FROM t2
          176  +  "
          177  +  execsql_float_test 1.$tn.8.2 "
          178  +    SELECT ntile(101) OVER ( PARTITION BY b%10 ORDER BY a $window ) FROM t2
          179  +  "
          180  +  execsql_float_test 1.$tn.8.3 "
          181  +    SELECT ntile(102) OVER ( ORDER BY b,a $window ) FROM t2
          182  +  "
          183  +  execsql_float_test 1.$tn.8.4 "
          184  +    SELECT ntile(103) OVER ( PARTITION BY b%10 ORDER BY b,a $window ) FROM t2
          185  +  "
          186  +  execsql_float_test 1.$tn.8.5 "
          187  +    SELECT ntile(104) OVER ( ORDER BY b%10,a $window ) FROM t2
          188  +  "
          189  +  execsql_float_test 1.$tn.8.6 "
          190  +    SELECT ntile(105) OVER (PARTITION BY b%2,a ORDER BY b%10 $window) FROM t2
          191  +  "
          192  +  execsql_float_test 1.$tn.8.7 "
          193  +    SELECT ntile(105) OVER ( $window ) FROM t2
          194  +  "
          195  +
          196  +  execsql_test 1.$tn.9.1 "
          197  +    SELECT last_value(a+b) OVER ( ORDER BY a $window ) FROM t2
          198  +  "
          199  +  execsql_test 1.$tn.9.2 "
          200  +    SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY a $window ) FROM t2
          201  +  "
          202  +  execsql_test 1.$tn.9.3 "
          203  +    SELECT last_value(a+b) OVER ( ORDER BY b,a $window ) FROM t2
          204  +  "
          205  +  execsql_test 1.$tn.9.4 "
          206  +    SELECT last_value(a+b) OVER ( PARTITION BY b%10 ORDER BY b,a $window ) FROM t2
          207  +  "
          208  +  execsql_test 1.$tn.9.5 "
          209  +    SELECT last_value(a+b) OVER ( ORDER BY b%10,a $window ) FROM t2
          210  +  "
          211  +  execsql_test 1.$tn.9.6 "
          212  +    SELECT last_value(a+b) OVER (PARTITION BY b%2,a ORDER BY b%10 $window) FROM t2
          213  +  "
          214  +
          215  +  execsql_test 1.$tn.10.1 "
          216  +    SELECT nth_value(b,b+1) OVER (ORDER BY a $window) FROM t2
          217  +  "
          218  +  execsql_test 1.$tn.10.2 "
          219  +    SELECT nth_value(b,b+1) OVER (PARTITION BY b%10 ORDER BY a $window) FROM t2
          220  +  "
          221  +  execsql_test 1.$tn.10.3 "
          222  +    SELECT nth_value(b,b+1) OVER ( ORDER BY b,a $window ) FROM t2
          223  +  "
          224  +  execsql_test 1.$tn.10.4 "
          225  +    SELECT nth_value(b,b+1) OVER ( PARTITION BY b%10 ORDER BY b,a $window ) FROM t2
          226  +  "
          227  +  execsql_test 1.$tn.10.5 "
          228  +    SELECT nth_value(b,b+1) OVER ( ORDER BY b%10,a $window ) FROM t2
          229  +  "
          230  +  execsql_test 1.$tn.10.6 "
          231  +    SELECT nth_value(b,b+1) OVER (PARTITION BY b%2,a ORDER BY b%10 $window) FROM t2
          232  +  "
          233  +
          234  +  execsql_test 1.$tn.11.1 "
          235  +    SELECT first_value(b) OVER (ORDER BY a $window) FROM t2
          236  +  "
          237  +  execsql_test 1.$tn.11.2 "
          238  +    SELECT first_value(b) OVER (PARTITION BY b%10 ORDER BY a $window) FROM t2
          239  +  "
          240  +  execsql_test 1.$tn.11.3 "
          241  +    SELECT first_value(b) OVER ( ORDER BY b,a $window ) FROM t2
          242  +  "
          243  +  execsql_test 1.$tn.11.4 "
          244  +    SELECT first_value(b) OVER ( PARTITION BY b%10 ORDER BY b,a $window ) FROM t2
          245  +  "
          246  +  execsql_test 1.$tn.11.5 "
          247  +    SELECT first_value(b) OVER ( ORDER BY b%10,a $window ) FROM t2
          248  +  "
          249  +  execsql_test 1.$tn.11.6 "
          250  +    SELECT first_value(b) OVER (PARTITION BY b%2,a ORDER BY b%10 $window) FROM t2
          251  +  "
          252  +
          253  +  execsql_test 1.$tn.12.1 "
          254  +    SELECT lead(b,b) OVER (ORDER BY a $window) FROM t2
          255  +  "
          256  +  execsql_test 1.$tn.12.2 "
          257  +    SELECT lead(b,b) OVER (PARTITION BY b%10 ORDER BY a $window) FROM t2
          258  +  "
          259  +  execsql_test 1.$tn.12.3 "
          260  +    SELECT lead(b,b) OVER ( ORDER BY b,a $window ) FROM t2
          261  +  "
          262  +  execsql_test 1.$tn.12.4 "
          263  +    SELECT lead(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a $window ) FROM t2
          264  +  "
          265  +  execsql_test 1.$tn.12.5 "
          266  +    SELECT lead(b,b) OVER ( ORDER BY b%10,a $window ) FROM t2
          267  +  "
          268  +  execsql_test 1.$tn.12.6 "
          269  +    SELECT lead(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 $window) FROM t2
          270  +  "
          271  +
          272  +  execsql_test 1.$tn.13.1 "
          273  +    SELECT lag(b,b) OVER (ORDER BY a $window) FROM t2
          274  +  "
          275  +  execsql_test 1.$tn.13.2 "
          276  +    SELECT lag(b,b) OVER (PARTITION BY b%10 ORDER BY a $window) FROM t2
          277  +  "
          278  +  execsql_test 1.$tn.13.3 "
          279  +    SELECT lag(b,b) OVER ( ORDER BY b,a $window ) FROM t2
          280  +  "
          281  +  execsql_test 1.$tn.13.4 "
          282  +    SELECT lag(b,b) OVER ( PARTITION BY b%10 ORDER BY b,a $window ) FROM t2
          283  +  "
          284  +  execsql_test 1.$tn.13.5 "
          285  +    SELECT lag(b,b) OVER ( ORDER BY b%10,a $window ) FROM t2
          286  +  "
          287  +  execsql_test 1.$tn.13.6 "
          288  +    SELECT lag(b,b) OVER (PARTITION BY b%2,a ORDER BY b%10 $window) FROM t2
          289  +  "
          290  +
          291  +  execsql_test 1.$tn.14.1 "
          292  +    SELECT string_agg(CAST(b AS TEXT), '.') OVER (ORDER BY a $window) FROM t2
          293  +  "
          294  +  execsql_test 1.$tn.14.2 "
          295  +    SELECT string_agg(CAST(b AS TEXT), '.') OVER (PARTITION BY b%10 ORDER BY a $window) FROM t2
          296  +  "
          297  +  execsql_test 1.$tn.14.3 "
          298  +    SELECT string_agg(CAST(b AS TEXT), '.') OVER ( ORDER BY b,a $window ) FROM t2
          299  +  "
          300  +  execsql_test 1.$tn.14.4 "
          301  +    SELECT string_agg(CAST(b AS TEXT), '.') OVER ( PARTITION BY b%10 ORDER BY b,a $window ) FROM t2
          302  +  "
          303  +  execsql_test 1.$tn.14.5 "
          304  +    SELECT string_agg(CAST(b AS TEXT), '.') OVER ( ORDER BY b%10,a $window ) FROM t2
          305  +  "
          306  +  execsql_test 1.$tn.14.6 "
          307  +    SELECT string_agg(CAST(b AS TEXT), '.') OVER (PARTITION BY b%2,a ORDER BY b%10 $window) FROM t2
          308  +  "
          309  +
          310  +  execsql_test 1.$tn.15.1 "
          311  +    SELECT string_agg(CAST(b AS TEXT), '.') 
          312  +    FILTER (WHERE a%2=0) OVER (ORDER BY a $window) FROM t2
          313  +  "
          314  +
          315  +  execsql_test 1.$tn.15.2 "
          316  +    SELECT string_agg(CAST(b AS TEXT), '.') 
          317  +    FILTER (WHERE 0=1) OVER (ORDER BY a $window) FROM t2
          318  +  "
          319  +
          320  +  execsql_test 1.$tn.15.3 "
          321  +    SELECT string_agg(CAST(b AS TEXT), '.') 
          322  +    FILTER (WHERE 1=0) OVER (PARTITION BY (a%10) ORDER BY a $window) FROM t2
          323  +  "
          324  +
          325  +  execsql_test 1.$tn.15.4 "
          326  +    SELECT string_agg(CAST(b AS TEXT), '.') 
          327  +    FILTER (WHERE a%2=0) OVER (PARTITION BY (a%10) ORDER BY a $window) FROM t2
          328  +  "
          329  +}
          330  +
          331  +finish_test
          332  +

Added test/window3.test.

cannot compute difference between binary files

Added test/window4.tcl.

            1  +# 2018 May 19
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +
           13  +source [file join [file dirname $argv0] pg_common.tcl]
           14  +
           15  +#=========================================================================
           16  +
           17  +start_test window4 "2018 June 04"
           18  +ifcapable !windowfunc
           19  +
           20  +execsql_test 1.0 {
           21  +  DROP TABLE IF EXISTS t3;
           22  +  CREATE TABLE t3(a TEXT PRIMARY KEY);
           23  +  INSERT INTO t3 VALUES('a'), ('b'), ('c'), ('d'), ('e');
           24  +  INSERT INTO t3 VALUES('f'), ('g'), ('h'), ('i'), ('j');
           25  +}
           26  +
           27  +for {set i 1} {$i < 20} {incr i} {
           28  +  execsql_test 1.$i "SELECT a, ntile($i) OVER (ORDER BY a) FROM t3"
           29  +}
           30  +
           31  +execsql_test 2.0 {
           32  +  DROP TABLE IF EXISTS t4;
           33  +  CREATE TABLE t4(a INTEGER PRIMARY KEY, b TEXT, c INTEGER);
           34  +  INSERT INTO t4 VALUES(1, 'A', 9);
           35  +  INSERT INTO t4 VALUES(2, 'B', 3);
           36  +  INSERT INTO t4 VALUES(3, 'C', 2);
           37  +  INSERT INTO t4 VALUES(4, 'D', 10);
           38  +  INSERT INTO t4 VALUES(5, 'E', 5);
           39  +  INSERT INTO t4 VALUES(6, 'F', 1);
           40  +  INSERT INTO t4 VALUES(7, 'G', 1);
           41  +  INSERT INTO t4 VALUES(8, 'H', 2);
           42  +  INSERT INTO t4 VALUES(9, 'I', 10);
           43  +  INSERT INTO t4 VALUES(10, 'J', 4);
           44  +}
           45  +
           46  +execsql_test 2.1 {
           47  +  SELECT a, nth_value(b, c) OVER (ORDER BY a) FROM t4
           48  +}
           49  +
           50  +execsql_test 2.2.1 {
           51  +  SELECT a, lead(b) OVER (ORDER BY a) FROM t4
           52  +}
           53  +execsql_test 2.2.2 {
           54  +  SELECT a, lead(b, 2) OVER (ORDER BY a) FROM t4
           55  +}
           56  +execsql_test 2.2.3 {
           57  +  SELECT a, lead(b, 3, 'abc') OVER (ORDER BY a) FROM t4
           58  +}
           59  +
           60  +execsql_test 2.3.1 {
           61  +  SELECT a, lag(b) OVER (ORDER BY a) FROM t4
           62  +}
           63  +execsql_test 2.3.2 {
           64  +  SELECT a, lag(b, 2) OVER (ORDER BY a) FROM t4
           65  +}
           66  +execsql_test 2.3.3 {
           67  +  SELECT a, lag(b, 3, 'abc') OVER (ORDER BY a) FROM t4
           68  +}
           69  +
           70  +execsql_test 2.4.1 {
           71  +  SELECT string_agg(b, '.') OVER (
           72  +    ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
           73  +  ) FROM t4
           74  +}
           75  +
           76  +execsql_test 3.0 {
           77  +  DROP TABLE IF EXISTS t5;
           78  +  CREATE TABLE t5(a INTEGER PRIMARY KEY, b TEXT, c TEXT, d INTEGER);
           79  +  INSERT INTO t5 VALUES(1, 'A', 'one',   5);
           80  +  INSERT INTO t5 VALUES(2, 'B', 'two',   4);
           81  +  INSERT INTO t5 VALUES(3, 'A', 'three', 3);
           82  +  INSERT INTO t5 VALUES(4, 'B', 'four',  2);
           83  +  INSERT INTO t5 VALUES(5, 'A', 'five',  1);
           84  +}
           85  +
           86  +execsql_test 3.1 {
           87  +  SELECT a, nth_value(c, d) OVER (ORDER BY b) FROM t5
           88  +}
           89  +
           90  +execsql_test 3.2 {
           91  +  SELECT a, nth_value(c, d) OVER (PARTITION BY b ORDER BY a) FROM t5
           92  +}
           93  +
           94  +execsql_test 3.3 {
           95  +  SELECT a, count(*) OVER abc, count(*) OVER def FROM t5
           96  +  WINDOW abc AS (ORDER BY a), 
           97  +         def AS (ORDER BY a DESC)
           98  +  ORDER BY a;
           99  +}
          100  +
          101  +execsql_test 3.4 {
          102  +  SELECT a, max(a) FILTER (WHERE (a%2)=0) OVER w FROM t5 
          103  +  WINDOW w AS (ORDER BY a)
          104  +}
          105  +
          106  +execsql_test 3.5.1 {
          107  +  SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 1 PRECEDING AND 2 PRECEDING)
          108  +  FROM t5
          109  +}
          110  +execsql_test 3.5.2 {
          111  +  SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
          112  +  FROM t5
          113  +}
          114  +execsql_test 3.5.3 {
          115  +  SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 0 PRECEDING AND 0 PRECEDING)
          116  +  FROM t5
          117  +}
          118  +
          119  +execsql_test 3.6.1 {
          120  +  SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 1 FOLLOWING)
          121  +  FROM t5
          122  +}
          123  +execsql_test 3.6.2 {
          124  +  SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING)
          125  +  FROM t5
          126  +}
          127  +execsql_test 3.6.3 {
          128  +  SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 0 FOLLOWING AND 0 FOLLOWING)
          129  +  FROM t5
          130  +}
          131  +
          132  +==========
          133  +
          134  +execsql_test 4.0 {
          135  +  DROP TABLE IF EXISTS ttt;
          136  +  CREATE TABLE ttt(a INTEGER PRIMARY KEY, b INTEGER, c INTEGER);
          137  +  INSERT INTO ttt VALUES(1, 1, 1);
          138  +  INSERT INTO ttt VALUES(2, 2, 2);
          139  +  INSERT INTO ttt VALUES(3, 3, 3);
          140  +
          141  +  INSERT INTO ttt VALUES(4, 1, 2);
          142  +  INSERT INTO ttt VALUES(5, 2, 3);
          143  +  INSERT INTO ttt VALUES(6, 3, 4);
          144  +
          145  +  INSERT INTO ttt VALUES(7, 1, 3);
          146  +  INSERT INTO ttt VALUES(8, 2, 4);
          147  +  INSERT INTO ttt VALUES(9, 3, 5);
          148  +}
          149  +
          150  +execsql_test 4.1 {
          151  +  SELECT max(c), max(b) OVER (ORDER BY b) FROM ttt GROUP BY b;
          152  +}
          153  +
          154  +execsql_test 4.2 {
          155  +  SELECT max(b) OVER (ORDER BY max(c)) FROM ttt GROUP BY b;
          156  +}
          157  +
          158  +execsql_test 4.3 {
          159  +  SELECT abs(max(b) OVER (ORDER BY b)) FROM ttt GROUP BY b;
          160  +}
          161  +
          162  +execsql_test 4.4 {
          163  +  SELECT sum(b) OVER (
          164  +    ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
          165  +  ) FROM ttt;
          166  +}
          167  +
          168  +set lPart  [list "PARTITION BY b" "PARTITION BY b, a" "" "PARTITION BY a"]
          169  +set lOrder [list "ORDER BY a" "ORDER BY a DESC" "" "ORDER BY b, a"]
          170  +set lRange {
          171  +    "RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW"
          172  +    "RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING"
          173  +    "RANGE BETWEEN CURRENT ROW AND CURRENT ROW"
          174  +    "RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING"
          175  +}
          176  +
          177  +set lRows {
          178  +    "ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING"
          179  +    "ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING"
          180  +    "ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING"
          181  +    "ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING"
          182  +    "ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING"
          183  +}
          184  +
          185  +set tn 1
          186  +set SQL {
          187  +  SELECT max(c) OVER ($p1 $o1 $r1), 
          188  +  min(c) OVER ($p2 $o2 $r2)
          189  +  FROM ttt ORDER BY a
          190  +}
          191  +set SQL2 {
          192  +  SELECT sum(c) OVER ($p1 $o1 $r1), 
          193  +         sum(c) OVER ($p2 $o2 $r2)
          194  +  FROM ttt ORDER BY a
          195  +}
          196  +
          197  +set o1 [lindex $lOrder 0]
          198  +set o2 [lindex $lOrder 0]
          199  +set r1 [lindex $lRange 0]
          200  +set r2 [lindex $lRange 0]
          201  +foreach p1 $lPart { foreach p2 $lPart { 
          202  +  execsql_test 4.5.$tn.1 [subst $SQL]
          203  +  execsql_test 4.5.$tn.2 [subst $SQL2]
          204  +  incr tn
          205  +}}
          206  +
          207  +set o1 [lindex $lOrder 0]
          208  +set o2 [lindex $lOrder 0]
          209  +set p1 [lindex $lPart 0]
          210  +set p2 [lindex $lPart 0]
          211  +foreach r1 $lRange { foreach r2 $lRange { 
          212  +  execsql_test 4.5.$tn.1 [subst $SQL]
          213  +  execsql_test 4.5.$tn.2 [subst $SQL2]
          214  +  incr tn
          215  +}}
          216  +foreach r1 $lRows { foreach r2 $lRows { 
          217  +  execsql_test 4.5.$tn.1 [subst $SQL]
          218  +  execsql_test 4.5.$tn.2 [subst $SQL2]
          219  +  incr tn
          220  +}}
          221  +
          222  +set r1 [lindex $lRange 0]
          223  +set r2 [lindex $lRange 0]
          224  +set p1 [lindex $lPart 0]
          225  +set p2 [lindex $lPart 0]
          226  +foreach o1 $lOrder { foreach o2 $lOrder { 
          227  +  execsql_test 4.5.$tn.1 [subst $SQL]
          228  +  execsql_test 4.5.$tn.2 [subst $SQL2]
          229  +  incr tn
          230  +}}
          231  +
          232  +==========
          233  +
          234  +execsql_test 7.0 {
          235  +  DROP TABLE IF EXISTS t1;
          236  +  CREATE TABLE t1(x INTEGER, y INTEGER);
          237  +  INSERT INTO t1 VALUES(1, 2);
          238  +  INSERT INTO t1 VALUES(3, 4);
          239  +  INSERT INTO t1 VALUES(5, 6);
          240  +  INSERT INTO t1 VALUES(7, 8);
          241  +  INSERT INTO t1 VALUES(9, 10);
          242  +}
          243  +
          244  +execsql_test 7.1 {
          245  +  SELECT lead(y) OVER win FROM t1
          246  +  WINDOW win AS (ORDER BY x)
          247  +}
          248  +
          249  +execsql_test 7.2 {
          250  +  SELECT lead(y, 2) OVER win FROM t1
          251  +  WINDOW win AS (ORDER BY x)
          252  +}
          253  +
          254  +execsql_test 7.3 {
          255  +  SELECT lead(y, 3, -1) OVER win FROM t1
          256  +  WINDOW win AS (ORDER BY x)
          257  +}
          258  +
          259  +execsql_test 7.4 {
          260  +  SELECT 
          261  +    lead(y) OVER win, lead(y) OVER win
          262  +  FROM t1
          263  +  WINDOW win AS (ORDER BY x)
          264  +}
          265  +
          266  +execsql_test 7.5 {
          267  +  SELECT 
          268  +    lead(y) OVER win, 
          269  +    lead(y, 2) OVER win, 
          270  +    lead(y, 3, -1) OVER win
          271  +  FROM t1
          272  +  WINDOW win AS (ORDER BY x)
          273  +}
          274  +
          275  +==========
          276  +
          277  +execsql_test 8.0 {
          278  +  DROP TABLE IF EXISTS t1;
          279  +  CREATE TABLE t1(a INTEGER, b INTEGER, c INTEGER, d INTEGER);
          280  +  INSERT INTO t1 VALUES(1, 2, 3, 4);
          281  +  INSERT INTO t1 VALUES(5, 6, 7, 8);
          282  +  INSERT INTO t1 VALUES(9, 10, 11, 12);
          283  +}
          284  +
          285  +execsql_test 8.1 {
          286  +  SELECT row_number() OVER win,
          287  +         nth_value(d,2) OVER win,
          288  +         lead(d) OVER win
          289  +  FROM t1
          290  +  WINDOW win AS (ORDER BY a)
          291  +}
          292  +
          293  +execsql_test 8.2 {
          294  +    SELECT row_number() OVER win,
          295  +           rank() OVER win,
          296  +           dense_rank() OVER win,
          297  +           ntile(2) OVER win,
          298  +           first_value(d) OVER win,
          299  +           last_value(d) OVER win,
          300  +           nth_value(d,2) OVER win,
          301  +           lead(d) OVER win,
          302  +           lag(d) OVER win,
          303  +           max(d) OVER win,
          304  +           min(d) OVER win
          305  +    FROM t1
          306  +    WINDOW win AS (ORDER BY a)
          307  +}
          308  +
          309  +==========
          310  +
          311  +execsql_test 9.0 {
          312  +  DROP TABLE IF EXISTS t2;
          313  +  CREATE TABLE t2(x INTEGER);
          314  +  INSERT INTO t2 VALUES(1), (1), (1), (4), (4), (6), (7);
          315  +}
          316  +
          317  +execsql_test 9.1 {
          318  +  SELECT rank() OVER () FROM t2
          319  +}
          320  +execsql_test 9.2 {
          321  +  SELECT dense_rank() OVER (PARTITION BY x) FROM t2
          322  +}
          323  +execsql_float_test 9.3 {
          324  +  SELECT x, percent_rank() OVER (PARTITION BY x ORDER BY x) FROM t2
          325  +}
          326  +
          327  +execsql_test 9.4 {
          328  +  SELECT x, rank() OVER (ORDER BY x) FROM t2 ORDER BY 1,2
          329  +}
          330  +
          331  +execsql_test 9.5 {
          332  +  SELECT DISTINCT x, rank() OVER (ORDER BY x) FROM t2 ORDER BY 1,2
          333  +}
          334  +
          335  +finish_test
          336  +

Added test/window4.test.

            1  +# 2018 June 04
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +# This file implements regression tests for SQLite library.
           12  +#
           13  +
           14  +####################################################
           15  +# DO NOT EDIT! THIS FILE IS AUTOMATICALLY GENERATED!
           16  +####################################################
           17  +
           18  +set testdir [file dirname $argv0]
           19  +source $testdir/tester.tcl
           20  +set testprefix window4
           21  +
           22  +ifcapable !windowfunc { finish_test ; return }
           23  +do_execsql_test 1.0 {
           24  +  DROP TABLE IF EXISTS t3;
           25  +  CREATE TABLE t3(a TEXT PRIMARY KEY);
           26  +  INSERT INTO t3 VALUES('a'), ('b'), ('c'), ('d'), ('e');
           27  +  INSERT INTO t3 VALUES('f'), ('g'), ('h'), ('i'), ('j');
           28  +} {}
           29  +
           30  +do_execsql_test 1.1 {
           31  +  SELECT a, ntile(1) OVER (ORDER BY a) FROM t3
           32  +} {a 1   b 1   c 1   d 1   e 1   f 1   g 1   h 1   i 1   j 1}
           33  +
           34  +do_execsql_test 1.2 {
           35  +  SELECT a, ntile(2) OVER (ORDER BY a) FROM t3
           36  +} {a 1   b 1   c 1   d 1   e 1   f 2   g 2   h 2   i 2   j 2}
           37  +
           38  +do_execsql_test 1.3 {
           39  +  SELECT a, ntile(3) OVER (ORDER BY a) FROM t3
           40  +} {a 1   b 1   c 1   d 1   e 2   f 2   g 2   h 3   i 3   j 3}
           41  +
           42  +do_execsql_test 1.4 {
           43  +  SELECT a, ntile(4) OVER (ORDER BY a) FROM t3
           44  +} {a 1   b 1   c 1   d 2   e 2   f 2   g 3   h 3   i 4   j 4}
           45  +
           46  +do_execsql_test 1.5 {
           47  +  SELECT a, ntile(5) OVER (ORDER BY a) FROM t3
           48  +} {a 1   b 1   c 2   d 2   e 3   f 3   g 4   h 4   i 5   j 5}
           49  +
           50  +do_execsql_test 1.6 {
           51  +  SELECT a, ntile(6) OVER (ORDER BY a) FROM t3
           52  +} {a 1   b 1   c 2   d 2   e 3   f 3   g 4   h 4   i 5   j 6}
           53  +
           54  +do_execsql_test 1.7 {
           55  +  SELECT a, ntile(7) OVER (ORDER BY a) FROM t3
           56  +} {a 1   b 1   c 2   d 2   e 3   f 3   g 4   h 5   i 6   j 7}
           57  +
           58  +do_execsql_test 1.8 {
           59  +  SELECT a, ntile(8) OVER (ORDER BY a) FROM t3
           60  +} {a 1   b 1   c 2   d 2   e 3   f 4   g 5   h 6   i 7   j 8}
           61  +
           62  +do_execsql_test 1.9 {
           63  +  SELECT a, ntile(9) OVER (ORDER BY a) FROM t3
           64  +} {a 1   b 1   c 2   d 3   e 4   f 5   g 6   h 7   i 8   j 9}
           65  +
           66  +do_execsql_test 1.10 {
           67  +  SELECT a, ntile(10) OVER (ORDER BY a) FROM t3
           68  +} {a 1   b 2   c 3   d 4   e 5   f 6   g 7   h 8   i 9   j 10}
           69  +
           70  +do_execsql_test 1.11 {
           71  +  SELECT a, ntile(11) OVER (ORDER BY a) FROM t3
           72  +} {a 1   b 2   c 3   d 4   e 5   f 6   g 7   h 8   i 9   j 10}
           73  +
           74  +do_execsql_test 1.12 {
           75  +  SELECT a, ntile(12) OVER (ORDER BY a) FROM t3
           76  +} {a 1   b 2   c 3   d 4   e 5   f 6   g 7   h 8   i 9   j 10}
           77  +
           78  +do_execsql_test 1.13 {
           79  +  SELECT a, ntile(13) OVER (ORDER BY a) FROM t3
           80  +} {a 1   b 2   c 3   d 4   e 5   f 6   g 7   h 8   i 9   j 10}
           81  +
           82  +do_execsql_test 1.14 {
           83  +  SELECT a, ntile(14) OVER (ORDER BY a) FROM t3
           84  +} {a 1   b 2   c 3   d 4   e 5   f 6   g 7   h 8   i 9   j 10}
           85  +
           86  +do_execsql_test 1.15 {
           87  +  SELECT a, ntile(15) OVER (ORDER BY a) FROM t3
           88  +} {a 1   b 2   c 3   d 4   e 5   f 6   g 7   h 8   i 9   j 10}
           89  +
           90  +do_execsql_test 1.16 {
           91  +  SELECT a, ntile(16) OVER (ORDER BY a) FROM t3
           92  +} {a 1   b 2   c 3   d 4   e 5   f 6   g 7   h 8   i 9   j 10}
           93  +
           94  +do_execsql_test 1.17 {
           95  +  SELECT a, ntile(17) OVER (ORDER BY a) FROM t3
           96  +} {a 1   b 2   c 3   d 4   e 5   f 6   g 7   h 8   i 9   j 10}
           97  +
           98  +do_execsql_test 1.18 {
           99  +  SELECT a, ntile(18) OVER (ORDER BY a) FROM t3
          100  +} {a 1   b 2   c 3   d 4   e 5   f 6   g 7   h 8   i 9   j 10}
          101  +
          102  +do_execsql_test 1.19 {
          103  +  SELECT a, ntile(19) OVER (ORDER BY a) FROM t3
          104  +} {a 1   b 2   c 3   d 4   e 5   f 6   g 7   h 8   i 9   j 10}
          105  +
          106  +do_execsql_test 2.0 {
          107  +  DROP TABLE IF EXISTS t4;
          108  +  CREATE TABLE t4(a INTEGER PRIMARY KEY, b TEXT, c INTEGER);
          109  +  INSERT INTO t4 VALUES(1, 'A', 9);
          110  +  INSERT INTO t4 VALUES(2, 'B', 3);
          111  +  INSERT INTO t4 VALUES(3, 'C', 2);
          112  +  INSERT INTO t4 VALUES(4, 'D', 10);
          113  +  INSERT INTO t4 VALUES(5, 'E', 5);
          114  +  INSERT INTO t4 VALUES(6, 'F', 1);
          115  +  INSERT INTO t4 VALUES(7, 'G', 1);
          116  +  INSERT INTO t4 VALUES(8, 'H', 2);
          117  +  INSERT INTO t4 VALUES(9, 'I', 10);
          118  +  INSERT INTO t4 VALUES(10, 'J', 4);
          119  +} {}
          120  +
          121  +do_execsql_test 2.1 {
          122  +  SELECT a, nth_value(b, c) OVER (ORDER BY a) FROM t4
          123  +} {1 {}   2 {}   3 B   4 {}   5 E   6 A   7 A   8 B   9 {}   10 D}
          124  +
          125  +do_execsql_test 2.2.1 {
          126  +  SELECT a, lead(b) OVER (ORDER BY a) FROM t4
          127  +} {1 B   2 C   3 D   4 E   5 F   6 G   7 H   8 I   9 J   10 {}}
          128  +
          129  +do_execsql_test 2.2.2 {
          130  +  SELECT a, lead(b, 2) OVER (ORDER BY a) FROM t4
          131  +} {1 C   2 D   3 E   4 F   5 G   6 H   7 I   8 J   9 {}   10 {}}
          132  +
          133  +do_execsql_test 2.2.3 {
          134  +  SELECT a, lead(b, 3, 'abc') OVER (ORDER BY a) FROM t4
          135  +} {1 D   2 E   3 F   4 G   5 H   6 I   7 J   8 abc   9 abc   10 abc}
          136  +
          137  +do_execsql_test 2.3.1 {
          138  +  SELECT a, lag(b) OVER (ORDER BY a) FROM t4
          139  +} {1 {}   2 A   3 B   4 C   5 D   6 E   7 F   8 G   9 H   10 I}
          140  +
          141  +do_execsql_test 2.3.2 {
          142  +  SELECT a, lag(b, 2) OVER (ORDER BY a) FROM t4
          143  +} {1 {}   2 {}   3 A   4 B   5 C   6 D   7 E   8 F   9 G   10 H}
          144  +
          145  +do_execsql_test 2.3.3 {
          146  +  SELECT a, lag(b, 3, 'abc') OVER (ORDER BY a) FROM t4
          147  +} {1 abc   2 abc   3 abc   4 A   5 B   6 C   7 D   8 E   9 F   10 G}
          148  +
          149  +do_execsql_test 2.4.1 {
          150  +  SELECT group_concat(b, '.') OVER (
          151  +    ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
          152  +  ) FROM t4
          153  +} {A.B.C.D.E.F.G.H.I.J   B.C.D.E.F.G.H.I.J   C.D.E.F.G.H.I.J   D.E.F.G.H.I.J   E.F.G.H.I.J   F.G.H.I.J   G.H.I.J   H.I.J   I.J   J}
          154  +
          155  +do_execsql_test 3.0 {
          156  +  DROP TABLE IF EXISTS t5;
          157  +  CREATE TABLE t5(a INTEGER PRIMARY KEY, b TEXT, c TEXT, d INTEGER);
          158  +  INSERT INTO t5 VALUES(1, 'A', 'one',   5);
          159  +  INSERT INTO t5 VALUES(2, 'B', 'two',   4);
          160  +  INSERT INTO t5 VALUES(3, 'A', 'three', 3);
          161  +  INSERT INTO t5 VALUES(4, 'B', 'four',  2);
          162  +  INSERT INTO t5 VALUES(5, 'A', 'five',  1);
          163  +} {}
          164  +
          165  +do_execsql_test 3.1 {
          166  +  SELECT a, nth_value(c, d) OVER (ORDER BY b) FROM t5
          167  +} {1 {}   3 five   5 one   2 two   4 three}
          168  +
          169  +do_execsql_test 3.2 {
          170  +  SELECT a, nth_value(c, d) OVER (PARTITION BY b ORDER BY a) FROM t5
          171  +} {1 {}   3 {}   5 one   2 {}   4 four}
          172  +
          173  +do_execsql_test 3.3 {
          174  +  SELECT a, count(*) OVER abc, count(*) OVER def FROM t5
          175  +  WINDOW abc AS (ORDER BY a), 
          176  +         def AS (ORDER BY a DESC)
          177  +  ORDER BY a;
          178  +} {1 1 5   2 2 4   3 3 3   4 4 2   5 5 1}
          179  +
          180  +do_execsql_test 3.4 {
          181  +  SELECT a, max(a) FILTER (WHERE (a%2)=0) OVER w FROM t5 
          182  +  WINDOW w AS (ORDER BY a)
          183  +} {1 {}   2 2   3 2   4 4   5 4}
          184  +
          185  +do_execsql_test 3.5.1 {
          186  +  SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 1 PRECEDING AND 2 PRECEDING)
          187  +  FROM t5
          188  +} {1 {}   2 {}   3 {}   4 {}   5 {}}
          189  +
          190  +do_execsql_test 3.5.2 {
          191  +  SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
          192  +  FROM t5
          193  +} {1 {}   2 one   3 two   4 three   5 four}
          194  +
          195  +do_execsql_test 3.5.3 {
          196  +  SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 0 PRECEDING AND 0 PRECEDING)
          197  +  FROM t5
          198  +} {1 one   2 two   3 three   4 four   5 five}
          199  +
          200  +do_execsql_test 3.6.1 {
          201  +  SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 1 FOLLOWING)
          202  +  FROM t5
          203  +} {1 {}   2 {}   3 {}   4 {}   5 {}}
          204  +
          205  +do_execsql_test 3.6.2 {
          206  +  SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING)
          207  +  FROM t5
          208  +} {1 two   2 three   3 four   4 five   5 {}}
          209  +
          210  +do_execsql_test 3.6.3 {
          211  +  SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 0 FOLLOWING AND 0 FOLLOWING)
          212  +  FROM t5
          213  +} {1 one   2 two   3 three   4 four   5 five}
          214  +
          215  +#==========================================================================
          216  +
          217  +do_execsql_test 4.0 {
          218  +  DROP TABLE IF EXISTS ttt;
          219  +  CREATE TABLE ttt(a INTEGER PRIMARY KEY, b INTEGER, c INTEGER);
          220  +  INSERT INTO ttt VALUES(1, 1, 1);
          221  +  INSERT INTO ttt VALUES(2, 2, 2);
          222  +  INSERT INTO ttt VALUES(3, 3, 3);
          223  +
          224  +  INSERT INTO ttt VALUES(4, 1, 2);
          225  +  INSERT INTO ttt VALUES(5, 2, 3);
          226  +  INSERT INTO ttt VALUES(6, 3, 4);
          227  +
          228  +  INSERT INTO ttt VALUES(7, 1, 3);
          229  +  INSERT INTO ttt VALUES(8, 2, 4);
          230  +  INSERT INTO ttt VALUES(9, 3, 5);
          231  +} {}
          232  +
          233  +do_execsql_test 4.1 {
          234  +  SELECT max(c), max(b) OVER (ORDER BY b) FROM ttt GROUP BY b;
          235  +} {3 1   4 2   5 3}
          236  +
          237  +do_execsql_test 4.2 {
          238  +  SELECT max(b) OVER (ORDER BY max(c)) FROM ttt GROUP BY b;
          239  +} {1   2   3}
          240  +
          241  +do_execsql_test 4.3 {
          242  +  SELECT abs(max(b) OVER (ORDER BY b)) FROM ttt GROUP BY b;
          243  +} {1   2   3}
          244  +
          245  +do_execsql_test 4.4 {
          246  +  SELECT sum(b) OVER (
          247  +    ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
          248  +  ) FROM ttt;
          249  +} {18   17   15   12   11   9   6   5   3}
          250  +
          251  +do_execsql_test 4.5.1.1 {
          252  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          253  +  min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          254  +  FROM ttt ORDER BY a
          255  +} {1 1   2 2   3 3   2 1   3 2   4 3   3 1   4 2   5 3}
          256  +
          257  +do_execsql_test 4.5.1.2 {
          258  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          259  +         sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          260  +  FROM ttt ORDER BY a
          261  +} {1 1   2 2   3 3   3 3   5 5   7 7   6 6   9 9   12 12}
          262  +
          263  +do_execsql_test 4.5.2.1 {
          264  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          265  +  min(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          266  +  FROM ttt ORDER BY a
          267  +} {1 1   2 2   3 3   2 2   3 3   4 4   3 3   4 4   5 5}
          268  +
          269  +do_execsql_test 4.5.2.2 {
          270  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          271  +         sum(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          272  +  FROM ttt ORDER BY a
          273  +} {1 1   2 2   3 3   3 2   5 3   7 4   6 3   9 4   12 5}
          274  +
          275  +do_execsql_test 4.5.3.1 {
          276  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          277  +  min(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          278  +  FROM ttt ORDER BY a
          279  +} {1 1   2 1   3 1   2 1   3 1   4 1   3 1   4 1   5 1}
          280  +
          281  +do_execsql_test 4.5.3.2 {
          282  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          283  +         sum(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          284  +  FROM ttt ORDER BY a
          285  +} {1 1   2 3   3 6   3 8   5 11   7 15   6 18   9 22   12 27}
          286  +
          287  +do_execsql_test 4.5.4.1 {
          288  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          289  +  min(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          290  +  FROM ttt ORDER BY a
          291  +} {1 1   2 2   3 3   2 2   3 3   4 4   3 3   4 4   5 5}
          292  +
          293  +do_execsql_test 4.5.4.2 {
          294  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          295  +         sum(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          296  +  FROM ttt ORDER BY a
          297  +} {1 1   2 2   3 3   3 2   5 3   7 4   6 3   9 4   12 5}
          298  +
          299  +do_execsql_test 4.5.5.1 {
          300  +  SELECT max(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          301  +  min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          302  +  FROM ttt ORDER BY a
          303  +} {1 1   2 2   3 3   2 1   3 2   4 3   3 1   4 2   5 3}
          304  +
          305  +do_execsql_test 4.5.5.2 {
          306  +  SELECT sum(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          307  +         sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          308  +  FROM ttt ORDER BY a
          309  +} {1 1   2 2   3 3   2 3   3 5   4 7   3 6   4 9   5 12}
          310  +
          311  +do_execsql_test 4.5.6.1 {
          312  +  SELECT max(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          313  +  min(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          314  +  FROM ttt ORDER BY a
          315  +} {1 1   2 2   3 3   2 2   3 3   4 4   3 3   4 4   5 5}
          316  +
          317  +do_execsql_test 4.5.6.2 {
          318  +  SELECT sum(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          319  +         sum(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          320  +  FROM ttt ORDER BY a
          321  +} {1 1   2 2   3 3   2 2   3 3   4 4   3 3   4 4   5 5}
          322  +
          323  +do_execsql_test 4.5.7.1 {
          324  +  SELECT max(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          325  +  min(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          326  +  FROM ttt ORDER BY a
          327  +} {1 1   2 1   3 1   2 1   3 1   4 1   3 1   4 1   5 1}
          328  +
          329  +do_execsql_test 4.5.7.2 {
          330  +  SELECT sum(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          331  +         sum(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          332  +  FROM ttt ORDER BY a
          333  +} {1 1   2 3   3 6   2 8   3 11   4 15   3 18   4 22   5 27}
          334  +
          335  +do_execsql_test 4.5.8.1 {
          336  +  SELECT max(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          337  +  min(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          338  +  FROM ttt ORDER BY a
          339  +} {1 1   2 2   3 3   2 2   3 3   4 4   3 3   4 4   5 5}
          340  +
          341  +do_execsql_test 4.5.8.2 {
          342  +  SELECT sum(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          343  +         sum(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          344  +  FROM ttt ORDER BY a
          345  +} {1 1   2 2   3 3   2 2   3 3   4 4   3 3   4 4   5 5}
          346  +
          347  +do_execsql_test 4.5.9.1 {
          348  +  SELECT max(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          349  +  min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          350  +  FROM ttt ORDER BY a
          351  +} {1 1   2 2   3 3   3 1   3 2   4 3   4 1   4 2   5 3}
          352  +
          353  +do_execsql_test 4.5.9.2 {
          354  +  SELECT sum(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          355  +         sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          356  +  FROM ttt ORDER BY a
          357  +} {1 1   3 2   6 3   8 3   11 5   15 7   18 6   22 9   27 12}
          358  +
          359  +do_execsql_test 4.5.10.1 {
          360  +  SELECT max(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          361  +  min(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          362  +  FROM ttt ORDER BY a
          363  +} {1 1   2 2   3 3   3 2   3 3   4 4   4 3   4 4   5 5}
          364  +
          365  +do_execsql_test 4.5.10.2 {
          366  +  SELECT sum(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          367  +         sum(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          368  +  FROM ttt ORDER BY a
          369  +} {1 1   3 2   6 3   8 2   11 3   15 4   18 3   22 4   27 5}
          370  +
          371  +do_execsql_test 4.5.11.1 {
          372  +  SELECT max(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          373  +  min(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          374  +  FROM ttt ORDER BY a
          375  +} {1 1   2 1   3 1   3 1   3 1   4 1   4 1   4 1   5 1}
          376  +
          377  +do_execsql_test 4.5.11.2 {
          378  +  SELECT sum(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          379  +         sum(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          380  +  FROM ttt ORDER BY a
          381  +} {1 1   3 3   6 6   8 8   11 11   15 15   18 18   22 22   27 27}
          382  +
          383  +do_execsql_test 4.5.12.1 {
          384  +  SELECT max(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          385  +  min(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          386  +  FROM ttt ORDER BY a
          387  +} {1 1   2 2   3 3   3 2   3 3   4 4   4 3   4 4   5 5}
          388  +
          389  +do_execsql_test 4.5.12.2 {
          390  +  SELECT sum(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          391  +         sum(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          392  +  FROM ttt ORDER BY a
          393  +} {1 1   3 2   6 3   8 2   11 3   15 4   18 3   22 4   27 5}
          394  +
          395  +do_execsql_test 4.5.13.1 {
          396  +  SELECT max(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          397  +  min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          398  +  FROM ttt ORDER BY a
          399  +} {1 1   2 2   3 3   2 1   3 2   4 3   3 1   4 2   5 3}
          400  +
          401  +do_execsql_test 4.5.13.2 {
          402  +  SELECT sum(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          403  +         sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          404  +  FROM ttt ORDER BY a
          405  +} {1 1   2 2   3 3   2 3   3 5   4 7   3 6   4 9   5 12}
          406  +
          407  +do_execsql_test 4.5.14.1 {
          408  +  SELECT max(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          409  +  min(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          410  +  FROM ttt ORDER BY a
          411  +} {1 1   2 2   3 3   2 2   3 3   4 4   3 3   4 4   5 5}
          412  +
          413  +do_execsql_test 4.5.14.2 {
          414  +  SELECT sum(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          415  +         sum(c) OVER (PARTITION BY b, a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          416  +  FROM ttt ORDER BY a
          417  +} {1 1   2 2   3 3   2 2   3 3   4 4   3 3   4 4   5 5}
          418  +
          419  +do_execsql_test 4.5.15.1 {
          420  +  SELECT max(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          421  +  min(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          422  +  FROM ttt ORDER BY a
          423  +} {1 1   2 1   3 1   2 1   3 1   4 1   3 1   4 1   5 1}
          424  +
          425  +do_execsql_test 4.5.15.2 {
          426  +  SELECT sum(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          427  +         sum(c) OVER ( ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          428  +  FROM ttt ORDER BY a
          429  +} {1 1   2 3   3 6   2 8   3 11   4 15   3 18   4 22   5 27}
          430  +
          431  +do_execsql_test 4.5.16.1 {
          432  +  SELECT max(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          433  +  min(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          434  +  FROM ttt ORDER BY a
          435  +} {1 1   2 2   3 3   2 2   3 3   4 4   3 3   4 4   5 5}
          436  +
          437  +do_execsql_test 4.5.16.2 {
          438  +  SELECT sum(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          439  +         sum(c) OVER (PARTITION BY a ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          440  +  FROM ttt ORDER BY a
          441  +} {1 1   2 2   3 3   2 2   3 3   4 4   3 3   4 4   5 5}
          442  +
          443  +do_execsql_test 4.5.17.1 {
          444  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          445  +  min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          446  +  FROM ttt ORDER BY a
          447  +} {1 1   2 2   3 3   2 1   3 2   4 3   3 1   4 2   5 3}
          448  +
          449  +do_execsql_test 4.5.17.2 {
          450  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          451  +         sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          452  +  FROM ttt ORDER BY a
          453  +} {1 1   2 2   3 3   3 3   5 5   7 7   6 6   9 9   12 12}
          454  +
          455  +do_execsql_test 4.5.18.1 {
          456  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          457  +  min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
          458  +  FROM ttt ORDER BY a
          459  +} {1 1   2 2   3 3   2 1   3 2   4 3   3 1   4 2   5 3}
          460  +
          461  +do_execsql_test 4.5.18.2 {
          462  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          463  +         sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
          464  +  FROM ttt ORDER BY a
          465  +} {1 6   2 9   3 12   3 6   5 9   7 12   6 6   9 9   12 12}
          466  +
          467  +do_execsql_test 4.5.19.1 {
          468  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          469  +  min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW)
          470  +  FROM ttt ORDER BY a
          471  +} {1 1   2 2   3 3   2 2   3 3   4 4   3 3   4 4   5 5}
          472  +
          473  +do_execsql_test 4.5.19.2 {
          474  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          475  +         sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW)
          476  +  FROM ttt ORDER BY a
          477  +} {1 1   2 2   3 3   3 2   5 3   7 4   6 3   9 4   12 5}
          478  +
          479  +do_execsql_test 4.5.20.1 {
          480  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          481  +  min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
          482  +  FROM ttt ORDER BY a
          483  +} {1 1   2 2   3 3   2 2   3 3   4 4   3 3   4 4   5 5}
          484  +
          485  +do_execsql_test 4.5.20.2 {
          486  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          487  +         sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
          488  +  FROM ttt ORDER BY a
          489  +} {1 6   2 9   3 12   3 5   5 7   7 9   6 3   9 4   12 5}
          490  +
          491  +do_execsql_test 4.5.21.1 {
          492  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING), 
          493  +  min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          494  +  FROM ttt ORDER BY a
          495  +} {3 1   4 2   5 3   3 1   4 2   5 3   3 1   4 2   5 3}
          496  +
          497  +do_execsql_test 4.5.21.2 {
          498  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING), 
          499  +         sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          500  +  FROM ttt ORDER BY a
          501  +} {6 1   9 2   12 3   6 3   9 5   12 7   6 6   9 9   12 12}
          502  +
          503  +do_execsql_test 4.5.22.1 {
          504  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING), 
          505  +  min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
          506  +  FROM ttt ORDER BY a
          507  +} {3 1   4 2   5 3   3 1   4 2   5 3   3 1   4 2   5 3}
          508  +
          509  +do_execsql_test 4.5.22.2 {
          510  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING), 
          511  +         sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
          512  +  FROM ttt ORDER BY a
          513  +} {6 6   9 9   12 12   6 6   9 9   12 12   6 6   9 9   12 12}
          514  +
          515  +do_execsql_test 4.5.23.1 {
          516  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING), 
          517  +  min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW)
          518  +  FROM ttt ORDER BY a
          519  +} {3 1   4 2   5 3   3 2   4 3   5 4   3 3   4 4   5 5}
          520  +
          521  +do_execsql_test 4.5.23.2 {
          522  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING), 
          523  +         sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW)
          524  +  FROM ttt ORDER BY a
          525  +} {6 1   9 2   12 3   6 2   9 3   12 4   6 3   9 4   12 5}
          526  +
          527  +do_execsql_test 4.5.24.1 {
          528  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING), 
          529  +  min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
          530  +  FROM ttt ORDER BY a
          531  +} {3 1   4 2   5 3   3 2   4 3   5 4   3 3   4 4   5 5}
          532  +
          533  +do_execsql_test 4.5.24.2 {
          534  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING), 
          535  +         sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
          536  +  FROM ttt ORDER BY a
          537  +} {6 6   9 9   12 12   6 5   9 7   12 9   6 3   9 4   12 5}
          538  +
          539  +do_execsql_test 4.5.25.1 {
          540  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW), 
          541  +  min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          542  +  FROM ttt ORDER BY a
          543  +} {1 1   2 2   3 3   2 1   3 2   4 3   3 1   4 2   5 3}
          544  +
          545  +do_execsql_test 4.5.25.2 {
          546  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW), 
          547  +         sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          548  +  FROM ttt ORDER BY a
          549  +} {1 1   2 2   3 3   2 3   3 5   4 7   3 6   4 9   5 12}
          550  +
          551  +do_execsql_test 4.5.26.1 {
          552  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW), 
          553  +  min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
          554  +  FROM ttt ORDER BY a
          555  +} {1 1   2 2   3 3   2 1   3 2   4 3   3 1   4 2   5 3}
          556  +
          557  +do_execsql_test 4.5.26.2 {
          558  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW), 
          559  +         sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
          560  +  FROM ttt ORDER BY a
          561  +} {1 6   2 9   3 12   2 6   3 9   4 12   3 6   4 9   5 12}
          562  +
          563  +do_execsql_test 4.5.27.1 {
          564  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW), 
          565  +  min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW)
          566  +  FROM ttt ORDER BY a
          567  +} {1 1   2 2   3 3   2 2   3 3   4 4   3 3   4 4   5 5}
          568  +
          569  +do_execsql_test 4.5.27.2 {
          570  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW), 
          571  +         sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW)
          572  +  FROM ttt ORDER BY a
          573  +} {1 1   2 2   3 3   2 2   3 3   4 4   3 3   4 4   5 5}
          574  +
          575  +do_execsql_test 4.5.28.1 {
          576  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW), 
          577  +  min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
          578  +  FROM ttt ORDER BY a
          579  +} {1 1   2 2   3 3   2 2   3 3   4 4   3 3   4 4   5 5}
          580  +
          581  +do_execsql_test 4.5.28.2 {
          582  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW), 
          583  +         sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
          584  +  FROM ttt ORDER BY a
          585  +} {1 6   2 9   3 12   2 5   3 7   4 9   3 3   4 4   5 5}
          586  +
          587  +do_execsql_test 4.5.29.1 {
          588  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING), 
          589  +  min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          590  +  FROM ttt ORDER BY a
          591  +} {3 1   4 2   5 3   3 1   4 2   5 3   3 1   4 2   5 3}
          592  +
          593  +do_execsql_test 4.5.29.2 {
          594  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING), 
          595  +         sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          596  +  FROM ttt ORDER BY a
          597  +} {6 1   9 2   12 3   5 3   7 5   9 7   3 6   4 9   5 12}
          598  +
          599  +do_execsql_test 4.5.30.1 {
          600  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING), 
          601  +  min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
          602  +  FROM ttt ORDER BY a
          603  +} {3 1   4 2   5 3   3 1   4 2   5 3   3 1   4 2   5 3}
          604  +
          605  +do_execsql_test 4.5.30.2 {
          606  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING), 
          607  +         sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
          608  +  FROM ttt ORDER BY a
          609  +} {6 6   9 9   12 12   5 6   7 9   9 12   3 6   4 9   5 12}
          610  +
          611  +do_execsql_test 4.5.31.1 {
          612  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING), 
          613  +  min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW)
          614  +  FROM ttt ORDER BY a
          615  +} {3 1   4 2   5 3   3 2   4 3   5 4   3 3   4 4   5 5}
          616  +
          617  +do_execsql_test 4.5.31.2 {
          618  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING), 
          619  +         sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND CURRENT ROW)
          620  +  FROM ttt ORDER BY a
          621  +} {6 1   9 2   12 3   5 2   7 3   9 4   3 3   4 4   5 5}
          622  +
          623  +do_execsql_test 4.5.32.1 {
          624  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING), 
          625  +  min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
          626  +  FROM ttt ORDER BY a
          627  +} {3 1   4 2   5 3   3 2   4 3   5 4   3 3   4 4   5 5}
          628  +
          629  +do_execsql_test 4.5.32.2 {
          630  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING), 
          631  +         sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
          632  +  FROM ttt ORDER BY a
          633  +} {6 6   9 9   12 12   5 5   7 7   9 9   3 3   4 4   5 5}
          634  +
          635  +do_execsql_test 4.5.33.1 {
          636  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING), 
          637  +  min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING)
          638  +  FROM ttt ORDER BY a
          639  +} {2 1   3 2   4 3   3 1   4 2   5 3   3 1   4 2   5 3}
          640  +
          641  +do_execsql_test 4.5.33.2 {
          642  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING), 
          643  +         sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING)
          644  +  FROM ttt ORDER BY a
          645  +} {3 3   5 5   7 7   6 6   9 9   12 12   6 6   9 9   12 12}
          646  +
          647  +do_execsql_test 4.5.34.1 {
          648  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING), 
          649  +  min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING)
          650  +  FROM ttt ORDER BY a
          651  +} {2 1   3 2   4 3   3 1   4 2   5 3   3 1   4 2   5 3}
          652  +
          653  +do_execsql_test 4.5.34.2 {
          654  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING), 
          655  +         sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING)
          656  +  FROM ttt ORDER BY a
          657  +} {3 6   5 9   7 12   6 6   9 9   12 12   6 6   9 9   12 12}
          658  +
          659  +do_execsql_test 4.5.35.1 {
          660  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING), 
          661  +  min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
          662  +  FROM ttt ORDER BY a
          663  +} {2 {}   3 {}   4 {}   3 1   4 2   5 3   3 2   4 3   5 4}
          664  +
          665  +do_execsql_test 4.5.35.2 {
          666  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING), 
          667  +         sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
          668  +  FROM ttt ORDER BY a
          669  +} {3 {}   5 {}   7 {}   6 1   9 2   12 3   6 2   9 3   12 4}
          670  +
          671  +do_execsql_test 4.5.36.1 {
          672  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING), 
          673  +  min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING)
          674  +  FROM ttt ORDER BY a
          675  +} {2 {}   3 {}   4 {}   3 {}   4 {}   5 {}   3 {}   4 {}   5 {}}
          676  +
          677  +do_execsql_test 4.5.36.2 {
          678  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING), 
          679  +         sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING)
          680  +  FROM ttt ORDER BY a
          681  +} {3 {}   5 {}   7 {}   6 {}   9 {}   12 {}   6 {}   9 {}   12 {}}
          682  +
          683  +do_execsql_test 4.5.37.1 {
          684  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING), 
          685  +  min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING)
          686  +  FROM ttt ORDER BY a
          687  +} {2 2   3 3   4 4   3 3   4 4   5 5   3 {}   4 {}   5 {}}
          688  +
          689  +do_execsql_test 4.5.37.2 {
          690  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING), 
          691  +         sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING)
          692  +  FROM ttt ORDER BY a
          693  +} {3 5   5 7   7 9   6 3   9 4   12 5   6 {}   9 {}   12 {}}
          694  +
          695  +do_execsql_test 4.5.38.1 {
          696  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING), 
          697  +  min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING)
          698  +  FROM ttt ORDER BY a
          699  +} {3 1   4 2   5 3   3 1   4 2   5 3   3 1   4 2   5 3}
          700  +
          701  +do_execsql_test 4.5.38.2 {
          702  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING), 
          703  +         sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING)
          704  +  FROM ttt ORDER BY a
          705  +} {6 3   9 5   12 7   6 6   9 9   12 12   6 6   9 9   12 12}
          706  +
          707  +do_execsql_test 4.5.39.1 {
          708  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING), 
          709  +  min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING)
          710  +  FROM ttt ORDER BY a
          711  +} {3 1   4 2   5 3   3 1   4 2   5 3   3 1   4 2   5 3}
          712  +
          713  +do_execsql_test 4.5.39.2 {
          714  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING), 
          715  +         sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING)
          716  +  FROM ttt ORDER BY a
          717  +} {6 6   9 9   12 12   6 6   9 9   12 12   6 6   9 9   12 12}
          718  +
          719  +do_execsql_test 4.5.40.1 {
          720  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING), 
          721  +  min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
          722  +  FROM ttt ORDER BY a
          723  +} {3 {}   4 {}   5 {}   3 1   4 2   5 3   3 2   4 3   5 4}
          724  +
          725  +do_execsql_test 4.5.40.2 {
          726  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING), 
          727  +         sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
          728  +  FROM ttt ORDER BY a
          729  +} {6 {}   9 {}   12 {}   6 1   9 2   12 3   6 2   9 3   12 4}
          730  +
          731  +do_execsql_test 4.5.41.1 {
          732  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING), 
          733  +  min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING)
          734  +  FROM ttt ORDER BY a
          735  +} {3 {}   4 {}   5 {}   3 {}   4 {}   5 {}   3 {}   4 {}   5 {}}
          736  +
          737  +do_execsql_test 4.5.41.2 {
          738  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING), 
          739  +         sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING)
          740  +  FROM ttt ORDER BY a
          741  +} {6 {}   9 {}   12 {}   6 {}   9 {}   12 {}   6 {}   9 {}   12 {}}
          742  +
          743  +do_execsql_test 4.5.42.1 {
          744  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING), 
          745  +  min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING)
          746  +  FROM ttt ORDER BY a
          747  +} {3 2   4 3   5 4   3 3   4 4   5 5   3 {}   4 {}   5 {}}
          748  +
          749  +do_execsql_test 4.5.42.2 {
          750  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING), 
          751  +         sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING)
          752  +  FROM ttt ORDER BY a
          753  +} {6 5   9 7   12 9   6 3   9 4   12 5   6 {}   9 {}   12 {}}
          754  +
          755  +do_execsql_test 4.5.43.1 {
          756  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING), 
          757  +  min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING)
          758  +  FROM ttt ORDER BY a
          759  +} {{} 1   {} 2   {} 3   1 1   2 2   3 3   2 1   3 2   4 3}
          760  +
          761  +do_execsql_test 4.5.43.2 {
          762  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING), 
          763  +         sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING)
          764  +  FROM ttt ORDER BY a
          765  +} {{} 3   {} 5   {} 7   1 6   2 9   3 12   2 6   3 9   4 12}
          766  +
          767  +do_execsql_test 4.5.44.1 {
          768  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING), 
          769  +  min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING)
          770  +  FROM ttt ORDER BY a
          771  +} {{} 1   {} 2   {} 3   1 1   2 2   3 3   2 1   3 2   4 3}
          772  +
          773  +do_execsql_test 4.5.44.2 {
          774  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING), 
          775  +         sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING)
          776  +  FROM ttt ORDER BY a
          777  +} {{} 6   {} 9   {} 12   1 6   2 9   3 12   2 6   3 9   4 12}
          778  +
          779  +do_execsql_test 4.5.45.1 {
          780  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING), 
          781  +  min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
          782  +  FROM ttt ORDER BY a
          783  +} {{} {}   {} {}   {} {}   1 1   2 2   3 3   2 2   3 3   4 4}
          784  +
          785  +do_execsql_test 4.5.45.2 {
          786  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING), 
          787  +         sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
          788  +  FROM ttt ORDER BY a
          789  +} {{} {}   {} {}   {} {}   1 1   2 2   3 3   2 2   3 3   4 4}
          790  +
          791  +do_execsql_test 4.5.46.1 {
          792  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING), 
          793  +  min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING)
          794  +  FROM ttt ORDER BY a
          795  +} {{} {}   {} {}   {} {}   1 {}   2 {}   3 {}   2 {}   3 {}   4 {}}
          796  +
          797  +do_execsql_test 4.5.46.2 {
          798  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING), 
          799  +         sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING)
          800  +  FROM ttt ORDER BY a
          801  +} {{} {}   {} {}   {} {}   1 {}   2 {}   3 {}   2 {}   3 {}   4 {}}
          802  +
          803  +do_execsql_test 4.5.47.1 {
          804  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING), 
          805  +  min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING)
          806  +  FROM ttt ORDER BY a
          807  +} {{} 2   {} 3   {} 4   1 3   2 4   3 5   2 {}   3 {}   4 {}}
          808  +
          809  +do_execsql_test 4.5.47.2 {
          810  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING), 
          811  +         sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING)
          812  +  FROM ttt ORDER BY a
          813  +} {{} 5   {} 7   {} 9   1 3   2 4   3 5   2 {}   3 {}   4 {}}
          814  +
          815  +do_execsql_test 4.5.48.1 {
          816  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING), 
          817  +  min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING)
          818  +  FROM ttt ORDER BY a
          819  +} {{} 1   {} 2   {} 3   {} 1   {} 2   {} 3   {} 1   {} 2   {} 3}
          820  +
          821  +do_execsql_test 4.5.48.2 {
          822  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING), 
          823  +         sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING)
          824  +  FROM ttt ORDER BY a
          825  +} {{} 3   {} 5   {} 7   {} 6   {} 9   {} 12   {} 6   {} 9   {} 12}
          826  +
          827  +do_execsql_test 4.5.49.1 {
          828  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING), 
          829  +  min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING)
          830  +  FROM ttt ORDER BY a
          831  +} {{} 1   {} 2   {} 3   {} 1   {} 2   {} 3   {} 1   {} 2   {} 3}
          832  +
          833  +do_execsql_test 4.5.49.2 {
          834  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING), 
          835  +         sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING)
          836  +  FROM ttt ORDER BY a
          837  +} {{} 6   {} 9   {} 12   {} 6   {} 9   {} 12   {} 6   {} 9   {} 12}
          838  +
          839  +do_execsql_test 4.5.50.1 {
          840  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING), 
          841  +  min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
          842  +  FROM ttt ORDER BY a
          843  +} {{} {}   {} {}   {} {}   {} 1   {} 2   {} 3   {} 2   {} 3   {} 4}
          844  +
          845  +do_execsql_test 4.5.50.2 {
          846  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING), 
          847  +         sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
          848  +  FROM ttt ORDER BY a
          849  +} {{} {}   {} {}   {} {}   {} 1   {} 2   {} 3   {} 2   {} 3   {} 4}
          850  +
          851  +do_execsql_test 4.5.51.1 {
          852  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING), 
          853  +  min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING)
          854  +  FROM ttt ORDER BY a
          855  +} {{} {}   {} {}   {} {}   {} {}   {} {}   {} {}   {} {}   {} {}   {} {}}
          856  +
          857  +do_execsql_test 4.5.51.2 {
          858  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING), 
          859  +         sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING)
          860  +  FROM ttt ORDER BY a
          861  +} {{} {}   {} {}   {} {}   {} {}   {} {}   {} {}   {} {}   {} {}   {} {}}
          862  +
          863  +do_execsql_test 4.5.52.1 {
          864  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING), 
          865  +  min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING)
          866  +  FROM ttt ORDER BY a
          867  +} {{} 2   {} 3   {} 4   {} 3   {} 4   {} 5   {} {}   {} {}   {} {}}
          868  +
          869  +do_execsql_test 4.5.52.2 {
          870  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING), 
          871  +         sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING)
          872  +  FROM ttt ORDER BY a
          873  +} {{} 5   {} 7   {} 9   {} 3   {} 4   {} 5   {} {}   {} {}   {} {}}
          874  +
          875  +do_execsql_test 4.5.53.1 {
          876  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING), 
          877  +  min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING)
          878  +  FROM ttt ORDER BY a
          879  +} {3 1   4 2   5 3   3 1   4 2   5 3   {} 1   {} 2   {} 3}
          880  +
          881  +do_execsql_test 4.5.53.2 {
          882  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING), 
          883  +         sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 1 FOLLOWING)
          884  +  FROM ttt ORDER BY a
          885  +} {5 3   7 5   9 7   3 6   4 9   5 12   {} 6   {} 9   {} 12}
          886  +
          887  +do_execsql_test 4.5.54.1 {
          888  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING), 
          889  +  min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING)
          890  +  FROM ttt ORDER BY a
          891  +} {3 1   4 2   5 3   3 1   4 2   5 3   {} 1   {} 2   {} 3}
          892  +
          893  +do_execsql_test 4.5.54.2 {
          894  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING), 
          895  +         sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING)
          896  +  FROM ttt ORDER BY a
          897  +} {5 6   7 9   9 12   3 6   4 9   5 12   {} 6   {} 9   {} 12}
          898  +
          899  +do_execsql_test 4.5.55.1 {
          900  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING), 
          901  +  min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
          902  +  FROM ttt ORDER BY a
          903  +} {3 {}   4 {}   5 {}   3 1   4 2   5 3   {} 2   {} 3   {} 4}
          904  +
          905  +do_execsql_test 4.5.55.2 {
          906  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING), 
          907  +         sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
          908  +  FROM ttt ORDER BY a
          909  +} {5 {}   7 {}   9 {}   3 1   4 2   5 3   {} 2   {} 3   {} 4}
          910  +
          911  +do_execsql_test 4.5.56.1 {
          912  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING), 
          913  +  min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING)
          914  +  FROM ttt ORDER BY a
          915  +} {3 {}   4 {}   5 {}   3 {}   4 {}   5 {}   {} {}   {} {}   {} {}}
          916  +
          917  +do_execsql_test 4.5.56.2 {
          918  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING), 
          919  +         sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 0 PRECEDING AND 1 PRECEDING)
          920  +  FROM ttt ORDER BY a
          921  +} {5 {}   7 {}   9 {}   3 {}   4 {}   5 {}   {} {}   {} {}   {} {}}
          922  +
          923  +do_execsql_test 4.5.57.1 {
          924  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING), 
          925  +  min(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING)
          926  +  FROM ttt ORDER BY a
          927  +} {3 2   4 3   5 4   3 3   4 4   5 5   {} {}   {} {}   {} {}}
          928  +
          929  +do_execsql_test 4.5.57.2 {
          930  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING), 
          931  +         sum(c) OVER (PARTITION BY b ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 500 FOLLOWING)
          932  +  FROM ttt ORDER BY a
          933  +} {5 5   7 7   9 9   3 3   4 4   5 5   {} {}   {} {}   {} {}}
          934  +
          935  +do_execsql_test 4.5.58.1 {
          936  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          937  +  min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          938  +  FROM ttt ORDER BY a
          939  +} {1 1   2 2   3 3   2 1   3 2   4 3   3 1   4 2   5 3}
          940  +
          941  +do_execsql_test 4.5.58.2 {
          942  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          943  +         sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          944  +  FROM ttt ORDER BY a
          945  +} {1 1   2 2   3 3   3 3   5 5   7 7   6 6   9 9   12 12}
          946  +
          947  +do_execsql_test 4.5.59.1 {
          948  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          949  +  min(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          950  +  FROM ttt ORDER BY a
          951  +} {1 1   2 2   3 3   2 2   3 3   4 4   3 3   4 4   5 5}
          952  +
          953  +do_execsql_test 4.5.59.2 {
          954  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          955  +         sum(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          956  +  FROM ttt ORDER BY a
          957  +} {1 6   2 9   3 12   3 5   5 7   7 9   6 3   9 4   12 5}
          958  +
          959  +do_execsql_test 4.5.60.1 {
          960  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          961  +  min(c) OVER (PARTITION BY b  RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          962  +  FROM ttt ORDER BY a
          963  +} {1 1   2 2   3 3   2 1   3 2   4 3   3 1   4 2   5 3}
          964  +
          965  +do_execsql_test 4.5.60.2 {
          966  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          967  +         sum(c) OVER (PARTITION BY b  RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          968  +  FROM ttt ORDER BY a
          969  +} {1 6   2 9   3 12   3 6   5 9   7 12   6 6   9 9   12 12}
          970  +
          971  +do_execsql_test 4.5.61.1 {
          972  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          973  +  min(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          974  +  FROM ttt ORDER BY a
          975  +} {1 1   2 2   3 3   2 1   3 2   4 3   3 1   4 2   5 3}
          976  +
          977  +do_execsql_test 4.5.61.2 {
          978  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          979  +         sum(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          980  +  FROM ttt ORDER BY a
          981  +} {1 1   2 2   3 3   3 3   5 5   7 7   6 6   9 9   12 12}
          982  +
          983  +do_execsql_test 4.5.62.1 {
          984  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          985  +  min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          986  +  FROM ttt ORDER BY a
          987  +} {3 1   4 2   5 3   3 1   4 2   5 3   3 1   4 2   5 3}
          988  +
          989  +do_execsql_test 4.5.62.2 {
          990  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          991  +         sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          992  +  FROM ttt ORDER BY a
          993  +} {6 1   9 2   12 3   5 3   7 5   9 7   3 6   4 9   5 12}
          994  +
          995  +do_execsql_test 4.5.63.1 {
          996  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
          997  +  min(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          998  +  FROM ttt ORDER BY a
          999  +} {3 1   4 2   5 3   3 2   4 3   5 4   3 3   4 4   5 5}
         1000  +
         1001  +do_execsql_test 4.5.63.2 {
         1002  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
         1003  +         sum(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
         1004  +  FROM ttt ORDER BY a
         1005  +} {6 6   9 9   12 12   5 5   7 7   9 9   3 3   4 4   5 5}
         1006  +
         1007  +do_execsql_test 4.5.64.1 {
         1008  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
         1009  +  min(c) OVER (PARTITION BY b  RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
         1010  +  FROM ttt ORDER BY a
         1011  +} {3 1   4 2   5 3   3 1   4 2   5 3   3 1   4 2   5 3}
         1012  +
         1013  +do_execsql_test 4.5.64.2 {
         1014  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
         1015  +         sum(c) OVER (PARTITION BY b  RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
         1016  +  FROM ttt ORDER BY a
         1017  +} {6 6   9 9   12 12   5 6   7 9   9 12   3 6   4 9   5 12}
         1018  +
         1019  +do_execsql_test 4.5.65.1 {
         1020  +  SELECT max(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
         1021  +  min(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
         1022  +  FROM ttt ORDER BY a
         1023  +} {3 1   4 2   5 3   3 1   4 2   5 3   3 1   4 2   5 3}
         1024  +
         1025  +do_execsql_test 4.5.65.2 {
         1026  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
         1027  +         sum(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
         1028  +  FROM ttt ORDER BY a
         1029  +} {6 1   9 2   12 3   5 3   7 5   9 7   3 6   4 9   5 12}
         1030  +
         1031  +do_execsql_test 4.5.66.1 {
         1032  +  SELECT max(c) OVER (PARTITION BY b  RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
         1033  +  min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
         1034  +  FROM ttt ORDER BY a
         1035  +} {3 1   4 2   5 3   3 1   4 2   5 3   3 1   4 2   5 3}
         1036  +
         1037  +do_execsql_test 4.5.66.2 {
         1038  +  SELECT sum(c) OVER (PARTITION BY b  RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
         1039  +         sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
         1040  +  FROM ttt ORDER BY a
         1041  +} {6 1   9 2   12 3   6 3   9 5   12 7   6 6   9 9   12 12}
         1042  +
         1043  +do_execsql_test 4.5.67.1 {
         1044  +  SELECT max(c) OVER (PARTITION BY b  RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
         1045  +  min(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
         1046  +  FROM ttt ORDER BY a
         1047  +} {3 1   4 2   5 3   3 2   4 3   5 4   3 3   4 4   5 5}
         1048  +
         1049  +do_execsql_test 4.5.67.2 {
         1050  +  SELECT sum(c) OVER (PARTITION BY b  RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
         1051  +         sum(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
         1052  +  FROM ttt ORDER BY a
         1053  +} {6 6   9 9   12 12   6 5   9 7   12 9   6 3   9 4   12 5}
         1054  +
         1055  +do_execsql_test 4.5.68.1 {
         1056  +  SELECT max(c) OVER (PARTITION BY b  RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
         1057  +  min(c) OVER (PARTITION BY b  RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
         1058  +  FROM ttt ORDER BY a
         1059  +} {3 1   4 2   5 3   3 1   4 2   5 3   3 1   4 2   5 3}
         1060  +
         1061  +do_execsql_test 4.5.68.2 {
         1062  +  SELECT sum(c) OVER (PARTITION BY b  RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
         1063  +         sum(c) OVER (PARTITION BY b  RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
         1064  +  FROM ttt ORDER BY a
         1065  +} {6 6   9 9   12 12   6 6   9 9   12 12   6 6   9 9   12 12}
         1066  +
         1067  +do_execsql_test 4.5.69.1 {
         1068  +  SELECT max(c) OVER (PARTITION BY b  RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
         1069  +  min(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
         1070  +  FROM ttt ORDER BY a
         1071  +} {3 1   4 2   5 3   3 1   4 2   5 3   3 1   4 2   5 3}
         1072  +
         1073  +do_execsql_test 4.5.69.2 {
         1074  +  SELECT sum(c) OVER (PARTITION BY b  RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
         1075  +         sum(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
         1076  +  FROM ttt ORDER BY a
         1077  +} {6 1   9 2   12 3   6 3   9 5   12 7   6 6   9 9   12 12}
         1078  +
         1079  +do_execsql_test 4.5.70.1 {
         1080  +  SELECT max(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
         1081  +  min(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
         1082  +  FROM ttt ORDER BY a
         1083  +} {1 1   2 2   3 3   2 1   3 2   4 3   3 1   4 2   5 3}
         1084  +
         1085  +do_execsql_test 4.5.70.2 {
         1086  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
         1087  +         sum(c) OVER (PARTITION BY b ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
         1088  +  FROM ttt ORDER BY a
         1089  +} {1 1   2 2   3 3   3 3   5 5   7 7   6 6   9 9   12 12}
         1090  +
         1091  +do_execsql_test 4.5.71.1 {
         1092  +  SELECT max(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
         1093  +  min(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
         1094  +  FROM ttt ORDER BY a
         1095  +} {1 1   2 2   3 3   2 2   3 3   4 4   3 3   4 4   5 5}
         1096  +
         1097  +do_execsql_test 4.5.71.2 {
         1098  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
         1099  +         sum(c) OVER (PARTITION BY b ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
         1100  +  FROM ttt ORDER BY a
         1101  +} {1 6   2 9   3 12   3 5   5 7   7 9   6 3   9 4   12 5}
         1102  +
         1103  +do_execsql_test 4.5.72.1 {
         1104  +  SELECT max(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
         1105  +  min(c) OVER (PARTITION BY b  RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
         1106  +  FROM ttt ORDER BY a
         1107  +} {1 1   2 2   3 3   2 1   3 2   4 3   3 1   4 2   5 3}
         1108  +
         1109  +do_execsql_test 4.5.72.2 {
         1110  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
         1111  +         sum(c) OVER (PARTITION BY b  RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
         1112  +  FROM ttt ORDER BY a
         1113  +} {1 6   2 9   3 12   3 6   5 9   7 12   6 6   9 9   12 12}
         1114  +
         1115  +do_execsql_test 4.5.73.1 {
         1116  +  SELECT max(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
         1117  +  min(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
         1118  +  FROM ttt ORDER BY a
         1119  +} {1 1   2 2   3 3   2 1   3 2   4 3   3 1   4 2   5 3}
         1120  +
         1121  +do_execsql_test 4.5.73.2 {
         1122  +  SELECT sum(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 
         1123  +         sum(c) OVER (PARTITION BY b ORDER BY b, a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
         1124  +  FROM ttt ORDER BY a
         1125  +} {1 1   2 2   3 3   3 3   5 5   7 7   6 6   9 9   12 12}
         1126  +
         1127  +#==========================================================================
         1128  +
         1129  +do_execsql_test 7.0 {
         1130  +  DROP TABLE IF EXISTS t1;
         1131  +  CREATE TABLE t1(x INTEGER, y INTEGER);
         1132  +  INSERT INTO t1 VALUES(1, 2);
         1133  +  INSERT INTO t1 VALUES(3, 4);
         1134  +  INSERT INTO t1 VALUES(5, 6);
         1135  +  INSERT INTO t1 VALUES(7, 8);
         1136  +  INSERT INTO t1 VALUES(9, 10);
         1137  +} {}
         1138  +
         1139  +do_execsql_test 7.1 {
         1140  +  SELECT lead(y) OVER win FROM t1
         1141  +  WINDOW win AS (ORDER BY x)
         1142  +} {4   6   8   10   {}}
         1143  +
         1144  +do_execsql_test 7.2 {
         1145  +  SELECT lead(y, 2) OVER win FROM t1
         1146  +  WINDOW win AS (ORDER BY x)
         1147  +} {6   8   10   {}   {}}
         1148  +
         1149  +do_execsql_test 7.3 {
         1150  +  SELECT lead(y, 3, -1) OVER win FROM t1
         1151  +  WINDOW win AS (ORDER BY x)
         1152  +} {8   10   -1   -1   -1}
         1153  +
         1154  +do_execsql_test 7.4 {
         1155  +  SELECT 
         1156  +    lead(y) OVER win, lead(y) OVER win
         1157  +  FROM t1
         1158  +  WINDOW win AS (ORDER BY x)
         1159  +} {4 4   6 6   8 8   10 10   {} {}}
         1160  +
         1161  +do_execsql_test 7.5 {
         1162  +  SELECT 
         1163  +    lead(y) OVER win, 
         1164  +    lead(y, 2) OVER win, 
         1165  +    lead(y, 3, -1) OVER win
         1166  +  FROM t1
         1167  +  WINDOW win AS (ORDER BY x)
         1168  +} {4 6 8   6 8 10   8 10 -1   10 {} -1   {} {} -1}
         1169  +
         1170  +#==========================================================================
         1171  +
         1172  +do_execsql_test 8.0 {
         1173  +  DROP TABLE IF EXISTS t1;
         1174  +  CREATE TABLE t1(a INTEGER, b INTEGER, c INTEGER, d INTEGER);
         1175  +  INSERT INTO t1 VALUES(1, 2, 3, 4);
         1176  +  INSERT INTO t1 VALUES(5, 6, 7, 8);
         1177  +  INSERT INTO t1 VALUES(9, 10, 11, 12);
         1178  +} {}
         1179  +
         1180  +do_execsql_test 8.1 {
         1181  +  SELECT row_number() OVER win,
         1182  +         nth_value(d,2) OVER win,
         1183  +         lead(d) OVER win
         1184  +  FROM t1
         1185  +  WINDOW win AS (ORDER BY a)
         1186  +} {1 {} 8   2 8 12   3 8 {}}
         1187  +
         1188  +do_execsql_test 8.2 {
         1189  +  SELECT row_number() OVER win,
         1190  +           rank() OVER win,
         1191  +           dense_rank() OVER win,
         1192  +           ntile(2) OVER win,
         1193  +           first_value(d) OVER win,
         1194  +           last_value(d) OVER win,
         1195  +           nth_value(d,2) OVER win,
         1196  +           lead(d) OVER win,
         1197  +           lag(d) OVER win,
         1198  +           max(d) OVER win,
         1199  +           min(d) OVER win
         1200  +    FROM t1
         1201  +    WINDOW win AS (ORDER BY a)
         1202  +} {1 1 1 1 4 4 {} 8 {} 4 4   2 2 2 1 4 8 8 12 4 8 4   3 3 3 2 4 12 8 {} 8 12 4}
         1203  +
         1204  +#==========================================================================
         1205  +
         1206  +do_execsql_test 9.0 {
         1207  +  DROP TABLE IF EXISTS t2;
         1208  +  CREATE TABLE t2(x INTEGER);
         1209  +  INSERT INTO t2 VALUES(1), (1), (1), (4), (4), (6), (7);
         1210  +} {}
         1211  +
         1212  +do_execsql_test 9.1 {
         1213  +  SELECT rank() OVER () FROM t2
         1214  +} {1   1   1   1   1   1   1}
         1215  +
         1216  +do_execsql_test 9.2 {
         1217  +  SELECT dense_rank() OVER (PARTITION BY x) FROM t2
         1218  +} {1   1   1   1   1   1   1}
         1219  +
         1220  +do_test 9.3 {
         1221  +  set myres {}
         1222  +  foreach r [db eval {SELECT x, percent_rank() OVER (PARTITION BY x ORDER BY x) FROM t2}] {
         1223  +    lappend myres [format %.2f [set r]]
         1224  +  }
         1225  +  set myres
         1226  +} {1.00 0.00 1.00 0.00 1.00 0.00 4.00 0.00 4.00 0.00 6.00 0.00 7.00 0.00}
         1227  +
         1228  +do_execsql_test 9.4 {
         1229  +  SELECT x, rank() OVER (ORDER BY x) FROM t2 ORDER BY 1,2
         1230  +} {1 1   1 1   1 1   4 4   4 4   6 6   7 7}
         1231  +
         1232  +do_execsql_test 9.5 {
         1233  +  SELECT DISTINCT x, rank() OVER (ORDER BY x) FROM t2 ORDER BY 1,2
         1234  +} {1 1   4 4   6 6   7 7}
         1235  +
         1236  +finish_test

Added test/window5.test.

            1  +# 2018 May 8
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +# This file implements regression tests for SQLite library. Specifically,
           12  +# it tests the sqlite3_create_window_function() API.
           13  +#
           14  +
           15  +set testdir [file dirname $argv0]
           16  +source $testdir/tester.tcl
           17  +set testprefix window5
           18  +
           19  +ifcapable !windowfunc {
           20  +  finish_test
           21  +  return
           22  +}
           23  +
           24  +proc m_step {ctx val} {
           25  +  lappend ctx $val
           26  +  return $ctx
           27  +}
           28  +proc m_value {ctx} {
           29  +  set lSort [lsort $ctx]
           30  +
           31  +  set nVal [llength $lSort]
           32  +  set n [expr $nVal/2]
           33  +  
           34  +  if {($nVal % 2)==0 && $nVal>0} {
           35  +    set a [lindex $lSort $n]
           36  +    set b [lindex $lSort $n-1]
           37  +    if {($a+$b) % 2} {
           38  +      set ret [expr ($a+$b)/2.0]
           39  +    } else {
           40  +      set ret [expr ($a+$b)/2]
           41  +    }
           42  +  } else {
           43  +    set ret [lindex $lSort $n]
           44  +  }
           45  +  return $ret
           46  +}
           47  +proc m_inverse {ctx val} {
           48  +  set ctx [lrange $ctx 1 end]
           49  +  return $ctx
           50  +}
           51  +proc w_value {ctx} {
           52  +  lsort $ctx
           53  +}
           54  +
           55  +sqlite3_create_window_function db median m_step m_value m_value m_inverse
           56  +sqlite3_create_window_function db win m_step w_value w_value m_inverse
           57  +
           58  +do_test 0.0 {
           59  +  test_create_window_function_misuse db
           60  +} {}
           61  +
           62  +do_execsql_test 1.0 {
           63  +  CREATE TABLE t1(a, b);
           64  +  INSERT INTO t1 VALUES(4, 'a');
           65  +  INSERT INTO t1 VALUES(6, 'b');
           66  +  INSERT INTO t1 VALUES(1, 'c');
           67  +  INSERT INTO t1 VALUES(5, 'd');
           68  +  INSERT INTO t1 VALUES(2, 'e');
           69  +  INSERT INTO t1 VALUES(3, 'f');
           70  +}
           71  +
           72  +do_execsql_test 1.1 {
           73  +  SELECT win(a) OVER (ORDER BY b), median(a) OVER (ORDER BY b) FROM t1;
           74  +} {4 4  {4 6} 5  {1 4 6} 4  {1 4 5 6} 4.5  {1 2 4 5 6} 4 {1 2 3 4 5 6} 3.5}
           75  +
           76  +test_create_sumint db
           77  +do_execsql_test 2.0 {
           78  +  SELECT sumint(a) OVER (ORDER BY rowid) FROM t1 ORDER BY rowid;
           79  +} {4 10 11 16 18 21}
           80  +
           81  +do_execsql_test 2.1 {
           82  +  SELECT sumint(a) OVER (ORDER BY rowid ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) FROM t1 ORDER BY rowid;
           83  +} {10 11 12 8 10 5}
           84  +
           85  +
           86  +finish_test
           87  +

Added test/window6.test.

            1  +# 2018 May 8
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +# This file implements regression tests for SQLite library. Specifically,
           12  +# it tests the sqlite3_create_window_function() API.
           13  +#
           14  +
           15  +set testdir [file dirname $argv0]
           16  +source $testdir/tester.tcl
           17  +set testprefix window6
           18  +
           19  +ifcapable !windowfunc {
           20  +  finish_test
           21  +  return
           22  +}
           23  +
           24  +set setup {
           25  +  CREATE TABLE %t1(%x, %y %typename);
           26  +  INSERT INTO %t1 VALUES(1, 'a');
           27  +  INSERT INTO %t1 VALUES(2, 'b');
           28  +  INSERT INTO %t1 VALUES(3, 'c');
           29  +  INSERT INTO %t1 VALUES(4, 'd');
           30  +  INSERT INTO %t1 VALUES(5, 'e');
           31  +}
           32  +
           33  +foreach {tn vars} {
           34  +  1 {}
           35  +  2 { set A(%t1) over }
           36  +  3 { set A(%x)  over }
           37  +  4 { 
           38  +    set A(%alias)   over 
           39  +    set A(%x)       following 
           40  +    set A(%y)       over 
           41  +  }
           42  +  5 { 
           43  +    set A(%t1)      over
           44  +    set A(%x)       following 
           45  +    set A(%y)       preceding 
           46  +    set A(%w)       current 
           47  +    set A(%alias)   filter
           48  +    set A(%typename)  window
           49  +  }
           50  +
           51  +  6 { 
           52  +    set A(%x)       window 
           53  +  }
           54  +} {
           55  +  set A(%t1)    t1
           56  +  set A(%x)     x
           57  +  set A(%y)     y
           58  +  set A(%w)     w
           59  +  set A(%alias) alias
           60  +  set A(%typename) integer
           61  +  eval $vars
           62  +
           63  +  set MAP [array get A]
           64  +  set setup_sql [string map $MAP $setup]
           65  +  reset_db
           66  +  execsql $setup_sql
           67  +
           68  +  do_execsql_test 1.$tn.1 [string map $MAP {
           69  +    SELECT group_concat(%x, '.') OVER (ORDER BY %y) FROM %t1
           70  +  }] {1 1.2 1.2.3 1.2.3.4 1.2.3.4.5}
           71  +
           72  +  do_execsql_test 1.$tn.2 [string map $MAP {
           73  +    SELECT sum(%x) OVER %w FROM %t1 WINDOW %w AS (ORDER BY %y)
           74  +  }] {1 3 6 10 15}
           75  +
           76  +  do_execsql_test 1.$tn.3 [string map $MAP {
           77  +    SELECT sum(%alias.%x) OVER %w FROM %t1 %alias WINDOW %w AS (ORDER BY %y)
           78  +  }] {1 3 6 10 15}
           79  +
           80  +  do_execsql_test 1.$tn.4 [string map $MAP {
           81  +    SELECT sum(%x) %alias FROM %t1
           82  +  }] {15}
           83  +}
           84  +
           85  +
           86  +proc winproc {args} { return "window: $args" }
           87  +db func window winproc
           88  +do_execsql_test 2.0 {
           89  +  SELECT window('hello world');
           90  +} {{window: {hello world}}}
           91  +
           92  +proc wincmp {a b} { string compare $b $a }
           93  +db collate window wincmp
           94  +do_execsql_test 3.0 {
           95  +  CREATE TABLE window(x COLLATE window);
           96  +  INSERT INTO window VALUES('bob'), ('alice'), ('cate');
           97  +  SELECT * FROM window ORDER BY x COLLATE window;
           98  +} {cate bob alice}
           99  +do_execsql_test 3.1 {
          100  +  DROP TABLE window;
          101  +  CREATE TABLE x1(x);
          102  +  INSERT INTO x1 VALUES('bob'), ('alice'), ('cate');
          103  +  CREATE INDEX window ON x1(x COLLATE window);
          104  +  SELECT * FROM x1 ORDER BY x COLLATE window;
          105  +} {cate bob alice}
          106  +
          107  +
          108  +do_execsql_test 4.0 { CREATE TABLE t4(x, y); }
          109  +
          110  +# do_execsql_test 4.1 { PRAGMA parser_trace = 1 }
          111  +do_execsql_test 4.1 { 
          112  +  SELECT * FROM t4 window, t4;
          113  +}
          114  +
          115  +#-------------------------------------------------------------------------
          116  +reset_db
          117  +
          118  +do_execsql_test 5.0 {
          119  +  CREATE TABLE over(x, over);
          120  +  CREATE TABLE window(x, window);
          121  +  INSERT INTO over VALUES(1, 2), (3, 4), (5, 6);
          122  +  INSERT INTO window VALUES(1, 2), (3, 4), (5, 6);
          123  +  SELECT sum(x) over FROM over
          124  +} {9}
          125  +
          126  +do_execsql_test 5.1 {
          127  +  SELECT sum(x) over over FROM over WINDOW over AS ()
          128  +} {9 9 9}
          129  +
          130  +do_execsql_test 5.2 {
          131  +  SELECT sum(over) over over over FROM over over WINDOW over AS (ORDER BY over)
          132  +} {2 6 12}
          133  +
          134  +do_execsql_test 5.3 {
          135  +  SELECT sum(over) over over over FROM over over WINDOW over AS (ORDER BY over);
          136  +} {2 6 12}
          137  +
          138  +do_execsql_test 5.4 {
          139  +  SELECT sum(window) OVER window window FROM window window window window AS (ORDER BY window);
          140  +} {2 6 12}
          141  +
          142  +finish_test
          143  +

Added test/windowfault.test.

            1  +# 2018 May 8
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +# This file implements regression tests for SQLite library.
           12  +#
           13  +
           14  +set testdir [file dirname $argv0]
           15  +source $testdir/tester.tcl
           16  +set testprefix windowfault
           17  +
           18  +ifcapable !windowfunc {
           19  +  finish_test
           20  +  return
           21  +}
           22  +
           23  +do_execsql_test 1.0 {
           24  +  CREATE TABLE t1(a, b, c, d);
           25  +  INSERT INTO t1 VALUES(1, 2, 3, 4);
           26  +  INSERT INTO t1 VALUES(5, 6, 7, 8);
           27  +  INSERT INTO t1 VALUES(9, 10, 11, 12);
           28  +}
           29  +faultsim_save_and_close
           30  +
           31  +do_faultsim_test 1 -start 1 -faults oom-* -prep {
           32  +  faultsim_restore_and_reopen
           33  +} -body {
           34  +  execsql {
           35  +    SELECT row_number() OVER win,
           36  +           rank() OVER win,
           37  +           dense_rank() OVER win,
           38  +           ntile(2) OVER win,
           39  +           first_value(d) OVER win,
           40  +           last_value(d) OVER win,
           41  +           nth_value(d,2) OVER win,
           42  +           lead(d) OVER win,
           43  +           lag(d) OVER win,
           44  +           max(d) OVER win,
           45  +           min(d) OVER win
           46  +    FROM t1
           47  +    WINDOW win AS (ORDER BY a)
           48  +  }
           49  +} -test {
           50  +  faultsim_test_result {0 {1 1 1 1 4 4 {} 8 {} 4 4 2 2 2 1 4 8 8 12 4 8 4 3 3 3 2 4 12 8 {} 8 12 4}}
           51  +}
           52  +
           53  +do_faultsim_test 1.1 -faults oom-t* -prep {
           54  +  faultsim_restore_and_reopen
           55  +} -body {
           56  +  execsql {
           57  +    SELECT row_number() OVER win,
           58  +           rank() OVER win,
           59  +           dense_rank() OVER win
           60  +    FROM t1
           61  +    WINDOW win AS (PARTITION BY c<7 ORDER BY a)
           62  +  }
           63  +} -test {
           64  +  faultsim_test_result {0 {1 1 1 2 2 2 1 1 1}}
           65  +}
           66  +
           67  +do_faultsim_test 1.2 -faults oom-t* -prep {
           68  +  faultsim_restore_and_reopen
           69  +} -body {
           70  +  execsql {
           71  +    SELECT ntile(105) 
           72  +    OVER ( RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) 
           73  +    FROM t1
           74  +  }
           75  +} -test {
           76  +  faultsim_test_result {0 {1 2 3}}
           77  +}
           78  +
           79  +do_faultsim_test 2 -start 1 -faults oom-* -prep {
           80  +  faultsim_restore_and_reopen
           81  +} -body {
           82  +  execsql {
           83  +    SELECT round(percent_rank() OVER win, 2),
           84  +           round(cume_dist() OVER win, 2)
           85  +    FROM t1
           86  +    WINDOW win AS (ORDER BY a)
           87  +  }
           88  +} -test {
           89  +  faultsim_test_result {0 {0.0 0.33 0.5 0.67 1.0 1.0}}
           90  +}
           91  +
           92  +do_faultsim_test 3 -faults oom-* -prep {
           93  +  faultsim_restore_and_reopen
           94  +} -body {
           95  +  execsql {
           96  +    SELECT min(d) OVER win, max(d) OVER win
           97  +    FROM t1
           98  +    WINDOW win AS (ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
           99  +  }
          100  +} -test {
          101  +  faultsim_test_result {0 {4 12 8 12 12 12}}
          102  +}
          103  +
          104  +do_faultsim_test 4 -faults oom-* -prep {
          105  +  faultsim_restore_and_reopen
          106  +} -body {
          107  +  execsql {
          108  +    CREATE VIEW aaa AS
          109  +    SELECT min(d) OVER w, max(d) OVER w
          110  +    FROM t1
          111  +    WINDOW w AS (ORDER BY a RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING);
          112  +    SELECT * FROM aaa;
          113  +  }
          114  +} -test {
          115  +  faultsim_test_result {0 {4 12 8 12 12 12}}
          116  +}
          117  +
          118  +do_faultsim_test 5 -start 1 -faults oom-* -prep {
          119  +  faultsim_restore_and_reopen
          120  +} -body {
          121  +  execsql {
          122  +    SELECT last_value(a) OVER win1,
          123  +           last_value(a) OVER win2
          124  +    FROM t1
          125  +    WINDOW win1 AS (ORDER BY a ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING),
          126  +           win2 AS (ORDER BY a)
          127  +  }
          128  +} -test {
          129  +  faultsim_test_result {0 {5 1 9 5 9 9}}
          130  +}
          131  +
          132  +finish_test
          133  +

Changes to tool/lempar.c.

    86     86   */
    87     87   #ifndef INTERFACE
    88     88   # define INTERFACE 1
    89     89   #endif
    90     90   /************* Begin control #defines *****************************************/
    91     91   %%
    92     92   /************* End control #defines *******************************************/
           93  +#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))
    93     94   
    94     95   /* Define the yytestcase() macro to be a no-op if is not already defined
    95     96   ** otherwise.
    96     97   **
    97     98   ** Applications can choose to define yytestcase() in the %include section
    98     99   ** to a macro that can assist in verifying code coverage.  For production
    99    100   ** code the yytestcase() macro should be turned off.  But it is useful
................................................................................
   515    516     assert( stateno <= YY_SHIFT_COUNT );
   516    517   #if defined(YYCOVERAGE)
   517    518     yycoverage[stateno][iLookAhead] = 1;
   518    519   #endif
   519    520     do{
   520    521       i = yy_shift_ofst[stateno];
   521    522       assert( i>=0 );
   522         -    assert( i+YYNTOKEN<=(int)sizeof(yy_lookahead)/sizeof(yy_lookahead[0]) );
          523  +    /* assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD ); */
   523    524       assert( iLookAhead!=YYNOCODE );
   524    525       assert( iLookAhead < YYNTOKEN );
   525    526       i += iLookAhead;
   526         -    if( yy_lookahead[i]!=iLookAhead ){
          527  +    if( i>=YY_NLOOKAHEAD || yy_lookahead[i]!=iLookAhead ){
   527    528   #ifdef YYFALLBACK
   528    529         YYCODETYPE iFallback;            /* Fallback token */
   529    530         if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
   530    531                && (iFallback = yyFallback[iLookAhead])!=0 ){
   531    532   #ifndef NDEBUG
   532    533           if( yyTraceFILE ){
   533    534             fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n",
................................................................................
  1053   1054         cDiv = ' ';
  1054   1055       }
  1055   1056       fprintf(yyTraceFILE,"]\n");
  1056   1057     }
  1057   1058   #endif
  1058   1059     return;
  1059   1060   }
         1061  +
         1062  +/*
         1063  +** Return the fallback token corresponding to canonical token iToken, or
         1064  +** 0 if iToken has no fallback.
         1065  +*/
         1066  +int ParseFallback(int iToken){
         1067  +#ifdef YYFALLBACK
         1068  +  if( iToken<sizeof(yyFallback)/sizeof(yyFallback[0]) ){
         1069  +    return yyFallback[iToken];
         1070  +  }
         1071  +#endif
         1072  +  return 0;
         1073  +}

Changes to tool/mkkeywordhash.c.

   144    144   #  define CTE        0x00040000
   145    145   #endif
   146    146   #ifdef SQLITE_OMIT_UPSERT
   147    147   #  define UPSERT     0
   148    148   #else
   149    149   #  define UPSERT     0x00080000
   150    150   #endif
          151  +#ifdef SQLITE_OMIT_WINDOWFUNC
          152  +#  define WINDOWFUNC 0
          153  +#else
          154  +#  define WINDOWFUNC 0x00100000
          155  +#endif
   151    156   
   152    157   /*
   153    158   ** These are the keywords
   154    159   */
   155    160   static Keyword aKeywordTable[] = {
   156    161     { "ABORT",            "TK_ABORT",        CONFLICT|TRIGGER       },
   157    162     { "ACTION",           "TK_ACTION",       FKEY                   },
................................................................................
   176    181     { "COLLATE",          "TK_COLLATE",      ALWAYS                 },
   177    182     { "COLUMN",           "TK_COLUMNKW",     ALTER                  },
   178    183     { "COMMIT",           "TK_COMMIT",       ALWAYS                 },
   179    184     { "CONFLICT",         "TK_CONFLICT",     CONFLICT               },
   180    185     { "CONSTRAINT",       "TK_CONSTRAINT",   ALWAYS                 },
   181    186     { "CREATE",           "TK_CREATE",       ALWAYS                 },
   182    187     { "CROSS",            "TK_JOIN_KW",      ALWAYS                 },
          188  +  { "CURRENT",          "TK_CURRENT",      WINDOWFUNC             },
   183    189     { "CURRENT_DATE",     "TK_CTIME_KW",     ALWAYS                 },
   184    190     { "CURRENT_TIME",     "TK_CTIME_KW",     ALWAYS                 },
   185    191     { "CURRENT_TIMESTAMP","TK_CTIME_KW",     ALWAYS                 },
   186    192     { "DATABASE",         "TK_DATABASE",     ATTACH                 },
   187    193     { "DEFAULT",          "TK_DEFAULT",      ALWAYS                 },
   188    194     { "DEFERRED",         "TK_DEFERRED",     ALWAYS                 },
   189    195     { "DEFERRABLE",       "TK_DEFERRABLE",   FKEY                   },
................................................................................
   198    204     { "ELSE",             "TK_ELSE",         ALWAYS                 },
   199    205     { "ESCAPE",           "TK_ESCAPE",       ALWAYS                 },
   200    206     { "EXCEPT",           "TK_EXCEPT",       COMPOUND               },
   201    207     { "EXCLUSIVE",        "TK_EXCLUSIVE",    ALWAYS                 },
   202    208     { "EXISTS",           "TK_EXISTS",       ALWAYS                 },
   203    209     { "EXPLAIN",          "TK_EXPLAIN",      EXPLAIN                },
   204    210     { "FAIL",             "TK_FAIL",         CONFLICT|TRIGGER       },
          211  +  { "FILTER",           "TK_FILTER",       WINDOWFUNC             },
          212  +  { "FOLLOWING",        "TK_FOLLOWING",    WINDOWFUNC             },
   205    213     { "FOR",              "TK_FOR",          TRIGGER                },
   206    214     { "FOREIGN",          "TK_FOREIGN",      FKEY                   },
   207    215     { "FROM",             "TK_FROM",         ALWAYS                 },
   208    216     { "FULL",             "TK_JOIN_KW",      ALWAYS                 },
   209    217     { "GLOB",             "TK_LIKE_KW",      ALWAYS                 },
   210    218     { "GROUP",            "TK_GROUP",        ALWAYS                 },
   211    219     { "HAVING",           "TK_HAVING",       ALWAYS                 },
................................................................................
   237    245     { "NULL",             "TK_NULL",         ALWAYS                 },
   238    246     { "OF",               "TK_OF",           ALWAYS                 },
   239    247     { "OFFSET",           "TK_OFFSET",       ALWAYS                 },
   240    248     { "ON",               "TK_ON",           ALWAYS                 },
   241    249     { "OR",               "TK_OR",           ALWAYS                 },
   242    250     { "ORDER",            "TK_ORDER",        ALWAYS                 },
   243    251     { "OUTER",            "TK_JOIN_KW",      ALWAYS                 },
          252  +  { "OVER",             "TK_OVER",         WINDOWFUNC             },
          253  +  { "PARTITION",        "TK_PARTITION",    WINDOWFUNC             },
   244    254     { "PLAN",             "TK_PLAN",         EXPLAIN                },
   245    255     { "PRAGMA",           "TK_PRAGMA",       PRAGMA                 },
          256  +  { "PRECEDING",        "TK_PRECEDING",    WINDOWFUNC             },
   246    257     { "PRIMARY",          "TK_PRIMARY",      ALWAYS                 },
   247    258     { "QUERY",            "TK_QUERY",        EXPLAIN                },
   248    259     { "RAISE",            "TK_RAISE",        TRIGGER                },
          260  +  { "RANGE",            "TK_RANGE",        WINDOWFUNC             },
   249    261     { "RECURSIVE",        "TK_RECURSIVE",    CTE                    },
   250    262     { "REFERENCES",       "TK_REFERENCES",   FKEY                   },
   251    263     { "REGEXP",           "TK_LIKE_KW",      ALWAYS                 },
   252    264     { "REINDEX",          "TK_REINDEX",      REINDEX                },
   253    265     { "RELEASE",          "TK_RELEASE",      ALWAYS                 },
   254    266     { "RENAME",           "TK_RENAME",       ALTER                  },
   255    267     { "REPLACE",          "TK_REPLACE",      CONFLICT               },
   256    268     { "RESTRICT",         "TK_RESTRICT",     FKEY                   },
   257    269     { "RIGHT",            "TK_JOIN_KW",      ALWAYS                 },
   258    270     { "ROLLBACK",         "TK_ROLLBACK",     ALWAYS                 },
   259    271     { "ROW",              "TK_ROW",          TRIGGER                },
          272  +  { "ROWS",             "TK_ROWS",         ALWAYS                 },
   260    273     { "SAVEPOINT",        "TK_SAVEPOINT",    ALWAYS                 },
   261    274     { "SELECT",           "TK_SELECT",       ALWAYS                 },
   262    275     { "SET",              "TK_SET",          ALWAYS                 },
   263    276     { "TABLE",            "TK_TABLE",        ALWAYS                 },
   264    277     { "TEMP",             "TK_TEMP",         ALWAYS                 },
   265    278     { "TEMPORARY",        "TK_TEMP",         ALWAYS                 },
   266    279     { "THEN",             "TK_THEN",         ALWAYS                 },
   267    280     { "TO",               "TK_TO",           ALWAYS                 },
   268    281     { "TRANSACTION",      "TK_TRANSACTION",  ALWAYS                 },
   269    282     { "TRIGGER",          "TK_TRIGGER",      TRIGGER                },
          283  +  { "UNBOUNDED",        "TK_UNBOUNDED",    WINDOWFUNC             },
   270    284     { "UNION",            "TK_UNION",        COMPOUND               },
   271    285     { "UNIQUE",           "TK_UNIQUE",       ALWAYS                 },
   272    286     { "UPDATE",           "TK_UPDATE",       ALWAYS                 },
   273    287     { "USING",            "TK_USING",        ALWAYS                 },
   274    288     { "VACUUM",           "TK_VACUUM",       VACUUM                 },
   275    289     { "VALUES",           "TK_VALUES",       ALWAYS                 },
   276    290     { "VIEW",             "TK_VIEW",         VIEW                   },
   277    291     { "VIRTUAL",          "TK_VIRTUAL",      VTAB                   },
          292  +  { "WINDOW",           "TK_WINDOW",       WINDOWFUNC             },
   278    293     { "WITH",             "TK_WITH",         CTE                    },
   279    294     { "WITHOUT",          "TK_WITHOUT",      ALWAYS                 },
   280    295     { "WHEN",             "TK_WHEN",         ALWAYS                 },
   281    296     { "WHERE",            "TK_WHERE",        ALWAYS                 },
   282    297   };
   283    298   
   284    299   /* Number of keywords */

Changes to tool/mksqlite3c-noext.tcl.

   347    347      trigger.c
   348    348      update.c
   349    349      vacuum.c
   350    350      vtab.c
   351    351      wherecode.c
   352    352      whereexpr.c
   353    353      where.c
          354  +   window.c
   354    355   
   355    356      parse.c
   356    357   
   357    358      tokenize.c
   358    359      complete.c
   359    360   
   360    361      main.c
   361    362      notify.c
   362    363   } {
   363    364     copy_file tsrc/$file
   364    365   }
   365    366   
   366    367   close $out

Changes to tool/mksqlite3c.tcl.

   365    365      update.c
   366    366      upsert.c
   367    367      vacuum.c
   368    368      vtab.c
   369    369      wherecode.c
   370    370      whereexpr.c
   371    371      where.c
          372  +   window.c
   372    373   
   373    374      parse.c
   374    375   
   375    376      tokenize.c
   376    377      complete.c
   377    378   
   378    379      main.c