/ Check-in [0b35aebb]
Login

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

Overview
Comment:Merge enhancements from trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | apple-osx
Files: files | file ages | folders
SHA3-256: 0b35aebbb316fb2849c3a6bb93ffa6300187d1dccbb162bdd00fde53eb61356e
User & Date: drh 2019-04-02 00:34:14
Context
2019-04-02
01:00
Merge fixes from trunk. check-in: 20372906 user: drh tags: apple-osx
00:34
Merge enhancements from trunk. check-in: 0b35aebb user: drh tags: apple-osx
00:28
Add the sqlite3_value_frombind() interface. Use that interface to improve fts3_tokenizer(). check-in: b3f2c320 user: drh tags: trunk
2019-03-26
12:37
Merge recent enhancements from trunk. check-in: dc3c0b8b user: drh tags: apple-osx
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.in.

   421    421     $(TOP)/src/test_schema.c \
   422    422     $(TOP)/src/test_server.c \
   423    423     $(TOP)/src/test_superlock.c \
   424    424     $(TOP)/src/test_syscall.c \
   425    425     $(TOP)/src/test_tclsh.c \
   426    426     $(TOP)/src/test_tclvar.c \
   427    427     $(TOP)/src/test_thread.c \
          428  +  $(TOP)/src/test_vdbecov.c \
   428    429     $(TOP)/src/test_vfs.c \
   429    430     $(TOP)/src/test_windirent.c \
   430    431     $(TOP)/src/test_window.c \
   431    432     $(TOP)/src/test_wsd.c       \
   432    433     $(TOP)/ext/fts3/fts3_term.c \
   433    434     $(TOP)/ext/fts3/fts3_test.c  \
   434    435     $(TOP)/ext/session/test_session.c \

Changes to Makefile.msc.

   315    315   !IFNDEF SQLITETCLH
   316    316   SQLITETCLH = sqlite_tcl.h
   317    317   !ENDIF
   318    318   
   319    319   !IFNDEF SQLITETCLDECLSH
   320    320   SQLITETCLDECLSH = sqlite_tclDecls.h
   321    321   !ENDIF
          322  +
          323  +# This is the name to use for the dynamic link library (DLL) containing the
          324  +# Tcl bindings for SQLite.
          325  +#
          326  +!IFNDEF SQLITE3TCLDLL
          327  +SQLITE3TCLDLL = tclsqlite3.dll
          328  +!ENDIF
   322    329   
   323    330   # These are the additional targets that the targets that integrate with the
   324    331   # Tcl library should depend on when compiling, etc.
   325    332   #
   326    333   !IFNDEF SQLITE_TCL_DEP
   327    334   !IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0
   328    335   SQLITE_TCL_DEP = $(SQLITETCLDECLSH) $(SQLITETCLH)
................................................................................
   491    498   
   492    499   UCRTLIBPATH = $(UCRTLIBPATH:\\=\)
   493    500   
   494    501   # C compiler and options for use in building executables that
   495    502   # will run on the platform that is doing the build.
   496    503   #
   497    504   !IF $(USE_FULLWARN)!=0
   498         -BCC = $(NCC) -nologo -W4 $(CCOPTS) $(BCCOPTS)
          505  +BCC = $(NCC) -nologo -W4 -Fd$*.pdb $(CCOPTS) $(BCCOPTS)
   499    506   !ELSE
   500         -BCC = $(NCC) -nologo -W3 $(CCOPTS) $(BCCOPTS)
          507  +BCC = $(NCC) -nologo -W3 -Fd$*.pdb $(CCOPTS) $(BCCOPTS)
   501    508   !ENDIF
   502    509   
   503    510   # Check if assembly code listings should be generated for the source
   504    511   # code files to be compiled.
   505    512   #
   506    513   !IF $(USE_LISTINGS)!=0
   507    514   BCC = $(BCC) -FAcs
................................................................................
   849    856   # <<mark>>
   850    857   # The locations of the Tcl header and library files.  Also, the library that
   851    858   # non-stubs enabled programs using Tcl must link against.  These variables
   852    859   # (TCLINCDIR, TCLLIBDIR, and LIBTCL) may be overridden via the environment
   853    860   # prior to running nmake in order to match the actual installed location and
   854    861   # version on this machine.
   855    862   #
          863  +!IFNDEF TCLVERSION
          864  +TCLVERSION = 86
          865  +!ENDIF
          866  +
          867  +!IFNDEF TCLSUFFIX
          868  +TCLSUFFIX =
          869  +!ENDIF
          870  +
   856    871   !IFNDEF TCLDIR
   857    872   TCLDIR = $(TOP)\compat\tcl
   858    873   !ENDIF
   859    874   
   860    875   !IFNDEF TCLINCDIR
   861    876   TCLINCDIR = $(TCLDIR)\include
   862    877   !ENDIF
   863    878   
   864    879   !IFNDEF TCLLIBDIR
   865    880   TCLLIBDIR = $(TCLDIR)\lib
   866    881   !ENDIF
   867    882   
   868    883   !IFNDEF LIBTCL
   869         -LIBTCL = tcl86.lib
          884  +LIBTCL = tcl$(TCLVERSION)$(TCLSUFFIX).lib
   870    885   !ENDIF
   871    886   
   872    887   !IFNDEF LIBTCLSTUB
   873         -LIBTCLSTUB = tclstub86.lib
          888  +LIBTCLSTUB = tclstub$(TCLVERSION)$(TCLSUFFIX).lib
   874    889   !ENDIF
   875    890   
   876    891   !IFNDEF LIBTCLPATH
   877    892   LIBTCLPATH = $(TCLDIR)\bin
   878    893   !ENDIF
   879    894   
   880    895   # The locations of the zlib header and library files.  These variables
................................................................................
  1059   1074   RCC = $(RCC) -I$(ICUINCDIR)
  1060   1075   !ENDIF
  1061   1076   # <</mark>>
  1062   1077   
  1063   1078   # Command line prefixes for compiling code, compiling resources,
  1064   1079   # linking, etc.
  1065   1080   #
  1066         -LTCOMPILE = $(TCC) -Fo$@
         1081  +LTCOMPILE = $(TCC) -Fo$@ -Fd$*.pdb
  1067   1082   LTRCOMPILE = $(RCC) -r
  1068   1083   LTLIB = lib.exe
  1069   1084   LTLINK = $(TCC) -Fe$@
  1070   1085   
  1071   1086   # If requested, link to the RPCRT4 library.
  1072   1087   #
  1073   1088   !IF $(USE_RPCRT4_LIB)!=0
................................................................................
  1077   1092   # If a platform was set, force the linker to target that.
  1078   1093   # Note that the vcvars*.bat family of batch files typically
  1079   1094   # set this for you.  Otherwise, the linker will attempt
  1080   1095   # to deduce the binary type based on the object files.
  1081   1096   !IFDEF PLATFORM
  1082   1097   LTLINKOPTS = /NOLOGO /MACHINE:$(PLATFORM)
  1083   1098   LTLIBOPTS = /NOLOGO /MACHINE:$(PLATFORM)
         1099  +!ELSEIF "$(VISUALSTUDIOVERSION)"=="12.0" || \
         1100  +        "$(VISUALSTUDIOVERSION)"=="14.0" || \
         1101  +        "$(VISUALSTUDIOVERSION)"=="15.0"
         1102  +LTLINKOPTS = /NOLOGO /MACHINE:x86
         1103  +LTLIBOPTS = /NOLOGO /MACHINE:x86
  1084   1104   !ELSE
  1085   1105   LTLINKOPTS = /NOLOGO
  1086   1106   LTLIBOPTS = /NOLOGO
  1087   1107   !ENDIF
  1088   1108   
  1089   1109   # When compiling for use in the WinRT environment, the following
  1090   1110   # linker option must be used to mark the executable as runnable
................................................................................
  1493   1513     $(TOP)\src\test_schema.c \
  1494   1514     $(TOP)\src\test_server.c \
  1495   1515     $(TOP)\src\test_superlock.c \
  1496   1516     $(TOP)\src\test_syscall.c \
  1497   1517     $(TOP)\src\test_tclsh.c \
  1498   1518     $(TOP)\src\test_tclvar.c \
  1499   1519     $(TOP)\src\test_thread.c \
         1520  +  $(TOP)\src\test_vdbecov.c \
  1500   1521     $(TOP)\src\test_vfs.c \
  1501   1522     $(TOP)\src\test_windirent.c \
  1502   1523     $(TOP)\src\test_window.c \
  1503   1524     $(TOP)\src\test_wsd.c \
  1504   1525     $(TOP)\ext\fts3\fts3_term.c \
  1505   1526     $(TOP)\ext\fts3\fts3_test.c \
  1506   1527     $(TOP)\ext\rbu\test_rbu.c \
................................................................................
  1661   1682   # Standard options to testfixture.
  1662   1683   #
  1663   1684   TESTOPTS = --verbose=file --output=test-out.txt
  1664   1685   
  1665   1686   # Extra targets for the "all" target that require Tcl.
  1666   1687   #
  1667   1688   !IF $(NO_TCL)==0
  1668         -ALL_TCL_TARGETS = libtclsqlite3.lib
         1689  +ALL_TCL_TARGETS = $(SQLITE3TCLDLL)
  1669   1690   !ELSE
  1670   1691   ALL_TCL_TARGETS =
  1671   1692   !ENDIF
  1672   1693   # <</mark>>
  1673   1694   
  1674   1695   # This is the default Makefile target.  The objects listed here
  1675   1696   # are what get build when you type just "make" with no arguments.
................................................................................
  1693   1714   shell:	$(SQLITE3EXE)
  1694   1715   
  1695   1716   # <<mark>>
  1696   1717   libsqlite3.lib:	$(LIBOBJ)
  1697   1718   	$(LTLIB) $(LTLIBOPTS) /OUT:$@ $(LIBOBJ) $(TLIBS)
  1698   1719   
  1699   1720   libtclsqlite3.lib:	tclsqlite.lo libsqlite3.lib
  1700         -	$(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCLSTUB) $(TLIBS)
         1721  +	$(LTLIB) $(LTLIBOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCLSTUB) $(TLIBS)
         1722  +
         1723  +tclsqlite3.def:	tclsqlite.lo
         1724  +	echo EXPORTS > tclsqlite3.def
         1725  +	dumpbin /all tclsqlite.lo \
         1726  +		| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+/EXPORT:_?((?:Sqlite3|Tclsqlite3)_[^@]*)(?:@\d+)?$$" \1 \
         1727  +		| sort >> tclsqlite3.def
         1728  +
         1729  +pkgIndex.tcl:	$(TOP)\VERSION
         1730  +	for /F %%V in ('type "$(TOP)\VERSION"') do ( \
         1731  +		echo package ifneeded sqlite3 @version@ [list load [file join $$dir $(SQLITE3TCLDLL)] sqlite3] \
         1732  +			| $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact @version@ %%V > pkgIndex.tcl \
         1733  +	)
         1734  +
         1735  +$(SQLITE3TCLDLL):	libtclsqlite3.lib $(LIBRESOBJS) tclsqlite3.def pkgIndex.tcl
         1736  +	$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /DEF:tclsqlite3.def /OUT:$@ libtclsqlite3.lib $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
  1701   1737   # <</mark>>
  1702   1738   
  1703   1739   $(SQLITE3DLL):	$(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
  1704   1740   	$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL $(CORE_LINK_OPTS) /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
  1705   1741   
  1706   1742   # <<block2>>
  1707   1743   sqlite3.def:	libsqlite3.lib
................................................................................
  1833   1869   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c opcodes.c
  1834   1870   # <</mark>>
  1835   1871   
  1836   1872   # Rule to build the Win32 resources object file.
  1837   1873   #
  1838   1874   !IF $(USE_RC)!=0
  1839   1875   # <<block1>>
  1840         -$(LIBRESOBJS):	$(TOP)\src\sqlite3.rc $(SQLITE3H)
         1876  +$(LIBRESOBJS):	$(TOP)\src\sqlite3.rc $(SQLITE3H) $(TOP)\VERSION
  1841   1877   	echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h
  1842   1878   	for /F %%V in ('type "$(TOP)\VERSION"') do ( \
  1843   1879   		echo #define SQLITE_RESOURCE_VERSION %%V \
  1844   1880   			| $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact . ^, >> sqlite3rc.h \
  1845   1881   	)
  1846   1882   	echo #endif >> sqlite3rc.h
  1847   1883   	$(LTRCOMPILE) -fo $(LIBRESOBJS) $(TOP)\src\sqlite3.rc
................................................................................
  2510   2546   # <</mark>>
  2511   2547   
  2512   2548   clean:
  2513   2549   	del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL
  2514   2550   	del /Q *.bsc *.def *.cod *.da *.bb *.bbg *.vc gmon.out 2>NUL
  2515   2551   	del /Q $(SQLITE3EXE) $(SQLITE3DLL) Replace.exe 2>NUL
  2516   2552   # <<mark>>
         2553  +	del /Q $(SQLITE3TCLDLL) pkgIndex.tcl 2>NUL
  2517   2554   	del /Q opcodes.c opcodes.h 2>NUL
  2518   2555   	del /Q lemon.* lempar.c parse.* 2>NUL
  2519   2556   	del /Q mksourceid.* mkkeywordhash.* keywordhash.h 2>NUL
  2520   2557   	del /Q notasharedlib.* 2>NUL
  2521   2558   	-rmdir /Q/S .deps 2>NUL
  2522   2559   	-rmdir /Q/S .libs 2>NUL
  2523   2560   	-rmdir /Q/S tsrc 2>NUL
  2524   2561   	del /Q .target_source 2>NUL
  2525   2562   	del /Q tclsqlite3.exe $(SQLITETCLH) $(SQLITETCLDECLSH) 2>NUL
  2526   2563   	del /Q lsm.dll lsmtest.exe 2>NUL
         2564  +	del /Q atrc.exe changesetfuzz.exe dbtotxt.exe index_usage.exe 2>NUL
  2527   2565   	del /Q testloadext.dll 2>NUL
  2528   2566   	del /Q testfixture.exe test.db 2>NUL
  2529   2567   	del /Q LogEst.exe fts3view.exe rollback-test.exe showdb.exe dbdump.exe 2>NUL
  2530   2568   	del /Q changeset.exe 2>NUL
  2531   2569   	del /Q showjournal.exe showstat4.exe showwal.exe speedtest1.exe 2>NUL
  2532   2570   	del /Q mptester.exe wordcount.exe rbu.exe srcck1.exe 2>NUL
  2533   2571   	del /Q sqlite3.c sqlite3-*.c sqlite3.h 2>NUL

Changes to README.md.

    37     37   
    38     38     *  Latest release as
    39     39        [Tarball](https://www.sqlite.org/src/tarball/sqlite.tar.gz?r=release),
    40     40        [ZIP-archive](https://www.sqlite.org/src/zip/sqlite.zip?r=release), or
    41     41        [SQLite-archive](https://www.sqlite.org/src/sqlar/sqlite.sqlar?r=release).
    42     42   
    43     43     *  For other check-ins, substitute an appropriate branch name or
    44         -     tag or hash prefix for "release" in the URLs of the previous
           44  +     tag or hash prefix in place of "release" in the URLs of the previous
    45     45        bullet.  Or browse the [timeline](https://www.sqlite.org/src/timeline)
    46     46        to locate the check-in desired, click on its information page link,
    47     47        then click on the "Tarball" or "ZIP Archive" links on the information
    48     48        page.
    49     49   
    50     50   If you do want to use Fossil to check out the source tree, 
    51     51   first install Fossil version 2.0 or later.
................................................................................
   309    309   <a name="vauth"></a>
   310    310   ## Verifying Code Authenticity
   311    311   
   312    312   If you obtained an SQLite source tree from a secondary source, such as a
   313    313   GitHub mirror, and you want to verify that it has not been altered, there
   314    314   are a couple of ways to do that.
   315    315   
   316         -If you have an official release version of SQLite, and you are using the
          316  +If you have a release version of SQLite, and you are using the
   317    317   `sqlite3.c` amalgamation, then SHA3-256 hashes for the amalgamation are
   318    318   available in the [change log](https://www.sqlite.org/changes.html) on
   319    319   the official website.  After building the `sqlite3.c` file, you can check
   320         -that is authentic by comparing the hash.  This does not ensure that the
          320  +that it is authentic by comparing the hash.  This does not ensure that the
   321    321   test scripts are unaltered, but it does validate the deliverable part of
   322         -the code and only involves computing and comparing a single hash.
          322  +the code and the verification process only involves computing and
          323  +comparing a single hash.
   323    324   
   324    325   For versions other than an official release, or if you are building the
   325    326   `sqlite3.c` amalgamation using non-standard build options, the verification
   326    327   process is a little more involved.  The `manifest` file at the root directory
   327         -of the source tree ([example](https://sqlite.org/src/artifact/bd49a8271d650fa8))
          328  +of the source tree
   328    329   contains either a SHA3-256 hash (for newer files) or a SHA1 hash (for 
   329    330   older files) for every source file in the repository.  You can write a script
   330    331   to extracts hashes from `manifest` and verifies the hashes against the 
   331    332   corresponding files in the source tree.  The SHA3-256 hash of the `manifest`
   332    333   file itself is the official name of the version of the source tree that you
   333    334   have.  The `manifest.uuid` file should contain the SHA3-256 hash of the
   334    335   `manifest` file.  If all of the above hash comparisons are correct, then
   335    336   you can be confident that your source tree is authentic and unadulterated.
   336    337   
          338  +The format of the `manifest` file should be mostly self-explanatory, but
          339  +if you want details, they are available
          340  +[here](https://fossil-scm.org/fossil/doc/trunk/www/fileformat.wiki#manifest).
          341  +
   337    342   ## Contacts
   338    343   
   339         -The main SQLite webpage is [http://www.sqlite.org/](http://www.sqlite.org/)
          344  +The main SQLite website is [http://www.sqlite.org/](http://www.sqlite.org/)
   340    345   with geographically distributed backups at
   341    346   [http://www2.sqlite.org/](http://www2.sqlite.org) and
   342    347   [http://www3.sqlite.org/](http://www3.sqlite.org).

Changes to autoconf/Makefile.msc.

   429    429   
   430    430   UCRTLIBPATH = $(UCRTLIBPATH:\\=\)
   431    431   
   432    432   # C compiler and options for use in building executables that
   433    433   # will run on the platform that is doing the build.
   434    434   #
   435    435   !IF $(USE_FULLWARN)!=0
   436         -BCC = $(NCC) -nologo -W4 $(CCOPTS) $(BCCOPTS)
          436  +BCC = $(NCC) -nologo -W4 -Fd$*.pdb $(CCOPTS) $(BCCOPTS)
   437    437   !ELSE
   438         -BCC = $(NCC) -nologo -W3 $(CCOPTS) $(BCCOPTS)
          438  +BCC = $(NCC) -nologo -W3 -Fd$*.pdb $(CCOPTS) $(BCCOPTS)
   439    439   !ENDIF
   440    440   
   441    441   # Check if assembly code listings should be generated for the source
   442    442   # code files to be compiled.
   443    443   #
   444    444   !IF $(USE_LISTINGS)!=0
   445    445   BCC = $(BCC) -FAcs
................................................................................
   804    804   BCC = $(BCC) -Zi
   805    805   !ENDIF
   806    806   
   807    807   
   808    808   # Command line prefixes for compiling code, compiling resources,
   809    809   # linking, etc.
   810    810   #
   811         -LTCOMPILE = $(TCC) -Fo$@
          811  +LTCOMPILE = $(TCC) -Fo$@ -Fd$*.pdb
   812    812   LTRCOMPILE = $(RCC) -r
   813    813   LTLIB = lib.exe
   814    814   LTLINK = $(TCC) -Fe$@
   815    815   
   816    816   # If requested, link to the RPCRT4 library.
   817    817   #
   818    818   !IF $(USE_RPCRT4_LIB)!=0
................................................................................
   822    822   # If a platform was set, force the linker to target that.
   823    823   # Note that the vcvars*.bat family of batch files typically
   824    824   # set this for you.  Otherwise, the linker will attempt
   825    825   # to deduce the binary type based on the object files.
   826    826   !IFDEF PLATFORM
   827    827   LTLINKOPTS = /NOLOGO /MACHINE:$(PLATFORM)
   828    828   LTLIBOPTS = /NOLOGO /MACHINE:$(PLATFORM)
          829  +!ELSEIF "$(VISUALSTUDIOVERSION)"=="12.0" || \
          830  +        "$(VISUALSTUDIOVERSION)"=="14.0" || \
          831  +        "$(VISUALSTUDIOVERSION)"=="15.0"
          832  +LTLINKOPTS = /NOLOGO /MACHINE:x86
          833  +LTLIBOPTS = /NOLOGO /MACHINE:x86
   829    834   !ELSE
   830    835   LTLINKOPTS = /NOLOGO
   831    836   LTLIBOPTS = /NOLOGO
   832    837   !ENDIF
   833    838   
   834    839   # When compiling for use in the WinRT environment, the following
   835    840   # linker option must be used to mark the executable as runnable

Changes to ext/fts3/fts3_tokenizer.c.

    75     75   
    76     76     pHash = (Fts3Hash *)sqlite3_user_data(context);
    77     77   
    78     78     zName = sqlite3_value_text(argv[0]);
    79     79     nName = sqlite3_value_bytes(argv[0])+1;
    80     80   
    81     81     if( argc==2 ){
    82         -    if( fts3TokenizerEnabled(context) ){
           82  +    if( fts3TokenizerEnabled(context) || sqlite3_value_frombind(argv[1]) ){
    83     83         void *pOld;
    84     84         int n = sqlite3_value_bytes(argv[1]);
    85     85         if( zName==0 || n!=sizeof(pPtr) ){
    86     86           sqlite3_result_error(context, "argument type mismatch", -1);
    87     87           return;
    88     88         }
    89     89         pPtr = *(void **)sqlite3_value_blob(argv[1]);
................................................................................
   102    102       if( !pPtr ){
   103    103         char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName);
   104    104         sqlite3_result_error(context, zErr, -1);
   105    105         sqlite3_free(zErr);
   106    106         return;
   107    107       }
   108    108     }
   109         -  if( fts3TokenizerEnabled(context) ){
          109  +  if( fts3TokenizerEnabled(context) || sqlite3_value_frombind(argv[0]) ){
   110    110       sqlite3_result_blob(context, (void *)&pPtr, sizeof(pPtr), SQLITE_TRANSIENT);
   111    111     }
   112    112   }
   113    113   
   114    114   int sqlite3Fts3IsIdChar(char c){
   115    115     static const char isFtsIdChar[] = {
   116    116         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 0x */

Added ext/misc/blobio.c.

            1  +/*
            2  +** 2019-03-30
            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  +** An SQL function that uses the incremental BLOB I/O mechanism of SQLite
           14  +** to read or write part of a blob.  This is intended for debugging use
           15  +** in the CLI.
           16  +**
           17  +**      readblob(SCHEMA,TABLE,COLUMN,ROWID,OFFSET,N)
           18  +**
           19  +** Returns N bytes of the blob starting at OFFSET.
           20  +**
           21  +**      writeblob(SCHEMA,TABLE,COLUMN,ROWID,OFFSET,NEWDATA)
           22  +**
           23  +** NEWDATA must be a blob.  The content of NEWDATA overwrites the
           24  +** existing BLOB data at SCHEMA.TABLE.COLUMN for row ROWID beginning
           25  +** at OFFSET bytes into the blob.
           26  +*/
           27  +#include "sqlite3ext.h"
           28  +SQLITE_EXTENSION_INIT1
           29  +#include <assert.h>
           30  +#include <string.h>
           31  +
           32  +static void readblobFunc(
           33  +  sqlite3_context *context,
           34  +  int argc,
           35  +  sqlite3_value **argv
           36  +){
           37  +  sqlite3_blob *pBlob = 0;
           38  +  const char *zSchema;
           39  +  const char *zTable;
           40  +  const char *zColumn;
           41  +  sqlite3_int64 iRowid;
           42  +  int iOfst;
           43  +  unsigned char *aData;
           44  +  int nData;
           45  +  sqlite3 *db;
           46  +  int rc;
           47  +
           48  +  zSchema = (const char*)sqlite3_value_text(argv[0]);
           49  +  zTable = (const char*)sqlite3_value_text(argv[1]);
           50  +  if( zTable==0 ){
           51  +    sqlite3_result_error(context, "bad table name", -1);
           52  +    return;
           53  +  }
           54  +  zColumn = (const char*)sqlite3_value_text(argv[2]);
           55  +  if( zTable==0 ){
           56  +    sqlite3_result_error(context, "bad column name", -1);
           57  +    return;
           58  +  }
           59  +  iRowid = sqlite3_value_int64(argv[3]);
           60  +  iOfst = sqlite3_value_int(argv[4]);
           61  +  nData = sqlite3_value_int(argv[5]);
           62  +  if( nData<=0 ) return;
           63  +  aData = sqlite3_malloc64( nData+1 );
           64  +  if( aData==0 ){
           65  +    sqlite3_result_error_nomem(context);
           66  +    return;
           67  +  }
           68  +  db = sqlite3_context_db_handle(context);
           69  +  rc = sqlite3_blob_open(db, zSchema, zTable, zColumn, iRowid, 0, &pBlob);
           70  +  if( rc ){
           71  +    sqlite3_free(aData);
           72  +    sqlite3_result_error(context, "cannot open BLOB pointer", -1);
           73  +    return;
           74  +  }
           75  +  rc = sqlite3_blob_read(pBlob, aData, nData, iOfst);
           76  +  sqlite3_blob_close(pBlob);
           77  +  if( rc ){
           78  +    sqlite3_free(aData);
           79  +    sqlite3_result_error(context, "BLOB write failed", -1);
           80  +  }else{
           81  +    sqlite3_result_blob(context, aData, nData, sqlite3_free);
           82  +  }
           83  +}    
           84  +
           85  +static void writeblobFunc(
           86  +  sqlite3_context *context,
           87  +  int argc,
           88  +  sqlite3_value **argv
           89  +){
           90  +  sqlite3_blob *pBlob = 0;
           91  +  const char *zSchema;
           92  +  const char *zTable;
           93  +  const char *zColumn;
           94  +  sqlite3_int64 iRowid;
           95  +  int iOfst;
           96  +  unsigned char *aData;
           97  +  int nData;
           98  +  sqlite3 *db;
           99  +  int rc;
          100  +
          101  +  zSchema = (const char*)sqlite3_value_text(argv[0]);
          102  +  zTable = (const char*)sqlite3_value_text(argv[1]);
          103  +  if( zTable==0 ){
          104  +    sqlite3_result_error(context, "bad table name", -1);
          105  +    return;
          106  +  }
          107  +  zColumn = (const char*)sqlite3_value_text(argv[2]);
          108  +  if( zTable==0 ){
          109  +    sqlite3_result_error(context, "bad column name", -1);
          110  +    return;
          111  +  }
          112  +  iRowid = sqlite3_value_int64(argv[3]);
          113  +  iOfst = sqlite3_value_int(argv[4]);
          114  +  if( sqlite3_value_type(argv[5])!=SQLITE_BLOB ){
          115  +    sqlite3_result_error(context, "6th argument must be a BLOB", -1);
          116  +    return;
          117  +  }
          118  +  nData = sqlite3_value_bytes(argv[5]);
          119  +  aData = (unsigned char *)sqlite3_value_blob(argv[5]);
          120  +  db = sqlite3_context_db_handle(context);
          121  +  rc = sqlite3_blob_open(db, zSchema, zTable, zColumn, iRowid, 1, &pBlob);
          122  +  if( rc ){
          123  +    sqlite3_result_error(context, "cannot open BLOB pointer", -1);
          124  +    return;
          125  +  }
          126  +  rc = sqlite3_blob_write(pBlob, aData, nData, iOfst);
          127  +  sqlite3_blob_close(pBlob);
          128  +  if( rc ){
          129  +    sqlite3_result_error(context, "BLOB write failed", -1);
          130  +  }
          131  +}    
          132  +
          133  +
          134  +#ifdef _WIN32
          135  +__declspec(dllexport)
          136  +#endif
          137  +int sqlite3_blobio_init(
          138  +  sqlite3 *db, 
          139  +  char **pzErrMsg, 
          140  +  const sqlite3_api_routines *pApi
          141  +){
          142  +  int rc = SQLITE_OK;
          143  +  SQLITE_EXTENSION_INIT2(pApi);
          144  +  (void)pzErrMsg;  /* Unused parameter */
          145  +  rc = sqlite3_create_function(db, "readblob", 6, SQLITE_UTF8, 0,
          146  +                               readblobFunc, 0, 0);
          147  +  if( rc==SQLITE_OK ){
          148  +    rc = sqlite3_create_function(db, "writeblob", 6, SQLITE_UTF8, 0,
          149  +                               writeblobFunc, 0, 0);
          150  +  }
          151  +  return rc;
          152  +}

Changes to ext/misc/fileio.c.

   154    154     }
   155    155     pBuf = sqlite3_malloc64( nIn ? nIn : 1 );
   156    156     if( pBuf==0 ){
   157    157       sqlite3_result_error_nomem(ctx);
   158    158       fclose(in);
   159    159       return;
   160    160     }
   161         -  if( nIn==fread(pBuf, 1, (size_t)nIn, in) ){
          161  +  if( nIn==(sqlite3_int64)fread(pBuf, 1, (size_t)nIn, in) ){
   162    162       sqlite3_result_blob64(ctx, pBuf, nIn, sqlite3_free);
   163    163     }else{
   164    164       sqlite3_result_error_code(ctx, SQLITE_IOERR);
   165    165       sqlite3_free(pBuf);
   166    166     }
   167    167     fclose(in);
   168    168   }

Changes to ext/session/changesetfuzz.c.

   150    150     }
   151    151     fseek(f, 0, SEEK_END);
   152    152     sz = ftell(f);
   153    153     rewind(f);
   154    154     pBuf = sqlite3_malloc64( sz ? sz : 1 );
   155    155     if( pBuf==0 ){
   156    156       fprintf(stderr, "cannot allocate %d to hold content of \"%s\"\n",
   157         -            sz, zFilename);
          157  +            (int)sz, zFilename);
   158    158       exit(1);
   159    159     }
   160    160     if( sz>0 ){
   161         -    if( fread(pBuf, sz, 1, f)!=1 ){
   162         -      fprintf(stderr, "cannot read all %d bytes of \"%s\"\n", sz, zFilename);
          161  +    if( fread(pBuf, (size_t)sz, 1, f)!=1 ){
          162  +      fprintf(stderr, "cannot read all %d bytes of \"%s\"\n",
          163  +              (int)sz, zFilename);
   163    164         exit(1);
   164    165       }
   165    166       fclose(f);
   166    167     }
   167         -  *pSz = sz;
          168  +  *pSz = (int)sz;
   168    169     *ppBuf = pBuf;
   169    170   }
   170    171   
   171    172   /* 
   172    173   ** Write the contents of buffer pBuf, size nBuf bytes, into file zFilename
   173    174   ** on disk. zFilename, if it already exists, is clobbered.
   174    175   */
................................................................................
   339    340   
   340    341   /*
   341    342   ** Allocate and return nByte bytes of zeroed memory.
   342    343   */
   343    344   static void *fuzzMalloc(sqlite3_int64 nByte){
   344    345     void *pRet = sqlite3_malloc64(nByte);
   345    346     if( pRet ){
   346         -    memset(pRet, 0, nByte);
          347  +    memset(pRet, 0, (size_t)nByte);
   347    348     }
   348    349     return pRet;
   349    350   }
   350    351   
   351    352   /*
   352    353   ** Free the buffer indicated by the first argument. This function is used
   353    354   ** to free buffers allocated by fuzzMalloc().
................................................................................
   380    381   ** Write value nVal into the buffer indicated by argument p as an SQLite
   381    382   ** varint. nVal is guaranteed to be between 0 and (2^21-1), inclusive.
   382    383   ** Return the number of bytes written to buffer p.
   383    384   */
   384    385   static int fuzzPutVarint(u8 *p, int nVal){
   385    386     assert( nVal>0 && nVal<2097152 );
   386    387     if( nVal<128 ){
   387         -    p[0] = nVal;
          388  +    p[0] = (u8)nVal;
   388    389       return 1;
   389    390     }
   390    391     if( nVal<16384 ){
   391    392       p[0] = ((nVal >> 7) & 0x7F) | 0x80;
   392    393       p[1] = (nVal & 0x7F);
   393    394       return 2;
   394    395     }
................................................................................
   455    456         rc = fuzzCorrupt();
   456    457       }else{
   457    458         p++;
   458    459         p += fuzzGetVarint(p, &pGrp->nCol);
   459    460         pGrp->aPK = p;
   460    461         p += pGrp->nCol;
   461    462         pGrp->zTab = (const char*)p;
   462         -      p = &p[strlen(p)+1];
          463  +      p = &p[strlen((const char*)p)+1];
   463    464   
   464    465         if( p>=pEnd ){
   465    466           rc = fuzzCorrupt();
   466    467         }
   467    468       }
   468    469       *ppHdr = p;
   469    470     }
................................................................................
   691    692             p += 8;
   692    693             break;
   693    694           }
   694    695   
   695    696           case 0x03:                    /* text */
   696    697           case 0x04: {                  /* blob */
   697    698             int nTxt;
   698         -          int sz;
   699         -          int i;
   700    699             p += fuzzGetVarint(p, &nTxt);
   701    700             printf("%s%s", zPre, eType==0x03 ? "'" : "X'");
   702    701             for(i=0; i<nTxt; i++){
   703    702               if( eType==0x03 ){
   704    703                 printf("%c", p[i]);
   705    704               }else{
   706    705                 char aHex[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
................................................................................
   855    854             fuzzPutU64(&pChange->aSub[1], iVal1);
   856    855             break;
   857    856           }
   858    857   
   859    858           case 0x03:                    /* text */
   860    859           case 0x04: {                  /* blob */
   861    860             int nByte = fuzzRandomInt(48);
   862         -          pChange->aSub[1] = nByte;
          861  +          pChange->aSub[1] = (u8)nByte;
   863    862             fuzzRandomBlob(nByte, &pChange->aSub[2]);
   864    863             if( pChange->aSub[0]==0x03 ){
   865    864               int i;
   866    865               for(i=0; i<nByte; i++){
   867    866                 pChange->aSub[2+i] &= 0x7F;
   868    867               }
   869    868             }
................................................................................
  1000    999         }
  1001   1000   
  1002   1001         if( p==pFuzz->pSub1 ){
  1003   1002           pCopy = pFuzz->pSub2;
  1004   1003         }else if( p==pFuzz->pSub2 ){
  1005   1004           pCopy = pFuzz->pSub1;
  1006   1005         }else if( i==iUndef ){
  1007         -        pCopy = "\0";
         1006  +        pCopy = (u8*)"\0";
  1008   1007         }
  1009   1008   
  1010   1009         if( pCopy[0]==0x00 && eNew!=eType && eType==SQLITE_UPDATE && iRec==0 ){
  1011   1010           while( pCopy[0]==0x00 ){
  1012   1011             pCopy = pParse->apVal[fuzzRandomInt(pParse->nVal)];
  1013   1012           }
  1014   1013         }else if( p[0]==0x00 && pCopy[0]!=0x00 ){
................................................................................
  1063   1062       }
  1064   1063       if( eNew!=eType && eNew==SQLITE_UPDATE && !bPS ){
  1065   1064         int i;
  1066   1065         u8 *pCsr = (*ppOut) + 2;
  1067   1066         for(i=0; i<pGrp->nCol; i++){
  1068   1067           int sz;
  1069   1068           u8 *pCopy = pCsr;
  1070         -        if( pGrp->aPK[i] ) pCopy = "\0";
         1069  +        if( pGrp->aPK[i] ) pCopy = (u8*)"\0";
  1071   1070           fuzzChangeSize(pCopy, &sz);
  1072   1071           memcpy(pOut, pCopy, sz);
  1073   1072           pOut += sz;
  1074   1073           fuzzChangeSize(pCsr, &sz);
  1075   1074           pCsr += sz;
  1076   1075         }
  1077   1076       }

Changes to ext/session/sqlite3session.c.

  3858   3858       if( rc!=SQLITE_ROW ) rc = sqlite3_reset(pSelect);
  3859   3859     }
  3860   3860   
  3861   3861     return rc;
  3862   3862   }
  3863   3863   
  3864   3864   /*
  3865         -** This function is called from within sqlite3changset_apply_v2() when
         3865  +** This function is called from within sqlite3changeset_apply_v2() when
  3866   3866   ** a conflict is encountered and resolved using conflict resolution
  3867   3867   ** mode eType (either SQLITE_CHANGESET_OMIT or SQLITE_CHANGESET_REPLACE)..
  3868   3868   ** It adds a conflict resolution record to the buffer in 
  3869   3869   ** SessionApplyCtx.rebase, which will eventually be returned to the caller
  3870   3870   ** of apply_v2() as the "rebase" buffer.
  3871   3871   **
  3872   3872   ** Return SQLITE_OK if successful, or an SQLite error code otherwise.

Changes to ext/session/sqlite3session.h.

  1411   1411   ** CAPI3REF: Rebase a changeset
  1412   1412   ** EXPERIMENTAL
  1413   1413   **
  1414   1414   ** Argument pIn must point to a buffer containing a changeset nIn bytes
  1415   1415   ** in size. This function allocates and populates a buffer with a copy
  1416   1416   ** of the changeset rebased rebased according to the configuration of the
  1417   1417   ** rebaser object passed as the first argument. If successful, (*ppOut)
  1418         -** is set to point to the new buffer containing the rebased changset and 
         1418  +** is set to point to the new buffer containing the rebased changeset and 
  1419   1419   ** (*pnOut) to its size in bytes and SQLITE_OK returned. It is the
  1420   1420   ** responsibility of the caller to eventually free the new buffer using
  1421   1421   ** sqlite3_free(). Otherwise, if an error occurs, (*ppOut) and (*pnOut)
  1422   1422   ** are set to zero and an SQLite error code returned.
  1423   1423   */
  1424   1424   int sqlite3rebaser_rebase(
  1425   1425     sqlite3_rebaser*,

Changes to main.mk.

   347    347     $(TOP)/src/test_server.c \
   348    348     $(TOP)/src/test_sqllog.c \
   349    349     $(TOP)/src/test_superlock.c \
   350    350     $(TOP)/src/test_syscall.c \
   351    351     $(TOP)/src/test_tclsh.c \
   352    352     $(TOP)/src/test_tclvar.c \
   353    353     $(TOP)/src/test_thread.c \
          354  +  $(TOP)/src/test_vdbecov.c \
   354    355     $(TOP)/src/test_vfs.c \
   355    356     $(TOP)/src/test_windirent.c \
   356    357     $(TOP)/src/test_window.c \
   357    358     $(TOP)/src/test_wsd.c
   358    359   
   359    360   # Extensions to be statically loaded.
   360    361   #

Changes to src/btree.c.

   835    835   ** when saveCursorPosition() was called. Note that this call deletes the 
   836    836   ** saved position info stored by saveCursorPosition(), so there can be
   837    837   ** at most one effective restoreCursorPosition() call after each 
   838    838   ** saveCursorPosition().
   839    839   */
   840    840   static int btreeRestoreCursorPosition(BtCursor *pCur){
   841    841     int rc;
   842         -  int skipNext;
          842  +  int skipNext = 0;
   843    843     assert( cursorOwnsBtShared(pCur) );
   844    844     assert( pCur->eState>=CURSOR_REQUIRESEEK );
   845    845     if( pCur->eState==CURSOR_FAULT ){
   846    846       return pCur->skipNext;
   847    847     }
   848    848     pCur->eState = CURSOR_INVALID;
   849         -  rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &skipNext);
          849  +  if( sqlite3FaultSim(410) ){
          850  +    rc = SQLITE_IOERR;
          851  +  }else{
          852  +    rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &skipNext);
          853  +  }
   850    854     if( rc==SQLITE_OK ){
   851    855       sqlite3_free(pCur->pKey);
   852    856       pCur->pKey = 0;
   853    857       assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID );
   854    858       if( skipNext ) pCur->skipNext = skipNext;
   855    859       if( pCur->skipNext && pCur->eState==CURSOR_VALID ){
   856    860         pCur->eState = CURSOR_SKIPNEXT;
................................................................................
  1434   1438     /* This block handles pages with two or fewer free blocks and nMaxFrag
  1435   1439     ** or fewer fragmented bytes. In this case it is faster to move the
  1436   1440     ** two (or one) blocks of cells using memmove() and add the required
  1437   1441     ** offsets to each pointer in the cell-pointer array than it is to 
  1438   1442     ** reconstruct the entire page.  */
  1439   1443     if( (int)data[hdr+7]<=nMaxFrag ){
  1440   1444       int iFree = get2byte(&data[hdr+1]);
  1441         -
  1442         -    /* If the initial freeblock offset were out of bounds, that would have
  1443         -    ** been detected by btreeComputeFreeSpace() when it was computing the
  1444         -    ** number of free bytes on the page. */
  1445         -    assert( iFree<=usableSize-4 );
         1445  +    if( iFree>usableSize-4 ) return SQLITE_CORRUPT_PAGE(pPage);
  1446   1446       if( iFree ){
  1447   1447         int iFree2 = get2byte(&data[iFree]);
  1448   1448         if( iFree2>usableSize-4 ) return SQLITE_CORRUPT_PAGE(pPage);
  1449   1449         if( 0==iFree2 || (data[iFree2]==0 && data[iFree2+1]==0) ){
  1450   1450           u8 *pEnd = &data[cellOffset + nCell*2];
  1451   1451           u8 *pAddr;
  1452   1452           int sz2 = 0;
................................................................................
  5275   5275       assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
  5276   5276       *pRes = 1;
  5277   5277       rc = SQLITE_OK;
  5278   5278     }
  5279   5279     return rc;
  5280   5280   }
  5281   5281   
  5282         -/*
  5283         -** This function is a no-op if cursor pCur does not point to a valid row.
  5284         -** Otherwise, if pCur is valid, configure it so that the next call to
  5285         -** sqlite3BtreeNext() is a no-op.
  5286         -*/
  5287         -#ifndef SQLITE_OMIT_WINDOWFUNC
  5288         -void sqlite3BtreeSkipNext(BtCursor *pCur){
  5289         -  /* We believe that the cursor must always be in the valid state when
  5290         -  ** this routine is called, but the proof is difficult, so we add an
  5291         -  ** ALWaYS() test just in case we are wrong. */
  5292         -  if( ALWAYS(pCur->eState==CURSOR_VALID) ){
  5293         -    pCur->eState = CURSOR_SKIPNEXT;
  5294         -    pCur->skipNext = 1;
  5295         -  }
  5296         -}
  5297         -#endif /* SQLITE_OMIT_WINDOWFUNC */
  5298         -
  5299   5282   /* Move the cursor to the last entry in the table.  Return SQLITE_OK
  5300   5283   ** on success.  Set *pRes to 0 if the cursor actually points to something
  5301   5284   ** or set *pRes to 1 if the table is empty.
  5302   5285   */
  5303   5286   int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
  5304   5287     int rc;
  5305   5288    
................................................................................
  8836   8819   
  8837   8820     assert( cursorOwnsBtShared(pCur) );
  8838   8821     assert( pBt->inTransaction==TRANS_WRITE );
  8839   8822     assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
  8840   8823     assert( pCur->curFlags & BTCF_WriteFlag );
  8841   8824     assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
  8842   8825     assert( !hasReadConflicts(p, pCur->pgnoRoot) );
  8843         -  assert( pCur->ix<pCur->pPage->nCell );
  8844         -  assert( pCur->eState==CURSOR_VALID );
  8845   8826     assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 );
         8827  +  if( pCur->eState==CURSOR_REQUIRESEEK ){
         8828  +    rc = btreeRestoreCursorPosition(pCur);
         8829  +    if( rc ) return rc;
         8830  +  }
         8831  +  assert( pCur->eState==CURSOR_VALID );
  8846   8832   
  8847   8833     iCellDepth = pCur->iPage;
  8848   8834     iCellIdx = pCur->ix;
  8849   8835     pPage = pCur->pPage;
  8850   8836     pCell = findCell(pPage, iCellIdx);
  8851   8837     if( pPage->nFree<0 && btreeComputeFreeSpace(pPage) ) return SQLITE_CORRUPT;
  8852   8838   

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
   307    304   int sqlite3BtreeLast(BtCursor*, int *pRes);
   308    305   int sqlite3BtreeNext(BtCursor*, int flags);
   309    306   int sqlite3BtreeEof(BtCursor*);
   310    307   int sqlite3BtreePrevious(BtCursor*, int flags);
   311    308   i64 sqlite3BtreeIntegerKey(BtCursor*);
   312    309   #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
   313    310   i64 sqlite3BtreeOffset(BtCursor*);

Changes to src/build.c.

   260    260     zSql = sqlite3VMPrintf(db, zFormat, ap);
   261    261     va_end(ap);
   262    262     if( zSql==0 ){
   263    263       /* This can result either from an OOM or because the formatted string
   264    264       ** exceeds SQLITE_LIMIT_LENGTH.  In the latter case, we need to set
   265    265       ** an error */
   266    266       if( !db->mallocFailed ) pParse->rc = SQLITE_TOOBIG;
          267  +    pParse->nErr++;
   267    268       return;
   268    269     }
   269    270     pParse->nested++;
   270    271     memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ);
   271    272     memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
   272    273     sqlite3RunParser(pParse, zSql, &zErrMsg);
   273    274     sqlite3DbFree(db, zErrMsg);
................................................................................
  3260   3261       pList = sqlite3ExprListAppend(pParse, 0,
  3261   3262                 sqlite3ExprAlloc(db, TK_ID, &prevCol, 0));
  3262   3263       if( pList==0 ) goto exit_create_index;
  3263   3264       assert( pList->nExpr==1 );
  3264   3265       sqlite3ExprListSetSortOrder(pList, sortOrder);
  3265   3266     }else{
  3266   3267       sqlite3ExprListCheckLength(pParse, pList, "index");
         3268  +    if( pParse->nErr ) goto exit_create_index;
  3267   3269     }
  3268   3270   
  3269   3271     /* Figure out how many bytes of space are required to store explicitly
  3270   3272     ** specified collation sequence names.
  3271   3273     */
  3272   3274     for(i=0; i<pList->nExpr; i++){
  3273   3275       Expr *pExpr = pList->a[i].pExpr;
................................................................................
  3278   3280     }
  3279   3281   
  3280   3282     /* 
  3281   3283     ** Allocate the index structure. 
  3282   3284     */
  3283   3285     nName = sqlite3Strlen30(zName);
  3284   3286     nExtraCol = pPk ? pPk->nKeyCol : 1;
         3287  +  assert( pList->nExpr + nExtraCol <= 32767 /* Fits in i16 */ );
  3285   3288     pIndex = sqlite3AllocateIndexObject(db, pList->nExpr + nExtraCol,
  3286   3289                                         nName + nExtra + 1, &zExtra);
  3287   3290     if( db->mallocFailed ){
  3288   3291       goto exit_create_index;
  3289   3292     }
  3290   3293     assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowLogEst) );
  3291   3294     assert( EIGHT_BYTE_ALIGNMENT(pIndex->azColl) );

Changes to src/expr.c.

  5028   5028   ** an ordinary JOIN.  The p argument is the WHERE clause.  If the WHERE
  5029   5029   ** clause requires that some column of the right table of the LEFT JOIN
  5030   5030   ** be non-NULL, then the LEFT JOIN can be safely converted into an
  5031   5031   ** ordinary join.
  5032   5032   */
  5033   5033   int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){
  5034   5034     Walker w;
         5035  +  p = sqlite3ExprSkipCollate(p);
         5036  +  while( p ){
         5037  +    if( p->op==TK_NOTNULL ){
         5038  +      p = p->pLeft;
         5039  +    }else if( p->op==TK_AND ){
         5040  +      if( sqlite3ExprImpliesNonNullRow(p->pLeft, iTab) ) return 1;
         5041  +      p = p->pRight;
         5042  +    }else{
         5043  +      break;
         5044  +    }
         5045  +  }
  5035   5046     w.xExprCallback = impliesNotNullRow;
  5036   5047     w.xSelectCallback = 0;
  5037   5048     w.xSelectCallback2 = 0;
  5038   5049     w.eCode = 0;
  5039   5050     w.u.iCur = iTab;
  5040   5051     sqlite3WalkExpr(&w, p);
  5041   5052     return w.eCode;

Changes to src/parse.y.

   214    214     QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW ROWS
   215    215     ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT
   216    216   %ifdef SQLITE_OMIT_COMPOUND_SELECT
   217    217     EXCEPT INTERSECT UNION
   218    218   %endif SQLITE_OMIT_COMPOUND_SELECT
   219    219   %ifndef SQLITE_OMIT_WINDOWFUNC
   220    220     CURRENT FOLLOWING PARTITION PRECEDING RANGE UNBOUNDED
          221  +  EXCLUDE GROUPS OTHERS TIES
   221    222   %endif SQLITE_OMIT_WINDOWFUNC
   222    223     REINDEX RENAME CTIME_KW IF
   223    224     .
   224    225   %wildcard ANY.
   225    226   
   226    227   // Define operator precedence early so that this is the first occurrence
   227    228   // of the operator tokens in the grammer.  Keeping the operators together
................................................................................
  1629   1630   //
  1630   1631   %ifndef SQLITE_OMIT_WINDOWFUNC
  1631   1632   %type windowdefn_list {Window*}
  1632   1633   %destructor windowdefn_list {sqlite3WindowListDelete(pParse->db, $$);}
  1633   1634   windowdefn_list(A) ::= windowdefn(Z). { A = Z; }
  1634   1635   windowdefn_list(A) ::= windowdefn_list(Y) COMMA windowdefn(Z). {
  1635   1636     assert( Z!=0 );
         1637  +  sqlite3WindowChain(pParse, Z, Y);
  1636   1638     Z->pNextWin = Y;
  1637   1639     A = Z;
  1638   1640   }
  1639   1641   
  1640   1642   %type windowdefn {Window*}
  1641   1643   %destructor windowdefn {sqlite3WindowDelete(pParse->db, $$);}
  1642         -windowdefn(A) ::= nm(X) AS window(Y). {
         1644  +windowdefn(A) ::= nm(X) AS LP window(Y) RP. {
  1643   1645     if( ALWAYS(Y) ){
  1644   1646       Y->zName = sqlite3DbStrNDup(pParse->db, X.z, X.n);
  1645   1647     }
  1646   1648     A = Y;
  1647   1649   }
  1648   1650   
  1649   1651   %type window {Window*}
................................................................................
  1663   1665   %type frame_bound {struct FrameBound}
  1664   1666   %destructor frame_bound {sqlite3ExprDelete(pParse->db, $$.pExpr);}
  1665   1667   %type frame_bound_s {struct FrameBound}
  1666   1668   %destructor frame_bound_s {sqlite3ExprDelete(pParse->db, $$.pExpr);}
  1667   1669   %type frame_bound_e {struct FrameBound}
  1668   1670   %destructor frame_bound_e {sqlite3ExprDelete(pParse->db, $$.pExpr);}
  1669   1671   
  1670         -window(A) ::= LP part_opt(X) orderby_opt(Y) frame_opt(Z) RP. {
         1672  +window(A) ::= PARTITION BY nexprlist(X) orderby_opt(Y) frame_opt(Z). {
         1673  +  A = sqlite3WindowAssemble(pParse, Z, X, Y, 0);
         1674  +}
         1675  +window(A) ::= nm(W) PARTITION BY nexprlist(X) orderby_opt(Y) frame_opt(Z). {
         1676  +  A = sqlite3WindowAssemble(pParse, Z, X, Y, &W);
         1677  +}
         1678  +window(A) ::= ORDER BY sortlist(Y) frame_opt(Z). {
         1679  +  A = sqlite3WindowAssemble(pParse, Z, 0, Y, 0);
         1680  +}
         1681  +window(A) ::= nm(W) ORDER BY sortlist(Y) frame_opt(Z). {
         1682  +  A = sqlite3WindowAssemble(pParse, Z, 0, Y, &W);
         1683  +}
         1684  +window(A) ::= frame_opt(Z). {
  1671   1685     A = Z;
  1672         -  if( ALWAYS(A) ){
  1673         -    A->pPartition = X;
  1674         -    A->pOrderBy = Y;
  1675         -  }
  1676   1686   }
  1677         -
  1678         -part_opt(A) ::= PARTITION BY nexprlist(X). { A = X; }
  1679         -part_opt(A) ::= .                          { A = 0; }
         1687  +window(A) ::= nm(W) frame_opt(Z). {
         1688  +  A = sqlite3WindowAssemble(pParse, Z, 0, 0, &W);
         1689  +}
  1680   1690   
  1681   1691   frame_opt(A) ::= .                             { 
  1682         -  A = sqlite3WindowAlloc(pParse, TK_RANGE, TK_UNBOUNDED, 0, TK_CURRENT, 0);
         1692  +  A = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0);
  1683   1693   }
  1684         -frame_opt(A) ::= range_or_rows(X) frame_bound_s(Y). { 
  1685         -  A = sqlite3WindowAlloc(pParse, X, Y.eType, Y.pExpr, TK_CURRENT, 0);
         1694  +frame_opt(A) ::= range_or_rows(X) frame_bound_s(Y) frame_exclude_opt(Z). { 
         1695  +  A = sqlite3WindowAlloc(pParse, X, Y.eType, Y.pExpr, TK_CURRENT, 0, Z);
  1686   1696   }
  1687         -frame_opt(A) ::= range_or_rows(X) BETWEEN frame_bound_s(Y) AND frame_bound_e(Z). { 
  1688         -  A = sqlite3WindowAlloc(pParse, X, Y.eType, Y.pExpr, Z.eType, Z.pExpr);
         1697  +frame_opt(A) ::= range_or_rows(X) BETWEEN frame_bound_s(Y) AND frame_bound_e(Z) frame_exclude_opt(W). { 
         1698  +  A = sqlite3WindowAlloc(pParse, X, Y.eType, Y.pExpr, Z.eType, Z.pExpr, W);
  1689   1699   }
  1690   1700   
  1691   1701   range_or_rows(A) ::= RANGE.   { A = TK_RANGE; }
  1692   1702   range_or_rows(A) ::= ROWS.    { A = TK_ROWS;  }
         1703  +range_or_rows(A) ::= GROUPS.  { A = TK_GROUPS;}
  1693   1704   
  1694   1705   
  1695   1706   frame_bound_s(A) ::= frame_bound(X). { A = X; }
  1696   1707   frame_bound_s(A) ::= UNBOUNDED PRECEDING. {A.eType = TK_UNBOUNDED; A.pExpr = 0;}
  1697   1708   frame_bound_e(A) ::= frame_bound(X). { A = X; }
  1698   1709   frame_bound_e(A) ::= UNBOUNDED FOLLOWING. {A.eType = TK_UNBOUNDED; A.pExpr = 0;}
  1699   1710   
  1700   1711   frame_bound(A) ::= expr(X) PRECEDING.   { A.eType = TK_PRECEDING; A.pExpr = X; }
  1701   1712   frame_bound(A) ::= CURRENT ROW.         { A.eType = TK_CURRENT  ; A.pExpr = 0; }
  1702   1713   frame_bound(A) ::= expr(X) FOLLOWING.   { A.eType = TK_FOLLOWING; A.pExpr = X; }
         1714  +
         1715  +%type frame_exclude_opt {u8}
         1716  +frame_exclude_opt(A) ::= . { A = 0; }
         1717  +frame_exclude_opt(A) ::= EXCLUDE frame_exclude(X). { A = X; }
         1718  +
         1719  +%type frame_exclude {u8}
         1720  +frame_exclude(A) ::= NO OTHERS.   { A = 0; }
         1721  +frame_exclude(A) ::= CURRENT ROW. { A = TK_CURRENT; }
         1722  +frame_exclude(A) ::= GROUP.       { A = TK_GROUP; }
         1723  +frame_exclude(A) ::= TIES.        { A = TK_TIES; }
         1724  +
  1703   1725   
  1704   1726   %type window_clause {Window*}
  1705   1727   %destructor window_clause {sqlite3WindowListDelete(pParse->db, $$);}
  1706   1728   window_clause(A) ::= WINDOW windowdefn_list(B). { A = B; }
  1707   1729   
  1708   1730   %type over_clause {Window*}
  1709   1731   %destructor over_clause {sqlite3WindowDelete(pParse->db, $$);}
  1710         -over_clause(A) ::= filter_opt(W) OVER window(Z). {
         1732  +over_clause(A) ::= filter_opt(W) OVER LP window(Z) RP. {
  1711   1733     A = Z;
  1712   1734     assert( A!=0 );
  1713   1735     A->pFilter = W;
  1714   1736   }
  1715   1737   over_clause(A) ::= filter_opt(W) OVER nm(Z). {
  1716   1738     A = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
  1717   1739     if( A ){

Changes to src/resolve.c.

   430    430             assert( pExpr->pLeft==0 && pExpr->pRight==0 );
   431    431             assert( pExpr->x.pList==0 );
   432    432             assert( pExpr->x.pSelect==0 );
   433    433             pOrig = pEList->a[j].pExpr;
   434    434             if( (pNC->ncFlags&NC_AllowAgg)==0 && ExprHasProperty(pOrig, EP_Agg) ){
   435    435               sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
   436    436               return WRC_Abort;
          437  +          }
          438  +          if( (pNC->ncFlags&NC_AllowWin)==0 && ExprHasProperty(pOrig, EP_Win) ){
          439  +            sqlite3ErrorMsg(pParse, "misuse of aliased window function %s",zAs);
          440  +            return WRC_Abort;
   437    441             }
   438    442             if( sqlite3ExprVectorSize(pOrig)!=1 ){
   439    443               sqlite3ErrorMsg(pParse, "row value misused");
   440    444               return WRC_Abort;
   441    445             }
   442    446             resolveAlias(pParse, pEList, j, pExpr, "", nSubquery);
   443    447             cnt = 1;
................................................................................
   721    725         int no_such_func = 0;       /* True if no such function exists */
   722    726         int wrong_num_args = 0;     /* True if wrong number of arguments */
   723    727         int is_agg = 0;             /* True if is an aggregate function */
   724    728         int nId;                    /* Number of characters in function name */
   725    729         const char *zId;            /* The function name. */
   726    730         FuncDef *pDef;              /* Information about the function */
   727    731         u8 enc = ENC(pParse->db);   /* The database encoding */
          732  +      int savedAllowFlags = (pNC->ncFlags & (NC_AllowAgg | NC_AllowWin));
   728    733   
   729    734         assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
   730    735         zId = pExpr->u.zToken;
   731    736         nId = sqlite3Strlen30(zId);
   732    737         pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
   733    738         if( pDef==0 ){
   734    739           pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0);
................................................................................
   842    847             pNC->nErr++;
   843    848           }else if( wrong_num_args ){
   844    849             sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()",
   845    850                  nId, zId);
   846    851             pNC->nErr++;
   847    852           }
   848    853           if( is_agg ){
          854  +          /* Window functions may not be arguments of aggregate functions.
          855  +          ** Or arguments of other window functions. But aggregate functions
          856  +          ** may be arguments for window functions.  */
   849    857   #ifndef SQLITE_OMIT_WINDOWFUNC
   850         -          pNC->ncFlags &= ~(pExpr->y.pWin ? NC_AllowWin : NC_AllowAgg);
          858  +          pNC->ncFlags &= ~(NC_AllowWin | (!pExpr->y.pWin ? NC_AllowAgg : 0));
   851    859   #else
   852    860             pNC->ncFlags &= ~NC_AllowAgg;
   853    861   #endif
   854    862           }
   855    863         }
   856    864         sqlite3WalkExprList(pWalker, pList);
   857    865         if( is_agg ){
................................................................................
   864    872             sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
   865    873             if( 0==pSel->pWin 
   866    874              || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->y.pWin) 
   867    875             ){
   868    876               pExpr->y.pWin->pNextWin = pSel->pWin;
   869    877               pSel->pWin = pExpr->y.pWin;
   870    878             }
   871         -          pNC->ncFlags |= NC_AllowWin;
          879  +          pNC->ncFlags |= NC_HasWin;
   872    880           }else
   873    881   #endif /* SQLITE_OMIT_WINDOWFUNC */
   874    882           {
   875    883             NameContext *pNC2 = pNC;
   876    884             pExpr->op = TK_AGG_FUNCTION;
   877    885             pExpr->op2 = 0;
   878    886             while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){
................................................................................
   882    890             assert( pDef!=0 );
   883    891             if( pNC2 ){
   884    892               assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
   885    893               testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
   886    894               pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX);
   887    895   
   888    896             }
   889         -          pNC->ncFlags |= NC_AllowAgg;
   890    897           }
          898  +        pNC->ncFlags |= savedAllowFlags;
   891    899         }
   892    900         /* FIX ME:  Compute pExpr->affinity based on the expected return
   893    901         ** type of the function 
   894    902         */
   895    903         return WRC_Prune;
   896    904       }
   897    905   #ifndef SQLITE_OMIT_SUBQUERY
................................................................................
  1420   1428         p->pOrderBy = 0;
  1421   1429       }
  1422   1430     
  1423   1431       /* Recursively resolve names in all subqueries
  1424   1432       */
  1425   1433       for(i=0; i<p->pSrc->nSrc; i++){
  1426   1434         struct SrcList_item *pItem = &p->pSrc->a[i];
  1427         -      if( pItem->pSelect ){
         1435  +      if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){
  1428   1436           NameContext *pNC;         /* Used to iterate name contexts */
  1429   1437           int nRef = 0;             /* Refcount for pOuterNC and outer contexts */
  1430   1438           const char *zSavedContext = pParse->zAuthContext;
  1431   1439   
  1432   1440           /* Count the total number of references to pOuterNC and all of its
  1433   1441           ** parent contexts. After resolving references to expressions in
  1434   1442           ** pItem->pSelect, check if this value has changed. If so, then
................................................................................
  1644   1652     NameContext *pNC,       /* Namespace to resolve expressions in. */
  1645   1653     Expr *pExpr             /* The expression to be analyzed. */
  1646   1654   ){
  1647   1655     u16 savedHasAgg;
  1648   1656     Walker w;
  1649   1657   
  1650   1658     if( pExpr==0 ) return SQLITE_OK;
  1651         -  savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg);
  1652         -  pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg);
         1659  +  savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
         1660  +  pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
  1653   1661     w.pParse = pNC->pParse;
  1654   1662     w.xExprCallback = resolveExprStep;
  1655   1663     w.xSelectCallback = resolveSelectStep;
  1656   1664     w.xSelectCallback2 = 0;
  1657   1665     w.u.pNC = pNC;
  1658   1666   #if SQLITE_MAX_EXPR_DEPTH>0
  1659   1667     w.pParse->nHeight += pExpr->nHeight;
................................................................................
  1661   1669       return SQLITE_ERROR;
  1662   1670     }
  1663   1671   #endif
  1664   1672     sqlite3WalkExpr(&w, pExpr);
  1665   1673   #if SQLITE_MAX_EXPR_DEPTH>0
  1666   1674     w.pParse->nHeight -= pExpr->nHeight;
  1667   1675   #endif
  1668         -  if( pNC->ncFlags & NC_HasAgg ){
  1669         -    ExprSetProperty(pExpr, EP_Agg);
  1670         -  }
         1676  +  assert( EP_Agg==NC_HasAgg );
         1677  +  assert( EP_Win==NC_HasWin );
         1678  +  testcase( pNC->ncFlags & NC_HasAgg );
         1679  +  testcase( pNC->ncFlags & NC_HasWin );
         1680  +  ExprSetProperty(pExpr, pNC->ncFlags & (NC_HasAgg|NC_HasWin) );
  1671   1681     pNC->ncFlags |= savedHasAgg;
  1672   1682     return pNC->nErr>0 || w.pParse->nErr>0;
  1673   1683   }
  1674   1684   
  1675   1685   /*
  1676   1686   ** Resolve all names for all expression in an expression list.  This is
  1677   1687   ** just like sqlite3ResolveExprNames() except that it works for an expression

Changes to src/sqlite.h.in.

   185    185   **
   186    186   ** See also: SQL functions [sqlite_compileoption_used()] and
   187    187   ** [sqlite_compileoption_get()] and the [compile_options pragma].
   188    188   */
   189    189   #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
   190    190   int sqlite3_compileoption_used(const char *zOptName);
   191    191   const char *sqlite3_compileoption_get(int N);
          192  +#else
          193  +# define sqlite3_compileoption_used(X) 0
          194  +# define sqlite3_compileoption_get(X)  ((void*)0)
   192    195   #endif
   193    196   
   194    197   /*
   195    198   ** CAPI3REF: Test To See If The Library Is Threadsafe
   196    199   **
   197    200   ** ^The sqlite3_threadsafe() function returns zero if and only if
   198    201   ** SQLite was compiled with mutexing code omitted due to the
................................................................................
  4973   4976   ** <tr><td><b>sqlite3_value_type</b><td>&rarr;<td>Default
  4974   4977   ** datatype of the value
  4975   4978   ** <tr><td><b>sqlite3_value_numeric_type&nbsp;&nbsp;</b>
  4976   4979   ** <td>&rarr;&nbsp;&nbsp;<td>Best numeric datatype of the value
  4977   4980   ** <tr><td><b>sqlite3_value_nochange&nbsp;&nbsp;</b>
  4978   4981   ** <td>&rarr;&nbsp;&nbsp;<td>True if the column is unchanged in an UPDATE
  4979   4982   ** against a virtual table.
         4983  +** <tr><td><b>sqlite3_value_frombind&nbsp;&nbsp;</b>
         4984  +** <td>&rarr;&nbsp;&nbsp;<td>True if value originated a bound parameter
  4980   4985   ** </table></blockquote>
  4981   4986   **
  4982   4987   ** <b>Details:</b>
  4983   4988   **
  4984   4989   ** These routines extract type, size, and content information from
  4985   4990   ** [protected sqlite3_value] objects.  Protected sqlite3_value objects
  4986   4991   ** are used to pass parameter information into implementation of
................................................................................
  5033   5038   ** the value for that column returned without setting a result (probably
  5034   5039   ** because it queried [sqlite3_vtab_nochange()] and found that the column
  5035   5040   ** was unchanging).  ^Within an [xUpdate] method, any value for which
  5036   5041   ** sqlite3_value_nochange(X) is true will in all other respects appear
  5037   5042   ** to be a NULL value.  If sqlite3_value_nochange(X) is invoked anywhere other
  5038   5043   ** than within an [xUpdate] method call for an UPDATE statement, then
  5039   5044   ** the return value is arbitrary and meaningless.
         5045  +**
         5046  +** ^The sqlite3_value_frombind(X) interface returns non-zero if the
         5047  +** value X originated from one of the [sqlite3_bind_int|sqlite3_bind()]
         5048  +** interfaces.  ^If X comes from an SQL literal value, or a table column,
         5049  +** and expression, then sqlite3_value_frombind(X) returns zero.
  5040   5050   **
  5041   5051   ** Please pay particular attention to the fact that the pointer returned
  5042   5052   ** from [sqlite3_value_blob()], [sqlite3_value_text()], or
  5043   5053   ** [sqlite3_value_text16()] can be invalidated by a subsequent call to
  5044   5054   ** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()],
  5045   5055   ** or [sqlite3_value_text16()].
  5046   5056   **
................................................................................
  5079   5089   const void *sqlite3_value_text16le(sqlite3_value*);
  5080   5090   const void *sqlite3_value_text16be(sqlite3_value*);
  5081   5091   int sqlite3_value_bytes(sqlite3_value*);
  5082   5092   int sqlite3_value_bytes16(sqlite3_value*);
  5083   5093   int sqlite3_value_type(sqlite3_value*);
  5084   5094   int sqlite3_value_numeric_type(sqlite3_value*);
  5085   5095   int sqlite3_value_nochange(sqlite3_value*);
         5096  +int sqlite3_value_frombind(sqlite3_value*);
  5086   5097   
  5087   5098   /*
  5088   5099   ** CAPI3REF: Finding The Subtype Of SQL Values
  5089   5100   ** METHOD: sqlite3_value
  5090   5101   **
  5091   5102   ** The sqlite3_value_subtype(V) function returns the subtype for
  5092   5103   ** an [application-defined SQL function] argument V.  The subtype

Changes to src/sqliteInt.h.

  1703   1703   #define SQLITE_FUNC_CONSTANT 0x0800 /* Constant inputs give a constant output */
  1704   1704   #define SQLITE_FUNC_MINMAX   0x1000 /* True for min() and max() aggregates */
  1705   1705   #define SQLITE_FUNC_SLOCHNG  0x2000 /* "Slow Change". Value constant during a
  1706   1706                                       ** single query - might change over time */
  1707   1707   #define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */
  1708   1708   #define SQLITE_FUNC_OFFSET   0x8000 /* Built-in sqlite_offset() function */
  1709   1709   #define SQLITE_FUNC_WINDOW   0x00010000 /* Built-in window-only function */
  1710         -#define SQLITE_FUNC_WINDOW_SIZE 0x20000 /* Requires partition size as arg. */
  1711   1710   #define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
  1712   1711   
  1713   1712   /*
  1714   1713   ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
  1715   1714   ** used to create the initializers for the FuncDef structures.
  1716   1715   **
  1717   1716   **   FUNCTION(zName, nArg, iArg, bNC, xFunc)
................................................................................
  2509   2508         int regReturn;         /* Register used to hold return address */
  2510   2509       } sub;
  2511   2510     } y;
  2512   2511   };
  2513   2512   
  2514   2513   /*
  2515   2514   ** The following are the meanings of bits in the Expr.flags field.
         2515  +** Value restrictions:
         2516  +**
         2517  +**          EP_Agg == NC_HasAgg == SF_HasAgg
         2518  +**          EP_Win == NC_HasWin
  2516   2519   */
  2517   2520   #define EP_FromJoin  0x000001 /* Originates in ON/USING clause of outer join */
  2518         -#define EP_Agg       0x000002 /* Contains one or more aggregate functions */
         2521  +#define EP_Distinct  0x000002 /* Aggregate function with DISTINCT keyword */
  2519   2522   #define EP_HasFunc   0x000004 /* Contains one or more functions of any kind */
  2520   2523   #define EP_FixedCol  0x000008 /* TK_Column with a known fixed value */
  2521         -#define EP_Distinct  0x000010 /* Aggregate function with DISTINCT keyword */
         2524  +#define EP_Agg       0x000010 /* Contains one or more aggregate functions */
  2522   2525   #define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */
  2523   2526   #define EP_DblQuoted 0x000040 /* token.z was originally in "..." */
  2524   2527   #define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */
  2525   2528   #define EP_Collate   0x000100 /* Tree contains a TK_COLLATE operator */
  2526   2529   #define EP_Generic   0x000200 /* Ignore COLLATE or affinity on this tree */
  2527   2530   #define EP_IntValue  0x000400 /* Integer value contained in u.iValue */
  2528   2531   #define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */
  2529   2532   #define EP_Skip      0x001000 /* COLLATE, AS, or UNLIKELY */
  2530   2533   #define EP_Reduced   0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */
  2531   2534   #define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
  2532         -#define EP_Static    0x008000 /* Held in memory not obtained from malloc() */
         2535  +#define EP_Win       0x008000 /* Contains window functions */
  2533   2536   #define EP_MemToken  0x010000 /* Need to sqlite3DbFree() Expr.zToken */
  2534   2537   #define EP_NoReduce  0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
  2535   2538   #define EP_Unlikely  0x040000 /* unlikely() or likelihood() function */
  2536   2539   #define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
  2537   2540   #define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
  2538   2541   #define EP_Subquery  0x200000 /* Tree contains a TK_SELECT operator */
  2539   2542   #define EP_Alias     0x400000 /* Is an alias for a result set column */
  2540   2543   #define EP_Leaf      0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
  2541   2544   #define EP_WinFunc  0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
  2542   2545   #define EP_Subrtn   0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */
  2543   2546   #define EP_Quoted   0x4000000 /* TK_ID was originally quoted */
         2547  +#define EP_Static   0x8000000 /* Held in memory not obtained from malloc() */
  2544   2548   
  2545   2549   /*
  2546   2550   ** The EP_Propagate mask is a set of properties that automatically propagate
  2547   2551   ** upwards into parent nodes.
  2548   2552   */
  2549   2553   #define EP_Propagate (EP_Collate|EP_Subquery|EP_HasFunc)
  2550   2554   
................................................................................
  2776   2780     Select *pWinSelect;  /* SELECT statement for any window functions */
  2777   2781   };
  2778   2782   
  2779   2783   /*
  2780   2784   ** Allowed values for the NameContext, ncFlags field.
  2781   2785   **
  2782   2786   ** Value constraints (all checked via assert()):
  2783         -**    NC_HasAgg    == SF_HasAgg
         2787  +**    NC_HasAgg    == SF_HasAgg    == EP_Agg
  2784   2788   **    NC_MinMaxAgg == SF_MinMaxAgg == SQLITE_FUNC_MINMAX
         2789  +**    NC_HasWin    == EP_Win
  2785   2790   **
  2786   2791   */
  2787   2792   #define NC_AllowAgg  0x0001  /* Aggregate functions are allowed here */
  2788   2793   #define NC_PartIdx   0x0002  /* True if resolving a partial index WHERE */
  2789   2794   #define NC_IsCheck   0x0004  /* True if resolving names in a CHECK constraint */
  2790   2795   #define NC_InAggFunc 0x0008  /* True if analyzing arguments to an agg func */
  2791   2796   #define NC_HasAgg    0x0010  /* One or more aggregate functions seen */
................................................................................
  2793   2798   #define NC_VarSelect 0x0040  /* A correlated subquery has been seen */
  2794   2799   #define NC_UEList    0x0080  /* True if uNC.pEList is used */
  2795   2800   #define NC_UAggInfo  0x0100  /* True if uNC.pAggInfo is used */
  2796   2801   #define NC_UUpsert   0x0200  /* True if uNC.pUpsert is used */
  2797   2802   #define NC_MinMaxAgg 0x1000  /* min/max aggregates seen.  See note above */
  2798   2803   #define NC_Complex   0x2000  /* True if a function or subquery seen */
  2799   2804   #define NC_AllowWin  0x4000  /* Window functions are allowed here */
         2805  +#define NC_HasWin    0x8000  /* One or more window functions seen */
  2800   2806   
  2801   2807   /*
  2802   2808   ** An instance of the following object describes a single ON CONFLICT
  2803   2809   ** clause in an upsert.
  2804   2810   **
  2805   2811   ** The pUpsertTarget field is only set if the ON CONFLICT clause includes
  2806   2812   ** conflict-target clause.  (In "ON CONFLICT(a,b)" the "(a,b)" is the
................................................................................
  3548   3554   struct TreeView {
  3549   3555     int iLevel;             /* Which level of the tree we are on */
  3550   3556     u8  bLine[100];         /* Draw vertical in column i if bLine[i] is true */
  3551   3557   };
  3552   3558   #endif /* SQLITE_DEBUG */
  3553   3559   
  3554   3560   /*
  3555         -** This object is used in varioius ways, all related to window functions
         3561  +** This object is used in various ways, all related to window functions
  3556   3562   **
  3557   3563   **   (1) A single instance of this structure is attached to the
  3558   3564   **       the Expr.pWin field for each window function in an expression tree.
  3559   3565   **       This object holds the information contained in the OVER clause,
  3560   3566   **       plus additional fields used during code generation.
  3561   3567   **
  3562   3568   **   (2) All window functions in a single SELECT form a linked-list
................................................................................
  3563   3569   **       attached to Select.pWin.  The Window.pFunc and Window.pExpr
  3564   3570   **       fields point back to the expression that is the window function.
  3565   3571   **
  3566   3572   **   (3) The terms of the WINDOW clause of a SELECT are instances of this
  3567   3573   **       object on a linked list attached to Select.pWinDefn.
  3568   3574   **
  3569   3575   ** The uses (1) and (2) are really the same Window object that just happens
  3570         -** to be accessible in two different ways.  Use (3) is are separate objects.
         3576  +** to be accessible in two different ways.  Use case (3) are separate objects.
  3571   3577   */
  3572   3578   struct Window {
  3573   3579     char *zName;            /* Name of window (may be NULL) */
         3580  +  char *zBase;            /* Name of base window for chaining (may be NULL) */
  3574   3581     ExprList *pPartition;   /* PARTITION BY clause */
  3575   3582     ExprList *pOrderBy;     /* ORDER BY clause */
  3576         -  u8 eType;               /* TK_RANGE or TK_ROWS */
         3583  +  u8 eFrmType;            /* TK_RANGE, TK_GROUPS, TK_ROWS, or 0 */
  3577   3584     u8 eStart;              /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */
  3578   3585     u8 eEnd;                /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */
         3586  +  u8 bImplicitFrame;      /* True if frame was implicitly specified */
         3587  +  u8 eExclude;            /* TK_NO, TK_CURRENT, TK_TIES, TK_GROUP, or 0 */
  3579   3588     Expr *pStart;           /* Expression for "<expr> PRECEDING" */
  3580   3589     Expr *pEnd;             /* Expression for "<expr> FOLLOWING" */
  3581   3590     Window *pNextWin;       /* Next window function belonging to this SELECT */
  3582   3591     Expr *pFilter;          /* The FILTER expression */
  3583   3592     FuncDef *pFunc;         /* The function */
  3584   3593     int iEphCsr;            /* Partition buffer or Peer buffer */
  3585   3594     int regAccum;
  3586   3595     int regResult;
  3587   3596     int csrApp;             /* Function cursor (used by min/max) */
  3588   3597     int regApp;             /* Function register (also used by min/max) */
  3589         -  int regPart;            /* First in a set of registers holding PARTITION BY
  3590         -                          ** and ORDER BY values for the window */
         3598  +  int regPart;            /* Array of registers for PARTITION BY values */
  3591   3599     Expr *pOwner;           /* Expression object this window is attached to */
  3592   3600     int nBufferCol;         /* Number of columns in buffer table */
  3593   3601     int iArgCol;            /* Offset of first argument for this function */
         3602  +  int regOne;             /* Register containing constant value 1 */
         3603  +  int regStartRowid;
         3604  +  int regEndRowid;
  3594   3605   };
  3595   3606   
  3596   3607   #ifndef SQLITE_OMIT_WINDOWFUNC
  3597   3608   void sqlite3WindowDelete(sqlite3*, Window*);
  3598   3609   void sqlite3WindowListDelete(sqlite3 *db, Window *p);
  3599         -Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*);
         3610  +Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*, u8);
  3600   3611   void sqlite3WindowAttach(Parse*, Expr*, Window*);
  3601   3612   int sqlite3WindowCompare(Parse*, Window*, Window*);
  3602   3613   void sqlite3WindowCodeInit(Parse*, Window*);
  3603   3614   void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int);
  3604   3615   int sqlite3WindowRewrite(Parse*, Select*);
  3605   3616   int sqlite3ExpandSubquery(Parse*, struct SrcList_item*);
  3606   3617   void sqlite3WindowUpdate(Parse*, Window*, Window*, FuncDef*);
  3607   3618   Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p);
  3608   3619   Window *sqlite3WindowListDup(sqlite3 *db, Window *p);
  3609   3620   void sqlite3WindowFunctions(void);
         3621  +void sqlite3WindowChain(Parse*, Window*, Window*);
         3622  +Window *sqlite3WindowAssemble(Parse*, Window*, ExprList*, ExprList*, Token*);
  3610   3623   #else
  3611   3624   # define sqlite3WindowDelete(a,b)
  3612   3625   # define sqlite3WindowFunctions()
  3613   3626   # define sqlite3WindowAttach(a,b,c)
  3614   3627   #endif
  3615   3628   
  3616   3629   /*

Changes to src/test_func.c.

   625    625   static void test_getsubtype(
   626    626     sqlite3_context *context,
   627    627     int argc,
   628    628     sqlite3_value **argv
   629    629   ){
   630    630     sqlite3_result_int(context, (int)sqlite3_value_subtype(argv[0]));
   631    631   }
          632  +
          633  +/*         test_frombind(A,B,C,...)
          634  +**
          635  +** Return an integer bitmask that has a bit set for every argument
          636  +** (up to the first 63 arguments) that originates from a bind a parameter.
          637  +*/
          638  +static void test_frombind(
          639  +  sqlite3_context *context,
          640  +  int argc,
          641  +  sqlite3_value **argv
          642  +){
          643  +  sqlite3_uint64 m = 0;
          644  +  int i;
          645  +  for(i=0; i<argc && i<63; i++){
          646  +    if( sqlite3_value_frombind(argv[i]) ) m |= ((sqlite3_uint64)1)<<i;
          647  +  }
          648  +  sqlite3_result_int64(context, (sqlite3_int64)m);
          649  +}
   632    650   
   633    651   /*         test_setsubtype(V, T)
   634    652   **
   635    653   ** Return the value V with its subtype changed to T
   636    654   */
   637    655   static void test_setsubtype(
   638    656     sqlite3_context *context,
................................................................................
   671    689       { "test_counter",          1, SQLITE_UTF8, counterFunc},
   672    690       { "real2hex",              1, SQLITE_UTF8, real2hex},
   673    691       { "test_decode",           1, SQLITE_UTF8, test_decode},
   674    692       { "test_extract",          2, SQLITE_UTF8, test_extract},
   675    693       { "test_zeroblob",  1, SQLITE_UTF8|SQLITE_DETERMINISTIC, test_zeroblob},
   676    694       { "test_getsubtype",       1, SQLITE_UTF8, test_getsubtype},
   677    695       { "test_setsubtype",       2, SQLITE_UTF8, test_setsubtype},
          696  +    { "test_frombind",        -1, SQLITE_UTF8, test_frombind},
   678    697     };
   679    698     int i;
   680    699   
   681    700     for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
   682    701       sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg,
   683    702           aFuncs[i].eTextRep, 0, aFuncs[i].xFunc, 0, 0);
   684    703     }

Changes to src/test_tclsh.c.

   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    108     extern int Sqlitetest_window_Init(Tcl_Interp *);
          109  +  extern int Sqlitetestvdbecov_Init(Tcl_Interp *);
   109    110   
   110    111     Tcl_CmdInfo cmdInfo;
   111    112   
   112    113     /* Since the primary use case for this binary is testing of SQLite,
   113    114     ** be sure to generate core files if we crash */
   114    115   #if defined(unix)
   115    116     { struct rlimit x;
................................................................................
   167    168     Sqlitetesttcl_Init(interp);
   168    169   
   169    170   #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
   170    171     Sqlitetestfts3_Init(interp);
   171    172   #endif
   172    173     TestExpert_Init(interp);
   173    174     Sqlitetest_window_Init(interp);
          175  +  Sqlitetestvdbecov_Init(interp);
   174    176   
   175    177     Tcl_CreateObjCommand(
   176    178         interp, "load_testfixture_extensions", load_testfixture_extensions,0,0
   177    179     );
   178    180     return 0;
   179    181   }
   180    182   

Added src/test_vdbecov.c.

            1  +/*
            2  +** 2019 April 02
            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  +#if SQLITE_TEST          /* This file is used for testing only */
           15  +
           16  +#include "sqlite3.h"
           17  +#include "sqliteInt.h"
           18  +#if defined(INCLUDE_SQLITE_TCL_H)
           19  +#  include "sqlite_tcl.h"
           20  +#else
           21  +#  include "tcl.h"
           22  +#endif
           23  +
           24  +#ifdef SQLITE_VDBE_COVERAGE
           25  +
           26  +static u8 aBranchArray[200000];
           27  +
           28  +static void test_vdbe_branch(
           29  +  void *pCtx, 
           30  +  unsigned int iSrc, 
           31  +  unsigned char iBranch, 
           32  +  unsigned char iType
           33  +){
           34  +  if( iSrc<sizeof(aBranchArray) ){
           35  +    aBranchArray[iSrc] |= iBranch;
           36  +  }
           37  +}
           38  +
           39  +static void appendToList(
           40  +  Tcl_Obj *pList, 
           41  +  int iLine, 
           42  +  int iPath, 
           43  +  const char *zNever
           44  +){
           45  +  Tcl_Obj *pNew = Tcl_NewObj();
           46  +  Tcl_IncrRefCount(pNew);
           47  +  Tcl_ListObjAppendElement(0, pNew, Tcl_NewIntObj(iLine));
           48  +  Tcl_ListObjAppendElement(0, pNew, Tcl_NewIntObj(iPath));
           49  +  Tcl_ListObjAppendElement(0, pNew, Tcl_NewStringObj(zNever, -1));
           50  +  Tcl_ListObjAppendElement(0, pList, pNew);
           51  +  Tcl_DecrRefCount(pNew);
           52  +}
           53  +
           54  +
           55  +static int SQLITE_TCLAPI test_vdbe_coverage(
           56  +  ClientData cd,
           57  +  Tcl_Interp *interp,
           58  +  int objc,
           59  +  Tcl_Obj *CONST objv[]
           60  +){
           61  +  const char *aSub[] = { "start", "report", "stop", 0 };
           62  +  int iSub = -1;
           63  +  if( objc!=2 ){
           64  +    Tcl_WrongNumArgs(interp, 1, objv, "sub-command");
           65  +    return TCL_ERROR;
           66  +  }
           67  +
           68  +  if( Tcl_GetIndexFromObj(interp, objv[1], aSub, "sub-command", 0, &iSub) ){
           69  +    return TCL_ERROR;
           70  +  }
           71  +
           72  +  Tcl_ResetResult(interp);
           73  +  assert( iSub==0 || iSub==1 || iSub==2 );
           74  +  switch( iSub ){
           75  +    case 0:       /* start */
           76  +      memset(aBranchArray, 0, sizeof(aBranchArray));
           77  +      sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, test_vdbe_branch, 0);
           78  +      break;
           79  +    case 1: {     /* report */
           80  +      int i;
           81  +      Tcl_Obj *pRes = Tcl_NewObj();
           82  +      Tcl_IncrRefCount(pRes);
           83  +      for(i=0; i<sizeof(aBranchArray); i++){
           84  +        u8 b = aBranchArray[i];
           85  +        int bFlag = ((b >> 4)==4);
           86  +        if( b ){
           87  +          if( (b & 0x01)==0 ){
           88  +            appendToList(pRes, i, 0, bFlag ? "less than" : "falls through");
           89  +          }
           90  +          if( (b & 0x02)==0 ){
           91  +            appendToList(pRes, i, 1, bFlag ? "equal" : "taken");
           92  +          }
           93  +          if( (b & 0x04)==0 ){
           94  +            appendToList(pRes, i, 2, bFlag ? "greater-than" : "NULL");
           95  +          }
           96  +        }
           97  +      }
           98  +      Tcl_SetObjResult(interp, pRes);
           99  +      Tcl_DecrRefCount(pRes);
          100  +      break;
          101  +    };
          102  +      
          103  +    default:      /* stop */         
          104  +      sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, 0, 0);
          105  +      break;
          106  +  }
          107  +
          108  +  return TCL_OK;
          109  +}
          110  +
          111  +#endif  /* SQLITE_VDBE_COVERAGE */
          112  +
          113  +int Sqlitetestvdbecov_Init(Tcl_Interp *interp){
          114  +#ifdef SQLITE_VDBE_COVERAGE
          115  +  Tcl_CreateObjCommand(interp, "vdbe_coverage", test_vdbe_coverage, 0, 0);
          116  +#endif
          117  +  return TCL_OK;
          118  +}
          119  +
          120  +#endif

Changes to src/treeview.c.

   305    305   #endif /* SQLITE_OMIT_WINDOWFUNC */
   306    306   
   307    307   #ifndef SQLITE_OMIT_WINDOWFUNC
   308    308   /*
   309    309   ** Generate a human-readable explanation for a Window object
   310    310   */
   311    311   void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){
          312  +  int nElement = 0;
          313  +  if( pWin->pFilter ){
          314  +    sqlite3TreeViewItem(pView, "FILTER", 1);
          315  +    sqlite3TreeViewExpr(pView, pWin->pFilter, 0);
          316  +    sqlite3TreeViewPop(pView);
          317  +  }
   312    318     pView = sqlite3TreeViewPush(pView, more);
   313    319     if( pWin->zName ){
   314         -    sqlite3TreeViewLine(pView, "OVER %s", pWin->zName);
          320  +    sqlite3TreeViewLine(pView, "OVER %s (%p)", pWin->zName, pWin);
   315    321     }else{
   316         -    sqlite3TreeViewLine(pView, "OVER");
          322  +    sqlite3TreeViewLine(pView, "OVER (%p)", pWin);
          323  +  }
          324  +  if( pWin->zBase )    nElement++;
          325  +  if( pWin->pOrderBy ) nElement++;
          326  +  if( pWin->eFrmType ) nElement++;
          327  +  if( pWin->eExclude ) nElement++;
          328  +  if( pWin->zBase ){
          329  +    sqlite3TreeViewPush(pView, (--nElement)>0);
          330  +    sqlite3TreeViewLine(pView, "window: %s", pWin->zBase);
          331  +    sqlite3TreeViewPop(pView);
   317    332     }
   318    333     if( pWin->pPartition ){
   319         -    sqlite3TreeViewExprList(pView, pWin->pPartition, 1, "PARTITION-BY");
          334  +    sqlite3TreeViewExprList(pView, pWin->pPartition, nElement>0,"PARTITION-BY");
   320    335     }
   321    336     if( pWin->pOrderBy ){
   322         -    sqlite3TreeViewExprList(pView, pWin->pOrderBy, 1, "ORDER-BY");
          337  +    sqlite3TreeViewExprList(pView, pWin->pOrderBy, (--nElement)>0, "ORDER-BY");
   323    338     }
   324         -  if( pWin->eType ){
   325         -    sqlite3TreeViewItem(pView, pWin->eType==TK_RANGE ? "RANGE" : "ROWS", 0);
          339  +  if( pWin->eFrmType ){
          340  +    char zBuf[30];
          341  +    const char *zFrmType = "ROWS";
          342  +    if( pWin->eFrmType==TK_RANGE ) zFrmType = "RANGE";
          343  +    if( pWin->eFrmType==TK_GROUPS ) zFrmType = "GROUPS";
          344  +    sqlite3_snprintf(sizeof(zBuf),zBuf,"%s%s",zFrmType,
          345  +        pWin->bImplicitFrame ? " (implied)" : "");
          346  +    sqlite3TreeViewItem(pView, zBuf, (--nElement)>0);
   326    347       sqlite3TreeViewBound(pView, pWin->eStart, pWin->pStart, 1);
   327    348       sqlite3TreeViewBound(pView, pWin->eEnd, pWin->pEnd, 0);
   328    349       sqlite3TreeViewPop(pView);
   329    350     }
          351  +  if( pWin->eExclude ){
          352  +    char zBuf[30];
          353  +    const char *zExclude;
          354  +    switch( pWin->eExclude ){
          355  +      case TK_NO:      zExclude = "NO OTHERS";   break;
          356  +      case TK_CURRENT: zExclude = "CURRENT ROW"; break;
          357  +      case TK_GROUP:   zExclude = "GROUP";       break;
          358  +      case TK_TIES:    zExclude = "TIES";        break;
          359  +      default:
          360  +        sqlite3_snprintf(sizeof(zBuf),zBuf,"invalid(%d)", pWin->eExclude);
          361  +        zExclude = zBuf;
          362  +        break;
          363  +    }
          364  +    sqlite3TreeViewPush(pView, 0);
          365  +    sqlite3TreeViewLine(pView, "EXCLUDE %s", zExclude);
          366  +    sqlite3TreeViewPop(pView);
          367  +  }
   330    368     sqlite3TreeViewPop(pView);
   331    369   }
   332    370   #endif /* SQLITE_OMIT_WINDOWFUNC */
   333    371   
   334    372   #ifndef SQLITE_OMIT_WINDOWFUNC
   335    373   /*
   336    374   ** Generate a human-readable explanation for a Window Function object

Changes to src/vdbe.c.

   118    118   #endif
   119    119   
   120    120   /*
   121    121   ** Invoke the VDBE coverage callback, if that callback is defined.  This
   122    122   ** feature is used for test suite validation only and does not appear an
   123    123   ** production builds.
   124    124   **
   125         -** M is an integer between 2 and 4.  2 indicates a ordinary two-way
   126         -** branch (I=0 means fall through and I=1 means taken).  3 indicates
   127         -** a 3-way branch where the third way is when one of the operands is
   128         -** NULL.  4 indicates the OP_Jump instruction which has three destinations
   129         -** depending on whether the first operand is less than, equal to, or greater
   130         -** than the second. 
          125  +** M is the type of branch.  I is the direction taken for this instance of
          126  +** the branch.
          127  +**
          128  +**   M: 2 - two-way branch (I=0: fall-thru   1: jump                )
          129  +**      3 - two-way + NULL (I=0: fall-thru   1: jump      2: NULL   )
          130  +**      4 - OP_Jump        (I=0: jump p1     1: jump p2   2: jump p3)
          131  +**
          132  +** In other words, if M is 2, then I is either 0 (for fall-through) or
          133  +** 1 (for when the branch is taken).  If M is 3, the I is 0 for an
          134  +** ordinary fall-through, I is 1 if the branch was taken, and I is 2 
          135  +** if the result of comparison is NULL.  For M=3, I=2 the jump may or
          136  +** may not be taken, depending on the SQLITE_JUMPIFNULL flags in p5.
          137  +** When M is 4, that means that an OP_Jump is being run.  I is 0, 1, or 2
          138  +** depending on if the operands are less than, equal, or greater than.
   131    139   **
   132    140   ** iSrcLine is the source code line (from the __LINE__ macro) that
   133    141   ** generated the VDBE instruction combined with flag bits.  The source
   134    142   ** code line number is in the lower 24 bits of iSrcLine and the upper
   135    143   ** 8 bytes are flags.  The lower three bits of the flags indicate
   136    144   ** values for I that should never occur.  For example, if the branch is
   137    145   ** always taken, the flags should be 0x05 since the fall-through and
   138    146   ** alternate branch are never taken.  If a branch is never taken then
   139    147   ** flags should be 0x06 since only the fall-through approach is allowed.
   140    148   **
   141         -** Bit 0x04 of the flags indicates an OP_Jump opcode that is only
          149  +** Bit 0x08 of the flags indicates an OP_Jump opcode that is only
   142    150   ** interested in equal or not-equal.  In other words, I==0 and I==2
   143         -** should be treated the same.
          151  +** should be treated as equivalent
   144    152   **
   145    153   ** Since only a line number is retained, not the filename, this macro
   146    154   ** only works for amalgamation builds.  But that is ok, since these macros
   147    155   ** should be no-ops except for special builds used to measure test coverage.
   148    156   */
   149    157   #if !defined(SQLITE_VDBE_COVERAGE)
   150    158   # define VdbeBranchTaken(I,M)
................................................................................
   160    168       /* The upper 8 bits of iSrcLine are flags.  The lower three bits of
   161    169       ** the flags indicate directions that the branch can never go.  If
   162    170       ** a branch really does go in one of those directions, assert right
   163    171       ** away. */
   164    172       mNever = iSrcLine >> 24;
   165    173       assert( (I & mNever)==0 );
   166    174       if( sqlite3GlobalConfig.xVdbeBranch==0 ) return;  /*NO_TEST*/
          175  +    /* Invoke the branch coverage callback with three arguments:
          176  +    **    iSrcLine - the line number of the VdbeCoverage() macro, with
          177  +    **               flags removed.
          178  +    **    I        - Mask of bits 0x07 indicating which cases are are
          179  +    **               fulfilled by this instance of the jump.  0x01 means
          180  +    **               fall-thru, 0x02 means taken, 0x04 means NULL.  Any
          181  +    **               impossible cases (ex: if the comparison is never NULL)
          182  +    **               are filled in automatically so that the coverage
          183  +    **               measurement logic does not flag those impossible cases
          184  +    **               as missed coverage.
          185  +    **    M        - Type of jump.  Same as M argument above
          186  +    */
   167    187       I |= mNever;
   168    188       if( M==2 ) I |= 0x04;
   169    189       if( M==4 ){
   170    190         I |= 0x08;
   171    191         if( (mNever&0x08)!=0 && (I&0x05)!=0) I |= 0x05; /*NO_TEST*/
   172    192       }
   173    193       sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg,
................................................................................
  1233   1253     assert( pOp->p1>0 && pOp->p1<=p->nVar );
  1234   1254     assert( pOp->p4.z==0 || pOp->p4.z==sqlite3VListNumToName(p->pVList,pOp->p1) );
  1235   1255     pVar = &p->aVar[pOp->p1 - 1];
  1236   1256     if( sqlite3VdbeMemTooBig(pVar) ){
  1237   1257       goto too_big;
  1238   1258     }
  1239   1259     pOut = &aMem[pOp->p2];
  1240         -  sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static);
         1260  +  if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut);
         1261  +  memcpy(pOut, pVar, MEMCELLSIZE);
         1262  +  pOut->flags &= ~(MEM_Dyn|MEM_Ephem);
         1263  +  pOut->flags |= MEM_Static|MEM_FromBind;
  1241   1264     UPDATE_MAX_BLOBSIZE(pOut);
  1242   1265     break;
  1243   1266   }
  1244   1267   
  1245   1268   /* Opcode: Move P1 P2 P3 * *
  1246   1269   ** Synopsis: r[P2@P3]=r[P1@P3]
  1247   1270   **
................................................................................
  1731   1754   ** without data loss, then jump immediately to P2, or if P2==0
  1732   1755   ** raise an SQLITE_MISMATCH exception.
  1733   1756   */
  1734   1757   case OP_MustBeInt: {            /* jump, in1 */
  1735   1758     pIn1 = &aMem[pOp->p1];
  1736   1759     if( (pIn1->flags & MEM_Int)==0 ){
  1737   1760       applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
  1738         -    VdbeBranchTaken((pIn1->flags&MEM_Int)==0, 2);
  1739   1761       if( (pIn1->flags & MEM_Int)==0 ){
         1762  +      VdbeBranchTaken(1, 2);
  1740   1763         if( pOp->p2==0 ){
  1741   1764           rc = SQLITE_MISMATCH;
  1742   1765           goto abort_due_to_error;
  1743   1766         }else{
  1744   1767           goto jump_to_p2;
  1745   1768         }
  1746   1769       }
  1747   1770     }
         1771  +  VdbeBranchTaken(0, 2);
  1748   1772     MemSetTypeFlag(pIn1, MEM_Int);
  1749   1773     break;
  1750   1774   }
  1751   1775   
  1752   1776   #ifndef SQLITE_OMIT_FLOATING_POINT
  1753   1777   /* Opcode: RealAffinity P1 * * * *
  1754   1778   **
................................................................................
  1915   1939     if( (flags1 | flags3)&MEM_Null ){
  1916   1940       /* One or both operands are NULL */
  1917   1941       if( pOp->p5 & SQLITE_NULLEQ ){
  1918   1942         /* If SQLITE_NULLEQ is set (which will only happen if the operator is
  1919   1943         ** OP_Eq or OP_Ne) then take the jump or not depending on whether
  1920   1944         ** or not both operands are null.
  1921   1945         */
  1922         -      assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
  1923   1946         assert( (flags1 & MEM_Cleared)==0 );
  1924   1947         assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 || CORRUPT_DB );
  1925   1948         testcase( (pOp->p5 & SQLITE_JUMPIFNULL)!=0 );
  1926   1949         if( (flags1&flags3&MEM_Null)!=0
  1927   1950          && (flags3&MEM_Cleared)==0
  1928   1951         ){
  1929   1952           res = 0;  /* Operands are equal */
  1930   1953         }else{
  1931         -        res = 1;  /* Operands are not equal */
         1954  +        res = ((flags3 & MEM_Null) ? -1 : +1);  /* Operands are not equal */
  1932   1955         }
  1933   1956       }else{
  1934   1957         /* SQLITE_NULLEQ is clear and at least one operand is NULL,
  1935   1958         ** then the result is always NULL.
  1936   1959         ** The jump is taken if the SQLITE_JUMPIFNULL bit is set.
  1937   1960         */
  1938   1961         if( pOp->p5 & SQLITE_STOREP2 ){
................................................................................
  2042   2065         if( (pOp->opcode==OP_Eq)==res2 ) break;
  2043   2066       }
  2044   2067       memAboutToChange(p, pOut);
  2045   2068       MemSetTypeFlag(pOut, MEM_Int);
  2046   2069       pOut->u.i = res2;
  2047   2070       REGISTER_TRACE(pOp->p2, pOut);
  2048   2071     }else{
  2049         -    VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
         2072  +    VdbeBranchTaken(res2!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
  2050   2073       if( res2 ){
  2051   2074         goto jump_to_p2;
  2052   2075       }
  2053   2076     }
  2054   2077     break;
  2055   2078   }
  2056   2079   
................................................................................
  3603   3626     pCx = allocateCursor(p, pOp->p1, pOrig->nField, -1, CURTYPE_BTREE);
  3604   3627     if( pCx==0 ) goto no_mem;
  3605   3628     pCx->nullRow = 1;
  3606   3629     pCx->isEphemeral = 1;
  3607   3630     pCx->pKeyInfo = pOrig->pKeyInfo;
  3608   3631     pCx->isTable = pOrig->isTable;
  3609   3632     pCx->pgnoRoot = pOrig->pgnoRoot;
         3633  +  pCx->isOrdered = pOrig->isOrdered;
  3610   3634     rc = sqlite3BtreeCursor(pOrig->pBtx, pCx->pgnoRoot, BTREE_WRCSR,
  3611   3635                             pCx->pKeyInfo, pCx->uc.pCursor);
  3612   3636     /* The sqlite3BtreeCursor() routine can only fail for the first cursor
  3613   3637     ** opened for a database.  Since there is already an open cursor when this
  3614   3638     ** opcode is run, the sqlite3BtreeCursor() cannot fail */
  3615   3639     assert( rc==SQLITE_OK );
  3616   3640     break;
................................................................................
  5111   5135   #ifdef SQLITE_TEST
  5112   5136     sqlite3_sort_count++;
  5113   5137     sqlite3_search_count--;
  5114   5138   #endif
  5115   5139     p->aCounter[SQLITE_STMTSTATUS_SORT]++;
  5116   5140     /* Fall through into OP_Rewind */
  5117   5141   }
  5118         -/* Opcode: Rewind P1 P2 * * P5
         5142  +/* Opcode: Rewind P1 P2 * * *
  5119   5143   **
  5120   5144   ** The next use of the Rowid or Column or Next instruction for P1 
  5121   5145   ** will refer to the first entry in the database table or index.
  5122   5146   ** If the table or index is empty, jump immediately to P2.
  5123   5147   ** If the table or index is not empty, fall through to the following 
  5124   5148   ** instruction.
  5125   5149   **
  5126         -** If P5 is non-zero and the table is not empty, then the "skip-next"
  5127         -** flag is set on the cursor so that the next OP_Next instruction 
  5128         -** executed on it is a no-op.
  5129         -**
  5130   5150   ** This opcode leaves the cursor configured to move in forward order,
  5131   5151   ** from the beginning toward the end.  In other words, the cursor is
  5132   5152   ** configured to use Next, not Prev.
  5133   5153   */
  5134   5154   case OP_Rewind: {        /* jump */
  5135   5155     VdbeCursor *pC;
  5136   5156     BtCursor *pCrsr;
  5137   5157     int res;
  5138   5158   
  5139   5159     assert( pOp->p1>=0 && pOp->p1<p->nCursor );
         5160  +  assert( pOp->p5==0 );
  5140   5161     pC = p->apCsr[pOp->p1];
  5141   5162     assert( pC!=0 );
  5142   5163     assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) );
  5143   5164     res = 1;
  5144   5165   #ifdef SQLITE_DEBUG
  5145   5166     pC->seekOp = OP_Rewind;
  5146   5167   #endif
................................................................................
  5147   5168     if( isSorter(pC) ){
  5148   5169       rc = sqlite3VdbeSorterRewind(pC, &res);
  5149   5170     }else{
  5150   5171       assert( pC->eCurType==CURTYPE_BTREE );
  5151   5172       pCrsr = pC->uc.pCursor;
  5152   5173       assert( pCrsr );
  5153   5174       rc = sqlite3BtreeFirst(pCrsr, &res);
  5154         -#ifndef SQLITE_OMIT_WINDOWFUNC
  5155         -    if( pOp->p5 ) sqlite3BtreeSkipNext(pCrsr);
  5156         -#endif
  5157   5175       pC->deferredMoveto = 0;
  5158   5176       pC->cacheStatus = CACHE_STALE;
  5159   5177     }
  5160   5178     if( rc ) goto abort_due_to_error;
  5161   5179     pC->nullRow = (u8)res;
  5162   5180     assert( pOp->p2>0 && pOp->p2<p->nOp );
  5163   5181     VdbeBranchTaken(res!=0,2);
................................................................................
  6531   6549     Mem *pMem;
  6532   6550     assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
  6533   6551     assert( pOp->p3==0 || pOp->opcode==OP_AggValue );
  6534   6552     pMem = &aMem[pOp->p1];
  6535   6553     assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
  6536   6554   #ifndef SQLITE_OMIT_WINDOWFUNC
  6537   6555     if( pOp->p3 ){
         6556  +    memAboutToChange(p, &aMem[pOp->p3]);
  6538   6557       rc = sqlite3VdbeMemAggValue(pMem, &aMem[pOp->p3], pOp->p4.pFunc);
  6539   6558       pMem = &aMem[pOp->p3];
  6540   6559     }else
  6541   6560   #endif
  6542   6561     {
  6543   6562       rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
  6544   6563     }

Changes to src/vdbeInt.h.

   242    242   */
   243    243   #define MEM_Null      0x0001   /* Value is NULL (or a pointer) */
   244    244   #define MEM_Str       0x0002   /* Value is a string */
   245    245   #define MEM_Int       0x0004   /* Value is an integer */
   246    246   #define MEM_Real      0x0008   /* Value is a real number */
   247    247   #define MEM_Blob      0x0010   /* Value is a BLOB */
   248    248   #define MEM_AffMask   0x001f   /* Mask of affinity bits */
   249         -/* Available          0x0020   */
          249  +#define MEM_FromBind  0x0020   /* Value originates from sqlite3_bind() */
   250    250   /* Available          0x0040   */
   251    251   #define MEM_Undefined 0x0080   /* Value is undefined */
   252    252   #define MEM_Cleared   0x0100   /* NULL set by OP_Null, not from data */
   253    253   #define MEM_TypeMask  0xc1ff   /* Mask of type bits */
   254    254   
   255    255   
   256    256   /* Whenever Mem contains a valid string or blob representation, one of

Changes to src/vdbeapi.c.

   286    286     return aType[pVal->flags&MEM_AffMask];
   287    287   }
   288    288   
   289    289   /* Return true if a parameter to xUpdate represents an unchanged column */
   290    290   int sqlite3_value_nochange(sqlite3_value *pVal){
   291    291     return (pVal->flags&(MEM_Null|MEM_Zero))==(MEM_Null|MEM_Zero);
   292    292   }
          293  +
          294  +/* Return true if a parameter value originated from an sqlite3_bind() */
          295  +int sqlite3_value_frombind(sqlite3_value *pVal){
          296  +  return (pVal->flags&MEM_FromBind)!=0;
          297  +}
   293    298   
   294    299   /* Make a copy of an sqlite3_value object
   295    300   */
   296    301   sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){
   297    302     sqlite3_value *pNew;
   298    303     if( pOrig==0 ) return 0;
   299    304     pNew = sqlite3_malloc( sizeof(*pNew) );

Changes to src/vdbemem.c.

    53     53         /* This is a pointer type.  There may be a flag to indicate what to
    54     54         ** do with the pointer. */
    55     55         assert( ((p->flags&MEM_Dyn)!=0 ? 1 : 0) +
    56     56                 ((p->flags&MEM_Ephem)!=0 ? 1 : 0) +
    57     57                 ((p->flags&MEM_Static)!=0 ? 1 : 0) <= 1 );
    58     58   
    59     59         /* No other bits set */
    60         -      assert( (p->flags & ~(MEM_Null|MEM_Term|MEM_Subtype
           60  +      assert( (p->flags & ~(MEM_Null|MEM_Term|MEM_Subtype|MEM_FromBind
    61     61                              |MEM_Dyn|MEM_Ephem|MEM_Static))==0 );
    62     62       }else{
    63     63         /* A pure NULL might have other flags, such as MEM_Static, MEM_Dyn,
    64     64         ** MEM_Ephem, MEM_Cleared, or MEM_Subtype */
    65     65       }
    66     66     }else{
    67     67       /* The MEM_Cleared bit is only allowed on NULLs */

Changes to src/where.c.

  3331   3331   
  3332   3332     /* First call xBestIndex() with all constraints usable. */
  3333   3333     WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName));
  3334   3334     WHERETRACE(0x40, ("  VirtualOne: all usable\n"));
  3335   3335     rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn);
  3336   3336   
  3337   3337     /* If the call to xBestIndex() with all terms enabled produced a plan
  3338         -  ** that does not require any source tables (IOW: a plan with mBest==0),
  3339         -  ** then there is no point in making any further calls to xBestIndex() 
  3340         -  ** since they will all return the same result (if the xBestIndex()
  3341         -  ** implementation is sane). */
  3342         -  if( rc==SQLITE_OK && (mBest = (pNew->prereq & ~mPrereq))!=0 ){
         3338  +  ** that does not require any source tables (IOW: a plan with mBest==0)
         3339  +  ** and does not use an IN(...) operator, then there is no point in making 
         3340  +  ** any further calls to xBestIndex() since they will all return the same
         3341  +  ** result (if the xBestIndex() implementation is sane). */
         3342  +  if( rc==SQLITE_OK && ((mBest = (pNew->prereq & ~mPrereq))!=0 || bIn) ){
  3343   3343       int seenZero = 0;             /* True if a plan with no prereqs seen */
  3344   3344       int seenZeroNoIN = 0;         /* Plan with no prereqs and no IN(...) seen */
  3345   3345       Bitmask mPrev = 0;
  3346   3346       Bitmask mBestNoIn = 0;
  3347   3347   
  3348   3348       /* If the plan produced by the earlier call uses an IN(...) term, call
  3349   3349       ** xBestIndex again, this time with IN(...) terms disabled. */

Changes to src/wherecode.c.

  2193   2193           ** that compares BLOBs. */
  2194   2194   #ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
  2195   2195           continue;
  2196   2196   #else
  2197   2197           u32 x = pLevel->iLikeRepCntr;
  2198   2198           if( x>0 ){
  2199   2199             skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)?OP_IfNot:OP_If,(int)(x>>1));
         2200  +          VdbeCoverageIf(v, (x&1)==1);
         2201  +          VdbeCoverageIf(v, (x&1)==0);
  2200   2202           }
  2201         -        VdbeCoverage(v);
  2202   2203   #endif
  2203   2204         }
  2204   2205   #ifdef WHERETRACE_ENABLED /* 0xffff */
  2205   2206         if( sqlite3WhereTrace ){
  2206   2207           VdbeNoopComment((v, "WhereTerm[%d] (%p) priority=%d",
  2207   2208                            pWC->nTerm-j, pTerm, iLoop));
  2208   2209         }

Changes to src/window.c.

   194    194         p->nValue++;
   195    195         p->nStep = 0;
   196    196       }
   197    197       sqlite3_result_int64(pCtx, p->nValue);
   198    198     }
   199    199   }
   200    200   
          201  +/*
          202  +** Implementation of built-in window function nth_value(). This
          203  +** implementation is used in "slow mode" only - when the EXCLUDE clause
          204  +** is not set to the default value "NO OTHERS".
          205  +*/
          206  +struct NthValueCtx {
          207  +  i64 nStep;
          208  +  sqlite3_value *pValue;
          209  +};
          210  +static void nth_valueStepFunc(
          211  +  sqlite3_context *pCtx, 
          212  +  int nArg,
          213  +  sqlite3_value **apArg
          214  +){
          215  +  struct NthValueCtx *p;
          216  +  p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          217  +  if( p ){
          218  +    i64 iVal;
          219  +    switch( sqlite3_value_numeric_type(apArg[1]) ){
          220  +      case SQLITE_INTEGER:
          221  +        iVal = sqlite3_value_int64(apArg[1]);
          222  +        break;
          223  +      case SQLITE_FLOAT: {
          224  +        double fVal = sqlite3_value_double(apArg[1]);
          225  +        if( ((i64)fVal)!=fVal ) goto error_out;
          226  +        iVal = (i64)fVal;
          227  +        break;
          228  +      }
          229  +      default:
          230  +        goto error_out;
          231  +    }
          232  +    if( iVal<=0 ) goto error_out;
          233  +
          234  +    p->nStep++;
          235  +    if( iVal==p->nStep ){
          236  +      p->pValue = sqlite3_value_dup(apArg[0]);
          237  +      if( !p->pValue ){
          238  +        sqlite3_result_error_nomem(pCtx);
          239  +      }
          240  +    }
          241  +  }
          242  +  UNUSED_PARAMETER(nArg);
          243  +  UNUSED_PARAMETER(apArg);
          244  +  return;
          245  +
          246  + error_out:
          247  +  sqlite3_result_error(
          248  +      pCtx, "second argument to nth_value must be a positive integer", -1
          249  +  );
          250  +}
          251  +static void nth_valueFinalizeFunc(sqlite3_context *pCtx){
          252  +  struct NthValueCtx *p;
          253  +  p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, 0);
          254  +  if( p && p->pValue ){
          255  +    sqlite3_result_value(pCtx, p->pValue);
          256  +    sqlite3_value_free(p->pValue);
          257  +    p->pValue = 0;
          258  +  }
          259  +}
          260  +#define nth_valueInvFunc noopStepFunc
          261  +#define nth_valueValueFunc noopValueFunc
          262  +
          263  +static void first_valueStepFunc(
          264  +  sqlite3_context *pCtx, 
          265  +  int nArg,
          266  +  sqlite3_value **apArg
          267  +){
          268  +  struct NthValueCtx *p;
          269  +  p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          270  +  if( p && p->pValue==0 ){
          271  +    p->pValue = sqlite3_value_dup(apArg[0]);
          272  +    if( !p->pValue ){
          273  +      sqlite3_result_error_nomem(pCtx);
          274  +    }
          275  +  }
          276  +  UNUSED_PARAMETER(nArg);
          277  +  UNUSED_PARAMETER(apArg);
          278  +}
          279  +static void first_valueFinalizeFunc(sqlite3_context *pCtx){
          280  +  struct NthValueCtx *p;
          281  +  p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          282  +  if( p && p->pValue ){
          283  +    sqlite3_result_value(pCtx, p->pValue);
          284  +    sqlite3_value_free(p->pValue);
          285  +    p->pValue = 0;
          286  +  }
          287  +}
          288  +#define first_valueInvFunc noopStepFunc
          289  +#define first_valueValueFunc noopValueFunc
          290  +
   201    291   /*
   202    292   ** Implementation of built-in window function rank(). Assumes that
   203    293   ** the window frame has been set to:
   204    294   **
   205    295   **   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
   206    296   */
   207    297   static void rankStepFunc(
................................................................................
   229    319     }
   230    320   }
   231    321   
   232    322   /*
   233    323   ** Implementation of built-in window function percent_rank(). Assumes that
   234    324   ** the window frame has been set to:
   235    325   **
   236         -**   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
          326  +**   GROUPS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
   237    327   */
   238    328   static void percent_rankStepFunc(
   239    329     sqlite3_context *pCtx, 
   240    330     int nArg,
   241    331     sqlite3_value **apArg
   242    332   ){
   243    333     struct CallCount *p;
   244         -  UNUSED_PARAMETER(nArg); assert( nArg==1 );
   245         -
          334  +  UNUSED_PARAMETER(nArg); assert( nArg==0 );
          335  +  UNUSED_PARAMETER(apArg);
   246    336     p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
   247    337     if( p ){
   248         -    if( p->nTotal==0 ){
   249         -      p->nTotal = sqlite3_value_int64(apArg[0]);
   250         -    }
   251         -    p->nStep++;
   252         -    if( p->nValue==0 ){
   253         -      p->nValue = p->nStep;
   254         -    }
          338  +    p->nTotal++;
   255    339     }
          340  +}
          341  +static void percent_rankInvFunc(
          342  +  sqlite3_context *pCtx, 
          343  +  int nArg,
          344  +  sqlite3_value **apArg
          345  +){
          346  +  struct CallCount *p;
          347  +  UNUSED_PARAMETER(nArg); assert( nArg==0 );
          348  +  UNUSED_PARAMETER(apArg);
          349  +  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          350  +  p->nStep++;
   256    351   }
   257    352   static void percent_rankValueFunc(sqlite3_context *pCtx){
   258    353     struct CallCount *p;
   259    354     p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
   260    355     if( p ){
          356  +    p->nValue = p->nStep;
   261    357       if( p->nTotal>1 ){
   262         -      double r = (double)(p->nValue-1) / (double)(p->nTotal-1);
          358  +      double r = (double)p->nValue / (double)(p->nTotal-1);
   263    359         sqlite3_result_double(pCtx, r);
   264    360       }else{
   265    361         sqlite3_result_double(pCtx, 0.0);
   266    362       }
   267         -    p->nValue = 0;
   268    363     }
   269    364   }
          365  +#define percent_rankFinalizeFunc percent_rankValueFunc
   270    366   
   271    367   /*
   272    368   ** Implementation of built-in window function cume_dist(). Assumes that
   273    369   ** the window frame has been set to:
   274    370   **
   275         -**   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
          371  +**   GROUPS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING
   276    372   */
   277    373   static void cume_distStepFunc(
   278    374     sqlite3_context *pCtx, 
   279    375     int nArg,
   280    376     sqlite3_value **apArg
   281    377   ){
   282    378     struct CallCount *p;
   283         -  assert( nArg==1 ); UNUSED_PARAMETER(nArg);
   284         -
          379  +  UNUSED_PARAMETER(nArg); assert( nArg==0 );
          380  +  UNUSED_PARAMETER(apArg);
   285    381     p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
   286    382     if( p ){
   287         -    if( p->nTotal==0 ){
   288         -      p->nTotal = sqlite3_value_int64(apArg[0]);
   289         -    }
   290         -    p->nStep++;
          383  +    p->nTotal++;
   291    384     }
          385  +}
          386  +static void cume_distInvFunc(
          387  +  sqlite3_context *pCtx, 
          388  +  int nArg,
          389  +  sqlite3_value **apArg
          390  +){
          391  +  struct CallCount *p;
          392  +  UNUSED_PARAMETER(nArg); assert( nArg==0 );
          393  +  UNUSED_PARAMETER(apArg);
          394  +  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          395  +  p->nStep++;
   292    396   }
   293    397   static void cume_distValueFunc(sqlite3_context *pCtx){
   294    398     struct CallCount *p;
   295         -  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
   296         -  if( p && p->nTotal ){
          399  +  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, 0);
          400  +  if( p ){
   297    401       double r = (double)(p->nStep) / (double)(p->nTotal);
   298    402       sqlite3_result_double(pCtx, r);
   299    403     }
   300    404   }
          405  +#define cume_distFinalizeFunc cume_distValueFunc
   301    406   
   302    407   /*
   303    408   ** Context object for ntile() window function.
   304    409   */
   305    410   struct NtileCtx {
   306    411     i64 nTotal;                     /* Total rows in partition */
   307    412     i64 nParam;                     /* Parameter passed to ntile(N) */
................................................................................
   308    413     i64 iRow;                       /* Current row */
   309    414   };
   310    415   
   311    416   /*
   312    417   ** Implementation of ntile(). This assumes that the window frame has
   313    418   ** been coerced to:
   314    419   **
   315         -**   ROWS UNBOUNDED PRECEDING AND CURRENT ROW
          420  +**   ROWS CURRENT ROW AND UNBOUNDED FOLLOWING
   316    421   */
   317    422   static void ntileStepFunc(
   318    423     sqlite3_context *pCtx, 
   319    424     int nArg,
   320    425     sqlite3_value **apArg
   321    426   ){
   322    427     struct NtileCtx *p;
   323         -  assert( nArg==2 ); UNUSED_PARAMETER(nArg);
          428  +  assert( nArg==1 ); UNUSED_PARAMETER(nArg);
   324    429     p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
   325    430     if( p ){
   326    431       if( p->nTotal==0 ){
   327    432         p->nParam = sqlite3_value_int64(apArg[0]);
   328         -      p->nTotal = sqlite3_value_int64(apArg[1]);
   329    433         if( p->nParam<=0 ){
   330    434           sqlite3_result_error(
   331    435               pCtx, "argument of ntile must be a positive integer", -1
   332    436           );
   333    437         }
   334    438       }
   335         -    p->iRow++;
          439  +    p->nTotal++;
   336    440     }
          441  +}
          442  +static void ntileInvFunc(
          443  +  sqlite3_context *pCtx, 
          444  +  int nArg,
          445  +  sqlite3_value **apArg
          446  +){
          447  +  struct NtileCtx *p;
          448  +  assert( nArg==1 ); UNUSED_PARAMETER(nArg);
          449  +  UNUSED_PARAMETER(apArg);
          450  +  p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          451  +  p->iRow++;
   337    452   }
   338    453   static void ntileValueFunc(sqlite3_context *pCtx){
   339    454     struct NtileCtx *p;
   340    455     p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
   341    456     if( p && p->nParam>0 ){
   342    457       int nSize = (p->nTotal / p->nParam);
   343    458       if( nSize==0 ){
   344         -      sqlite3_result_int64(pCtx, p->iRow);
          459  +      sqlite3_result_int64(pCtx, p->iRow+1);
   345    460       }else{
   346    461         i64 nLarge = p->nTotal - p->nParam*nSize;
   347    462         i64 iSmall = nLarge*(nSize+1);
   348         -      i64 iRow = p->iRow-1;
          463  +      i64 iRow = p->iRow;
   349    464   
   350    465         assert( (nLarge*(nSize+1) + (p->nParam-nLarge)*nSize)==p->nTotal );
   351    466   
   352    467         if( iRow<iSmall ){
   353    468           sqlite3_result_int64(pCtx, 1 + iRow/(nSize+1));
   354    469         }else{
   355    470           sqlite3_result_int64(pCtx, 1 + nLarge + (iRow-iSmall)/nSize);
   356    471         }
   357    472       }
   358    473     }
   359    474   }
          475  +#define ntileFinalizeFunc ntileValueFunc
   360    476   
   361    477   /*
   362    478   ** Context object for last_value() window function.
   363    479   */
   364    480   struct LastValueCtx {
   365    481     sqlite3_value *pVal;
   366    482     int nVal;
................................................................................
   402    518         sqlite3_value_free(p->pVal);
   403    519         p->pVal = 0;
   404    520       }
   405    521     }
   406    522   }
   407    523   static void last_valueValueFunc(sqlite3_context *pCtx){
   408    524     struct LastValueCtx *p;
   409         -  p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          525  +  p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, 0);
   410    526     if( p && p->pVal ){
   411    527       sqlite3_result_value(pCtx, p->pVal);
   412    528     }
   413    529   }
   414    530   static void last_valueFinalizeFunc(sqlite3_context *pCtx){
   415    531     struct LastValueCtx *p;
   416    532     p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
................................................................................
   492    608   ** Register those built-in window functions that are not also aggregates.
   493    609   */
   494    610   void sqlite3WindowFunctions(void){
   495    611     static FuncDef aWindowFuncs[] = {
   496    612       WINDOWFUNCX(row_number, 0, 0),
   497    613       WINDOWFUNCX(dense_rank, 0, 0),
   498    614       WINDOWFUNCX(rank, 0, 0),
   499         -    WINDOWFUNCX(percent_rank, 0, SQLITE_FUNC_WINDOW_SIZE),
   500         -    WINDOWFUNCX(cume_dist, 0, SQLITE_FUNC_WINDOW_SIZE),
   501         -    WINDOWFUNCX(ntile, 1, SQLITE_FUNC_WINDOW_SIZE),
          615  +    WINDOWFUNCALL(percent_rank, 0, 0),
          616  +    WINDOWFUNCALL(cume_dist, 0, 0),
          617  +    WINDOWFUNCALL(ntile, 1, 0),
   502    618       WINDOWFUNCALL(last_value, 1, 0),
   503         -    WINDOWFUNCNOOP(nth_value, 2, 0),
   504         -    WINDOWFUNCNOOP(first_value, 1, 0),
          619  +    WINDOWFUNCALL(nth_value, 2, 0),
          620  +    WINDOWFUNCALL(first_value, 1, 0),
   505    621       WINDOWFUNCNOOP(lead, 1, 0),
   506    622       WINDOWFUNCNOOP(lead, 2, 0),
   507    623       WINDOWFUNCNOOP(lead, 3, 0),
   508    624       WINDOWFUNCNOOP(lag, 1, 0),
   509    625       WINDOWFUNCNOOP(lag, 2, 0),
   510    626       WINDOWFUNCNOOP(lag, 3, 0),
   511    627     };
   512    628     sqlite3InsertBuiltinFuncs(aWindowFuncs, ArraySize(aWindowFuncs));
   513    629   }
          630  +
          631  +static Window *windowFind(Parse *pParse, Window *pList, const char *zName){
          632  +  Window *p;
          633  +  for(p=pList; p; p=p->pNextWin){
          634  +    if( sqlite3StrICmp(p->zName, zName)==0 ) break;
          635  +  }
          636  +  if( p==0 ){
          637  +    sqlite3ErrorMsg(pParse, "no such window: %s", zName);
          638  +  }
          639  +  return p;
          640  +}
   514    641   
   515    642   /*
   516    643   ** This function is called immediately after resolving the function name
   517    644   ** for a window function within a SELECT statement. Argument pList is a
   518    645   ** linked list of WINDOW definitions for the current SELECT statement.
   519    646   ** Argument pFunc is the function definition just resolved and pWin
   520    647   ** is the Window object representing the associated OVER clause. This
................................................................................
   531    658   */
   532    659   void sqlite3WindowUpdate(
   533    660     Parse *pParse, 
   534    661     Window *pList,                  /* List of named windows for this SELECT */
   535    662     Window *pWin,                   /* Window frame to update */
   536    663     FuncDef *pFunc                  /* Window function definition */
   537    664   ){
   538         -  if( pWin->zName && pWin->eType==0 ){
   539         -    Window *p;
   540         -    for(p=pList; p; p=p->pNextWin){
   541         -      if( sqlite3StrICmp(p->zName, pWin->zName)==0 ) break;
   542         -    }
   543         -    if( p==0 ){
   544         -      sqlite3ErrorMsg(pParse, "no such window: %s", pWin->zName);
   545         -      return;
   546         -    }
          665  +  if( pWin->zName && pWin->eFrmType==0 ){
          666  +    Window *p = windowFind(pParse, pList, pWin->zName);
          667  +    if( p==0 ) return;
   547    668       pWin->pPartition = sqlite3ExprListDup(pParse->db, p->pPartition, 0);
   548    669       pWin->pOrderBy = sqlite3ExprListDup(pParse->db, p->pOrderBy, 0);
   549    670       pWin->pStart = sqlite3ExprDup(pParse->db, p->pStart, 0);
   550    671       pWin->pEnd = sqlite3ExprDup(pParse->db, p->pEnd, 0);
   551    672       pWin->eStart = p->eStart;
   552    673       pWin->eEnd = p->eEnd;
   553         -    pWin->eType = p->eType;
          674  +    pWin->eFrmType = p->eFrmType;
          675  +    pWin->eExclude = p->eExclude;
          676  +  }else{
          677  +    sqlite3WindowChain(pParse, pWin, pList);
   554    678     }
          679  +  if( (pWin->eFrmType==TK_RANGE)
          680  +   && (pWin->pStart || pWin->pEnd) 
          681  +   && (pWin->pOrderBy==0 || pWin->pOrderBy->nExpr!=1)
          682  +  ){
          683  +    sqlite3ErrorMsg(pParse, 
          684  +      "RANGE with offset PRECEDING/FOLLOWING requires one ORDER BY expression"
          685  +    );
          686  +  }else
   555    687     if( pFunc->funcFlags & SQLITE_FUNC_WINDOW ){
   556    688       sqlite3 *db = pParse->db;
   557    689       if( pWin->pFilter ){
   558    690         sqlite3ErrorMsg(pParse, 
   559    691             "FILTER clause may only be used with aggregate window functions"
   560    692         );
   561         -    }else
   562         -    if( pFunc->zName==row_numberName || pFunc->zName==ntileName ){
   563         -      sqlite3ExprDelete(db, pWin->pStart);
   564         -      sqlite3ExprDelete(db, pWin->pEnd);
   565         -      pWin->pStart = pWin->pEnd = 0;
   566         -      pWin->eType = TK_ROWS;
   567         -      pWin->eStart = TK_UNBOUNDED;
   568         -      pWin->eEnd = TK_CURRENT;
   569         -    }else
   570         -
   571         -    if( pFunc->zName==dense_rankName || pFunc->zName==rankName
   572         -     || pFunc->zName==percent_rankName || pFunc->zName==cume_distName
   573         -    ){
   574         -      sqlite3ExprDelete(db, pWin->pStart);
   575         -      sqlite3ExprDelete(db, pWin->pEnd);
   576         -      pWin->pStart = pWin->pEnd = 0;
   577         -      pWin->eType = TK_RANGE;
   578         -      pWin->eStart = TK_UNBOUNDED;
   579         -      pWin->eEnd = TK_CURRENT;
          693  +    }else{
          694  +      struct WindowUpdate {
          695  +        const char *zFunc;
          696  +        int eFrmType;
          697  +        int eStart;
          698  +        int eEnd;
          699  +      } aUp[] = {
          700  +        { row_numberName,   TK_ROWS,   TK_UNBOUNDED, TK_CURRENT }, 
          701  +        { dense_rankName,   TK_RANGE,  TK_UNBOUNDED, TK_CURRENT }, 
          702  +        { rankName,         TK_RANGE,  TK_UNBOUNDED, TK_CURRENT }, 
          703  +        { percent_rankName, TK_GROUPS, TK_CURRENT,   TK_UNBOUNDED }, 
          704  +        { cume_distName,    TK_GROUPS, TK_FOLLOWING, TK_UNBOUNDED }, 
          705  +        { ntileName,        TK_ROWS,   TK_CURRENT,   TK_UNBOUNDED }, 
          706  +        { leadName,         TK_ROWS,   TK_UNBOUNDED, TK_UNBOUNDED }, 
          707  +        { lagName,          TK_ROWS,   TK_UNBOUNDED, TK_CURRENT }, 
          708  +      };
          709  +      int i;
          710  +      for(i=0; i<ArraySize(aUp); i++){
          711  +        if( pFunc->zName==aUp[i].zFunc ){
          712  +          sqlite3ExprDelete(db, pWin->pStart);
          713  +          sqlite3ExprDelete(db, pWin->pEnd);
          714  +          pWin->pEnd = pWin->pStart = 0;
          715  +          pWin->eFrmType = aUp[i].eFrmType;
          716  +          pWin->eStart = aUp[i].eStart;
          717  +          pWin->eEnd = aUp[i].eEnd;
          718  +          pWin->eExclude = 0;
          719  +          if( pWin->eStart==TK_FOLLOWING ){
          720  +            pWin->pStart = sqlite3Expr(db, TK_INTEGER, "1");
          721  +          }
          722  +          break;
          723  +        }
          724  +      }
   580    725       }
   581    726     }
   582    727     pWin->pFunc = pFunc;
   583    728   }
   584    729   
   585    730   /*
   586    731   ** Context object passed through sqlite3WalkExprList() to
................................................................................
   777    922         }
   778    923       }
   779    924   
   780    925       /* Assign a cursor number for the ephemeral table used to buffer rows.
   781    926       ** The OpenEphemeral instruction is coded later, after it is known how
   782    927       ** many columns the table will have.  */
   783    928       pMWin->iEphCsr = pParse->nTab++;
          929  +    pParse->nTab += 3;
   784    930   
   785    931       selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, &pSublist);
   786    932       selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, &pSublist);
   787    933       pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0);
   788    934   
   789    935       /* Append the PARTITION BY and ORDER BY expressions to the to the 
   790    936       ** sub-select expression list. They are required to figure out where 
................................................................................
   832    978         }else{
   833    979           pSub->selFlags |= SF_Expanded;
   834    980           p->selFlags &= ~SF_Aggregate;
   835    981           sqlite3SelectPrep(pParse, pSub, 0);
   836    982         }
   837    983   
   838    984         sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, pSublist->nExpr);
          985  +      sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr);
          986  +      sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+2, pMWin->iEphCsr);
          987  +      sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+3, pMWin->iEphCsr);
   839    988       }else{
   840    989         sqlite3SelectDelete(db, pSub);
   841    990       }
   842    991       if( db->mallocFailed ) rc = SQLITE_NOMEM;
   843    992     }
   844    993   
   845    994     return rc;
................................................................................
   852   1001     if( p ){
   853   1002       sqlite3ExprDelete(db, p->pFilter);
   854   1003       sqlite3ExprListDelete(db, p->pPartition);
   855   1004       sqlite3ExprListDelete(db, p->pOrderBy);
   856   1005       sqlite3ExprDelete(db, p->pEnd);
   857   1006       sqlite3ExprDelete(db, p->pStart);
   858   1007       sqlite3DbFree(db, p->zName);
         1008  +    sqlite3DbFree(db, p->zBase);
   859   1009       sqlite3DbFree(db, p);
   860   1010     }
   861   1011   }
   862   1012   
   863   1013   /*
   864   1014   ** Free the linked list of Window objects starting at the second argument.
   865   1015   */
................................................................................
   888   1038   }
   889   1039   
   890   1040   /*
   891   1041   ** Allocate and return a new Window object describing a Window Definition.
   892   1042   */
   893   1043   Window *sqlite3WindowAlloc(
   894   1044     Parse *pParse,    /* Parsing context */
   895         -  int eType,        /* Frame type. TK_RANGE or TK_ROWS */
         1045  +  int eType,        /* Frame type. TK_RANGE, TK_ROWS, TK_GROUPS, or 0 */
   896   1046     int eStart,       /* Start type: CURRENT, PRECEDING, FOLLOWING, UNBOUNDED */
   897   1047     Expr *pStart,     /* Start window size if TK_PRECEDING or FOLLOWING */
   898   1048     int eEnd,         /* End type: CURRENT, FOLLOWING, TK_UNBOUNDED, PRECEDING */
   899         -  Expr *pEnd        /* End window size if TK_FOLLOWING or PRECEDING */
         1049  +  Expr *pEnd,       /* End window size if TK_FOLLOWING or PRECEDING */
         1050  +  u8 eExclude       /* EXCLUDE clause */
   900   1051   ){
   901   1052     Window *pWin = 0;
         1053  +  int bImplicitFrame = 0;
   902   1054   
   903   1055     /* Parser assures the following: */
   904         -  assert( eType==TK_RANGE || eType==TK_ROWS );
         1056  +  assert( eType==0 || eType==TK_RANGE || eType==TK_ROWS || eType==TK_GROUPS );
   905   1057     assert( eStart==TK_CURRENT || eStart==TK_PRECEDING
   906   1058              || eStart==TK_UNBOUNDED || eStart==TK_FOLLOWING );
   907   1059     assert( eEnd==TK_CURRENT || eEnd==TK_FOLLOWING
   908   1060              || eEnd==TK_UNBOUNDED || eEnd==TK_PRECEDING );
   909   1061     assert( (eStart==TK_PRECEDING || eStart==TK_FOLLOWING)==(pStart!=0) );
   910   1062     assert( (eEnd==TK_FOLLOWING || eEnd==TK_PRECEDING)==(pEnd!=0) );
   911   1063   
   912         -
   913         -  /* If a frame is declared "RANGE" (not "ROWS"), then it may not use
   914         -  ** either "<expr> PRECEDING" or "<expr> FOLLOWING".
   915         -  */
   916         -  if( eType==TK_RANGE && (pStart!=0 || pEnd!=0) ){
   917         -    sqlite3ErrorMsg(pParse, "RANGE must use only UNBOUNDED or CURRENT ROW");
   918         -    goto windowAllocErr;
         1064  +  if( eType==0 ){
         1065  +    bImplicitFrame = 1;
         1066  +    eType = TK_RANGE;
   919   1067     }
   920   1068   
   921   1069     /* Additionally, the
   922   1070     ** starting boundary type may not occur earlier in the following list than
   923   1071     ** the ending boundary type:
   924   1072     **
   925   1073     **   UNBOUNDED PRECEDING
................................................................................
   931   1079     ** The parser ensures that "UNBOUNDED PRECEDING" cannot be used as an ending
   932   1080     ** boundary, and than "UNBOUNDED FOLLOWING" cannot be used as a starting
   933   1081     ** frame boundary.
   934   1082     */
   935   1083     if( (eStart==TK_CURRENT && eEnd==TK_PRECEDING)
   936   1084      || (eStart==TK_FOLLOWING && (eEnd==TK_PRECEDING || eEnd==TK_CURRENT))
   937   1085     ){
   938         -    sqlite3ErrorMsg(pParse, "unsupported frame delimiter for ROWS");
         1086  +    sqlite3ErrorMsg(pParse, "unsupported frame specification");
   939   1087       goto windowAllocErr;
   940   1088     }
   941   1089   
   942   1090     pWin = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
   943   1091     if( pWin==0 ) goto windowAllocErr;
   944         -  pWin->eType = eType;
         1092  +  pWin->eFrmType = eType;
   945   1093     pWin->eStart = eStart;
   946   1094     pWin->eEnd = eEnd;
         1095  +  if( eExclude==0 && OptimizationDisabled(pParse->db, SQLITE_QueryFlattener) ){
         1096  +    eExclude = TK_NO;
         1097  +  }
         1098  +  pWin->eExclude = eExclude;
         1099  +  pWin->bImplicitFrame = bImplicitFrame;
   947   1100     pWin->pEnd = sqlite3WindowOffsetExpr(pParse, pEnd);
   948   1101     pWin->pStart = sqlite3WindowOffsetExpr(pParse, pStart);
   949   1102     return pWin;
   950   1103   
   951   1104   windowAllocErr:
   952   1105     sqlite3ExprDelete(pParse->db, pEnd);
   953   1106     sqlite3ExprDelete(pParse->db, pStart);
   954   1107     return 0;
   955   1108   }
         1109  +
         1110  +/*
         1111  +** Attach PARTITION and ORDER BY clauses pPartition and pOrderBy to window
         1112  +** pWin. Also, if parameter pBase is not NULL, set pWin->zBase to the
         1113  +** equivalent nul-terminated string.
         1114  +*/
         1115  +Window *sqlite3WindowAssemble(
         1116  +  Parse *pParse, 
         1117  +  Window *pWin, 
         1118  +  ExprList *pPartition, 
         1119  +  ExprList *pOrderBy, 
         1120  +  Token *pBase
         1121  +){
         1122  +  if( pWin ){
         1123  +    pWin->pPartition = pPartition;
         1124  +    pWin->pOrderBy = pOrderBy;
         1125  +    if( pBase ){
         1126  +      pWin->zBase = sqlite3DbStrNDup(pParse->db, pBase->z, pBase->n);
         1127  +    }
         1128  +  }else{
         1129  +    sqlite3ExprListDelete(pParse->db, pPartition);
         1130  +    sqlite3ExprListDelete(pParse->db, pOrderBy);
         1131  +  }
         1132  +  return pWin;
         1133  +}
         1134  +
         1135  +/*
         1136  +** Window *pWin has just been created from a WINDOW clause. Tokne pBase
         1137  +** is the base window. Earlier windows from the same WINDOW clause are
         1138  +** stored in the linked list starting at pWin->pNextWin. This function
         1139  +** either updates *pWin according to the base specification, or else
         1140  +** leaves an error in pParse.
         1141  +*/
         1142  +void sqlite3WindowChain(Parse *pParse, Window *pWin, Window *pList){
         1143  +  if( pWin->zBase ){
         1144  +    sqlite3 *db = pParse->db;
         1145  +    Window *pExist = windowFind(pParse, pList, pWin->zBase);
         1146  +    if( pExist ){
         1147  +      const char *zErr = 0;
         1148  +      /* Check for errors */
         1149  +      if( pWin->pPartition ){
         1150  +        zErr = "PARTITION clause";
         1151  +      }else if( pExist->pOrderBy && pWin->pOrderBy ){
         1152  +        zErr = "ORDER BY clause";
         1153  +      }else if( pExist->bImplicitFrame==0 ){
         1154  +        zErr = "frame specification";
         1155  +      }
         1156  +      if( zErr ){
         1157  +        sqlite3ErrorMsg(pParse, 
         1158  +            "cannot override %s of window: %s", zErr, pWin->zBase
         1159  +        );
         1160  +      }else{
         1161  +        pWin->pPartition = sqlite3ExprListDup(db, pExist->pPartition, 0);
         1162  +        if( pExist->pOrderBy ){
         1163  +          assert( pWin->pOrderBy==0 );
         1164  +          pWin->pOrderBy = sqlite3ExprListDup(db, pExist->pOrderBy, 0);
         1165  +        }
         1166  +        sqlite3DbFree(db, pWin->zBase);
         1167  +        pWin->zBase = 0;
         1168  +      }
         1169  +    }
         1170  +  }
         1171  +}
   956   1172   
   957   1173   /*
   958   1174   ** Attach window object pWin to expression p.
   959   1175   */
   960   1176   void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
   961   1177     if( p ){
   962   1178       assert( p->op==TK_FUNCTION );
................................................................................
   978   1194   }
   979   1195   
   980   1196   /*
   981   1197   ** Return 0 if the two window objects are identical, or non-zero otherwise.
   982   1198   ** Identical window objects can be processed in a single scan.
   983   1199   */
   984   1200   int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2){
   985         -  if( p1->eType!=p2->eType ) return 1;
         1201  +  if( p1->eFrmType!=p2->eFrmType ) return 1;
   986   1202     if( p1->eStart!=p2->eStart ) return 1;
   987   1203     if( p1->eEnd!=p2->eEnd ) return 1;
         1204  +  if( p1->eExclude!=p2->eExclude ) return 1;
   988   1205     if( sqlite3ExprCompare(pParse, p1->pStart, p2->pStart, -1) ) return 1;
   989   1206     if( sqlite3ExprCompare(pParse, p1->pEnd, p2->pEnd, -1) ) return 1;
   990   1207     if( sqlite3ExprListCompare(p1->pPartition, p2->pPartition, -1) ) return 1;
   991   1208     if( sqlite3ExprListCompare(p1->pOrderBy, p2->pOrderBy, -1) ) return 1;
   992   1209     return 0;
   993   1210   }
   994   1211   
................................................................................
   997   1214   ** This is called by code in select.c before it calls sqlite3WhereBegin()
   998   1215   ** to begin iterating through the sub-query results. It is used to allocate
   999   1216   ** and initialize registers and cursors used by sqlite3WindowCodeStep().
  1000   1217   */
  1001   1218   void sqlite3WindowCodeInit(Parse *pParse, Window *pMWin){
  1002   1219     Window *pWin;
  1003   1220     Vdbe *v = sqlite3GetVdbe(pParse);
  1004         -  int nPart = (pMWin->pPartition ? pMWin->pPartition->nExpr : 0);
  1005         -  nPart += (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);
  1006         -  if( nPart ){
         1221  +
         1222  +  /* Allocate registers to use for PARTITION BY values, if any. Initialize
         1223  +  ** said registers to NULL.  */
         1224  +  if( pMWin->pPartition ){
         1225  +    int nExpr = pMWin->pPartition->nExpr;
  1007   1226       pMWin->regPart = pParse->nMem+1;
  1008         -    pParse->nMem += nPart;
  1009         -    sqlite3VdbeAddOp3(v, OP_Null, 0, pMWin->regPart, pMWin->regPart+nPart-1);
         1227  +    pParse->nMem += nExpr;
         1228  +    sqlite3VdbeAddOp3(v, OP_Null, 0, pMWin->regPart, pMWin->regPart+nExpr-1);
         1229  +  }
         1230  +
         1231  +  pMWin->regOne = ++pParse->nMem;
         1232  +  sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regOne);
         1233  +
         1234  +  if( pMWin->eExclude ){
         1235  +    pMWin->regStartRowid = ++pParse->nMem;
         1236  +    pMWin->regEndRowid = ++pParse->nMem;
         1237  +    pMWin->csrApp = pParse->nTab++;
         1238  +    sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regStartRowid);
         1239  +    sqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regEndRowid);
         1240  +    sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->csrApp, pMWin->iEphCsr);
         1241  +    return;
  1010   1242     }
  1011   1243   
  1012   1244     for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
  1013   1245       FuncDef *p = pWin->pFunc;
  1014   1246       if( (p->funcFlags & SQLITE_FUNC_MINMAX) && pWin->eStart!=TK_UNBOUNDED ){
  1015   1247         /* The inline versions of min() and max() require a single ephemeral
  1016   1248         ** table and 3 registers. The registers are used as follows:
................................................................................
  1031   1263         sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2);
  1032   1264         sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);
  1033   1265         sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
  1034   1266       }
  1035   1267       else if( p->zName==nth_valueName || p->zName==first_valueName ){
  1036   1268         /* Allocate two registers at pWin->regApp. These will be used to
  1037   1269         ** store the start and end index of the current frame.  */
  1038         -      assert( pMWin->iEphCsr );
  1039   1270         pWin->regApp = pParse->nMem+1;
  1040   1271         pWin->csrApp = pParse->nTab++;
  1041   1272         pParse->nMem += 2;
  1042   1273         sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);
  1043   1274       }
  1044   1275       else if( p->zName==leadName || p->zName==lagName ){
  1045         -      assert( pMWin->iEphCsr );
  1046   1276         pWin->csrApp = pParse->nTab++;
  1047   1277         sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);
  1048   1278       }
  1049   1279     }
  1050   1280   }
         1281  +
         1282  +#define WINDOW_STARTING_INT  0
         1283  +#define WINDOW_ENDING_INT    1
         1284  +#define WINDOW_NTH_VALUE_INT 2
         1285  +#define WINDOW_STARTING_NUM  3
         1286  +#define WINDOW_ENDING_NUM    4
  1051   1287   
  1052   1288   /*
  1053   1289   ** A "PRECEDING <expr>" (eCond==0) or "FOLLOWING <expr>" (eCond==1) or the
  1054   1290   ** value of the second argument to nth_value() (eCond==2) has just been
  1055   1291   ** evaluated and the result left in register reg. This function generates VM
  1056   1292   ** code to check that the value is a non-negative integer and throws an
  1057   1293   ** exception if it is not.
  1058   1294   */
  1059         -static void windowCheckIntValue(Parse *pParse, int reg, int eCond){
         1295  +static void windowCheckValue(Parse *pParse, int reg, int eCond){
  1060   1296     static const char *azErr[] = {
  1061   1297       "frame starting offset must be a non-negative integer",
  1062   1298       "frame ending offset must be a non-negative integer",
  1063         -    "second argument to nth_value must be a positive integer"
         1299  +    "second argument to nth_value must be a positive integer",
         1300  +    "frame starting offset must be a non-negative number",
         1301  +    "frame ending offset must be a non-negative number",
  1064   1302     };
  1065         -  static int aOp[] = { OP_Ge, OP_Ge, OP_Gt };
         1303  +  static int aOp[] = { OP_Ge, OP_Ge, OP_Gt, OP_Ge, OP_Ge };
  1066   1304     Vdbe *v = sqlite3GetVdbe(pParse);
  1067   1305     int regZero = sqlite3GetTempReg(pParse);
  1068         -  assert( eCond==0 || eCond==1 || eCond==2 );
         1306  +  assert( eCond>=0 && eCond<ArraySize(azErr) );
  1069   1307     sqlite3VdbeAddOp2(v, OP_Integer, 0, regZero);
  1070         -  sqlite3VdbeAddOp2(v, OP_MustBeInt, reg, sqlite3VdbeCurrentAddr(v)+2);
  1071         -  VdbeCoverageIf(v, eCond==0);
  1072         -  VdbeCoverageIf(v, eCond==1);
  1073         -  VdbeCoverageIf(v, eCond==2);
         1308  +  if( eCond>=WINDOW_STARTING_NUM ){
         1309  +    int regString = sqlite3GetTempReg(pParse);
         1310  +    sqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC);
         1311  +    sqlite3VdbeAddOp3(v, OP_Ge, regString, sqlite3VdbeCurrentAddr(v)+2, reg);
         1312  +    sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC|SQLITE_JUMPIFNULL);
         1313  +    VdbeCoverage(v);
         1314  +    assert( eCond==3 || eCond==4 );
         1315  +    VdbeCoverageIf(v, eCond==3);
         1316  +    VdbeCoverageIf(v, eCond==4);
         1317  +  }else{
         1318  +    sqlite3VdbeAddOp2(v, OP_MustBeInt, reg, sqlite3VdbeCurrentAddr(v)+2);
         1319  +    VdbeCoverage(v);
         1320  +    assert( eCond==0 || eCond==1 || eCond==2 );
         1321  +    VdbeCoverageIf(v, eCond==0);
         1322  +    VdbeCoverageIf(v, eCond==1);
         1323  +    VdbeCoverageIf(v, eCond==2);
         1324  +  }
  1074   1325     sqlite3VdbeAddOp3(v, aOp[eCond], regZero, sqlite3VdbeCurrentAddr(v)+2, reg);
  1075         -  VdbeCoverageNeverNullIf(v, eCond==0);
  1076         -  VdbeCoverageNeverNullIf(v, eCond==1);
         1326  +  VdbeCoverageNeverNullIf(v, eCond==0); /* NULL case captured by */
         1327  +  VdbeCoverageNeverNullIf(v, eCond==1); /*   the OP_MustBeInt */
  1077   1328     VdbeCoverageNeverNullIf(v, eCond==2);
         1329  +  VdbeCoverageNeverNullIf(v, eCond==3); /* NULL case caught by */
         1330  +  VdbeCoverageNeverNullIf(v, eCond==4); /*   the OP_Ge */
  1078   1331     sqlite3MayAbort(pParse);
  1079   1332     sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_ERROR, OE_Abort);
  1080   1333     sqlite3VdbeAppendP4(v, (void*)azErr[eCond], P4_STATIC);
  1081   1334     sqlite3ReleaseTempReg(pParse, regZero);
  1082   1335   }
  1083   1336   
  1084   1337   /*
................................................................................
  1110   1363   ** number of rows in the current partition.
  1111   1364   */
  1112   1365   static void windowAggStep(
  1113   1366     Parse *pParse, 
  1114   1367     Window *pMWin,                  /* Linked list of window functions */
  1115   1368     int csr,                        /* Read arguments from this cursor */
  1116   1369     int bInverse,                   /* True to invoke xInverse instead of xStep */
  1117         -  int reg,                        /* Array of registers */
  1118         -  int regPartSize                 /* Register containing size of partition */
         1370  +  int reg                         /* Array of registers */
  1119   1371   ){
  1120   1372     Vdbe *v = sqlite3GetVdbe(pParse);
  1121   1373     Window *pWin;
  1122   1374     for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
  1123         -    int flags = pWin->pFunc->funcFlags;
         1375  +    FuncDef *pFunc = pWin->pFunc;
  1124   1376       int regArg;
  1125   1377       int nArg = windowArgCount(pWin);
         1378  +    int i;
  1126   1379   
  1127         -    if( csr>=0 ){
  1128         -      int i;
  1129         -      for(i=0; i<nArg; i++){
         1380  +    for(i=0; i<nArg; i++){
         1381  +      if( i!=1 || pFunc->zName!=nth_valueName ){
  1130   1382           sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i);
         1383  +      }else{
         1384  +        sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+i, reg+i);
  1131   1385         }
  1132         -      regArg = reg;
  1133         -      if( flags & SQLITE_FUNC_WINDOW_SIZE ){
  1134         -        if( nArg==0 ){
  1135         -          regArg = regPartSize;
  1136         -        }else{
  1137         -          sqlite3VdbeAddOp2(v, OP_SCopy, regPartSize, reg+nArg);
  1138         -        }
  1139         -        nArg++;
  1140         -      }
  1141         -    }else{
  1142         -      assert( !(flags & SQLITE_FUNC_WINDOW_SIZE) );
  1143         -      regArg = reg + pWin->iArgCol;
  1144   1386       }
         1387  +    regArg = reg;
  1145   1388   
  1146         -    if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX) 
  1147         -      && pWin->eStart!=TK_UNBOUNDED 
         1389  +    if( pMWin->regStartRowid==0
         1390  +     && (pFunc->funcFlags & SQLITE_FUNC_MINMAX) 
         1391  +     && (pWin->eStart!=TK_UNBOUNDED)
  1148   1392       ){
  1149   1393         int addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regArg);
  1150   1394         VdbeCoverage(v);
  1151   1395         if( bInverse==0 ){
  1152   1396           sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1, 1);
  1153   1397           sqlite3VdbeAddOp2(v, OP_SCopy, regArg, pWin->regApp);
  1154   1398           sqlite3VdbeAddOp3(v, OP_MakeRecord, pWin->regApp, 2, pWin->regApp+2);
................................................................................
  1157   1401           sqlite3VdbeAddOp4Int(v, OP_SeekGE, pWin->csrApp, 0, regArg, 1);
  1158   1402           VdbeCoverageNeverTaken(v);
  1159   1403           sqlite3VdbeAddOp1(v, OP_Delete, pWin->csrApp);
  1160   1404           sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
  1161   1405         }
  1162   1406         sqlite3VdbeJumpHere(v, addrIsNull);
  1163   1407       }else if( pWin->regApp ){
  1164         -      assert( pWin->pFunc->zName==nth_valueName
  1165         -           || pWin->pFunc->zName==first_valueName
         1408  +      assert( pFunc->zName==nth_valueName
         1409  +           || pFunc->zName==first_valueName
  1166   1410         );
  1167   1411         assert( bInverse==0 || bInverse==1 );
  1168   1412         sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1);
  1169         -    }else if( pWin->pFunc->zName==leadName
  1170         -           || pWin->pFunc->zName==lagName
  1171         -    ){
  1172         -      /* no-op */
  1173         -    }else{
         1413  +    }else if( pFunc->xSFunc!=noopStepFunc ){
  1174   1414         int addrIf = 0;
  1175   1415         if( pWin->pFilter ){
  1176   1416           int regTmp;
  1177   1417           assert( nArg==0 || nArg==pWin->pOwner->x.pList->nExpr );
  1178   1418           assert( nArg || pWin->pOwner->x.pList==0 );
  1179         -        if( csr>0 ){
  1180         -          regTmp = sqlite3GetTempReg(pParse);
  1181         -          sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
  1182         -        }else{
  1183         -          regTmp = regArg + nArg;
  1184         -        }
         1419  +        regTmp = sqlite3GetTempReg(pParse);
         1420  +        sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
  1185   1421           addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
  1186   1422           VdbeCoverage(v);
  1187         -        if( csr>0 ){
  1188         -          sqlite3ReleaseTempReg(pParse, regTmp);
  1189         -        }
         1423  +        sqlite3ReleaseTempReg(pParse, regTmp);
  1190   1424         }
  1191         -      if( pWin->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
         1425  +      if( pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
  1192   1426           CollSeq *pColl;
  1193   1427           assert( nArg>0 );
  1194   1428           pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr);
  1195   1429           sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ);
  1196   1430         }
  1197   1431         sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep, 
  1198   1432                           bInverse, regArg, pWin->regAccum);
  1199         -      sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
         1433  +      sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF);
  1200   1434         sqlite3VdbeChangeP5(v, (u8)nArg);
  1201   1435         if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
  1202   1436       }
  1203   1437     }
  1204   1438   }
         1439  +
         1440  +typedef struct WindowCodeArg WindowCodeArg;
         1441  +typedef struct WindowCsrAndReg WindowCsrAndReg;
         1442  +struct WindowCsrAndReg {
         1443  +  int csr;
         1444  +  int reg;
         1445  +};
         1446  +
         1447  +struct WindowCodeArg {
         1448  +  Parse *pParse;
         1449  +  Window *pMWin;
         1450  +  Vdbe *pVdbe;
         1451  +  int regGosub;
         1452  +  int addrGosub;
         1453  +  int regArg;
         1454  +  int eDelete;
         1455  +
         1456  +  WindowCsrAndReg start;
         1457  +  WindowCsrAndReg current;
         1458  +  WindowCsrAndReg end;
         1459  +};
         1460  +
         1461  +/*
         1462  +** Values that may be passed as the second argument to windowCodeOp().
         1463  +*/
         1464  +#define WINDOW_RETURN_ROW 1
         1465  +#define WINDOW_AGGINVERSE 2
         1466  +#define WINDOW_AGGSTEP    3
         1467  +
         1468  +/*
         1469  +** Generate VM code to read the window frames peer values from cursor csr into
         1470  +** an array of registers starting at reg.
         1471  +*/
         1472  +static void windowReadPeerValues(
         1473  +  WindowCodeArg *p,
         1474  +  int csr,
         1475  +  int reg
         1476  +){
         1477  +  Window *pMWin = p->pMWin;
         1478  +  ExprList *pOrderBy = pMWin->pOrderBy;
         1479  +  if( pOrderBy ){
         1480  +    Vdbe *v = sqlite3GetVdbe(p->pParse);
         1481  +    ExprList *pPart = pMWin->pPartition;
         1482  +    int iColOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0);
         1483  +    int i;
         1484  +    for(i=0; i<pOrderBy->nExpr; i++){
         1485  +      sqlite3VdbeAddOp3(v, OP_Column, csr, iColOff+i, reg+i);
         1486  +    }
         1487  +  }
         1488  +}
  1205   1489   
  1206   1490   /*
  1207         -** Generate VM code to invoke either xValue() (bFinal==0) or xFinalize()
  1208         -** (bFinal==1) for each window function in the linked list starting at
         1491  +** Generate VM code to invoke either xValue() (bFin==0) or xFinalize()
         1492  +** (bFin==1) for each window function in the linked list starting at
  1209   1493   ** pMWin. Or, for built-in window-functions that do not use the standard
  1210   1494   ** API, generate the equivalent VM code.
  1211   1495   */
  1212         -static void windowAggFinal(Parse *pParse, Window *pMWin, int bFinal){
         1496  +static void windowAggFinal(WindowCodeArg *p, int bFin){
         1497  +  Parse *pParse = p->pParse;
         1498  +  Window *pMWin = p->pMWin;
  1213   1499     Vdbe *v = sqlite3GetVdbe(pParse);
  1214   1500     Window *pWin;
  1215   1501   
  1216   1502     for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
  1217         -    if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX) 
  1218         -     && pWin->eStart!=TK_UNBOUNDED 
         1503  +    if( pMWin->regStartRowid==0
         1504  +     && (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX) 
         1505  +     && (pWin->eStart!=TK_UNBOUNDED)
  1219   1506       ){
  1220   1507         sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
  1221   1508         sqlite3VdbeAddOp1(v, OP_Last, pWin->csrApp);
  1222   1509         VdbeCoverage(v);
  1223   1510         sqlite3VdbeAddOp3(v, OP_Column, pWin->csrApp, 0, pWin->regResult);
  1224   1511         sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
  1225         -      if( bFinal ){
  1226         -        sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp);
  1227         -      }
  1228   1512       }else if( pWin->regApp ){
         1513  +      assert( pMWin->regStartRowid==0 );
  1229   1514       }else{
  1230         -      if( bFinal ){
  1231         -        sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, windowArgCount(pWin));
         1515  +      int nArg = windowArgCount(pWin);
         1516  +      if( bFin ){
         1517  +        sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, nArg);
  1232   1518           sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
  1233   1519           sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult);
  1234   1520           sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
  1235   1521         }else{
  1236         -        sqlite3VdbeAddOp3(v, OP_AggValue, pWin->regAccum, windowArgCount(pWin),
  1237         -                             pWin->regResult);
         1522  +        sqlite3VdbeAddOp3(v, OP_AggValue,pWin->regAccum,nArg,pWin->regResult);
  1238   1523           sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
  1239   1524         }
  1240   1525       }
  1241   1526     }
  1242   1527   }
  1243   1528   
  1244   1529   /*
  1245         -** This function generates VM code to invoke the sub-routine at address
  1246         -** lblFlushPart once for each partition with the entire partition cached in
  1247         -** the Window.iEphCsr temp table.
         1530  +** Generate code to calculate the current values of all window functions in the
         1531  +** p->pMWin list by doing a full scan of the current window frame. Store the
         1532  +** results in the Window.regResult registers, ready to return the upper
         1533  +** layer.
  1248   1534   */
  1249         -static void windowPartitionCache(
  1250         -  Parse *pParse,
  1251         -  Select *p,                      /* The rewritten SELECT statement */
  1252         -  WhereInfo *pWInfo,              /* WhereInfo to call WhereEnd() on */
  1253         -  int regFlushPart,               /* Register to use with Gosub lblFlushPart */
  1254         -  int lblFlushPart,               /* Subroutine to Gosub to */
  1255         -  int *pRegSize                   /* OUT: Register containing partition size */
  1256         -){
  1257         -  Window *pMWin = p->pWin;
  1258         -  Vdbe *v = sqlite3GetVdbe(pParse);
  1259         -  int iSubCsr = p->pSrc->a[0].iCursor;
  1260         -  int nSub = p->pSrc->a[0].pTab->nCol;
  1261         -  int k;
  1262         -
  1263         -  int reg = pParse->nMem+1;
  1264         -  int regRecord = reg+nSub;
  1265         -  int regRowid = regRecord+1;
  1266         -
  1267         -  *pRegSize = regRowid;
  1268         -  pParse->nMem += nSub + 2;
  1269         -
  1270         -  /* Load the column values for the row returned by the sub-select
  1271         -  ** into an array of registers starting at reg. */
  1272         -  for(k=0; k<nSub; k++){
  1273         -    sqlite3VdbeAddOp3(v, OP_Column, iSubCsr, k, reg+k);
  1274         -  }
  1275         -  sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, nSub, regRecord);
  1276         -
  1277         -  /* Check if this is the start of a new partition. If so, call the
  1278         -  ** flush_partition sub-routine.  */
  1279         -  if( pMWin->pPartition ){
         1535  +static void windowFullScan(WindowCodeArg *p){
         1536  +  Window *pWin;
         1537  +  Parse *pParse = p->pParse;
         1538  +  Window *pMWin = p->pMWin;
         1539  +  Vdbe *v = p->pVdbe;
         1540  +
         1541  +  int regCRowid = 0;              /* Current rowid value */
         1542  +  int regCPeer = 0;               /* Current peer values */
         1543  +  int regRowid = 0;               /* AggStep rowid value */
         1544  +  int regPeer = 0;                /* AggStep peer values */
         1545  +
         1546  +  int nPeer;
         1547  +  int lblNext;
         1548  +  int lblBrk;
         1549  +  int addrNext;
         1550  +  int csr = pMWin->csrApp;
         1551  +
         1552  +  nPeer = (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);
         1553  +
         1554  +  lblNext = sqlite3VdbeMakeLabel(pParse);
         1555  +  lblBrk = sqlite3VdbeMakeLabel(pParse);
         1556  +
         1557  +  regCRowid = sqlite3GetTempReg(pParse);
         1558  +  regRowid = sqlite3GetTempReg(pParse);
         1559  +  if( nPeer ){
         1560  +    regCPeer = sqlite3GetTempRange(pParse, nPeer);
         1561  +    regPeer = sqlite3GetTempRange(pParse, nPeer);
         1562  +  }
         1563  +
         1564  +  sqlite3VdbeAddOp2(v, OP_Rowid, pMWin->iEphCsr, regCRowid);
         1565  +  windowReadPeerValues(p, pMWin->iEphCsr, regCPeer);
         1566  +
         1567  +  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
         1568  +    sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
         1569  +  }
         1570  +
         1571  +  sqlite3VdbeAddOp3(v, OP_SeekGE, csr, lblBrk, pMWin->regStartRowid);
         1572  +  VdbeCoverage(v);
         1573  +  addrNext = sqlite3VdbeCurrentAddr(v);
         1574  +  sqlite3VdbeAddOp2(v, OP_Rowid, csr, regRowid);
         1575  +  sqlite3VdbeAddOp3(v, OP_Gt, pMWin->regEndRowid, lblBrk, regRowid);
         1576  +  VdbeCoverageNeverNull(v);
         1577  +
         1578  +  if( pMWin->eExclude==TK_CURRENT ){
         1579  +    sqlite3VdbeAddOp3(v, OP_Eq, regCRowid, lblNext, regRowid);
         1580  +    VdbeCoverageNeverNull(v);
         1581  +  }else if( pMWin->eExclude!=TK_NO ){
  1280   1582       int addr;
  1281         -    ExprList *pPart = pMWin->pPartition;
  1282         -    int nPart = pPart->nExpr;
  1283         -    int regNewPart = reg + pMWin->nBufferCol;
  1284         -    KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
  1285         -
  1286         -    addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart,nPart);
  1287         -    sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
  1288         -    sqlite3VdbeAddOp3(v, OP_Jump, addr+2, addr+4, addr+2);
  1289         -    VdbeCoverageEqNe(v);
  1290         -    sqlite3VdbeAddOp3(v, OP_Copy, regNewPart, pMWin->regPart, nPart-1);
  1291         -    sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart);
  1292         -    VdbeComment((v, "call flush_partition"));
  1293         -  }
  1294         -
  1295         -  /* Buffer the current row in the ephemeral table. */
  1296         -  sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid);
  1297         -  sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid);
  1298         -
  1299         -  /* End of the input loop */
  1300         -  sqlite3WhereEnd(pWInfo);
  1301         -
  1302         -  /* Invoke "flush_partition" to deal with the final (or only) partition */
  1303         -  sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart);
  1304         -  VdbeComment((v, "call flush_partition"));
         1583  +    int addrEq = 0;
         1584  +    KeyInfo *pKeyInfo = 0;
         1585  +
         1586  +    if( pMWin->pOrderBy ){
         1587  +      pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pMWin->pOrderBy, 0, 0);
         1588  +    }
         1589  +    if( pMWin->eExclude==TK_TIES ){
         1590  +      addrEq = sqlite3VdbeAddOp3(v, OP_Eq, regCRowid, 0, regRowid);
         1591  +      VdbeCoverageNeverNull(v);
         1592  +    }
         1593  +    if( pKeyInfo ){
         1594  +      windowReadPeerValues(p, csr, regPeer);
         1595  +      sqlite3VdbeAddOp3(v, OP_Compare, regPeer, regCPeer, nPeer);
         1596  +      sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
         1597  +      addr = sqlite3VdbeCurrentAddr(v)+1;
         1598  +      sqlite3VdbeAddOp3(v, OP_Jump, addr, lblNext, addr);
         1599  +      VdbeCoverageEqNe(v);
         1600  +    }else{
         1601  +      sqlite3VdbeAddOp2(v, OP_Goto, 0, lblNext);
         1602  +    }
         1603  +    if( addrEq ) sqlite3VdbeJumpHere(v, addrEq);
         1604  +  }
         1605  +
         1606  +  windowAggStep(pParse, pMWin, csr, 0, p->regArg);
         1607  +
         1608  +  sqlite3VdbeResolveLabel(v, lblNext);
         1609  +  sqlite3VdbeAddOp2(v, OP_Next, csr, addrNext);
         1610  +  VdbeCoverage(v);
         1611  +  sqlite3VdbeJumpHere(v, addrNext-1);
         1612  +  sqlite3VdbeJumpHere(v, addrNext+1);
         1613  +  sqlite3ReleaseTempReg(pParse, regRowid);
         1614  +  sqlite3ReleaseTempReg(pParse, regCRowid);
         1615  +  if( nPeer ){
         1616  +    sqlite3ReleaseTempRange(pParse, regPeer, nPeer);
         1617  +    sqlite3ReleaseTempRange(pParse, regCPeer, nPeer);
         1618  +  }
         1619  +
         1620  +  windowAggFinal(p, 1);
  1305   1621   }
  1306   1622   
  1307   1623   /*
  1308   1624   ** Invoke the sub-routine at regGosub (generated by code in select.c) to
  1309   1625   ** return the current row of Window.iEphCsr. If all window functions are
  1310   1626   ** aggregate window functions that use the standard API, a single
  1311   1627   ** OP_Gosub instruction is all that this routine generates. Extra VM code
................................................................................
  1313   1629   ** functions:
  1314   1630   **
  1315   1631   **   nth_value()
  1316   1632   **   first_value()
  1317   1633   **   lag()
  1318   1634   **   lead()
  1319   1635   */
  1320         -static void windowReturnOneRow(
  1321         -  Parse *pParse,
  1322         -  Window *pMWin,
  1323         -  int regGosub,
  1324         -  int addrGosub
  1325         -){
  1326         -  Vdbe *v = sqlite3GetVdbe(pParse);
  1327         -  Window *pWin;
  1328         -  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
  1329         -    FuncDef *pFunc = pWin->pFunc;
  1330         -    if( pFunc->zName==nth_valueName
  1331         -     || pFunc->zName==first_valueName
  1332         -    ){
  1333         -      int csr = pWin->csrApp;
  1334         -      int lbl = sqlite3VdbeMakeLabel(pParse);
  1335         -      int tmpReg = sqlite3GetTempReg(pParse);
  1336         -      sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
  1337         -
  1338         -      if( pFunc->zName==nth_valueName ){
  1339         -        sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+1,tmpReg);
  1340         -        windowCheckIntValue(pParse, tmpReg, 2);
  1341         -      }else{
  1342         -        sqlite3VdbeAddOp2(v, OP_Integer, 1, tmpReg);
         1636  +static void windowReturnOneRow(WindowCodeArg *p){
         1637  +  Window *pMWin = p->pMWin;
         1638  +  Vdbe *v = p->pVdbe;
         1639  +
         1640  +  if( pMWin->regStartRowid ){
         1641  +    windowFullScan(p);
         1642  +  }else{
         1643  +    Parse *pParse = p->pParse;
         1644  +    Window *pWin;
         1645  +
         1646  +    for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
         1647  +      FuncDef *pFunc = pWin->pFunc;
         1648  +      if( pFunc->zName==nth_valueName
         1649  +       || pFunc->zName==first_valueName
         1650  +      ){
         1651  +        int csr = pWin->csrApp;
         1652  +        int lbl = sqlite3VdbeMakeLabel(pParse);
         1653  +        int tmpReg = sqlite3GetTempReg(pParse);
         1654  +        sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
         1655  +  
         1656  +        if( pFunc->zName==nth_valueName ){
         1657  +          sqlite3VdbeAddOp3(v, OP_Column,pMWin->iEphCsr,pWin->iArgCol+1,tmpReg);
         1658  +          windowCheckValue(pParse, tmpReg, 2);
         1659  +        }else{
         1660  +          sqlite3VdbeAddOp2(v, OP_Integer, 1, tmpReg);
         1661  +        }
         1662  +        sqlite3VdbeAddOp3(v, OP_Add, tmpReg, pWin->regApp, tmpReg);
         1663  +        sqlite3VdbeAddOp3(v, OP_Gt, pWin->regApp+1, lbl, tmpReg);
         1664  +        VdbeCoverageNeverNull(v);
         1665  +        sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, 0, tmpReg);
         1666  +        VdbeCoverageNeverTaken(v);
         1667  +        sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
         1668  +        sqlite3VdbeResolveLabel(v, lbl);
         1669  +        sqlite3ReleaseTempReg(pParse, tmpReg);
  1343   1670         }
  1344         -      sqlite3VdbeAddOp3(v, OP_Add, tmpReg, pWin->regApp, tmpReg);
  1345         -      sqlite3VdbeAddOp3(v, OP_Gt, pWin->regApp+1, lbl, tmpReg);
  1346         -      VdbeCoverageNeverNull(v);
  1347         -      sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, 0, tmpReg);
  1348         -      VdbeCoverageNeverTaken(v);
  1349         -      sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
  1350         -      sqlite3VdbeResolveLabel(v, lbl);
  1351         -      sqlite3ReleaseTempReg(pParse, tmpReg);
  1352         -    }
  1353         -    else if( pFunc->zName==leadName || pFunc->zName==lagName ){
  1354         -      int nArg = pWin->pOwner->x.pList->nExpr;
  1355         -      int iEph = pMWin->iEphCsr;
  1356         -      int csr = pWin->csrApp;
  1357         -      int lbl = sqlite3VdbeMakeLabel(pParse);
  1358         -      int tmpReg = sqlite3GetTempReg(pParse);
  1359         -
  1360         -      if( nArg<3 ){
  1361         -        sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
  1362         -      }else{
  1363         -        sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+2, pWin->regResult);
  1364         -      }
  1365         -      sqlite3VdbeAddOp2(v, OP_Rowid, iEph, tmpReg);
  1366         -      if( nArg<2 ){
  1367         -        int val = (pFunc->zName==leadName ? 1 : -1);
  1368         -        sqlite3VdbeAddOp2(v, OP_AddImm, tmpReg, val);
  1369         -      }else{
  1370         -        int op = (pFunc->zName==leadName ? OP_Add : OP_Subtract);
  1371         -        int tmpReg2 = sqlite3GetTempReg(pParse);
  1372         -        sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+1, tmpReg2);
  1373         -        sqlite3VdbeAddOp3(v, op, tmpReg2, tmpReg, tmpReg);
  1374         -        sqlite3ReleaseTempReg(pParse, tmpReg2);
  1375         -      }
  1376         -
  1377         -      sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, lbl, tmpReg);
  1378         -      VdbeCoverage(v);
  1379         -      sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
  1380         -      sqlite3VdbeResolveLabel(v, lbl);
  1381         -      sqlite3ReleaseTempReg(pParse, tmpReg);
         1671  +      else if( pFunc->zName==leadName || pFunc->zName==lagName ){
         1672  +        int nArg = pWin->pOwner->x.pList->nExpr;
         1673  +        int csr = pWin->csrApp;
         1674  +        int lbl = sqlite3VdbeMakeLabel(pParse);
         1675  +        int tmpReg = sqlite3GetTempReg(pParse);
         1676  +        int iEph = pMWin->iEphCsr;
         1677  +  
         1678  +        if( nArg<3 ){
         1679  +          sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
         1680  +        }else{
         1681  +          sqlite3VdbeAddOp3(v, OP_Column, iEph,pWin->iArgCol+2,pWin->regResult);
         1682  +        }
         1683  +        sqlite3VdbeAddOp2(v, OP_Rowid, iEph, tmpReg);
         1684  +        if( nArg<2 ){
         1685  +          int val = (pFunc->zName==leadName ? 1 : -1);
         1686  +          sqlite3VdbeAddOp2(v, OP_AddImm, tmpReg, val);
         1687  +        }else{
         1688  +          int op = (pFunc->zName==leadName ? OP_Add : OP_Subtract);
         1689  +          int tmpReg2 = sqlite3GetTempReg(pParse);
         1690  +          sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+1, tmpReg2);
         1691  +          sqlite3VdbeAddOp3(v, op, tmpReg2, tmpReg, tmpReg);
         1692  +          sqlite3ReleaseTempReg(pParse, tmpReg2);
         1693  +        }
         1694  +  
         1695  +        sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, lbl, tmpReg);
         1696  +        VdbeCoverage(v);
         1697  +        sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
         1698  +        sqlite3VdbeResolveLabel(v, lbl);
         1699  +        sqlite3ReleaseTempReg(pParse, tmpReg);
         1700  +      }
  1382   1701       }
  1383   1702     }
  1384         -  sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
  1385         -}
  1386         -
  1387         -/*
  1388         -** Invoke the code generated by windowReturnOneRow() and, optionally, the
  1389         -** xInverse() function for each window function, for one or more rows
  1390         -** from the Window.iEphCsr temp table. This routine generates VM code
  1391         -** similar to:
  1392         -**
  1393         -**   while( regCtr>0 ){
  1394         -**     regCtr--;
  1395         -**     windowReturnOneRow()
  1396         -**     if( bInverse ){
  1397         -**       AggInverse
  1398         -**     }
  1399         -**     Next (Window.iEphCsr)
  1400         -**   }
  1401         -*/
  1402         -static void windowReturnRows(
  1403         -  Parse *pParse,
  1404         -  Window *pMWin,                  /* List of window functions */
  1405         -  int regCtr,                     /* Register containing number of rows */
  1406         -  int regGosub,                   /* Register for Gosub addrGosub */
  1407         -  int addrGosub,                  /* Address of sub-routine for ReturnOneRow */
  1408         -  int regInvArg,                  /* Array of registers for xInverse args */
  1409         -  int regInvSize                  /* Register containing size of partition */
  1410         -){
  1411         -  int addr;
  1412         -  Vdbe *v = sqlite3GetVdbe(pParse);
  1413         -  windowAggFinal(pParse, pMWin, 0);
  1414         -  addr = sqlite3VdbeAddOp3(v, OP_IfPos, regCtr, sqlite3VdbeCurrentAddr(v)+2 ,1);
  1415         -  VdbeCoverage(v);
  1416         -  sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
  1417         -  windowReturnOneRow(pParse, pMWin, regGosub, addrGosub);
  1418         -  if( regInvArg ){
  1419         -    windowAggStep(pParse, pMWin, pMWin->iEphCsr, 1, regInvArg, regInvSize);
  1420         -  }
  1421         -  sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, addr);
  1422         -  VdbeCoverage(v);
  1423         -  sqlite3VdbeJumpHere(v, addr+1);   /* The OP_Goto */
         1703  +  sqlite3VdbeAddOp2(v, OP_Gosub, p->regGosub, p->addrGosub);
  1424   1704   }
  1425   1705   
  1426   1706   /*
  1427   1707   ** Generate code to set the accumulator register for each window function
  1428   1708   ** in the linked list passed as the second argument to NULL. And perform
  1429   1709   ** any equivalent initialization required by any built-in window functions
  1430   1710   ** in the list.
................................................................................
  1434   1714     int regArg;
  1435   1715     int nArg = 0;
  1436   1716     Window *pWin;
  1437   1717     for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
  1438   1718       FuncDef *pFunc = pWin->pFunc;
  1439   1719       sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
  1440   1720       nArg = MAX(nArg, windowArgCount(pWin));
  1441         -    if( pFunc->zName==nth_valueName
  1442         -     || pFunc->zName==first_valueName
  1443         -    ){
  1444         -      sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp);
  1445         -      sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
  1446         -    }
         1721  +    if( pMWin->regStartRowid==0 ){
         1722  +      if( pFunc->zName==nth_valueName || pFunc->zName==first_valueName ){
         1723  +        sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp);
         1724  +        sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
         1725  +      }
  1447   1726   
  1448         -    if( (pFunc->funcFlags & SQLITE_FUNC_MINMAX) && pWin->csrApp ){
  1449         -      assert( pWin->eStart!=TK_UNBOUNDED );
  1450         -      sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp);
  1451         -      sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
         1727  +      if( (pFunc->funcFlags & SQLITE_FUNC_MINMAX) && pWin->csrApp ){
         1728  +        assert( pWin->eStart!=TK_UNBOUNDED );
         1729  +        sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp);
         1730  +        sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
         1731  +      }
  1452   1732       }
  1453   1733     }
  1454   1734     regArg = pParse->nMem+1;
  1455   1735     pParse->nMem += nArg;
  1456   1736     return regArg;
  1457   1737   }
  1458   1738   
         1739  +/* 
         1740  +** Return true if the current frame should be cached in the ephemeral table,
         1741  +** even if there are no xInverse() calls required.
         1742  +*/
         1743  +static int windowCacheFrame(Window *pMWin){
         1744  +  Window *pWin;
         1745  +  if( pMWin->regStartRowid ) return 1;
         1746  +  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
         1747  +    FuncDef *pFunc = pWin->pFunc;
         1748  +    if( (pFunc->zName==nth_valueName)
         1749  +     || (pFunc->zName==first_valueName)
         1750  +     || (pFunc->zName==leadName)
         1751  +     || (pFunc->zName==lagName)
         1752  +    ){
         1753  +      return 1;
         1754  +    }
         1755  +  }
         1756  +  return 0;
         1757  +}
         1758  +
         1759  +/*
         1760  +** regOld and regNew are each the first register in an array of size
         1761  +** pOrderBy->nExpr. This function generates code to compare the two
         1762  +** arrays of registers using the collation sequences and other comparison
         1763  +** parameters specified by pOrderBy. 
         1764  +**
         1765  +** If the two arrays are not equal, the contents of regNew is copied to 
         1766  +** regOld and control falls through. Otherwise, if the contents of the arrays
         1767  +** are equal, an OP_Goto is executed. The address of the OP_Goto is returned.
         1768  +*/
         1769  +static void windowIfNewPeer(
         1770  +  Parse *pParse,
         1771  +  ExprList *pOrderBy,
         1772  +  int regNew,                     /* First in array of new values */
         1773  +  int regOld,                     /* First in array of old values */
         1774  +  int addr                        /* Jump here */
         1775  +){
         1776  +  Vdbe *v = sqlite3GetVdbe(pParse);
         1777  +  if( pOrderBy ){
         1778  +    int nVal = pOrderBy->nExpr;
         1779  +    KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);
         1780  +    sqlite3VdbeAddOp3(v, OP_Compare, regOld, regNew, nVal);
         1781  +    sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
         1782  +    sqlite3VdbeAddOp3(v, OP_Jump, 
         1783  +      sqlite3VdbeCurrentAddr(v)+1, addr, sqlite3VdbeCurrentAddr(v)+1
         1784  +    );
         1785  +    VdbeCoverageEqNe(v);
         1786  +    sqlite3VdbeAddOp3(v, OP_Copy, regNew, regOld, nVal-1);
         1787  +  }else{
         1788  +    sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
         1789  +  }
         1790  +}
         1791  +
         1792  +/*
         1793  +** This function is called as part of generating VM programs for RANGE
         1794  +** offset PRECEDING/FOLLOWING frame boundaries. Assuming "ASC" order for
         1795  +** the ORDER BY term in the window, it generates code equivalent to:
         1796  +**
         1797  +**   if( csr1.peerVal + regVal >= csr2.peerVal ) goto lbl;
         1798  +**
         1799  +** A special type of arithmetic is used such that if csr.peerVal is not
         1800  +** a numeric type (real or integer), then the result of the addition is
         1801  +** a copy of csr1.peerVal.
         1802  +*/
         1803  +static void windowCodeRangeTest(
         1804  +  WindowCodeArg *p, 
         1805  +  int op,                          /* OP_Ge or OP_Gt */
         1806  +  int csr1, 
         1807  +  int regVal, 
         1808  +  int csr2,
         1809  +  int lbl
         1810  +){
         1811  +  Parse *pParse = p->pParse;
         1812  +  Vdbe *v = sqlite3GetVdbe(pParse);
         1813  +  int reg1 = sqlite3GetTempReg(pParse);
         1814  +  int reg2 = sqlite3GetTempReg(pParse);
         1815  +  int arith = OP_Add;
         1816  +  int addrGe;
         1817  +
         1818  +  int regString = ++pParse->nMem;
         1819  +
         1820  +  assert( op==OP_Ge || op==OP_Gt || op==OP_Le );
         1821  +  assert( p->pMWin->pOrderBy && p->pMWin->pOrderBy->nExpr==1 );
         1822  +  if( p->pMWin->pOrderBy->a[0].sortOrder ){
         1823  +    switch( op ){
         1824  +      case OP_Ge: op = OP_Le; break;
         1825  +      case OP_Gt: op = OP_Lt; break;
         1826  +      default: assert( op==OP_Le ); op = OP_Ge; break;
         1827  +    }
         1828  +    arith = OP_Subtract;
         1829  +  }
         1830  +
         1831  +  windowReadPeerValues(p, csr1, reg1);
         1832  +  windowReadPeerValues(p, csr2, reg2);
         1833  +
         1834  +  /* Check if the peer value for csr1 value is a text or blob by comparing
         1835  +  ** it to the smallest possible string - ''. If it is, jump over the
         1836  +  ** OP_Add or OP_Subtract operation and proceed directly to the comparison. */
         1837  +  sqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC);
         1838  +  addrGe = sqlite3VdbeAddOp3(v, OP_Ge, regString, 0, reg1);
         1839  +  VdbeCoverage(v);
         1840  +  sqlite3VdbeAddOp3(v, arith, regVal, reg1, reg1);
         1841  +  sqlite3VdbeJumpHere(v, addrGe);
         1842  +  sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1); VdbeCoverage(v);
         1843  +  sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
         1844  +  assert( op==OP_Ge || op==OP_Gt || op==OP_Lt || op==OP_Le );
         1845  +  testcase(op==OP_Ge); VdbeCoverageIf(v, op==OP_Ge);
         1846  +  testcase(op==OP_Lt); VdbeCoverageIf(v, op==OP_Lt);
         1847  +  testcase(op==OP_Le); VdbeCoverageIf(v, op==OP_Le);
         1848  +  testcase(op==OP_Gt); VdbeCoverageIf(v, op==OP_Gt);
         1849  +
         1850  +  sqlite3ReleaseTempReg(pParse, reg1);
         1851  +  sqlite3ReleaseTempReg(pParse, reg2);
         1852  +}
  1459   1853   
  1460   1854   /*
  1461         -** This function does the work of sqlite3WindowCodeStep() for all "ROWS"
  1462         -** window frame types except for "BETWEEN UNBOUNDED PRECEDING AND CURRENT
  1463         -** ROW". Pseudo-code for each follows.
  1464         -**
  1465         -** ROWS BETWEEN <expr1> PRECEDING AND <expr2> FOLLOWING
  1466         -**
  1467         -**     ...
  1468         -**       if( new partition ){
  1469         -**         Gosub flush_partition
  1470         -**       }
  1471         -**       Insert (record in eph-table)
  1472         -**     sqlite3WhereEnd()
  1473         -**     Gosub flush_partition
  1474         -**  
  1475         -**   flush_partition:
  1476         -**     Once {
  1477         -**       OpenDup (iEphCsr -> csrStart)
  1478         -**       OpenDup (iEphCsr -> csrEnd)
  1479         -**     }
  1480         -**     regStart = <expr1>                // PRECEDING expression
  1481         -**     regEnd = <expr2>                  // FOLLOWING expression
  1482         -**     if( regStart<0 || regEnd<0 ){ error! }
  1483         -**     Rewind (csr,csrStart,csrEnd)      // if EOF goto flush_partition_done
  1484         -**       Next(csrEnd)                    // if EOF skip Aggstep
  1485         -**       Aggstep (csrEnd)
  1486         -**       if( (regEnd--)<=0 ){
  1487         -**         AggFinal (xValue)
  1488         -**         Gosub addrGosub
  1489         -**         Next(csr)                // if EOF goto flush_partition_done
  1490         -**         if( (regStart--)<=0 ){
  1491         -**           AggInverse (csrStart)
  1492         -**           Next(csrStart)
  1493         -**         }
  1494         -**       }
  1495         -**   flush_partition_done:
  1496         -**     ResetSorter (csr)
  1497         -**     Return
  1498         -**
  1499         -** ROWS BETWEEN <expr> PRECEDING    AND CURRENT ROW
  1500         -** ROWS BETWEEN CURRENT ROW         AND <expr> FOLLOWING
  1501         -** ROWS BETWEEN UNBOUNDED PRECEDING AND <expr> FOLLOWING
  1502         -**
  1503         -**   These are similar to the above. For "CURRENT ROW", intialize the
  1504         -**   register to 0. For "UNBOUNDED PRECEDING" to infinity.
  1505         -**
  1506         -** ROWS BETWEEN <expr> PRECEDING    AND UNBOUNDED FOLLOWING
  1507         -** ROWS BETWEEN CURRENT ROW         AND UNBOUNDED FOLLOWING
  1508         -**
  1509         -**     Rewind (csr,csrStart,csrEnd)    // if EOF goto flush_partition_done
  1510         -**     while( 1 ){
  1511         -**       Next(csrEnd)                  // Exit while(1) at EOF
  1512         -**       Aggstep (csrEnd)
  1513         -**     }
  1514         -**     while( 1 ){
  1515         -**       AggFinal (xValue)
  1516         -**       Gosub addrGosub
  1517         -**       Next(csr)                     // if EOF goto flush_partition_done
  1518         -**       if( (regStart--)<=0 ){
  1519         -**         AggInverse (csrStart)
  1520         -**         Next(csrStart)
  1521         -**       }
  1522         -**     }
  1523         -**
  1524         -**   For the "CURRENT ROW AND UNBOUNDED FOLLOWING" case, the final if() 
  1525         -**   condition is always true (as if regStart were initialized to 0).
  1526         -**
  1527         -** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
  1528         -** 
  1529         -**   This is the only RANGE case handled by this routine. It modifies the
  1530         -**   second while( 1 ) loop in "ROWS BETWEEN CURRENT ... UNBOUNDED..." to
  1531         -**   be:
  1532         -**
  1533         -**     while( 1 ){
  1534         -**       AggFinal (xValue)
  1535         -**       while( 1 ){
  1536         -**         regPeer++
  1537         -**         Gosub addrGosub
  1538         -**         Next(csr)                     // if EOF goto flush_partition_done
  1539         -**         if( new peer ) break;
  1540         -**       }
  1541         -**       while( (regPeer--)>0 ){
  1542         -**         AggInverse (csrStart)
  1543         -**         Next(csrStart)
  1544         -**       }
  1545         -**     }
  1546         -**
  1547         -** ROWS BETWEEN <expr> FOLLOWING    AND <expr> FOLLOWING
  1548         -**
  1549         -**   regEnd = regEnd - regStart
  1550         -**   Rewind (csr,csrStart,csrEnd)   // if EOF goto flush_partition_done
  1551         -**     Aggstep (csrEnd)
  1552         -**     Next(csrEnd)                 // if EOF fall-through
  1553         -**     if( (regEnd--)<=0 ){
  1554         -**       if( (regStart--)<=0 ){
  1555         -**         AggFinal (xValue)
  1556         -**         Gosub addrGosub
  1557         -**         Next(csr)              // if EOF goto flush_partition_done
  1558         -**       }
  1559         -**       AggInverse (csrStart)
  1560         -**       Next (csrStart)
  1561         -**     }
  1562         -**
  1563         -** ROWS BETWEEN <expr> PRECEDING    AND <expr> PRECEDING
  1564         -**
  1565         -**   Replace the bit after "Rewind" in the above with:
  1566         -**
  1567         -**     if( (regEnd--)<=0 ){
  1568         -**       AggStep (csrEnd)
  1569         -**       Next (csrEnd)
  1570         -**     }
  1571         -**     AggFinal (xValue)
  1572         -**     Gosub addrGosub
  1573         -**     Next(csr)                  // if EOF goto flush_partition_done
  1574         -**     if( (regStart--)<=0 ){
  1575         -**       AggInverse (csr2)
  1576         -**       Next (csr2)
  1577         -**     }
  1578         -**
         1855  +** Helper function for sqlite3WindowCodeStep(). Each call to this function
         1856  +** generates VM code for a single RETURN_ROW, AGGSTEP or AGGINVERSE 
         1857  +** operation. Refer to the header comment for sqlite3WindowCodeStep() for
         1858  +** details.
  1579   1859   */
  1580         -static void windowCodeRowExprStep(
  1581         -  Parse *pParse, 
  1582         -  Select *p,
  1583         -  WhereInfo *pWInfo,
  1584         -  int regGosub, 
  1585         -  int addrGosub
         1860  +static int windowCodeOp(
         1861  + WindowCodeArg *p,                /* Context object */
         1862  + int op,                          /* WINDOW_RETURN_ROW, AGGSTEP or AGGINVERSE */
         1863  + int regCountdown,                /* Register for OP_IfPos countdown */
         1864  + int jumpOnEof                    /* Jump here if stepped cursor reaches EOF */
  1586   1865   ){
  1587         -  Window *pMWin = p->pWin;
  1588         -  Vdbe *v = sqlite3GetVdbe(pParse);
  1589         -  int regFlushPart;               /* Register for "Gosub flush_partition" */
  1590         -  int lblFlushPart;               /* Label for "Gosub flush_partition" */
  1591         -  int lblFlushDone;               /* Label for "Gosub flush_partition_done" */
  1592         -
  1593         -  int regArg;
  1594         -  int addr;
  1595         -  int csrStart = pParse->nTab++;
  1596         -  int csrEnd = pParse->nTab++;
  1597         -  int regStart;                    /* Value of <expr> PRECEDING */
  1598         -  int regEnd;                      /* Value of <expr> FOLLOWING */
  1599         -  int addrGoto;
  1600         -  int addrTop;
  1601         -  int addrIfPos1 = 0;
  1602         -  int addrIfPos2 = 0;
  1603         -  int regSize = 0;
  1604         -
  1605         -  assert( pMWin->eStart==TK_PRECEDING 
  1606         -       || pMWin->eStart==TK_CURRENT 
  1607         -       || pMWin->eStart==TK_FOLLOWING 
  1608         -       || pMWin->eStart==TK_UNBOUNDED 
  1609         -  );
  1610         -  assert( pMWin->eEnd==TK_FOLLOWING 
  1611         -       || pMWin->eEnd==TK_CURRENT 
  1612         -       || pMWin->eEnd==TK_UNBOUNDED 
  1613         -       || pMWin->eEnd==TK_PRECEDING 
  1614         -  );
  1615         -
  1616         -  /* Allocate register and label for the "flush_partition" sub-routine. */
  1617         -  regFlushPart = ++pParse->nMem;
  1618         -  lblFlushPart = sqlite3VdbeMakeLabel(pParse);
  1619         -  lblFlushDone = sqlite3VdbeMakeLabel(pParse);
  1620         -
  1621         -  regStart = ++pParse->nMem;
  1622         -  regEnd = ++pParse->nMem;
  1623         -
  1624         -  windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, &regSize);
  1625         -
  1626         -  addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
  1627         -
  1628         -  /* Start of "flush_partition" */
  1629         -  sqlite3VdbeResolveLabel(v, lblFlushPart);
  1630         -  sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+3);
  1631         -  VdbeCoverage(v);
  1632         -  VdbeComment((v, "Flush_partition subroutine"));
  1633         -  sqlite3VdbeAddOp2(v, OP_OpenDup, csrStart, pMWin->iEphCsr);
  1634         -  sqlite3VdbeAddOp2(v, OP_OpenDup, csrEnd, pMWin->iEphCsr);
  1635         -
  1636         -  /* If either regStart or regEnd are not non-negative integers, throw 
  1637         -  ** an exception.  */
  1638         -  if( pMWin->pStart ){
  1639         -    sqlite3ExprCode(pParse, pMWin->pStart, regStart);
  1640         -    windowCheckIntValue(pParse, regStart, 0);
  1641         -  }
  1642         -  if( pMWin->pEnd ){
  1643         -    sqlite3ExprCode(pParse, pMWin->pEnd, regEnd);
  1644         -    windowCheckIntValue(pParse, regEnd, 1);
  1645         -  }
  1646         -
  1647         -  /* If this is "ROWS <expr1> FOLLOWING AND ROWS <expr2> FOLLOWING", do:
  1648         -  **
  1649         -  **   if( regEnd<regStart ){
  1650         -  **     // The frame always consists of 0 rows
  1651         -  **     regStart = regSize;
  1652         -  **   }
  1653         -  **   regEnd = regEnd - regStart;
  1654         -  */
  1655         -  if( pMWin->pEnd && pMWin->eStart==TK_FOLLOWING ){
  1656         -    assert( pMWin->pStart!=0 );
  1657         -    assert( pMWin->eEnd==TK_FOLLOWING );
  1658         -    sqlite3VdbeAddOp3(v, OP_Ge, regStart, sqlite3VdbeCurrentAddr(v)+2, regEnd);
  1659         -    VdbeCoverageNeverNull(v);
  1660         -    sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart);
  1661         -    sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regEnd);
  1662         -  }
  1663         -
  1664         -  if( pMWin->pStart && pMWin->eEnd==TK_PRECEDING ){
  1665         -    assert( pMWin->pEnd!=0 );
  1666         -    assert( pMWin->eStart==TK_PRECEDING );
  1667         -    sqlite3VdbeAddOp3(v, OP_Le, regStart, sqlite3VdbeCurrentAddr(v)+3, regEnd);
  1668         -    VdbeCoverageNeverNull(v);
  1669         -    sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart);
  1670         -    sqlite3VdbeAddOp2(v, OP_Copy, regSize, regEnd);
  1671         -  }
  1672         -
  1673         -  /* Initialize the accumulator register for each window function to NULL */
  1674         -  regArg = windowInitAccum(pParse, pMWin);
  1675         -
  1676         -  sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr, lblFlushDone);
  1677         -  VdbeCoverage(v);
  1678         -  sqlite3VdbeAddOp2(v, OP_Rewind, csrStart, lblFlushDone);
  1679         -  VdbeCoverageNeverTaken(v);
  1680         -  sqlite3VdbeChangeP5(v, 1);
  1681         -  sqlite3VdbeAddOp2(v, OP_Rewind, csrEnd, lblFlushDone);
  1682         -  VdbeCoverageNeverTaken(v);
  1683         -  sqlite3VdbeChangeP5(v, 1);
  1684         -
  1685         -  /* Invoke AggStep function for each window function using the row that
  1686         -  ** csrEnd currently points to. Or, if csrEnd is already at EOF,
  1687         -  ** do nothing.  */
  1688         -  addrTop = sqlite3VdbeCurrentAddr(v);
  1689         -  if( pMWin->eEnd==TK_PRECEDING ){
  1690         -    addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1);
         1866  +  int csr, reg;
         1867  +  Parse *pParse = p->pParse;
         1868  +  Window *pMWin = p->pMWin;
         1869  +  int ret = 0;
         1870  +  Vdbe *v = p->pVdbe;
         1871  +  int addrIf = 0; 
         1872  +  int addrContinue = 0;
         1873  +  int addrGoto = 0;
         1874  +  int bPeer = (pMWin->eFrmType!=TK_ROWS);
         1875  +
         1876  +  int lblDone = sqlite3VdbeMakeLabel(pParse);
         1877  +  int addrNextRange = 0;
         1878  +
         1879  +  /* Special case - WINDOW_AGGINVERSE is always a no-op if the frame
         1880  +  ** starts with UNBOUNDED PRECEDING. */
         1881  +  if( op==WINDOW_AGGINVERSE && pMWin->eStart==TK_UNBOUNDED ){
         1882  +    assert( regCountdown==0 && jumpOnEof==0 );
         1883  +    return 0;
         1884  +  }
         1885  +
         1886  +  if( regCountdown>0 ){
         1887  +    if( pMWin->eFrmType==TK_RANGE ){
         1888  +      addrNextRange = sqlite3VdbeCurrentAddr(v);
         1889  +      assert( op==WINDOW_AGGINVERSE || op==WINDOW_AGGSTEP );
         1890  +      if( op==WINDOW_AGGINVERSE ){
         1891  +        if( pMWin->eStart==TK_FOLLOWING ){
         1892  +          windowCodeRangeTest(
         1893  +              p, OP_Le, p->current.csr, regCountdown, p->start.csr, lblDone
         1894  +          );
         1895  +        }else{
         1896  +          windowCodeRangeTest(
         1897  +              p, OP_Ge, p->start.csr, regCountdown, p->current.csr, lblDone
         1898  +          );
         1899  +        }
         1900  +      }else{
         1901  +        windowCodeRangeTest(
         1902  +            p, OP_Gt, p->end.csr, regCountdown, p->current.csr, lblDone
         1903  +        );
         1904  +      }
         1905  +    }else{
         1906  +      addrIf = sqlite3VdbeAddOp3(v, OP_IfPos, regCountdown, 0, 1);
         1907  +      VdbeCoverage(v);
         1908  +    }
         1909  +  }
         1910  +
         1911  +  if( op==WINDOW_RETURN_ROW && pMWin->regStartRowid==0 ){
         1912  +    windowAggFinal(p, 0);
         1913  +  }
         1914  +  addrContinue = sqlite3VdbeCurrentAddr(v);
         1915  +  switch( op ){
         1916  +    case WINDOW_RETURN_ROW:
         1917  +      csr = p->current.csr;
         1918  +      reg = p->current.reg;
         1919  +      windowReturnOneRow(p);
         1920  +      break;
         1921  +
         1922  +    case WINDOW_AGGINVERSE:
         1923  +      csr = p->start.csr;
         1924  +      reg = p->start.reg;
         1925  +      if( pMWin->regStartRowid ){
         1926  +        assert( pMWin->regEndRowid );
         1927  +        sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regStartRowid, 1);
         1928  +      }else{
         1929  +        windowAggStep(pParse, pMWin, csr, 1, p->regArg);
         1930  +      }
         1931  +      break;
         1932  +
         1933  +    default:
         1934  +      assert( op==WINDOW_AGGSTEP );
         1935  +      csr = p->end.csr;
         1936  +      reg = p->end.reg;
         1937  +      if( pMWin->regStartRowid ){
         1938  +        assert( pMWin->regEndRowid );
         1939  +        sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regEndRowid, 1);
         1940  +      }else{
         1941  +        windowAggStep(pParse, pMWin, csr, 0, p->regArg);
         1942  +      }
         1943  +      break;
         1944  +  }
         1945  +
         1946  +  if( op==p->eDelete ){
         1947  +    sqlite3VdbeAddOp1(v, OP_Delete, csr);
         1948  +    sqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION);
         1949  +  }
         1950  +
         1951  +  if( jumpOnEof ){
         1952  +    sqlite3VdbeAddOp2(v, OP_Next, csr, sqlite3VdbeCurrentAddr(v)+2);
         1953  +    VdbeCoverage(v);
         1954  +    ret = sqlite3VdbeAddOp0(v, OP_Goto);
         1955  +  }else{
         1956  +    sqlite3VdbeAddOp2(v, OP_Next, csr, sqlite3VdbeCurrentAddr(v)+1+bPeer);
  1691   1957       VdbeCoverage(v);
  1692         -  }
  1693         -  sqlite3VdbeAddOp2(v, OP_Next, csrEnd, sqlite3VdbeCurrentAddr(v)+2);
  1694         -  VdbeCoverage(v);
  1695         -  addr = sqlite3VdbeAddOp0(v, OP_Goto);
  1696         -  windowAggStep(pParse, pMWin, csrEnd, 0, regArg, regSize);
  1697         -  if( pMWin->eEnd==TK_UNBOUNDED ){
  1698         -    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
  1699         -    sqlite3VdbeJumpHere(v, addr);
  1700         -    addrTop = sqlite3VdbeCurrentAddr(v);
  1701         -  }else{
  1702         -    sqlite3VdbeJumpHere(v, addr);
  1703         -    if( pMWin->eEnd==TK_PRECEDING ){
  1704         -      sqlite3VdbeJumpHere(v, addrIfPos1);
         1958  +    if( bPeer ){
         1959  +      addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
  1705   1960       }
  1706   1961     }
  1707   1962   
  1708         -  if( pMWin->eEnd==TK_FOLLOWING ){
  1709         -    addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1);
  1710         -    VdbeCoverage(v);
  1711         -  }
  1712         -  if( pMWin->eStart==TK_FOLLOWING ){
  1713         -    addrIfPos2 = sqlite3VdbeAddOp3(v, OP_IfPos, regStart, 0 , 1);
  1714         -    VdbeCoverage(v);
  1715         -  }
  1716         -  windowAggFinal(pParse, pMWin, 0);
  1717         -  windowReturnOneRow(pParse, pMWin, regGosub, addrGosub);
  1718         -  sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)+2);
  1719         -  VdbeCoverage(v);
  1720         -  sqlite3VdbeAddOp2(v, OP_Goto, 0, lblFlushDone);
  1721         -  if( pMWin->eStart==TK_FOLLOWING ){
  1722         -    sqlite3VdbeJumpHere(v, addrIfPos2);
  1723         -  }
  1724         -
  1725         -  if( pMWin->eStart==TK_CURRENT 
  1726         -   || pMWin->eStart==TK_PRECEDING 
  1727         -   || pMWin->eStart==TK_FOLLOWING 
  1728         -  ){
  1729         -    int lblSkipInverse = sqlite3VdbeMakeLabel(pParse);;
  1730         -    if( pMWin->eStart==TK_PRECEDING ){
  1731         -      sqlite3VdbeAddOp3(v, OP_IfPos, regStart, lblSkipInverse, 1);
  1732         -      VdbeCoverage(v);
  1733         -    }
  1734         -    if( pMWin->eStart==TK_FOLLOWING ){
  1735         -      sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+2);
  1736         -      VdbeCoverage(v);
  1737         -      sqlite3VdbeAddOp2(v, OP_Goto, 0, lblSkipInverse);
  1738         -    }else{
  1739         -      sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+1);
  1740         -      VdbeCoverageAlwaysTaken(v);
  1741         -    }
  1742         -    windowAggStep(pParse, pMWin, csrStart, 1, regArg, regSize);
  1743         -    sqlite3VdbeResolveLabel(v, lblSkipInverse);
  1744         -  }
  1745         -  if( pMWin->eEnd==TK_FOLLOWING ){
  1746         -    sqlite3VdbeJumpHere(v, addrIfPos1);
  1747         -  }
  1748         -  sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
  1749         -
  1750         -  /* flush_partition_done: */
  1751         -  sqlite3VdbeResolveLabel(v, lblFlushDone);
  1752         -  sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
  1753         -  sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);
  1754         -  VdbeComment((v, "end flush_partition subroutine"));
  1755         -
  1756         -  /* Jump to here to skip over flush_partition */
  1757         -  sqlite3VdbeJumpHere(v, addrGoto);
         1963  +  if( bPeer ){
         1964  +    int nReg = (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);
         1965  +    int regTmp = (nReg ? sqlite3GetTempRange(pParse, nReg) : 0);
         1966  +    windowReadPeerValues(p, csr, regTmp);
         1967  +    windowIfNewPeer(pParse, pMWin->pOrderBy, regTmp, reg, addrContinue);
         1968  +    sqlite3ReleaseTempRange(pParse, regTmp, nReg);
         1969  +  }
         1970  +
         1971  +  if( addrNextRange ){
         1972  +    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNextRange);
         1973  +  }
         1974  +  sqlite3VdbeResolveLabel(v, lblDone);
         1975  +  if( addrGoto ) sqlite3VdbeJumpHere(v, addrGoto);
         1976  +  if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
         1977  +  return ret;
  1758   1978   }
  1759   1979   
  1760         -/*
  1761         -** This function does the work of sqlite3WindowCodeStep() for cases that
  1762         -** would normally be handled by windowCodeDefaultStep() when there are
  1763         -** one or more built-in window-functions that require the entire partition
  1764         -** to be cached in a temp table before any rows can be returned. Additionally.
  1765         -** "RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING" is always handled by
  1766         -** this function.
  1767         -**
  1768         -** Pseudo-code corresponding to the VM code generated by this function
  1769         -** for each type of window follows.
  1770         -**
  1771         -** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  1772         -**
  1773         -**   flush_partition:
  1774         -**     Once {
  1775         -**       OpenDup (iEphCsr -> csrLead)
  1776         -**     }
  1777         -**     Integer ctr 0
  1778         -**     foreach row (csrLead){
  1779         -**       if( new peer ){
  1780         -**         AggFinal (xValue)
  1781         -**         for(i=0; i<ctr; i++){
  1782         -**           Gosub addrGosub
  1783         -**           Next iEphCsr
  1784         -**         }
  1785         -**         Integer ctr 0
  1786         -**       }
  1787         -**       AggStep (csrLead)
  1788         -**       Incr ctr
  1789         -**     }
  1790         -**
  1791         -**     AggFinal (xFinalize)
  1792         -**     for(i=0; i<ctr; i++){
  1793         -**       Gosub addrGosub
  1794         -**       Next iEphCsr
  1795         -**     }
  1796         -**
  1797         -**     ResetSorter (csr)
  1798         -**     Return
  1799         -**
  1800         -** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  1801         -**
  1802         -**   As above, except that the "if( new peer )" branch is always taken.
  1803         -**
  1804         -** RANGE BETWEEN CURRENT ROW AND CURRENT ROW 
  1805         -**
  1806         -**   As above, except that each of the for() loops becomes:
  1807         -**
  1808         -**         for(i=0; i<ctr; i++){
  1809         -**           Gosub addrGosub
  1810         -**           AggInverse (iEphCsr)
  1811         -**           Next iEphCsr
  1812         -**         }
  1813         -**
  1814         -** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
  1815         -**
  1816         -**   flush_partition:
  1817         -**     Once {
  1818         -**       OpenDup (iEphCsr -> csrLead)
  1819         -**     }
  1820         -**     foreach row (csrLead) {
  1821         -**       AggStep (csrLead)
  1822         -**     }
  1823         -**     foreach row (iEphCsr) {
  1824         -**       Gosub addrGosub
  1825         -**     }
  1826         -** 
  1827         -** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
  1828         -**
  1829         -**   flush_partition:
  1830         -**     Once {
  1831         -**       OpenDup (iEphCsr -> csrLead)
  1832         -**     }
  1833         -**     foreach row (csrLead){
  1834         -**       AggStep (csrLead)
  1835         -**     }
  1836         -**     Rewind (csrLead)
  1837         -**     Integer ctr 0
  1838         -**     foreach row (csrLead){
  1839         -**       if( new peer ){
  1840         -**         AggFinal (xValue)
  1841         -**         for(i=0; i<ctr; i++){
  1842         -**           Gosub addrGosub
  1843         -**           AggInverse (iEphCsr)
  1844         -**           Next iEphCsr
  1845         -**         }
  1846         -**         Integer ctr 0
  1847         -**       }
  1848         -**       Incr ctr
  1849         -**     }
  1850         -**
  1851         -**     AggFinal (xFinalize)
  1852         -**     for(i=0; i<ctr; i++){
  1853         -**       Gosub addrGosub
  1854         -**       Next iEphCsr
  1855         -**     }
  1856         -**
  1857         -**     ResetSorter (csr)
  1858         -**     Return
  1859         -*/
  1860         -static void windowCodeCacheStep(
  1861         -  Parse *pParse, 
  1862         -  Select *p,
  1863         -  WhereInfo *pWInfo,
  1864         -  int regGosub, 
  1865         -  int addrGosub
  1866         -){
  1867         -  Window *pMWin = p->pWin;
  1868         -  Vdbe *v = sqlite3GetVdbe(pParse);
  1869         -  int k;
  1870         -  int addr;
  1871         -  ExprList *pPart = pMWin->pPartition;
  1872         -  ExprList *pOrderBy = pMWin->pOrderBy;
  1873         -  int nPeer = pOrderBy ? pOrderBy->nExpr : 0;
  1874         -  int regNewPeer;
  1875         -
  1876         -  int addrGoto;                   /* Address of Goto used to jump flush_par.. */
  1877         -  int addrNext;                   /* Jump here for next iteration of loop */
  1878         -  int regFlushPart;
  1879         -  int lblFlushPart;
  1880         -  int csrLead;
  1881         -  int regCtr;
  1882         -  int regArg;                     /* Register array to martial function args */
  1883         -  int regSize;
  1884         -  int lblEmpty;
  1885         -  int bReverse = pMWin->pOrderBy && pMWin->eStart==TK_CURRENT 
  1886         -          && pMWin->eEnd==TK_UNBOUNDED;
  1887         -
  1888         -  assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT) 
  1889         -       || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED) 
  1890         -       || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT) 
  1891         -       || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED) 
  1892         -  );
  1893         -
  1894         -  lblEmpty = sqlite3VdbeMakeLabel(pParse);
  1895         -  regNewPeer = pParse->nMem+1;
  1896         -  pParse->nMem += nPeer;
  1897         -
  1898         -  /* Allocate register and label for the "flush_partition" sub-routine. */
  1899         -  regFlushPart = ++pParse->nMem;
  1900         -  lblFlushPart = sqlite3VdbeMakeLabel(pParse);
  1901         -
  1902         -  csrLead = pParse->nTab++;
  1903         -  regCtr = ++pParse->nMem;
  1904         -
  1905         -  windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, &regSize);
  1906         -  addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
  1907         -
  1908         -  /* Start of "flush_partition" */
  1909         -  sqlite3VdbeResolveLabel(v, lblFlushPart);
  1910         -  sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+2);
  1911         -  VdbeCoverage(v);
  1912         -  sqlite3VdbeAddOp2(v, OP_OpenDup, csrLead, pMWin->iEphCsr);
  1913         -
  1914         -  /* Initialize the accumulator register for each window function to NULL */
  1915         -  regArg = windowInitAccum(pParse, pMWin);
  1916         -
  1917         -  sqlite3VdbeAddOp2(v, OP_Integer, 0, regCtr);
  1918         -  sqlite3VdbeAddOp2(v, OP_Rewind, csrLead, lblEmpty);
  1919         -  VdbeCoverage(v);
  1920         -  sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr, lblEmpty);
  1921         -  VdbeCoverageNeverTaken(v);
  1922         -
  1923         -  if( bReverse ){
  1924         -    int addr2 = sqlite3VdbeCurrentAddr(v);
  1925         -    windowAggStep(pParse, pMWin, csrLead, 0, regArg, regSize);
  1926         -    sqlite3VdbeAddOp2(v, OP_Next, csrLead, addr2);
  1927         -    VdbeCoverage(v);
  1928         -    sqlite3VdbeAddOp2(v, OP_Rewind, csrLead, lblEmpty);
  1929         -    VdbeCoverageNeverTaken(v);
  1930         -  }
  1931         -  addrNext = sqlite3VdbeCurrentAddr(v);
  1932         -
  1933         -  if( pOrderBy && (pMWin->eEnd==TK_CURRENT || pMWin->eStart==TK_CURRENT) ){
  1934         -    int bCurrent = (pMWin->eStart==TK_CURRENT);
  1935         -    int addrJump = 0;             /* Address of OP_Jump below */
  1936         -    if( pMWin->eType==TK_RANGE ){
  1937         -      int iOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0);
  1938         -      int regPeer = pMWin->regPart + (pPart ? pPart->nExpr : 0);
  1939         -      KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);
  1940         -      for(k=0; k<nPeer; k++){
  1941         -        sqlite3VdbeAddOp3(v, OP_Column, csrLead, iOff+k, regNewPeer+k);
  1942         -      }
  1943         -      addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPeer, regPeer, nPeer);
  1944         -      sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
  1945         -      addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
  1946         -      VdbeCoverage(v);
  1947         -      sqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, nPeer-1);
  1948         -    }
  1949         -
  1950         -    windowReturnRows(pParse, pMWin, regCtr, regGosub, addrGosub, 
  1951         -        (bCurrent ? regArg : 0), (bCurrent ? regSize : 0)
  1952         -    );
  1953         -    if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
  1954         -  }
  1955         -
  1956         -  if( bReverse==0 ){
  1957         -    windowAggStep(pParse, pMWin, csrLead, 0, regArg, regSize);
  1958         -  }
  1959         -  sqlite3VdbeAddOp2(v, OP_AddImm, regCtr, 1);
  1960         -  sqlite3VdbeAddOp2(v, OP_Next, csrLead, addrNext);
  1961         -  VdbeCoverage(v);
  1962         -
  1963         -  windowReturnRows(pParse, pMWin, regCtr, regGosub, addrGosub, 0, 0);
  1964         -
  1965         -  sqlite3VdbeResolveLabel(v, lblEmpty);
  1966         -  sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
  1967         -  sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);
  1968         -
  1969         -  /* Jump to here to skip over flush_partition */
  1970         -  sqlite3VdbeJumpHere(v, addrGoto);
  1971         -}
  1972         -
  1973         -
  1974         -/*
  1975         -** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  1976         -**
  1977         -**   ...
  1978         -**     if( new partition ){
  1979         -**       AggFinal (xFinalize)
  1980         -**       Gosub addrGosub
  1981         -**       ResetSorter eph-table
  1982         -**     }
  1983         -**     else if( new peer ){
  1984         -**       AggFinal (xValue)
  1985         -**       Gosub addrGosub
  1986         -**       ResetSorter eph-table
  1987         -**     }
  1988         -**     AggStep
  1989         -**     Insert (record into eph-table)
  1990         -**   sqlite3WhereEnd()
  1991         -**   AggFinal (xFinalize)
  1992         -**   Gosub addrGosub
  1993         -**
  1994         -** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
  1995         -**
  1996         -**   As above, except take no action for a "new peer". Invoke
  1997         -**   the sub-routine once only for each partition.
  1998         -**
  1999         -** RANGE BETWEEN CURRENT ROW AND CURRENT ROW
  2000         -**
  2001         -**   As above, except that the "new peer" condition is handled in the
  2002         -**   same way as "new partition" (so there is no "else if" block).
  2003         -**
  2004         -** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  2005         -** 
  2006         -**   As above, except assume every row is a "new peer".
  2007         -*/
  2008         -static void windowCodeDefaultStep(
  2009         -  Parse *pParse, 
  2010         -  Select *p,
  2011         -  WhereInfo *pWInfo,
  2012         -  int regGosub, 
  2013         -  int addrGosub
  2014         -){
  2015         -  Window *pMWin = p->pWin;
  2016         -  Vdbe *v = sqlite3GetVdbe(pParse);
  2017         -  int k;
  2018         -  int iSubCsr = p->pSrc->a[0].iCursor;
  2019         -  int nSub = p->pSrc->a[0].pTab->nCol;
  2020         -  int reg = pParse->nMem+1;
  2021         -  int regRecord = reg+nSub;
  2022         -  int regRowid = regRecord+1;
  2023         -  int addr;
  2024         -  ExprList *pPart = pMWin->pPartition;
  2025         -  ExprList *pOrderBy = pMWin->pOrderBy;
  2026         -
  2027         -  assert( pMWin->eType==TK_RANGE 
  2028         -      || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT)
  2029         -  );
  2030         -
  2031         -  assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT)
  2032         -       || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED)
  2033         -       || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT)
  2034         -       || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED && !pOrderBy)
  2035         -  );
  2036         -
  2037         -  if( pMWin->eEnd==TK_UNBOUNDED ){
  2038         -    pOrderBy = 0;
  2039         -  }
  2040         -
  2041         -  pParse->nMem += nSub + 2;
  2042         -
  2043         -  /* Load the individual column values of the row returned by
  2044         -  ** the sub-select into an array of registers. */
  2045         -  for(k=0; k<nSub; k++){
  2046         -    sqlite3VdbeAddOp3(v, OP_Column, iSubCsr, k, reg+k);
  2047         -  }
  2048         -
  2049         -  /* Check if this is the start of a new partition or peer group. */
  2050         -  if( pPart || pOrderBy ){
  2051         -    int nPart = (pPart ? pPart->nExpr : 0);
  2052         -    int addrGoto = 0;
  2053         -    int addrJump = 0;
  2054         -    int nPeer = (pOrderBy ? pOrderBy->nExpr : 0);
  2055         -
  2056         -    if( pPart ){
  2057         -      int regNewPart = reg + pMWin->nBufferCol;
  2058         -      KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
  2059         -      addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart,nPart);
  2060         -      sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
  2061         -      addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
  2062         -      VdbeCoverageEqNe(v);
  2063         -      windowAggFinal(pParse, pMWin, 1);
  2064         -      if( pOrderBy ){
  2065         -        addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
  2066         -      }
  2067         -    }
  2068         -
  2069         -    if( pOrderBy ){
  2070         -      int regNewPeer = reg + pMWin->nBufferCol + nPart;
  2071         -      int regPeer = pMWin->regPart + nPart;
  2072         -
  2073         -      if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
  2074         -      if( pMWin->eType==TK_RANGE ){
  2075         -        KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);
  2076         -        addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPeer, regPeer, nPeer);
  2077         -        sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
  2078         -        addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
  2079         -        VdbeCoverage(v);
  2080         -      }else{
  2081         -        addrJump = 0;
  2082         -      }
  2083         -      windowAggFinal(pParse, pMWin, pMWin->eStart==TK_CURRENT);
  2084         -      if( addrGoto ) sqlite3VdbeJumpHere(v, addrGoto);
  2085         -    }
  2086         -
  2087         -    sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3);
  2088         -    VdbeCoverage(v);
  2089         -    sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
  2090         -    sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1);
  2091         -    VdbeCoverage(v);
  2092         -
  2093         -    sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
  2094         -    sqlite3VdbeAddOp3(
  2095         -        v, OP_Copy, reg+pMWin->nBufferCol, pMWin->regPart, nPart+nPeer-1
  2096         -    );
  2097         -
  2098         -    if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
  2099         -  }
  2100         -
  2101         -  /* Invoke step function for window functions */
  2102         -  windowAggStep(pParse, pMWin, -1, 0, reg, 0);
  2103         -
  2104         -  /* Buffer the current row in the ephemeral table. */
  2105         -  if( pMWin->nBufferCol>0 ){
  2106         -    sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, pMWin->nBufferCol, regRecord);
  2107         -  }else{
  2108         -    sqlite3VdbeAddOp2(v, OP_Blob, 0, regRecord);
  2109         -    sqlite3VdbeAppendP4(v, (void*)"", 0);
  2110         -  }
  2111         -  sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid);
  2112         -  sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid);
  2113         -
  2114         -  /* End the database scan loop. */
  2115         -  sqlite3WhereEnd(pWInfo);
  2116         -
  2117         -  windowAggFinal(pParse, pMWin, 1);
  2118         -  sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3);
  2119         -  VdbeCoverage(v);
  2120         -  sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
  2121         -  sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1);
  2122         -  VdbeCoverage(v);
  2123         -}
  2124   1980   
  2125   1981   /*
  2126   1982   ** Allocate and return a duplicate of the Window object indicated by the
  2127   1983   ** third argument. Set the Window.pOwner field of the new object to
  2128   1984   ** pOwner.
  2129   1985   */
  2130   1986   Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
................................................................................
  2133   1989       pNew = sqlite3DbMallocZero(db, sizeof(Window));
  2134   1990       if( pNew ){
  2135   1991         pNew->zName = sqlite3DbStrDup(db, p->zName);
  2136   1992         pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
  2137   1993         pNew->pFunc = p->pFunc;
  2138   1994         pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
  2139   1995         pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
  2140         -      pNew->eType = p->eType;
         1996  +      pNew->eFrmType = p->eFrmType;
  2141   1997         pNew->eEnd = p->eEnd;
  2142   1998         pNew->eStart = p->eStart;
         1999  +      pNew->eExclude = p->eExclude;
  2143   2000         pNew->pStart = sqlite3ExprDup(db, p->pStart, 0);
  2144   2001         pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0);
  2145   2002         pNew->pOwner = pOwner;
  2146   2003       }
  2147   2004     }
  2148   2005     return pNew;
  2149   2006   }
................................................................................
  2161   2018       *pp = sqlite3WindowDup(db, 0, pWin);
  2162   2019       if( *pp==0 ) break;
  2163   2020       pp = &((*pp)->pNextWin);
  2164   2021     }
  2165   2022   
  2166   2023     return pRet;
  2167   2024   }
         2025  +
         2026  +/*
         2027  +** Return true if it can be determined at compile time that expression 
         2028  +** pExpr evaluates to a value that, when cast to an integer, is greater 
         2029  +** than zero. False otherwise.
         2030  +**
         2031  +** If an OOM error occurs, this function sets the Parse.db.mallocFailed 
         2032  +** flag and returns zero.
         2033  +*/
         2034  +static int windowExprGtZero(Parse *pParse, Expr *pExpr){
         2035  +  int ret = 0;
         2036  +  sqlite3 *db = pParse->db;
         2037  +  sqlite3_value *pVal = 0;
         2038  +  sqlite3ValueFromExpr(db, pExpr, db->enc, SQLITE_AFF_NUMERIC, &pVal);
         2039  +  if( pVal && sqlite3_value_int(pVal)>0 ){
         2040  +    ret = 1;
         2041  +  }
         2042  +  sqlite3ValueFree(pVal);
         2043  +  return ret;
         2044  +}
  2168   2045   
  2169   2046   /*
  2170   2047   ** sqlite3WhereBegin() has already been called for the SELECT statement 
  2171   2048   ** passed as the second argument when this function is invoked. It generates
  2172         -** code to populate the Window.regResult register for each window function and
  2173         -** invoke the sub-routine at instruction addrGosub once for each row.
  2174         -** This function calls sqlite3WhereEnd() before returning. 
         2049  +** code to populate the Window.regResult register for each window function 
         2050  +** and invoke the sub-routine at instruction addrGosub once for each row.
         2051  +** sqlite3WhereEnd() is always called before returning. 
         2052  +**
         2053  +** This function handles several different types of window frames, which
         2054  +** require slightly different processing. The following pseudo code is
         2055  +** used to implement window frames of the form:
         2056  +**
         2057  +**   ROWS BETWEEN <expr1> PRECEDING AND <expr2> FOLLOWING
         2058  +**
         2059  +** Other window frame types use variants of the following:
         2060  +**
         2061  +**     ... loop started by sqlite3WhereBegin() ...
         2062  +**       if( new partition ){
         2063  +**         Gosub flush
         2064  +**       }
         2065  +**       Insert new row into eph table.
         2066  +**       
         2067  +**       if( first row of partition ){
         2068  +**         // Rewind three cursors, all open on the eph table.
         2069  +**         Rewind(csrEnd);
         2070  +**         Rewind(csrStart);
         2071  +**         Rewind(csrCurrent);
         2072  +**       
         2073  +**         regEnd = <expr2>          // FOLLOWING expression
         2074  +**         regStart = <expr1>        // PRECEDING expression
         2075  +**       }else{
         2076  +**         // First time this branch is taken, the eph table contains two 
         2077  +**         // rows. The first row in the partition, which all three cursors
         2078  +**         // currently point to, and the following row.
         2079  +**         AGGSTEP
         2080  +**         if( (regEnd--)<=0 ){
         2081  +**           RETURN_ROW
         2082  +**           if( (regStart--)<=0 ){
         2083  +**             AGGINVERSE
         2084  +**           }
         2085  +**         }
         2086  +**       }
         2087  +**     }
         2088  +**     flush:
         2089  +**       AGGSTEP
         2090  +**       while( 1 ){
         2091  +**         RETURN ROW
         2092  +**         if( csrCurrent is EOF ) break;
         2093  +**         if( (regStart--)<=0 ){
         2094  +**           AggInverse(csrStart)
         2095  +**           Next(csrStart)
         2096  +**         }
         2097  +**       }
         2098  +**
         2099  +** The pseudo-code above uses the following shorthand:
         2100  +**
         2101  +**   AGGSTEP:    invoke the aggregate xStep() function for each window function
         2102  +**               with arguments read from the current row of cursor csrEnd, then
         2103  +**               step cursor csrEnd forward one row (i.e. sqlite3BtreeNext()).
         2104  +**
         2105  +**   RETURN_ROW: return a row to the caller based on the contents of the 
         2106  +**               current row of csrCurrent and the current state of all 
         2107  +**               aggregates. Then step cursor csrCurrent forward one row.
         2108  +**
         2109  +**   AGGINVERSE: invoke the aggregate xInverse() function for each window 
         2110  +**               functions with arguments read from the current row of cursor
         2111  +**               csrStart. Then step csrStart forward one row.
         2112  +**
         2113  +** There are two other ROWS window frames that are handled significantly
         2114  +** differently from the above - "BETWEEN <expr> PRECEDING AND <expr> PRECEDING"
         2115  +** and "BETWEEN <expr> FOLLOWING AND <expr> FOLLOWING". These are special 
         2116  +** cases because they change the order in which the three cursors (csrStart,
         2117  +** csrCurrent and csrEnd) iterate through the ephemeral table. Cases that
         2118  +** use UNBOUNDED or CURRENT ROW are much simpler variations on one of these
         2119  +** three.
         2120  +**
         2121  +**   ROWS BETWEEN <expr1> PRECEDING AND <expr2> PRECEDING
         2122  +**
         2123  +**     ... loop started by sqlite3WhereBegin() ...
         2124  +**       if( new partition ){
         2125  +**         Gosub flush
         2126  +**       }
         2127  +**       Insert new row into eph table.
         2128  +**       if( first row of partition ){
         2129  +**         Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
         2130  +**         regEnd = <expr2>
         2131  +**         regStart = <expr1>
         2132  +**       }else{
         2133  +**         if( (regEnd--)<=0 ){
         2134  +**           AGGSTEP
         2135  +**         }
         2136  +**         RETURN_ROW
         2137  +**         if( (regStart--)<=0 ){
         2138  +**           AGGINVERSE
         2139  +**         }
         2140  +**       }
         2141  +**     }
         2142  +**     flush:
         2143  +**       if( (regEnd--)<=0 ){
         2144  +**         AGGSTEP
         2145  +**       }
         2146  +**       RETURN_ROW
         2147  +**
         2148  +**
         2149  +**   ROWS BETWEEN <expr1> FOLLOWING AND <expr2> FOLLOWING
         2150  +**
         2151  +**     ... loop started by sqlite3WhereBegin() ...
         2152  +**     if( new partition ){
         2153  +**       Gosub flush
         2154  +**     }
         2155  +**     Insert new row into eph table.
         2156  +**     if( first row of partition ){
         2157  +**       Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
         2158  +**       regEnd = <expr2>
         2159  +**       regStart = regEnd - <expr1>
         2160  +**     }else{
         2161  +**       AGGSTEP
         2162  +**       if( (regEnd--)<=0 ){
         2163  +**         RETURN_ROW
         2164  +**       }
         2165  +**       if( (regStart--)<=0 ){
         2166  +**         AGGINVERSE
         2167  +**       }
         2168  +**     }
         2169  +**   }
         2170  +**   flush:
         2171  +**     AGGSTEP
         2172  +**     while( 1 ){
         2173  +**       if( (regEnd--)<=0 ){
         2174  +**         RETURN_ROW
         2175  +**         if( eof ) break;
         2176  +**       }
         2177  +**       if( (regStart--)<=0 ){
         2178  +**         AGGINVERSE
         2179  +**         if( eof ) break
         2180  +**       }
         2181  +**     }
         2182  +**     while( !eof csrCurrent ){
         2183  +**       RETURN_ROW
         2184  +**     }
         2185  +**
         2186  +** For the most part, the patterns above are adapted to support UNBOUNDED by
         2187  +** assuming that it is equivalent to "infinity PRECEDING/FOLLOWING" and
         2188  +** CURRENT ROW by assuming that it is equivilent to "0 PRECEDING/FOLLOWING".
         2189  +** This is optimized of course - branches that will never be taken and
         2190  +** conditions that are always true are omitted from the VM code. The only
         2191  +** exceptional case is:
         2192  +**
         2193  +**   ROWS BETWEEN <expr1> FOLLOWING AND UNBOUNDED FOLLOWING
         2194  +**
         2195  +**     ... loop started by sqlite3WhereBegin() ...
         2196  +**     if( new partition ){
         2197  +**       Gosub flush
         2198  +**     }
         2199  +**     Insert new row into eph table.
         2200  +**     if( first row of partition ){
         2201  +**       Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
         2202  +**       regStart = <expr1>
         2203  +**     }else{
         2204  +**       AGGSTEP
         2205  +**     }
         2206  +**   }
         2207  +**   flush:
         2208  +**     AGGSTEP
         2209  +**     while( 1 ){
         2210  +**       if( (regStart--)<=0 ){
         2211  +**         AGGINVERSE
         2212  +**         if( eof ) break
         2213  +**       }
         2214  +**       RETURN_ROW
         2215  +**     }
         2216  +**     while( !eof csrCurrent ){
         2217  +**       RETURN_ROW
         2218  +**     }
         2219  +**
         2220  +** Also requiring special handling are the cases:
         2221  +**
         2222  +**   ROWS BETWEEN <expr1> PRECEDING AND <expr2> PRECEDING
         2223  +**   ROWS BETWEEN <expr1> FOLLOWING AND <expr2> FOLLOWING
         2224  +**
         2225  +** when (expr1 < expr2). This is detected at runtime, not by this function.
         2226  +** To handle this case, the pseudo-code programs depicted above are modified
         2227  +** slightly to be:
         2228  +**
         2229  +**     ... loop started by sqlite3WhereBegin() ...
         2230  +**     if( new partition ){
         2231  +**       Gosub flush
         2232  +**     }
         2233  +**     Insert new row into eph table.
         2234  +**     if( first row of partition ){
         2235  +**       Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
         2236  +**       regEnd = <expr2>
         2237  +**       regStart = <expr1>
         2238  +**       if( regEnd < regStart ){
         2239  +**         RETURN_ROW
         2240  +**         delete eph table contents
         2241  +**         continue
         2242  +**       }
         2243  +**     ...
         2244  +**
         2245  +** The new "continue" statement in the above jumps to the next iteration
         2246  +** of the outer loop - the one started by sqlite3WhereBegin().
         2247  +**
         2248  +** The various GROUPS cases are implemented using the same patterns as
         2249  +** ROWS. The VM code is modified slightly so that:
         2250  +**
         2251  +**   1. The else branch in the main loop is only taken if the row just
         2252  +**      added to the ephemeral table is the start of a new group. In
         2253  +**      other words, it becomes:
         2254  +**
         2255  +**         ... loop started by sqlite3WhereBegin() ...
         2256  +**         if( new partition ){
         2257  +**           Gosub flush
         2258  +**         }
         2259  +**         Insert new row into eph table.
         2260  +**         if( first row of partition ){
         2261  +**           Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
         2262  +**           regEnd = <expr2>
         2263  +**           regStart = <expr1>
         2264  +**         }else if( new group ){
         2265  +**           ... 
         2266  +**         }
         2267  +**       }
         2268  +**
         2269  +**   2. Instead of processing a single row, each RETURN_ROW, AGGSTEP or 
         2270  +**      AGGINVERSE step processes the current row of the relevant cursor and
         2271  +**      all subsequent rows belonging to the same group.
         2272  +**
         2273  +** RANGE window frames are a little different again. As for GROUPS, the 
         2274  +** main loop runs once per group only. And RETURN_ROW, AGGSTEP and AGGINVERSE
         2275  +** deal in groups instead of rows. As for ROWS and GROUPS, there are three
         2276  +** basic cases:
         2277  +**
         2278  +**   RANGE BETWEEN <expr1> PRECEDING AND <expr2> FOLLOWING
         2279  +**
         2280  +**     ... loop started by sqlite3WhereBegin() ...
         2281  +**       if( new partition ){
         2282  +**         Gosub flush
         2283  +**       }
         2284  +**       Insert new row into eph table.
         2285  +**       if( first row of partition ){
         2286  +**         Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
         2287  +**         regEnd = <expr2>
         2288  +**         regStart = <expr1>
         2289  +**       }else{
         2290  +**         AGGSTEP
         2291  +**         while( (csrCurrent.key + regEnd) < csrEnd.key ){
         2292  +**           RETURN_ROW
         2293  +**           while( csrStart.key + regStart) < csrCurrent.key ){
         2294  +**             AGGINVERSE
         2295  +**           }
         2296  +**         }
         2297  +**       }
         2298  +**     }
         2299  +**     flush:
         2300  +**       AGGSTEP
         2301  +**       while( 1 ){
         2302  +**         RETURN ROW
         2303  +**         if( csrCurrent is EOF ) break;
         2304  +**           while( csrStart.key + regStart) < csrCurrent.key ){
         2305  +**             AGGINVERSE
         2306  +**           }
         2307  +**         }
         2308  +**       }
         2309  +**
         2310  +** In the above notation, "csr.key" means the current value of the ORDER BY 
         2311  +** expression (there is only ever 1 for a RANGE that uses an <expr> FOLLOWING
         2312  +** or <expr PRECEDING) read from cursor csr.
         2313  +**
         2314  +**   RANGE BETWEEN <expr1> PRECEDING AND <expr2> PRECEDING
         2315  +**
         2316  +**     ... loop started by sqlite3WhereBegin() ...
         2317  +**       if( new partition ){
         2318  +**         Gosub flush
         2319  +**       }
         2320  +**       Insert new row into eph table.
         2321  +**       if( first row of partition ){
         2322  +**         Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
         2323  +**         regEnd = <expr2>
         2324  +**         regStart = <expr1>
         2325  +**       }else{
         2326  +**         while( (csrEnd.key + regEnd) <= csrCurrent.key ){
         2327  +**           AGGSTEP
         2328  +**         }
         2329  +**         RETURN_ROW
         2330  +**         while( (csrStart.key + regStart) < csrCurrent.key ){
         2331  +**           AGGINVERSE
         2332  +**         }
         2333  +**       }
         2334  +**     }
         2335  +**     flush:
         2336  +**       while( (csrEnd.key + regEnd) <= csrCurrent.key ){
         2337  +**         AGGSTEP
         2338  +**       }
         2339  +**       RETURN_ROW
         2340  +**
         2341  +**   RANGE BETWEEN <expr1> FOLLOWING AND <expr2> FOLLOWING
         2342  +**
         2343  +**     ... loop started by sqlite3WhereBegin() ...
         2344  +**       if( new partition ){
         2345  +**         Gosub flush
         2346  +**       }
         2347  +**       Insert new row into eph table.
         2348  +**       if( first row of partition ){
         2349  +**         Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
         2350  +**         regEnd = <expr2>
         2351  +**         regStart = <expr1>
         2352  +**       }else{
         2353  +**         AGGSTEP
         2354  +**         while( (csrCurrent.key + regEnd) < csrEnd.key ){
         2355  +**           while( (csrCurrent.key + regStart) > csrStart.key ){
         2356  +**             AGGINVERSE
         2357  +**           }
         2358  +**           RETURN_ROW
         2359  +**         }
         2360  +**       }
         2361  +**     }
         2362  +**     flush:
         2363  +**       AGGSTEP
         2364  +**       while( 1 ){
         2365  +**         while( (csrCurrent.key + regStart) > csrStart.key ){
         2366  +**           AGGINVERSE
         2367  +**           if( eof ) break "while( 1 )" loop.
         2368  +**         }
         2369  +**         RETURN_ROW
         2370  +**       }
         2371  +**       while( !eof csrCurrent ){
         2372  +**         RETURN_ROW
         2373  +**       }
         2374  +**
         2375  +** The text above leaves out many details. Refer to the code and comments
         2376  +** below for a more complete picture.
  2175   2377   */
  2176   2378   void sqlite3WindowCodeStep(
  2177   2379     Parse *pParse,                  /* Parse context */
  2178   2380     Select *p,                      /* Rewritten SELECT statement */
  2179   2381     WhereInfo *pWInfo,              /* Context returned by sqlite3WhereBegin() */
  2180   2382     int regGosub,                   /* Register for OP_Gosub */
  2181   2383     int addrGosub                   /* OP_Gosub here to return each row */
  2182   2384   ){
  2183   2385     Window *pMWin = p->pWin;
         2386  +  ExprList *pOrderBy = pMWin->pOrderBy;
         2387  +  Vdbe *v = sqlite3GetVdbe(pParse);
         2388  +  int csrWrite;                   /* Cursor used to write to eph. table */
         2389  +  int csrInput = p->pSrc->a[0].iCursor;     /* Cursor of sub-select */
         2390  +  int nInput = p->pSrc->a[0].pTab->nCol;    /* Number of cols returned by sub */
         2391  +  int iInput;                               /* To iterate through sub cols */
         2392  +  int addrNe;                     /* Address of OP_Ne */
         2393  +  int addrGosubFlush = 0;         /* Address of OP_Gosub to flush: */
         2394  +  int addrInteger = 0;            /* Address of OP_Integer */
         2395  +  int addrEmpty;                  /* Address of OP_Rewind in flush: */
         2396  +  int regStart = 0;               /* Value of <expr> PRECEDING */
         2397  +  int regEnd = 0;                 /* Value of <expr> FOLLOWING */
         2398  +  int regNew;                     /* Array of registers holding new input row */
         2399  +  int regRecord;                  /* regNew array in record form */
         2400  +  int regRowid;                   /* Rowid for regRecord in eph table */
         2401  +  int regNewPeer = 0;             /* Peer values for new row (part of regNew) */
         2402  +  int regPeer = 0;                /* Peer values for current row */
         2403  +  int regFlushPart = 0;           /* Register for "Gosub flush_partition" */
         2404  +  WindowCodeArg s;                /* Context object for sub-routines */
         2405  +  int lblWhereEnd;                /* Label just before sqlite3WhereEnd() code */
         2406  +
         2407  +  assert( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_CURRENT 
         2408  +       || pMWin->eStart==TK_FOLLOWING || pMWin->eStart==TK_UNBOUNDED 
         2409  +  );
         2410  +  assert( pMWin->eEnd==TK_FOLLOWING || pMWin->eEnd==TK_CURRENT 
         2411  +       || pMWin->eEnd==TK_UNBOUNDED || pMWin->eEnd==TK_PRECEDING 
         2412  +  );
         2413  +  assert( pMWin->eExclude==0 || pMWin->eExclude==TK_CURRENT
         2414  +       || pMWin->eExclude==TK_GROUP || pMWin->eExclude==TK_TIES
         2415  +       || pMWin->eExclude==TK_NO
         2416  +  );
         2417  +
         2418  +  lblWhereEnd = sqlite3VdbeMakeLabel(pParse);
         2419  +
         2420  +  /* Fill in the context object */
         2421  +  memset(&s, 0, sizeof(WindowCodeArg));
         2422  +  s.pParse = pParse;
         2423  +  s.pMWin = pMWin;
         2424  +  s.pVdbe = v;
         2425  +  s.regGosub = regGosub;
         2426  +  s.addrGosub = addrGosub;
         2427  +  s.current.csr = pMWin->iEphCsr;
         2428  +  csrWrite = s.current.csr+1;
         2429  +  s.start.csr = s.current.csr+2;
         2430  +  s.end.csr = s.current.csr+3;
         2431  +
         2432  +  /* Figure out when rows may be deleted from the ephemeral table. There
         2433  +  ** are four options - they may never be deleted (eDelete==0), they may 
         2434  +  ** be deleted as soon as they are no longer part of the window frame
         2435  +  ** (eDelete==WINDOW_AGGINVERSE), they may be deleted as after the row 
         2436  +  ** has been returned to the caller (WINDOW_RETURN_ROW), or they may
         2437  +  ** be deleted after they enter the frame (WINDOW_AGGSTEP). */
         2438  +  switch( pMWin->eStart ){
         2439  +    case TK_FOLLOWING:
         2440  +      if( pMWin->eFrmType!=TK_RANGE
         2441  +       && windowExprGtZero(pParse, pMWin->pStart)
         2442  +      ){
         2443  +        s.eDelete = WINDOW_RETURN_ROW;
         2444  +      }
         2445  +      break;
         2446  +    case TK_UNBOUNDED:
         2447  +      if( windowCacheFrame(pMWin)==0 ){
         2448  +        if( pMWin->eEnd==TK_PRECEDING ){
         2449  +          if( pMWin->eFrmType!=TK_RANGE
         2450  +           && windowExprGtZero(pParse, pMWin->pEnd)
         2451  +          ){
         2452  +            s.eDelete = WINDOW_AGGSTEP;
         2453  +          }
         2454  +        }else{
         2455  +          s.eDelete = WINDOW_RETURN_ROW;
         2456  +        }
         2457  +      }
         2458  +      break;
         2459  +    default:
         2460  +      s.eDelete = WINDOW_AGGINVERSE;
         2461  +      break;
         2462  +  }
         2463  +
         2464  +  /* Allocate registers for the array of values from the sub-query, the
         2465  +  ** samve values in record form, and the rowid used to insert said record
         2466  +  ** into the ephemeral table.  */
         2467  +  regNew = pParse->nMem+1;
         2468  +  pParse->nMem += nInput;
         2469  +  regRecord = ++pParse->nMem;
         2470  +  regRowid = ++pParse->nMem;
         2471  +
         2472  +  /* If the window frame contains an "<expr> PRECEDING" or "<expr> FOLLOWING"
         2473  +  ** clause, allocate registers to store the results of evaluating each
         2474  +  ** <expr>.  */
         2475  +  if( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_FOLLOWING ){
         2476  +    regStart = ++pParse->nMem;
         2477  +  }
         2478  +  if( pMWin->eEnd==TK_PRECEDING || pMWin->eEnd==TK_FOLLOWING ){
         2479  +    regEnd = ++pParse->nMem;
         2480  +  }
         2481  +
         2482  +  /* If this is not a "ROWS BETWEEN ..." frame, then allocate arrays of
         2483  +  ** registers to store copies of the ORDER BY expressions (peer values) 
         2484  +  ** for the main loop, and for each cursor (start, current and end). */
         2485  +  if( pMWin->eFrmType!=TK_ROWS ){
         2486  +    int nPeer = (pOrderBy ? pOrderBy->nExpr : 0);
         2487  +    regNewPeer = regNew + pMWin->nBufferCol;
         2488  +    if( pMWin->pPartition ) regNewPeer += pMWin->pPartition->nExpr;
         2489  +    regPeer = pParse->nMem+1;       pParse->nMem += nPeer;
         2490  +    s.start.reg = pParse->nMem+1;   pParse->nMem += nPeer;
         2491  +    s.current.reg = pParse->nMem+1; pParse->nMem += nPeer;
         2492  +    s.end.reg = pParse->nMem+1;     pParse->nMem += nPeer;
         2493  +  }
         2494  +
         2495  +  /* Load the column values for the row returned by the sub-select
         2496  +  ** into an array of registers starting at regNew. Assemble them into
         2497  +  ** a record in register regRecord. */
         2498  +  for(iInput=0; iInput<nInput; iInput++){
         2499  +    sqlite3VdbeAddOp3(v, OP_Column, csrInput, iInput, regNew+iInput);
         2500  +  }
         2501  +  sqlite3VdbeAddOp3(v, OP_MakeRecord, regNew, nInput, regRecord);
         2502  +
         2503  +  /* An input row has just been read into an array of registers starting
         2504  +  ** at regNew. If the window has a PARTITION clause, this block generates 
         2505  +  ** VM code to check if the input row is the start of a new partition.
         2506  +  ** If so, it does an OP_Gosub to an address to be filled in later. The
         2507  +  ** address of the OP_Gosub is stored in local variable addrGosubFlush. */
         2508  +  if( pMWin->pPartition ){
         2509  +    int addr;
         2510  +    ExprList *pPart = pMWin->pPartition;
         2511  +    int nPart = pPart->nExpr;
         2512  +    int regNewPart = regNew + pMWin->nBufferCol;
         2513  +    KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
         2514  +
         2515  +    regFlushPart = ++pParse->nMem;
         2516  +    addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart, nPart);
         2517  +    sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
         2518  +    sqlite3VdbeAddOp3(v, OP_Jump, addr+2, addr+4, addr+2);
         2519  +    VdbeCoverageEqNe(v);
         2520  +    addrGosubFlush = sqlite3VdbeAddOp1(v, OP_Gosub, regFlushPart);
         2521  +    VdbeComment((v, "call flush_partition"));
         2522  +    sqlite3VdbeAddOp3(v, OP_Copy, regNewPart, pMWin->regPart, nPart-1);
         2523  +  }
         2524  +
         2525  +  /* Insert the new row into the ephemeral table */
         2526  +  sqlite3VdbeAddOp2(v, OP_NewRowid, csrWrite, regRowid);
         2527  +  sqlite3VdbeAddOp3(v, OP_Insert, csrWrite, regRecord, regRowid);
         2528  +  addrNe = sqlite3VdbeAddOp3(v, OP_Ne, pMWin->regOne, 0, regRowid);
         2529  +  VdbeCoverageNeverNull(v);
         2530  +
         2531  +  /* This block is run for the first row of each partition */
         2532  +  s.regArg = windowInitAccum(pParse, pMWin);
         2533  +
         2534  +  if( regStart ){
         2535  +    sqlite3ExprCode(pParse, pMWin->pStart, regStart);
         2536  +    windowCheckValue(pParse, regStart, 0 + (pMWin->eFrmType==TK_RANGE ? 3 : 0));
         2537  +  }
         2538  +  if( regEnd ){
         2539  +    sqlite3ExprCode(pParse, pMWin->pEnd, regEnd);
         2540  +    windowCheckValue(pParse, regEnd, 1 + (pMWin->eFrmType==TK_RANGE ? 3 : 0));
         2541  +  }
         2542  +
         2543  +  if( pMWin->eStart==pMWin->eEnd && regStart ){
         2544  +    int op = ((pMWin->eStart==TK_FOLLOWING) ? OP_Ge : OP_Le);
         2545  +    int addrGe = sqlite3VdbeAddOp3(v, op, regStart, 0, regEnd);
         2546  +    VdbeCoverageNeverNullIf(v, op==OP_Ge); /* NeverNull because bound <expr> */
         2547  +    VdbeCoverageNeverNullIf(v, op==OP_Le); /*   values previously checked */
         2548  +    windowAggFinal(&s, 0);
         2549  +    sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1);
         2550  +    VdbeCoverageNeverTaken(v);
         2551  +    windowReturnOneRow(&s);
         2552  +    sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr);
         2553  +    sqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd);
         2554  +    sqlite3VdbeJumpHere(v, addrGe);
         2555  +  }
         2556  +  if( pMWin->eStart==TK_FOLLOWING && pMWin->eFrmType!=TK_RANGE && regEnd ){
         2557  +    assert( pMWin->eEnd==TK_FOLLOWING );
         2558  +    sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regStart);
         2559  +  }
         2560  +
         2561  +  if( pMWin->eStart!=TK_UNBOUNDED ){
         2562  +    sqlite3VdbeAddOp2(v, OP_Rewind, s.start.csr, 1);
         2563  +    VdbeCoverageNeverTaken(v);
         2564  +  }
         2565  +  sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1);
         2566  +  VdbeCoverageNeverTaken(v);
         2567  +  sqlite3VdbeAddOp2(v, OP_Rewind, s.end.csr, 1);
         2568  +  VdbeCoverageNeverTaken(v);
         2569  +  if( regPeer && pOrderBy ){
         2570  +    sqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, pOrderBy->nExpr-1);
         2571  +    sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.start.reg, pOrderBy->nExpr-1);
         2572  +    sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.current.reg, pOrderBy->nExpr-1);
         2573  +    sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.end.reg, pOrderBy->nExpr-1);
         2574  +  }
  2184   2575   
  2185         -  /* There are three different functions that may be used to do the work
  2186         -  ** of this one, depending on the window frame and the specific built-in
  2187         -  ** window functions used (if any).
  2188         -  **
  2189         -  ** windowCodeRowExprStep() handles all "ROWS" window frames, except for:
  2190         -  **
  2191         -  **   ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  2192         -  **
  2193         -  ** The exception is because windowCodeRowExprStep() implements all window
  2194         -  ** frame types by caching the entire partition in a temp table, and
  2195         -  ** "ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW" is easy enough to
  2196         -  ** implement without such a cache.
  2197         -  **
  2198         -  ** windowCodeCacheStep() is used for:
  2199         -  **
  2200         -  **   RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
  2201         -  **
  2202         -  ** It is also used for anything not handled by windowCodeRowExprStep() 
  2203         -  ** that invokes a built-in window function that requires the entire 
  2204         -  ** partition to be cached in a temp table before any rows are returned
  2205         -  ** (e.g. nth_value() or percent_rank()).
  2206         -  **
  2207         -  ** Finally, assuming there is no built-in window function that requires
  2208         -  ** the partition to be cached, windowCodeDefaultStep() is used for:
  2209         -  **
  2210         -  **   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
  2211         -  **   RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
  2212         -  **   RANGE BETWEEN CURRENT ROW AND CURRENT ROW 
  2213         -  **   ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  2214         -  **
  2215         -  ** windowCodeDefaultStep() is the only one of the three functions that
  2216         -  ** does not cache each partition in a temp table before beginning to
  2217         -  ** return rows.
  2218         -  */
  2219         -  if( pMWin->eType==TK_ROWS 
  2220         -   && (pMWin->eStart!=TK_UNBOUNDED||pMWin->eEnd!=TK_CURRENT||!pMWin->pOrderBy)
  2221         -  ){
  2222         -    VdbeModuleComment((pParse->pVdbe, "Begin RowExprStep()"));
  2223         -    windowCodeRowExprStep(pParse, p, pWInfo, regGosub, addrGosub);
  2224         -  }else{
  2225         -    Window *pWin;
  2226         -    int bCache = 0;               /* True to use CacheStep() */
         2576  +  sqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd);
  2227   2577   
  2228         -    if( pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED ){
  2229         -      bCache = 1;
  2230         -    }else{
  2231         -      for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
  2232         -        FuncDef *pFunc = pWin->pFunc;
  2233         -        if( (pFunc->funcFlags & SQLITE_FUNC_WINDOW_SIZE)
  2234         -         || (pFunc->zName==nth_valueName)
  2235         -         || (pFunc->zName==first_valueName)
  2236         -         || (pFunc->zName==leadName)
  2237         -         || (pFunc->zName==lagName)
  2238         -        ){
  2239         -          bCache = 1;
  2240         -          break;
         2578  +  sqlite3VdbeJumpHere(v, addrNe);
         2579  +  if( regPeer ){
         2580  +    windowIfNewPeer(pParse, pOrderBy, regNewPeer, regPeer, lblWhereEnd);
         2581  +  }
         2582  +  if( pMWin->eStart==TK_FOLLOWING ){
         2583  +    windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
         2584  +    if( pMWin->eEnd!=TK_UNBOUNDED ){
         2585  +      if( pMWin->eFrmType==TK_RANGE ){
         2586  +        int lbl = sqlite3VdbeMakeLabel(pParse);
         2587  +        int addrNext = sqlite3VdbeCurrentAddr(v);
         2588  +        windowCodeRangeTest(&s, OP_Ge, s.current.csr, regEnd, s.end.csr, lbl);
         2589  +        windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
         2590  +        windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
         2591  +        sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext);
         2592  +        sqlite3VdbeResolveLabel(v, lbl);
         2593  +      }else{
         2594  +        windowCodeOp(&s, WINDOW_RETURN_ROW, regEnd, 0);
         2595  +        windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
         2596  +      }
         2597  +    }
         2598  +  }else
         2599  +  if( pMWin->eEnd==TK_PRECEDING ){
         2600  +    windowCodeOp(&s, WINDOW_AGGSTEP, regEnd, 0);
         2601  +    windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
         2602  +    windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
         2603  +  }else{
         2604  +    int addr = 0;
         2605  +    windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
         2606  +    if( pMWin->eEnd!=TK_UNBOUNDED ){
         2607  +      if( pMWin->eFrmType==TK_RANGE ){
         2608  +        int lbl = 0;
         2609  +        addr = sqlite3VdbeCurrentAddr(v);
         2610  +        if( regEnd ){
         2611  +          lbl = sqlite3VdbeMakeLabel(pParse);
         2612  +          windowCodeRangeTest(&s, OP_Ge, s.current.csr, regEnd, s.end.csr, lbl);
         2613  +        }
         2614  +        windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
         2615  +        windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
         2616  +        if( regEnd ){
         2617  +          sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
         2618  +          sqlite3VdbeResolveLabel(v, lbl);
         2619  +        }
         2620  +      }else{
         2621  +        if( regEnd ){
         2622  +          addr = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0, 1);
         2623  +          VdbeCoverage(v);
  2241   2624           }
         2625  +        windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
         2626  +        windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
         2627  +        if( regEnd ) sqlite3VdbeJumpHere(v, addr);
  2242   2628         }
  2243   2629       }
         2630  +  }
         2631  +
         2632  +  /* End of the main input loop */
         2633  +  sqlite3VdbeResolveLabel(v, lblWhereEnd);
         2634  +  sqlite3WhereEnd(pWInfo);
         2635  +
         2636  +  /* Fall through */
         2637  +  if( pMWin->pPartition ){
         2638  +    addrInteger = sqlite3VdbeAddOp2(v, OP_Integer, 0, regFlushPart);
         2639  +    sqlite3VdbeJumpHere(v, addrGosubFlush);
         2640  +  }
  2244   2641   
  2245         -    /* Otherwise, call windowCodeDefaultStep().  */
  2246         -    if( bCache ){
  2247         -      VdbeModuleComment((pParse->pVdbe, "Begin CacheStep()"));
  2248         -      windowCodeCacheStep(pParse, p, pWInfo, regGosub, addrGosub);
         2642  +  addrEmpty = sqlite3VdbeAddOp1(v, OP_Rewind, csrWrite);
         2643  +  VdbeCoverage(v);
         2644  +  if( pMWin->eEnd==TK_PRECEDING ){
         2645  +    windowCodeOp(&s, WINDOW_AGGSTEP, regEnd, 0);
         2646  +    windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
         2647  +  }else if( pMWin->eStart==TK_FOLLOWING ){
         2648  +    int addrStart;
         2649  +    int addrBreak1;
         2650  +    int addrBreak2;
         2651  +    int addrBreak3;
         2652  +    windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
         2653  +    if( pMWin->eFrmType==TK_RANGE ){
         2654  +      addrStart = sqlite3VdbeCurrentAddr(v);
         2655  +      addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 1);
         2656  +      addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1);
         2657  +    }else
         2658  +    if( pMWin->eEnd==TK_UNBOUNDED ){
         2659  +      addrStart = sqlite3VdbeCurrentAddr(v);
         2660  +      addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, regStart, 1);
         2661  +      addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, 0, 1);
  2249   2662       }else{
  2250         -      VdbeModuleComment((pParse->pVdbe, "Begin DefaultStep()"));
  2251         -      windowCodeDefaultStep(pParse, p, pWInfo, regGosub, addrGosub);
         2663  +      assert( pMWin->eEnd==TK_FOLLOWING );
         2664  +      addrStart = sqlite3VdbeCurrentAddr(v);
         2665  +      addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, regEnd, 1);
         2666  +      addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 1);
         2667  +    }
         2668  +    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart);
         2669  +    sqlite3VdbeJumpHere(v, addrBreak2);
         2670  +    addrStart = sqlite3VdbeCurrentAddr(v);
         2671  +    addrBreak3 = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1);
         2672  +    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart);
         2673  +    sqlite3VdbeJumpHere(v, addrBreak1);
         2674  +    sqlite3VdbeJumpHere(v, addrBreak3);
         2675  +  }else{
         2676  +    int addrBreak;
         2677  +    int addrStart;
         2678  +    windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
         2679  +    addrStart = sqlite3VdbeCurrentAddr(v);
         2680  +    addrBreak = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1);
         2681  +    windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
         2682  +    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart);
         2683  +    sqlite3VdbeJumpHere(v, addrBreak);
         2684  +  }
         2685  +  sqlite3VdbeJumpHere(v, addrEmpty);
         2686  +
         2687  +  sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr);
         2688  +  if( pMWin->pPartition ){
         2689  +    if( pMWin->regStartRowid ){
         2690  +      sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regStartRowid);
         2691  +      sqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regEndRowid);
  2252   2692       }
         2693  +    sqlite3VdbeChangeP1(v, addrInteger, sqlite3VdbeCurrentAddr(v));
         2694  +    sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);
  2253   2695     }
  2254   2696   }
  2255   2697   
  2256   2698   #endif /* SQLITE_OMIT_WINDOWFUNC */

Changes to test/bestindex1.test.

   261    261     WHERE a.FlagA=0 AND a.ColumnA IN ('ValueA', 'ValueB') 
   262    262   } {
   263    263     1 0 ValueA 1 0 ValueA
   264    264     2 0 ValueA 2 0 ValueA
   265    265     3 0 ValueB 3 0 ValueB
   266    266     4 0 ValueB 4 0 ValueB
   267    267   }
          268  +
          269  +#-------------------------------------------------------------------------
          270  +# If there is an IN(..) condition in the WHERE clause of a query on a
          271  +# virtual table, the xBestIndex method is first invoked with the IN(...)
          272  +# represented by a "usable" SQLITE_INDEX_CONSTRAINT_EQ constraint. If
          273  +# the virtual table elects to use the IN(...) constraint, then the 
          274  +# xBestIndex method is invoked again, this time with the IN(...) marked
          275  +# as "not usable". Depending on the relative costs of the two plans as
          276  +# defined by the virtual table implementation, and the cardinality of the
          277  +# IN(...) operator, SQLite chooses the most efficient plan. 
          278  +#
          279  +# At one point the second invocation of xBestIndex() was only being made
          280  +# for join queries. The following tests check that this problem has been
          281  +# fixed.
          282  +#
          283  +proc vtab_command {method args} {
          284  +  switch -- $method {
          285  +    xConnect {
          286  +      return "CREATE TABLE t1(a, b, c, d)"
          287  +    }
          288  +
          289  +    xBestIndex {
          290  +      set clist [lindex $args 0]
          291  +      lappend ::bestindex_calls $clist
          292  +      set ret "cost 1000000 idxnum 555"
          293  +      for {set i 0} {$i < [llength $clist]} {incr i} {
          294  +        array set C [lindex $clist $i]
          295  +        if {$C(usable)} { lappend ret use $i }
          296  +      }
          297  +      return $ret
          298  +    }
          299  +  }
          300  +  return {}
          301  +}
          302  +
          303  +do_execsql_test 4.0 {
          304  +  CREATE VIRTUAL TABLE x1 USING tcl(vtab_command);
          305  +} {}
          306  +
          307  +do_test 4.1 {
          308  +  set ::bestindex_calls [list]
          309  +  execsql {
          310  +    SELECT * FROM x1 WHERE a=? AND b BETWEEN ? AND ? AND c IN (1, 2, 3, 4);
          311  +  }
          312  +  set ::bestindex_calls
          313  +} [list \
          314  +    [list {op eq column 0 usable 1} \
          315  +          {op eq column 2 usable 1} \
          316  +          {op ge column 1 usable 1} \
          317  +          {op le column 1 usable 1} \
          318  +    ] \
          319  +    [list {op eq column 0 usable 1} \
          320  +          {op eq column 2 usable 0} \
          321  +          {op ge column 1 usable 1} \
          322  +          {op le column 1 usable 1}
          323  +    ]
          324  +]
   268    325   
   269    326   
   270    327   finish_test

Changes to test/createtab.test.

     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this file is testing that it is OK to create new tables
    13     13   # and indices while creating existing tables and indices.
    14     14   #
    15         -# $Id: createtab.test,v 1.3 2007/09/12 17:01:45 danielk1977 Exp $
    16     15   
    17     16   set testdir [file dirname $argv0]
    18     17   source $testdir/tester.tcl
    19     18   
    20     19   ifcapable autovacuum {
    21     20     set upperBound 2
    22     21   } else {
................................................................................
   138    137       execsql {
   139    138         SELECT name FROM sqlite_master WHERE type='table' ORDER BY 1
   140    139       }
   141    140     } {t1 t2 t3 t4}
   142    141     integrity_check createtab-$av.40
   143    142   
   144    143   }
          144  +
          145  +# 2019-03-31 Ensure that a proper error is returned for an index
          146  +# with too many columns.
          147  +#
          148  +do_test createtab-3.1 {
          149  +  db eval {DROP TABLE IF EXISTS t1;}
          150  +  set sql "CREATE TABLE t1(x,UNIQUE(x[string repeat ,x 100000]))"
          151  +  catchsql $sql
          152  +} {1 {too many columns in index}}
   145    153     
   146    154   finish_test

Changes to test/fts3atoken.test.

    82     82       INSERT INTO t1(content) VALUES('There was movement at the station');
    83     83       INSERT INTO t1(content) VALUES('For the word has passed around');
    84     84       INSERT INTO t1(content) VALUES('That the colt from ol regret had got');
    85     85       SELECT content FROM t1 WHERE content MATCH 'movement'
    86     86     }
    87     87   } {{There was movement at the station}}
    88     88   
           89  +unset -nocomplain simple blah2name simplename
           90  +set simplename "simple"
           91  +set blah2name "blah2"
           92  +set simple [db one {SELECT fts3_tokenizer('simple')}]
    89     93   sqlite3_db_config db SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 0
    90     94   do_catchsql_test 1.6 {
    91     95     SELECT fts3_tokenizer('blah', fts3_tokenizer('simple')) IS NULL;
    92     96   } {1 {fts3tokenize disabled}}
           97  +do_test fts3atoken-1.7 {
           98  +  execsql {
           99  +    SELECT fts3_tokenizer('blah2', $simple) IS NULL;
          100  +  }
          101  +} {1}
    93    102   
          103  +# With ENABLE_FTS3_TOKENIZER off, the fts3_tokenzer(1) function
          104  +# returns NULL unless the first parameter is a bound parameter.
          105  +# If the first parameter is a bound parameter, then fts3_tokenizer(1)
          106  +# returns the actual pointer value as a BLOB.
          107  +#
          108  +do_test fts3atoken-1.8 {
          109  +  execsql {
          110  +    SELECT fts3_tokenizer($blah2name) == fts3_tokenizer($simplename),
          111  +           typeof(fts3_tokenizer($blah2name)),
          112  +           typeof(fts3_tokenizer('blah2')),
          113  +           typeof(fts3_tokenizer($simplename)),
          114  +           typeof(fts3_tokenizer('simple'));
          115  +  }
          116  +} {1 blob null blob null}
          117  +
          118  +# With ENABLE_FTS3_TOKENIZER on, fts3_tokenizer() always returns
          119  +# the BLOB pointer, regardless the parameter
          120  +#
          121  +sqlite3_db_config db SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1
          122  +do_test fts3atoken-1.9 {
          123  +  execsql {
          124  +    SELECT fts3_tokenizer('blah2') == fts3_tokenizer('simple'),
          125  +           typeof(fts3_tokenizer($blah2name)),
          126  +           typeof(fts3_tokenizer('blah2')),
          127  +           typeof(fts3_tokenizer($simplename)),
          128  +           typeof(fts3_tokenizer('simple'));
          129  +  }
          130  +} {1 blob blob blob blob}
    94    131   
    95    132   #--------------------------------------------------------------------------
    96    133   # Test cases fts3atoken-2.* test error cases in the scalar function based
    97    134   # API for getting and setting tokenizers.
    98    135   #
    99    136   do_test fts3atoken-2.1 {
   100    137     catchsql {

Changes to test/func.test.

  1387   1387   }
  1388   1388   
  1389   1389   # Test char().
  1390   1390   #
  1391   1391   do_execsql_test func-31.1 { 
  1392   1392     SELECT char(), length(char()), typeof(char()) 
  1393   1393   } {{} 0 text}
         1394  +
         1395  +# sqlite3_value_frombind()
         1396  +#
         1397  +do_execsql_test func-32.100 {
         1398  +  SELECT test_frombind(1,2,3,4);
         1399  +} {0}
         1400  +do_execsql_test func-32.110 {
         1401  +  SELECT test_frombind(1,2,?,4);
         1402  +} {4}
         1403  +do_execsql_test func-32.120 {
         1404  +  SELECT test_frombind(1,(?),4,?+7);
         1405  +} {2}
         1406  +do_execsql_test func-32.130 {
         1407  +  DROP TABLE IF EXISTS t1;
         1408  +  CREATE TABLE t1(a,b,c,e,f);
         1409  +  INSERT INTO t1 VALUES(1,2.5,'xyz',x'e0c1b2a3',null);
         1410  +  SELECT test_frombind(a,b,c,e,f,$xyz) FROM t1;
         1411  +} {32}
         1412  +do_execsql_test func-32.140 {
         1413  +  SELECT test_frombind(a,b,c,e,f,$xyz+f) FROM t1;
         1414  +} {0}
         1415  +do_execsql_test func-32.150 {
         1416  +  SELECT test_frombind(x.a,y.b,x.c,:123,y.e,x.f,$xyz+y.f) FROM t1 x, t1 y;
         1417  +} {8}
         1418  +
         1419  +
         1420  +
         1421  +
  1394   1422   finish_test

Changes to test/fuzzdata8.db.

cannot compute difference between binary files

Changes to test/permutations.test.

  1028   1028   } -files [
  1029   1029     test_set [glob -nocomplain $::testdir/../ext/rbu/*.test] -exclude rbu.test
  1030   1030   ]
  1031   1031   
  1032   1032   test_suite "no_optimization" -description {
  1033   1033     Run test scripts with optimizations disabled using the
  1034   1034     sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS) interface.
  1035         -} -files {
  1036         -  where.test where2.test where3.test where4.test where5.test
  1037         -  where6.test where7.test where8.test where9.test
  1038         -  whereA.test whereB.test wherelimit.test
  1039         -  select1.test select2.test select3.test select4.test select5.test
  1040         -  select7.test select8.test selectA.test selectC.test
  1041         -} -dbconfig {
         1035  +} -files [
         1036  +  test_set \
         1037  +    [glob -nocomplain $::testdir/window*.test]                       \
         1038  +    where.test where2.test where3.test where4.test where5.test       \
         1039  +    where6.test where7.test where8.test where9.test                  \
         1040  +    whereA.test whereB.test wherelimit.test                          \
         1041  +    select1.test select2.test select3.test select4.test select5.test \
         1042  +    select7.test select8.test selectA.test selectC.test     
         1043  +] -dbconfig {
  1042   1044     optimization_control $::dbhandle all 0
  1043   1045   }
  1044   1046   
  1045   1047   test_suite "prepare" -description {
  1046   1048     Run tests with the db connection using sqlite3_prepare() instead of _v2().
  1047   1049   } -dbconfig {
  1048   1050     $::dbhandle version -use-legacy-prepare 1

Changes to test/pg_common.tcl.

    36     36     }
    37     37     if {$frag != ""} {
    38     38       lappend lSql $frag
    39     39     }
    40     40     #puts $lSql
    41     41   
    42     42     set ret ""
           43  +  set nChar 0
    43     44     foreach stmt $lSql {
    44     45       set res [pg_exec $::db $stmt]
    45     46       set err [pg_result $res -error]
    46     47       if {$err!=""} { error $err }
           48  +
    47     49       for {set i 0} {$i < [pg_result $res -numTuples]} {incr i} {
    48         -      if {$i==0} {
    49         -        set ret [pg_result $res -getTuple 0]
           50  +      set t [pg_result $res -getTuple $i]
           51  +      set nNew [string length $t]
           52  +      if {$nChar>0 && ($nChar+$nNew+3)>75} {
           53  +        append ret "\n  "
           54  +        set nChar 0
    50     55         } else {
    51         -        append ret "   [pg_result $res -getTuple $i]"
           56  +        if {$nChar>0} {
           57  +          append ret "   "
           58  +          incr nChar 3
           59  +        }
    52     60         }
    53         -      # lappend ret {*}[pg_result $res -getTuple $i]
           61  +      incr nChar $nNew
           62  +      append ret $t
    54     63       }
    55     64       pg_result $res -clear
    56     65     }
    57     66   
    58     67     set ret
    59     68   }
    60     69   
    61     70   proc execsql_test {tn sql} {
    62     71     set res [execsql $sql]
    63     72     set sql [string map {string_agg group_concat} $sql]
           73  +  set sql [string map [list {NULLS FIRST} {}] $sql]
           74  +  set sql [string map [list {NULLS LAST} {}] $sql]
    64     75     puts $::fd "do_execsql_test $tn {"
    65     76     puts $::fd "  [string trim $sql]"
    66     77     puts $::fd "} {$res}"
    67     78     puts $::fd ""
    68     79   }
           80  +
           81  +proc errorsql_test {tn sql} {
           82  +  set rc [catch {execsql $sql} msg]
           83  +  if {$rc==0} {
           84  +    error "errorsql_test SQL did not cause an error!"
           85  +  }
           86  +  set msg [lindex [split [string trim $msg] "\n"] 0]
           87  +  puts $::fd "# PG says $msg"
           88  +  set sql [string map {string_agg group_concat} $sql]
           89  +  puts $::fd "do_test $tn { catch { execsql {"
           90  +  puts $::fd "  [string trim $sql]"
           91  +  puts $::fd "} } } 1"
           92  +  puts $::fd ""
           93  +}
    69     94   
    70     95   # Same as [execsql_test], except coerce all results to floating point values
    71     96   # with two decimal points.
    72     97   #
    73     98   proc execsql_float_test {tn sql} {
    74     99     set F "%.4f"
    75    100     set T 0.0001
................................................................................
    84    109   puts $::fd [subst -nocommands {
    85    110   do_test $tn {
    86    111     set myres {}
    87    112     foreach r [db eval {$sql}] {
    88    113       lappend myres [format $F [set r]]
    89    114     }
    90    115     set res2 {$res2}
          116  +  set i 0
    91    117     foreach r [set myres] r2 [set res2] {
    92    118       if {[set r]<([set r2]-$T) || [set r]>([set r2]+$T)} {
    93    119         error "list element [set i] does not match: got=[set r] expected=[set r2]"
    94    120       }
          121  +    incr i
    95    122     }
    96    123     set {} {}
    97    124   } {}
    98    125   }]
    99    126   }
   100    127   
   101    128   proc start_test {name date} {

Changes to test/tester.tcl.

   572    572       set ::G(output_fd) [open $cmdlinearg(output) w]
   573    573       fconfigure $::G(output_fd) -buffering line
   574    574     }
   575    575   
   576    576     if {$cmdlinearg(verbose)==""} {
   577    577       set cmdlinearg(verbose) 1
   578    578     }
          579  +
          580  +  if {[info commands vdbe_coverage]!=""} {
          581  +    vdbe_coverage start
          582  +  }
   579    583   }
   580    584   
   581    585   # Update the soft-heap-limit each time this script is run. In that
   582    586   # way if an individual test file changes the soft-heap-limit, it
   583    587   # will be reset at the start of the next test file.
   584    588   #
   585    589   sqlite3_soft_heap_limit $cmdlinearg(soft-heap-limit)
................................................................................
  1317   1321       sqlite3_memdebug_log clear
  1318   1322       if {[sqlite3_memory_used]>0} {
  1319   1323         output2 "Writing leaks.tcl..."
  1320   1324         sqlite3_memdebug_log sync
  1321   1325         memdebug_log_sql leaks.tcl
  1322   1326       }
  1323   1327     }
         1328  +  if {[info commands vdbe_coverage]!=""} {
         1329  +    vdbe_coverage_report
         1330  +  }
  1324   1331     catch {
  1325   1332       foreach f [glob -nocomplain test.db-*-journal] {
  1326   1333         forcedelete $f
  1327   1334       }
  1328   1335     }
  1329   1336     catch {
  1330   1337       foreach f [glob -nocomplain test.db-mj*] {
  1331   1338         forcedelete $f
  1332   1339       }
  1333   1340     }
  1334   1341     exit [expr {$nErr>0}]
  1335   1342   }
         1343  +
         1344  +proc vdbe_coverage_report {} {
         1345  +  puts "Writing vdbe coverage report to vdbe_coverage.txt"
         1346  +  set lSrc [list]
         1347  +  set iLine 0
         1348  +  if {[file exists ../sqlite3.c]} {
         1349  +    set fd [open ../sqlite3.c]
         1350  +    set iLine
         1351  +    while { ![eof $fd] } {
         1352  +      set line [gets $fd]
         1353  +      incr iLine
         1354  +      if {[regexp {^/\** Begin file (.*\.c) \**/} $line -> file]} {
         1355  +        lappend lSrc [list $iLine $file]
         1356  +      }
         1357  +    }
         1358  +    close $fd
         1359  +  }
         1360  +  set fd [open vdbe_coverage.txt w]
         1361  +  foreach miss [vdbe_coverage report] {
         1362  +    foreach {line branch never} $miss {}
         1363  +    set nextfile ""
         1364  +    while {[llength $lSrc]>0 && [lindex $lSrc 0 0] < $line} {
         1365  +      set nextfile [lindex $lSrc 0 1]
         1366  +      set lSrc [lrange $lSrc 1 end]
         1367  +    }
         1368  +    if {$nextfile != ""} {
         1369  +      puts $fd ""
         1370  +      puts $fd "### $nextfile ###"
         1371  +    }
         1372  +    puts $fd "Vdbe branch $line: never $never (path $branch)"
         1373  +  }
         1374  +  close $fd
         1375  +}
  1336   1376   
  1337   1377   # Display memory statistics for analysis and debugging purposes.
  1338   1378   #
  1339   1379   proc show_memstats {} {
  1340   1380     set x [sqlite3_status SQLITE_STATUS_MEMORY_USED 0]
  1341   1381     set y [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0]
  1342   1382     set val [format {now %10d  max %10d  max-size %10d} \

Changes to test/window1.test.

   715    715   } {6 6 6}
   716    716   
   717    717   do_execsql_test 17.3 {
   718    718     SELECT 10+sum(a) OVER (ORDER BY a) 
   719    719     FROM t8 
   720    720     ORDER BY 10+sum(a) OVER (ORDER BY a) DESC;
   721    721   } {16 13 11}
          722  +
   722    723   
   723    724   #-------------------------------------------------------------------------
          725  +# Test error cases from chaining window definitions.
   724    726   #
   725    727   reset_db
   726    728   do_execsql_test 18.0 {
          729  +  DROP TABLE IF EXISTS t1;
          730  +  CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c TEXT, d INTEGER);
          731  +  INSERT INTO t1 VALUES(1, 'odd',  'one',   1);
          732  +  INSERT INTO t1 VALUES(2, 'even', 'two',   2);
          733  +  INSERT INTO t1 VALUES(3, 'odd',  'three', 3);
          734  +  INSERT INTO t1 VALUES(4, 'even', 'four',  4);
          735  +  INSERT INTO t1 VALUES(5, 'odd',  'five',  5);
          736  +  INSERT INTO t1 VALUES(6, 'even', 'six',   6);
          737  +}
          738  +
          739  +foreach {tn sql error} {
          740  +  1 {
          741  +    SELECT c, sum(d) OVER win2 FROM t1
          742  +      WINDOW win1 AS (ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING), 
          743  +             win2 AS (win1 ORDER BY b)
          744  +  } {cannot override frame specification of window: win1}
          745  +
          746  +  2 {
          747  +    SELECT c, sum(d) OVER win2 FROM t1
          748  +      WINDOW win1 AS (),
          749  +             win2 AS (win4 ORDER BY b)
          750  +  } {no such window: win4}
          751  +
          752  +  3 {
          753  +    SELECT c, sum(d) OVER win2 FROM t1
          754  +      WINDOW win1 AS (),
          755  +             win2 AS (win1 PARTITION BY d)
          756  +  } {cannot override PARTITION clause of window: win1}
          757  +
          758  +  4 {
          759  +    SELECT c, sum(d) OVER win2 FROM t1
          760  +      WINDOW win1 AS (ORDER BY b),
          761  +             win2 AS (win1 ORDER BY d)
          762  +  } {cannot override ORDER BY clause of window: win1}
          763  +} {
          764  +  do_catchsql_test 18.1.$tn $sql [list 1 $error]
          765  +}
          766  +
          767  +foreach {tn sql error} {
          768  +  1 {
          769  +    SELECT c, sum(d) OVER (win1 ORDER BY b) FROM t1
          770  +      WINDOW win1 AS (ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
          771  +  } {cannot override frame specification of window: win1}
          772  +
          773  +  2 {
          774  +    SELECT c, sum(d) OVER (win4 ORDER BY b) FROM t1
          775  +      WINDOW win1 AS ()
          776  +  } {no such window: win4}
          777  +
          778  +  3 {
          779  +    SELECT c, sum(d) OVER (win1 PARTITION BY d) FROM t1
          780  +      WINDOW win1 AS ()
          781  +  } {cannot override PARTITION clause of window: win1}
          782  +
          783  +  4 {
          784  +    SELECT c, sum(d) OVER (win1 ORDER BY d) FROM t1
          785  +      WINDOW win1 AS (ORDER BY b)
          786  +  } {cannot override ORDER BY clause of window: win1}
          787  +} {
          788  +  do_catchsql_test 18.2.$tn $sql [list 1 $error]
          789  +}
          790  +
          791  +do_execsql_test 18.3.1 {
          792  +  SELECT group_concat(c, '.') OVER (PARTITION BY b ORDER BY c)
          793  +  FROM t1
          794  +} {four four.six four.six.two five five.one five.one.three}
          795  +
          796  +do_execsql_test 18.3.2 {
          797  +  SELECT group_concat(c, '.') OVER (win1 ORDER BY c)
          798  +  FROM t1
          799  +  WINDOW win1 AS (PARTITION BY b)
          800  +} {four four.six four.six.two five five.one five.one.three}
          801  +
          802  +do_execsql_test 18.3.3 {
          803  +  SELECT group_concat(c, '.') OVER win2
          804  +  FROM t1
          805  +  WINDOW win1 AS (PARTITION BY b),
          806  +         win2 AS (win1 ORDER BY c)
          807  +} {four four.six four.six.two five five.one five.one.three}
          808  +
          809  +do_execsql_test 18.3.4 {
          810  +  SELECT group_concat(c, '.') OVER (win2)
          811  +  FROM t1
          812  +  WINDOW win1 AS (PARTITION BY b),
          813  +         win2 AS (win1 ORDER BY c)
          814  +} {four four.six four.six.two five five.one five.one.three}
          815  +
          816  +do_execsql_test 18.3.5 {
          817  +  SELECT group_concat(c, '.') OVER win5
          818  +  FROM t1
          819  +  WINDOW win1 AS (PARTITION BY b),
          820  +         win2 AS (win1),
          821  +         win3 AS (win2),
          822  +         win4 AS (win3),
          823  +         win5 AS (win4 ORDER BY c)
          824  +} {four four.six four.six.two five five.one five.one.three}
          825  +
          826  +#-------------------------------------------------------------------------
          827  +# Test RANGE <expr> PRECEDING/FOLLOWING when there are string, blob
          828  +# and NULL values in the dataset.
          829  +#
          830  +reset_db
          831  +do_execsql_test 19.0 {
          832  +  CREATE TABLE t1(a, b);
          833  +  INSERT INTO t1 VALUES
          834  +    (1, 1), (2, 2), (3, 3), (4, 4), (5, 5),
          835  +    ('a', 6), ('b', 7), ('c', 8), ('d', 9), ('e', 10);
          836  +}
          837  +do_execsql_test 19.1 {
          838  +  SELECT a, sum(b) OVER (ORDER BY a) FROM t1;
          839  +} {1 1  2 3  3 6  4 10  5 15  a 21 b 28 c 36 d 45 e 55}
          840  +
          841  +do_execsql_test 19.2.1 {
          842  +  SELECT a, sum(b) OVER (
          843  +    ORDER BY a RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING
          844  +  ) FROM t1;
          845  +} {1 3 2 6 3 9 4 12 5 9 a 6 b 7 c 8 d 9 e 10}
          846  +do_execsql_test 19.2.2 {
          847  +  SELECT a, sum(b) OVER (
          848  +    ORDER BY a DESC RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING
          849  +  ) FROM t1 ORDER BY a ASC;
          850  +} {1 3 2 6 3 9 4 12 5 9 a 6 b 7 c 8 d 9 e 10}
          851  +
          852  +do_execsql_test 19.3.1 {
          853  +  SELECT a, sum(b) OVER (
          854  +    ORDER BY a RANGE BETWEEN 2 PRECEDING AND 1 FOLLOWING
          855  +  ) FROM t1;
          856  +} {1 3 2 6 3 10 4 14 5 12 a 6 b 7 c 8 d 9 e 10}
          857  +do_execsql_test 19.3.2 {
          858  +  SELECT a, sum(b) OVER (
          859  +    ORDER BY a DESC RANGE BETWEEN 1 PRECEDING AND 2 FOLLOWING
          860  +  ) FROM t1 ORDER BY a ASC;
          861  +} {1 3 2 6 3 10 4 14 5 12 a 6 b 7 c 8 d 9 e 10}
          862  +
          863  +
          864  +reset_db
          865  +do_execsql_test 20.0 {
          866  +  CREATE TABLE t1(a, b);
          867  +  INSERT INTO t1 VALUES
          868  +    (NULL, 100), (NULL, 100), 
          869  +    (1, 1), (2, 2), (3, 3), (4, 4), (5, 5),
          870  +    ('a', 6), ('b', 7), ('c', 8), ('d', 9), ('e', 10);
          871  +}
          872  +do_execsql_test 20.1 {
          873  +  SELECT a, sum(b) OVER (ORDER BY a) FROM t1;
          874  +} {
          875  +  {} 200 {} 200 1 201  2 203  3 206  4 210  5 215  
          876  +  a 221 b 228 c 236 d 245 e 255
          877  +}
          878  +
          879  +do_execsql_test 20.2.1 {
          880  +  SELECT a, sum(b) OVER (
          881  +    ORDER BY a RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING
          882  +  ) FROM t1;
          883  +} {{} 200 {} 200 1 3 2 6 3 9 4 12 5 9 a 6 b 7 c 8 d 9 e 10}
          884  +do_execsql_test 20.2.2 {
          885  +  SELECT a, sum(b) OVER (
          886  +    ORDER BY a DESC RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING
          887  +  ) FROM t1 ORDER BY a ASC;
          888  +} {{} 200 {} 200 1 3 2 6 3 9 4 12 5 9 a 6 b 7 c 8 d 9 e 10}
          889  +
          890  +do_execsql_test 20.3.1 {
          891  +  SELECT a, sum(b) OVER (
          892  +    ORDER BY a RANGE BETWEEN 2 PRECEDING AND 1 FOLLOWING
          893  +  ) FROM t1;
          894  +} {{} 200 {} 200 1 3 2 6 3 10 4 14 5 12 a 6 b 7 c 8 d 9 e 10}
          895  +do_execsql_test 20.3.2 {
          896  +  SELECT a, sum(b) OVER (
          897  +    ORDER BY a DESC RANGE BETWEEN 1 PRECEDING AND 2 FOLLOWING
          898  +  ) FROM t1 ORDER BY a ASC;
          899  +} {{} 200 {} 200 1 3 2 6 3 10 4 14 5 12 a 6 b 7 c 8 d 9 e 10}
          900  +
          901  +#-------------------------------------------------------------------------
          902  +do_execsql_test 21.0 {
          903  +  CREATE TABLE keyword_tab(
          904  +    current, exclude, filter, following, groups, no, others, over,
          905  +    partition, preceding, range, ties, unbounded, window
          906  +  );
          907  +}
          908  +do_execsql_test 21.1 {
          909  +  SELECT
          910  +    current, exclude, filter, following, groups, no, others, over,
          911  +    partition, preceding, range, ties, unbounded, window
          912  +  FROM keyword_tab
          913  +}
          914  +
          915  +#-------------------------------------------------------------------------
          916  +foreach {tn expr err} {
          917  +  1   4.5      0
          918  +  2   NULL     1
          919  +  3   0.0      0
          920  +  4   0.1      0
          921  +  5  -0.1      1
          922  +  6  ''        1
          923  +  7  '2.0'     0
          924  +  8  '2.0x'    1
          925  +  9  x'1234'   1
          926  + 10  '1.2'     0
          927  +} {
          928  +  set res {0 1}
          929  +  if {$err} {set res {1 {frame starting offset must be a non-negative number}} }
          930  +  do_catchsql_test 22.$tn.1 "
          931  +    WITH a(x, y) AS ( VALUES(1, 2) )
          932  +    SELECT sum(x) OVER (
          933  +      ORDER BY y RANGE BETWEEN $expr PRECEDING AND UNBOUNDED FOLLOWING
          934  +    ) FROM a
          935  +  " $res
          936  +
          937  +  set res {0 1}
          938  +  if {$err} {set res {1 {frame ending offset must be a non-negative number}} }
          939  +  do_catchsql_test 22.$tn.2 "
          940  +    WITH a(x, y) AS ( VALUES(1, 2) )
          941  +    SELECT sum(x) OVER (
          942  +      ORDER BY y RANGE BETWEEN UNBOUNDED PRECEDING AND $expr FOLLOWING
          943  +    ) FROM a
          944  +  " $res
          945  +}
          946  +
          947  +#-------------------------------------------------------------------------
          948  +reset_db
          949  +do_execsql_test 23.0 {
          950  +  CREATE TABLE t5(a, b, c);
          951  +  CREATE INDEX t5ab ON t5(a, b);
          952  +}
          953  +
          954  +proc do_ordercount_test {tn sql nOrderBy} {
          955  +  set plan [execsql "EXPLAIN QUERY PLAN $sql"]
          956  +  uplevel [list do_test $tn [list regexp -all ORDER $plan] $nOrderBy]
          957  +}
          958  +
          959  +do_ordercount_test 23.1 {
          960  +  SELECT 
          961  +    sum(c) OVER (ORDER BY a, b),
          962  +    sum(c) OVER (PARTITION BY a ORDER BY b)
          963  +  FROM t5
          964  +} 0
          965  +
          966  +do_ordercount_test 23.2 {
          967  +  SELECT 
          968  +    sum(c) OVER (ORDER BY b, a),
          969  +    sum(c) OVER (PARTITION BY b ORDER BY a)
          970  +  FROM t5
          971  +} 1
          972  +
          973  +do_ordercount_test 23.3 {
          974  +  SELECT 
          975  +    sum(c) OVER (ORDER BY b, a),
          976  +    sum(c) OVER (ORDER BY c, b)
          977  +  FROM t5
          978  +} 2
          979  +
          980  +do_ordercount_test 23.4 {
          981  +  SELECT 
          982  +    sum(c) OVER (ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW),
          983  +    sum(c) OVER (ORDER BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW),
          984  +    sum(c) OVER (ORDER BY b GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          985  +  FROM t5
          986  +} 1
          987  +
          988  +do_ordercount_test 23.5 {
          989  +  SELECT 
          990  +    sum(c) OVER (ORDER BY b+1 ROWS UNBOUNDED PRECEDING),
          991  +    sum(c) OVER (ORDER BY b+1 RANGE UNBOUNDED PRECEDING),
          992  +    sum(c) OVER (ORDER BY b+1 GROUPS UNBOUNDED PRECEDING)
          993  +  FROM t5
          994  +} 1
          995  +
          996  +do_ordercount_test 23.6 {
          997  +  SELECT 
          998  +    sum(c) OVER (ORDER BY b+1 ROWS UNBOUNDED PRECEDING),
          999  +    sum(c) OVER (ORDER BY b+2 RANGE UNBOUNDED PRECEDING),
         1000  +    sum(c) OVER (ORDER BY b+3 GROUPS UNBOUNDED PRECEDING)
         1001  +  FROM t5
         1002  +} 3
         1003  +
         1004  +do_execsql_test 24.1 {
         1005  +  SELECT sum(44) OVER ()
         1006  +} {44}
         1007  +
         1008  +do_execsql_test 24.2 {
         1009  +  SELECT lead(44) OVER ()
         1010  +} {{}}
         1011  +
         1012  +#-------------------------------------------------------------------------
         1013  +#
         1014  +reset_db
         1015  +do_execsql_test 25.0 {
   727   1016     CREATE TABLE t1 ( t1_id INTEGER PRIMARY KEY );
   728   1017     CREATE TABLE t2 ( t2_id INTEGER PRIMARY KEY );
   729   1018     CREATE TABLE t3 ( t3_id INTEGER PRIMARY KEY );
   730   1019   
   731   1020     INSERT INTO t1 VALUES(1),  (3), (5);
   732   1021     INSERT INTO t2 VALUES      (3), (5);
   733   1022     INSERT INTO t3 VALUES(10), (11), (12);
   734   1023   }
   735   1024   
   736         -do_execsql_test 18.1 {
         1025  +do_execsql_test 25.1 {
   737   1026     SELECT t1.* FROM t1, t2 WHERE 
   738   1027       t1_id=t2_id AND t1_id IN (
   739   1028           SELECT t1_id + row_number() OVER ( ORDER BY t1_id ) FROM t3
   740   1029       )
   741   1030   }
   742   1031   
   743         -do_execsql_test 18.2 {
         1032  +do_execsql_test 25.2 {
   744   1033     SELECT t1.* FROM t1, t2 WHERE 
   745   1034       t1_id=t2_id AND t1_id IN (
   746   1035           SELECT         row_number() OVER ( ORDER BY t1_id ) FROM t3
   747   1036       )
   748   1037   } {3}
   749   1038   
         1039  +#-------------------------------------------------------------------------
         1040  +reset_db
         1041  +do_execsql_test 26.0 {
         1042  +  CREATE TABLE t1(x);
         1043  +  CREATE TABLE t2(c);
         1044  +}
         1045  +
         1046  +do_execsql_test 26.1 {
         1047  +  SELECT ( SELECT row_number() OVER () FROM ( SELECT c FROM t1 ) ) FROM t2
         1048  +} {}
         1049  +
         1050  +do_execsql_test 26.2 {
         1051  +  INSERT INTO t1 VALUES(1), (2), (3), (4);
         1052  +  INSERT INTO t2 VALUES(2), (6), (8), (4);
         1053  +  SELECT c, c IN ( 
         1054  +    SELECT row_number() OVER () FROM ( SELECT c FROM t1 )
         1055  +  ) FROM t2
         1056  +} {2 1  6 0  8 0  4 1}
         1057  +
         1058  +do_execsql_test 26.3 {
         1059  +  DELETE FROM t1;
         1060  +  DELETE FROM t2;
         1061  +
         1062  +  INSERT INTO t2 VALUES(1), (2), (3), (4);
         1063  +  INSERT INTO t1 VALUES(1), (1), (2), (3), (3), (3), (3), (4), (4);
         1064  +
         1065  +  SELECT c, c IN ( 
         1066  +    SELECT row_number() OVER () FROM ( SELECT 1 FROM t1 WHERE x=c )
         1067  +  ) FROM t2
         1068  +} {1 1  2 0  3 1  4 0}
         1069  +
         1070  +#-------------------------------------------------------------------------
         1071  +reset_db
         1072  +do_execsql_test 27.0 {
         1073  +  CREATE TABLE t1(x);
         1074  +  INSERT INTO t1 VALUES(NULL), (1), (2), (3), (4), (5);
         1075  +}
         1076  +do_execsql_test 27.1 {
         1077  +  SELECT min(x) FROM t1;
         1078  +} {1}
         1079  +do_execsql_test 27.2 {
         1080  +  SELECT min(x) OVER win FROM t1
         1081  +  WINDOW win AS (ORDER BY rowid ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
         1082  +} {1 1 1 2 3 4}
         1083  +
   750   1084   
   751   1085   finish_test
         1086  +
         1087  +

Changes to test/window3.tcl.

    17     17   start_test window3 "2018 May 31"
    18     18   ifcapable !windowfunc
    19     19   
    20     20   execsql_test 1.0 {
    21     21     DROP TABLE IF EXISTS t2;
    22     22     CREATE TABLE t2(a INTEGER PRIMARY KEY, b INTEGER);
    23     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     24     (10,89), (11,81), (12,96), (13,59), (14,38), (15,68), (16,39), (17,62),
    26     25     (18,91), (19,46), (20,6), (21,99), (22,97), (23,27), (24,46), (25,78),
    27     26     (26,54), (27,97), (28,8), (29,67), (30,29), (31,93), (32,84), (33,77),
    28     27     (34,23), (35,16), (36,16), (37,93), (38,65), (39,35), (40,47), (41,7),
    29     28     (42,86), (43,74), (44,61), (45,91), (46,85), (47,24), (48,85), (49,43),
    30     29     (50,59), (51,12), (52,32), (53,56), (54,3), (55,91), (56,22), (57,90),
    31     30     (58,55), (59,15), (60,28), (61,89), (62,25), (63,47), (64,1), (65,56),
................................................................................
    69     68     11 "ROWS BETWEEN 4 PRECEDING    AND 2 FOLLOWING"
    70     69     12 "ROWS BETWEEN CURRENT ROW         AND 4 FOLLOWING"
    71     70     13 "ROWS BETWEEN 2 FOLLOWING    AND 4 FOLLOWING"
    72     71     14 "ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING"
    73     72     15 "ROWS BETWEEN 4 PRECEDING    AND UNBOUNDED FOLLOWING"
    74     73     16 "ROWS BETWEEN CURRENT ROW         AND UNBOUNDED FOLLOWING"
    75     74     17 "ROWS BETWEEN 4 FOLLOWING    AND UNBOUNDED FOLLOWING"
           75  +
           76  +  18 "ROWS BETWEEN 4 PRECEDING    AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW"
           77  +  19 "ROWS BETWEEN 4 PRECEDING    AND UNBOUNDED FOLLOWING EXCLUDE TIES"
           78  +  20 "ROWS BETWEEN 4 PRECEDING    AND UNBOUNDED FOLLOWING EXCLUDE GROUP"
           79  +
    76     80   } {
    77     81     execsql_test 1.$tn.2.1 "SELECT max(b) OVER ( ORDER BY a $window ) FROM t2"
    78     82     execsql_test 1.$tn.2.2 "SELECT min(b) OVER ( ORDER BY a $window ) FROM t2"
    79     83   
    80     84     execsql_test 1.$tn.3.1 "
    81     85       SELECT row_number() OVER ( ORDER BY a $window ) FROM t2
    82     86     "
................................................................................
   302    306     "
   303    307     execsql_test 1.$tn.14.5 "
   304    308       SELECT string_agg(CAST(b AS TEXT), '.') OVER ( ORDER BY b%10,a $window ) FROM t2
   305    309     "
   306    310     execsql_test 1.$tn.14.6 "
   307    311       SELECT string_agg(CAST(b AS TEXT), '.') OVER (PARTITION BY b%2,a ORDER BY b%10 $window) FROM t2
   308    312     "
          313  +
          314  +  execsql_test 1.$tn.14.7 "
          315  +    SELECT string_agg(CAST(b AS TEXT), '.') OVER (win1 ORDER BY b%10 $window) 
          316  +    FROM t2
          317  +    WINDOW win1 AS (PARTITION BY b%2,a)
          318  +    ORDER BY 1
          319  +  "
          320  +
          321  +  execsql_test 1.$tn.14.8 "
          322  +    SELECT string_agg(CAST(b AS TEXT), '.') OVER (win1 $window) 
          323  +    FROM t2
          324  +    WINDOW win1 AS (PARTITION BY b%2,a ORDER BY b%10)
          325  +    ORDER BY 1
          326  +  "
          327  +
          328  +  execsql_test 1.$tn.14.9 "
          329  +    SELECT string_agg(CAST(b AS TEXT), '.') OVER win2
          330  +    FROM t2
          331  +    WINDOW win1 AS (PARTITION BY b%2,a ORDER BY b%10),
          332  +           win2 AS (win1 $window)
          333  +    ORDER BY 1
          334  +  "
   309    335   
   310    336     execsql_test 1.$tn.15.1 "
   311    337       SELECT count(*) OVER win, string_agg(CAST(b AS TEXT), '.') 
   312    338       FILTER (WHERE a%2=0) OVER win FROM t2
   313    339       WINDOW win AS (ORDER BY a $window)
   314    340     "
   315    341   

Changes to test/window3.test.

cannot compute difference between binary files

Changes to test/window4.tcl.

     1         -# 2018 May 19
            1  +## 2018 May 19
     2      2   #
     3      3   # The author disclaims copyright to this source code.  In place of
     4      4   # a legal notice, here is a blessing:
     5      5   #
     6      6   #    May you do good and not evil.
     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.

Changes to test/window4.test.

   146    146     SELECT a, lag(b, 3, 'abc') OVER (ORDER BY a) FROM t4
   147    147   } {1 abc   2 abc   3 abc   4 A   5 B   6 C   7 D   8 E   9 F   10 G}
   148    148   
   149    149   do_execsql_test 2.4.1 {
   150    150     SELECT group_concat(b, '.') OVER (
   151    151       ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
   152    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}
          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
          154  +  E.F.G.H.I.J   F.G.H.I.J   G.H.I.J   H.I.J   I.J   J}
   154    155   
   155    156   do_execsql_test 3.0 {
   156    157     DROP TABLE IF EXISTS t5;
   157    158     CREATE TABLE t5(a INTEGER PRIMARY KEY, b TEXT, c TEXT, d INTEGER);
   158    159     INSERT INTO t5 VALUES(1, 'A', 'one',   5);
   159    160     INSERT INTO t5 VALUES(2, 'B', 'two',   4);
   160    161     INSERT INTO t5 VALUES(3, 'A', 'three', 3);
................................................................................
  1220   1221   
  1221   1222   do_test 9.3 {
  1222   1223     set myres {}
  1223   1224     foreach r [db eval {SELECT x, percent_rank() OVER (PARTITION BY x ORDER BY x) FROM t2}] {
  1224   1225       lappend myres [format %.4f [set r]]
  1225   1226     }
  1226   1227     set res2 {1.0000 0.0000 1.0000 0.0000 1.0000 0.0000 4.0000 0.0000 4.0000 0.0000 6.0000 0.0000 7.0000 0.0000}
         1228  +  set i 0
  1227   1229     foreach r [set myres] r2 [set res2] {
  1228   1230       if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} {
  1229   1231         error "list element [set i] does not match: got=[set r] expected=[set r2]"
  1230   1232       }
         1233  +    incr i
  1231   1234     }
  1232   1235     set {} {}
  1233   1236   } {}
  1234   1237   
  1235   1238   do_execsql_test 9.4 {
  1236   1239     SELECT x, rank() OVER (ORDER BY x) FROM t2 ORDER BY 1,2
  1237   1240   } {1 1   1 1   1 1   4 4   4 4   6 6   7 7}
................................................................................
  1243   1246   
  1244   1247   do_test 9.6 {
  1245   1248     set myres {}
  1246   1249     foreach r [db eval {SELECT percent_rank() OVER () FROM t1}] {
  1247   1250       lappend myres [format %.4f [set r]]
  1248   1251     }
  1249   1252     set res2 {0.0000 0.0000 0.0000}
         1253  +  set i 0
  1250   1254     foreach r [set myres] r2 [set res2] {
  1251   1255       if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} {
  1252   1256         error "list element [set i] does not match: got=[set r] expected=[set r2]"
  1253   1257       }
         1258  +    incr i
  1254   1259     }
  1255   1260     set {} {}
  1256   1261   } {}
  1257   1262   
  1258   1263   
  1259   1264   do_test 9.7 {
  1260   1265     set myres {}
  1261   1266     foreach r [db eval {SELECT cume_dist() OVER () FROM t1}] {
  1262   1267       lappend myres [format %.4f [set r]]
  1263   1268     }
  1264   1269     set res2 {1.0000 1.0000 1.0000}
         1270  +  set i 0
  1265   1271     foreach r [set myres] r2 [set res2] {
  1266   1272       if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} {
  1267   1273         error "list element [set i] does not match: got=[set r] expected=[set r2]"
  1268   1274       }
         1275  +    incr i
  1269   1276     }
  1270   1277     set {} {}
  1271   1278   } {}
  1272   1279   
  1273   1280   do_execsql_test 10.0 {
  1274   1281     DROP TABLE IF EXISTS t7;
  1275   1282     CREATE TABLE t7(id INTEGER PRIMARY KEY, a INTEGER, b INTEGER);

Changes to test/window6.test.

   215    215   do_execsql_test 9.0 {
   216    216     WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5)
   217    217     SELECT x, group_concat(x) OVER (ORDER BY x ROWS 2 PRECEDING)
   218    218     FROM c;
   219    219   } {
   220    220     1 1  2 1,2  3 1,2,3  4 2,3,4  5 3,4,5
   221    221   }
   222         -do_catchsql_test 9.1 {
   223         -  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5)
   224         -  SELECT x, group_concat(x) OVER (ORDER BY x RANGE 2 PRECEDING)
   225         -  FROM c;
   226         -} {1 {RANGE must use only UNBOUNDED or CURRENT ROW}}
   227         -
   228         -do_catchsql_test 9.2 {
   229         -  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5)
   230         -  SELECT x, group_concat(x) OVER (ORDER BY x RANGE BETWEEN UNBOUNDED PRECEDING AND 2 FOLLOWING)
   231         -  FROM c;
   232         -} {1 {RANGE must use only UNBOUNDED or CURRENT ROW}}
          222  +#do_catchsql_test 9.1 {
          223  +#  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5)
          224  +#  SELECT x, group_concat(x) OVER (ORDER BY x RANGE 2 PRECEDING)
          225  +#  FROM c;
          226  +#} {1 {RANGE must use only UNBOUNDED or CURRENT ROW}}
          227  +#
          228  +#do_catchsql_test 9.2 {
          229  +#  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5)
          230  +#  SELECT x, group_concat(x) OVER (ORDER BY x RANGE BETWEEN UNBOUNDED PRECEDING AND 2 FOLLOWING)
          231  +#  FROM c;
          232  +#} {1 {RANGE must use only UNBOUNDED or CURRENT ROW}}
   233    233   
   234    234   do_catchsql_test 9.3 {
   235    235     WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5)
   236    236     SELECT count(DISTINCT x) OVER (ORDER BY x) FROM c;
   237    237   } {1 {DISTINCT is not supported for window functions}}
   238    238   
   239    239   do_catchsql_test 9.4 {
................................................................................
   258    258     4 "BETWEEN 4 FOLLOWING AND 2 PRECEDING"
   259    259   } {
   260    260     do_catchsql_test 9.7.$tn "
   261    261       WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5)
   262    262       SELECT count() OVER (
   263    263           ORDER BY x ROWS $frame 
   264    264       ) FROM c;
   265         -  " {1 {unsupported frame delimiter for ROWS}}
          265  +  " {1 {unsupported frame specification}}
   266    266   }
   267    267   
   268    268   do_catchsql_test 9.8.1 {
   269    269     WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5)
   270    270     SELECT count() OVER (
   271    271         ORDER BY x ROWS BETWEEN a PRECEDING AND 2 FOLLOWING
   272    272     ) FROM c;
................................................................................
   332    332   do_execsql_test 11.2 {
   333    333     SELECT a, (SELECT y FROM t3 WHERE x=a), sum(a) OVER (ORDER BY a)
   334    334       FROM t1 ORDER BY a;
   335    335   } {
   336    336     10 ten 10   15 fifteen 25   20 {} 65        20 {} 65   
   337    337     25 {} 90    30 thirty 150   30 thirty 150   50 {} 200
   338    338   }
          339  +
          340  +do_execsql_test 11.3.1 {
          341  +  SELECT a, sum(a) OVER win FROM t1
          342  +  WINDOW win AS (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          343  +} {
          344  +  10 10 15 25 20 45 20 65 25 90 30 120 30 150 50 200
          345  +}
          346  +do_execsql_test 11.3.2 {
          347  +  SELECT a, sum(a) OVER win FROM t1
          348  +  WINDOW win AS (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 0 FOLLOWING)
          349  +} {
          350  +  10 10 15 25 20 45 20 65 25 90 30 120 30 150 50 200
          351  +}
          352  +do_execsql_test 11.3.3 {
          353  +  SELECT a, sum(a) OVER win FROM t1
          354  +  WINDOW win AS (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING)
          355  +} {
          356  +  10 10 15 25 20 45 20 65 25 90 30 120 30 150 50 200
          357  +}
          358  +
          359  +do_execsql_test 11.4.1 {
          360  +  SELECT y, group_concat(y, '.') OVER win FROM t3
          361  +  WINDOW win AS (
          362  +    ORDER BY y RANGE BETWEEN UNBOUNDED PRECEDING AND 10 PRECEDING
          363  +  );
          364  +} {
          365  +  fifteen fifteen 
          366  +  ten     fifteen.ten 
          367  +  thirty  fifteen.ten.thirty
          368  +}
   339    369   
   340    370   finish_test
          371  +

Added test/window7.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 window7 "2019 March 01"
           18  +ifcapable !windowfunc
           19  +
           20  +execsql_test 1.0 {
           21  +  DROP TABLE IF EXISTS t3;
           22  +  CREATE TABLE t3(a INTEGER, b INTEGER);
           23  +  INSERT INTO t3 VALUES
           24  +    (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), 
           25  +    (9, 9), (0, 10), (1, 11), (2, 12), (3, 13), (4, 14), (5, 15), (6, 16), 
           26  +    (7, 17), (8, 18), (9, 19), (0, 20), (1, 21), (2, 22), (3, 23), (4, 24), 
           27  +    (5, 25), (6, 26), (7, 27), (8, 28), (9, 29), (0, 30), (1, 31), (2, 32), 
           28  +    (3, 33), (4, 34), (5, 35), (6, 36), (7, 37), (8, 38), (9, 39), (0, 40), 
           29  +    (1, 41), (2, 42), (3, 43), (4, 44), (5, 45), (6, 46), (7, 47), (8, 48), 
           30  +    (9, 49), (0, 50), (1, 51), (2, 52), (3, 53), (4, 54), (5, 55), (6, 56), 
           31  +    (7, 57), (8, 58), (9, 59), (0, 60), (1, 61), (2, 62), (3, 63), (4, 64), 
           32  +    (5, 65), (6, 66), (7, 67), (8, 68), (9, 69), (0, 70), (1, 71), (2, 72), 
           33  +    (3, 73), (4, 74), (5, 75), (6, 76), (7, 77), (8, 78), (9, 79), (0, 80), 
           34  +    (1, 81), (2, 82), (3, 83), (4, 84), (5, 85), (6, 86), (7, 87), (8, 88), 
           35  +    (9, 89), (0, 90), (1, 91), (2, 92), (3, 93), (4, 94), (5, 95), (6, 96), 
           36  +    (7, 97), (8, 98), (9, 99), (0, 100);
           37  +}
           38  +
           39  +execsql_test 1.1 {
           40  +  SELECT a, sum(b) FROM t3 GROUP BY a ORDER BY 1;
           41  +}
           42  +
           43  +execsql_test 1.2 {
           44  +  SELECT a, sum(b) OVER (
           45  +    ORDER BY a GROUPS BETWEEN CURRENT ROW AND CURRENT ROW
           46  +  ) FROM t3 ORDER BY 1;
           47  +}
           48  +
           49  +execsql_test 1.3 {
           50  +  SELECT a, sum(b) OVER (
           51  +    ORDER BY a GROUPS BETWEEN 0 PRECEDING AND 0 FOLLOWING
           52  +  ) FROM t3 ORDER BY 1;
           53  +}
           54  +
           55  +execsql_test 1.4 {
           56  +  SELECT a, sum(b) OVER (
           57  +    ORDER BY a GROUPS BETWEEN 2 PRECEDING AND 2 FOLLOWING
           58  +  ) FROM t3 ORDER BY 1;
           59  +}
           60  +
           61  +execsql_test 1.5 {
           62  +  SELECT a, sum(b) OVER (
           63  +    ORDER BY a RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING
           64  +  ) FROM t3 ORDER BY 1;
           65  +}
           66  +
           67  +execsql_test 1.6 {
           68  +  SELECT a, sum(b) OVER (
           69  +    ORDER BY a RANGE BETWEEN 2 PRECEDING AND 2 FOLLOWING
           70  +  ) FROM t3 ORDER BY 1;
           71  +}
           72  +
           73  +execsql_test 1.7 {
           74  +  SELECT a, sum(b) OVER (
           75  +    ORDER BY a RANGE BETWEEN 2 PRECEDING AND 1 FOLLOWING
           76  +  ) FROM t3 ORDER BY 1;
           77  +}
           78  +
           79  +execsql_test 1.8.1 {
           80  +  SELECT a, sum(b) OVER (
           81  +    ORDER BY a RANGE BETWEEN 0 PRECEDING AND 1 FOLLOWING
           82  +  ) FROM t3 ORDER BY 1;
           83  +}
           84  +execsql_test 1.8.2 {
           85  +  SELECT a, sum(b) OVER (
           86  +    ORDER BY a DESC RANGE BETWEEN 0 PRECEDING AND 1 FOLLOWING
           87  +  ) FROM t3 ORDER BY 1;
           88  +}
           89  +
           90  +finish_test
           91  +

Added test/window7.test.

            1  +# 2019 March 01
            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 window7
           21  +
           22  +ifcapable !windowfunc { finish_test ; return }
           23  +do_execsql_test 1.0 {
           24  +  DROP TABLE IF EXISTS t3;
           25  +  CREATE TABLE t3(a INTEGER, b INTEGER);
           26  +  INSERT INTO t3 VALUES
           27  +    (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), 
           28  +    (9, 9), (0, 10), (1, 11), (2, 12), (3, 13), (4, 14), (5, 15), (6, 16), 
           29  +    (7, 17), (8, 18), (9, 19), (0, 20), (1, 21), (2, 22), (3, 23), (4, 24), 
           30  +    (5, 25), (6, 26), (7, 27), (8, 28), (9, 29), (0, 30), (1, 31), (2, 32), 
           31  +    (3, 33), (4, 34), (5, 35), (6, 36), (7, 37), (8, 38), (9, 39), (0, 40), 
           32  +    (1, 41), (2, 42), (3, 43), (4, 44), (5, 45), (6, 46), (7, 47), (8, 48), 
           33  +    (9, 49), (0, 50), (1, 51), (2, 52), (3, 53), (4, 54), (5, 55), (6, 56), 
           34  +    (7, 57), (8, 58), (9, 59), (0, 60), (1, 61), (2, 62), (3, 63), (4, 64), 
           35  +    (5, 65), (6, 66), (7, 67), (8, 68), (9, 69), (0, 70), (1, 71), (2, 72), 
           36  +    (3, 73), (4, 74), (5, 75), (6, 76), (7, 77), (8, 78), (9, 79), (0, 80), 
           37  +    (1, 81), (2, 82), (3, 83), (4, 84), (5, 85), (6, 86), (7, 87), (8, 88), 
           38  +    (9, 89), (0, 90), (1, 91), (2, 92), (3, 93), (4, 94), (5, 95), (6, 96), 
           39  +    (7, 97), (8, 98), (9, 99), (0, 100);
           40  +} {}
           41  +
           42  +do_execsql_test 1.1 {
           43  +  SELECT a, sum(b) FROM t3 GROUP BY a ORDER BY 1;
           44  +} {0 550   1 460   2 470   3 480   4 490   5 500   6 510   7 520   8 530   9 540}
           45  +
           46  +do_execsql_test 1.2 {
           47  +  SELECT a, sum(b) OVER (
           48  +    ORDER BY a GROUPS BETWEEN CURRENT ROW AND CURRENT ROW
           49  +  ) FROM t3 ORDER BY 1;
           50  +} {0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   1 460   1 460   1 460   1 460   1 460   1 460   1 460   1 460   1 460   1 460   2 470   2 470   2 470   2 470   2 470   2 470   2 470   2 470   2 470   2 470   3 480   3 480   3 480   3 480   3 480   3 480   3 480   3 480   3 480   3 480   4 490   4 490   4 490   4 490   4 490   4 490   4 490   4 490   4 490   4 490   5 500   5 500   5 500   5 500   5 500   5 500   5 500   5 500   5 500   5 500   6 510   6 510   6 510   6 510   6 510   6 510   6 510   6 510   6 510   6 510   7 520   7 520   7 520   7 520   7 520   7 520   7 520   7 520   7 520   7 520   8 530   8 530   8 530   8 530   8 530   8 530   8 530   8 530   8 530   8 530   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540}
           51  +
           52  +do_execsql_test 1.3 {
           53  +  SELECT a, sum(b) OVER (
           54  +    ORDER BY a GROUPS BETWEEN 0 PRECEDING AND 0 FOLLOWING
           55  +  ) FROM t3 ORDER BY 1;
           56  +} {0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   1 460   1 460   1 460   1 460   1 460   1 460   1 460   1 460   1 460   1 460   2 470   2 470   2 470   2 470   2 470   2 470   2 470   2 470   2 470   2 470   3 480   3 480   3 480   3 480   3 480   3 480   3 480   3 480   3 480   3 480   4 490   4 490   4 490   4 490   4 490   4 490   4 490   4 490   4 490   4 490   5 500   5 500   5 500   5 500   5 500   5 500   5 500   5 500   5 500   5 500   6 510   6 510   6 510   6 510   6 510   6 510   6 510   6 510   6 510   6 510   7 520   7 520   7 520   7 520   7 520   7 520   7 520   7 520   7 520   7 520   8 530   8 530   8 530   8 530   8 530   8 530   8 530   8 530   8 530   8 530   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540}
           57  +
           58  +do_execsql_test 1.4 {
           59  +  SELECT a, sum(b) OVER (
           60  +    ORDER BY a GROUPS BETWEEN 2 PRECEDING AND 2 FOLLOWING
           61  +  ) FROM t3 ORDER BY 1;
           62  +} {0 1480   0 1480   0 1480   0 1480   0 1480   0 1480   0 1480   0 1480   0 1480   0 1480   1 1960   1 1960   1 1960   1 1960   1 1960   1 1960   1 1960   1 1960   1 1960   1 1960   2 2450   2 2450   2 2450   2 2450   2 2450   2 2450   2 2450   2 2450   2 2450   2 2450   3 2400   3 2400   3 2400   3 2400   3 2400   3 2400   3 2400   3 2400   3 2400   3 2400   4 2450   4 2450   4 2450   4 2450   4 2450   4 2450   4 2450   4 2450   4 2450   4 2450   5 2500   5 2500   5 2500   5 2500   5 2500   5 2500   5 2500   5 2500   5 2500   5 2500   6 2550   6 2550   6 2550   6 2550   6 2550   6 2550   6 2550   6 2550   6 2550   6 2550   7 2600   7 2600   7 2600   7 2600   7 2600   7 2600   7 2600   7 2600   7 2600   7 2600   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590}
           63  +
           64  +do_execsql_test 1.5 {
           65  +  SELECT a, sum(b) OVER (
           66  +    ORDER BY a RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING
           67  +  ) FROM t3 ORDER BY 1;
           68  +} {0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   1 460   1 460   1 460   1 460   1 460   1 460   1 460   1 460   1 460   1 460   2 470   2 470   2 470   2 470   2 470   2 470   2 470   2 470   2 470   2 470   3 480   3 480   3 480   3 480   3 480   3 480   3 480   3 480   3 480   3 480   4 490   4 490   4 490   4 490   4 490   4 490   4 490   4 490   4 490   4 490   5 500   5 500   5 500   5 500   5 500   5 500   5 500   5 500   5 500   5 500   6 510   6 510   6 510   6 510   6 510   6 510   6 510   6 510   6 510   6 510   7 520   7 520   7 520   7 520   7 520   7 520   7 520   7 520   7 520   7 520   8 530   8 530   8 530   8 530   8 530   8 530   8 530   8 530   8 530   8 530   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540}
           69  +
           70  +do_execsql_test 1.6 {
           71  +  SELECT a, sum(b) OVER (
           72  +    ORDER BY a RANGE BETWEEN 2 PRECEDING AND 2 FOLLOWING
           73  +  ) FROM t3 ORDER BY 1;
           74  +} {0 1480   0 1480   0 1480   0 1480   0 1480   0 1480   0 1480   0 1480   0 1480   0 1480   1 1960   1 1960   1 1960   1 1960   1 1960   1 1960   1 1960   1 1960   1 1960   1 1960   2 2450   2 2450   2 2450   2 2450   2 2450   2 2450   2 2450   2 2450   2 2450   2 2450   3 2400   3 2400   3 2400   3 2400   3 2400   3 2400   3 2400   3 2400   3 2400   3 2400   4 2450   4 2450   4 2450   4 2450   4 2450   4 2450   4 2450   4 2450   4 2450   4 2450   5 2500   5 2500   5 2500   5 2500   5 2500   5 2500   5 2500   5 2500   5 2500   5 2500   6 2550   6 2550   6 2550   6 2550   6 2550   6 2550   6 2550   6 2550   6 2550   6 2550   7 2600   7 2600   7 2600   7 2600   7 2600   7 2600   7 2600   7 2600   7 2600   7 2600   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590}
           75  +
           76  +do_execsql_test 1.7 {
           77  +  SELECT a, sum(b) OVER (
           78  +    ORDER BY a RANGE BETWEEN 2 PRECEDING AND 1 FOLLOWING
           79  +  ) FROM t3 ORDER BY 1;
           80  +} {0 1010   0 1010   0 1010   0 1010   0 1010   0 1010   0 1010   0 1010   0 1010   0 1010   1 1480   1 1480   1 1480   1 1480   1 1480   1 1480   1 1480   1 1480   1 1480   1 1480   2 1960   2 1960   2 1960   2 1960   2 1960   2 1960   2 1960   2 1960   2 1960   2 1960   3 1900   3 1900   3 1900   3 1900   3 1900   3 1900   3 1900   3 1900   3 1900   3 1900   4 1940   4 1940   4 1940   4 1940   4 1940   4 1940   4 1940   4 1940   4 1940   4 1940   5 1980   5 1980   5 1980   5 1980   5 1980   5 1980   5 1980   5 1980   5 1980   5 1980   6 2020   6 2020   6 2020   6 2020   6 2020   6 2020   6 2020   6 2020   6 2020   6 2020   7 2060   7 2060   7 2060   7 2060   7 2060   7 2060   7 2060   7 2060   7 2060   7 2060   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   8 2100   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590   9 1590}
           81  +
           82  +do_execsql_test 1.8.1 {
           83  +  SELECT a, sum(b) OVER (
           84  +    ORDER BY a RANGE BETWEEN 0 PRECEDING AND 1 FOLLOWING
           85  +  ) FROM t3 ORDER BY 1;
           86  +} {0 1010   0 1010   0 1010   0 1010   0 1010   0 1010   0 1010   0 1010   0 1010   0 1010   1 930   1 930   1 930   1 930   1 930   1 930   1 930   1 930   1 930   1 930   2 950   2 950   2 950   2 950   2 950   2 950   2 950   2 950   2 950   2 950   3 970   3 970   3 970   3 970   3 970   3 970   3 970   3 970   3 970   3 970   4 990   4 990   4 990   4 990   4 990   4 990   4 990   4 990   4 990   4 990   5 1010   5 1010   5 1010   5 1010   5 1010   5 1010   5 1010   5 1010   5 1010   5 1010   6 1030   6 1030   6 1030   6 1030   6 1030   6 1030   6 1030   6 1030   6 1030   6 1030   7 1050   7 1050   7 1050   7 1050   7 1050   7 1050   7 1050   7 1050   7 1050   7 1050   8 1070   8 1070   8 1070   8 1070   8 1070   8 1070   8 1070   8 1070   8 1070   8 1070   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540   9 540}
           87  +
           88  +do_execsql_test 1.8.2 {
           89  +  SELECT a, sum(b) OVER (
           90  +    ORDER BY a DESC RANGE BETWEEN 0 PRECEDING AND 1 FOLLOWING
           91  +  ) FROM t3 ORDER BY 1;
           92  +} {0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   0 550   1 1010   1 1010   1 1010   1 1010   1 1010   1 1010   1 1010   1 1010   1 1010   1 1010   2 930   2 930   2 930   2 930   2 930   2 930   2 930   2 930   2 930   2 930   3 950   3 950   3 950   3 950   3 950   3 950   3 950   3 950   3 950   3 950   4 970   4 970   4 970   4 970   4 970   4 970   4 970   4 970   4 970   4 970   5 990   5 990   5 990   5 990   5 990   5 990   5 990   5 990   5 990   5 990   6 1010   6 1010   6 1010   6 1010   6 1010   6 1010   6 1010   6 1010   6 1010   6 1010   7 1030   7 1030   7 1030   7 1030   7 1030   7 1030   7 1030   7 1030   7 1030   7 1030   8 1050   8 1050   8 1050   8 1050   8 1050   8 1050   8 1050   8 1050   8 1050   8 1050   9 1070   9 1070   9 1070   9 1070   9 1070   9 1070   9 1070   9 1070   9 1070   9 1070}
           93  +
           94  +finish_test

Added test/window8.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 window8 "2019 March 01"
           18  +ifcapable !windowfunc
           19  +
           20  +execsql_test 1.0 {
           21  +  DROP TABLE IF EXISTS t3;
           22  +  CREATE TABLE t3(a TEXT, b TEXT, c INTEGER);
           23  +  INSERT INTO t3 VALUES
           24  +    ('HH', 'bb', 355), ('CC', 'aa', 158), ('BB', 'aa', 399), 
           25  +    ('FF', 'bb', 938), ('HH', 'aa', 480), ('FF', 'bb', 870), 
           26  +    ('JJ', 'aa', 768), ('JJ', 'aa', 899), ('GG', 'bb', 929), 
           27  +    ('II', 'bb', 421), ('GG', 'bb', 844), ('FF', 'bb', 574), 
           28  +    ('CC', 'bb', 822), ('GG', 'bb', 938), ('BB', 'aa', 660), 
           29  +    ('HH', 'aa', 979), ('BB', 'bb', 792), ('DD', 'aa', 845), 
           30  +    ('JJ', 'bb', 354), ('FF', 'bb', 295), ('JJ', 'aa', 234), 
           31  +    ('BB', 'bb', 840), ('AA', 'aa', 934), ('EE', 'aa', 113), 
           32  +    ('AA', 'bb', 309), ('BB', 'aa', 412), ('AA', 'aa', 911), 
           33  +    ('AA', 'bb', 572), ('II', 'aa', 398), ('II', 'bb', 250), 
           34  +    ('II', 'aa', 652), ('BB', 'bb', 633), ('AA', 'aa', 239), 
           35  +    ('FF', 'aa', 670), ('BB', 'bb', 705), ('HH', 'bb', 963), 
           36  +    ('CC', 'bb', 346), ('II', 'bb', 671), ('BB', 'aa', 247), 
           37  +    ('AA', 'aa', 223), ('GG', 'aa', 480), ('HH', 'aa', 790), 
           38  +    ('FF', 'aa', 208), ('BB', 'bb', 711), ('EE', 'aa', 777), 
           39  +    ('DD', 'bb', 716), ('CC', 'aa', 759), ('CC', 'aa', 430), 
           40  +    ('CC', 'aa', 607), ('DD', 'bb', 794), ('GG', 'aa', 148), 
           41  +    ('GG', 'aa', 634), ('JJ', 'bb', 257), ('DD', 'bb', 959), 
           42  +    ('FF', 'bb', 726), ('BB', 'aa', 762), ('JJ', 'bb', 336), 
           43  +    ('GG', 'aa', 335), ('HH', 'bb', 330), ('GG', 'bb', 160), 
           44  +    ('JJ', 'bb', 839), ('FF', 'aa', 618), ('BB', 'aa', 393), 
           45  +    ('EE', 'bb', 629), ('FF', 'aa', 667), ('AA', 'bb', 870), 
           46  +    ('FF', 'bb', 102), ('JJ', 'aa', 113), ('DD', 'aa', 224), 
           47  +    ('AA', 'bb', 627), ('HH', 'bb', 730), ('II', 'bb', 443), 
           48  +    ('HH', 'bb', 133), ('EE', 'bb', 252), ('II', 'bb', 805), 
           49  +    ('BB', 'bb', 786), ('EE', 'bb', 768), ('HH', 'bb', 683), 
           50  +    ('DD', 'bb', 238), ('DD', 'aa', 256);
           51  +}
           52  +
           53  +foreach {tn frame} {
           54  +  1  { GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING }
           55  +  2  { GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW }
           56  +  3  { GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING }
           57  +  4  { GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING }
           58  +  5  { GROUPS BETWEEN 1 PRECEDING         AND 2 PRECEDING }
           59  +  6  { GROUPS BETWEEN 2 PRECEDING         AND 1 PRECEDING }
           60  +  7  { GROUPS BETWEEN 3 PRECEDING         AND 1 PRECEDING }
           61  +  8  { GROUPS BETWEEN 3 PRECEDING         AND 0 PRECEDING }
           62  +  9  { GROUPS BETWEEN 2 PRECEDING         AND CURRENT ROW }
           63  +  10 { GROUPS BETWEEN 3 PRECEDING         AND 0 FOLLOWING }
           64  +  11 { GROUPS BETWEEN 2 PRECEDING         AND UNBOUNDED FOLLOWING }
           65  +  12 { GROUPS BETWEEN CURRENT ROW         AND 0 FOLLOWING }
           66  +  13 { GROUPS BETWEEN CURRENT ROW         AND 1 FOLLOWING }
           67  +  14 { GROUPS BETWEEN CURRENT ROW         AND 100 FOLLOWING }
           68  +  15 { GROUPS BETWEEN CURRENT ROW         AND UNBOUNDED FOLLOWING }
           69  +  16 { GROUPS BETWEEN 0 FOLLOWING         AND 0 FOLLOWING }
           70  +  17 { GROUPS BETWEEN 1 FOLLOWING         AND 0 FOLLOWING }
           71  +  18 { GROUPS BETWEEN 1 FOLLOWING         AND 5 FOLLOWING }
           72  +  19 { GROUPS BETWEEN 1 FOLLOWING         AND UNBOUNDED FOLLOWING }
           73  +
           74  +} {
           75  +  execsql_test 1.$tn.1 "
           76  +    SELECT a, b, sum(c) OVER (ORDER BY a $frame) FROM t3 ORDER BY 1, 2, 3;
           77  +  "
           78  +  execsql_test 1.$tn.2 "
           79  +    SELECT a, b, sum(c) OVER (ORDER BY a,b $frame) FROM t3 ORDER BY 1, 2, 3;
           80  +  "
           81  +  execsql_test 1.$tn.3 "
           82  +    SELECT a, b, rank() OVER (ORDER BY a $frame) FROM t3 ORDER BY 1, 2, 3;
           83  +  "
           84  +  execsql_test 1.$tn.4 "
           85  +    SELECT a, b, max(c) OVER (ORDER BY a,b $frame) FROM t3 ORDER BY 1, 2, 3;
           86  +  "
           87  +  execsql_test 1.$tn.5 "
           88  +    SELECT a, b, min(c) OVER (ORDER BY a,b $frame) FROM t3 ORDER BY 1, 2, 3;
           89  +  "
           90  +
           91  +  set f2 "$frame EXCLUDE CURRENT ROW"
           92  +
           93  +  execsql_test 1.$tn.6 "
           94  +    SELECT a, b, sum(c) OVER (ORDER BY a $f2) FROM t3 ORDER BY 1, 2, 3;
           95  +  "
           96  +  execsql_test 1.$tn.7 "
           97  +    SELECT a, b, sum(c) OVER (ORDER BY a,b $f2) FROM t3 ORDER BY 1, 2, 3;
           98  +  "
           99  +
          100  +  execsql_test 1.$tn.8 "
          101  +    SELECT a, b, 
          102  +      sum(c) OVER (ORDER BY a $f2),
          103  +      sum(c) OVER (ORDER BY a $frame),
          104  +      sum(c) OVER (ORDER BY a,b $f2),
          105  +      sum(c) OVER (ORDER BY a,b $frame)
          106  +    FROM t3 ORDER BY 1, 2, 3;
          107  +  "
          108  +}
          109  +
          110  +
          111  +foreach {tn ex} {
          112  +  1  { EXCLUDE NO OTHERS }
          113  +  2  { EXCLUDE CURRENT ROW }
          114  +  3  { EXCLUDE GROUP }
          115  +  4  { EXCLUDE TIES }
          116  +} {
          117  +  execsql_test 2.$tn.1 "
          118  +    SELECT row_number() OVER win 
          119  +    FROM t3
          120  +    WINDOW win AS (
          121  +      ORDER BY c, b, a
          122  +      ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING $ex
          123  +    )
          124  +  "
          125  +
          126  +  execsql_test 2.$tn.2 "
          127  +    SELECT nth_value(c, 14) OVER win 
          128  +    FROM t3
          129  +    WINDOW win AS (
          130  +      ORDER BY c, b, a
          131  +      ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING $ex
          132  +    )
          133  +  "
          134  +
          135  +  execsql_test 2.$tn.3 "
          136  +    SELECT min(c) OVER win, max(c) OVER win, sum(c) OVER win FROM t3
          137  +    WINDOW win AS (
          138  +      ORDER BY c, b, a
          139  +      ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW $ex
          140  +    ) ORDER BY a, b, c;
          141  +  "
          142  +}
          143  +
          144  +==========
          145  +
          146  +execsql_test 3.0 {
          147  +  DROP TABLE IF EXISTS t1;
          148  +  CREATE TABLE t1(a REAL, b INTEGER);
          149  +  INSERT INTO t1 VALUES
          150  +      (5, 10), (10, 20), (13, 26), (13, 26), 
          151  +      (15, 30), (20, 40), (22,80), (30, 90);
          152  +}
          153  +
          154  +foreach {tn frame} {
          155  +  1 { ORDER BY a RANGE BETWEEN 5 PRECEDING AND 5 FOLLOWING }
          156  +  2 { ORDER BY a RANGE BETWEEN 10 PRECEDING AND 5 PRECEDING }
          157  +  3 { ORDER BY a RANGE BETWEEN 2 FOLLOWING AND 3 FOLLOWING }
          158  +  4 { ORDER BY a DESC RANGE BETWEEN 5 PRECEDING AND 5 FOLLOWING }
          159  +  5 { ORDER BY a DESC RANGE BETWEEN 10 PRECEDING AND 5 PRECEDING }
          160  +  6 { ORDER BY a DESC RANGE BETWEEN 2 FOLLOWING AND 3 FOLLOWING }
          161  +
          162  +  7  { ORDER BY a RANGE BETWEEN 5.1 PRECEDING AND 5.3 FOLLOWING }
          163  +  8  { ORDER BY a RANGE BETWEEN 10.2 PRECEDING AND 5.4 PRECEDING }
          164  +  9  { ORDER BY a RANGE BETWEEN 2.6 FOLLOWING AND 3.5 FOLLOWING }
          165  +  10 { ORDER BY a DESC RANGE BETWEEN 5.7 PRECEDING AND 5.8 FOLLOWING }
          166  +  11 { ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND 5.9 PRECEDING }
          167  +  12 { ORDER BY a DESC RANGE BETWEEN 2.1 FOLLOWING AND UNBOUNDED FOLLOWING }
          168  +  13  { ORDER BY a RANGE 5.1 PRECEDING }
          169  +} {
          170  +  execsql_test 3.$tn "
          171  +    SELECT CAST(a AS INTEGER), sum(b) OVER win FROM t1 WINDOW win AS ($frame)
          172  +  "
          173  +}
          174  +
          175  +==========
          176  +
          177  +execsql_test 4.0 {
          178  +  DROP TABLE IF EXISTS t1;
          179  +  CREATE TABLE t1(a INTEGER, b INTEGER);
          180  +  INSERT INTO t1 VALUES
          181  +    (NULL, 1), (NULL, 2), (NULL, 3), (10, 4), (10, 5);
          182  +}
          183  +
          184  +execsql_test 4.1.1 {
          185  +  SELECT sum(b) OVER (
          186  +    ORDER BY a RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING
          187  +  ) FROM t1 ORDER BY 1;
          188  +}
          189  +execsql_test 4.1.2 {
          190  +  SELECT sum(b) OVER (
          191  +    ORDER BY a DESC RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING
          192  +  ) FROM t1 ORDER BY 1;
          193  +}
          194  +
          195  +execsql_test 4.2.1 {
          196  +  SELECT sum(b) OVER (
          197  +    ORDER BY a RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING
          198  +  ) FROM t1 ORDER BY 1 NULLS FIRST;
          199  +}
          200  +
          201  +execsql_test 4.2.2 {
          202  +  SELECT sum(b) OVER (
          203  +    ORDER BY a DESC RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING
          204  +  ) FROM t1 ORDER BY 1 NULLS FIRST;
          205  +}
          206  +
          207  +execsql_test 4.3.1 {
          208  +  SELECT sum(b) OVER (
          209  +    ORDER BY a NULLS FIRST RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING
          210  +  ) FROM t1 ORDER BY 1 NULLS FIRST;
          211  +}
          212  +
          213  +execsql_test 4.4.1 {
          214  +  SELECT sum(b) OVER (
          215  +    ORDER BY a NULLS FIRST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
          216  +  ) FROM t1 ORDER BY 1 NULLS FIRST;
          217  +}
          218  +
          219  +execsql_test 4.4.2 {
          220  +  SELECT sum(b) OVER (
          221  +    ORDER BY a DESC NULLS LAST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
          222  +  ) FROM t1 ORDER BY 1 NULLS FIRST;
          223  +}
          224  +
          225  +==========
          226  +
          227  +execsql_test 5.0 {
          228  +  INSERT INTO t3 VALUES
          229  +    (NULL, 'bb', 355), (NULL, 'cc', 158), (NULL, 'aa', 399), 
          230  +    ('JJ', NULL, 839), ('FF', NULL, 618), ('BB', NULL, 393), 
          231  +    (NULL, 'bb', 629), (NULL, NULL, 667), (NULL, NULL, 870);
          232  +}
          233  +
          234  +foreach {tn ex} {
          235  +  1  { EXCLUDE NO OTHERS }
          236  +  2  { EXCLUDE CURRENT ROW }
          237  +  3  { EXCLUDE GROUP }
          238  +  4  { EXCLUDE TIES }
          239  +} {
          240  +  foreach {tn2 frame} {
          241  +    1 { RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING }
          242  +    2 { ORDER BY a NULLS FIRST 
          243  +        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING }
          244  +    3 { PARTITION BY coalesce(a, '') 
          245  +        RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING }
          246  +    4 { ORDER BY a NULLS FIRST GROUPS 6 PRECEDING }
          247  +    5 { ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING }
          248  +    6 { ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING }
          249  +    7 { ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST
          250  +        ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING }
          251  +  } {
          252  +    execsql_test 5.$tn.$tn2.1 "
          253  +      SELECT max(c) OVER win,
          254  +             min(c) OVER win,
          255  +             count(a) OVER win
          256  +      FROM t3
          257  +      WINDOW win AS ( $frame $ex )
          258  +      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
          259  +    "
          260  +
          261  +    execsql_test 5.$tn.$tn2.2 "
          262  +      SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
          263  +             rank() OVER win,
          264  +             dense_rank() OVER win
          265  +      FROM t3
          266  +      WINDOW win AS ( $frame $ex )
          267  +      ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
          268  +    "
          269  +  }
          270  +}
          271  +
          272  +finish_test
          273  +
          274  +

Added test/window8.test.

            1  +# 2019 March 01
            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 window8
           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, b TEXT, c INTEGER);
           26  +  INSERT INTO t3 VALUES
           27  +    ('HH', 'bb', 355), ('CC', 'aa', 158), ('BB', 'aa', 399), 
           28  +    ('FF', 'bb', 938), ('HH', 'aa', 480), ('FF', 'bb', 870), 
           29  +    ('JJ', 'aa', 768), ('JJ', 'aa', 899), ('GG', 'bb', 929), 
           30  +    ('II', 'bb', 421), ('GG', 'bb', 844), ('FF', 'bb', 574), 
           31  +    ('CC', 'bb', 822), ('GG', 'bb', 938), ('BB', 'aa', 660), 
           32  +    ('HH', 'aa', 979), ('BB', 'bb', 792), ('DD', 'aa', 845), 
           33  +    ('JJ', 'bb', 354), ('FF', 'bb', 295), ('JJ', 'aa', 234), 
           34  +    ('BB', 'bb', 840), ('AA', 'aa', 934), ('EE', 'aa', 113), 
           35  +    ('AA', 'bb', 309), ('BB', 'aa', 412), ('AA', 'aa', 911), 
           36  +    ('AA', 'bb', 572), ('II', 'aa', 398), ('II', 'bb', 250), 
           37  +    ('II', 'aa', 652), ('BB', 'bb', 633), ('AA', 'aa', 239), 
           38  +    ('FF', 'aa', 670), ('BB', 'bb', 705), ('HH', 'bb', 963), 
           39  +    ('CC', 'bb', 346), ('II', 'bb', 671), ('BB', 'aa', 247), 
           40  +    ('AA', 'aa', 223), ('GG', 'aa', 480), ('HH', 'aa', 790), 
           41  +    ('FF', 'aa', 208), ('BB', 'bb', 711), ('EE', 'aa', 777), 
           42  +    ('DD', 'bb', 716), ('CC', 'aa', 759), ('CC', 'aa', 430), 
           43  +    ('CC', 'aa', 607), ('DD', 'bb', 794), ('GG', 'aa', 148), 
           44  +    ('GG', 'aa', 634), ('JJ', 'bb', 257), ('DD', 'bb', 959), 
           45  +    ('FF', 'bb', 726), ('BB', 'aa', 762), ('JJ', 'bb', 336), 
           46  +    ('GG', 'aa', 335), ('HH', 'bb', 330), ('GG', 'bb', 160), 
           47  +    ('JJ', 'bb', 839), ('FF', 'aa', 618), ('BB', 'aa', 393), 
           48  +    ('EE', 'bb', 629), ('FF', 'aa', 667), ('AA', 'bb', 870), 
           49  +    ('FF', 'bb', 102), ('JJ', 'aa', 113), ('DD', 'aa', 224), 
           50  +    ('AA', 'bb', 627), ('HH', 'bb', 730), ('II', 'bb', 443), 
           51  +    ('HH', 'bb', 133), ('EE', 'bb', 252), ('II', 'bb', 805), 
           52  +    ('BB', 'bb', 786), ('EE', 'bb', 768), ('HH', 'bb', 683), 
           53  +    ('DD', 'bb', 238), ('DD', 'aa', 256);
           54  +} {}
           55  +
           56  +do_execsql_test 1.1.1 {
           57  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
           58  +} {AA aa {}   AA aa {}   AA aa {}   AA aa {}   AA bb {}   AA bb {}   AA bb {}
           59  +  AA bb {}   BB aa 4685   BB aa 4685   BB aa 4685   BB aa 4685   BB aa 4685
           60  +  BB aa 4685   BB bb 4685   BB bb 4685   BB bb 4685   BB bb 4685   BB bb 4685
           61  +  BB bb 4685   CC aa 12025   CC aa 12025   CC aa 12025   CC aa 12025
           62  +  CC bb 12025   CC bb 12025   DD aa 15147   DD aa 15147   DD aa 15147
           63  +  DD bb 15147   DD bb 15147   DD bb 15147   DD bb 15147   EE aa 19179
           64  +  EE aa 19179   EE bb 19179   EE bb 19179   EE bb 19179   FF aa 21718
           65  +  FF aa 21718   FF aa 21718   FF aa 21718   FF bb 21718   FF bb 21718
           66  +  FF bb 21718   FF bb 21718   FF bb 21718   FF bb 21718   GG aa 27386
           67  +  GG aa 27386   GG aa 27386   GG aa 27386   GG bb 27386   GG bb 27386
           68  +  GG bb 27386   GG bb 27386   HH aa 31854   HH aa 31854   HH aa 31854
           69  +  HH bb 31854   HH bb 31854   HH bb 31854   HH bb 31854   HH bb 31854
           70  +  HH bb 31854   II aa 37297   II aa 37297   II bb 37297   II bb 37297
           71  +  II bb 37297   II bb 37297   II bb 37297   JJ aa 40937   JJ aa 40937
           72  +  JJ aa 40937   JJ aa 40937   JJ bb 40937   JJ bb 40937   JJ bb 40937
           73  +  JJ bb 40937}
           74  +
           75  +do_execsql_test 1.1.2 {
           76  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
           77  +} {AA aa {}   AA aa {}   AA aa {}   AA aa {}   AA bb 2307   AA bb 2307
           78  +  AA bb 2307   AA bb 2307   BB aa 4685   BB aa 4685   BB aa 4685   BB aa 4685
           79  +  BB aa 4685   BB aa 4685   BB bb 7558   BB bb 7558   BB bb 7558   BB bb 7558
           80  +  BB bb 7558   BB bb 7558   CC aa 12025   CC aa 12025   CC aa 12025
           81  +  CC aa 12025   CC bb 13979   CC bb 13979   DD aa 15147   DD aa 15147
           82  +  DD aa 15147   DD bb 16472   DD bb 16472   DD bb 16472   DD bb 16472
           83  +  EE aa 19179   EE aa 19179   EE bb 20069   EE bb 20069   EE bb 20069
           84  +  FF aa 21718   FF aa 21718   FF aa 21718   FF aa 21718   FF bb 23881
           85  +  FF bb 23881   FF bb 23881   FF bb 23881   FF bb 23881   FF bb 23881
           86  +  GG aa 27386   GG aa 27386   GG aa 27386   GG aa 27386   GG bb 28983
           87  +  GG bb 28983   GG bb 28983   GG bb 28983   HH aa 31854   HH aa 31854
           88  +  HH aa 31854   HH bb 34103   HH bb 34103   HH bb 34103   HH bb 34103
           89  +  HH bb 34103   HH bb 34103   II aa 37297   II aa 37297   II bb 38347
           90  +  II bb 38347   II bb 38347   II bb 38347   II bb 38347   JJ aa 40937
           91  +  JJ aa 40937   JJ aa 40937   JJ aa 40937   JJ bb 42951   JJ bb 42951
           92  +  JJ bb 42951   JJ bb 42951}
           93  +
           94  +do_execsql_test 1.1.3 {
           95  +  SELECT a, b, rank() OVER (ORDER BY a  GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
           96  +} {AA aa 1   AA aa 1   AA aa 1   AA aa 1   AA bb 1   AA bb 1   AA bb 1
           97  +  AA bb 1   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9
           98  +  BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   CC aa 21
           99  +  CC aa 21   CC aa 21   CC aa 21   CC bb 21   CC bb 21   DD aa 27   DD aa 27
          100  +  DD aa 27   DD bb 27   DD bb 27   DD bb 27   DD bb 27   EE aa 34   EE aa 34
          101  +  EE bb 34   EE bb 34   EE bb 34   FF aa 39   FF aa 39   FF aa 39   FF aa 39
          102  +  FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   GG aa 49
          103  +  GG aa 49   GG aa 49   GG aa 49   GG bb 49   GG bb 49   GG bb 49   GG bb 49
          104  +  HH aa 57   HH aa 57   HH aa 57   HH bb 57   HH bb 57   HH bb 57   HH bb 57
          105  +  HH bb 57   HH bb 57   II aa 66   II aa 66   II bb 66   II bb 66   II bb 66
          106  +  II bb 66   II bb 66   JJ aa 73   JJ aa 73   JJ aa 73   JJ aa 73   JJ bb 73
          107  +  JJ bb 73   JJ bb 73   JJ bb 73}
          108  +
          109  +do_execsql_test 1.1.4 {
          110  +  SELECT a, b, max(c) OVER (ORDER BY a,b  GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
          111  +} {AA aa {}   AA aa {}   AA aa {}   AA aa {}   AA bb 934   AA bb 934
          112  +  AA bb 934   AA bb 934   BB aa 934   BB aa 934   BB aa 934   BB aa 934
          113  +  BB aa 934   BB aa 934   BB bb 934   BB bb 934   BB bb 934   BB bb 934
          114  +  BB bb 934   BB bb 934   CC aa 934   CC aa 934   CC aa 934   CC aa 934
          115  +  CC bb 934   CC bb 934   DD aa 934   DD aa 934   DD aa 934   DD bb 934
          116  +  DD bb 934   DD bb 934   DD bb 934   EE aa 959   EE aa 959   EE bb 959
          117  +  EE bb 959   EE bb 959   FF aa 959   FF aa 959   FF aa 959   FF aa 959
          118  +  FF bb 959   FF bb 959   FF bb 959   FF bb 959   FF bb 959   FF bb 959
          119  +  GG aa 959   GG aa 959   GG aa 959   GG aa 959   GG bb 959   GG bb 959
          120  +  GG bb 959   GG bb 959   HH aa 959   HH aa 959   HH aa 959   HH bb 979
          121  +  HH bb 979   HH bb 979   HH bb 979   HH bb 979   HH bb 979   II aa 979
          122  +  II aa 979   II bb 979   II bb 979   II bb 979   II bb 979   II bb 979
          123  +  JJ aa 979   JJ aa 979   JJ aa 979   JJ aa 979   JJ bb 979   JJ bb 979
          124  +  JJ bb 979   JJ bb 979}
          125  +
          126  +do_execsql_test 1.1.5 {
          127  +  SELECT a, b, min(c) OVER (ORDER BY a,b  GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
          128  +} {AA aa {}   AA aa {}   AA aa {}   AA aa {}   AA bb 223   AA bb 223
          129  +  AA bb 223   AA bb 223   BB aa 223   BB aa 223   BB aa 223   BB aa 223
          130  +  BB aa 223   BB aa 223   BB bb 223   BB bb 223   BB bb 223   BB bb 223
          131  +  BB bb 223   BB bb 223   CC aa 223   CC aa 223   CC aa 223   CC aa 223
          132  +  CC bb 158   CC bb 158   DD aa 158   DD aa 158   DD aa 158   DD bb 158
          133  +  DD bb 158   DD bb 158   DD bb 158   EE aa 158   EE aa 158   EE bb 113
          134  +  EE bb 113   EE bb 113   FF aa 113   FF aa 113   FF aa 113   FF aa 113
          135  +  FF bb 113   FF bb 113   FF bb 113   FF bb 113   FF bb 113   FF bb 113
          136  +  GG aa 102   GG aa 102   GG aa 102   GG aa 102   GG bb 102   GG bb 102
          137  +  GG bb 102   GG bb 102   HH aa 102   HH aa 102   HH aa 102   HH bb 102
          138  +  HH bb 102   HH bb 102   HH bb 102   HH bb 102   HH bb 102   II aa 102
          139  +  II aa 102   II bb 102   II bb 102   II bb 102   II bb 102   II bb 102
          140  +  JJ aa 102   JJ aa 102   JJ aa 102   JJ aa 102   JJ bb 102   JJ bb 102
          141  +  JJ bb 102   JJ bb 102}
          142  +
          143  +do_execsql_test 1.1.6 {
          144  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
          145  +} {AA aa {}   AA aa {}   AA aa {}   AA aa {}   AA bb {}   AA bb {}   AA bb {}
          146  +  AA bb {}   BB aa 4685   BB aa 4685   BB aa 4685   BB aa 4685   BB aa 4685
          147  +  BB aa 4685   BB bb 4685   BB bb 4685   BB bb 4685   BB bb 4685   BB bb 4685
          148  +  BB bb 4685   CC aa 12025   CC aa 12025   CC aa 12025   CC aa 12025
          149  +  CC bb 12025   CC bb 12025   DD aa 15147   DD aa 15147   DD aa 15147
          150  +  DD bb 15147   DD bb 15147   DD bb 15147   DD bb 15147   EE aa 19179
          151  +  EE aa 19179   EE bb 19179   EE bb 19179   EE bb 19179   FF aa 21718
          152  +  FF aa 21718   FF aa 21718   FF aa 21718   FF bb 21718   FF bb 21718
          153  +  FF bb 21718   FF bb 21718   FF bb 21718   FF bb 21718   GG aa 27386
          154  +  GG aa 27386   GG aa 27386   GG aa 27386   GG bb 27386   GG bb 27386
          155  +  GG bb 27386   GG bb 27386   HH aa 31854   HH aa 31854   HH aa 31854
          156  +  HH bb 31854   HH bb 31854   HH bb 31854   HH bb 31854   HH bb 31854
          157  +  HH bb 31854   II aa 37297   II aa 37297   II bb 37297   II bb 37297
          158  +  II bb 37297   II bb 37297   II bb 37297   JJ aa 40937   JJ aa 40937
          159  +  JJ aa 40937   JJ aa 40937   JJ bb 40937   JJ bb 40937   JJ bb 40937
          160  +  JJ bb 40937}
          161  +
          162  +do_execsql_test 1.1.7 {
          163  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
          164  +} {AA aa {}   AA aa {}   AA aa {}   AA aa {}   AA bb 2307   AA bb 2307
          165  +  AA bb 2307   AA bb 2307   BB aa 4685   BB aa 4685   BB aa 4685   BB aa 4685
          166  +  BB aa 4685   BB aa 4685   BB bb 7558   BB bb 7558   BB bb 7558   BB bb 7558
          167  +  BB bb 7558   BB bb 7558   CC aa 12025   CC aa 12025   CC aa 12025
          168  +  CC aa 12025   CC bb 13979   CC bb 13979   DD aa 15147   DD aa 15147
          169  +  DD aa 15147   DD bb 16472   DD bb 16472   DD bb 16472   DD bb 16472
          170  +  EE aa 19179   EE aa 19179   EE bb 20069   EE bb 20069   EE bb 20069
          171  +  FF aa 21718   FF aa 21718   FF aa 21718   FF aa 21718   FF bb 23881
          172  +  FF bb 23881   FF bb 23881   FF bb 23881   FF bb 23881   FF bb 23881
          173  +  GG aa 27386   GG aa 27386   GG aa 27386   GG aa 27386   GG bb 28983
          174  +  GG bb 28983   GG bb 28983   GG bb 28983   HH aa 31854   HH aa 31854
          175  +  HH aa 31854   HH bb 34103   HH bb 34103   HH bb 34103   HH bb 34103
          176  +  HH bb 34103   HH bb 34103   II aa 37297   II aa 37297   II bb 38347
          177  +  II bb 38347   II bb 38347   II bb 38347   II bb 38347   JJ aa 40937
          178  +  JJ aa 40937   JJ aa 40937   JJ aa 40937   JJ bb 42951   JJ bb 42951
          179  +  JJ bb 42951   JJ bb 42951}
          180  +
          181  +do_execsql_test 1.1.8 {
          182  +  SELECT a, b, 
          183  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING  EXCLUDE CURRENT ROW),
          184  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ),
          185  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING  EXCLUDE CURRENT ROW),
          186  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING )
          187  +    FROM t3 ORDER BY 1, 2, 3;
          188  +} {AA aa {} {} {} {}   AA aa {} {} {} {}   AA aa {} {} {} {}
          189  +  AA aa {} {} {} {}   AA bb {} {} 2307 2307   AA bb {} {} 2307 2307
          190  +  AA bb {} {} 2307 2307   AA bb {} {} 2307 2307   BB aa 4685 4685 4685 4685
          191  +  BB aa 4685 4685 4685 4685   BB aa 4685 4685 4685 4685
          192  +  BB aa 4685 4685 4685 4685   BB aa 4685 4685 4685 4685
          193  +  BB aa 4685 4685 4685 4685   BB bb 4685 4685 7558 7558
          194  +  BB bb 4685 4685 7558 7558   BB bb 4685 4685 7558 7558
          195  +  BB bb 4685 4685 7558 7558   BB bb 4685 4685 7558 7558
          196  +  BB bb 4685 4685 7558 7558   CC aa 12025 12025 12025 12025
          197  +  CC aa 12025 12025 12025 12025   CC aa 12025 12025 12025 12025
          198  +  CC aa 12025 12025 12025 12025   CC bb 12025 12025 13979 13979
          199  +  CC bb 12025 12025 13979 13979   DD aa 15147 15147 15147 15147
          200  +  DD aa 15147 15147 15147 15147   DD aa 15147 15147 15147 15147
          201  +  DD bb 15147 15147 16472 16472   DD bb 15147 15147 16472 16472
          202  +  DD bb 15147 15147 16472 16472   DD bb 15147 15147 16472 16472
          203  +  EE aa 19179 19179 19179 19179   EE aa 19179 19179 19179 19179
          204  +  EE bb 19179 19179 20069 20069   EE bb 19179 19179 20069 20069
          205  +  EE bb 19179 19179 20069 20069   FF aa 21718 21718 21718 21718
          206  +  FF aa 21718 21718 21718 21718   FF aa 21718 21718 21718 21718
          207  +  FF aa 21718 21718 21718 21718   FF bb 21718 21718 23881 23881
          208  +  FF bb 21718 21718 23881 23881   FF bb 21718 21718 23881 23881
          209  +  FF bb 21718 21718 23881 23881   FF bb 21718 21718 23881 23881
          210  +  FF bb 21718 21718 23881 23881   GG aa 27386 27386 27386 27386
          211  +  GG aa 27386 27386 27386 27386   GG aa 27386 27386 27386 27386
          212  +  GG aa 27386 27386 27386 27386   GG bb 27386 27386 28983 28983
          213  +  GG bb 27386 27386 28983 28983   GG bb 27386 27386 28983 28983
          214  +  GG bb 27386 27386 28983 28983   HH aa 31854 31854 31854 31854
          215  +  HH aa 31854 31854 31854 31854   HH aa 31854 31854 31854 31854
          216  +  HH bb 31854 31854 34103 34103   HH bb 31854 31854 34103 34103
          217  +  HH bb 31854 31854 34103 34103   HH bb 31854 31854 34103 34103
          218  +  HH bb 31854 31854 34103 34103   HH bb 31854 31854 34103 34103
          219  +  II aa 37297 37297 37297 37297   II aa 37297 37297 37297 37297
          220  +  II bb 37297 37297 38347 38347   II bb 37297 37297 38347 38347
          221  +  II bb 37297 37297 38347 38347   II bb 37297 37297 38347 38347
          222  +  II bb 37297 37297 38347 38347   JJ aa 40937 40937 40937 40937
          223  +  JJ aa 40937 40937 40937 40937   JJ aa 40937 40937 40937 40937
          224  +  JJ aa 40937 40937 40937 40937   JJ bb 40937 40937 42951 42951
          225  +  JJ bb 40937 40937 42951 42951   JJ bb 40937 40937 42951 42951
          226  +  JJ bb 40937 40937 42951 42951}
          227  +
          228  +do_execsql_test 1.2.1 {
          229  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t3 ORDER BY 1, 2, 3;
          230  +} {AA aa 4685   AA aa 4685   AA aa 4685   AA aa 4685   AA bb 4685   AA bb 4685
          231  +  AA bb 4685   AA bb 4685   BB aa 12025   BB aa 12025   BB aa 12025
          232  +  BB aa 12025   BB aa 12025   BB aa 12025   BB bb 12025   BB bb 12025
          233  +  BB bb 12025   BB bb 12025   BB bb 12025   BB bb 12025   CC aa 15147
          234  +  CC aa 15147   CC aa 15147   CC aa 15147   CC bb 15147   CC bb 15147
          235  +  DD aa 19179   DD aa 19179   DD aa 19179   DD bb 19179   DD bb 19179
          236  +  DD bb 19179   DD bb 19179   EE aa 21718   EE aa 21718   EE bb 21718
          237  +  EE bb 21718   EE bb 21718   FF aa 27386   FF aa 27386   FF aa 27386
          238  +  FF aa 27386   FF bb 27386   FF bb 27386   FF bb 27386   FF bb 27386
          239  +  FF bb 27386   FF bb 27386   GG aa 31854   GG aa 31854   GG aa 31854
          240  +  GG aa 31854   GG bb 31854   GG bb 31854   GG bb 31854   GG bb 31854
          241  +  HH aa 37297   HH aa 37297   HH aa 37297   HH bb 37297   HH bb 37297
          242  +  HH bb 37297   HH bb 37297   HH bb 37297   HH bb 37297   II aa 40937
          243  +  II aa 40937   II bb 40937   II bb 40937   II bb 40937   II bb 40937
          244  +  II bb 40937   JJ aa 44737   JJ aa 44737   JJ aa 44737   JJ aa 44737
          245  +  JJ bb 44737   JJ bb 44737   JJ bb 44737   JJ bb 44737}
          246  +
          247  +do_execsql_test 1.2.2 {
          248  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t3 ORDER BY 1, 2, 3;
          249  +} {AA aa 2307   AA aa 2307   AA aa 2307   AA aa 2307   AA bb 4685   AA bb 4685
          250  +  AA bb 4685   AA bb 4685   BB aa 7558   BB aa 7558   BB aa 7558   BB aa 7558
          251  +  BB aa 7558   BB aa 7558   BB bb 12025   BB bb 12025   BB bb 12025
          252  +  BB bb 12025   BB bb 12025   BB bb 12025   CC aa 13979   CC aa 13979
          253  +  CC aa 13979   CC aa 13979   CC bb 15147   CC bb 15147   DD aa 16472
          254  +  DD aa 16472   DD aa 16472   DD bb 19179   DD bb 19179   DD bb 19179
          255  +  DD bb 19179   EE aa 20069   EE aa 20069   EE bb 21718   EE bb 21718
          256  +  EE bb 21718   FF aa 23881   FF aa 23881   FF aa 23881   FF aa 23881
          257  +  FF bb 27386   FF bb 27386   FF bb 27386   FF bb 27386   FF bb 27386
          258  +  FF bb 27386   GG aa 28983   GG aa 28983   GG aa 28983   GG aa 28983
          259  +  GG bb 31854   GG bb 31854   GG bb 31854   GG bb 31854   HH aa 34103
          260  +  HH aa 34103   HH aa 34103   HH bb 37297   HH bb 37297   HH bb 37297
          261  +  HH bb 37297   HH bb 37297   HH bb 37297   II aa 38347   II aa 38347
          262  +  II bb 40937   II bb 40937   II bb 40937   II bb 40937   II bb 40937
          263  +  JJ aa 42951   JJ aa 42951   JJ aa 42951   JJ aa 42951   JJ bb 44737
          264  +  JJ bb 44737   JJ bb 44737   JJ bb 44737}
          265  +
          266  +do_execsql_test 1.2.3 {
          267  +  SELECT a, b, rank() OVER (ORDER BY a  GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t3 ORDER BY 1, 2, 3;
          268  +} {AA aa 1   AA aa 1   AA aa 1   AA aa 1   AA bb 1   AA bb 1   AA bb 1
          269  +  AA bb 1   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9
          270  +  BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   CC aa 21
          271  +  CC aa 21   CC aa 21   CC aa 21   CC bb 21   CC bb 21   DD aa 27   DD aa 27
          272  +  DD aa 27   DD bb 27   DD bb 27   DD bb 27   DD bb 27   EE aa 34   EE aa 34
          273  +  EE bb 34   EE bb 34   EE bb 34   FF aa 39   FF aa 39   FF aa 39   FF aa 39
          274  +  FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   GG aa 49
          275  +  GG aa 49   GG aa 49   GG aa 49   GG bb 49   GG bb 49   GG bb 49   GG bb 49
          276  +  HH aa 57   HH aa 57   HH aa 57   HH bb 57   HH bb 57   HH bb 57   HH bb 57
          277  +  HH bb 57   HH bb 57   II aa 66   II aa 66   II bb 66   II bb 66   II bb 66
          278  +  II bb 66   II bb 66   JJ aa 73   JJ aa 73   JJ aa 73   JJ aa 73   JJ bb 73
          279  +  JJ bb 73   JJ bb 73   JJ bb 73}
          280  +
          281  +do_execsql_test 1.2.4 {
          282  +  SELECT a, b, max(c) OVER (ORDER BY a,b  GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t3 ORDER BY 1, 2, 3;
          283  +} {AA aa 934   AA aa 934   AA aa 934   AA aa 934   AA bb 934   AA bb 934
          284  +  AA bb 934   AA bb 934   BB aa 934   BB aa 934   BB aa 934   BB aa 934
          285  +  BB aa 934   BB aa 934   BB bb 934   BB bb 934   BB bb 934   BB bb 934
          286  +  BB bb 934   BB bb 934   CC aa 934   CC aa 934   CC aa 934   CC aa 934
          287  +  CC bb 934   CC bb 934   DD aa 934   DD aa 934   DD aa 934   DD bb 959
          288  +  DD bb 959   DD bb 959   DD bb 959   EE aa 959   EE aa 959   EE bb 959
          289  +  EE bb 959   EE bb 959   FF aa 959   FF aa 959   FF aa 959   FF aa 959
          290  +  FF bb 959   FF bb 959   FF bb 959   FF bb 959   FF bb 959   FF bb 959
          291  +  GG aa 959   GG aa 959   GG aa 959   GG aa 959   GG bb 959   GG bb 959
          292  +  GG bb 959   GG bb 959   HH aa 979   HH aa 979   HH aa 979   HH bb 979
          293  +  HH bb 979   HH bb 979   HH bb 979   HH bb 979   HH bb 979   II aa 979
          294  +  II aa 979   II bb 979   II bb 979   II bb 979   II bb 979   II bb 979
          295  +  JJ aa 979   JJ aa 979   JJ aa 979   JJ aa 979   JJ bb 979   JJ bb 979
          296  +  JJ bb 979   JJ bb 979}
          297  +
          298  +do_execsql_test 1.2.5 {
          299  +  SELECT a, b, min(c) OVER (ORDER BY a,b  GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t3 ORDER BY 1, 2, 3;
          300  +} {AA aa 223   AA aa 223   AA aa 223   AA aa 223   AA bb 223   AA bb 223
          301  +  AA bb 223   AA bb 223   BB aa 223   BB aa 223   BB aa 223   BB aa 223
          302  +  BB aa 223   BB aa 223   BB bb 223   BB bb 223   BB bb 223   BB bb 223
          303  +  BB bb 223   BB bb 223   CC aa 158   CC aa 158   CC aa 158   CC aa 158
          304  +  CC bb 158   CC bb 158   DD aa 158   DD aa 158   DD aa 158   DD bb 158
          305  +  DD bb 158   DD bb 158   DD bb 158   EE aa 113   EE aa 113   EE bb 113
          306  +  EE bb 113   EE bb 113   FF aa 113   FF aa 113   FF aa 113   FF aa 113
          307  +  FF bb 102   FF bb 102   FF bb 102   FF bb 102   FF bb 102   FF bb 102
          308  +  GG aa 102   GG aa 102   GG aa 102   GG aa 102   GG bb 102   GG bb 102
          309  +  GG bb 102   GG bb 102   HH aa 102   HH aa 102   HH aa 102   HH bb 102
          310  +  HH bb 102   HH bb 102   HH bb 102   HH bb 102   HH bb 102   II aa 102
          311  +  II aa 102   II bb 102   II bb 102   II bb 102   II bb 102   II bb 102
          312  +  JJ aa 102   JJ aa 102   JJ aa 102   JJ aa 102   JJ bb 102   JJ bb 102
          313  +  JJ bb 102   JJ bb 102}
          314  +
          315  +do_execsql_test 1.2.6 {
          316  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
          317  +} {AA aa 3751   AA aa 3774   AA aa 4446   AA aa 4462   AA bb 3815   AA bb 4058
          318  +  AA bb 4113   AA bb 4376   BB aa 11263   BB aa 11365   BB aa 11613
          319  +  BB aa 11626   BB aa 11632   BB aa 11778   BB bb 11185   BB bb 11233
          320  +  BB bb 11239   BB bb 11314   BB bb 11320   BB bb 11392   CC aa 14388
          321  +  CC aa 14540   CC aa 14717   CC aa 14989   CC bb 14325   CC bb 14801
          322  +  DD aa 18334   DD aa 18923   DD aa 18955   DD bb 18220   DD bb 18385
          323  +  DD bb 18463   DD bb 18941   EE aa 20941   EE aa 21605   EE bb 20950
          324  +  EE bb 21089   EE bb 21466   FF aa 26716   FF aa 26719   FF aa 26768
          325  +  FF aa 27178   FF bb 26448   FF bb 26516   FF bb 26660   FF bb 26812
          326  +  FF bb 27091   FF bb 27284   GG aa 31220   GG aa 31374   GG aa 31519
          327  +  GG aa 31706   GG bb 30916   GG bb 30925   GG bb 31010   GG bb 31694
          328  +  HH aa 36318   HH aa 36507   HH aa 36817   HH bb 36334   HH bb 36567
          329  +  HH bb 36614   HH bb 36942   HH bb 36967   HH bb 37164   II aa 40285
          330  +  II aa 40539   II bb 40132   II bb 40266   II bb 40494   II bb 40516
          331  +  II bb 40687   JJ aa 43838   JJ aa 43969   JJ aa 44503   JJ aa 44624
          332  +  JJ bb 43898   JJ bb 44383   JJ bb 44401   JJ bb 44480}
          333  +
          334  +do_execsql_test 1.2.7 {
          335  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
          336  +} {AA aa 1373   AA aa 1396   AA aa 2068   AA aa 2084   AA bb 3815   AA bb 4058
          337  +  AA bb 4113   AA bb 4376   BB aa 6796   BB aa 6898   BB aa 7146   BB aa 7159
          338  +  BB aa 7165   BB aa 7311   BB bb 11185   BB bb 11233   BB bb 11239
          339  +  BB bb 11314   BB bb 11320   BB bb 11392   CC aa 13220   CC aa 13372
          340  +  CC aa 13549   CC aa 13821   CC bb 14325   CC bb 14801   DD aa 15627
          341  +  DD aa 16216   DD aa 16248   DD bb 18220   DD bb 18385   DD bb 18463
          342  +  DD bb 18941   EE aa 19292   EE aa 19956   EE bb 20950   EE bb 21089
          343  +  EE bb 21466   FF aa 23211   FF aa 23214   FF aa 23263   FF aa 23673
          344  +  FF bb 26448   FF bb 26516   FF bb 26660   FF bb 26812   FF bb 27091
          345  +  FF bb 27284   GG aa 28349   GG aa 28503   GG aa 28648   GG aa 28835
          346  +  GG bb 30916   GG bb 30925   GG bb 31010   GG bb 31694   HH aa 33124
          347  +  HH aa 33313   HH aa 33623   HH bb 36334   HH bb 36567   HH bb 36614
          348  +  HH bb 36942   HH bb 36967   HH bb 37164   II aa 37695   II aa 37949
          349  +  II bb 40132   II bb 40266   II bb 40494   II bb 40516   II bb 40687
          350  +  JJ aa 42052   JJ aa 42183   JJ aa 42717   JJ aa 42838   JJ bb 43898
          351  +  JJ bb 44383   JJ bb 44401   JJ bb 44480}
          352  +
          353  +do_execsql_test 1.2.8 {
          354  +  SELECT a, b, 
          355  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW  EXCLUDE CURRENT ROW),
          356  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ),
          357  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW  EXCLUDE CURRENT ROW),
          358  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW )
          359  +    FROM t3 ORDER BY 1, 2, 3;
          360  +} {AA aa 3751 4685 1373 2307   AA aa 3774 4685 1396 2307
          361  +  AA aa 4446 4685 2068 2307   AA aa 4462 4685 2084 2307
          362  +  AA bb 3815 4685 3815 4685   AA bb 4058 4685 4058 4685
          363  +  AA bb 4113 4685 4113 4685   AA bb 4376 4685 4376 4685
          364  +  BB aa 11263 12025 6796 7558   BB aa 11365 12025 6898 7558
          365  +  BB aa 11613 12025 7146 7558   BB aa 11626 12025 7159 7558
          366  +  BB aa 11632 12025 7165 7558   BB aa 11778 12025 7311 7558
          367  +  BB bb 11185 12025 11185 12025   BB bb 11233 12025 11233 12025
          368  +  BB bb 11239 12025 11239 12025   BB bb 11314 12025 11314 12025
          369  +  BB bb 11320 12025 11320 12025   BB bb 11392 12025 11392 12025
          370  +  CC aa 14388 15147 13220 13979   CC aa 14540 15147 13372 13979
          371  +  CC aa 14717 15147 13549 13979   CC aa 14989 15147 13821 13979
          372  +  CC bb 14325 15147 14325 15147   CC bb 14801 15147 14801 15147
          373  +  DD aa 18334 19179 15627 16472   DD aa 18923 19179 16216 16472
          374  +  DD aa 18955 19179 16248 16472   DD bb 18220 19179 18220 19179
          375  +  DD bb 18385 19179 18385 19179   DD bb 18463 19179 18463 19179
          376  +  DD bb 18941 19179 18941 19179   EE aa 20941 21718 19292 20069
          377  +  EE aa 21605 21718 19956 20069   EE bb 20950 21718 20950 21718
          378  +  EE bb 21089 21718 21089 21718   EE bb 21466 21718 21466 21718
          379  +  FF aa 26716 27386 23211 23881   FF aa 26719 27386 23214 23881
          380  +  FF aa 26768 27386 23263 23881   FF aa 27178 27386 23673 23881
          381  +  FF bb 26448 27386 26448 27386   FF bb 26516 27386 26516 27386
          382  +  FF bb 26660 27386 26660 27386   FF bb 26812 27386 26812 27386
          383  +  FF bb 27091 27386 27091 27386   FF bb 27284 27386 27284 27386
          384  +  GG aa 31220 31854 28349 28983   GG aa 31374 31854 28503 28983
          385  +  GG aa 31519 31854 28648 28983   GG aa 31706 31854 28835 28983
          386  +  GG bb 30916 31854 30916 31854   GG bb 30925 31854 30925 31854
          387  +  GG bb 31010 31854 31010 31854   GG bb 31694 31854 31694 31854
          388  +  HH aa 36318 37297 33124 34103   HH aa 36507 37297 33313 34103
          389  +  HH aa 36817 37297 33623 34103   HH bb 36334 37297 36334 37297
          390  +  HH bb 36567 37297 36567 37297   HH bb 36614 37297 36614 37297
          391  +  HH bb 36942 37297 36942 37297   HH bb 36967 37297 36967 37297
          392  +  HH bb 37164 37297 37164 37297   II aa 40285 40937 37695 38347
          393  +  II aa 40539 40937 37949 38347   II bb 40132 40937 40132 40937
          394  +  II bb 40266 40937 40266 40937   II bb 40494 40937 40494 40937
          395  +  II bb 40516 40937 40516 40937   II bb 40687 40937 40687 40937
          396  +  JJ aa 43838 44737 42052 42951   JJ aa 43969 44737 42183 42951
          397  +  JJ aa 44503 44737 42717 42951   JJ aa 44624 44737 42838 42951
          398  +  JJ bb 43898 44737 43898 44737   JJ bb 44383 44737 44383 44737
          399  +  JJ bb 44401 44737 44401 44737   JJ bb 44480 44737 44480 44737}
          400  +
          401  +do_execsql_test 1.3.1 {
          402  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
          403  +} {AA aa 12025   AA aa 12025   AA aa 12025   AA aa 12025   AA bb 12025
          404  +  AA bb 12025   AA bb 12025   AA bb 12025   BB aa 15147   BB aa 15147
          405  +  BB aa 15147   BB aa 15147   BB aa 15147   BB aa 15147   BB bb 15147
          406  +  BB bb 15147   BB bb 15147   BB bb 15147   BB bb 15147   BB bb 15147
          407  +  CC aa 19179   CC aa 19179   CC aa 19179   CC aa 19179   CC bb 19179
          408  +  CC bb 19179   DD aa 21718   DD aa 21718   DD aa 21718   DD bb 21718
          409  +  DD bb 21718   DD bb 21718   DD bb 21718   EE aa 27386   EE aa 27386
          410  +  EE bb 27386   EE bb 27386   EE bb 27386   FF aa 31854   FF aa 31854
          411  +  FF aa 31854   FF aa 31854   FF bb 31854   FF bb 31854   FF bb 31854
          412  +  FF bb 31854   FF bb 31854   FF bb 31854   GG aa 37297   GG aa 37297
          413  +  GG aa 37297   GG aa 37297   GG bb 37297   GG bb 37297   GG bb 37297
          414  +  GG bb 37297   HH aa 40937   HH aa 40937   HH aa 40937   HH bb 40937
          415  +  HH bb 40937   HH bb 40937   HH bb 40937   HH bb 40937   HH bb 40937
          416  +  II aa 44737   II aa 44737   II bb 44737   II bb 44737   II bb 44737
          417  +  II bb 44737   II bb 44737   JJ aa 44737   JJ aa 44737   JJ aa 44737
          418  +  JJ aa 44737   JJ bb 44737   JJ bb 44737   JJ bb 44737   JJ bb 44737}
          419  +
          420  +do_execsql_test 1.3.2 {
          421  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
          422  +} {AA aa 4685   AA aa 4685   AA aa 4685   AA aa 4685   AA bb 7558   AA bb 7558
          423  +  AA bb 7558   AA bb 7558   BB aa 12025   BB aa 12025   BB aa 12025
          424  +  BB aa 12025   BB aa 12025   BB aa 12025   BB bb 13979   BB bb 13979
          425  +  BB bb 13979   BB bb 13979   BB bb 13979   BB bb 13979   CC aa 15147
          426  +  CC aa 15147   CC aa 15147   CC aa 15147   CC bb 16472   CC bb 16472
          427  +  DD aa 19179   DD aa 19179   DD aa 19179   DD bb 20069   DD bb 20069
          428  +  DD bb 20069   DD bb 20069   EE aa 21718   EE aa 21718   EE bb 23881
          429  +  EE bb 23881   EE bb 23881   FF aa 27386   FF aa 27386   FF aa 27386
          430  +  FF aa 27386   FF bb 28983   FF bb 28983   FF bb 28983   FF bb 28983
          431  +  FF bb 28983   FF bb 28983   GG aa 31854   GG aa 31854   GG aa 31854
          432  +  GG aa 31854   GG bb 34103   GG bb 34103   GG bb 34103   GG bb 34103
          433  +  HH aa 37297   HH aa 37297   HH aa 37297   HH bb 38347   HH bb 38347
          434  +  HH bb 38347   HH bb 38347   HH bb 38347   HH bb 38347   II aa 40937
          435  +  II aa 40937   II bb 42951   II bb 42951   II bb 42951   II bb 42951
          436  +  II bb 42951   JJ aa 44737   JJ aa 44737   JJ aa 44737   JJ aa 44737
          437  +  JJ bb 44737   JJ bb 44737   JJ bb 44737   JJ bb 44737}
          438  +
          439  +do_execsql_test 1.3.3 {
          440  +  SELECT a, b, rank() OVER (ORDER BY a  GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
          441  +} {AA aa 1   AA aa 1   AA aa 1   AA aa 1   AA bb 1   AA bb 1   AA bb 1
          442  +  AA bb 1   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9
          443  +  BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   CC aa 21
          444  +  CC aa 21   CC aa 21   CC aa 21   CC bb 21   CC bb 21   DD aa 27   DD aa 27
          445  +  DD aa 27   DD bb 27   DD bb 27   DD bb 27   DD bb 27   EE aa 34   EE aa 34
          446  +  EE bb 34   EE bb 34   EE bb 34   FF aa 39   FF aa 39   FF aa 39   FF aa 39
          447  +  FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   GG aa 49
          448  +  GG aa 49   GG aa 49   GG aa 49   GG bb 49   GG bb 49   GG bb 49   GG bb 49
          449  +  HH aa 57   HH aa 57   HH aa 57   HH bb 57   HH bb 57   HH bb 57   HH bb 57
          450  +  HH bb 57   HH bb 57   II aa 66   II aa 66   II bb 66   II bb 66   II bb 66
          451  +  II bb 66   II bb 66   JJ aa 73   JJ aa 73   JJ aa 73   JJ aa 73   JJ bb 73
          452  +  JJ bb 73   JJ bb 73   JJ bb 73}
          453  +
          454  +do_execsql_test 1.3.4 {
          455  +  SELECT a, b, max(c) OVER (ORDER BY a,b  GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
          456  +} {AA aa 934   AA aa 934   AA aa 934   AA aa 934   AA bb 934   AA bb 934
          457  +  AA bb 934   AA bb 934   BB aa 934   BB aa 934   BB aa 934   BB aa 934
          458  +  BB aa 934   BB aa 934   BB bb 934   BB bb 934   BB bb 934   BB bb 934
          459  +  BB bb 934   BB bb 934   CC aa 934   CC aa 934   CC aa 934   CC aa 934
          460  +  CC bb 934   CC bb 934   DD aa 959   DD aa 959   DD aa 959   DD bb 959
          461  +  DD bb 959   DD bb 959   DD bb 959   EE aa 959   EE aa 959   EE bb 959
          462  +  EE bb 959   EE bb 959   FF aa 959   FF aa 959   FF aa 959   FF aa 959
          463  +  FF bb 959   FF bb 959   FF bb 959   FF bb 959   FF bb 959   FF bb 959
          464  +  GG aa 959   GG aa 959   GG aa 959   GG aa 959   GG bb 979   GG bb 979
          465  +  GG bb 979   GG bb 979   HH aa 979   HH aa 979   HH aa 979   HH bb 979
          466  +  HH bb 979   HH bb 979   HH bb 979   HH bb 979   HH bb 979   II aa 979
          467  +  II aa 979   II bb 979   II bb 979   II bb 979   II bb 979   II bb 979
          468  +  JJ aa 979   JJ aa 979   JJ aa 979   JJ aa 979   JJ bb 979   JJ bb 979
          469  +  JJ bb 979   JJ bb 979}
          470  +
          471  +do_execsql_test 1.3.5 {
          472  +  SELECT a, b, min(c) OVER (ORDER BY a,b  GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
          473  +} {AA aa 223   AA aa 223   AA aa 223   AA aa 223   AA bb 223   AA bb 223
          474  +  AA bb 223   AA bb 223   BB aa 223   BB aa 223   BB aa 223   BB aa 223
          475  +  BB aa 223   BB aa 223   BB bb 158   BB bb 158   BB bb 158   BB bb 158
          476  +  BB bb 158   BB bb 158   CC aa 158   CC aa 158   CC aa 158   CC aa 158
          477  +  CC bb 158   CC bb 158   DD aa 158   DD aa 158   DD aa 158   DD bb 113
          478  +  DD bb 113   DD bb 113   DD bb 113   EE aa 113   EE aa 113   EE bb 113
          479  +  EE bb 113   EE bb 113   FF aa 102   FF aa 102   FF aa 102   FF aa 102
          480  +  FF bb 102   FF bb 102   FF bb 102   FF bb 102   FF bb 102   FF bb 102
          481  +  GG aa 102   GG aa 102   GG aa 102   GG aa 102   GG bb 102   GG bb 102
          482  +  GG bb 102   GG bb 102   HH aa 102   HH aa 102   HH aa 102   HH bb 102
          483  +  HH bb 102   HH bb 102   HH bb 102   HH bb 102   HH bb 102   II aa 102
          484  +  II aa 102   II bb 102   II bb 102   II bb 102   II bb 102   II bb 102
          485  +  JJ aa 102   JJ aa 102   JJ aa 102   JJ aa 102   JJ bb 102   JJ bb 102
          486  +  JJ bb 102   JJ bb 102}
          487  +
          488  +do_execsql_test 1.3.6 {
          489  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
          490  +} {AA aa 11091   AA aa 11114   AA aa 11786   AA aa 11802   AA bb 11155
          491  +  AA bb 11398   AA bb 11453   AA bb 11716   BB aa 14385   BB aa 14487
          492  +  BB aa 14735   BB aa 14748   BB aa 14754   BB aa 14900   BB bb 14307
          493  +  BB bb 14355   BB bb 14361   BB bb 14436   BB bb 14442   BB bb 14514
          494  +  CC aa 18420   CC aa 18572   CC aa 18749   CC aa 19021   CC bb 18357
          495  +  CC bb 18833   DD aa 20873   DD aa 21462   DD aa 21494   DD bb 20759
          496  +  DD bb 20924   DD bb 21002   DD bb 21480   EE aa 26609   EE aa 27273
          497  +  EE bb 26618   EE bb 26757   EE bb 27134   FF aa 31184   FF aa 31187
          498  +  FF aa 31236   FF aa 31646   FF bb 30916   FF bb 30984   FF bb 31128
          499  +  FF bb 31280   FF bb 31559   FF bb 31752   GG aa 36663   GG aa 36817
          500  +  GG aa 36962   GG aa 37149   GG bb 36359   GG bb 36368   GG bb 36453
          501  +  GG bb 37137   HH aa 39958   HH aa 40147   HH aa 40457   HH bb 39974
          502  +  HH bb 40207   HH bb 40254   HH bb 40582   HH bb 40607   HH bb 40804
          503  +  II aa 44085   II aa 44339   II bb 43932   II bb 44066   II bb 44294
          504  +  II bb 44316   II bb 44487   JJ aa 43838   JJ aa 43969   JJ aa 44503
          505  +  JJ aa 44624   JJ bb 43898   JJ bb 44383   JJ bb 44401   JJ bb 44480}
          506  +
          507  +do_execsql_test 1.3.7 {
          508  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
          509  +} {AA aa 3751   AA aa 3774   AA aa 4446   AA aa 4462   AA bb 6688   AA bb 6931
          510  +  AA bb 6986   AA bb 7249   BB aa 11263   BB aa 11365   BB aa 11613
          511  +  BB aa 11626   BB aa 11632   BB aa 11778   BB bb 13139   BB bb 13187
          512  +  BB bb 13193   BB bb 13268   BB bb 13274   BB bb 13346   CC aa 14388
          513  +  CC aa 14540   CC aa 14717   CC aa 14989   CC bb 15650   CC bb 16126
          514  +  DD aa 18334   DD aa 18923   DD aa 18955   DD bb 19110   DD bb 19275
          515  +  DD bb 19353   DD bb 19831   EE aa 20941   EE aa 21605   EE bb 23113
          516  +  EE bb 23252   EE bb 23629   FF aa 26716   FF aa 26719   FF aa 26768
          517  +  FF aa 27178   FF bb 28045   FF bb 28113   FF bb 28257   FF bb 28409
          518  +  FF bb 28688   FF bb 28881   GG aa 31220   GG aa 31374   GG aa 31519
          519  +  GG aa 31706   GG bb 33165   GG bb 33174   GG bb 33259   GG bb 33943
          520  +  HH aa 36318   HH aa 36507   HH aa 36817   HH bb 37384   HH bb 37617
          521  +  HH bb 37664   HH bb 37992   HH bb 38017   HH bb 38214   II aa 40285
          522  +  II aa 40539   II bb 42146   II bb 42280   II bb 42508   II bb 42530
          523  +  II bb 42701   JJ aa 43838   JJ aa 43969   JJ aa 44503   JJ aa 44624
          524  +  JJ bb 43898   JJ bb 44383   JJ bb 44401   JJ bb 44480}
          525  +
          526  +do_execsql_test 1.3.8 {
          527  +  SELECT a, b, 
          528  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING  EXCLUDE CURRENT ROW),
          529  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING ),
          530  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING  EXCLUDE CURRENT ROW),
          531  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING )
          532  +    FROM t3 ORDER BY 1, 2, 3;
          533  +} {AA aa 11091 12025 3751 4685   AA aa 11114 12025 3774 4685
          534  +  AA aa 11786 12025 4446 4685   AA aa 11802 12025 4462 4685
          535  +  AA bb 11155 12025 6688 7558   AA bb 11398 12025 6931 7558
          536  +  AA bb 11453 12025 6986 7558   AA bb 11716 12025 7249 7558
          537  +  BB aa 14385 15147 11263 12025   BB aa 14487 15147 11365 12025
          538  +  BB aa 14735 15147 11613 12025   BB aa 14748 15147 11626 12025
          539  +  BB aa 14754 15147 11632 12025   BB aa 14900 15147 11778 12025
          540  +  BB bb 14307 15147 13139 13979   BB bb 14355 15147 13187 13979
          541  +  BB bb 14361 15147 13193 13979   BB bb 14436 15147 13268 13979
          542  +  BB bb 14442 15147 13274 13979   BB bb 14514 15147 13346 13979
          543  +  CC aa 18420 19179 14388 15147   CC aa 18572 19179 14540 15147
          544  +  CC aa 18749 19179 14717 15147   CC aa 19021 19179 14989 15147
          545  +  CC bb 18357 19179 15650 16472   CC bb 18833 19179 16126 16472
          546  +  DD aa 20873 21718 18334 19179   DD aa 21462 21718 18923 19179
          547  +  DD aa 21494 21718 18955 19179   DD bb 20759 21718 19110 20069
          548  +  DD bb 20924 21718 19275 20069   DD bb 21002 21718 19353 20069
          549  +  DD bb 21480 21718 19831 20069   EE aa 26609 27386 20941 21718
          550  +  EE aa 27273 27386 21605 21718   EE bb 26618 27386 23113 23881
          551  +  EE bb 26757 27386 23252 23881   EE bb 27134 27386 23629 23881
          552  +  FF aa 31184 31854 26716 27386   FF aa 31187 31854 26719 27386
          553  +  FF aa 31236 31854 26768 27386   FF aa 31646 31854 27178 27386
          554  +  FF bb 30916 31854 28045 28983   FF bb 30984 31854 28113 28983
          555  +  FF bb 31128 31854 28257 28983   FF bb 31280 31854 28409 28983
          556  +  FF bb 31559 31854 28688 28983   FF bb 31752 31854 28881 28983
          557  +  GG aa 36663 37297 31220 31854   GG aa 36817 37297 31374 31854
          558  +  GG aa 36962 37297 31519 31854   GG aa 37149 37297 31706 31854
          559  +  GG bb 36359 37297 33165 34103   GG bb 36368 37297 33174 34103
          560  +  GG bb 36453 37297 33259 34103   GG bb 37137 37297 33943 34103
          561  +  HH aa 39958 40937 36318 37297   HH aa 40147 40937 36507 37297
          562  +  HH aa 40457 40937 36817 37297   HH bb 39974 40937 37384 38347
          563  +  HH bb 40207 40937 37617 38347   HH bb 40254 40937 37664 38347
          564  +  HH bb 40582 40937 37992 38347   HH bb 40607 40937 38017 38347
          565  +  HH bb 40804 40937 38214 38347   II aa 44085 44737 40285 40937
          566  +  II aa 44339 44737 40539 40937   II bb 43932 44737 42146 42951
          567  +  II bb 44066 44737 42280 42951   II bb 44294 44737 42508 42951
          568  +  II bb 44316 44737 42530 42951   II bb 44487 44737 42701 42951
          569  +  JJ aa 43838 44737 43838 44737   JJ aa 43969 44737 43969 44737
          570  +  JJ aa 44503 44737 44503 44737   JJ aa 44624 44737 44624 44737
          571  +  JJ bb 43898 44737 43898 44737   JJ bb 44383 44737 44383 44737
          572  +  JJ bb 44401 44737 44401 44737   JJ bb 44480 44737 44480 44737}
          573  +
          574  +do_execsql_test 1.4.1 {
          575  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
          576  +} {AA aa 44737   AA aa 44737   AA aa 44737   AA aa 44737   AA bb 44737
          577  +  AA bb 44737   AA bb 44737   AA bb 44737   BB aa 44737   BB aa 44737
          578  +  BB aa 44737   BB aa 44737   BB aa 44737   BB aa 44737   BB bb 44737
          579  +  BB bb 44737   BB bb 44737   BB bb 44737   BB bb 44737   BB bb 44737
          580  +  CC aa 44737   CC aa 44737   CC aa 44737   CC aa 44737   CC bb 44737
          581  +  CC bb 44737   DD aa 44737   DD aa 44737   DD aa 44737   DD bb 44737
          582  +  DD bb 44737   DD bb 44737   DD bb 44737   EE aa 44737   EE aa 44737
          583  +  EE bb 44737   EE bb 44737   EE bb 44737   FF aa 44737   FF aa 44737
          584  +  FF aa 44737   FF aa 44737   FF bb 44737   FF bb 44737   FF bb 44737
          585  +  FF bb 44737   FF bb 44737   FF bb 44737   GG aa 44737   GG aa 44737
          586  +  GG aa 44737   GG aa 44737   GG bb 44737   GG bb 44737   GG bb 44737
          587  +  GG bb 44737   HH aa 44737   HH aa 44737   HH aa 44737   HH bb 44737
          588  +  HH bb 44737   HH bb 44737   HH bb 44737   HH bb 44737   HH bb 44737
          589  +  II aa 44737   II aa 44737   II bb 44737   II bb 44737   II bb 44737
          590  +  II bb 44737   II bb 44737   JJ aa 44737   JJ aa 44737   JJ aa 44737
          591  +  JJ aa 44737   JJ bb 44737   JJ bb 44737   JJ bb 44737   JJ bb 44737}
          592  +
          593  +do_execsql_test 1.4.2 {
          594  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
          595  +} {AA aa 44737   AA aa 44737   AA aa 44737   AA aa 44737   AA bb 44737
          596  +  AA bb 44737   AA bb 44737   AA bb 44737   BB aa 44737   BB aa 44737
          597  +  BB aa 44737   BB aa 44737   BB aa 44737   BB aa 44737   BB bb 44737
          598  +  BB bb 44737   BB bb 44737   BB bb 44737   BB bb 44737   BB bb 44737
          599  +  CC aa 44737   CC aa 44737   CC aa 44737   CC aa 44737   CC bb 44737
          600  +  CC bb 44737   DD aa 44737   DD aa 44737   DD aa 44737   DD bb 44737
          601  +  DD bb 44737   DD bb 44737   DD bb 44737   EE aa 44737   EE aa 44737
          602  +  EE bb 44737   EE bb 44737   EE bb 44737   FF aa 44737   FF aa 44737
          603  +  FF aa 44737   FF aa 44737   FF bb 44737   FF bb 44737   FF bb 44737
          604  +  FF bb 44737   FF bb 44737   FF bb 44737   GG aa 44737   GG aa 44737
          605  +  GG aa 44737   GG aa 44737   GG bb 44737   GG bb 44737   GG bb 44737
          606  +  GG bb 44737   HH aa 44737   HH aa 44737   HH aa 44737   HH bb 44737
          607  +  HH bb 44737   HH bb 44737   HH bb 44737   HH bb 44737   HH bb 44737
          608  +  II aa 44737   II aa 44737   II bb 44737   II bb 44737   II bb 44737
          609  +  II bb 44737   II bb 44737   JJ aa 44737   JJ aa 44737   JJ aa 44737
          610  +  JJ aa 44737   JJ bb 44737   JJ bb 44737   JJ bb 44737   JJ bb 44737}
          611  +
          612  +do_execsql_test 1.4.3 {
          613  +  SELECT a, b, rank() OVER (ORDER BY a  GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
          614  +} {AA aa 1   AA aa 1   AA aa 1   AA aa 1   AA bb 1   AA bb 1   AA bb 1
          615  +  AA bb 1   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9
          616  +  BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   CC aa 21
          617  +  CC aa 21   CC aa 21   CC aa 21   CC bb 21   CC bb 21   DD aa 27   DD aa 27
          618  +  DD aa 27   DD bb 27   DD bb 27   DD bb 27   DD bb 27   EE aa 34   EE aa 34
          619  +  EE bb 34   EE bb 34   EE bb 34   FF aa 39   FF aa 39   FF aa 39   FF aa 39
          620  +  FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   GG aa 49
          621  +  GG aa 49   GG aa 49   GG aa 49   GG bb 49   GG bb 49   GG bb 49   GG bb 49
          622  +  HH aa 57   HH aa 57   HH aa 57   HH bb 57   HH bb 57   HH bb 57   HH bb 57
          623  +  HH bb 57   HH bb 57   II aa 66   II aa 66   II bb 66   II bb 66   II bb 66
          624  +  II bb 66   II bb 66   JJ aa 73   JJ aa 73   JJ aa 73   JJ aa 73   JJ bb 73
          625  +  JJ bb 73   JJ bb 73   JJ bb 73}
          626  +
          627  +do_execsql_test 1.4.4 {
          628  +  SELECT a, b, max(c) OVER (ORDER BY a,b  GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
          629  +} {AA aa 979   AA aa 979   AA aa 979   AA aa 979   AA bb 979   AA bb 979
          630  +  AA bb 979   AA bb 979   BB aa 979   BB aa 979   BB aa 979   BB aa 979
          631  +  BB aa 979   BB aa 979   BB bb 979   BB bb 979   BB bb 979   BB bb 979
          632  +  BB bb 979   BB bb 979   CC aa 979   CC aa 979   CC aa 979   CC aa 979
          633  +  CC bb 979   CC bb 979   DD aa 979   DD aa 979   DD aa 979   DD bb 979
          634  +  DD bb 979   DD bb 979   DD bb 979   EE aa 979   EE aa 979   EE bb 979
          635  +  EE bb 979   EE bb 979   FF aa 979   FF aa 979   FF aa 979   FF aa 979
          636  +  FF bb 979   FF bb 979   FF bb 979   FF bb 979   FF bb 979   FF bb 979
          637  +  GG aa 979   GG aa 979   GG aa 979   GG aa 979   GG bb 979   GG bb 979
          638  +  GG bb 979   GG bb 979   HH aa 979   HH aa 979   HH aa 979   HH bb 979
          639  +  HH bb 979   HH bb 979   HH bb 979   HH bb 979   HH bb 979   II aa 979
          640  +  II aa 979   II bb 979   II bb 979   II bb 979   II bb 979   II bb 979
          641  +  JJ aa 979   JJ aa 979   JJ aa 979   JJ aa 979   JJ bb 979   JJ bb 979
          642  +  JJ bb 979   JJ bb 979}
          643  +
          644  +do_execsql_test 1.4.5 {
          645  +  SELECT a, b, min(c) OVER (ORDER BY a,b  GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
          646  +} {AA aa 102   AA aa 102   AA aa 102   AA aa 102   AA bb 102   AA bb 102
          647  +  AA bb 102   AA bb 102   BB aa 102   BB aa 102   BB aa 102   BB aa 102
          648  +  BB aa 102   BB aa 102   BB bb 102   BB bb 102   BB bb 102   BB bb 102
          649  +  BB bb 102   BB bb 102   CC aa 102   CC aa 102   CC aa 102   CC aa 102
          650  +  CC bb 102   CC bb 102   DD aa 102   DD aa 102   DD aa 102   DD bb 102
          651  +  DD bb 102   DD bb 102   DD bb 102   EE aa 102   EE aa 102   EE bb 102
          652  +  EE bb 102   EE bb 102   FF aa 102   FF aa 102   FF aa 102   FF aa 102
          653  +  FF bb 102   FF bb 102   FF bb 102   FF bb 102   FF bb 102   FF bb 102
          654  +  GG aa 102   GG aa 102   GG aa 102   GG aa 102   GG bb 102   GG bb 102
          655  +  GG bb 102   GG bb 102   HH aa 102   HH aa 102   HH aa 102   HH bb 102
          656  +  HH bb 102   HH bb 102   HH bb 102   HH bb 102   HH bb 102   II aa 102
          657  +  II aa 102   II bb 102   II bb 102   II bb 102   II bb 102   II bb 102
          658  +  JJ aa 102   JJ aa 102   JJ aa 102   JJ aa 102   JJ bb 102   JJ bb 102
          659  +  JJ bb 102   JJ bb 102}
          660  +
          661  +do_execsql_test 1.4.6 {
          662  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
          663  +} {AA aa 43803   AA aa 43826   AA aa 44498   AA aa 44514   AA bb 43867
          664  +  AA bb 44110   AA bb 44165   AA bb 44428   BB aa 43975   BB aa 44077
          665  +  BB aa 44325   BB aa 44338   BB aa 44344   BB aa 44490   BB bb 43897
          666  +  BB bb 43945   BB bb 43951   BB bb 44026   BB bb 44032   BB bb 44104
          667  +  CC aa 43978   CC aa 44130   CC aa 44307   CC aa 44579   CC bb 43915
          668  +  CC bb 44391   DD aa 43892   DD aa 44481   DD aa 44513   DD bb 43778
          669  +  DD bb 43943   DD bb 44021   DD bb 44499   EE aa 43960   EE aa 44624
          670  +  EE bb 43969   EE bb 44108   EE bb 44485   FF aa 44067   FF aa 44070
          671  +  FF aa 44119   FF aa 44529   FF bb 43799   FF bb 43867   FF bb 44011
          672  +  FF bb 44163   FF bb 44442   FF bb 44635   GG aa 44103   GG aa 44257
          673  +  GG aa 44402   GG aa 44589   GG bb 43799   GG bb 43808   GG bb 43893
          674  +  GG bb 44577   HH aa 43758   HH aa 43947   HH aa 44257   HH bb 43774
          675  +  HH bb 44007   HH bb 44054   HH bb 44382   HH bb 44407   HH bb 44604
          676  +  II aa 44085   II aa 44339   II bb 43932   II bb 44066   II bb 44294
          677  +  II bb 44316   II bb 44487   JJ aa 43838   JJ aa 43969   JJ aa 44503
          678  +  JJ aa 44624   JJ bb 43898   JJ bb 44383   JJ bb 44401   JJ bb 44480}
          679  +
          680  +do_execsql_test 1.4.7 {
          681  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
          682  +} {AA aa 43803   AA aa 43826   AA aa 44498   AA aa 44514   AA bb 43867
          683  +  AA bb 44110   AA bb 44165   AA bb 44428   BB aa 43975   BB aa 44077
          684  +  BB aa 44325   BB aa 44338   BB aa 44344   BB aa 44490   BB bb 43897
          685  +  BB bb 43945   BB bb 43951   BB bb 44026   BB bb 44032   BB bb 44104
          686  +  CC aa 43978   CC aa 44130   CC aa 44307   CC aa 44579   CC bb 43915
          687  +  CC bb 44391   DD aa 43892   DD aa 44481   DD aa 44513   DD bb 43778
          688  +  DD bb 43943   DD bb 44021   DD bb 44499   EE aa 43960   EE aa 44624
          689  +  EE bb 43969   EE bb 44108   EE bb 44485   FF aa 44067   FF aa 44070
          690  +  FF aa 44119   FF aa 44529   FF bb 43799   FF bb 43867   FF bb 44011
          691  +  FF bb 44163   FF bb 44442   FF bb 44635   GG aa 44103   GG aa 44257
          692  +  GG aa 44402   GG aa 44589   GG bb 43799   GG bb 43808   GG bb 43893
          693  +  GG bb 44577   HH aa 43758   HH aa 43947   HH aa 44257   HH bb 43774
          694  +  HH bb 44007   HH bb 44054   HH bb 44382   HH bb 44407   HH bb 44604
          695  +  II aa 44085   II aa 44339   II bb 43932   II bb 44066   II bb 44294
          696  +  II bb 44316   II bb 44487   JJ aa 43838   JJ aa 43969   JJ aa 44503
          697  +  JJ aa 44624   JJ bb 43898   JJ bb 44383   JJ bb 44401   JJ bb 44480}
          698  +
          699  +do_execsql_test 1.4.8 {
          700  +  SELECT a, b, 
          701  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING  EXCLUDE CURRENT ROW),
          702  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ),
          703  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING  EXCLUDE CURRENT ROW),
          704  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING )
          705  +    FROM t3 ORDER BY 1, 2, 3;
          706  +} {AA aa 43803 44737 43803 44737   AA aa 43826 44737 43826 44737
          707  +  AA aa 44498 44737 44498 44737   AA aa 44514 44737 44514 44737
          708  +  AA bb 43867 44737 43867 44737   AA bb 44110 44737 44110 44737
          709  +  AA bb 44165 44737 44165 44737   AA bb 44428 44737 44428 44737
          710  +  BB aa 43975 44737 43975 44737   BB aa 44077 44737 44077 44737
          711  +  BB aa 44325 44737 44325 44737   BB aa 44338 44737 44338 44737
          712  +  BB aa 44344 44737 44344 44737   BB aa 44490 44737 44490 44737
          713  +  BB bb 43897 44737 43897 44737   BB bb 43945 44737 43945 44737
          714  +  BB bb 43951 44737 43951 44737   BB bb 44026 44737 44026 44737
          715  +  BB bb 44032 44737 44032 44737   BB bb 44104 44737 44104 44737
          716  +  CC aa 43978 44737 43978 44737   CC aa 44130 44737 44130 44737
          717  +  CC aa 44307 44737 44307 44737   CC aa 44579 44737 44579 44737
          718  +  CC bb 43915 44737 43915 44737   CC bb 44391 44737 44391 44737
          719  +  DD aa 43892 44737 43892 44737   DD aa 44481 44737 44481 44737
          720  +  DD aa 44513 44737 44513 44737   DD bb 43778 44737 43778 44737
          721  +  DD bb 43943 44737 43943 44737   DD bb 44021 44737 44021 44737
          722  +  DD bb 44499 44737 44499 44737   EE aa 43960 44737 43960 44737
          723  +  EE aa 44624 44737 44624 44737   EE bb 43969 44737 43969 44737
          724  +  EE bb 44108 44737 44108 44737   EE bb 44485 44737 44485 44737
          725  +  FF aa 44067 44737 44067 44737   FF aa 44070 44737 44070 44737
          726  +  FF aa 44119 44737 44119 44737   FF aa 44529 44737 44529 44737
          727  +  FF bb 43799 44737 43799 44737   FF bb 43867 44737 43867 44737
          728  +  FF bb 44011 44737 44011 44737   FF bb 44163 44737 44163 44737
          729  +  FF bb 44442 44737 44442 44737   FF bb 44635 44737 44635 44737
          730  +  GG aa 44103 44737 44103 44737   GG aa 44257 44737 44257 44737
          731  +  GG aa 44402 44737 44402 44737   GG aa 44589 44737 44589 44737
          732  +  GG bb 43799 44737 43799 44737   GG bb 43808 44737 43808 44737
          733  +  GG bb 43893 44737 43893 44737   GG bb 44577 44737 44577 44737
          734  +  HH aa 43758 44737 43758 44737   HH aa 43947 44737 43947 44737
          735  +  HH aa 44257 44737 44257 44737   HH bb 43774 44737 43774 44737
          736  +  HH bb 44007 44737 44007 44737   HH bb 44054 44737 44054 44737
          737  +  HH bb 44382 44737 44382 44737   HH bb 44407 44737 44407 44737
          738  +  HH bb 44604 44737 44604 44737   II aa 44085 44737 44085 44737
          739  +  II aa 44339 44737 44339 44737   II bb 43932 44737 43932 44737
          740  +  II bb 44066 44737 44066 44737   II bb 44294 44737 44294 44737
          741  +  II bb 44316 44737 44316 44737   II bb 44487 44737 44487 44737
          742  +  JJ aa 43838 44737 43838 44737   JJ aa 43969 44737 43969 44737
          743  +  JJ aa 44503 44737 44503 44737   JJ aa 44624 44737 44624 44737
          744  +  JJ bb 43898 44737 43898 44737   JJ bb 44383 44737 44383 44737
          745  +  JJ bb 44401 44737 44401 44737   JJ bb 44480 44737 44480 44737}
          746  +
          747  +do_execsql_test 1.5.1 {
          748  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN 1 PRECEDING         AND 2 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
          749  +} {AA aa {}   AA aa {}   AA aa {}   AA aa {}   AA bb {}   AA bb {}   AA bb {}
          750  +  AA bb {}   BB aa {}   BB aa {}   BB aa {}   BB aa {}   BB aa {}   BB aa {}
          751  +  BB bb {}   BB bb {}   BB bb {}   BB bb {}   BB bb {}   BB bb {}   CC aa {}
          752  +  CC aa {}   CC aa {}   CC aa {}   CC bb {}   CC bb {}   DD aa {}   DD aa {}
          753  +  DD aa {}   DD bb {}   DD bb {}   DD bb {}   DD bb {}   EE aa {}   EE aa {}
          754  +  EE bb {}   EE bb {}   EE bb {}   FF aa {}   FF aa {}   FF aa {}   FF aa {}
          755  +  FF bb {}   FF bb {}   FF bb {}   FF bb {}   FF bb {}   FF bb {}   GG aa {}
          756  +  GG aa {}   GG aa {}   GG aa {}   GG bb {}   GG bb {}   GG bb {}   GG bb {}
          757  +  HH aa {}   HH aa {}   HH aa {}   HH bb {}   HH bb {}   HH bb {}   HH bb {}
          758  +  HH bb {}   HH bb {}   II aa {}   II aa {}   II bb {}   II bb {}   II bb {}
          759  +  II bb {}   II bb {}   JJ aa {}   JJ aa {}   JJ aa {}   JJ aa {}   JJ bb {}
          760  +  JJ bb {}   JJ bb {}   JJ bb {}}
          761  +
          762  +do_execsql_test 1.5.2 {
          763  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 1 PRECEDING         AND 2 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
          764  +} {AA aa {}   AA aa {}   AA aa {}   AA aa {}   AA bb {}   AA bb {}   AA bb {}
          765  +  AA bb {}   BB aa {}   BB aa {}   BB aa {}   BB aa {}   BB aa {}   BB aa {}
          766  +  BB bb {}   BB bb {}   BB bb {}   BB bb {}   BB bb {}   BB bb {}   CC aa {}
          767  +  CC aa {}   CC aa {}   CC aa {}   CC bb {}   CC bb {}   DD aa {}   DD aa {}
          768  +  DD aa {}   DD bb {}   DD bb {}   DD bb {}   DD bb {}   EE aa {}   EE aa {}
          769  +  EE bb {}   EE bb {}   EE bb {}   FF aa {}   FF aa {}   FF aa {}   FF aa {}
          770  +  FF bb {}   FF bb {}   FF bb {}   FF bb {}   FF bb {}   FF bb {}   GG aa {}
          771  +  GG aa {}   GG aa {}   GG aa {}   GG bb {}   GG bb {}   GG bb {}   GG bb {}
          772  +  HH aa {}   HH aa {}   HH aa {}   HH bb {}   HH bb {}   HH bb {}   HH bb {}
          773  +  HH bb {}   HH bb {}   II aa {}   II aa {}   II bb {}   II bb {}   II bb {}
          774  +  II bb {}   II bb {}   JJ aa {}   JJ aa {}   JJ aa {}   JJ aa {}   JJ bb {}
          775  +  JJ bb {}   JJ bb {}   JJ bb {}}
          776  +
          777  +do_execsql_test 1.5.3 {
          778  +  SELECT a, b, rank() OVER (ORDER BY a  GROUPS BETWEEN 1 PRECEDING         AND 2 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
          779  +} {AA aa 1   AA aa 1   AA aa 1   AA aa 1   AA bb 1   AA bb 1   AA bb 1
          780  +  AA bb 1   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9
          781  +  BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   CC aa 21
          782  +  CC aa 21   CC aa 21   CC aa 21   CC bb 21   CC bb 21   DD aa 27   DD aa 27
          783  +  DD aa 27   DD bb 27   DD bb 27   DD bb 27   DD bb 27   EE aa 34   EE aa 34
          784  +  EE bb 34   EE bb 34   EE bb 34   FF aa 39   FF aa 39   FF aa 39   FF aa 39
          785  +  FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   GG aa 49
          786  +  GG aa 49   GG aa 49   GG aa 49   GG bb 49   GG bb 49   GG bb 49   GG bb 49
          787  +  HH aa 57   HH aa 57   HH aa 57   HH bb 57   HH bb 57   HH bb 57   HH bb 57
          788  +  HH bb 57   HH bb 57   II aa 66   II aa 66   II bb 66   II bb 66   II bb 66
          789  +  II bb 66   II bb 66   JJ aa 73   JJ aa 73   JJ aa 73   JJ aa 73   JJ bb 73
          790  +  JJ bb 73   JJ bb 73   JJ bb 73}
          791  +
          792  +do_execsql_test 1.5.4 {
          793  +  SELECT a, b, max(c) OVER (ORDER BY a,b  GROUPS BETWEEN 1 PRECEDING         AND 2 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
          794  +} {AA aa {}   AA aa {}   AA aa {}   AA aa {}   AA bb {}   AA bb {}   AA bb {}
          795  +  AA bb {}   BB aa {}   BB aa {}   BB aa {}   BB aa {}   BB aa {}   BB aa {}
          796  +  BB bb {}   BB bb {}   BB bb {}   BB bb {}   BB bb {}   BB bb {}   CC aa {}
          797  +  CC aa {}   CC aa {}   CC aa {}   CC bb {}   CC bb {}   DD aa {}   DD aa {}
          798  +  DD aa {}   DD bb {}   DD bb {}   DD bb {}   DD bb {}   EE aa {}   EE aa {}
          799  +  EE bb {}   EE bb {}   EE bb {}   FF aa {}   FF aa {}   FF aa {}   FF aa {}
          800  +  FF bb {}   FF bb {}   FF bb {}   FF bb {}   FF bb {}   FF bb {}   GG aa {}
          801  +  GG aa {}   GG aa {}   GG aa {}   GG bb {}   GG bb {}   GG bb {}   GG bb {}
          802  +  HH aa {}   HH aa {}   HH aa {}   HH bb {}   HH bb {}   HH bb {}   HH bb {}
          803  +  HH bb {}   HH bb {}   II aa {}   II aa {}   II bb {}   II bb {}   II bb {}
          804  +  II bb {}   II bb {}   JJ aa {}   JJ aa {}   JJ aa {}   JJ aa {}   JJ bb {}
          805  +  JJ bb {}   JJ bb {}   JJ bb {}}
          806  +
          807  +do_execsql_test 1.5.5 {
          808  +  SELECT a, b, min(c) OVER (ORDER BY a,b  GROUPS BETWEEN 1 PRECEDING         AND 2 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
          809  +} {AA aa {}   AA aa {}   AA aa {}   AA aa {}   AA bb {}   AA bb {}   AA bb {}
          810  +  AA bb {}   BB aa {}   BB aa {}   BB aa {}   BB aa {}   BB aa {}   BB aa {}
          811  +  BB bb {}   BB bb {}   BB bb {}   BB bb {}   BB bb {}   BB bb {}   CC aa {}
          812  +  CC aa {}   CC aa {}   CC aa {}   CC bb {}   CC bb {}   DD aa {}   DD aa {}
          813  +  DD aa {}   DD bb {}   DD bb {}   DD bb {}   DD bb {}   EE aa {}   EE aa {}
          814  +  EE bb {}   EE bb {}   EE bb {}   FF aa {}   FF aa {}   FF aa {}   FF aa {}
          815  +  FF bb {}   FF bb {}   FF bb {}   FF bb {}   FF bb {}   FF bb {}   GG aa {}
          816  +  GG aa {}   GG aa {}   GG aa {}   GG bb {}   GG bb {}   GG bb {}   GG bb {}
          817  +  HH aa {}   HH aa {}   HH aa {}   HH bb {}   HH bb {}   HH bb {}   HH bb {}
          818  +  HH bb {}   HH bb {}   II aa {}   II aa {}   II bb {}   II bb {}   II bb {}
          819  +  II bb {}   II bb {}   JJ aa {}   JJ aa {}   JJ aa {}   JJ aa {}   JJ bb {}
          820  +  JJ bb {}   JJ bb {}   JJ bb {}}
          821  +
          822  +do_execsql_test 1.5.6 {
          823  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN 1 PRECEDING         AND 2 PRECEDING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
          824  +} {AA aa {}   AA aa {}   AA aa {}   AA aa {}   AA bb {}   AA bb {}   AA bb {}
          825  +  AA bb {}   BB aa {}   BB aa {}   BB aa {}   BB aa {}   BB aa {}   BB aa {}
          826  +  BB bb {}   BB bb {}   BB bb {}   BB bb {}   BB bb {}   BB bb {}   CC aa {}
          827  +  CC aa {}   CC aa {}   CC aa {}   CC bb {}   CC bb {}   DD aa {}   DD aa {}
          828  +  DD aa {}   DD bb {}   DD bb {}   DD bb {}   DD bb {}   EE aa {}   EE aa {}
          829  +  EE bb {}   EE bb {}   EE bb {}   FF aa {}   FF aa {}   FF aa {}   FF aa {}
          830  +  FF bb {}   FF bb {}   FF bb {}   FF bb {}   FF bb {}   FF bb {}   GG aa {}
          831  +  GG aa {}   GG aa {}   GG aa {}   GG bb {}   GG bb {}   GG bb {}   GG bb {}
          832  +  HH aa {}   HH aa {}   HH aa {}   HH bb {}   HH bb {}   HH bb {}   HH bb {}
          833  +  HH bb {}   HH bb {}   II aa {}   II aa {}   II bb {}   II bb {}   II bb {}
          834  +  II bb {}   II bb {}   JJ aa {}   JJ aa {}   JJ aa {}   JJ aa {}   JJ bb {}
          835  +  JJ bb {}   JJ bb {}   JJ bb {}}
          836  +
          837  +do_execsql_test 1.5.7 {
          838  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 1 PRECEDING         AND 2 PRECEDING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
          839  +} {AA aa {}   AA aa {}   AA aa {}   AA aa {}   AA bb {}   AA bb {}   AA bb {}
          840  +  AA bb {}   BB aa {}   BB aa {}   BB aa {}   BB aa {}   BB aa {}   BB aa {}
          841  +  BB bb {}   BB bb {}   BB bb {}   BB bb {}   BB bb {}   BB bb {}   CC aa {}
          842  +  CC aa {}   CC aa {}   CC aa {}   CC bb {}   CC bb {}   DD aa {}   DD aa {}
          843  +  DD aa {}   DD bb {}   DD bb {}   DD bb {}   DD bb {}   EE aa {}   EE aa {}
          844  +  EE bb {}   EE bb {}   EE bb {}   FF aa {}   FF aa {}   FF aa {}   FF aa {}
          845  +  FF bb {}   FF bb {}   FF bb {}   FF bb {}   FF bb {}   FF bb {}   GG aa {}
          846  +  GG aa {}   GG aa {}   GG aa {}   GG bb {}   GG bb {}   GG bb {}   GG bb {}
          847  +  HH aa {}   HH aa {}   HH aa {}   HH bb {}   HH bb {}   HH bb {}   HH bb {}
          848  +  HH bb {}   HH bb {}   II aa {}   II aa {}   II bb {}   II bb {}   II bb {}
          849  +  II bb {}   II bb {}   JJ aa {}   JJ aa {}   JJ aa {}   JJ aa {}   JJ bb {}
          850  +  JJ bb {}   JJ bb {}   JJ bb {}}
          851  +
          852  +do_execsql_test 1.5.8 {
          853  +  SELECT a, b, 
          854  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN 1 PRECEDING         AND 2 PRECEDING  EXCLUDE CURRENT ROW),
          855  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN 1 PRECEDING         AND 2 PRECEDING ),
          856  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 1 PRECEDING         AND 2 PRECEDING  EXCLUDE CURRENT ROW),
          857  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 1 PRECEDING         AND 2 PRECEDING )
          858  +    FROM t3 ORDER BY 1, 2, 3;
          859  +} {AA aa {} {} {} {}   AA aa {} {} {} {}   AA aa {} {} {} {}
          860  +  AA aa {} {} {} {}   AA bb {} {} {} {}   AA bb {} {} {} {}
          861  +  AA bb {} {} {} {}   AA bb {} {} {} {}   BB aa {} {} {} {}
          862  +  BB aa {} {} {} {}   BB aa {} {} {} {}   BB aa {} {} {} {}
          863  +  BB aa {} {} {} {}   BB aa {} {} {} {}   BB bb {} {} {} {}
          864  +  BB bb {} {} {} {}   BB bb {} {} {} {}   BB bb {} {} {} {}
          865  +  BB bb {} {} {} {}   BB bb {} {} {} {}   CC aa {} {} {} {}
          866  +  CC aa {} {} {} {}   CC aa {} {} {} {}   CC aa {} {} {} {}
          867  +  CC bb {} {} {} {}   CC bb {} {} {} {}   DD aa {} {} {} {}
          868  +  DD aa {} {} {} {}   DD aa {} {} {} {}   DD bb {} {} {} {}
          869  +  DD bb {} {} {} {}   DD bb {} {} {} {}   DD bb {} {} {} {}
          870  +  EE aa {} {} {} {}   EE aa {} {} {} {}   EE bb {} {} {} {}
          871  +  EE bb {} {} {} {}   EE bb {} {} {} {}   FF aa {} {} {} {}
          872  +  FF aa {} {} {} {}   FF aa {} {} {} {}   FF aa {} {} {} {}
          873  +  FF bb {} {} {} {}   FF bb {} {} {} {}   FF bb {} {} {} {}
          874  +  FF bb {} {} {} {}   FF bb {} {} {} {}   FF bb {} {} {} {}
          875  +  GG aa {} {} {} {}   GG aa {} {} {} {}   GG aa {} {} {} {}
          876  +  GG aa {} {} {} {}   GG bb {} {} {} {}   GG bb {} {} {} {}
          877  +  GG bb {} {} {} {}   GG bb {} {} {} {}   HH aa {} {} {} {}
          878  +  HH aa {} {} {} {}   HH aa {} {} {} {}   HH bb {} {} {} {}
          879  +  HH bb {} {} {} {}   HH bb {} {} {} {}   HH bb {} {} {} {}
          880  +  HH bb {} {} {} {}   HH bb {} {} {} {}   II aa {} {} {} {}
          881  +  II aa {} {} {} {}   II bb {} {} {} {}   II bb {} {} {} {}
          882  +  II bb {} {} {} {}   II bb {} {} {} {}   II bb {} {} {} {}
          883  +  JJ aa {} {} {} {}   JJ aa {} {} {} {}   JJ aa {} {} {} {}
          884  +  JJ aa {} {} {} {}   JJ bb {} {} {} {}   JJ bb {} {} {} {}
          885  +  JJ bb {} {} {} {}   JJ bb {} {} {} {}}
          886  +
          887  +do_execsql_test 1.6.1 {
          888  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN 2 PRECEDING         AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
          889  +} {AA aa {}   AA aa {}   AA aa {}   AA aa {}   AA bb {}   AA bb {}   AA bb {}
          890  +  AA bb {}   BB aa 4685   BB aa 4685   BB aa 4685   BB aa 4685   BB aa 4685
          891  +  BB aa 4685   BB bb 4685   BB bb 4685   BB bb 4685   BB bb 4685   BB bb 4685
          892  +  BB bb 4685   CC aa 12025   CC aa 12025   CC aa 12025   CC aa 12025
          893  +  CC bb 12025   CC bb 12025   DD aa 10462   DD aa 10462   DD aa 10462
          894  +  DD bb 10462   DD bb 10462   DD bb 10462   DD bb 10462   EE aa 7154
          895  +  EE aa 7154   EE bb 7154   EE bb 7154   EE bb 7154   FF aa 6571   FF aa 6571
          896  +  FF aa 6571   FF aa 6571   FF bb 6571   FF bb 6571   FF bb 6571   FF bb 6571
          897  +  FF bb 6571   FF bb 6571   GG aa 8207   GG aa 8207   GG aa 8207   GG aa 8207
          898  +  GG bb 8207   GG bb 8207   GG bb 8207   GG bb 8207   HH aa 10136
          899  +  HH aa 10136   HH aa 10136   HH bb 10136   HH bb 10136   HH bb 10136
          900  +  HH bb 10136   HH bb 10136   HH bb 10136   II aa 9911   II aa 9911
          901  +  II bb 9911   II bb 9911   II bb 9911   II bb 9911   II bb 9911   JJ aa 9083
          902  +  JJ aa 9083   JJ aa 9083   JJ aa 9083   JJ bb 9083   JJ bb 9083   JJ bb 9083
          903  +  JJ bb 9083}
          904  +
          905  +do_execsql_test 1.6.2 {
          906  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 2 PRECEDING         AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
          907  +} {AA aa {}   AA aa {}   AA aa {}   AA aa {}   AA bb 2307   AA bb 2307
          908  +  AA bb 2307   AA bb 2307   BB aa 4685   BB aa 4685   BB aa 4685   BB aa 4685
          909  +  BB aa 4685   BB aa 4685   BB bb 5251   BB bb 5251   BB bb 5251   BB bb 5251
          910  +  BB bb 5251   BB bb 5251   CC aa 7340   CC aa 7340   CC aa 7340   CC aa 7340
          911  +  CC bb 6421   CC bb 6421   DD aa 3122   DD aa 3122   DD aa 3122   DD bb 2493
          912  +  DD bb 2493   DD bb 2493   DD bb 2493   EE aa 4032   EE aa 4032   EE bb 3597
          913  +  EE bb 3597   EE bb 3597   FF aa 2539   FF aa 2539   FF aa 2539   FF aa 2539
          914  +  FF bb 3812   FF bb 3812   FF bb 3812   FF bb 3812   FF bb 3812   FF bb 3812
          915  +  GG aa 5668   GG aa 5668   GG aa 5668   GG aa 5668   GG bb 5102   GG bb 5102
          916  +  GG bb 5102   GG bb 5102   HH aa 4468   HH aa 4468   HH aa 4468   HH bb 5120
          917  +  HH bb 5120   HH bb 5120   HH bb 5120   HH bb 5120   HH bb 5120   II aa 5443
          918  +  II aa 5443   II bb 4244   II bb 4244   II bb 4244   II bb 4244   II bb 4244
          919  +  JJ aa 3640   JJ aa 3640   JJ aa 3640   JJ aa 3640   JJ bb 4604   JJ bb 4604
          920  +  JJ bb 4604   JJ bb 4604}
          921  +
          922  +do_execsql_test 1.6.3 {
          923  +  SELECT a, b, rank() OVER (ORDER BY a  GROUPS BETWEEN 2 PRECEDING         AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
          924  +} {AA aa 1   AA aa 1   AA aa 1   AA aa 1   AA bb 1   AA bb 1   AA bb 1
          925  +  AA bb 1   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9
          926  +  BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   CC aa 21
          927  +  CC aa 21   CC aa 21   CC aa 21   CC bb 21   CC bb 21   DD aa 27   DD aa 27
          928  +  DD aa 27   DD bb 27   DD bb 27   DD bb 27   DD bb 27   EE aa 34   EE aa 34
          929  +  EE bb 34   EE bb 34   EE bb 34   FF aa 39   FF aa 39   FF aa 39   FF aa 39
          930  +  FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   GG aa 49
          931  +  GG aa 49   GG aa 49   GG aa 49   GG bb 49   GG bb 49   GG bb 49   GG bb 49
          932  +  HH aa 57   HH aa 57   HH aa 57   HH bb 57   HH bb 57   HH bb 57   HH bb 57
          933  +  HH bb 57   HH bb 57   II aa 66   II aa 66   II bb 66   II bb 66   II bb 66
          934  +  II bb 66   II bb 66   JJ aa 73   JJ aa 73   JJ aa 73   JJ aa 73   JJ bb 73
          935  +  JJ bb 73   JJ bb 73   JJ bb 73}
          936  +
          937  +do_execsql_test 1.6.4 {
          938  +  SELECT a, b, max(c) OVER (ORDER BY a,b  GROUPS BETWEEN 2 PRECEDING         AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
          939  +} {AA aa {}   AA aa {}   AA aa {}   AA aa {}   AA bb 934   AA bb 934
          940  +  AA bb 934   AA bb 934   BB aa 934   BB aa 934   BB aa 934   BB aa 934
          941  +  BB aa 934   BB aa 934   BB bb 870   BB bb 870   BB bb 870   BB bb 870
          942  +  BB bb 870   BB bb 870   CC aa 840   CC aa 840   CC aa 840   CC aa 840
          943  +  CC bb 840   CC bb 840   DD aa 822   DD aa 822   DD aa 822   DD bb 845
          944  +  DD bb 845   DD bb 845   DD bb 845   EE aa 959   EE aa 959   EE bb 959
          945  +  EE bb 959   EE bb 959   FF aa 777   FF aa 777   FF aa 777   FF aa 777
          946  +  FF bb 768   FF bb 768   FF bb 768   FF bb 768   FF bb 768   FF bb 768
          947  +  GG aa 938   GG aa 938   GG aa 938   GG aa 938   GG bb 938   GG bb 938
          948  +  GG bb 938   GG bb 938   HH aa 938   HH aa 938   HH aa 938   HH bb 979
          949  +  HH bb 979   HH bb 979   HH bb 979   HH bb 979   HH bb 979   II aa 979
          950  +  II aa 979   II bb 963   II bb 963   II bb 963   II bb 963   II bb 963
          951  +  JJ aa 805   JJ aa 805   JJ aa 805   JJ aa 805   JJ bb 899   JJ bb 899
          952  +  JJ bb 899   JJ bb 899}
          953  +
          954  +do_execsql_test 1.6.5 {
          955  +  SELECT a, b, min(c) OVER (ORDER BY a,b  GROUPS BETWEEN 2 PRECEDING         AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
          956  +} {AA aa {}   AA aa {}   AA aa {}   AA aa {}   AA bb 223   AA bb 223
          957  +  AA bb 223   AA bb 223   BB aa 223   BB aa 223   BB aa 223   BB aa 223
          958  +  BB aa 223   BB aa 223   BB bb 247   BB bb 247   BB bb 247   BB bb 247
          959  +  BB bb 247   BB bb 247   CC aa 247   CC aa 247   CC aa 247   CC aa 247
          960  +  CC bb 158   CC bb 158   DD aa 158   DD aa 158   DD aa 158   DD bb 224
          961  +  DD bb 224   DD bb 224   DD bb 224   EE aa 224   EE aa 224   EE bb 113
          962  +  EE bb 113   EE bb 113   FF aa 113   FF aa 113   FF aa 113   FF aa 113
          963  +  FF bb 208   FF bb 208   FF bb 208   FF bb 208   FF bb 208   FF bb 208
          964  +  GG aa 102   GG aa 102   GG aa 102   GG aa 102   GG bb 102   GG bb 102
          965  +  GG bb 102   GG bb 102   HH aa 148   HH aa 148   HH aa 148   HH bb 160
          966  +  HH bb 160   HH bb 160   HH bb 160   HH bb 160   HH bb 160   II aa 133
          967  +  II aa 133   II bb 133   II bb 133   II bb 133   II bb 133   II bb 133
          968  +  JJ aa 250   JJ aa 250   JJ aa 250   JJ aa 250   JJ bb 113   JJ bb 113
          969  +  JJ bb 113   JJ bb 113}
          970  +
          971  +do_execsql_test 1.6.6 {
          972  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN 2 PRECEDING         AND 1 PRECEDING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
          973  +} {AA aa {}   AA aa {}   AA aa {}   AA aa {}   AA bb {}   AA bb {}   AA bb {}
          974  +  AA bb {}   BB aa 4685   BB aa 4685   BB aa 4685   BB aa 4685   BB aa 4685
          975  +  BB aa 4685   BB bb 4685   BB bb 4685   BB bb 4685   BB bb 4685   BB bb 4685
          976  +  BB bb 4685   CC aa 12025   CC aa 12025   CC aa 12025   CC aa 12025
          977  +  CC bb 12025   CC bb 12025   DD aa 10462   DD aa 10462   DD aa 10462
          978  +  DD bb 10462   DD bb 10462   DD bb 10462   DD bb 10462   EE aa 7154
          979  +  EE aa 7154   EE bb 7154   EE bb 7154   EE bb 7154   FF aa 6571   FF aa 6571
          980  +  FF aa 6571   FF aa 6571   FF bb 6571   FF bb 6571   FF bb 6571   FF bb 6571
          981  +  FF bb 6571   FF bb 6571   GG aa 8207   GG aa 8207   GG aa 8207   GG aa 8207
          982  +  GG bb 8207   GG bb 8207   GG bb 8207   GG bb 8207   HH aa 10136
          983  +  HH aa 10136   HH aa 10136   HH bb 10136   HH bb 10136   HH bb 10136
          984  +  HH bb 10136   HH bb 10136   HH bb 10136   II aa 9911   II aa 9911
          985  +  II bb 9911   II bb 9911   II bb 9911   II bb 9911   II bb 9911   JJ aa 9083
          986  +  JJ aa 9083   JJ aa 9083   JJ aa 9083   JJ bb 9083   JJ bb 9083   JJ bb 9083
          987  +  JJ bb 9083}
          988  +
          989  +do_execsql_test 1.6.7 {
          990  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 2 PRECEDING         AND 1 PRECEDING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
          991  +} {AA aa {}   AA aa {}   AA aa {}   AA aa {}   AA bb 2307   AA bb 2307
          992  +  AA bb 2307   AA bb 2307   BB aa 4685   BB aa 4685   BB aa 4685   BB aa 4685
          993  +  BB aa 4685   BB aa 4685   BB bb 5251   BB bb 5251   BB bb 5251   BB bb 5251
          994  +  BB bb 5251   BB bb 5251   CC aa 7340   CC aa 7340   CC aa 7340   CC aa 7340
          995  +  CC bb 6421   CC bb 6421   DD aa 3122   DD aa 3122   DD aa 3122   DD bb 2493
          996  +  DD bb 2493   DD bb 2493   DD bb 2493   EE aa 4032   EE aa 4032   EE bb 3597
          997  +  EE bb 3597   EE bb 3597   FF aa 2539   FF aa 2539   FF aa 2539   FF aa 2539
          998  +  FF bb 3812   FF bb 3812   FF bb 3812   FF bb 3812   FF bb 3812   FF bb 3812
          999  +  GG aa 5668   GG aa 5668   GG aa 5668   GG aa 5668   GG bb 5102   GG bb 5102
         1000  +  GG bb 5102   GG bb 5102   HH aa 4468   HH aa 4468   HH aa 4468   HH bb 5120
         1001  +  HH bb 5120   HH bb 5120   HH bb 5120   HH bb 5120   HH bb 5120   II aa 5443
         1002  +  II aa 5443   II bb 4244   II bb 4244   II bb 4244   II bb 4244   II bb 4244
         1003  +  JJ aa 3640   JJ aa 3640   JJ aa 3640   JJ aa 3640   JJ bb 4604   JJ bb 4604
         1004  +  JJ bb 4604   JJ bb 4604}
         1005  +
         1006  +do_execsql_test 1.6.8 {
         1007  +  SELECT a, b, 
         1008  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN 2 PRECEDING         AND 1 PRECEDING  EXCLUDE CURRENT ROW),
         1009  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN 2 PRECEDING         AND 1 PRECEDING ),
         1010  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 2 PRECEDING         AND 1 PRECEDING  EXCLUDE CURRENT ROW),
         1011  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 2 PRECEDING         AND 1 PRECEDING )
         1012  +    FROM t3 ORDER BY 1, 2, 3;
         1013  +} {AA aa {} {} {} {}   AA aa {} {} {} {}   AA aa {} {} {} {}
         1014  +  AA aa {} {} {} {}   AA bb {} {} 2307 2307   AA bb {} {} 2307 2307
         1015  +  AA bb {} {} 2307 2307   AA bb {} {} 2307 2307   BB aa 4685 4685 4685 4685
         1016  +  BB aa 4685 4685 4685 4685   BB aa 4685 4685 4685 4685
         1017  +  BB aa 4685 4685 4685 4685   BB aa 4685 4685 4685 4685
         1018  +  BB aa 4685 4685 4685 4685   BB bb 4685 4685 5251 5251
         1019  +  BB bb 4685 4685 5251 5251   BB bb 4685 4685 5251 5251
         1020  +  BB bb 4685 4685 5251 5251   BB bb 4685 4685 5251 5251
         1021  +  BB bb 4685 4685 5251 5251   CC aa 12025 12025 7340 7340
         1022  +  CC aa 12025 12025 7340 7340   CC aa 12025 12025 7340 7340
         1023  +  CC aa 12025 12025 7340 7340   CC bb 12025 12025 6421 6421
         1024  +  CC bb 12025 12025 6421 6421   DD aa 10462 10462 3122 3122
         1025  +  DD aa 10462 10462 3122 3122   DD aa 10462 10462 3122 3122
         1026  +  DD bb 10462 10462 2493 2493   DD bb 10462 10462 2493 2493
         1027  +  DD bb 10462 10462 2493 2493   DD bb 10462 10462 2493 2493
         1028  +  EE aa 7154 7154 4032 4032   EE aa 7154 7154 4032 4032
         1029  +  EE bb 7154 7154 3597 3597   EE bb 7154 7154 3597 3597
         1030  +  EE bb 7154 7154 3597 3597   FF aa 6571 6571 2539 2539
         1031  +  FF aa 6571 6571 2539 2539   FF aa 6571 6571 2539 2539
         1032  +  FF aa 6571 6571 2539 2539   FF bb 6571 6571 3812 3812
         1033  +  FF bb 6571 6571 3812 3812   FF bb 6571 6571 3812 3812
         1034  +  FF bb 6571 6571 3812 3812   FF bb 6571 6571 3812 3812
         1035  +  FF bb 6571 6571 3812 3812   GG aa 8207 8207 5668 5668
         1036  +  GG aa 8207 8207 5668 5668   GG aa 8207 8207 5668 5668
         1037  +  GG aa 8207 8207 5668 5668   GG bb 8207 8207 5102 5102
         1038  +  GG bb 8207 8207 5102 5102   GG bb 8207 8207 5102 5102
         1039  +  GG bb 8207 8207 5102 5102   HH aa 10136 10136 4468 4468
         1040  +  HH aa 10136 10136 4468 4468   HH aa 10136 10136 4468 4468
         1041  +  HH bb 10136 10136 5120 5120   HH bb 10136 10136 5120 5120
         1042  +  HH bb 10136 10136 5120 5120   HH bb 10136 10136 5120 5120
         1043  +  HH bb 10136 10136 5120 5120   HH bb 10136 10136 5120 5120
         1044  +  II aa 9911 9911 5443 5443   II aa 9911 9911 5443 5443
         1045  +  II bb 9911 9911 4244 4244   II bb 9911 9911 4244 4244
         1046  +  II bb 9911 9911 4244 4244   II bb 9911 9911 4244 4244
         1047  +  II bb 9911 9911 4244 4244   JJ aa 9083 9083 3640 3640
         1048  +  JJ aa 9083 9083 3640 3640   JJ aa 9083 9083 3640 3640
         1049  +  JJ aa 9083 9083 3640 3640   JJ bb 9083 9083 4604 4604
         1050  +  JJ bb 9083 9083 4604 4604   JJ bb 9083 9083 4604 4604
         1051  +  JJ bb 9083 9083 4604 4604}
         1052  +
         1053  +do_execsql_test 1.7.1 {
         1054  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN 3 PRECEDING         AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
         1055  +} {AA aa {}   AA aa {}   AA aa {}   AA aa {}   AA bb {}   AA bb {}   AA bb {}
         1056  +  AA bb {}   BB aa 4685   BB aa 4685   BB aa 4685   BB aa 4685   BB aa 4685
         1057  +  BB aa 4685   BB bb 4685   BB bb 4685   BB bb 4685   BB bb 4685   BB bb 4685
         1058  +  BB bb 4685   CC aa 12025   CC aa 12025   CC aa 12025   CC aa 12025
         1059  +  CC bb 12025   CC bb 12025   DD aa 15147   DD aa 15147   DD aa 15147
         1060  +  DD bb 15147   DD bb 15147   DD bb 15147   DD bb 15147   EE aa 14494
         1061  +  EE aa 14494   EE bb 14494   EE bb 14494   EE bb 14494   FF aa 9693
         1062  +  FF aa 9693   FF aa 9693   FF aa 9693   FF bb 9693   FF bb 9693   FF bb 9693
         1063  +  FF bb 9693   FF bb 9693   FF bb 9693   GG aa 12239   GG aa 12239
         1064  +  GG aa 12239   GG aa 12239   GG bb 12239   GG bb 12239   GG bb 12239
         1065  +  GG bb 12239   HH aa 12675   HH aa 12675   HH aa 12675   HH bb 12675
         1066  +  HH bb 12675   HH bb 12675   HH bb 12675   HH bb 12675   HH bb 12675
         1067  +  II aa 15579   II aa 15579   II bb 15579   II bb 15579   II bb 15579
         1068  +  II bb 15579   II bb 15579   JJ aa 13551   JJ aa 13551   JJ aa 13551
         1069  +  JJ aa 13551   JJ bb 13551   JJ bb 13551   JJ bb 13551   JJ bb 13551}
         1070  +
         1071  +do_execsql_test 1.7.2 {
         1072  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 3 PRECEDING         AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
         1073  +} {AA aa {}   AA aa {}   AA aa {}   AA aa {}   AA bb 2307   AA bb 2307
         1074  +  AA bb 2307   AA bb 2307   BB aa 4685   BB aa 4685   BB aa 4685   BB aa 4685
         1075  +  BB aa 4685   BB aa 4685   BB bb 7558   BB bb 7558   BB bb 7558   BB bb 7558
         1076  +  BB bb 7558   BB bb 7558   CC aa 9718   CC aa 9718   CC aa 9718   CC aa 9718
         1077  +  CC bb 9294   CC bb 9294   DD aa 7589   DD aa 7589   DD aa 7589   DD bb 4447
         1078  +  DD bb 4447   DD bb 4447   DD bb 4447   EE aa 5200   EE aa 5200   EE bb 4922
         1079  +  EE bb 4922   EE bb 4922   FF aa 5246   FF aa 5246   FF aa 5246   FF aa 5246
         1080  +  FF bb 4702   FF bb 4702   FF bb 4702   FF bb 4702   FF bb 4702   FF bb 4702
         1081  +  GG aa 7317   GG aa 7317   GG aa 7317   GG aa 7317   GG bb 7265   GG bb 7265
         1082  +  GG bb 7265   GG bb 7265   HH aa 7973   HH aa 7973   HH aa 7973   HH bb 6717
         1083  +  HH bb 6717   HH bb 6717   HH bb 6717   HH bb 6717   HH bb 6717   II aa 8314
         1084  +  II aa 8314   II bb 6493   II bb 6493   II bb 6493   II bb 6493   II bb 6493
         1085  +  JJ aa 6834   JJ aa 6834   JJ aa 6834   JJ aa 6834   JJ bb 5654   JJ bb 5654
         1086  +  JJ bb 5654   JJ bb 5654}
         1087  +
         1088  +do_execsql_test 1.7.3 {
         1089  +  SELECT a, b, rank() OVER (ORDER BY a  GROUPS BETWEEN 3 PRECEDING         AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
         1090  +} {AA aa 1   AA aa 1   AA aa 1   AA aa 1   AA bb 1   AA bb 1   AA bb 1
         1091  +  AA bb 1   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9
         1092  +  BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   CC aa 21
         1093  +  CC aa 21   CC aa 21   CC aa 21   CC bb 21   CC bb 21   DD aa 27   DD aa 27
         1094  +  DD aa 27   DD bb 27   DD bb 27   DD bb 27   DD bb 27   EE aa 34   EE aa 34
         1095  +  EE bb 34   EE bb 34   EE bb 34   FF aa 39   FF aa 39   FF aa 39   FF aa 39
         1096  +  FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   GG aa 49
         1097  +  GG aa 49   GG aa 49   GG aa 49   GG bb 49   GG bb 49   GG bb 49   GG bb 49
         1098  +  HH aa 57   HH aa 57   HH aa 57   HH bb 57   HH bb 57   HH bb 57   HH bb 57
         1099  +  HH bb 57   HH bb 57   II aa 66   II aa 66   II bb 66   II bb 66   II bb 66
         1100  +  II bb 66   II bb 66   JJ aa 73   JJ aa 73   JJ aa 73   JJ aa 73   JJ bb 73
         1101  +  JJ bb 73   JJ bb 73   JJ bb 73}
         1102  +
         1103  +do_execsql_test 1.7.4 {
         1104  +  SELECT a, b, max(c) OVER (ORDER BY a,b  GROUPS BETWEEN 3 PRECEDING         AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
         1105  +} {AA aa {}   AA aa {}   AA aa {}   AA aa {}   AA bb 934   AA bb 934
         1106  +  AA bb 934   AA bb 934   BB aa 934   BB aa 934   BB aa 934   BB aa 934
         1107  +  BB aa 934   BB aa 934   BB bb 934   BB bb 934   BB bb 934   BB bb 934
         1108  +  BB bb 934   BB bb 934   CC aa 870   CC aa 870   CC aa 870   CC aa 870
         1109  +  CC bb 840   CC bb 840   DD aa 840   DD aa 840   DD aa 840   DD bb 845
         1110  +  DD bb 845   DD bb 845   DD bb 845   EE aa 959   EE aa 959   EE bb 959
         1111  +  EE bb 959   EE bb 959   FF aa 959   FF aa 959   FF aa 959   FF aa 959
         1112  +  FF bb 777   FF bb 777   FF bb 777   FF bb 777   FF bb 777   FF bb 777
         1113  +  GG aa 938   GG aa 938   GG aa 938   GG aa 938   GG bb 938   GG bb 938
         1114  +  GG bb 938   GG bb 938   HH aa 938   HH aa 938   HH aa 938   HH bb 979
         1115  +  HH bb 979   HH bb 979   HH bb 979   HH bb 979   HH bb 979   II aa 979
         1116  +  II aa 979   II bb 979   II bb 979   II bb 979   II bb 979   II bb 979
         1117  +  JJ aa 963   JJ aa 963   JJ aa 963   JJ aa 963   JJ bb 899   JJ bb 899
         1118  +  JJ bb 899   JJ bb 899}
         1119  +
         1120  +do_execsql_test 1.7.5 {
         1121  +  SELECT a, b, min(c) OVER (ORDER BY a,b  GROUPS BETWEEN 3 PRECEDING         AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
         1122  +} {AA aa {}   AA aa {}   AA aa {}   AA aa {}   AA bb 223   AA bb 223
         1123  +  AA bb 223   AA bb 223   BB aa 223   BB aa 223   BB aa 223   BB aa 223
         1124  +  BB aa 223   BB aa 223   BB bb 223   BB bb 223   BB bb 223   BB bb 223
         1125  +  BB bb 223   BB bb 223   CC aa 247   CC aa 247   CC aa 247   CC aa 247
         1126  +  CC bb 158   CC bb 158   DD aa 158   DD aa 158   DD aa 158   DD bb 158
         1127  +  DD bb 158   DD bb 158   DD bb 158   EE aa 224   EE aa 224   EE bb 113
         1128  +  EE bb 113   EE bb 113   FF aa 113   FF aa 113   FF aa 113   FF aa 113
         1129  +  FF bb 113   FF bb 113   FF bb 113   FF bb 113   FF bb 113   FF bb 113
         1130  +  GG aa 102   GG aa 102   GG aa 102   GG aa 102   GG bb 102   GG bb 102
         1131  +  GG bb 102   GG bb 102   HH aa 102   HH aa 102   HH aa 102   HH bb 148
         1132  +  HH bb 148   HH bb 148   HH bb 148   HH bb 148   HH bb 148   II aa 133
         1133  +  II aa 133   II bb 133   II bb 133   II bb 133   II bb 133   II bb 133
         1134  +  JJ aa 133   JJ aa 133   JJ aa 133   JJ aa 133   JJ bb 113   JJ bb 113
         1135  +  JJ bb 113   JJ bb 113}
         1136  +
         1137  +do_execsql_test 1.7.6 {
         1138  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN 3 PRECEDING         AND 1 PRECEDING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
         1139  +} {AA aa {}   AA aa {}   AA aa {}   AA aa {}   AA bb {}   AA bb {}   AA bb {}
         1140  +  AA bb {}   BB aa 4685   BB aa 4685   BB aa 4685   BB aa 4685   BB aa 4685
         1141  +  BB aa 4685   BB bb 4685   BB bb 4685   BB bb 4685   BB bb 4685   BB bb 4685
         1142  +  BB bb 4685   CC aa 12025   CC aa 12025   CC aa 12025   CC aa 12025
         1143  +  CC bb 12025   CC bb 12025   DD aa 15147   DD aa 15147   DD aa 15147
         1144  +  DD bb 15147   DD bb 15147   DD bb 15147   DD bb 15147   EE aa 14494
         1145  +  EE aa 14494   EE bb 14494   EE bb 14494   EE bb 14494   FF aa 9693
         1146  +  FF aa 9693   FF aa 9693   FF aa 9693   FF bb 9693   FF bb 9693   FF bb 9693
         1147  +  FF bb 9693   FF bb 9693   FF bb 9693   GG aa 12239   GG aa 12239
         1148  +  GG aa 12239   GG aa 12239   GG bb 12239   GG bb 12239   GG bb 12239
         1149  +  GG bb 12239   HH aa 12675   HH aa 12675   HH aa 12675   HH bb 12675
         1150  +  HH bb 12675   HH bb 12675   HH bb 12675   HH bb 12675   HH bb 12675
         1151  +  II aa 15579   II aa 15579   II bb 15579   II bb 15579   II bb 15579
         1152  +  II bb 15579   II bb 15579   JJ aa 13551   JJ aa 13551   JJ aa 13551
         1153  +  JJ aa 13551   JJ bb 13551   JJ bb 13551   JJ bb 13551   JJ bb 13551}
         1154  +
         1155  +do_execsql_test 1.7.7 {
         1156  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 3 PRECEDING         AND 1 PRECEDING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
         1157  +} {AA aa {}   AA aa {}   AA aa {}   AA aa {}   AA bb 2307   AA bb 2307
         1158  +  AA bb 2307   AA bb 2307   BB aa 4685   BB aa 4685   BB aa 4685   BB aa 4685
         1159  +  BB aa 4685   BB aa 4685   BB bb 7558   BB bb 7558   BB bb 7558   BB bb 7558
         1160  +  BB bb 7558   BB bb 7558   CC aa 9718   CC aa 9718   CC aa 9718   CC aa 9718
         1161  +  CC bb 9294   CC bb 9294   DD aa 7589   DD aa 7589   DD aa 7589   DD bb 4447
         1162  +  DD bb 4447   DD bb 4447   DD bb 4447   EE aa 5200   EE aa 5200   EE bb 4922
         1163  +  EE bb 4922   EE bb 4922   FF aa 5246   FF aa 5246   FF aa 5246   FF aa 5246
         1164  +  FF bb 4702   FF bb 4702   FF bb 4702   FF bb 4702   FF bb 4702   FF bb 4702
         1165  +  GG aa 7317   GG aa 7317   GG aa 7317   GG aa 7317   GG bb 7265   GG bb 7265
         1166  +  GG bb 7265   GG bb 7265   HH aa 7973   HH aa 7973   HH aa 7973   HH bb 6717
         1167  +  HH bb 6717   HH bb 6717   HH bb 6717   HH bb 6717   HH bb 6717   II aa 8314
         1168  +  II aa 8314   II bb 6493   II bb 6493   II bb 6493   II bb 6493   II bb 6493
         1169  +  JJ aa 6834   JJ aa 6834   JJ aa 6834   JJ aa 6834   JJ bb 5654   JJ bb 5654
         1170  +  JJ bb 5654   JJ bb 5654}
         1171  +
         1172  +do_execsql_test 1.7.8 {
         1173  +  SELECT a, b, 
         1174  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN 3 PRECEDING         AND 1 PRECEDING  EXCLUDE CURRENT ROW),
         1175  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN 3 PRECEDING         AND 1 PRECEDING ),
         1176  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 3 PRECEDING         AND 1 PRECEDING  EXCLUDE CURRENT ROW),
         1177  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 3 PRECEDING         AND 1 PRECEDING )
         1178  +    FROM t3 ORDER BY 1, 2, 3;
         1179  +} {AA aa {} {} {} {}   AA aa {} {} {} {}   AA aa {} {} {} {}
         1180  +  AA aa {} {} {} {}   AA bb {} {} 2307 2307   AA bb {} {} 2307 2307
         1181  +  AA bb {} {} 2307 2307   AA bb {} {} 2307 2307   BB aa 4685 4685 4685 4685
         1182  +  BB aa 4685 4685 4685 4685   BB aa 4685 4685 4685 4685
         1183  +  BB aa 4685 4685 4685 4685   BB aa 4685 4685 4685 4685
         1184  +  BB aa 4685 4685 4685 4685   BB bb 4685 4685 7558 7558
         1185  +  BB bb 4685 4685 7558 7558   BB bb 4685 4685 7558 7558
         1186  +  BB bb 4685 4685 7558 7558   BB bb 4685 4685 7558 7558
         1187  +  BB bb 4685 4685 7558 7558   CC aa 12025 12025 9718 9718
         1188  +  CC aa 12025 12025 9718 9718   CC aa 12025 12025 9718 9718
         1189  +  CC aa 12025 12025 9718 9718   CC bb 12025 12025 9294 9294
         1190  +  CC bb 12025 12025 9294 9294   DD aa 15147 15147 7589 7589
         1191  +  DD aa 15147 15147 7589 7589   DD aa 15147 15147 7589 7589
         1192  +  DD bb 15147 15147 4447 4447   DD bb 15147 15147 4447 4447
         1193  +  DD bb 15147 15147 4447 4447   DD bb 15147 15147 4447 4447
         1194  +  EE aa 14494 14494 5200 5200   EE aa 14494 14494 5200 5200
         1195  +  EE bb 14494 14494 4922 4922   EE bb 14494 14494 4922 4922
         1196  +  EE bb 14494 14494 4922 4922   FF aa 9693 9693 5246 5246
         1197  +  FF aa 9693 9693 5246 5246   FF aa 9693 9693 5246 5246
         1198  +  FF aa 9693 9693 5246 5246   FF bb 9693 9693 4702 4702
         1199  +  FF bb 9693 9693 4702 4702   FF bb 9693 9693 4702 4702
         1200  +  FF bb 9693 9693 4702 4702   FF bb 9693 9693 4702 4702
         1201  +  FF bb 9693 9693 4702 4702   GG aa 12239 12239 7317 7317
         1202  +  GG aa 12239 12239 7317 7317   GG aa 12239 12239 7317 7317
         1203  +  GG aa 12239 12239 7317 7317   GG bb 12239 12239 7265 7265
         1204  +  GG bb 12239 12239 7265 7265   GG bb 12239 12239 7265 7265
         1205  +  GG bb 12239 12239 7265 7265   HH aa 12675 12675 7973 7973
         1206  +  HH aa 12675 12675 7973 7973   HH aa 12675 12675 7973 7973
         1207  +  HH bb 12675 12675 6717 6717   HH bb 12675 12675 6717 6717
         1208  +  HH bb 12675 12675 6717 6717   HH bb 12675 12675 6717 6717
         1209  +  HH bb 12675 12675 6717 6717   HH bb 12675 12675 6717 6717
         1210  +  II aa 15579 15579 8314 8314   II aa 15579 15579 8314 8314
         1211  +  II bb 15579 15579 6493 6493   II bb 15579 15579 6493 6493
         1212  +  II bb 15579 15579 6493 6493   II bb 15579 15579 6493 6493
         1213  +  II bb 15579 15579 6493 6493   JJ aa 13551 13551 6834 6834
         1214  +  JJ aa 13551 13551 6834 6834   JJ aa 13551 13551 6834 6834
         1215  +  JJ aa 13551 13551 6834 6834   JJ bb 13551 13551 5654 5654
         1216  +  JJ bb 13551 13551 5654 5654   JJ bb 13551 13551 5654 5654
         1217  +  JJ bb 13551 13551 5654 5654}
         1218  +
         1219  +do_execsql_test 1.8.1 {
         1220  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN 3 PRECEDING         AND 0 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
         1221  +} {AA aa 4685   AA aa 4685   AA aa 4685   AA aa 4685   AA bb 4685   AA bb 4685
         1222  +  AA bb 4685   AA bb 4685   BB aa 12025   BB aa 12025   BB aa 12025
         1223  +  BB aa 12025   BB aa 12025   BB aa 12025   BB bb 12025   BB bb 12025
         1224  +  BB bb 12025   BB bb 12025   BB bb 12025   BB bb 12025   CC aa 15147
         1225  +  CC aa 15147   CC aa 15147   CC aa 15147   CC bb 15147   CC bb 15147
         1226  +  DD aa 19179   DD aa 19179   DD aa 19179   DD bb 19179   DD bb 19179
         1227  +  DD bb 19179   DD bb 19179   EE aa 17033   EE aa 17033   EE bb 17033
         1228  +  EE bb 17033   EE bb 17033   FF aa 15361   FF aa 15361   FF aa 15361
         1229  +  FF aa 15361   FF bb 15361   FF bb 15361   FF bb 15361   FF bb 15361
         1230  +  FF bb 15361   FF bb 15361   GG aa 16707   GG aa 16707   GG aa 16707
         1231  +  GG aa 16707   GG bb 16707   GG bb 16707   GG bb 16707   GG bb 16707
         1232  +  HH aa 18118   HH aa 18118   HH aa 18118   HH bb 18118   HH bb 18118
         1233  +  HH bb 18118   HH bb 18118   HH bb 18118   HH bb 18118   II aa 19219
         1234  +  II aa 19219   II bb 19219   II bb 19219   II bb 19219   II bb 19219
         1235  +  II bb 19219   JJ aa 17351   JJ aa 17351   JJ aa 17351   JJ aa 17351
         1236  +  JJ bb 17351   JJ bb 17351   JJ bb 17351   JJ bb 17351}
         1237  +
         1238  +do_execsql_test 1.8.2 {
         1239  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 3 PRECEDING         AND 0 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
         1240  +} {AA aa 2307   AA aa 2307   AA aa 2307   AA aa 2307   AA bb 4685   AA bb 4685
         1241  +  AA bb 4685   AA bb 4685   BB aa 7558   BB aa 7558   BB aa 7558   BB aa 7558
         1242  +  BB aa 7558   BB aa 7558   BB bb 12025   BB bb 12025   BB bb 12025
         1243  +  BB bb 12025   BB bb 12025   BB bb 12025   CC aa 11672   CC aa 11672
         1244  +  CC aa 11672   CC aa 11672   CC bb 10462   CC bb 10462   DD aa 8914
         1245  +  DD aa 8914   DD aa 8914   DD bb 7154   DD bb 7154   DD bb 7154   DD bb 7154
         1246  +  EE aa 6090   EE aa 6090   EE bb 6571   EE bb 6571   EE bb 6571   FF aa 7409
         1247  +  FF aa 7409   FF aa 7409   FF aa 7409   FF bb 8207   FF bb 8207   FF bb 8207
         1248  +  FF bb 8207   FF bb 8207   FF bb 8207   GG aa 8914   GG aa 8914   GG aa 8914
         1249  +  GG aa 8914   GG bb 10136   GG bb 10136   GG bb 10136   GG bb 10136
         1250  +  HH aa 10222   HH aa 10222   HH aa 10222   HH bb 9911   HH bb 9911
         1251  +  HH bb 9911   HH bb 9911   HH bb 9911   HH bb 9911   II aa 9364   II aa 9364
         1252  +  II bb 9083   II bb 9083   II bb 9083   II bb 9083   II bb 9083   JJ aa 8848
         1253  +  JJ aa 8848   JJ aa 8848   JJ aa 8848   JJ bb 7440   JJ bb 7440   JJ bb 7440
         1254  +  JJ bb 7440}
         1255  +
         1256  +do_execsql_test 1.8.3 {
         1257  +  SELECT a, b, rank() OVER (ORDER BY a  GROUPS BETWEEN 3 PRECEDING         AND 0 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
         1258  +} {AA aa 1   AA aa 1   AA aa 1   AA aa 1   AA bb 1   AA bb 1   AA bb 1
         1259  +  AA bb 1   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9
         1260  +  BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   CC aa 21
         1261  +  CC aa 21   CC aa 21   CC aa 21   CC bb 21   CC bb 21   DD aa 27   DD aa 27
         1262  +  DD aa 27   DD bb 27   DD bb 27   DD bb 27   DD bb 27   EE aa 34   EE aa 34
         1263  +  EE bb 34   EE bb 34   EE bb 34   FF aa 39   FF aa 39   FF aa 39   FF aa 39
         1264  +  FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   GG aa 49
         1265  +  GG aa 49   GG aa 49   GG aa 49   GG bb 49   GG bb 49   GG bb 49   GG bb 49
         1266  +  HH aa 57   HH aa 57   HH aa 57   HH bb 57   HH bb 57   HH bb 57   HH bb 57
         1267  +  HH bb 57   HH bb 57   II aa 66   II aa 66   II bb 66   II bb 66   II bb 66
         1268  +  II bb 66   II bb 66   JJ aa 73   JJ aa 73   JJ aa 73   JJ aa 73   JJ bb 73
         1269  +  JJ bb 73   JJ bb 73   JJ bb 73}
         1270  +
         1271  +do_execsql_test 1.8.4 {
         1272  +  SELECT a, b, max(c) OVER (ORDER BY a,b  GROUPS BETWEEN 3 PRECEDING         AND 0 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
         1273  +} {AA aa 934   AA aa 934   AA aa 934   AA aa 934   AA bb 934   AA bb 934
         1274  +  AA bb 934   AA bb 934   BB aa 934   BB aa 934   BB aa 934   BB aa 934
         1275  +  BB aa 934   BB aa 934   BB bb 934   BB bb 934   BB bb 934   BB bb 934
         1276  +  BB bb 934   BB bb 934   CC aa 870   CC aa 870   CC aa 870   CC aa 870
         1277  +  CC bb 840   CC bb 840   DD aa 845   DD aa 845   DD aa 845   DD bb 959
         1278  +  DD bb 959   DD bb 959   DD bb 959   EE aa 959   EE aa 959   EE bb 959
         1279  +  EE bb 959   EE bb 959   FF aa 959   FF aa 959   FF aa 959   FF aa 959
         1280  +  FF bb 938   FF bb 938   FF bb 938   FF bb 938   FF bb 938   FF bb 938
         1281  +  GG aa 938   GG aa 938   GG aa 938   GG aa 938   GG bb 938   GG bb 938
         1282  +  GG bb 938   GG bb 938   HH aa 979   HH aa 979   HH aa 979   HH bb 979
         1283  +  HH bb 979   HH bb 979   HH bb 979   HH bb 979   HH bb 979   II aa 979
         1284  +  II aa 979   II bb 979   II bb 979   II bb 979   II bb 979   II bb 979
         1285  +  JJ aa 963   JJ aa 963   JJ aa 963   JJ aa 963   JJ bb 899   JJ bb 899
         1286  +  JJ bb 899   JJ bb 899}
         1287  +
         1288  +do_execsql_test 1.8.5 {
         1289  +  SELECT a, b, min(c) OVER (ORDER BY a,b  GROUPS BETWEEN 3 PRECEDING         AND 0 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
         1290  +} {AA aa 223   AA aa 223   AA aa 223   AA aa 223   AA bb 223   AA bb 223
         1291  +  AA bb 223   AA bb 223   BB aa 223   BB aa 223   BB aa 223   BB aa 223
         1292  +  BB aa 223   BB aa 223   BB bb 223   BB bb 223   BB bb 223   BB bb 223
         1293  +  BB bb 223   BB bb 223   CC aa 158   CC aa 158   CC aa 158   CC aa 158
         1294  +  CC bb 158   CC bb 158   DD aa 158   DD aa 158   DD aa 158   DD bb 158
         1295  +  DD bb 158   DD bb 158   DD bb 158   EE aa 113   EE aa 113   EE bb 113
         1296  +  EE bb 113   EE bb 113   FF aa 113   FF aa 113   FF aa 113   FF aa 113
         1297  +  FF bb 102   FF bb 102   FF bb 102   FF bb 102   FF bb 102   FF bb 102
         1298  +  GG aa 102   GG aa 102   GG aa 102   GG aa 102   GG bb 102   GG bb 102
         1299  +  GG bb 102   GG bb 102   HH aa 102   HH aa 102   HH aa 102   HH bb 133
         1300  +  HH bb 133   HH bb 133   HH bb 133   HH bb 133   HH bb 133   II aa 133
         1301  +  II aa 133   II bb 133   II bb 133   II bb 133   II bb 133   II bb 133
         1302  +  JJ aa 113   JJ aa 113   JJ aa 113   JJ aa 113   JJ bb 113   JJ bb 113
         1303  +  JJ bb 113   JJ bb 113}
         1304  +
         1305  +do_execsql_test 1.8.6 {
         1306  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN 3 PRECEDING         AND 0 PRECEDING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
         1307  +} {AA aa 3751   AA aa 3774   AA aa 4446   AA aa 4462   AA bb 3815   AA bb 4058
         1308  +  AA bb 4113   AA bb 4376   BB aa 11263   BB aa 11365   BB aa 11613
         1309  +  BB aa 11626   BB aa 11632   BB aa 11778   BB bb 11185   BB bb 11233
         1310  +  BB bb 11239   BB bb 11314   BB bb 11320   BB bb 11392   CC aa 14388
         1311  +  CC aa 14540   CC aa 14717   CC aa 14989   CC bb 14325   CC bb 14801
         1312  +  DD aa 18334   DD aa 18923   DD aa 18955   DD bb 18220   DD bb 18385
         1313  +  DD bb 18463   DD bb 18941   EE aa 16256   EE aa 16920   EE bb 16265
         1314  +  EE bb 16404   EE bb 16781   FF aa 14691   FF aa 14694   FF aa 14743
         1315  +  FF aa 15153   FF bb 14423   FF bb 14491   FF bb 14635   FF bb 14787
         1316  +  FF bb 15066   FF bb 15259   GG aa 16073   GG aa 16227   GG aa 16372
         1317  +  GG aa 16559   GG bb 15769   GG bb 15778   GG bb 15863   GG bb 16547
         1318  +  HH aa 17139   HH aa 17328   HH aa 17638   HH bb 17155   HH bb 17388
         1319  +  HH bb 17435   HH bb 17763   HH bb 17788   HH bb 17985   II aa 18567
         1320  +  II aa 18821   II bb 18414   II bb 18548   II bb 18776   II bb 18798
         1321  +  II bb 18969   JJ aa 16452   JJ aa 16583   JJ aa 17117   JJ aa 17238
         1322  +  JJ bb 16512   JJ bb 16997   JJ bb 17015   JJ bb 17094}
         1323  +
         1324  +do_execsql_test 1.8.7 {
         1325  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 3 PRECEDING         AND 0 PRECEDING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
         1326  +} {AA aa 1373   AA aa 1396   AA aa 2068   AA aa 2084   AA bb 3815   AA bb 4058
         1327  +  AA bb 4113   AA bb 4376   BB aa 6796   BB aa 6898   BB aa 7146   BB aa 7159
         1328  +  BB aa 7165   BB aa 7311   BB bb 11185   BB bb 11233   BB bb 11239
         1329  +  BB bb 11314   BB bb 11320   BB bb 11392   CC aa 10913   CC aa 11065
         1330  +  CC aa 11242   CC aa 11514   CC bb 9640   CC bb 10116   DD aa 8069
         1331  +  DD aa 8658   DD aa 8690   DD bb 6195   DD bb 6360   DD bb 6438   DD bb 6916
         1332  +  EE aa 5313   EE aa 5977   EE bb 5803   EE bb 5942   EE bb 6319   FF aa 6739
         1333  +  FF aa 6742   FF aa 6791   FF aa 7201   FF bb 7269   FF bb 7337   FF bb 7481
         1334  +  FF bb 7633   FF bb 7912   FF bb 8105   GG aa 8280   GG aa 8434   GG aa 8579
         1335  +  GG aa 8766   GG bb 9198   GG bb 9207   GG bb 9292   GG bb 9976   HH aa 9243
         1336  +  HH aa 9432   HH aa 9742   HH bb 8948   HH bb 9181   HH bb 9228   HH bb 9556
         1337  +  HH bb 9581   HH bb 9778   II aa 8712   II aa 8966   II bb 8278   II bb 8412
         1338  +  II bb 8640   II bb 8662   II bb 8833   JJ aa 7949   JJ aa 8080   JJ aa 8614
         1339  +  JJ aa 8735   JJ bb 6601   JJ bb 7086   JJ bb 7104   JJ bb 7183}
         1340  +
         1341  +do_execsql_test 1.8.8 {
         1342  +  SELECT a, b, 
         1343  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN 3 PRECEDING         AND 0 PRECEDING  EXCLUDE CURRENT ROW),
         1344  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN 3 PRECEDING         AND 0 PRECEDING ),
         1345  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 3 PRECEDING         AND 0 PRECEDING  EXCLUDE CURRENT ROW),
         1346  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 3 PRECEDING         AND 0 PRECEDING )
         1347  +    FROM t3 ORDER BY 1, 2, 3;
         1348  +} {AA aa 3751 4685 1373 2307   AA aa 3774 4685 1396 2307
         1349  +  AA aa 4446 4685 2068 2307   AA aa 4462 4685 2084 2307
         1350  +  AA bb 3815 4685 3815 4685   AA bb 4058 4685 4058 4685
         1351  +  AA bb 4113 4685 4113 4685   AA bb 4376 4685 4376 4685
         1352  +  BB aa 11263 12025 6796 7558   BB aa 11365 12025 6898 7558
         1353  +  BB aa 11613 12025 7146 7558   BB aa 11626 12025 7159 7558
         1354  +  BB aa 11632 12025 7165 7558   BB aa 11778 12025 7311 7558
         1355  +  BB bb 11185 12025 11185 12025   BB bb 11233 12025 11233 12025
         1356  +  BB bb 11239 12025 11239 12025   BB bb 11314 12025 11314 12025
         1357  +  BB bb 11320 12025 11320 12025   BB bb 11392 12025 11392 12025
         1358  +  CC aa 14388 15147 10913 11672   CC aa 14540 15147 11065 11672
         1359  +  CC aa 14717 15147 11242 11672   CC aa 14989 15147 11514 11672
         1360  +  CC bb 14325 15147 9640 10462   CC bb 14801 15147 10116 10462
         1361  +  DD aa 18334 19179 8069 8914   DD aa 18923 19179 8658 8914
         1362  +  DD aa 18955 19179 8690 8914   DD bb 18220 19179 6195 7154
         1363  +  DD bb 18385 19179 6360 7154   DD bb 18463 19179 6438 7154
         1364  +  DD bb 18941 19179 6916 7154   EE aa 16256 17033 5313 6090
         1365  +  EE aa 16920 17033 5977 6090   EE bb 16265 17033 5803 6571
         1366  +  EE bb 16404 17033 5942 6571   EE bb 16781 17033 6319 6571
         1367  +  FF aa 14691 15361 6739 7409   FF aa 14694 15361 6742 7409
         1368  +  FF aa 14743 15361 6791 7409   FF aa 15153 15361 7201 7409
         1369  +  FF bb 14423 15361 7269 8207   FF bb 14491 15361 7337 8207
         1370  +  FF bb 14635 15361 7481 8207   FF bb 14787 15361 7633 8207
         1371  +  FF bb 15066 15361 7912 8207   FF bb 15259 15361 8105 8207
         1372  +  GG aa 16073 16707 8280 8914   GG aa 16227 16707 8434 8914
         1373  +  GG aa 16372 16707 8579 8914   GG aa 16559 16707 8766 8914
         1374  +  GG bb 15769 16707 9198 10136   GG bb 15778 16707 9207 10136
         1375  +  GG bb 15863 16707 9292 10136   GG bb 16547 16707 9976 10136
         1376  +  HH aa 17139 18118 9243 10222   HH aa 17328 18118 9432 10222
         1377  +  HH aa 17638 18118 9742 10222   HH bb 17155 18118 8948 9911
         1378  +  HH bb 17388 18118 9181 9911   HH bb 17435 18118 9228 9911
         1379  +  HH bb 17763 18118 9556 9911   HH bb 17788 18118 9581 9911
         1380  +  HH bb 17985 18118 9778 9911   II aa 18567 19219 8712 9364
         1381  +  II aa 18821 19219 8966 9364   II bb 18414 19219 8278 9083
         1382  +  II bb 18548 19219 8412 9083   II bb 18776 19219 8640 9083
         1383  +  II bb 18798 19219 8662 9083   II bb 18969 19219 8833 9083
         1384  +  JJ aa 16452 17351 7949 8848   JJ aa 16583 17351 8080 8848
         1385  +  JJ aa 17117 17351 8614 8848   JJ aa 17238 17351 8735 8848
         1386  +  JJ bb 16512 17351 6601 7440   JJ bb 16997 17351 7086 7440
         1387  +  JJ bb 17015 17351 7104 7440   JJ bb 17094 17351 7183 7440}
         1388  +
         1389  +do_execsql_test 1.9.1 {
         1390  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN 2 PRECEDING         AND CURRENT ROW ) FROM t3 ORDER BY 1, 2, 3;
         1391  +} {AA aa 4685   AA aa 4685   AA aa 4685   AA aa 4685   AA bb 4685   AA bb 4685
         1392  +  AA bb 4685   AA bb 4685   BB aa 12025   BB aa 12025   BB aa 12025
         1393  +  BB aa 12025   BB aa 12025   BB aa 12025   BB bb 12025   BB bb 12025
         1394  +  BB bb 12025   BB bb 12025   BB bb 12025   BB bb 12025   CC aa 15147
         1395  +  CC aa 15147   CC aa 15147   CC aa 15147   CC bb 15147   CC bb 15147
         1396  +  DD aa 14494   DD aa 14494   DD aa 14494   DD bb 14494   DD bb 14494
         1397  +  DD bb 14494   DD bb 14494   EE aa 9693   EE aa 9693   EE bb 9693
         1398  +  EE bb 9693   EE bb 9693   FF aa 12239   FF aa 12239   FF aa 12239
         1399  +  FF aa 12239   FF bb 12239   FF bb 12239   FF bb 12239   FF bb 12239
         1400  +  FF bb 12239   FF bb 12239   GG aa 12675   GG aa 12675   GG aa 12675
         1401  +  GG aa 12675   GG bb 12675   GG bb 12675   GG bb 12675   GG bb 12675
         1402  +  HH aa 15579   HH aa 15579   HH aa 15579   HH bb 15579   HH bb 15579
         1403  +  HH bb 15579   HH bb 15579   HH bb 15579   HH bb 15579   II aa 13551
         1404  +  II aa 13551   II bb 13551   II bb 13551   II bb 13551   II bb 13551
         1405  +  II bb 13551   JJ aa 12883   JJ aa 12883   JJ aa 12883   JJ aa 12883
         1406  +  JJ bb 12883   JJ bb 12883   JJ bb 12883   JJ bb 12883}
         1407  +
         1408  +do_execsql_test 1.9.2 {
         1409  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 2 PRECEDING         AND CURRENT ROW ) FROM t3 ORDER BY 1, 2, 3;
         1410  +} {AA aa 2307   AA aa 2307   AA aa 2307   AA aa 2307   AA bb 4685   AA bb 4685
         1411  +  AA bb 4685   AA bb 4685   BB aa 7558   BB aa 7558   BB aa 7558   BB aa 7558
         1412  +  BB aa 7558   BB aa 7558   BB bb 9718   BB bb 9718   BB bb 9718   BB bb 9718
         1413  +  BB bb 9718   BB bb 9718   CC aa 9294   CC aa 9294   CC aa 9294   CC aa 9294
         1414  +  CC bb 7589   CC bb 7589   DD aa 4447   DD aa 4447   DD aa 4447   DD bb 5200
         1415  +  DD bb 5200   DD bb 5200   DD bb 5200   EE aa 4922   EE aa 4922   EE bb 5246
         1416  +  EE bb 5246   EE bb 5246   FF aa 4702   FF aa 4702   FF aa 4702   FF aa 4702
         1417  +  FF bb 7317   FF bb 7317   FF bb 7317   FF bb 7317   FF bb 7317   FF bb 7317
         1418  +  GG aa 7265   GG aa 7265   GG aa 7265   GG aa 7265   GG bb 7973   GG bb 7973
         1419  +  GG bb 7973   GG bb 7973   HH aa 6717   HH aa 6717   HH aa 6717   HH bb 8314
         1420  +  HH bb 8314   HH bb 8314   HH bb 8314   HH bb 8314   HH bb 8314   II aa 6493
         1421  +  II aa 6493   II bb 6834   II bb 6834   II bb 6834   II bb 6834   II bb 6834
         1422  +  JJ aa 5654   JJ aa 5654   JJ aa 5654   JJ aa 5654   JJ bb 6390   JJ bb 6390
         1423  +  JJ bb 6390   JJ bb 6390}
         1424  +
         1425  +do_execsql_test 1.9.3 {
         1426  +  SELECT a, b, rank() OVER (ORDER BY a  GROUPS BETWEEN 2 PRECEDING         AND CURRENT ROW ) FROM t3 ORDER BY 1, 2, 3;
         1427  +} {AA aa 1   AA aa 1   AA aa 1   AA aa 1   AA bb 1   AA bb 1   AA bb 1
         1428  +  AA bb 1   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9
         1429  +  BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   CC aa 21
         1430  +  CC aa 21   CC aa 21   CC aa 21   CC bb 21   CC bb 21   DD aa 27   DD aa 27
         1431  +  DD aa 27   DD bb 27   DD bb 27   DD bb 27   DD bb 27   EE aa 34   EE aa 34
         1432  +  EE bb 34   EE bb 34   EE bb 34   FF aa 39   FF aa 39   FF aa 39   FF aa 39
         1433  +  FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   GG aa 49
         1434  +  GG aa 49   GG aa 49   GG aa 49   GG bb 49   GG bb 49   GG bb 49   GG bb 49
         1435  +  HH aa 57   HH aa 57   HH aa 57   HH bb 57   HH bb 57   HH bb 57   HH bb 57
         1436  +  HH bb 57   HH bb 57   II aa 66   II aa 66   II bb 66   II bb 66   II bb 66
         1437  +  II bb 66   II bb 66   JJ aa 73   JJ aa 73   JJ aa 73   JJ aa 73   JJ bb 73
         1438  +  JJ bb 73   JJ bb 73   JJ bb 73}
         1439  +
         1440  +do_execsql_test 1.9.4 {
         1441  +  SELECT a, b, max(c) OVER (ORDER BY a,b  GROUPS BETWEEN 2 PRECEDING         AND CURRENT ROW ) FROM t3 ORDER BY 1, 2, 3;
         1442  +} {AA aa 934   AA aa 934   AA aa 934   AA aa 934   AA bb 934   AA bb 934
         1443  +  AA bb 934   AA bb 934   BB aa 934   BB aa 934   BB aa 934   BB aa 934
         1444  +  BB aa 934   BB aa 934   BB bb 870   BB bb 870   BB bb 870   BB bb 870
         1445  +  BB bb 870   BB bb 870   CC aa 840   CC aa 840   CC aa 840   CC aa 840
         1446  +  CC bb 840   CC bb 840   DD aa 845   DD aa 845   DD aa 845   DD bb 959
         1447  +  DD bb 959   DD bb 959   DD bb 959   EE aa 959   EE aa 959   EE bb 959
         1448  +  EE bb 959   EE bb 959   FF aa 777   FF aa 777   FF aa 777   FF aa 777
         1449  +  FF bb 938   FF bb 938   FF bb 938   FF bb 938   FF bb 938   FF bb 938
         1450  +  GG aa 938   GG aa 938   GG aa 938   GG aa 938   GG bb 938   GG bb 938
         1451  +  GG bb 938   GG bb 938   HH aa 979   HH aa 979   HH aa 979   HH bb 979
         1452  +  HH bb 979   HH bb 979   HH bb 979   HH bb 979   HH bb 979   II aa 979
         1453  +  II aa 979   II bb 963   II bb 963   II bb 963   II bb 963   II bb 963
         1454  +  JJ aa 899   JJ aa 899   JJ aa 899   JJ aa 899   JJ bb 899   JJ bb 899
         1455  +  JJ bb 899   JJ bb 899}
         1456  +
         1457  +do_execsql_test 1.9.5 {
         1458  +  SELECT a, b, min(c) OVER (ORDER BY a,b  GROUPS BETWEEN 2 PRECEDING         AND CURRENT ROW ) FROM t3 ORDER BY 1, 2, 3;
         1459  +} {AA aa 223   AA aa 223   AA aa 223   AA aa 223   AA bb 223   AA bb 223
         1460  +  AA bb 223   AA bb 223   BB aa 223   BB aa 223   BB aa 223   BB aa 223
         1461  +  BB aa 223   BB aa 223   BB bb 247   BB bb 247   BB bb 247   BB bb 247
         1462  +  BB bb 247   BB bb 247   CC aa 158   CC aa 158   CC aa 158   CC aa 158
         1463  +  CC bb 158   CC bb 158   DD aa 158   DD aa 158   DD aa 158   DD bb 224
         1464  +  DD bb 224   DD bb 224   DD bb 224   EE aa 113   EE aa 113   EE bb 113
         1465  +  EE bb 113   EE bb 113   FF aa 113   FF aa 113   FF aa 113   FF aa 113
         1466  +  FF bb 102   FF bb 102   FF bb 102   FF bb 102   FF bb 102   FF bb 102
         1467  +  GG aa 102   GG aa 102   GG aa 102   GG aa 102   GG bb 102   GG bb 102
         1468  +  GG bb 102   GG bb 102   HH aa 148   HH aa 148   HH aa 148   HH bb 133
         1469  +  HH bb 133   HH bb 133   HH bb 133   HH bb 133   HH bb 133   II aa 133
         1470  +  II aa 133   II bb 133   II bb 133   II bb 133   II bb 133   II bb 133
         1471  +  JJ aa 113   JJ aa 113   JJ aa 113   JJ aa 113   JJ bb 113   JJ bb 113
         1472  +  JJ bb 113   JJ bb 113}
         1473  +
         1474  +do_execsql_test 1.9.6 {
         1475  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN 2 PRECEDING         AND CURRENT ROW  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
         1476  +} {AA aa 3751   AA aa 3774   AA aa 4446   AA aa 4462   AA bb 3815   AA bb 4058
         1477  +  AA bb 4113   AA bb 4376   BB aa 11263   BB aa 11365   BB aa 11613
         1478  +  BB aa 11626   BB aa 11632   BB aa 11778   BB bb 11185   BB bb 11233
         1479  +  BB bb 11239   BB bb 11314   BB bb 11320   BB bb 11392   CC aa 14388
         1480  +  CC aa 14540   CC aa 14717   CC aa 14989   CC bb 14325   CC bb 14801
         1481  +  DD aa 13649   DD aa 14238   DD aa 14270   DD bb 13535   DD bb 13700
         1482  +  DD bb 13778   DD bb 14256   EE aa 8916   EE aa 9580   EE bb 8925
         1483  +  EE bb 9064   EE bb 9441   FF aa 11569   FF aa 11572   FF aa 11621
         1484  +  FF aa 12031   FF bb 11301   FF bb 11369   FF bb 11513   FF bb 11665
         1485  +  FF bb 11944   FF bb 12137   GG aa 12041   GG aa 12195   GG aa 12340
         1486  +  GG aa 12527   GG bb 11737   GG bb 11746   GG bb 11831   GG bb 12515
         1487  +  HH aa 14600   HH aa 14789   HH aa 15099   HH bb 14616   HH bb 14849
         1488  +  HH bb 14896   HH bb 15224   HH bb 15249   HH bb 15446   II aa 12899
         1489  +  II aa 13153   II bb 12746   II bb 12880   II bb 13108   II bb 13130
         1490  +  II bb 13301   JJ aa 11984   JJ aa 12115   JJ aa 12649   JJ aa 12770
         1491  +  JJ bb 12044   JJ bb 12529   JJ bb 12547   JJ bb 12626}
         1492  +
         1493  +do_execsql_test 1.9.7 {
         1494  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 2 PRECEDING         AND CURRENT ROW  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
         1495  +} {AA aa 1373   AA aa 1396   AA aa 2068   AA aa 2084   AA bb 3815   AA bb 4058
         1496  +  AA bb 4113   AA bb 4376   BB aa 6796   BB aa 6898   BB aa 7146   BB aa 7159
         1497  +  BB aa 7165   BB aa 7311   BB bb 8878   BB bb 8926   BB bb 8932   BB bb 9007
         1498  +  BB bb 9013   BB bb 9085   CC aa 8535   CC aa 8687   CC aa 8864   CC aa 9136
         1499  +  CC bb 6767   CC bb 7243   DD aa 3602   DD aa 4191   DD aa 4223   DD bb 4241
         1500  +  DD bb 4406   DD bb 4484   DD bb 4962   EE aa 4145   EE aa 4809   EE bb 4478
         1501  +  EE bb 4617   EE bb 4994   FF aa 4032   FF aa 4035   FF aa 4084   FF aa 4494
         1502  +  FF bb 6379   FF bb 6447   FF bb 6591   FF bb 6743   FF bb 7022   FF bb 7215
         1503  +  GG aa 6631   GG aa 6785   GG aa 6930   GG aa 7117   GG bb 7035   GG bb 7044
         1504  +  GG bb 7129   GG bb 7813   HH aa 5738   HH aa 5927   HH aa 6237   HH bb 7351
         1505  +  HH bb 7584   HH bb 7631   HH bb 7959   HH bb 7984   HH bb 8181   II aa 5841
         1506  +  II aa 6095   II bb 6029   II bb 6163   II bb 6391   II bb 6413   II bb 6584
         1507  +  JJ aa 4755   JJ aa 4886   JJ aa 5420   JJ aa 5541   JJ bb 5551   JJ bb 6036
         1508  +  JJ bb 6054   JJ bb 6133}
         1509  +
         1510  +do_execsql_test 1.9.8 {
         1511  +  SELECT a, b, 
         1512  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN 2 PRECEDING         AND CURRENT ROW  EXCLUDE CURRENT ROW),
         1513  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN 2 PRECEDING         AND CURRENT ROW ),
         1514  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 2 PRECEDING         AND CURRENT ROW  EXCLUDE CURRENT ROW),
         1515  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 2 PRECEDING         AND CURRENT ROW )
         1516  +    FROM t3 ORDER BY 1, 2, 3;
         1517  +} {AA aa 3751 4685 1373 2307   AA aa 3774 4685 1396 2307
         1518  +  AA aa 4446 4685 2068 2307   AA aa 4462 4685 2084 2307
         1519  +  AA bb 3815 4685 3815 4685   AA bb 4058 4685 4058 4685
         1520  +  AA bb 4113 4685 4113 4685   AA bb 4376 4685 4376 4685
         1521  +  BB aa 11263 12025 6796 7558   BB aa 11365 12025 6898 7558
         1522  +  BB aa 11613 12025 7146 7558   BB aa 11626 12025 7159 7558
         1523  +  BB aa 11632 12025 7165 7558   BB aa 11778 12025 7311 7558
         1524  +  BB bb 11185 12025 8878 9718   BB bb 11233 12025 8926 9718
         1525  +  BB bb 11239 12025 8932 9718   BB bb 11314 12025 9007 9718
         1526  +  BB bb 11320 12025 9013 9718   BB bb 11392 12025 9085 9718
         1527  +  CC aa 14388 15147 8535 9294   CC aa 14540 15147 8687 9294
         1528  +  CC aa 14717 15147 8864 9294   CC aa 14989 15147 9136 9294
         1529  +  CC bb 14325 15147 6767 7589   CC bb 14801 15147 7243 7589
         1530  +  DD aa 13649 14494 3602 4447   DD aa 14238 14494 4191 4447
         1531  +  DD aa 14270 14494 4223 4447   DD bb 13535 14494 4241 5200
         1532  +  DD bb 13700 14494 4406 5200   DD bb 13778 14494 4484 5200
         1533  +  DD bb 14256 14494 4962 5200   EE aa 8916 9693 4145 4922
         1534  +  EE aa 9580 9693 4809 4922   EE bb 8925 9693 4478 5246
         1535  +  EE bb 9064 9693 4617 5246   EE bb 9441 9693 4994 5246
         1536  +  FF aa 11569 12239 4032 4702   FF aa 11572 12239 4035 4702
         1537  +  FF aa 11621 12239 4084 4702   FF aa 12031 12239 4494 4702
         1538  +  FF bb 11301 12239 6379 7317   FF bb 11369 12239 6447 7317
         1539  +  FF bb 11513 12239 6591 7317   FF bb 11665 12239 6743 7317
         1540  +  FF bb 11944 12239 7022 7317   FF bb 12137 12239 7215 7317
         1541  +  GG aa 12041 12675 6631 7265   GG aa 12195 12675 6785 7265
         1542  +  GG aa 12340 12675 6930 7265   GG aa 12527 12675 7117 7265
         1543  +  GG bb 11737 12675 7035 7973   GG bb 11746 12675 7044 7973
         1544  +  GG bb 11831 12675 7129 7973   GG bb 12515 12675 7813 7973
         1545  +  HH aa 14600 15579 5738 6717   HH aa 14789 15579 5927 6717
         1546  +  HH aa 15099 15579 6237 6717   HH bb 14616 15579 7351 8314
         1547  +  HH bb 14849 15579 7584 8314   HH bb 14896 15579 7631 8314
         1548  +  HH bb 15224 15579 7959 8314   HH bb 15249 15579 7984 8314
         1549  +  HH bb 15446 15579 8181 8314   II aa 12899 13551 5841 6493
         1550  +  II aa 13153 13551 6095 6493   II bb 12746 13551 6029 6834
         1551  +  II bb 12880 13551 6163 6834   II bb 13108 13551 6391 6834
         1552  +  II bb 13130 13551 6413 6834   II bb 13301 13551 6584 6834
         1553  +  JJ aa 11984 12883 4755 5654   JJ aa 12115 12883 4886 5654
         1554  +  JJ aa 12649 12883 5420 5654   JJ aa 12770 12883 5541 5654
         1555  +  JJ bb 12044 12883 5551 6390   JJ bb 12529 12883 6036 6390
         1556  +  JJ bb 12547 12883 6054 6390   JJ bb 12626 12883 6133 6390}
         1557  +
         1558  +do_execsql_test 1.10.1 {
         1559  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN 3 PRECEDING         AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         1560  +} {AA aa 4685   AA aa 4685   AA aa 4685   AA aa 4685   AA bb 4685   AA bb 4685
         1561  +  AA bb 4685   AA bb 4685   BB aa 12025   BB aa 12025   BB aa 12025
         1562  +  BB aa 12025   BB aa 12025   BB aa 12025   BB bb 12025   BB bb 12025
         1563  +  BB bb 12025   BB bb 12025   BB bb 12025   BB bb 12025   CC aa 15147
         1564  +  CC aa 15147   CC aa 15147   CC aa 15147   CC bb 15147   CC bb 15147
         1565  +  DD aa 19179   DD aa 19179   DD aa 19179   DD bb 19179   DD bb 19179
         1566  +  DD bb 19179   DD bb 19179   EE aa 17033   EE aa 17033   EE bb 17033
         1567  +  EE bb 17033   EE bb 17033   FF aa 15361   FF aa 15361   FF aa 15361
         1568  +  FF aa 15361   FF bb 15361   FF bb 15361   FF bb 15361   FF bb 15361
         1569  +  FF bb 15361   FF bb 15361   GG aa 16707   GG aa 16707   GG aa 16707
         1570  +  GG aa 16707   GG bb 16707   GG bb 16707   GG bb 16707   GG bb 16707
         1571  +  HH aa 18118   HH aa 18118   HH aa 18118   HH bb 18118   HH bb 18118
         1572  +  HH bb 18118   HH bb 18118   HH bb 18118   HH bb 18118   II aa 19219
         1573  +  II aa 19219   II bb 19219   II bb 19219   II bb 19219   II bb 19219
         1574  +  II bb 19219   JJ aa 17351   JJ aa 17351   JJ aa 17351   JJ aa 17351
         1575  +  JJ bb 17351   JJ bb 17351   JJ bb 17351   JJ bb 17351}
         1576  +
         1577  +do_execsql_test 1.10.2 {
         1578  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 3 PRECEDING         AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         1579  +} {AA aa 2307   AA aa 2307   AA aa 2307   AA aa 2307   AA bb 4685   AA bb 4685
         1580  +  AA bb 4685   AA bb 4685   BB aa 7558   BB aa 7558   BB aa 7558   BB aa 7558
         1581  +  BB aa 7558   BB aa 7558   BB bb 12025   BB bb 12025   BB bb 12025
         1582  +  BB bb 12025   BB bb 12025   BB bb 12025   CC aa 11672   CC aa 11672
         1583  +  CC aa 11672   CC aa 11672   CC bb 10462   CC bb 10462   DD aa 8914
         1584  +  DD aa 8914   DD aa 8914   DD bb 7154   DD bb 7154   DD bb 7154   DD bb 7154
         1585  +  EE aa 6090   EE aa 6090   EE bb 6571   EE bb 6571   EE bb 6571   FF aa 7409
         1586  +  FF aa 7409   FF aa 7409   FF aa 7409   FF bb 8207   FF bb 8207   FF bb 8207
         1587  +  FF bb 8207   FF bb 8207   FF bb 8207   GG aa 8914   GG aa 8914   GG aa 8914
         1588  +  GG aa 8914   GG bb 10136   GG bb 10136   GG bb 10136   GG bb 10136
         1589  +  HH aa 10222   HH aa 10222   HH aa 10222   HH bb 9911   HH bb 9911
         1590  +  HH bb 9911   HH bb 9911   HH bb 9911   HH bb 9911   II aa 9364   II aa 9364
         1591  +  II bb 9083   II bb 9083   II bb 9083   II bb 9083   II bb 9083   JJ aa 8848
         1592  +  JJ aa 8848   JJ aa 8848   JJ aa 8848   JJ bb 7440   JJ bb 7440   JJ bb 7440
         1593  +  JJ bb 7440}
         1594  +
         1595  +do_execsql_test 1.10.3 {
         1596  +  SELECT a, b, rank() OVER (ORDER BY a  GROUPS BETWEEN 3 PRECEDING         AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         1597  +} {AA aa 1   AA aa 1   AA aa 1   AA aa 1   AA bb 1   AA bb 1   AA bb 1
         1598  +  AA bb 1   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9
         1599  +  BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   CC aa 21
         1600  +  CC aa 21   CC aa 21   CC aa 21   CC bb 21   CC bb 21   DD aa 27   DD aa 27
         1601  +  DD aa 27   DD bb 27   DD bb 27   DD bb 27   DD bb 27   EE aa 34   EE aa 34
         1602  +  EE bb 34   EE bb 34   EE bb 34   FF aa 39   FF aa 39   FF aa 39   FF aa 39
         1603  +  FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   GG aa 49
         1604  +  GG aa 49   GG aa 49   GG aa 49   GG bb 49   GG bb 49   GG bb 49   GG bb 49
         1605  +  HH aa 57   HH aa 57   HH aa 57   HH bb 57   HH bb 57   HH bb 57   HH bb 57
         1606  +  HH bb 57   HH bb 57   II aa 66   II aa 66   II bb 66   II bb 66   II bb 66
         1607  +  II bb 66   II bb 66   JJ aa 73   JJ aa 73   JJ aa 73   JJ aa 73   JJ bb 73
         1608  +  JJ bb 73   JJ bb 73   JJ bb 73}
         1609  +
         1610  +do_execsql_test 1.10.4 {
         1611  +  SELECT a, b, max(c) OVER (ORDER BY a,b  GROUPS BETWEEN 3 PRECEDING         AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         1612  +} {AA aa 934   AA aa 934   AA aa 934   AA aa 934   AA bb 934   AA bb 934
         1613  +  AA bb 934   AA bb 934   BB aa 934   BB aa 934   BB aa 934   BB aa 934
         1614  +  BB aa 934   BB aa 934   BB bb 934   BB bb 934   BB bb 934   BB bb 934
         1615  +  BB bb 934   BB bb 934   CC aa 870   CC aa 870   CC aa 870   CC aa 870
         1616  +  CC bb 840   CC bb 840   DD aa 845   DD aa 845   DD aa 845   DD bb 959
         1617  +  DD bb 959   DD bb 959   DD bb 959   EE aa 959   EE aa 959   EE bb 959
         1618  +  EE bb 959   EE bb 959   FF aa 959   FF aa 959   FF aa 959   FF aa 959
         1619  +  FF bb 938   FF bb 938   FF bb 938   FF bb 938   FF bb 938   FF bb 938
         1620  +  GG aa 938   GG aa 938   GG aa 938   GG aa 938   GG bb 938   GG bb 938
         1621  +  GG bb 938   GG bb 938   HH aa 979   HH aa 979   HH aa 979   HH bb 979
         1622  +  HH bb 979   HH bb 979   HH bb 979   HH bb 979   HH bb 979   II aa 979
         1623  +  II aa 979   II bb 979   II bb 979   II bb 979   II bb 979   II bb 979
         1624  +  JJ aa 963   JJ aa 963   JJ aa 963   JJ aa 963   JJ bb 899   JJ bb 899
         1625  +  JJ bb 899   JJ bb 899}
         1626  +
         1627  +do_execsql_test 1.10.5 {
         1628  +  SELECT a, b, min(c) OVER (ORDER BY a,b  GROUPS BETWEEN 3 PRECEDING         AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         1629  +} {AA aa 223   AA aa 223   AA aa 223   AA aa 223   AA bb 223   AA bb 223
         1630  +  AA bb 223   AA bb 223   BB aa 223   BB aa 223   BB aa 223   BB aa 223
         1631  +  BB aa 223   BB aa 223   BB bb 223   BB bb 223   BB bb 223   BB bb 223
         1632  +  BB bb 223   BB bb 223   CC aa 158   CC aa 158   CC aa 158   CC aa 158
         1633  +  CC bb 158   CC bb 158   DD aa 158   DD aa 158   DD aa 158   DD bb 158
         1634  +  DD bb 158   DD bb 158   DD bb 158   EE aa 113   EE aa 113   EE bb 113
         1635  +  EE bb 113   EE bb 113   FF aa 113   FF aa 113   FF aa 113   FF aa 113
         1636  +  FF bb 102   FF bb 102   FF bb 102   FF bb 102   FF bb 102   FF bb 102
         1637  +  GG aa 102   GG aa 102   GG aa 102   GG aa 102   GG bb 102   GG bb 102
         1638  +  GG bb 102   GG bb 102   HH aa 102   HH aa 102   HH aa 102   HH bb 133
         1639  +  HH bb 133   HH bb 133   HH bb 133   HH bb 133   HH bb 133   II aa 133
         1640  +  II aa 133   II bb 133   II bb 133   II bb 133   II bb 133   II bb 133
         1641  +  JJ aa 113   JJ aa 113   JJ aa 113   JJ aa 113   JJ bb 113   JJ bb 113
         1642  +  JJ bb 113   JJ bb 113}
         1643  +
         1644  +do_execsql_test 1.10.6 {
         1645  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN 3 PRECEDING         AND 0 FOLLOWING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
         1646  +} {AA aa 3751   AA aa 3774   AA aa 4446   AA aa 4462   AA bb 3815   AA bb 4058
         1647  +  AA bb 4113   AA bb 4376   BB aa 11263   BB aa 11365   BB aa 11613
         1648  +  BB aa 11626   BB aa 11632   BB aa 11778   BB bb 11185   BB bb 11233
         1649  +  BB bb 11239   BB bb 11314   BB bb 11320   BB bb 11392   CC aa 14388
         1650  +  CC aa 14540   CC aa 14717   CC aa 14989   CC bb 14325   CC bb 14801
         1651  +  DD aa 18334   DD aa 18923   DD aa 18955   DD bb 18220   DD bb 18385
         1652  +  DD bb 18463   DD bb 18941   EE aa 16256   EE aa 16920   EE bb 16265
         1653  +  EE bb 16404   EE bb 16781   FF aa 14691   FF aa 14694   FF aa 14743
         1654  +  FF aa 15153   FF bb 14423   FF bb 14491   FF bb 14635   FF bb 14787
         1655  +  FF bb 15066   FF bb 15259   GG aa 16073   GG aa 16227   GG aa 16372
         1656  +  GG aa 16559   GG bb 15769   GG bb 15778   GG bb 15863   GG bb 16547
         1657  +  HH aa 17139   HH aa 17328   HH aa 17638   HH bb 17155   HH bb 17388
         1658  +  HH bb 17435   HH bb 17763   HH bb 17788   HH bb 17985   II aa 18567
         1659  +  II aa 18821   II bb 18414   II bb 18548   II bb 18776   II bb 18798
         1660  +  II bb 18969   JJ aa 16452   JJ aa 16583   JJ aa 17117   JJ aa 17238
         1661  +  JJ bb 16512   JJ bb 16997   JJ bb 17015   JJ bb 17094}
         1662  +
         1663  +do_execsql_test 1.10.7 {
         1664  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 3 PRECEDING         AND 0 FOLLOWING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
         1665  +} {AA aa 1373   AA aa 1396   AA aa 2068   AA aa 2084   AA bb 3815   AA bb 4058
         1666  +  AA bb 4113   AA bb 4376   BB aa 6796   BB aa 6898   BB aa 7146   BB aa 7159
         1667  +  BB aa 7165   BB aa 7311   BB bb 11185   BB bb 11233   BB bb 11239
         1668  +  BB bb 11314   BB bb 11320   BB bb 11392   CC aa 10913   CC aa 11065
         1669  +  CC aa 11242   CC aa 11514   CC bb 9640   CC bb 10116   DD aa 8069
         1670  +  DD aa 8658   DD aa 8690   DD bb 6195   DD bb 6360   DD bb 6438   DD bb 6916
         1671  +  EE aa 5313   EE aa 5977   EE bb 5803   EE bb 5942   EE bb 6319   FF aa 6739
         1672  +  FF aa 6742   FF aa 6791   FF aa 7201   FF bb 7269   FF bb 7337   FF bb 7481
         1673  +  FF bb 7633   FF bb 7912   FF bb 8105   GG aa 8280   GG aa 8434   GG aa 8579
         1674  +  GG aa 8766   GG bb 9198   GG bb 9207   GG bb 9292   GG bb 9976   HH aa 9243
         1675  +  HH aa 9432   HH aa 9742   HH bb 8948   HH bb 9181   HH bb 9228   HH bb 9556
         1676  +  HH bb 9581   HH bb 9778   II aa 8712   II aa 8966   II bb 8278   II bb 8412
         1677  +  II bb 8640   II bb 8662   II bb 8833   JJ aa 7949   JJ aa 8080   JJ aa 8614
         1678  +  JJ aa 8735   JJ bb 6601   JJ bb 7086   JJ bb 7104   JJ bb 7183}
         1679  +
         1680  +do_execsql_test 1.10.8 {
         1681  +  SELECT a, b, 
         1682  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN 3 PRECEDING         AND 0 FOLLOWING  EXCLUDE CURRENT ROW),
         1683  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN 3 PRECEDING         AND 0 FOLLOWING ),
         1684  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 3 PRECEDING         AND 0 FOLLOWING  EXCLUDE CURRENT ROW),
         1685  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 3 PRECEDING         AND 0 FOLLOWING )
         1686  +    FROM t3 ORDER BY 1, 2, 3;
         1687  +} {AA aa 3751 4685 1373 2307   AA aa 3774 4685 1396 2307
         1688  +  AA aa 4446 4685 2068 2307   AA aa 4462 4685 2084 2307
         1689  +  AA bb 3815 4685 3815 4685   AA bb 4058 4685 4058 4685
         1690  +  AA bb 4113 4685 4113 4685   AA bb 4376 4685 4376 4685
         1691  +  BB aa 11263 12025 6796 7558   BB aa 11365 12025 6898 7558
         1692  +  BB aa 11613 12025 7146 7558   BB aa 11626 12025 7159 7558
         1693  +  BB aa 11632 12025 7165 7558   BB aa 11778 12025 7311 7558
         1694  +  BB bb 11185 12025 11185 12025   BB bb 11233 12025 11233 12025
         1695  +  BB bb 11239 12025 11239 12025   BB bb 11314 12025 11314 12025
         1696  +  BB bb 11320 12025 11320 12025   BB bb 11392 12025 11392 12025
         1697  +  CC aa 14388 15147 10913 11672   CC aa 14540 15147 11065 11672
         1698  +  CC aa 14717 15147 11242 11672   CC aa 14989 15147 11514 11672
         1699  +  CC bb 14325 15147 9640 10462   CC bb 14801 15147 10116 10462
         1700  +  DD aa 18334 19179 8069 8914   DD aa 18923 19179 8658 8914
         1701  +  DD aa 18955 19179 8690 8914   DD bb 18220 19179 6195 7154
         1702  +  DD bb 18385 19179 6360 7154   DD bb 18463 19179 6438 7154
         1703  +  DD bb 18941 19179 6916 7154   EE aa 16256 17033 5313 6090
         1704  +  EE aa 16920 17033 5977 6090   EE bb 16265 17033 5803 6571
         1705  +  EE bb 16404 17033 5942 6571   EE bb 16781 17033 6319 6571
         1706  +  FF aa 14691 15361 6739 7409   FF aa 14694 15361 6742 7409
         1707  +  FF aa 14743 15361 6791 7409   FF aa 15153 15361 7201 7409
         1708  +  FF bb 14423 15361 7269 8207   FF bb 14491 15361 7337 8207
         1709  +  FF bb 14635 15361 7481 8207   FF bb 14787 15361 7633 8207
         1710  +  FF bb 15066 15361 7912 8207   FF bb 15259 15361 8105 8207
         1711  +  GG aa 16073 16707 8280 8914   GG aa 16227 16707 8434 8914
         1712  +  GG aa 16372 16707 8579 8914   GG aa 16559 16707 8766 8914
         1713  +  GG bb 15769 16707 9198 10136   GG bb 15778 16707 9207 10136
         1714  +  GG bb 15863 16707 9292 10136   GG bb 16547 16707 9976 10136
         1715  +  HH aa 17139 18118 9243 10222   HH aa 17328 18118 9432 10222
         1716  +  HH aa 17638 18118 9742 10222   HH bb 17155 18118 8948 9911
         1717  +  HH bb 17388 18118 9181 9911   HH bb 17435 18118 9228 9911
         1718  +  HH bb 17763 18118 9556 9911   HH bb 17788 18118 9581 9911
         1719  +  HH bb 17985 18118 9778 9911   II aa 18567 19219 8712 9364
         1720  +  II aa 18821 19219 8966 9364   II bb 18414 19219 8278 9083
         1721  +  II bb 18548 19219 8412 9083   II bb 18776 19219 8640 9083
         1722  +  II bb 18798 19219 8662 9083   II bb 18969 19219 8833 9083
         1723  +  JJ aa 16452 17351 7949 8848   JJ aa 16583 17351 8080 8848
         1724  +  JJ aa 17117 17351 8614 8848   JJ aa 17238 17351 8735 8848
         1725  +  JJ bb 16512 17351 6601 7440   JJ bb 16997 17351 7086 7440
         1726  +  JJ bb 17015 17351 7104 7440   JJ bb 17094 17351 7183 7440}
         1727  +
         1728  +do_execsql_test 1.11.1 {
         1729  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN 2 PRECEDING         AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         1730  +} {AA aa 44737   AA aa 44737   AA aa 44737   AA aa 44737   AA bb 44737
         1731  +  AA bb 44737   AA bb 44737   AA bb 44737   BB aa 44737   BB aa 44737
         1732  +  BB aa 44737   BB aa 44737   BB aa 44737   BB aa 44737   BB bb 44737
         1733  +  BB bb 44737   BB bb 44737   BB bb 44737   BB bb 44737   BB bb 44737
         1734  +  CC aa 44737   CC aa 44737   CC aa 44737   CC aa 44737   CC bb 44737
         1735  +  CC bb 44737   DD aa 40052   DD aa 40052   DD aa 40052   DD bb 40052
         1736  +  DD bb 40052   DD bb 40052   DD bb 40052   EE aa 32712   EE aa 32712
         1737  +  EE bb 32712   EE bb 32712   EE bb 32712   FF aa 29590   FF aa 29590
         1738  +  FF aa 29590   FF aa 29590   FF bb 29590   FF bb 29590   FF bb 29590
         1739  +  FF bb 29590   FF bb 29590   FF bb 29590   GG aa 25558   GG aa 25558
         1740  +  GG aa 25558   GG aa 25558   GG bb 25558   GG bb 25558   GG bb 25558
         1741  +  GG bb 25558   HH aa 23019   HH aa 23019   HH aa 23019   HH bb 23019
         1742  +  HH bb 23019   HH bb 23019   HH bb 23019   HH bb 23019   HH bb 23019
         1743  +  II aa 17351   II aa 17351   II bb 17351   II bb 17351   II bb 17351
         1744  +  II bb 17351   II bb 17351   JJ aa 12883   JJ aa 12883   JJ aa 12883
         1745  +  JJ aa 12883   JJ bb 12883   JJ bb 12883   JJ bb 12883   JJ bb 12883}
         1746  +
         1747  +do_execsql_test 1.11.2 {
         1748  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 2 PRECEDING         AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         1749  +} {AA aa 44737   AA aa 44737   AA aa 44737   AA aa 44737   AA bb 44737
         1750  +  AA bb 44737   AA bb 44737   AA bb 44737   BB aa 44737   BB aa 44737
         1751  +  BB aa 44737   BB aa 44737   BB aa 44737   BB aa 44737   BB bb 42430
         1752  +  BB bb 42430   BB bb 42430   BB bb 42430   BB bb 42430   BB bb 42430
         1753  +  CC aa 40052   CC aa 40052   CC aa 40052   CC aa 40052   CC bb 37179
         1754  +  CC bb 37179   DD aa 32712   DD aa 32712   DD aa 32712   DD bb 30758
         1755  +  DD bb 30758   DD bb 30758   DD bb 30758   EE aa 29590   EE aa 29590
         1756  +  EE bb 28265   EE bb 28265   EE bb 28265   FF aa 25558   FF aa 25558
         1757  +  FF aa 25558   FF aa 25558   FF bb 24668   FF bb 24668   FF bb 24668
         1758  +  FF bb 24668   FF bb 24668   FF bb 24668   GG aa 23019   GG aa 23019
         1759  +  GG aa 23019   GG aa 23019   GG bb 20856   GG bb 20856   GG bb 20856
         1760  +  GG bb 20856   HH aa 17351   HH aa 17351   HH aa 17351   HH bb 15754
         1761  +  HH bb 15754   HH bb 15754   HH bb 15754   HH bb 15754   HH bb 15754
         1762  +  II aa 12883   II aa 12883   II bb 10634   II bb 10634   II bb 10634
         1763  +  II bb 10634   II bb 10634   JJ aa 7440   JJ aa 7440   JJ aa 7440
         1764  +  JJ aa 7440   JJ bb 6390   JJ bb 6390   JJ bb 6390   JJ bb 6390}
         1765  +
         1766  +do_execsql_test 1.11.3 {
         1767  +  SELECT a, b, rank() OVER (ORDER BY a  GROUPS BETWEEN 2 PRECEDING         AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         1768  +} {AA aa 1   AA aa 1   AA aa 1   AA aa 1   AA bb 1   AA bb 1   AA bb 1
         1769  +  AA bb 1   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9
         1770  +  BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   CC aa 21
         1771  +  CC aa 21   CC aa 21   CC aa 21   CC bb 21   CC bb 21   DD aa 27   DD aa 27
         1772  +  DD aa 27   DD bb 27   DD bb 27   DD bb 27   DD bb 27   EE aa 34   EE aa 34
         1773  +  EE bb 34   EE bb 34   EE bb 34   FF aa 39   FF aa 39   FF aa 39   FF aa 39
         1774  +  FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   GG aa 49
         1775  +  GG aa 49   GG aa 49   GG aa 49   GG bb 49   GG bb 49   GG bb 49   GG bb 49
         1776  +  HH aa 57   HH aa 57   HH aa 57   HH bb 57   HH bb 57   HH bb 57   HH bb 57
         1777  +  HH bb 57   HH bb 57   II aa 66   II aa 66   II bb 66   II bb 66   II bb 66
         1778  +  II bb 66   II bb 66   JJ aa 73   JJ aa 73   JJ aa 73   JJ aa 73   JJ bb 73
         1779  +  JJ bb 73   JJ bb 73   JJ bb 73}
         1780  +
         1781  +do_execsql_test 1.11.4 {
         1782  +  SELECT a, b, max(c) OVER (ORDER BY a,b  GROUPS BETWEEN 2 PRECEDING         AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         1783  +} {AA aa 979   AA aa 979   AA aa 979   AA aa 979   AA bb 979   AA bb 979
         1784  +  AA bb 979   AA bb 979   BB aa 979   BB aa 979   BB aa 979   BB aa 979
         1785  +  BB aa 979   BB aa 979   BB bb 979   BB bb 979   BB bb 979   BB bb 979
         1786  +  BB bb 979   BB bb 979   CC aa 979   CC aa 979   CC aa 979   CC aa 979
         1787  +  CC bb 979   CC bb 979   DD aa 979   DD aa 979   DD aa 979   DD bb 979
         1788  +  DD bb 979   DD bb 979   DD bb 979   EE aa 979   EE aa 979   EE bb 979
         1789  +  EE bb 979   EE bb 979   FF aa 979   FF aa 979   FF aa 979   FF aa 979
         1790  +  FF bb 979   FF bb 979   FF bb 979   FF bb 979   FF bb 979   FF bb 979
         1791  +  GG aa 979   GG aa 979   GG aa 979   GG aa 979   GG bb 979   GG bb 979
         1792  +  GG bb 979   GG bb 979   HH aa 979   HH aa 979   HH aa 979   HH bb 979
         1793  +  HH bb 979   HH bb 979   HH bb 979   HH bb 979   HH bb 979   II aa 979
         1794  +  II aa 979   II bb 963   II bb 963   II bb 963   II bb 963   II bb 963
         1795  +  JJ aa 899   JJ aa 899   JJ aa 899   JJ aa 899   JJ bb 899   JJ bb 899
         1796  +  JJ bb 899   JJ bb 899}
         1797  +
         1798  +do_execsql_test 1.11.5 {
         1799  +  SELECT a, b, min(c) OVER (ORDER BY a,b  GROUPS BETWEEN 2 PRECEDING         AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         1800  +} {AA aa 102   AA aa 102   AA aa 102   AA aa 102   AA bb 102   AA bb 102
         1801  +  AA bb 102   AA bb 102   BB aa 102   BB aa 102   BB aa 102   BB aa 102
         1802  +  BB aa 102   BB aa 102   BB bb 102   BB bb 102   BB bb 102   BB bb 102
         1803  +  BB bb 102   BB bb 102   CC aa 102   CC aa 102   CC aa 102   CC aa 102
         1804  +  CC bb 102   CC bb 102   DD aa 102   DD aa 102   DD aa 102   DD bb 102
         1805  +  DD bb 102   DD bb 102   DD bb 102   EE aa 102   EE aa 102   EE bb 102
         1806  +  EE bb 102   EE bb 102   FF aa 102   FF aa 102   FF aa 102   FF aa 102
         1807  +  FF bb 102   FF bb 102   FF bb 102   FF bb 102   FF bb 102   FF bb 102
         1808  +  GG aa 102   GG aa 102   GG aa 102   GG aa 102   GG bb 102   GG bb 102
         1809  +  GG bb 102   GG bb 102   HH aa 113   HH aa 113   HH aa 113   HH bb 113
         1810  +  HH bb 113   HH bb 113   HH bb 113   HH bb 113   HH bb 113   II aa 113
         1811  +  II aa 113   II bb 113   II bb 113   II bb 113   II bb 113   II bb 113
         1812  +  JJ aa 113   JJ aa 113   JJ aa 113   JJ aa 113   JJ bb 113   JJ bb 113
         1813  +  JJ bb 113   JJ bb 113}
         1814  +
         1815  +do_execsql_test 1.11.6 {
         1816  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN 2 PRECEDING         AND UNBOUNDED FOLLOWING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
         1817  +} {AA aa 43803   AA aa 43826   AA aa 44498   AA aa 44514   AA bb 43867
         1818  +  AA bb 44110   AA bb 44165   AA bb 44428   BB aa 43975   BB aa 44077
         1819  +  BB aa 44325   BB aa 44338   BB aa 44344   BB aa 44490   BB bb 43897
         1820  +  BB bb 43945   BB bb 43951   BB bb 44026   BB bb 44032   BB bb 44104
         1821  +  CC aa 43978   CC aa 44130   CC aa 44307   CC aa 44579   CC bb 43915
         1822  +  CC bb 44391   DD aa 39207   DD aa 39796   DD aa 39828   DD bb 39093
         1823  +  DD bb 39258   DD bb 39336   DD bb 39814   EE aa 31935   EE aa 32599
         1824  +  EE bb 31944   EE bb 32083   EE bb 32460   FF aa 28920   FF aa 28923
         1825  +  FF aa 28972   FF aa 29382   FF bb 28652   FF bb 28720   FF bb 28864
         1826  +  FF bb 29016   FF bb 29295   FF bb 29488   GG aa 24924   GG aa 25078
         1827  +  GG aa 25223   GG aa 25410   GG bb 24620   GG bb 24629   GG bb 24714
         1828  +  GG bb 25398   HH aa 22040   HH aa 22229   HH aa 22539   HH bb 22056
         1829  +  HH bb 22289   HH bb 22336   HH bb 22664   HH bb 22689   HH bb 22886
         1830  +  II aa 16699   II aa 16953   II bb 16546   II bb 16680   II bb 16908
         1831  +  II bb 16930   II bb 17101   JJ aa 11984   JJ aa 12115   JJ aa 12649
         1832  +  JJ aa 12770   JJ bb 12044   JJ bb 12529   JJ bb 12547   JJ bb 12626}
         1833  +
         1834  +do_execsql_test 1.11.7 {
         1835  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 2 PRECEDING         AND UNBOUNDED FOLLOWING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
         1836  +} {AA aa 43803   AA aa 43826   AA aa 44498   AA aa 44514   AA bb 43867
         1837  +  AA bb 44110   AA bb 44165   AA bb 44428   BB aa 43975   BB aa 44077
         1838  +  BB aa 44325   BB aa 44338   BB aa 44344   BB aa 44490   BB bb 41590
         1839  +  BB bb 41638   BB bb 41644   BB bb 41719   BB bb 41725   BB bb 41797
         1840  +  CC aa 39293   CC aa 39445   CC aa 39622   CC aa 39894   CC bb 36357
         1841  +  CC bb 36833   DD aa 31867   DD aa 32456   DD aa 32488   DD bb 29799
         1842  +  DD bb 29964   DD bb 30042   DD bb 30520   EE aa 28813   EE aa 29477
         1843  +  EE bb 27497   EE bb 27636   EE bb 28013   FF aa 24888   FF aa 24891
         1844  +  FF aa 24940   FF aa 25350   FF bb 23730   FF bb 23798   FF bb 23942
         1845  +  FF bb 24094   FF bb 24373   FF bb 24566   GG aa 22385   GG aa 22539
         1846  +  GG aa 22684   GG aa 22871   GG bb 19918   GG bb 19927   GG bb 20012
         1847  +  GG bb 20696   HH aa 16372   HH aa 16561   HH aa 16871   HH bb 14791
         1848  +  HH bb 15024   HH bb 15071   HH bb 15399   HH bb 15424   HH bb 15621
         1849  +  II aa 12231   II aa 12485   II bb 9829   II bb 9963   II bb 10191
         1850  +  II bb 10213   II bb 10384   JJ aa 6541   JJ aa 6672   JJ aa 7206
         1851  +  JJ aa 7327   JJ bb 5551   JJ bb 6036   JJ bb 6054   JJ bb 6133}
         1852  +
         1853  +do_execsql_test 1.11.8 {
         1854  +  SELECT a, b, 
         1855  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN 2 PRECEDING         AND UNBOUNDED FOLLOWING  EXCLUDE CURRENT ROW),
         1856  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN 2 PRECEDING         AND UNBOUNDED FOLLOWING ),
         1857  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 2 PRECEDING         AND UNBOUNDED FOLLOWING  EXCLUDE CURRENT ROW),
         1858  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 2 PRECEDING         AND UNBOUNDED FOLLOWING )
         1859  +    FROM t3 ORDER BY 1, 2, 3;
         1860  +} {AA aa 43803 44737 43803 44737   AA aa 43826 44737 43826 44737
         1861  +  AA aa 44498 44737 44498 44737   AA aa 44514 44737 44514 44737
         1862  +  AA bb 43867 44737 43867 44737   AA bb 44110 44737 44110 44737
         1863  +  AA bb 44165 44737 44165 44737   AA bb 44428 44737 44428 44737
         1864  +  BB aa 43975 44737 43975 44737   BB aa 44077 44737 44077 44737
         1865  +  BB aa 44325 44737 44325 44737   BB aa 44338 44737 44338 44737
         1866  +  BB aa 44344 44737 44344 44737   BB aa 44490 44737 44490 44737
         1867  +  BB bb 43897 44737 41590 42430   BB bb 43945 44737 41638 42430
         1868  +  BB bb 43951 44737 41644 42430   BB bb 44026 44737 41719 42430
         1869  +  BB bb 44032 44737 41725 42430   BB bb 44104 44737 41797 42430
         1870  +  CC aa 43978 44737 39293 40052   CC aa 44130 44737 39445 40052
         1871  +  CC aa 44307 44737 39622 40052   CC aa 44579 44737 39894 40052
         1872  +  CC bb 43915 44737 36357 37179   CC bb 44391 44737 36833 37179
         1873  +  DD aa 39207 40052 31867 32712   DD aa 39796 40052 32456 32712
         1874  +  DD aa 39828 40052 32488 32712   DD bb 39093 40052 29799 30758
         1875  +  DD bb 39258 40052 29964 30758   DD bb 39336 40052 30042 30758
         1876  +  DD bb 39814 40052 30520 30758   EE aa 31935 32712 28813 29590
         1877  +  EE aa 32599 32712 29477 29590   EE bb 31944 32712 27497 28265
         1878  +  EE bb 32083 32712 27636 28265   EE bb 32460 32712 28013 28265
         1879  +  FF aa 28920 29590 24888 25558   FF aa 28923 29590 24891 25558
         1880  +  FF aa 28972 29590 24940 25558   FF aa 29382 29590 25350 25558
         1881  +  FF bb 28652 29590 23730 24668   FF bb 28720 29590 23798 24668
         1882  +  FF bb 28864 29590 23942 24668   FF bb 29016 29590 24094 24668
         1883  +  FF bb 29295 29590 24373 24668   FF bb 29488 29590 24566 24668
         1884  +  GG aa 24924 25558 22385 23019   GG aa 25078 25558 22539 23019
         1885  +  GG aa 25223 25558 22684 23019   GG aa 25410 25558 22871 23019
         1886  +  GG bb 24620 25558 19918 20856   GG bb 24629 25558 19927 20856
         1887  +  GG bb 24714 25558 20012 20856   GG bb 25398 25558 20696 20856
         1888  +  HH aa 22040 23019 16372 17351   HH aa 22229 23019 16561 17351
         1889  +  HH aa 22539 23019 16871 17351   HH bb 22056 23019 14791 15754
         1890  +  HH bb 22289 23019 15024 15754   HH bb 22336 23019 15071 15754
         1891  +  HH bb 22664 23019 15399 15754   HH bb 22689 23019 15424 15754
         1892  +  HH bb 22886 23019 15621 15754   II aa 16699 17351 12231 12883
         1893  +  II aa 16953 17351 12485 12883   II bb 16546 17351 9829 10634
         1894  +  II bb 16680 17351 9963 10634   II bb 16908 17351 10191 10634
         1895  +  II bb 16930 17351 10213 10634   II bb 17101 17351 10384 10634
         1896  +  JJ aa 11984 12883 6541 7440   JJ aa 12115 12883 6672 7440
         1897  +  JJ aa 12649 12883 7206 7440   JJ aa 12770 12883 7327 7440
         1898  +  JJ bb 12044 12883 5551 6390   JJ bb 12529 12883 6036 6390
         1899  +  JJ bb 12547 12883 6054 6390   JJ bb 12626 12883 6133 6390}
         1900  +
         1901  +do_execsql_test 1.12.1 {
         1902  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN CURRENT ROW         AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         1903  +} {AA aa 4685   AA aa 4685   AA aa 4685   AA aa 4685   AA bb 4685   AA bb 4685
         1904  +  AA bb 4685   AA bb 4685   BB aa 7340   BB aa 7340   BB aa 7340   BB aa 7340
         1905  +  BB aa 7340   BB aa 7340   BB bb 7340   BB bb 7340   BB bb 7340   BB bb 7340
         1906  +  BB bb 7340   BB bb 7340   CC aa 3122   CC aa 3122   CC aa 3122   CC aa 3122
         1907  +  CC bb 3122   CC bb 3122   DD aa 4032   DD aa 4032   DD aa 4032   DD bb 4032
         1908  +  DD bb 4032   DD bb 4032   DD bb 4032   EE aa 2539   EE aa 2539   EE bb 2539
         1909  +  EE bb 2539   EE bb 2539   FF aa 5668   FF aa 5668   FF aa 5668   FF aa 5668
         1910  +  FF bb 5668   FF bb 5668   FF bb 5668   FF bb 5668   FF bb 5668   FF bb 5668
         1911  +  GG aa 4468   GG aa 4468   GG aa 4468   GG aa 4468   GG bb 4468   GG bb 4468
         1912  +  GG bb 4468   GG bb 4468   HH aa 5443   HH aa 5443   HH aa 5443   HH bb 5443
         1913  +  HH bb 5443   HH bb 5443   HH bb 5443   HH bb 5443   HH bb 5443   II aa 3640
         1914  +  II aa 3640   II bb 3640   II bb 3640   II bb 3640   II bb 3640   II bb 3640
         1915  +  JJ aa 3800   JJ aa 3800   JJ aa 3800   JJ aa 3800   JJ bb 3800   JJ bb 3800
         1916  +  JJ bb 3800   JJ bb 3800}
         1917  +
         1918  +do_execsql_test 1.12.2 {
         1919  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN CURRENT ROW         AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         1920  +} {AA aa 2307   AA aa 2307   AA aa 2307   AA aa 2307   AA bb 2378   AA bb 2378
         1921  +  AA bb 2378   AA bb 2378   BB aa 2873   BB aa 2873   BB aa 2873   BB aa 2873
         1922  +  BB aa 2873   BB aa 2873   BB bb 4467   BB bb 4467   BB bb 4467   BB bb 4467
         1923  +  BB bb 4467   BB bb 4467   CC aa 1954   CC aa 1954   CC aa 1954   CC aa 1954
         1924  +  CC bb 1168   CC bb 1168   DD aa 1325   DD aa 1325   DD aa 1325   DD bb 2707
         1925  +  DD bb 2707   DD bb 2707   DD bb 2707   EE aa 890   EE aa 890   EE bb 1649
         1926  +  EE bb 1649   EE bb 1649   FF aa 2163   FF aa 2163   FF aa 2163   FF aa 2163
         1927  +  FF bb 3505   FF bb 3505   FF bb 3505   FF bb 3505   FF bb 3505   FF bb 3505
         1928  +  GG aa 1597   GG aa 1597   GG aa 1597   GG aa 1597   GG bb 2871   GG bb 2871
         1929  +  GG bb 2871   GG bb 2871   HH aa 2249   HH aa 2249   HH aa 2249   HH bb 3194
         1930  +  HH bb 3194   HH bb 3194   HH bb 3194   HH bb 3194   HH bb 3194   II aa 1050
         1931  +  II aa 1050   II bb 2590   II bb 2590   II bb 2590   II bb 2590   II bb 2590
         1932  +  JJ aa 2014   JJ aa 2014   JJ aa 2014   JJ aa 2014   JJ bb 1786   JJ bb 1786
         1933  +  JJ bb 1786   JJ bb 1786}
         1934  +
         1935  +do_execsql_test 1.12.3 {
         1936  +  SELECT a, b, rank() OVER (ORDER BY a  GROUPS BETWEEN CURRENT ROW         AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         1937  +} {AA aa 1   AA aa 1   AA aa 1   AA aa 1   AA bb 1   AA bb 1   AA bb 1
         1938  +  AA bb 1   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9
         1939  +  BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   CC aa 21
         1940  +  CC aa 21   CC aa 21   CC aa 21   CC bb 21   CC bb 21   DD aa 27   DD aa 27
         1941  +  DD aa 27   DD bb 27   DD bb 27   DD bb 27   DD bb 27   EE aa 34   EE aa 34
         1942  +  EE bb 34   EE bb 34   EE bb 34   FF aa 39   FF aa 39   FF aa 39   FF aa 39
         1943  +  FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   GG aa 49
         1944  +  GG aa 49   GG aa 49   GG aa 49   GG bb 49   GG bb 49   GG bb 49   GG bb 49
         1945  +  HH aa 57   HH aa 57   HH aa 57   HH bb 57   HH bb 57   HH bb 57   HH bb 57
         1946  +  HH bb 57   HH bb 57   II aa 66   II aa 66   II bb 66   II bb 66   II bb 66
         1947  +  II bb 66   II bb 66   JJ aa 73   JJ aa 73   JJ aa 73   JJ aa 73   JJ bb 73
         1948  +  JJ bb 73   JJ bb 73   JJ bb 73}
         1949  +
         1950  +do_execsql_test 1.12.4 {
         1951  +  SELECT a, b, max(c) OVER (ORDER BY a,b  GROUPS BETWEEN CURRENT ROW         AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         1952  +} {AA aa 934   AA aa 934   AA aa 934   AA aa 934   AA bb 870   AA bb 870
         1953  +  AA bb 870   AA bb 870   BB aa 762   BB aa 762   BB aa 762   BB aa 762
         1954  +  BB aa 762   BB aa 762   BB bb 840   BB bb 840   BB bb 840   BB bb 840
         1955  +  BB bb 840   BB bb 840   CC aa 759   CC aa 759   CC aa 759   CC aa 759
         1956  +  CC bb 822   CC bb 822   DD aa 845   DD aa 845   DD aa 845   DD bb 959
         1957  +  DD bb 959   DD bb 959   DD bb 959   EE aa 777   EE aa 777   EE bb 768
         1958  +  EE bb 768   EE bb 768   FF aa 670   FF aa 670   FF aa 670   FF aa 670
         1959  +  FF bb 938   FF bb 938   FF bb 938   FF bb 938   FF bb 938   FF bb 938
         1960  +  GG aa 634   GG aa 634   GG aa 634   GG aa 634   GG bb 938   GG bb 938
         1961  +  GG bb 938   GG bb 938   HH aa 979   HH aa 979   HH aa 979   HH bb 963
         1962  +  HH bb 963   HH bb 963   HH bb 963   HH bb 963   HH bb 963   II aa 652
         1963  +  II aa 652   II bb 805   II bb 805   II bb 805   II bb 805   II bb 805
         1964  +  JJ aa 899   JJ aa 899   JJ aa 899   JJ aa 899   JJ bb 839   JJ bb 839
         1965  +  JJ bb 839   JJ bb 839}
         1966  +
         1967  +do_execsql_test 1.12.5 {
         1968  +  SELECT a, b, min(c) OVER (ORDER BY a,b  GROUPS BETWEEN CURRENT ROW         AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         1969  +} {AA aa 223   AA aa 223   AA aa 223   AA aa 223   AA bb 309   AA bb 309
         1970  +  AA bb 309   AA bb 309   BB aa 247   BB aa 247   BB aa 247   BB aa 247
         1971  +  BB aa 247   BB aa 247   BB bb 633   BB bb 633   BB bb 633   BB bb 633
         1972  +  BB bb 633   BB bb 633   CC aa 158   CC aa 158   CC aa 158   CC aa 158
         1973  +  CC bb 346   CC bb 346   DD aa 224   DD aa 224   DD aa 224   DD bb 238
         1974  +  DD bb 238   DD bb 238   DD bb 238   EE aa 113   EE aa 113   EE bb 252
         1975  +  EE bb 252   EE bb 252   FF aa 208   FF aa 208   FF aa 208   FF aa 208
         1976  +  FF bb 102   FF bb 102   FF bb 102   FF bb 102   FF bb 102   FF bb 102
         1977  +  GG aa 148   GG aa 148   GG aa 148   GG aa 148   GG bb 160   GG bb 160
         1978  +  GG bb 160   GG bb 160   HH aa 480   HH aa 480   HH aa 480   HH bb 133
         1979  +  HH bb 133   HH bb 133   HH bb 133   HH bb 133   HH bb 133   II aa 398
         1980  +  II aa 398   II bb 250   II bb 250   II bb 250   II bb 250   II bb 250
         1981  +  JJ aa 113   JJ aa 113   JJ aa 113   JJ aa 113   JJ bb 257   JJ bb 257
         1982  +  JJ bb 257   JJ bb 257}
         1983  +
         1984  +do_execsql_test 1.12.6 {
         1985  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN CURRENT ROW         AND 0 FOLLOWING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
         1986  +} {AA aa 3751   AA aa 3774   AA aa 4446   AA aa 4462   AA bb 3815   AA bb 4058
         1987  +  AA bb 4113   AA bb 4376   BB aa 6578   BB aa 6680   BB aa 6928   BB aa 6941
         1988  +  BB aa 6947   BB aa 7093   BB bb 6500   BB bb 6548   BB bb 6554   BB bb 6629
         1989  +  BB bb 6635   BB bb 6707   CC aa 2363   CC aa 2515   CC aa 2692   CC aa 2964
         1990  +  CC bb 2300   CC bb 2776   DD aa 3187   DD aa 3776   DD aa 3808   DD bb 3073
         1991  +  DD bb 3238   DD bb 3316   DD bb 3794   EE aa 1762   EE aa 2426   EE bb 1771
         1992  +  EE bb 1910   EE bb 2287   FF aa 4998   FF aa 5001   FF aa 5050   FF aa 5460
         1993  +  FF bb 4730   FF bb 4798   FF bb 4942   FF bb 5094   FF bb 5373   FF bb 5566
         1994  +  GG aa 3834   GG aa 3988   GG aa 4133   GG aa 4320   GG bb 3530   GG bb 3539
         1995  +  GG bb 3624   GG bb 4308   HH aa 4464   HH aa 4653   HH aa 4963   HH bb 4480
         1996  +  HH bb 4713   HH bb 4760   HH bb 5088   HH bb 5113   HH bb 5310   II aa 2988
         1997  +  II aa 3242   II bb 2835   II bb 2969   II bb 3197   II bb 3219   II bb 3390
         1998  +  JJ aa 2901   JJ aa 3032   JJ aa 3566   JJ aa 3687   JJ bb 2961   JJ bb 3446
         1999  +  JJ bb 3464   JJ bb 3543}
         2000  +
         2001  +do_execsql_test 1.12.7 {
         2002  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN CURRENT ROW         AND 0 FOLLOWING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
         2003  +} {AA aa 1373   AA aa 1396   AA aa 2068   AA aa 2084   AA bb 1508   AA bb 1751
         2004  +  AA bb 1806   AA bb 2069   BB aa 2111   BB aa 2213   BB aa 2461   BB aa 2474
         2005  +  BB aa 2480   BB aa 2626   BB bb 3627   BB bb 3675   BB bb 3681   BB bb 3756
         2006  +  BB bb 3762   BB bb 3834   CC aa 1195   CC aa 1347   CC aa 1524   CC aa 1796
         2007  +  CC bb 346   CC bb 822   DD aa 480   DD aa 1069   DD aa 1101   DD bb 1748
         2008  +  DD bb 1913   DD bb 1991   DD bb 2469   EE aa 113   EE aa 777   EE bb 881
         2009  +  EE bb 1020   EE bb 1397   FF aa 1493   FF aa 1496   FF aa 1545   FF aa 1955
         2010  +  FF bb 2567   FF bb 2635   FF bb 2779   FF bb 2931   FF bb 3210   FF bb 3403
         2011  +  GG aa 963   GG aa 1117   GG aa 1262   GG aa 1449   GG bb 1933   GG bb 1942
         2012  +  GG bb 2027   GG bb 2711   HH aa 1270   HH aa 1459   HH aa 1769   HH bb 2231
         2013  +  HH bb 2464   HH bb 2511   HH bb 2839   HH bb 2864   HH bb 3061   II aa 398
         2014  +  II aa 652   II bb 1785   II bb 1919   II bb 2147   II bb 2169   II bb 2340
         2015  +  JJ aa 1115   JJ aa 1246   JJ aa 1780   JJ aa 1901   JJ bb 947   JJ bb 1432
         2016  +  JJ bb 1450   JJ bb 1529}
         2017  +
         2018  +do_execsql_test 1.12.8 {
         2019  +  SELECT a, b, 
         2020  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN CURRENT ROW         AND 0 FOLLOWING  EXCLUDE CURRENT ROW),
         2021  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN CURRENT ROW         AND 0 FOLLOWING ),
         2022  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN CURRENT ROW         AND 0 FOLLOWING  EXCLUDE CURRENT ROW),
         2023  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN CURRENT ROW         AND 0 FOLLOWING )
         2024  +    FROM t3 ORDER BY 1, 2, 3;
         2025  +} {AA aa 3751 4685 1373 2307   AA aa 3774 4685 1396 2307
         2026  +  AA aa 4446 4685 2068 2307   AA aa 4462 4685 2084 2307
         2027  +  AA bb 3815 4685 1508 2378   AA bb 4058 4685 1751 2378
         2028  +  AA bb 4113 4685 1806 2378   AA bb 4376 4685 2069 2378
         2029  +  BB aa 6578 7340 2111 2873   BB aa 6680 7340 2213 2873
         2030  +  BB aa 6928 7340 2461 2873   BB aa 6941 7340 2474 2873
         2031  +  BB aa 6947 7340 2480 2873   BB aa 7093 7340 2626 2873
         2032  +  BB bb 6500 7340 3627 4467   BB bb 6548 7340 3675 4467
         2033  +  BB bb 6554 7340 3681 4467   BB bb 6629 7340 3756 4467
         2034  +  BB bb 6635 7340 3762 4467   BB bb 6707 7340 3834 4467
         2035  +  CC aa 2363 3122 1195 1954   CC aa 2515 3122 1347 1954
         2036  +  CC aa 2692 3122 1524 1954   CC aa 2964 3122 1796 1954
         2037  +  CC bb 2300 3122 346 1168   CC bb 2776 3122 822 1168
         2038  +  DD aa 3187 4032 480 1325   DD aa 3776 4032 1069 1325
         2039  +  DD aa 3808 4032 1101 1325   DD bb 3073 4032 1748 2707
         2040  +  DD bb 3238 4032 1913 2707   DD bb 3316 4032 1991 2707
         2041  +  DD bb 3794 4032 2469 2707   EE aa 1762 2539 113 890
         2042  +  EE aa 2426 2539 777 890   EE bb 1771 2539 881 1649
         2043  +  EE bb 1910 2539 1020 1649   EE bb 2287 2539 1397 1649
         2044  +  FF aa 4998 5668 1493 2163   FF aa 5001 5668 1496 2163
         2045  +  FF aa 5050 5668 1545 2163   FF aa 5460 5668 1955 2163
         2046  +  FF bb 4730 5668 2567 3505   FF bb 4798 5668 2635 3505
         2047  +  FF bb 4942 5668 2779 3505   FF bb 5094 5668 2931 3505
         2048  +  FF bb 5373 5668 3210 3505   FF bb 5566 5668 3403 3505
         2049  +  GG aa 3834 4468 963 1597   GG aa 3988 4468 1117 1597
         2050  +  GG aa 4133 4468 1262 1597   GG aa 4320 4468 1449 1597
         2051  +  GG bb 3530 4468 1933 2871   GG bb 3539 4468 1942 2871
         2052  +  GG bb 3624 4468 2027 2871   GG bb 4308 4468 2711 2871
         2053  +  HH aa 4464 5443 1270 2249   HH aa 4653 5443 1459 2249
         2054  +  HH aa 4963 5443 1769 2249   HH bb 4480 5443 2231 3194
         2055  +  HH bb 4713 5443 2464 3194   HH bb 4760 5443 2511 3194
         2056  +  HH bb 5088 5443 2839 3194   HH bb 5113 5443 2864 3194
         2057  +  HH bb 5310 5443 3061 3194   II aa 2988 3640 398 1050
         2058  +  II aa 3242 3640 652 1050   II bb 2835 3640 1785 2590
         2059  +  II bb 2969 3640 1919 2590   II bb 3197 3640 2147 2590
         2060  +  II bb 3219 3640 2169 2590   II bb 3390 3640 2340 2590
         2061  +  JJ aa 2901 3800 1115 2014   JJ aa 3032 3800 1246 2014
         2062  +  JJ aa 3566 3800 1780 2014   JJ aa 3687 3800 1901 2014
         2063  +  JJ bb 2961 3800 947 1786   JJ bb 3446 3800 1432 1786
         2064  +  JJ bb 3464 3800 1450 1786   JJ bb 3543 3800 1529 1786}
         2065  +
         2066  +do_execsql_test 1.13.1 {
         2067  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN CURRENT ROW         AND 1 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         2068  +} {AA aa 12025   AA aa 12025   AA aa 12025   AA aa 12025   AA bb 12025
         2069  +  AA bb 12025   AA bb 12025   AA bb 12025   BB aa 10462   BB aa 10462
         2070  +  BB aa 10462   BB aa 10462   BB aa 10462   BB aa 10462   BB bb 10462
         2071  +  BB bb 10462   BB bb 10462   BB bb 10462   BB bb 10462   BB bb 10462
         2072  +  CC aa 7154   CC aa 7154   CC aa 7154   CC aa 7154   CC bb 7154   CC bb 7154
         2073  +  DD aa 6571   DD aa 6571   DD aa 6571   DD bb 6571   DD bb 6571   DD bb 6571
         2074  +  DD bb 6571   EE aa 8207   EE aa 8207   EE bb 8207   EE bb 8207   EE bb 8207
         2075  +  FF aa 10136   FF aa 10136   FF aa 10136   FF aa 10136   FF bb 10136
         2076  +  FF bb 10136   FF bb 10136   FF bb 10136   FF bb 10136   FF bb 10136
         2077  +  GG aa 9911   GG aa 9911   GG aa 9911   GG aa 9911   GG bb 9911   GG bb 9911
         2078  +  GG bb 9911   GG bb 9911   HH aa 9083   HH aa 9083   HH aa 9083   HH bb 9083
         2079  +  HH bb 9083   HH bb 9083   HH bb 9083   HH bb 9083   HH bb 9083   II aa 7440
         2080  +  II aa 7440   II bb 7440   II bb 7440   II bb 7440   II bb 7440   II bb 7440
         2081  +  JJ aa 3800   JJ aa 3800   JJ aa 3800   JJ aa 3800   JJ bb 3800   JJ bb 3800
         2082  +  JJ bb 3800   JJ bb 3800}
         2083  +
         2084  +do_execsql_test 1.13.2 {
         2085  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN CURRENT ROW         AND 1 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         2086  +} {AA aa 4685   AA aa 4685   AA aa 4685   AA aa 4685   AA bb 5251   AA bb 5251
         2087  +  AA bb 5251   AA bb 5251   BB aa 7340   BB aa 7340   BB aa 7340   BB aa 7340
         2088  +  BB aa 7340   BB aa 7340   BB bb 6421   BB bb 6421   BB bb 6421   BB bb 6421
         2089  +  BB bb 6421   BB bb 6421   CC aa 3122   CC aa 3122   CC aa 3122   CC aa 3122
         2090  +  CC bb 2493   CC bb 2493   DD aa 4032   DD aa 4032   DD aa 4032   DD bb 3597
         2091  +  DD bb 3597   DD bb 3597   DD bb 3597   EE aa 2539   EE aa 2539   EE bb 3812
         2092  +  EE bb 3812   EE bb 3812   FF aa 5668   FF aa 5668   FF aa 5668   FF aa 5668
         2093  +  FF bb 5102   FF bb 5102   FF bb 5102   FF bb 5102   FF bb 5102   FF bb 5102
         2094  +  GG aa 4468   GG aa 4468   GG aa 4468   GG aa 4468   GG bb 5120   GG bb 5120
         2095  +  GG bb 5120   GG bb 5120   HH aa 5443   HH aa 5443   HH aa 5443   HH bb 4244
         2096  +  HH bb 4244   HH bb 4244   HH bb 4244   HH bb 4244   HH bb 4244   II aa 3640
         2097  +  II aa 3640   II bb 4604   II bb 4604   II bb 4604   II bb 4604   II bb 4604
         2098  +  JJ aa 3800   JJ aa 3800   JJ aa 3800   JJ aa 3800   JJ bb 1786   JJ bb 1786
         2099  +  JJ bb 1786   JJ bb 1786}
         2100  +
         2101  +do_execsql_test 1.13.3 {
         2102  +  SELECT a, b, rank() OVER (ORDER BY a  GROUPS BETWEEN CURRENT ROW         AND 1 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         2103  +} {AA aa 1   AA aa 1   AA aa 1   AA aa 1   AA bb 1   AA bb 1   AA bb 1
         2104  +  AA bb 1   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9
         2105  +  BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   CC aa 21
         2106  +  CC aa 21   CC aa 21   CC aa 21   CC bb 21   CC bb 21   DD aa 27   DD aa 27
         2107  +  DD aa 27   DD bb 27   DD bb 27   DD bb 27   DD bb 27   EE aa 34   EE aa 34
         2108  +  EE bb 34   EE bb 34   EE bb 34   FF aa 39   FF aa 39   FF aa 39   FF aa 39
         2109  +  FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   GG aa 49
         2110  +  GG aa 49   GG aa 49   GG aa 49   GG bb 49   GG bb 49   GG bb 49   GG bb 49
         2111  +  HH aa 57   HH aa 57   HH aa 57   HH bb 57   HH bb 57   HH bb 57   HH bb 57
         2112  +  HH bb 57   HH bb 57   II aa 66   II aa 66   II bb 66   II bb 66   II bb 66
         2113  +  II bb 66   II bb 66   JJ aa 73   JJ aa 73   JJ aa 73   JJ aa 73   JJ bb 73
         2114  +  JJ bb 73   JJ bb 73   JJ bb 73}
         2115  +
         2116  +do_execsql_test 1.13.4 {
         2117  +  SELECT a, b, max(c) OVER (ORDER BY a,b  GROUPS BETWEEN CURRENT ROW         AND 1 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         2118  +} {AA aa 934   AA aa 934   AA aa 934   AA aa 934   AA bb 870   AA bb 870
         2119  +  AA bb 870   AA bb 870   BB aa 840   BB aa 840   BB aa 840   BB aa 840
         2120  +  BB aa 840   BB aa 840   BB bb 840   BB bb 840   BB bb 840   BB bb 840
         2121  +  BB bb 840   BB bb 840   CC aa 822   CC aa 822   CC aa 822   CC aa 822
         2122  +  CC bb 845   CC bb 845   DD aa 959   DD aa 959   DD aa 959   DD bb 959
         2123  +  DD bb 959   DD bb 959   DD bb 959   EE aa 777   EE aa 777   EE bb 768
         2124  +  EE bb 768   EE bb 768   FF aa 938   FF aa 938   FF aa 938   FF aa 938
         2125  +  FF bb 938   FF bb 938   FF bb 938   FF bb 938   FF bb 938   FF bb 938
         2126  +  GG aa 938   GG aa 938   GG aa 938   GG aa 938   GG bb 979   GG bb 979
         2127  +  GG bb 979   GG bb 979   HH aa 979   HH aa 979   HH aa 979   HH bb 963
         2128  +  HH bb 963   HH bb 963   HH bb 963   HH bb 963   HH bb 963   II aa 805
         2129  +  II aa 805   II bb 899   II bb 899   II bb 899   II bb 899   II bb 899
         2130  +  JJ aa 899   JJ aa 899   JJ aa 899   JJ aa 899   JJ bb 839   JJ bb 839
         2131  +  JJ bb 839   JJ bb 839}
         2132  +
         2133  +do_execsql_test 1.13.5 {
         2134  +  SELECT a, b, min(c) OVER (ORDER BY a,b  GROUPS BETWEEN CURRENT ROW         AND 1 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         2135  +} {AA aa 223   AA aa 223   AA aa 223   AA aa 223   AA bb 247   AA bb 247
         2136  +  AA bb 247   AA bb 247   BB aa 247   BB aa 247   BB aa 247   BB aa 247
         2137  +  BB aa 247   BB aa 247   BB bb 158   BB bb 158   BB bb 158   BB bb 158
         2138  +  BB bb 158   BB bb 158   CC aa 158   CC aa 158   CC aa 158   CC aa 158
         2139  +  CC bb 224   CC bb 224   DD aa 224   DD aa 224   DD aa 224   DD bb 113
         2140  +  DD bb 113   DD bb 113   DD bb 113   EE aa 113   EE aa 113   EE bb 208
         2141  +  EE bb 208   EE bb 208   FF aa 102   FF aa 102   FF aa 102   FF aa 102
         2142  +  FF bb 102   FF bb 102   FF bb 102   FF bb 102   FF bb 102   FF bb 102
         2143  +  GG aa 148   GG aa 148   GG aa 148   GG aa 148   GG bb 160   GG bb 160
         2144  +  GG bb 160   GG bb 160   HH aa 133   HH aa 133   HH aa 133   HH bb 133
         2145  +  HH bb 133   HH bb 133   HH bb 133   HH bb 133   HH bb 133   II aa 250
         2146  +  II aa 250   II bb 113   II bb 113   II bb 113   II bb 113   II bb 113
         2147  +  JJ aa 113   JJ aa 113   JJ aa 113   JJ aa 113   JJ bb 257   JJ bb 257
         2148  +  JJ bb 257   JJ bb 257}
         2149  +
         2150  +do_execsql_test 1.13.6 {
         2151  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN CURRENT ROW         AND 1 FOLLOWING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
         2152  +} {AA aa 11091   AA aa 11114   AA aa 11786   AA aa 11802   AA bb 11155
         2153  +  AA bb 11398   AA bb 11453   AA bb 11716   BB aa 9700   BB aa 9802
         2154  +  BB aa 10050   BB aa 10063   BB aa 10069   BB aa 10215   BB bb 9622
         2155  +  BB bb 9670   BB bb 9676   BB bb 9751   BB bb 9757   BB bb 9829   CC aa 6395
         2156  +  CC aa 6547   CC aa 6724   CC aa 6996   CC bb 6332   CC bb 6808   DD aa 5726
         2157  +  DD aa 6315   DD aa 6347   DD bb 5612   DD bb 5777   DD bb 5855   DD bb 6333
         2158  +  EE aa 7430   EE aa 8094   EE bb 7439   EE bb 7578   EE bb 7955   FF aa 9466
         2159  +  FF aa 9469   FF aa 9518   FF aa 9928   FF bb 9198   FF bb 9266   FF bb 9410
         2160  +  FF bb 9562   FF bb 9841   FF bb 10034   GG aa 9277   GG aa 9431
         2161  +  GG aa 9576   GG aa 9763   GG bb 8973   GG bb 8982   GG bb 9067   GG bb 9751
         2162  +  HH aa 8104   HH aa 8293   HH aa 8603   HH bb 8120   HH bb 8353   HH bb 8400
         2163  +  HH bb 8728   HH bb 8753   HH bb 8950   II aa 6788   II aa 7042   II bb 6635
         2164  +  II bb 6769   II bb 6997   II bb 7019   II bb 7190   JJ aa 2901   JJ aa 3032
         2165  +  JJ aa 3566   JJ aa 3687   JJ bb 2961   JJ bb 3446   JJ bb 3464   JJ bb 3543}
         2166  +
         2167  +do_execsql_test 1.13.7 {
         2168  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN CURRENT ROW         AND 1 FOLLOWING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
         2169  +} {AA aa 3751   AA aa 3774   AA aa 4446   AA aa 4462   AA bb 4381   AA bb 4624
         2170  +  AA bb 4679   AA bb 4942   BB aa 6578   BB aa 6680   BB aa 6928   BB aa 6941
         2171  +  BB aa 6947   BB aa 7093   BB bb 5581   BB bb 5629   BB bb 5635   BB bb 5710
         2172  +  BB bb 5716   BB bb 5788   CC aa 2363   CC aa 2515   CC aa 2692   CC aa 2964
         2173  +  CC bb 1671   CC bb 2147   DD aa 3187   DD aa 3776   DD aa 3808   DD bb 2638
         2174  +  DD bb 2803   DD bb 2881   DD bb 3359   EE aa 1762   EE aa 2426   EE bb 3044
         2175  +  EE bb 3183   EE bb 3560   FF aa 4998   FF aa 5001   FF aa 5050   FF aa 5460
         2176  +  FF bb 4164   FF bb 4232   FF bb 4376   FF bb 4528   FF bb 4807   FF bb 5000
         2177  +  GG aa 3834   GG aa 3988   GG aa 4133   GG aa 4320   GG bb 4182   GG bb 4191
         2178  +  GG bb 4276   GG bb 4960   HH aa 4464   HH aa 4653   HH aa 4963   HH bb 3281
         2179  +  HH bb 3514   HH bb 3561   HH bb 3889   HH bb 3914   HH bb 4111   II aa 2988
         2180  +  II aa 3242   II bb 3799   II bb 3933   II bb 4161   II bb 4183   II bb 4354
         2181  +  JJ aa 2901   JJ aa 3032   JJ aa 3566   JJ aa 3687   JJ bb 947   JJ bb 1432
         2182  +  JJ bb 1450   JJ bb 1529}
         2183  +
         2184  +do_execsql_test 1.13.8 {
         2185  +  SELECT a, b, 
         2186  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN CURRENT ROW         AND 1 FOLLOWING  EXCLUDE CURRENT ROW),
         2187  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN CURRENT ROW         AND 1 FOLLOWING ),
         2188  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN CURRENT ROW         AND 1 FOLLOWING  EXCLUDE CURRENT ROW),
         2189  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN CURRENT ROW         AND 1 FOLLOWING )
         2190  +    FROM t3 ORDER BY 1, 2, 3;
         2191  +} {AA aa 11091 12025 3751 4685   AA aa 11114 12025 3774 4685
         2192  +  AA aa 11786 12025 4446 4685   AA aa 11802 12025 4462 4685
         2193  +  AA bb 11155 12025 4381 5251   AA bb 11398 12025 4624 5251
         2194  +  AA bb 11453 12025 4679 5251   AA bb 11716 12025 4942 5251
         2195  +  BB aa 9700 10462 6578 7340   BB aa 9802 10462 6680 7340
         2196  +  BB aa 10050 10462 6928 7340   BB aa 10063 10462 6941 7340
         2197  +  BB aa 10069 10462 6947 7340   BB aa 10215 10462 7093 7340
         2198  +  BB bb 9622 10462 5581 6421   BB bb 9670 10462 5629 6421
         2199  +  BB bb 9676 10462 5635 6421   BB bb 9751 10462 5710 6421
         2200  +  BB bb 9757 10462 5716 6421   BB bb 9829 10462 5788 6421
         2201  +  CC aa 6395 7154 2363 3122   CC aa 6547 7154 2515 3122
         2202  +  CC aa 6724 7154 2692 3122   CC aa 6996 7154 2964 3122
         2203  +  CC bb 6332 7154 1671 2493   CC bb 6808 7154 2147 2493
         2204  +  DD aa 5726 6571 3187 4032   DD aa 6315 6571 3776 4032
         2205  +  DD aa 6347 6571 3808 4032   DD bb 5612 6571 2638 3597
         2206  +  DD bb 5777 6571 2803 3597   DD bb 5855 6571 2881 3597
         2207  +  DD bb 6333 6571 3359 3597   EE aa 7430 8207 1762 2539
         2208  +  EE aa 8094 8207 2426 2539   EE bb 7439 8207 3044 3812
         2209  +  EE bb 7578 8207 3183 3812   EE bb 7955 8207 3560 3812
         2210  +  FF aa 9466 10136 4998 5668   FF aa 9469 10136 5001 5668
         2211  +  FF aa 9518 10136 5050 5668   FF aa 9928 10136 5460 5668
         2212  +  FF bb 9198 10136 4164 5102   FF bb 9266 10136 4232 5102
         2213  +  FF bb 9410 10136 4376 5102   FF bb 9562 10136 4528 5102
         2214  +  FF bb 9841 10136 4807 5102   FF bb 10034 10136 5000 5102
         2215  +  GG aa 9277 9911 3834 4468   GG aa 9431 9911 3988 4468
         2216  +  GG aa 9576 9911 4133 4468   GG aa 9763 9911 4320 4468
         2217  +  GG bb 8973 9911 4182 5120   GG bb 8982 9911 4191 5120
         2218  +  GG bb 9067 9911 4276 5120   GG bb 9751 9911 4960 5120
         2219  +  HH aa 8104 9083 4464 5443   HH aa 8293 9083 4653 5443
         2220  +  HH aa 8603 9083 4963 5443   HH bb 8120 9083 3281 4244
         2221  +  HH bb 8353 9083 3514 4244   HH bb 8400 9083 3561 4244
         2222  +  HH bb 8728 9083 3889 4244   HH bb 8753 9083 3914 4244
         2223  +  HH bb 8950 9083 4111 4244   II aa 6788 7440 2988 3640
         2224  +  II aa 7042 7440 3242 3640   II bb 6635 7440 3799 4604
         2225  +  II bb 6769 7440 3933 4604   II bb 6997 7440 4161 4604
         2226  +  II bb 7019 7440 4183 4604   II bb 7190 7440 4354 4604
         2227  +  JJ aa 2901 3800 2901 3800   JJ aa 3032 3800 3032 3800
         2228  +  JJ aa 3566 3800 3566 3800   JJ aa 3687 3800 3687 3800
         2229  +  JJ bb 2961 3800 947 1786   JJ bb 3446 3800 1432 1786
         2230  +  JJ bb 3464 3800 1450 1786   JJ bb 3543 3800 1529 1786}
         2231  +
         2232  +do_execsql_test 1.14.1 {
         2233  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN CURRENT ROW         AND 100 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         2234  +} {AA aa 44737   AA aa 44737   AA aa 44737   AA aa 44737   AA bb 44737
         2235  +  AA bb 44737   AA bb 44737   AA bb 44737   BB aa 40052   BB aa 40052
         2236  +  BB aa 40052   BB aa 40052   BB aa 40052   BB aa 40052   BB bb 40052
         2237  +  BB bb 40052   BB bb 40052   BB bb 40052   BB bb 40052   BB bb 40052
         2238  +  CC aa 32712   CC aa 32712   CC aa 32712   CC aa 32712   CC bb 32712
         2239  +  CC bb 32712   DD aa 29590   DD aa 29590   DD aa 29590   DD bb 29590
         2240  +  DD bb 29590   DD bb 29590   DD bb 29590   EE aa 25558   EE aa 25558
         2241  +  EE bb 25558   EE bb 25558   EE bb 25558   FF aa 23019   FF aa 23019
         2242  +  FF aa 23019   FF aa 23019   FF bb 23019   FF bb 23019   FF bb 23019
         2243  +  FF bb 23019   FF bb 23019   FF bb 23019   GG aa 17351   GG aa 17351
         2244  +  GG aa 17351   GG aa 17351   GG bb 17351   GG bb 17351   GG bb 17351
         2245  +  GG bb 17351   HH aa 12883   HH aa 12883   HH aa 12883   HH bb 12883
         2246  +  HH bb 12883   HH bb 12883   HH bb 12883   HH bb 12883   HH bb 12883
         2247  +  II aa 7440   II aa 7440   II bb 7440   II bb 7440   II bb 7440   II bb 7440
         2248  +  II bb 7440   JJ aa 3800   JJ aa 3800   JJ aa 3800   JJ aa 3800   JJ bb 3800
         2249  +  JJ bb 3800   JJ bb 3800   JJ bb 3800}
         2250  +
         2251  +do_execsql_test 1.14.2 {
         2252  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN CURRENT ROW         AND 100 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         2253  +} {AA aa 44737   AA aa 44737   AA aa 44737   AA aa 44737   AA bb 42430
         2254  +  AA bb 42430   AA bb 42430   AA bb 42430   BB aa 40052   BB aa 40052
         2255  +  BB aa 40052   BB aa 40052   BB aa 40052   BB aa 40052   BB bb 37179
         2256  +  BB bb 37179   BB bb 37179   BB bb 37179   BB bb 37179   BB bb 37179
         2257  +  CC aa 32712   CC aa 32712   CC aa 32712   CC aa 32712   CC bb 30758
         2258  +  CC bb 30758   DD aa 29590   DD aa 29590   DD aa 29590   DD bb 28265
         2259  +  DD bb 28265   DD bb 28265   DD bb 28265   EE aa 25558   EE aa 25558
         2260  +  EE bb 24668   EE bb 24668   EE bb 24668   FF aa 23019   FF aa 23019
         2261  +  FF aa 23019   FF aa 23019   FF bb 20856   FF bb 20856   FF bb 20856
         2262  +  FF bb 20856   FF bb 20856   FF bb 20856   GG aa 17351   GG aa 17351
         2263  +  GG aa 17351   GG aa 17351   GG bb 15754   GG bb 15754   GG bb 15754
         2264  +  GG bb 15754   HH aa 12883   HH aa 12883   HH aa 12883   HH bb 10634
         2265  +  HH bb 10634   HH bb 10634   HH bb 10634   HH bb 10634   HH bb 10634
         2266  +  II aa 7440   II aa 7440   II bb 6390   II bb 6390   II bb 6390   II bb 6390
         2267  +  II bb 6390   JJ aa 3800   JJ aa 3800   JJ aa 3800   JJ aa 3800   JJ bb 1786
         2268  +  JJ bb 1786   JJ bb 1786   JJ bb 1786}
         2269  +
         2270  +do_execsql_test 1.14.3 {
         2271  +  SELECT a, b, rank() OVER (ORDER BY a  GROUPS BETWEEN CURRENT ROW         AND 100 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         2272  +} {AA aa 1   AA aa 1   AA aa 1   AA aa 1   AA bb 1   AA bb 1   AA bb 1
         2273  +  AA bb 1   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9
         2274  +  BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   CC aa 21
         2275  +  CC aa 21   CC aa 21   CC aa 21   CC bb 21   CC bb 21   DD aa 27   DD aa 27
         2276  +  DD aa 27   DD bb 27   DD bb 27   DD bb 27   DD bb 27   EE aa 34   EE aa 34
         2277  +  EE bb 34   EE bb 34   EE bb 34   FF aa 39   FF aa 39   FF aa 39   FF aa 39
         2278  +  FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   GG aa 49
         2279  +  GG aa 49   GG aa 49   GG aa 49   GG bb 49   GG bb 49   GG bb 49   GG bb 49
         2280  +  HH aa 57   HH aa 57   HH aa 57   HH bb 57   HH bb 57   HH bb 57   HH bb 57
         2281  +  HH bb 57   HH bb 57   II aa 66   II aa 66   II bb 66   II bb 66   II bb 66
         2282  +  II bb 66   II bb 66   JJ aa 73   JJ aa 73   JJ aa 73   JJ aa 73   JJ bb 73
         2283  +  JJ bb 73   JJ bb 73   JJ bb 73}
         2284  +
         2285  +do_execsql_test 1.14.4 {
         2286  +  SELECT a, b, max(c) OVER (ORDER BY a,b  GROUPS BETWEEN CURRENT ROW         AND 100 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         2287  +} {AA aa 979   AA aa 979   AA aa 979   AA aa 979   AA bb 979   AA bb 979
         2288  +  AA bb 979   AA bb 979   BB aa 979   BB aa 979   BB aa 979   BB aa 979
         2289  +  BB aa 979   BB aa 979   BB bb 979   BB bb 979   BB bb 979   BB bb 979
         2290  +  BB bb 979   BB bb 979   CC aa 979   CC aa 979   CC aa 979   CC aa 979
         2291  +  CC bb 979   CC bb 979   DD aa 979   DD aa 979   DD aa 979   DD bb 979
         2292  +  DD bb 979   DD bb 979   DD bb 979   EE aa 979   EE aa 979   EE bb 979
         2293  +  EE bb 979   EE bb 979   FF aa 979   FF aa 979   FF aa 979   FF aa 979
         2294  +  FF bb 979   FF bb 979   FF bb 979   FF bb 979   FF bb 979   FF bb 979
         2295  +  GG aa 979   GG aa 979   GG aa 979   GG aa 979   GG bb 979   GG bb 979
         2296  +  GG bb 979   GG bb 979   HH aa 979   HH aa 979   HH aa 979   HH bb 963
         2297  +  HH bb 963   HH bb 963   HH bb 963   HH bb 963   HH bb 963   II aa 899
         2298  +  II aa 899   II bb 899   II bb 899   II bb 899   II bb 899   II bb 899
         2299  +  JJ aa 899   JJ aa 899   JJ aa 899   JJ aa 899   JJ bb 839   JJ bb 839
         2300  +  JJ bb 839   JJ bb 839}
         2301  +
         2302  +do_execsql_test 1.14.5 {
         2303  +  SELECT a, b, min(c) OVER (ORDER BY a,b  GROUPS BETWEEN CURRENT ROW         AND 100 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         2304  +} {AA aa 102   AA aa 102   AA aa 102   AA aa 102   AA bb 102   AA bb 102
         2305  +  AA bb 102   AA bb 102   BB aa 102   BB aa 102   BB aa 102   BB aa 102
         2306  +  BB aa 102   BB aa 102   BB bb 102   BB bb 102   BB bb 102   BB bb 102
         2307  +  BB bb 102   BB bb 102   CC aa 102   CC aa 102   CC aa 102   CC aa 102
         2308  +  CC bb 102   CC bb 102   DD aa 102   DD aa 102   DD aa 102   DD bb 102
         2309  +  DD bb 102   DD bb 102   DD bb 102   EE aa 102   EE aa 102   EE bb 102
         2310  +  EE bb 102   EE bb 102   FF aa 102   FF aa 102   FF aa 102   FF aa 102
         2311  +  FF bb 102   FF bb 102   FF bb 102   FF bb 102   FF bb 102   FF bb 102
         2312  +  GG aa 113   GG aa 113   GG aa 113   GG aa 113   GG bb 113   GG bb 113
         2313  +  GG bb 113   GG bb 113   HH aa 113   HH aa 113   HH aa 113   HH bb 113
         2314  +  HH bb 113   HH bb 113   HH bb 113   HH bb 113   HH bb 113   II aa 113
         2315  +  II aa 113   II bb 113   II bb 113   II bb 113   II bb 113   II bb 113
         2316  +  JJ aa 113   JJ aa 113   JJ aa 113   JJ aa 113   JJ bb 257   JJ bb 257
         2317  +  JJ bb 257   JJ bb 257}
         2318  +
         2319  +do_execsql_test 1.14.6 {
         2320  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN CURRENT ROW         AND 100 FOLLOWING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
         2321  +} {AA aa 43803   AA aa 43826   AA aa 44498   AA aa 44514   AA bb 43867
         2322  +  AA bb 44110   AA bb 44165   AA bb 44428   BB aa 39290   BB aa 39392
         2323  +  BB aa 39640   BB aa 39653   BB aa 39659   BB aa 39805   BB bb 39212
         2324  +  BB bb 39260   BB bb 39266   BB bb 39341   BB bb 39347   BB bb 39419
         2325  +  CC aa 31953   CC aa 32105   CC aa 32282   CC aa 32554   CC bb 31890
         2326  +  CC bb 32366   DD aa 28745   DD aa 29334   DD aa 29366   DD bb 28631
         2327  +  DD bb 28796   DD bb 28874   DD bb 29352   EE aa 24781   EE aa 25445
         2328  +  EE bb 24790   EE bb 24929   EE bb 25306   FF aa 22349   FF aa 22352
         2329  +  FF aa 22401   FF aa 22811   FF bb 22081   FF bb 22149   FF bb 22293
         2330  +  FF bb 22445   FF bb 22724   FF bb 22917   GG aa 16717   GG aa 16871
         2331  +  GG aa 17016   GG aa 17203   GG bb 16413   GG bb 16422   GG bb 16507
         2332  +  GG bb 17191   HH aa 11904   HH aa 12093   HH aa 12403   HH bb 11920
         2333  +  HH bb 12153   HH bb 12200   HH bb 12528   HH bb 12553   HH bb 12750
         2334  +  II aa 6788   II aa 7042   II bb 6635   II bb 6769   II bb 6997   II bb 7019
         2335  +  II bb 7190   JJ aa 2901   JJ aa 3032   JJ aa 3566   JJ aa 3687   JJ bb 2961
         2336  +  JJ bb 3446   JJ bb 3464   JJ bb 3543}
         2337  +
         2338  +do_execsql_test 1.14.7 {
         2339  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN CURRENT ROW         AND 100 FOLLOWING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
         2340  +} {AA aa 43803   AA aa 43826   AA aa 44498   AA aa 44514   AA bb 41560
         2341  +  AA bb 41803   AA bb 41858   AA bb 42121   BB aa 39290   BB aa 39392
         2342  +  BB aa 39640   BB aa 39653   BB aa 39659   BB aa 39805   BB bb 36339
         2343  +  BB bb 36387   BB bb 36393   BB bb 36468   BB bb 36474   BB bb 36546
         2344  +  CC aa 31953   CC aa 32105   CC aa 32282   CC aa 32554   CC bb 29936
         2345  +  CC bb 30412   DD aa 28745   DD aa 29334   DD aa 29366   DD bb 27306
         2346  +  DD bb 27471   DD bb 27549   DD bb 28027   EE aa 24781   EE aa 25445
         2347  +  EE bb 23900   EE bb 24039   EE bb 24416   FF aa 22349   FF aa 22352
         2348  +  FF aa 22401   FF aa 22811   FF bb 19918   FF bb 19986   FF bb 20130
         2349  +  FF bb 20282   FF bb 20561   FF bb 20754   GG aa 16717   GG aa 16871
         2350  +  GG aa 17016   GG aa 17203   GG bb 14816   GG bb 14825   GG bb 14910
         2351  +  GG bb 15594   HH aa 11904   HH aa 12093   HH aa 12403   HH bb 9671
         2352  +  HH bb 9904   HH bb 9951   HH bb 10279   HH bb 10304   HH bb 10501
         2353  +  II aa 6788   II aa 7042   II bb 5585   II bb 5719   II bb 5947   II bb 5969
         2354  +  II bb 6140   JJ aa 2901   JJ aa 3032   JJ aa 3566   JJ aa 3687   JJ bb 947
         2355  +  JJ bb 1432   JJ bb 1450   JJ bb 1529}
         2356  +
         2357  +do_execsql_test 1.14.8 {
         2358  +  SELECT a, b, 
         2359  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN CURRENT ROW         AND 100 FOLLOWING  EXCLUDE CURRENT ROW),
         2360  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN CURRENT ROW         AND 100 FOLLOWING ),
         2361  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN CURRENT ROW         AND 100 FOLLOWING  EXCLUDE CURRENT ROW),
         2362  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN CURRENT ROW         AND 100 FOLLOWING )
         2363  +    FROM t3 ORDER BY 1, 2, 3;
         2364  +} {AA aa 43803 44737 43803 44737   AA aa 43826 44737 43826 44737
         2365  +  AA aa 44498 44737 44498 44737   AA aa 44514 44737 44514 44737
         2366  +  AA bb 43867 44737 41560 42430   AA bb 44110 44737 41803 42430
         2367  +  AA bb 44165 44737 41858 42430   AA bb 44428 44737 42121 42430
         2368  +  BB aa 39290 40052 39290 40052   BB aa 39392 40052 39392 40052
         2369  +  BB aa 39640 40052 39640 40052   BB aa 39653 40052 39653 40052
         2370  +  BB aa 39659 40052 39659 40052   BB aa 39805 40052 39805 40052
         2371  +  BB bb 39212 40052 36339 37179   BB bb 39260 40052 36387 37179
         2372  +  BB bb 39266 40052 36393 37179   BB bb 39341 40052 36468 37179
         2373  +  BB bb 39347 40052 36474 37179   BB bb 39419 40052 36546 37179
         2374  +  CC aa 31953 32712 31953 32712   CC aa 32105 32712 32105 32712
         2375  +  CC aa 32282 32712 32282 32712   CC aa 32554 32712 32554 32712
         2376  +  CC bb 31890 32712 29936 30758   CC bb 32366 32712 30412 30758
         2377  +  DD aa 28745 29590 28745 29590   DD aa 29334 29590 29334 29590
         2378  +  DD aa 29366 29590 29366 29590   DD bb 28631 29590 27306 28265
         2379  +  DD bb 28796 29590 27471 28265   DD bb 28874 29590 27549 28265
         2380  +  DD bb 29352 29590 28027 28265   EE aa 24781 25558 24781 25558
         2381  +  EE aa 25445 25558 25445 25558   EE bb 24790 25558 23900 24668
         2382  +  EE bb 24929 25558 24039 24668   EE bb 25306 25558 24416 24668
         2383  +  FF aa 22349 23019 22349 23019   FF aa 22352 23019 22352 23019
         2384  +  FF aa 22401 23019 22401 23019   FF aa 22811 23019 22811 23019
         2385  +  FF bb 22081 23019 19918 20856   FF bb 22149 23019 19986 20856
         2386  +  FF bb 22293 23019 20130 20856   FF bb 22445 23019 20282 20856
         2387  +  FF bb 22724 23019 20561 20856   FF bb 22917 23019 20754 20856
         2388  +  GG aa 16717 17351 16717 17351   GG aa 16871 17351 16871 17351
         2389  +  GG aa 17016 17351 17016 17351   GG aa 17203 17351 17203 17351
         2390  +  GG bb 16413 17351 14816 15754   GG bb 16422 17351 14825 15754
         2391  +  GG bb 16507 17351 14910 15754   GG bb 17191 17351 15594 15754
         2392  +  HH aa 11904 12883 11904 12883   HH aa 12093 12883 12093 12883
         2393  +  HH aa 12403 12883 12403 12883   HH bb 11920 12883 9671 10634
         2394  +  HH bb 12153 12883 9904 10634   HH bb 12200 12883 9951 10634
         2395  +  HH bb 12528 12883 10279 10634   HH bb 12553 12883 10304 10634
         2396  +  HH bb 12750 12883 10501 10634   II aa 6788 7440 6788 7440
         2397  +  II aa 7042 7440 7042 7440   II bb 6635 7440 5585 6390
         2398  +  II bb 6769 7440 5719 6390   II bb 6997 7440 5947 6390
         2399  +  II bb 7019 7440 5969 6390   II bb 7190 7440 6140 6390
         2400  +  JJ aa 2901 3800 2901 3800   JJ aa 3032 3800 3032 3800
         2401  +  JJ aa 3566 3800 3566 3800   JJ aa 3687 3800 3687 3800
         2402  +  JJ bb 2961 3800 947 1786   JJ bb 3446 3800 1432 1786
         2403  +  JJ bb 3464 3800 1450 1786   JJ bb 3543 3800 1529 1786}
         2404  +
         2405  +do_execsql_test 1.15.1 {
         2406  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN CURRENT ROW         AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         2407  +} {AA aa 44737   AA aa 44737   AA aa 44737   AA aa 44737   AA bb 44737
         2408  +  AA bb 44737   AA bb 44737   AA bb 44737   BB aa 40052   BB aa 40052
         2409  +  BB aa 40052   BB aa 40052   BB aa 40052   BB aa 40052   BB bb 40052
         2410  +  BB bb 40052   BB bb 40052   BB bb 40052   BB bb 40052   BB bb 40052
         2411  +  CC aa 32712   CC aa 32712   CC aa 32712   CC aa 32712   CC bb 32712
         2412  +  CC bb 32712   DD aa 29590   DD aa 29590   DD aa 29590   DD bb 29590
         2413  +  DD bb 29590   DD bb 29590   DD bb 29590   EE aa 25558   EE aa 25558
         2414  +  EE bb 25558   EE bb 25558   EE bb 25558   FF aa 23019   FF aa 23019
         2415  +  FF aa 23019   FF aa 23019   FF bb 23019   FF bb 23019   FF bb 23019
         2416  +  FF bb 23019   FF bb 23019   FF bb 23019   GG aa 17351   GG aa 17351
         2417  +  GG aa 17351   GG aa 17351   GG bb 17351   GG bb 17351   GG bb 17351
         2418  +  GG bb 17351   HH aa 12883   HH aa 12883   HH aa 12883   HH bb 12883
         2419  +  HH bb 12883   HH bb 12883   HH bb 12883   HH bb 12883   HH bb 12883
         2420  +  II aa 7440   II aa 7440   II bb 7440   II bb 7440   II bb 7440   II bb 7440
         2421  +  II bb 7440   JJ aa 3800   JJ aa 3800   JJ aa 3800   JJ aa 3800   JJ bb 3800
         2422  +  JJ bb 3800   JJ bb 3800   JJ bb 3800}
         2423  +
         2424  +do_execsql_test 1.15.2 {
         2425  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN CURRENT ROW         AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         2426  +} {AA aa 44737   AA aa 44737   AA aa 44737   AA aa 44737   AA bb 42430
         2427  +  AA bb 42430   AA bb 42430   AA bb 42430   BB aa 40052   BB aa 40052
         2428  +  BB aa 40052   BB aa 40052   BB aa 40052   BB aa 40052   BB bb 37179
         2429  +  BB bb 37179   BB bb 37179   BB bb 37179   BB bb 37179   BB bb 37179
         2430  +  CC aa 32712   CC aa 32712   CC aa 32712   CC aa 32712   CC bb 30758
         2431  +  CC bb 30758   DD aa 29590   DD aa 29590   DD aa 29590   DD bb 28265
         2432  +  DD bb 28265   DD bb 28265   DD bb 28265   EE aa 25558   EE aa 25558
         2433  +  EE bb 24668   EE bb 24668   EE bb 24668   FF aa 23019   FF aa 23019
         2434  +  FF aa 23019   FF aa 23019   FF bb 20856   FF bb 20856   FF bb 20856
         2435  +  FF bb 20856   FF bb 20856   FF bb 20856   GG aa 17351   GG aa 17351
         2436  +  GG aa 17351   GG aa 17351   GG bb 15754   GG bb 15754   GG bb 15754
         2437  +  GG bb 15754   HH aa 12883   HH aa 12883   HH aa 12883   HH bb 10634
         2438  +  HH bb 10634   HH bb 10634   HH bb 10634   HH bb 10634   HH bb 10634
         2439  +  II aa 7440   II aa 7440   II bb 6390   II bb 6390   II bb 6390   II bb 6390
         2440  +  II bb 6390   JJ aa 3800   JJ aa 3800   JJ aa 3800   JJ aa 3800   JJ bb 1786
         2441  +  JJ bb 1786   JJ bb 1786   JJ bb 1786}
         2442  +
         2443  +do_execsql_test 1.15.3 {
         2444  +  SELECT a, b, rank() OVER (ORDER BY a  GROUPS BETWEEN CURRENT ROW         AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         2445  +} {AA aa 1   AA aa 1   AA aa 1   AA aa 1   AA bb 1   AA bb 1   AA bb 1
         2446  +  AA bb 1   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9
         2447  +  BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   CC aa 21
         2448  +  CC aa 21   CC aa 21   CC aa 21   CC bb 21   CC bb 21   DD aa 27   DD aa 27
         2449  +  DD aa 27   DD bb 27   DD bb 27   DD bb 27   DD bb 27   EE aa 34   EE aa 34
         2450  +  EE bb 34   EE bb 34   EE bb 34   FF aa 39   FF aa 39   FF aa 39   FF aa 39
         2451  +  FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   GG aa 49
         2452  +  GG aa 49   GG aa 49   GG aa 49   GG bb 49   GG bb 49   GG bb 49   GG bb 49
         2453  +  HH aa 57   HH aa 57   HH aa 57   HH bb 57   HH bb 57   HH bb 57   HH bb 57
         2454  +  HH bb 57   HH bb 57   II aa 66   II aa 66   II bb 66   II bb 66   II bb 66
         2455  +  II bb 66   II bb 66   JJ aa 73   JJ aa 73   JJ aa 73   JJ aa 73   JJ bb 73
         2456  +  JJ bb 73   JJ bb 73   JJ bb 73}
         2457  +
         2458  +do_execsql_test 1.15.4 {
         2459  +  SELECT a, b, max(c) OVER (ORDER BY a,b  GROUPS BETWEEN CURRENT ROW         AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         2460  +} {AA aa 979   AA aa 979   AA aa 979   AA aa 979   AA bb 979   AA bb 979
         2461  +  AA bb 979   AA bb 979   BB aa 979   BB aa 979   BB aa 979   BB aa 979
         2462  +  BB aa 979   BB aa 979   BB bb 979   BB bb 979   BB bb 979   BB bb 979
         2463  +  BB bb 979   BB bb 979   CC aa 979   CC aa 979   CC aa 979   CC aa 979
         2464  +  CC bb 979   CC bb 979   DD aa 979   DD aa 979   DD aa 979   DD bb 979
         2465  +  DD bb 979   DD bb 979   DD bb 979   EE aa 979   EE aa 979   EE bb 979
         2466  +  EE bb 979   EE bb 979   FF aa 979   FF aa 979   FF aa 979   FF aa 979
         2467  +  FF bb 979   FF bb 979   FF bb 979   FF bb 979   FF bb 979   FF bb 979
         2468  +  GG aa 979   GG aa 979   GG aa 979   GG aa 979   GG bb 979   GG bb 979
         2469  +  GG bb 979   GG bb 979   HH aa 979   HH aa 979   HH aa 979   HH bb 963
         2470  +  HH bb 963   HH bb 963   HH bb 963   HH bb 963   HH bb 963   II aa 899
         2471  +  II aa 899   II bb 899   II bb 899   II bb 899   II bb 899   II bb 899
         2472  +  JJ aa 899   JJ aa 899   JJ aa 899   JJ aa 899   JJ bb 839   JJ bb 839
         2473  +  JJ bb 839   JJ bb 839}
         2474  +
         2475  +do_execsql_test 1.15.5 {
         2476  +  SELECT a, b, min(c) OVER (ORDER BY a,b  GROUPS BETWEEN CURRENT ROW         AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         2477  +} {AA aa 102   AA aa 102   AA aa 102   AA aa 102   AA bb 102   AA bb 102
         2478  +  AA bb 102   AA bb 102   BB aa 102   BB aa 102   BB aa 102   BB aa 102
         2479  +  BB aa 102   BB aa 102   BB bb 102   BB bb 102   BB bb 102   BB bb 102
         2480  +  BB bb 102   BB bb 102   CC aa 102   CC aa 102   CC aa 102   CC aa 102
         2481  +  CC bb 102   CC bb 102   DD aa 102   DD aa 102   DD aa 102   DD bb 102
         2482  +  DD bb 102   DD bb 102   DD bb 102   EE aa 102   EE aa 102   EE bb 102
         2483  +  EE bb 102   EE bb 102   FF aa 102   FF aa 102   FF aa 102   FF aa 102
         2484  +  FF bb 102   FF bb 102   FF bb 102   FF bb 102   FF bb 102   FF bb 102
         2485  +  GG aa 113   GG aa 113   GG aa 113   GG aa 113   GG bb 113   GG bb 113
         2486  +  GG bb 113   GG bb 113   HH aa 113   HH aa 113   HH aa 113   HH bb 113
         2487  +  HH bb 113   HH bb 113   HH bb 113   HH bb 113   HH bb 113   II aa 113
         2488  +  II aa 113   II bb 113   II bb 113   II bb 113   II bb 113   II bb 113
         2489  +  JJ aa 113   JJ aa 113   JJ aa 113   JJ aa 113   JJ bb 257   JJ bb 257
         2490  +  JJ bb 257   JJ bb 257}
         2491  +
         2492  +do_execsql_test 1.15.6 {
         2493  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN CURRENT ROW         AND UNBOUNDED FOLLOWING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
         2494  +} {AA aa 43803   AA aa 43826   AA aa 44498   AA aa 44514   AA bb 43867
         2495  +  AA bb 44110   AA bb 44165   AA bb 44428   BB aa 39290   BB aa 39392
         2496  +  BB aa 39640   BB aa 39653   BB aa 39659   BB aa 39805   BB bb 39212
         2497  +  BB bb 39260   BB bb 39266   BB bb 39341   BB bb 39347   BB bb 39419
         2498  +  CC aa 31953   CC aa 32105   CC aa 32282   CC aa 32554   CC bb 31890
         2499  +  CC bb 32366   DD aa 28745   DD aa 29334   DD aa 29366   DD bb 28631
         2500  +  DD bb 28796   DD bb 28874   DD bb 29352   EE aa 24781   EE aa 25445
         2501  +  EE bb 24790   EE bb 24929   EE bb 25306   FF aa 22349   FF aa 22352
         2502  +  FF aa 22401   FF aa 22811   FF bb 22081   FF bb 22149   FF bb 22293
         2503  +  FF bb 22445   FF bb 22724   FF bb 22917   GG aa 16717   GG aa 16871
         2504  +  GG aa 17016   GG aa 17203   GG bb 16413   GG bb 16422   GG bb 16507
         2505  +  GG bb 17191   HH aa 11904   HH aa 12093   HH aa 12403   HH bb 11920
         2506  +  HH bb 12153   HH bb 12200   HH bb 12528   HH bb 12553   HH bb 12750
         2507  +  II aa 6788   II aa 7042   II bb 6635   II bb 6769   II bb 6997   II bb 7019
         2508  +  II bb 7190   JJ aa 2901   JJ aa 3032   JJ aa 3566   JJ aa 3687   JJ bb 2961
         2509  +  JJ bb 3446   JJ bb 3464   JJ bb 3543}
         2510  +
         2511  +do_execsql_test 1.15.7 {
         2512  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN CURRENT ROW         AND UNBOUNDED FOLLOWING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
         2513  +} {AA aa 43803   AA aa 43826   AA aa 44498   AA aa 44514   AA bb 41560
         2514  +  AA bb 41803   AA bb 41858   AA bb 42121   BB aa 39290   BB aa 39392
         2515  +  BB aa 39640   BB aa 39653   BB aa 39659   BB aa 39805   BB bb 36339
         2516  +  BB bb 36387   BB bb 36393   BB bb 36468   BB bb 36474   BB bb 36546
         2517  +  CC aa 31953   CC aa 32105   CC aa 32282   CC aa 32554   CC bb 29936
         2518  +  CC bb 30412   DD aa 28745   DD aa 29334   DD aa 29366   DD bb 27306
         2519  +  DD bb 27471   DD bb 27549   DD bb 28027   EE aa 24781   EE aa 25445
         2520  +  EE bb 23900   EE bb 24039   EE bb 24416   FF aa 22349   FF aa 22352
         2521  +  FF aa 22401   FF aa 22811   FF bb 19918   FF bb 19986   FF bb 20130
         2522  +  FF bb 20282   FF bb 20561   FF bb 20754   GG aa 16717   GG aa 16871
         2523  +  GG aa 17016   GG aa 17203   GG bb 14816   GG bb 14825   GG bb 14910
         2524  +  GG bb 15594   HH aa 11904   HH aa 12093   HH aa 12403   HH bb 9671
         2525  +  HH bb 9904   HH bb 9951   HH bb 10279   HH bb 10304   HH bb 10501
         2526  +  II aa 6788   II aa 7042   II bb 5585   II bb 5719   II bb 5947   II bb 5969
         2527  +  II bb 6140   JJ aa 2901   JJ aa 3032   JJ aa 3566   JJ aa 3687   JJ bb 947
         2528  +  JJ bb 1432   JJ bb 1450   JJ bb 1529}
         2529  +
         2530  +do_execsql_test 1.15.8 {
         2531  +  SELECT a, b, 
         2532  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN CURRENT ROW         AND UNBOUNDED FOLLOWING  EXCLUDE CURRENT ROW),
         2533  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN CURRENT ROW         AND UNBOUNDED FOLLOWING ),
         2534  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN CURRENT ROW         AND UNBOUNDED FOLLOWING  EXCLUDE CURRENT ROW),
         2535  +      sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN CURRENT ROW         AND UNBOUNDED FOLLOWING )
         2536  +    FROM t3 ORDER BY 1, 2, 3;
         2537  +} {AA aa 43803 44737 43803 44737   AA aa 43826 44737 43826 44737
         2538  +  AA aa 44498 44737 44498 44737   AA aa 44514 44737 44514 44737
         2539  +  AA bb 43867 44737 41560 42430   AA bb 44110 44737 41803 42430
         2540  +  AA bb 44165 44737 41858 42430   AA bb 44428 44737 42121 42430
         2541  +  BB aa 39290 40052 39290 40052   BB aa 39392 40052 39392 40052
         2542  +  BB aa 39640 40052 39640 40052   BB aa 39653 40052 39653 40052
         2543  +  BB aa 39659 40052 39659 40052   BB aa 39805 40052 39805 40052
         2544  +  BB bb 39212 40052 36339 37179   BB bb 39260 40052 36387 37179
         2545  +  BB bb 39266 40052 36393 37179   BB bb 39341 40052 36468 37179
         2546  +  BB bb 39347 40052 36474 37179   BB bb 39419 40052 36546 37179
         2547  +  CC aa 31953 32712 31953 32712   CC aa 32105 32712 32105 32712
         2548  +  CC aa 32282 32712 32282 32712   CC aa 32554 32712 32554 32712
         2549  +  CC bb 31890 32712 29936 30758   CC bb 32366 32712 30412 30758
         2550  +  DD aa 28745 29590 28745 29590   DD aa 29334 29590 29334 29590
         2551  +  DD aa 29366 29590 29366 29590   DD bb 28631 29590 27306 28265
         2552  +  DD bb 28796 29590 27471 28265   DD bb 28874 29590 27549 28265
         2553  +  DD bb 29352 29590 28027 28265   EE aa 24781 25558 24781 25558
         2554  +  EE aa 25445 25558 25445 25558   EE bb 24790 25558 23900 24668
         2555  +  EE bb 24929 25558 24039 24668   EE bb 25306 25558 24416 24668
         2556  +  FF aa 22349 23019 22349 23019   FF aa 22352 23019 22352 23019
         2557  +  FF aa 22401 23019 22401 23019   FF aa 22811 23019 22811 23019
         2558  +  FF bb 22081 23019 19918 20856   FF bb 22149 23019 19986 20856
         2559  +  FF bb 22293 23019 20130 20856   FF bb 22445 23019 20282 20856
         2560  +  FF bb 22724 23019 20561 20856   FF bb 22917 23019 20754 20856
         2561  +  GG aa 16717 17351 16717 17351   GG aa 16871 17351 16871 17351
         2562  +  GG aa 17016 17351 17016 17351   GG aa 17203 17351 17203 17351
         2563  +  GG bb 16413 17351 14816 15754   GG bb 16422 17351 14825 15754
         2564  +  GG bb 16507 17351 14910 15754   GG bb 17191 17351 15594 15754
         2565  +  HH aa 11904 12883 11904 12883   HH aa 12093 12883 12093 12883
         2566  +  HH aa 12403 12883 12403 12883   HH bb 11920 12883 9671 10634
         2567  +  HH bb 12153 12883 9904 10634   HH bb 12200 12883 9951 10634
         2568  +  HH bb 12528 12883 10279 10634   HH bb 12553 12883 10304 10634
         2569  +  HH bb 12750 12883 10501 10634   II aa 6788 7440 6788 7440
         2570  +  II aa 7042 7440 7042 7440   II bb 6635 7440 5585 6390
         2571  +  II bb 6769 7440 5719 6390   II bb 6997 7440 5947 6390
         2572  +  II bb 7019 7440 5969 6390   II bb 7190 7440 6140 6390
         2573  +  JJ aa 2901 3800 2901 3800   JJ aa 3032 3800 3032 3800
         2574  +  JJ aa 3566 3800 3566 3800   JJ aa 3687 3800 3687 3800
         2575  +  JJ bb 2961 3800 947 1786   JJ bb 3446 3800 1432 1786
         2576  +  JJ bb 3464 3800 1450 1786   JJ bb 3543 3800 1529 1786}
         2577  +
         2578  +do_execsql_test 1.16.1 {
         2579  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN 0 FOLLOWING         AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         2580  +} {AA aa 4685   AA aa 4685   AA aa 4685   AA aa 4685   AA bb 4685   AA bb 4685
         2581  +  AA bb 4685   AA bb 4685   BB aa 7340   BB aa 7340   BB aa 7340   BB aa 7340
         2582  +  BB aa 7340   BB aa 7340   BB bb 7340   BB bb 7340   BB bb 7340   BB bb 7340
         2583  +  BB bb 7340   BB bb 7340   CC aa 3122   CC aa 3122   CC aa 3122   CC aa 3122
         2584  +  CC bb 3122   CC bb 3122   DD aa 4032   DD aa 4032   DD aa 4032   DD bb 4032
         2585  +  DD bb 4032   DD bb 4032   DD bb 4032   EE aa 2539   EE aa 2539   EE bb 2539
         2586  +  EE bb 2539   EE bb 2539   FF aa 5668   FF aa 5668   FF aa 5668   FF aa 5668
         2587  +  FF bb 5668   FF bb 5668   FF bb 5668   FF bb 5668   FF bb 5668   FF bb 5668
         2588  +  GG aa 4468   GG aa 4468   GG aa 4468   GG aa 4468   GG bb 4468   GG bb 4468
         2589  +  GG bb 4468   GG bb 4468   HH aa 5443   HH aa 5443   HH aa 5443   HH bb 5443
         2590  +  HH bb 5443   HH bb 5443   HH bb 5443   HH bb 5443   HH bb 5443   II aa 3640
         2591  +  II aa 3640   II bb 3640   II bb 3640   II bb 3640   II bb 3640   II bb 3640
         2592  +  JJ aa 3800   JJ aa 3800   JJ aa 3800   JJ aa 3800   JJ bb 3800   JJ bb 3800
         2593  +  JJ bb 3800   JJ bb 3800}
         2594  +
         2595  +do_execsql_test 1.16.2 {
         2596  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 0 FOLLOWING         AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         2597  +} {AA aa 2307   AA aa 2307   AA aa 2307   AA aa 2307   AA bb 2378   AA bb 2378
         2598  +  AA bb 2378   AA bb 2378   BB aa 2873   BB aa 2873   BB aa 2873   BB aa 2873
         2599  +  BB aa 2873   BB aa 2873   BB bb 4467   BB bb 4467   BB bb 4467   BB bb 4467
         2600  +  BB bb 4467   BB bb 4467   CC aa 1954   CC aa 1954   CC aa 1954   CC aa 1954
         2601  +  CC bb 1168   CC bb 1168   DD aa 1325   DD aa 1325   DD aa 1325   DD bb 2707
         2602  +  DD bb 2707   DD bb 2707   DD bb 2707   EE aa 890   EE aa 890   EE bb 1649
         2603  +  EE bb 1649   EE bb 1649   FF aa 2163   FF aa 2163   FF aa 2163   FF aa 2163
         2604  +  FF bb 3505   FF bb 3505   FF bb 3505   FF bb 3505   FF bb 3505   FF bb 3505
         2605  +  GG aa 1597   GG aa 1597   GG aa 1597   GG aa 1597   GG bb 2871   GG bb 2871
         2606  +  GG bb 2871   GG bb 2871   HH aa 2249   HH aa 2249   HH aa 2249   HH bb 3194
         2607  +  HH bb 3194   HH bb 3194   HH bb 3194   HH bb 3194   HH bb 3194   II aa 1050
         2608  +  II aa 1050   II bb 2590   II bb 2590   II bb 2590   II bb 2590   II bb 2590
         2609  +  JJ aa 2014   JJ aa 2014   JJ aa 2014   JJ aa 2014   JJ bb 1786   JJ bb 1786
         2610  +  JJ bb 1786   JJ bb 1786}
         2611  +
         2612  +do_execsql_test 1.16.3 {
         2613  +  SELECT a, b, rank() OVER (ORDER BY a  GROUPS BETWEEN 0 FOLLOWING         AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         2614  +} {AA aa 1   AA aa 1   AA aa 1   AA aa 1   AA bb 1   AA bb 1   AA bb 1
         2615  +  AA bb 1   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9   BB aa 9
         2616  +  BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   BB bb 9   CC aa 21
         2617  +  CC aa 21   CC aa 21   CC aa 21   CC bb 21   CC bb 21   DD aa 27   DD aa 27
         2618  +  DD aa 27   DD bb 27   DD bb 27   DD bb 27   DD bb 27   EE aa 34   EE aa 34
         2619  +  EE bb 34   EE bb 34   EE bb 34   FF aa 39   FF aa 39   FF aa 39   FF aa 39
         2620  +  FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   FF bb 39   GG aa 49
         2621  +  GG aa 49   GG aa 49   GG aa 49   GG bb 49   GG bb 49   GG bb 49   GG bb 49
         2622  +  HH aa 57   HH aa 57   HH aa 57   HH bb 57   HH bb 57   HH bb 57   HH bb 57
         2623  +  HH bb 57   HH bb 57   II aa 66   II aa 66   II bb 66   II bb 66   II bb 66
         2624  +  II bb 66   II bb 66   JJ aa 73   JJ aa 73   JJ aa 73   JJ aa 73   JJ bb 73
         2625  +  JJ bb 73   JJ bb 73   JJ bb 73}
         2626  +
         2627  +do_execsql_test 1.16.4 {
         2628  +  SELECT a, b, max(c) OVER (ORDER BY a,b  GROUPS BETWEEN 0 FOLLOWING         AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         2629  +} {AA aa 934   AA aa 934   AA aa 934   AA aa 934   AA bb 870   AA bb 870
         2630  +  AA bb 870   AA bb 870   BB aa 762   BB aa 762   BB aa 762   BB aa 762
         2631  +  BB aa 762   BB aa 762   BB bb 840   BB bb 840   BB bb 840   BB bb 840
         2632  +  BB bb 840   BB bb 840   CC aa 759   CC aa 759   CC aa 759   CC aa 759
         2633  +  CC bb 822   CC bb 822   DD aa 845   DD aa 845   DD aa 845   DD bb 959
         2634  +  DD bb 959   DD bb 959   DD bb 959   EE aa 777   EE aa 777   EE bb 768
         2635  +  EE bb 768   EE bb 768   FF aa 670   FF aa 670   FF aa 670   FF aa 670
         2636  +  FF bb 938   FF bb 938   FF bb 938   FF bb 938   FF bb 938   FF bb 938
         2637  +  GG aa 634   GG aa 634   GG aa 634   GG aa 634   GG bb 938   GG bb 938
         2638  +  GG bb 938   GG bb 938   HH aa 979   HH aa 979   HH aa 979   HH bb 963
         2639  +  HH bb 963   HH bb 963   HH bb 963   HH bb 963   HH bb 963   II aa 652
         2640  +  II aa 652   II bb 805   II bb 805   II bb 805   II bb 805   II bb 805
         2641  +  JJ aa 899   JJ aa 899   JJ aa 899   JJ aa 899   JJ bb 839   JJ bb 839
         2642  +  JJ bb 839   JJ bb 839}
         2643  +
         2644  +do_execsql_test 1.16.5 {
         2645  +  SELECT a, b, min(c) OVER (ORDER BY a,b  GROUPS BETWEEN 0 FOLLOWING         AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
         2646  +} {AA aa 223   AA aa 223   AA aa 223   AA aa 223   AA bb 309   AA bb 309
         2647  +  AA bb 309   AA bb 309   BB aa 247   BB aa 247   BB aa 247   BB aa 247
         2648  +  BB aa 247   BB aa 247   BB bb 633   BB bb 633   BB bb 633   BB bb 633
         2649  +  BB bb 633   BB bb 633   CC aa 158   CC aa 158   CC aa 158   CC aa 158
         2650  +  CC bb 346   CC bb 346   DD aa 224   DD aa 224   DD aa 224   DD bb 238
         2651  +  DD bb 238   DD bb 238   DD bb 238   EE aa 113   EE aa 113   EE bb 252
         2652  +  EE bb 252   EE bb 252   FF aa 208   FF aa 208   FF aa 208   FF aa 208
         2653  +  FF bb 102   FF bb 102   FF bb 102   FF bb 102   FF bb 102   FF bb 102
         2654  +  GG aa 148   GG aa 148   GG aa 148   GG aa 148   GG bb 160   GG bb 160
         2655  +  GG bb 160   GG bb 160   HH aa 480   HH aa 480   HH aa 480   HH bb 133
         2656  +  HH bb 133   HH bb 133   HH bb 133   HH bb 133   HH bb 133   II aa 398
         2657  +  II aa 398   II bb 250   II bb 250   II bb 250   II bb 250   II bb 250
         2658  +  JJ aa 113   JJ aa 113   JJ aa 113   JJ aa 113   JJ bb 257   JJ bb 257
         2659  +  JJ bb 257   JJ bb 257}
         2660  +
         2661  +do_execsql_test 1.16.6 {
         2662  +  SELECT a, b, sum(c) OVER (ORDER BY a  GROUPS BETWEEN 0 FOLLOWING         AND 0 FOLLOWING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
         2663  +} {AA aa 3751   AA aa 3774   AA aa 4446   AA aa 4462   AA bb 3815   AA bb 4058
         2664  +  AA bb 4113   AA bb 4376   BB aa 6578   BB aa 6680   BB aa 6928   BB aa 6941
         2665  +  BB aa 6947   BB aa 7093   BB bb 6500   BB bb 6548   BB bb 6554   BB bb 6629
         2666  +  BB bb 6635   BB bb 6707   CC aa 2363   CC aa 2515   CC aa 2692   CC aa 2964
         2667  +  CC bb 2300   CC bb 2776   DD aa 3187   DD aa 3776   DD aa 3808   DD bb 3073
         2668  +  DD bb 3238   DD bb 3316   DD bb 3794   EE aa 1762   EE aa 2426   EE bb 1771
         2669  +  EE bb 1910   EE bb 2287   FF aa 4998   FF aa 5001   FF aa 5050   FF aa 5460
         2670  +  FF bb 4730   FF bb 4798   FF bb 4942   FF bb 5094   FF bb 5373   FF bb 5566
         2671  +  GG aa 3834   GG aa 3988   GG aa 4133   GG aa 4320   GG bb 3530   GG bb 3539
         2672  +  GG bb 3624   GG bb 4308   HH aa 4464   HH aa 4653   HH aa 4963   HH bb 4480
         2673  +  HH bb 4713   HH bb 4760   HH bb 5088   HH bb 5113   HH bb 5310   II aa 2988
         2674  +  II aa 3242   II bb 2835   II bb 2969   II bb 3197   II bb 3219   II bb 3390
         2675  +  JJ aa 2901   JJ aa 3032   JJ aa 3566   JJ aa 3687   JJ bb 2961   JJ bb 3446
         2676  +  JJ bb 3464   JJ bb 3543}
         2677  +
         2678  +do_execsql_test 1.16.7 {
         2679  +  SELECT a, b, sum(c) OVER (ORDER BY a,b  GROUPS BETWEEN 0 FOLLOWING         AND 0 FOLLOWING  EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
         2680  +} {AA aa 1373   AA aa 1396   AA aa 2068   AA aa 2084   AA bb 1508   AA bb 1751
         2681  +  AA bb 1806   AA bb 2069   BB aa 2111   BB aa 2213   BB aa 2461   BB aa 2474
         2682  +  BB aa 2480   BB aa 2626   BB bb 3627   BB bb 3675   BB bb 3681   BB bb 3756
         2683  +  BB bb 3762   BB bb 3834   CC aa 1195   CC aa 1347   CC aa 1524   CC aa 1796
         2684  +  CC bb 346   CC bb 822   DD aa 480   DD aa 1069   DD aa 1101   DD bb 1748
         2685  +  DD bb 1913   DD bb 1991   DD bb 2469   EE aa 113   EE aa 777   EE bb 881
         2686  +  EE bb 1020   EE bb 1397   FF aa 1493   FF aa 1496   FF aa 1545   FF aa 1955
         2687  +  FF bb 2567   FF bb 2635   FF bb 2779   FF bb 2931   FF bb 3210   FF bb 3403
         2688  +  GG aa 963   GG aa 1117   GG aa 1262   GG aa 1449   GG bb 1933   GG bb 1942
         2689  +  GG bb 2027   GG bb 2711   HH aa 1270   HH aa 1459   HH aa 1769   HH bb 2231
         2690  +  HH bb 2464   HH bb 2511   HH bb 2839   HH bb 2864   HH bb 3061   II aa 398
         2691  +  II aa 652   II bb 1785   II bb 1919   II bb 2147   II bb 2169   II bb 2340
         2692  +  JJ aa 1115   JJ aa 1246   JJ aa 1780   JJ aa 1901   JJ bb 947   JJ bb 1432
         2693  +  JJ bb 1450   JJ bb 1529}
         2694  +
         2695  +do_execsql_test 1.16.8 {
         2696  +  SELECT a, b, 
         2697  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN 0 FOLLOWING         AND 0 FOLLOWING  EXCLUDE CURRENT ROW),
         2698  +      sum(c) OVER (ORDER BY a  GROUPS BETWEEN 0 FOLLOWING         AND 0 FOLLOWING ),
         2699  +