sqlite3_value_frombind
+** | → | True if value originated a bound parameter
**
**
** Details:
**
** These routines extract type, size, and content information from
@@ -5035,10 +5040,15 @@
** was unchanging). ^Within an [xUpdate] method, any value for which
** sqlite3_value_nochange(X) is true will in all other respects appear
** to be a NULL value. If sqlite3_value_nochange(X) is invoked anywhere other
** than within an [xUpdate] method call for an UPDATE statement, then
** the return value is arbitrary and meaningless.
+**
+** ^The sqlite3_value_frombind(X) interface returns non-zero if the
+** value X originated from one of the [sqlite3_bind_int|sqlite3_bind()]
+** interfaces. ^If X comes from an SQL literal value, or a table column,
+** and expression, then sqlite3_value_frombind(X) returns zero.
**
** Please pay particular attention to the fact that the pointer returned
** from [sqlite3_value_blob()], [sqlite3_value_text()], or
** [sqlite3_value_text16()] can be invalidated by a subsequent call to
** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()],
@@ -5081,10 +5091,11 @@
int sqlite3_value_bytes(sqlite3_value*);
int sqlite3_value_bytes16(sqlite3_value*);
int sqlite3_value_type(sqlite3_value*);
int sqlite3_value_numeric_type(sqlite3_value*);
int sqlite3_value_nochange(sqlite3_value*);
+int sqlite3_value_frombind(sqlite3_value*);
/*
** CAPI3REF: Finding The Subtype Of SQL Values
** METHOD: sqlite3_value
**
Index: src/sqliteInt.h
==================================================================
--- src/sqliteInt.h
+++ src/sqliteInt.h
@@ -1705,11 +1705,10 @@
#define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a
** single query - might change over time */
#define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */
#define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */
#define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */
-#define SQLITE_FUNC_WINDOW_SIZE 0x20000 /* Requires partition size as arg. */
#define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
/*
** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
** used to create the initializers for the FuncDef structures.
@@ -2511,16 +2510,20 @@
} y;
};
/*
** The following are the meanings of bits in the Expr.flags field.
+** Value restrictions:
+**
+** EP_Agg == NC_HasAgg == SF_HasAgg
+** EP_Win == NC_HasWin
*/
#define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */
-#define EP_Agg 0x000002 /* Contains one or more aggregate functions */
+#define EP_Distinct 0x000002 /* Aggregate function with DISTINCT keyword */
#define EP_HasFunc 0x000004 /* Contains one or more functions of any kind */
#define EP_FixedCol 0x000008 /* TK_Column with a known fixed value */
-#define EP_Distinct 0x000010 /* Aggregate function with DISTINCT keyword */
+#define EP_Agg 0x000010 /* Contains one or more aggregate functions */
#define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */
#define EP_DblQuoted 0x000040 /* token.z was originally in "..." */
#define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */
#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE operator */
#define EP_Generic 0x000200 /* Ignore COLLATE or affinity on this tree */
@@ -2527,11 +2530,11 @@
#define EP_IntValue 0x000400 /* Integer value contained in u.iValue */
#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */
#define EP_Skip 0x001000 /* COLLATE, AS, or UNLIKELY */
#define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */
#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
-#define EP_Static 0x008000 /* Held in memory not obtained from malloc() */
+#define EP_Win 0x008000 /* Contains window functions */
#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */
#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
@@ -2539,10 +2542,11 @@
#define EP_Alias 0x400000 /* Is an alias for a result set column */
#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
#define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
#define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */
#define EP_Quoted 0x4000000 /* TK_ID was originally quoted */
+#define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */
/*
** The EP_Propagate mask is a set of properties that automatically propagate
** upwards into parent nodes.
*/
@@ -2778,12 +2782,13 @@
/*
** Allowed values for the NameContext, ncFlags field.
**
** Value constraints (all checked via assert()):
-** NC_HasAgg == SF_HasAgg
+** NC_HasAgg == SF_HasAgg == EP_Agg
** NC_MinMaxAgg == SF_MinMaxAgg == SQLITE_FUNC_MINMAX
+** NC_HasWin == EP_Win
**
*/
#define NC_AllowAgg 0x0001 /* Aggregate functions are allowed here */
#define NC_PartIdx 0x0002 /* True if resolving a partial index WHERE */
#define NC_IsCheck 0x0004 /* True if resolving names in a CHECK constraint */
@@ -2795,10 +2800,11 @@
#define NC_UAggInfo 0x0100 /* True if uNC.pAggInfo is used */
#define NC_UUpsert 0x0200 /* True if uNC.pUpsert is used */
#define NC_MinMaxAgg 0x1000 /* min/max aggregates seen. See note above */
#define NC_Complex 0x2000 /* True if a function or subquery seen */
#define NC_AllowWin 0x4000 /* Window functions are allowed here */
+#define NC_HasWin 0x8000 /* One or more window functions seen */
/*
** An instance of the following object describes a single ON CONFLICT
** clause in an upsert.
**
@@ -3550,11 +3556,11 @@
u8 bLine[100]; /* Draw vertical in column i if bLine[i] is true */
};
#endif /* SQLITE_DEBUG */
/*
-** This object is used in varioius ways, all related to window functions
+** This object is used in various ways, all related to window functions
**
** (1) A single instance of this structure is attached to the
** the Expr.pWin field for each window function in an expression tree.
** This object holds the information contained in the OVER clause,
** plus additional fields used during code generation.
@@ -3565,19 +3571,22 @@
**
** (3) The terms of the WINDOW clause of a SELECT are instances of this
** object on a linked list attached to Select.pWinDefn.
**
** The uses (1) and (2) are really the same Window object that just happens
-** to be accessible in two different ways. Use (3) is are separate objects.
+** to be accessible in two different ways. Use case (3) are separate objects.
*/
struct Window {
char *zName; /* Name of window (may be NULL) */
+ char *zBase; /* Name of base window for chaining (may be NULL) */
ExprList *pPartition; /* PARTITION BY clause */
ExprList *pOrderBy; /* ORDER BY clause */
- u8 eType; /* TK_RANGE or TK_ROWS */
+ u8 eFrmType; /* TK_RANGE, TK_GROUPS, TK_ROWS, or 0 */
u8 eStart; /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */
u8 eEnd; /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */
+ u8 bImplicitFrame; /* True if frame was implicitly specified */
+ u8 eExclude; /* TK_NO, TK_CURRENT, TK_TIES, TK_GROUP, or 0 */
Expr *pStart; /* Expression for " PRECEDING" */
Expr *pEnd; /* Expression for " FOLLOWING" */
Window *pNextWin; /* Next window function belonging to this SELECT */
Expr *pFilter; /* The FILTER expression */
FuncDef *pFunc; /* The function */
@@ -3584,21 +3593,23 @@
int iEphCsr; /* Partition buffer or Peer buffer */
int regAccum;
int regResult;
int csrApp; /* Function cursor (used by min/max) */
int regApp; /* Function register (also used by min/max) */
- int regPart; /* First in a set of registers holding PARTITION BY
- ** and ORDER BY values for the window */
+ int regPart; /* Array of registers for PARTITION BY values */
Expr *pOwner; /* Expression object this window is attached to */
int nBufferCol; /* Number of columns in buffer table */
int iArgCol; /* Offset of first argument for this function */
+ int regOne; /* Register containing constant value 1 */
+ int regStartRowid;
+ int regEndRowid;
};
#ifndef SQLITE_OMIT_WINDOWFUNC
void sqlite3WindowDelete(sqlite3*, Window*);
void sqlite3WindowListDelete(sqlite3 *db, Window *p);
-Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*);
+Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*, u8);
void sqlite3WindowAttach(Parse*, Expr*, Window*);
int sqlite3WindowCompare(Parse*, Window*, Window*);
void sqlite3WindowCodeInit(Parse*, Window*);
void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int);
int sqlite3WindowRewrite(Parse*, Select*);
@@ -3605,10 +3616,12 @@
int sqlite3ExpandSubquery(Parse*, struct SrcList_item*);
void sqlite3WindowUpdate(Parse*, Window*, Window*, FuncDef*);
Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p);
Window *sqlite3WindowListDup(sqlite3 *db, Window *p);
void sqlite3WindowFunctions(void);
+void sqlite3WindowChain(Parse*, Window*, Window*);
+Window *sqlite3WindowAssemble(Parse*, Window*, ExprList*, ExprList*, Token*);
#else
# define sqlite3WindowDelete(a,b)
# define sqlite3WindowFunctions()
# define sqlite3WindowAttach(a,b,c)
#endif
Index: src/test_func.c
==================================================================
--- src/test_func.c
+++ src/test_func.c
@@ -627,10 +627,28 @@
int argc,
sqlite3_value **argv
){
sqlite3_result_int(context, (int)sqlite3_value_subtype(argv[0]));
}
+
+/* test_frombind(A,B,C,...)
+**
+** Return an integer bitmask that has a bit set for every argument
+** (up to the first 63 arguments) that originates from a bind a parameter.
+*/
+static void test_frombind(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ sqlite3_uint64 m = 0;
+ int i;
+ for(i=0; i> 4)==4);
+ if( b ){
+ if( (b & 0x01)==0 ){
+ appendToList(pRes, i, 0, bFlag ? "less than" : "falls through");
+ }
+ if( (b & 0x02)==0 ){
+ appendToList(pRes, i, 1, bFlag ? "equal" : "taken");
+ }
+ if( (b & 0x04)==0 ){
+ appendToList(pRes, i, 2, bFlag ? "greater-than" : "NULL");
+ }
+ }
+ }
+ Tcl_SetObjResult(interp, pRes);
+ Tcl_DecrRefCount(pRes);
+ break;
+ };
+
+ default: /* stop */
+ sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, 0, 0);
+ break;
+ }
+
+ return TCL_OK;
+}
+
+#endif /* SQLITE_VDBE_COVERAGE */
+
+int Sqlitetestvdbecov_Init(Tcl_Interp *interp){
+#ifdef SQLITE_VDBE_COVERAGE
+ Tcl_CreateObjCommand(interp, "vdbe_coverage", test_vdbe_coverage, 0, 0);
+#endif
+ return TCL_OK;
+}
+
+#endif
Index: src/treeview.c
==================================================================
--- src/treeview.c
+++ src/treeview.c
@@ -307,28 +307,66 @@
#ifndef SQLITE_OMIT_WINDOWFUNC
/*
** Generate a human-readable explanation for a Window object
*/
void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){
+ int nElement = 0;
+ if( pWin->pFilter ){
+ sqlite3TreeViewItem(pView, "FILTER", 1);
+ sqlite3TreeViewExpr(pView, pWin->pFilter, 0);
+ sqlite3TreeViewPop(pView);
+ }
pView = sqlite3TreeViewPush(pView, more);
if( pWin->zName ){
- sqlite3TreeViewLine(pView, "OVER %s", pWin->zName);
+ sqlite3TreeViewLine(pView, "OVER %s (%p)", pWin->zName, pWin);
}else{
- sqlite3TreeViewLine(pView, "OVER");
+ sqlite3TreeViewLine(pView, "OVER (%p)", pWin);
+ }
+ if( pWin->zBase ) nElement++;
+ if( pWin->pOrderBy ) nElement++;
+ if( pWin->eFrmType ) nElement++;
+ if( pWin->eExclude ) nElement++;
+ if( pWin->zBase ){
+ sqlite3TreeViewPush(pView, (--nElement)>0);
+ sqlite3TreeViewLine(pView, "window: %s", pWin->zBase);
+ sqlite3TreeViewPop(pView);
}
if( pWin->pPartition ){
- sqlite3TreeViewExprList(pView, pWin->pPartition, 1, "PARTITION-BY");
+ sqlite3TreeViewExprList(pView, pWin->pPartition, nElement>0,"PARTITION-BY");
}
if( pWin->pOrderBy ){
- sqlite3TreeViewExprList(pView, pWin->pOrderBy, 1, "ORDER-BY");
+ sqlite3TreeViewExprList(pView, pWin->pOrderBy, (--nElement)>0, "ORDER-BY");
}
- if( pWin->eType ){
- sqlite3TreeViewItem(pView, pWin->eType==TK_RANGE ? "RANGE" : "ROWS", 0);
+ if( pWin->eFrmType ){
+ char zBuf[30];
+ const char *zFrmType = "ROWS";
+ if( pWin->eFrmType==TK_RANGE ) zFrmType = "RANGE";
+ if( pWin->eFrmType==TK_GROUPS ) zFrmType = "GROUPS";
+ sqlite3_snprintf(sizeof(zBuf),zBuf,"%s%s",zFrmType,
+ pWin->bImplicitFrame ? " (implied)" : "");
+ sqlite3TreeViewItem(pView, zBuf, (--nElement)>0);
sqlite3TreeViewBound(pView, pWin->eStart, pWin->pStart, 1);
sqlite3TreeViewBound(pView, pWin->eEnd, pWin->pEnd, 0);
sqlite3TreeViewPop(pView);
}
+ if( pWin->eExclude ){
+ char zBuf[30];
+ const char *zExclude;
+ switch( pWin->eExclude ){
+ case TK_NO: zExclude = "NO OTHERS"; break;
+ case TK_CURRENT: zExclude = "CURRENT ROW"; break;
+ case TK_GROUP: zExclude = "GROUP"; break;
+ case TK_TIES: zExclude = "TIES"; break;
+ default:
+ sqlite3_snprintf(sizeof(zBuf),zBuf,"invalid(%d)", pWin->eExclude);
+ zExclude = zBuf;
+ break;
+ }
+ sqlite3TreeViewPush(pView, 0);
+ sqlite3TreeViewLine(pView, "EXCLUDE %s", zExclude);
+ sqlite3TreeViewPop(pView);
+ }
sqlite3TreeViewPop(pView);
}
#endif /* SQLITE_OMIT_WINDOWFUNC */
#ifndef SQLITE_OMIT_WINDOWFUNC
Index: src/vdbe.c
==================================================================
--- src/vdbe.c
+++ src/vdbe.c
@@ -120,16 +120,24 @@
/*
** Invoke the VDBE coverage callback, if that callback is defined. This
** feature is used for test suite validation only and does not appear an
** production builds.
**
-** M is an integer between 2 and 4. 2 indicates a ordinary two-way
-** branch (I=0 means fall through and I=1 means taken). 3 indicates
-** a 3-way branch where the third way is when one of the operands is
-** NULL. 4 indicates the OP_Jump instruction which has three destinations
-** depending on whether the first operand is less than, equal to, or greater
-** than the second.
+** M is the type of branch. I is the direction taken for this instance of
+** the branch.
+**
+** M: 2 - two-way branch (I=0: fall-thru 1: jump )
+** 3 - two-way + NULL (I=0: fall-thru 1: jump 2: NULL )
+** 4 - OP_Jump (I=0: jump p1 1: jump p2 2: jump p3)
+**
+** In other words, if M is 2, then I is either 0 (for fall-through) or
+** 1 (for when the branch is taken). If M is 3, the I is 0 for an
+** ordinary fall-through, I is 1 if the branch was taken, and I is 2
+** if the result of comparison is NULL. For M=3, I=2 the jump may or
+** may not be taken, depending on the SQLITE_JUMPIFNULL flags in p5.
+** When M is 4, that means that an OP_Jump is being run. I is 0, 1, or 2
+** depending on if the operands are less than, equal, or greater than.
**
** iSrcLine is the source code line (from the __LINE__ macro) that
** generated the VDBE instruction combined with flag bits. The source
** code line number is in the lower 24 bits of iSrcLine and the upper
** 8 bytes are flags. The lower three bits of the flags indicate
@@ -136,13 +144,13 @@
** values for I that should never occur. For example, if the branch is
** always taken, the flags should be 0x05 since the fall-through and
** alternate branch are never taken. If a branch is never taken then
** flags should be 0x06 since only the fall-through approach is allowed.
**
-** Bit 0x04 of the flags indicates an OP_Jump opcode that is only
+** Bit 0x08 of the flags indicates an OP_Jump opcode that is only
** interested in equal or not-equal. In other words, I==0 and I==2
-** should be treated the same.
+** should be treated as equivalent
**
** Since only a line number is retained, not the filename, this macro
** only works for amalgamation builds. But that is ok, since these macros
** should be no-ops except for special builds used to measure test coverage.
*/
@@ -162,10 +170,22 @@
** a branch really does go in one of those directions, assert right
** away. */
mNever = iSrcLine >> 24;
assert( (I & mNever)==0 );
if( sqlite3GlobalConfig.xVdbeBranch==0 ) return; /*NO_TEST*/
+ /* Invoke the branch coverage callback with three arguments:
+ ** iSrcLine - the line number of the VdbeCoverage() macro, with
+ ** flags removed.
+ ** I - Mask of bits 0x07 indicating which cases are are
+ ** fulfilled by this instance of the jump. 0x01 means
+ ** fall-thru, 0x02 means taken, 0x04 means NULL. Any
+ ** impossible cases (ex: if the comparison is never NULL)
+ ** are filled in automatically so that the coverage
+ ** measurement logic does not flag those impossible cases
+ ** as missed coverage.
+ ** M - Type of jump. Same as M argument above
+ */
I |= mNever;
if( M==2 ) I |= 0x04;
if( M==4 ){
I |= 0x08;
if( (mNever&0x08)!=0 && (I&0x05)!=0) I |= 0x05; /*NO_TEST*/
@@ -1235,11 +1255,14 @@
pVar = &p->aVar[pOp->p1 - 1];
if( sqlite3VdbeMemTooBig(pVar) ){
goto too_big;
}
pOut = &aMem[pOp->p2];
- sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static);
+ if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut);
+ memcpy(pOut, pVar, MEMCELLSIZE);
+ pOut->flags &= ~(MEM_Dyn|MEM_Ephem);
+ pOut->flags |= MEM_Static|MEM_FromBind;
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
/* Opcode: Move P1 P2 P3 * *
@@ -1733,20 +1756,21 @@
*/
case OP_MustBeInt: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
if( (pIn1->flags & MEM_Int)==0 ){
applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
- VdbeBranchTaken((pIn1->flags&MEM_Int)==0, 2);
if( (pIn1->flags & MEM_Int)==0 ){
+ VdbeBranchTaken(1, 2);
if( pOp->p2==0 ){
rc = SQLITE_MISMATCH;
goto abort_due_to_error;
}else{
goto jump_to_p2;
}
}
}
+ VdbeBranchTaken(0, 2);
MemSetTypeFlag(pIn1, MEM_Int);
break;
}
#ifndef SQLITE_OMIT_FLOATING_POINT
@@ -1917,20 +1941,19 @@
if( pOp->p5 & SQLITE_NULLEQ ){
/* If SQLITE_NULLEQ is set (which will only happen if the operator is
** OP_Eq or OP_Ne) then take the jump or not depending on whether
** or not both operands are null.
*/
- assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
assert( (flags1 & MEM_Cleared)==0 );
assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 || CORRUPT_DB );
testcase( (pOp->p5 & SQLITE_JUMPIFNULL)!=0 );
if( (flags1&flags3&MEM_Null)!=0
&& (flags3&MEM_Cleared)==0
){
res = 0; /* Operands are equal */
}else{
- res = 1; /* Operands are not equal */
+ res = ((flags3 & MEM_Null) ? -1 : +1); /* Operands are not equal */
}
}else{
/* SQLITE_NULLEQ is clear and at least one operand is NULL,
** then the result is always NULL.
** The jump is taken if the SQLITE_JUMPIFNULL bit is set.
@@ -2044,11 +2067,11 @@
memAboutToChange(p, pOut);
MemSetTypeFlag(pOut, MEM_Int);
pOut->u.i = res2;
REGISTER_TRACE(pOp->p2, pOut);
}else{
- VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
+ VdbeBranchTaken(res2!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
if( res2 ){
goto jump_to_p2;
}
}
break;
@@ -3605,10 +3628,11 @@
pCx->nullRow = 1;
pCx->isEphemeral = 1;
pCx->pKeyInfo = pOrig->pKeyInfo;
pCx->isTable = pOrig->isTable;
pCx->pgnoRoot = pOrig->pgnoRoot;
+ pCx->isOrdered = pOrig->isOrdered;
rc = sqlite3BtreeCursor(pOrig->pBtx, pCx->pgnoRoot, BTREE_WRCSR,
pCx->pKeyInfo, pCx->uc.pCursor);
/* The sqlite3BtreeCursor() routine can only fail for the first cursor
** opened for a database. Since there is already an open cursor when this
** opcode is run, the sqlite3BtreeCursor() cannot fail */
@@ -5113,22 +5137,18 @@
sqlite3_search_count--;
#endif
p->aCounter[SQLITE_STMTSTATUS_SORT]++;
/* Fall through into OP_Rewind */
}
-/* Opcode: Rewind P1 P2 * * P5
+/* Opcode: Rewind P1 P2 * * *
**
** The next use of the Rowid or Column or Next instruction for P1
** will refer to the first entry in the database table or index.
** If the table or index is empty, jump immediately to P2.
** If the table or index is not empty, fall through to the following
** instruction.
**
-** If P5 is non-zero and the table is not empty, then the "skip-next"
-** flag is set on the cursor so that the next OP_Next instruction
-** executed on it is a no-op.
-**
** This opcode leaves the cursor configured to move in forward order,
** from the beginning toward the end. In other words, the cursor is
** configured to use Next, not Prev.
*/
case OP_Rewind: { /* jump */
@@ -5135,10 +5155,11 @@
VdbeCursor *pC;
BtCursor *pCrsr;
int res;
assert( pOp->p1>=0 && pOp->p1nCursor );
+ assert( pOp->p5==0 );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) );
res = 1;
#ifdef SQLITE_DEBUG
@@ -5149,13 +5170,10 @@
}else{
assert( pC->eCurType==CURTYPE_BTREE );
pCrsr = pC->uc.pCursor;
assert( pCrsr );
rc = sqlite3BtreeFirst(pCrsr, &res);
-#ifndef SQLITE_OMIT_WINDOWFUNC
- if( pOp->p5 ) sqlite3BtreeSkipNext(pCrsr);
-#endif
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
}
if( rc ) goto abort_due_to_error;
pC->nullRow = (u8)res;
@@ -6533,10 +6551,11 @@
assert( pOp->p3==0 || pOp->opcode==OP_AggValue );
pMem = &aMem[pOp->p1];
assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
#ifndef SQLITE_OMIT_WINDOWFUNC
if( pOp->p3 ){
+ memAboutToChange(p, &aMem[pOp->p3]);
rc = sqlite3VdbeMemAggValue(pMem, &aMem[pOp->p3], pOp->p4.pFunc);
pMem = &aMem[pOp->p3];
}else
#endif
{
Index: src/vdbeInt.h
==================================================================
--- src/vdbeInt.h
+++ src/vdbeInt.h
@@ -244,11 +244,11 @@
#define MEM_Str 0x0002 /* Value is a string */
#define MEM_Int 0x0004 /* Value is an integer */
#define MEM_Real 0x0008 /* Value is a real number */
#define MEM_Blob 0x0010 /* Value is a BLOB */
#define MEM_AffMask 0x001f /* Mask of affinity bits */
-/* Available 0x0020 */
+#define MEM_FromBind 0x0020 /* Value originates from sqlite3_bind() */
/* Available 0x0040 */
#define MEM_Undefined 0x0080 /* Value is undefined */
#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
#define MEM_TypeMask 0xc1ff /* Mask of type bits */
Index: src/vdbeapi.c
==================================================================
--- src/vdbeapi.c
+++ src/vdbeapi.c
@@ -288,10 +288,15 @@
/* Return true if a parameter to xUpdate represents an unchanged column */
int sqlite3_value_nochange(sqlite3_value *pVal){
return (pVal->flags&(MEM_Null|MEM_Zero))==(MEM_Null|MEM_Zero);
}
+
+/* Return true if a parameter value originated from an sqlite3_bind() */
+int sqlite3_value_frombind(sqlite3_value *pVal){
+ return (pVal->flags&MEM_FromBind)!=0;
+}
/* Make a copy of an sqlite3_value object
*/
sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){
sqlite3_value *pNew;
Index: src/vdbemem.c
==================================================================
--- src/vdbemem.c
+++ src/vdbemem.c
@@ -55,11 +55,11 @@
assert( ((p->flags&MEM_Dyn)!=0 ? 1 : 0) +
((p->flags&MEM_Ephem)!=0 ? 1 : 0) +
((p->flags&MEM_Static)!=0 ? 1 : 0) <= 1 );
/* No other bits set */
- assert( (p->flags & ~(MEM_Null|MEM_Term|MEM_Subtype
+ assert( (p->flags & ~(MEM_Null|MEM_Term|MEM_Subtype|MEM_FromBind
|MEM_Dyn|MEM_Ephem|MEM_Static))==0 );
}else{
/* A pure NULL might have other flags, such as MEM_Static, MEM_Dyn,
** MEM_Ephem, MEM_Cleared, or MEM_Subtype */
}
Index: src/where.c
==================================================================
--- src/where.c
+++ src/where.c
@@ -3333,15 +3333,15 @@
WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName));
WHERETRACE(0x40, (" VirtualOne: all usable\n"));
rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn);
/* If the call to xBestIndex() with all terms enabled produced a plan
- ** that does not require any source tables (IOW: a plan with mBest==0),
- ** then there is no point in making any further calls to xBestIndex()
- ** since they will all return the same result (if the xBestIndex()
- ** implementation is sane). */
- if( rc==SQLITE_OK && (mBest = (pNew->prereq & ~mPrereq))!=0 ){
+ ** that does not require any source tables (IOW: a plan with mBest==0)
+ ** and does not use an IN(...) operator, then there is no point in making
+ ** any further calls to xBestIndex() since they will all return the same
+ ** result (if the xBestIndex() implementation is sane). */
+ if( rc==SQLITE_OK && ((mBest = (pNew->prereq & ~mPrereq))!=0 || bIn) ){
int seenZero = 0; /* True if a plan with no prereqs seen */
int seenZeroNoIN = 0; /* Plan with no prereqs and no IN(...) seen */
Bitmask mPrev = 0;
Bitmask mBestNoIn = 0;
Index: src/wherecode.c
==================================================================
--- src/wherecode.c
+++ src/wherecode.c
@@ -2195,12 +2195,13 @@
continue;
#else
u32 x = pLevel->iLikeRepCntr;
if( x>0 ){
skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)?OP_IfNot:OP_If,(int)(x>>1));
+ VdbeCoverageIf(v, (x&1)==1);
+ VdbeCoverageIf(v, (x&1)==0);
}
- VdbeCoverage(v);
#endif
}
#ifdef WHERETRACE_ENABLED /* 0xffff */
if( sqlite3WhereTrace ){
VdbeNoopComment((v, "WhereTerm[%d] (%p) priority=%d",
Index: src/window.c
==================================================================
--- src/window.c
+++ src/window.c
@@ -196,10 +196,100 @@
}
sqlite3_result_int64(pCtx, p->nValue);
}
}
+/*
+** Implementation of built-in window function nth_value(). This
+** implementation is used in "slow mode" only - when the EXCLUDE clause
+** is not set to the default value "NO OTHERS".
+*/
+struct NthValueCtx {
+ i64 nStep;
+ sqlite3_value *pValue;
+};
+static void nth_valueStepFunc(
+ sqlite3_context *pCtx,
+ int nArg,
+ sqlite3_value **apArg
+){
+ struct NthValueCtx *p;
+ p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ if( p ){
+ i64 iVal;
+ switch( sqlite3_value_numeric_type(apArg[1]) ){
+ case SQLITE_INTEGER:
+ iVal = sqlite3_value_int64(apArg[1]);
+ break;
+ case SQLITE_FLOAT: {
+ double fVal = sqlite3_value_double(apArg[1]);
+ if( ((i64)fVal)!=fVal ) goto error_out;
+ iVal = (i64)fVal;
+ break;
+ }
+ default:
+ goto error_out;
+ }
+ if( iVal<=0 ) goto error_out;
+
+ p->nStep++;
+ if( iVal==p->nStep ){
+ p->pValue = sqlite3_value_dup(apArg[0]);
+ if( !p->pValue ){
+ sqlite3_result_error_nomem(pCtx);
+ }
+ }
+ }
+ UNUSED_PARAMETER(nArg);
+ UNUSED_PARAMETER(apArg);
+ return;
+
+ error_out:
+ sqlite3_result_error(
+ pCtx, "second argument to nth_value must be a positive integer", -1
+ );
+}
+static void nth_valueFinalizeFunc(sqlite3_context *pCtx){
+ struct NthValueCtx *p;
+ p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, 0);
+ if( p && p->pValue ){
+ sqlite3_result_value(pCtx, p->pValue);
+ sqlite3_value_free(p->pValue);
+ p->pValue = 0;
+ }
+}
+#define nth_valueInvFunc noopStepFunc
+#define nth_valueValueFunc noopValueFunc
+
+static void first_valueStepFunc(
+ sqlite3_context *pCtx,
+ int nArg,
+ sqlite3_value **apArg
+){
+ struct NthValueCtx *p;
+ p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ if( p && p->pValue==0 ){
+ p->pValue = sqlite3_value_dup(apArg[0]);
+ if( !p->pValue ){
+ sqlite3_result_error_nomem(pCtx);
+ }
+ }
+ UNUSED_PARAMETER(nArg);
+ UNUSED_PARAMETER(apArg);
+}
+static void first_valueFinalizeFunc(sqlite3_context *pCtx){
+ struct NthValueCtx *p;
+ p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ if( p && p->pValue ){
+ sqlite3_result_value(pCtx, p->pValue);
+ sqlite3_value_free(p->pValue);
+ p->pValue = 0;
+ }
+}
+#define first_valueInvFunc noopStepFunc
+#define first_valueValueFunc noopValueFunc
+
/*
** Implementation of built-in window function rank(). Assumes that
** the window frame has been set to:
**
** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
@@ -231,75 +321,90 @@
/*
** Implementation of built-in window function percent_rank(). Assumes that
** the window frame has been set to:
**
-** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
+** GROUPS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
*/
static void percent_rankStepFunc(
sqlite3_context *pCtx,
int nArg,
sqlite3_value **apArg
){
struct CallCount *p;
- UNUSED_PARAMETER(nArg); assert( nArg==1 );
-
+ UNUSED_PARAMETER(nArg); assert( nArg==0 );
+ UNUSED_PARAMETER(apArg);
+ p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ if( p ){
+ p->nTotal++;
+ }
+}
+static void percent_rankInvFunc(
+ sqlite3_context *pCtx,
+ int nArg,
+ sqlite3_value **apArg
+){
+ struct CallCount *p;
+ UNUSED_PARAMETER(nArg); assert( nArg==0 );
+ UNUSED_PARAMETER(apArg);
p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
- if( p ){
- if( p->nTotal==0 ){
- p->nTotal = sqlite3_value_int64(apArg[0]);
- }
- p->nStep++;
- if( p->nValue==0 ){
- p->nValue = p->nStep;
- }
- }
+ p->nStep++;
}
static void percent_rankValueFunc(sqlite3_context *pCtx){
struct CallCount *p;
p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
if( p ){
+ p->nValue = p->nStep;
if( p->nTotal>1 ){
- double r = (double)(p->nValue-1) / (double)(p->nTotal-1);
+ double r = (double)p->nValue / (double)(p->nTotal-1);
sqlite3_result_double(pCtx, r);
}else{
sqlite3_result_double(pCtx, 0.0);
}
- p->nValue = 0;
}
}
+#define percent_rankFinalizeFunc percent_rankValueFunc
/*
** Implementation of built-in window function cume_dist(). Assumes that
** the window frame has been set to:
**
-** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
+** GROUPS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING
*/
static void cume_distStepFunc(
sqlite3_context *pCtx,
int nArg,
sqlite3_value **apArg
){
struct CallCount *p;
- assert( nArg==1 ); UNUSED_PARAMETER(nArg);
-
+ UNUSED_PARAMETER(nArg); assert( nArg==0 );
+ UNUSED_PARAMETER(apArg);
p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
if( p ){
- if( p->nTotal==0 ){
- p->nTotal = sqlite3_value_int64(apArg[0]);
- }
- p->nStep++;
+ p->nTotal++;
}
+}
+static void cume_distInvFunc(
+ sqlite3_context *pCtx,
+ int nArg,
+ sqlite3_value **apArg
+){
+ struct CallCount *p;
+ UNUSED_PARAMETER(nArg); assert( nArg==0 );
+ UNUSED_PARAMETER(apArg);
+ p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ p->nStep++;
}
static void cume_distValueFunc(sqlite3_context *pCtx){
struct CallCount *p;
- p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
- if( p && p->nTotal ){
+ p = (struct CallCount*)sqlite3_aggregate_context(pCtx, 0);
+ if( p ){
double r = (double)(p->nStep) / (double)(p->nTotal);
sqlite3_result_double(pCtx, r);
}
}
+#define cume_distFinalizeFunc cume_distValueFunc
/*
** Context object for ntile() window function.
*/
struct NtileCtx {
@@ -310,44 +415,54 @@
/*
** Implementation of ntile(). This assumes that the window frame has
** been coerced to:
**
-** ROWS UNBOUNDED PRECEDING AND CURRENT ROW
+** ROWS CURRENT ROW AND UNBOUNDED FOLLOWING
*/
static void ntileStepFunc(
sqlite3_context *pCtx,
int nArg,
sqlite3_value **apArg
){
struct NtileCtx *p;
- assert( nArg==2 ); UNUSED_PARAMETER(nArg);
+ assert( nArg==1 ); UNUSED_PARAMETER(nArg);
p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
if( p ){
if( p->nTotal==0 ){
p->nParam = sqlite3_value_int64(apArg[0]);
- p->nTotal = sqlite3_value_int64(apArg[1]);
if( p->nParam<=0 ){
sqlite3_result_error(
pCtx, "argument of ntile must be a positive integer", -1
);
}
}
- p->iRow++;
+ p->nTotal++;
}
+}
+static void ntileInvFunc(
+ sqlite3_context *pCtx,
+ int nArg,
+ sqlite3_value **apArg
+){
+ struct NtileCtx *p;
+ assert( nArg==1 ); UNUSED_PARAMETER(nArg);
+ UNUSED_PARAMETER(apArg);
+ p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ p->iRow++;
}
static void ntileValueFunc(sqlite3_context *pCtx){
struct NtileCtx *p;
p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
if( p && p->nParam>0 ){
int nSize = (p->nTotal / p->nParam);
if( nSize==0 ){
- sqlite3_result_int64(pCtx, p->iRow);
+ sqlite3_result_int64(pCtx, p->iRow+1);
}else{
i64 nLarge = p->nTotal - p->nParam*nSize;
i64 iSmall = nLarge*(nSize+1);
- i64 iRow = p->iRow-1;
+ i64 iRow = p->iRow;
assert( (nLarge*(nSize+1) + (p->nParam-nLarge)*nSize)==p->nTotal );
if( iRowpVal ){
sqlite3_result_value(pCtx, p->pVal);
}
}
static void last_valueFinalizeFunc(sqlite3_context *pCtx){
@@ -494,25 +610,36 @@
void sqlite3WindowFunctions(void){
static FuncDef aWindowFuncs[] = {
WINDOWFUNCX(row_number, 0, 0),
WINDOWFUNCX(dense_rank, 0, 0),
WINDOWFUNCX(rank, 0, 0),
- WINDOWFUNCX(percent_rank, 0, SQLITE_FUNC_WINDOW_SIZE),
- WINDOWFUNCX(cume_dist, 0, SQLITE_FUNC_WINDOW_SIZE),
- WINDOWFUNCX(ntile, 1, SQLITE_FUNC_WINDOW_SIZE),
+ WINDOWFUNCALL(percent_rank, 0, 0),
+ WINDOWFUNCALL(cume_dist, 0, 0),
+ WINDOWFUNCALL(ntile, 1, 0),
WINDOWFUNCALL(last_value, 1, 0),
- WINDOWFUNCNOOP(nth_value, 2, 0),
- WINDOWFUNCNOOP(first_value, 1, 0),
+ WINDOWFUNCALL(nth_value, 2, 0),
+ WINDOWFUNCALL(first_value, 1, 0),
WINDOWFUNCNOOP(lead, 1, 0),
WINDOWFUNCNOOP(lead, 2, 0),
WINDOWFUNCNOOP(lead, 3, 0),
WINDOWFUNCNOOP(lag, 1, 0),
WINDOWFUNCNOOP(lag, 2, 0),
WINDOWFUNCNOOP(lag, 3, 0),
};
sqlite3InsertBuiltinFuncs(aWindowFuncs, ArraySize(aWindowFuncs));
}
+
+static Window *windowFind(Parse *pParse, Window *pList, const char *zName){
+ Window *p;
+ for(p=pList; p; p=p->pNextWin){
+ if( sqlite3StrICmp(p->zName, zName)==0 ) break;
+ }
+ if( p==0 ){
+ sqlite3ErrorMsg(pParse, "no such window: %s", zName);
+ }
+ return p;
+}
/*
** This function is called immediately after resolving the function name
** for a window function within a SELECT statement. Argument pList is a
** linked list of WINDOW definitions for the current SELECT statement.
@@ -533,52 +660,70 @@
Parse *pParse,
Window *pList, /* List of named windows for this SELECT */
Window *pWin, /* Window frame to update */
FuncDef *pFunc /* Window function definition */
){
- if( pWin->zName && pWin->eType==0 ){
- Window *p;
- for(p=pList; p; p=p->pNextWin){
- if( sqlite3StrICmp(p->zName, pWin->zName)==0 ) break;
- }
- if( p==0 ){
- sqlite3ErrorMsg(pParse, "no such window: %s", pWin->zName);
- return;
- }
+ if( pWin->zName && pWin->eFrmType==0 ){
+ Window *p = windowFind(pParse, pList, pWin->zName);
+ if( p==0 ) return;
pWin->pPartition = sqlite3ExprListDup(pParse->db, p->pPartition, 0);
pWin->pOrderBy = sqlite3ExprListDup(pParse->db, p->pOrderBy, 0);
pWin->pStart = sqlite3ExprDup(pParse->db, p->pStart, 0);
pWin->pEnd = sqlite3ExprDup(pParse->db, p->pEnd, 0);
pWin->eStart = p->eStart;
pWin->eEnd = p->eEnd;
- pWin->eType = p->eType;
+ pWin->eFrmType = p->eFrmType;
+ pWin->eExclude = p->eExclude;
+ }else{
+ sqlite3WindowChain(pParse, pWin, pList);
}
+ if( (pWin->eFrmType==TK_RANGE)
+ && (pWin->pStart || pWin->pEnd)
+ && (pWin->pOrderBy==0 || pWin->pOrderBy->nExpr!=1)
+ ){
+ sqlite3ErrorMsg(pParse,
+ "RANGE with offset PRECEDING/FOLLOWING requires one ORDER BY expression"
+ );
+ }else
if( pFunc->funcFlags & SQLITE_FUNC_WINDOW ){
sqlite3 *db = pParse->db;
if( pWin->pFilter ){
sqlite3ErrorMsg(pParse,
"FILTER clause may only be used with aggregate window functions"
);
- }else
- if( pFunc->zName==row_numberName || pFunc->zName==ntileName ){
- sqlite3ExprDelete(db, pWin->pStart);
- sqlite3ExprDelete(db, pWin->pEnd);
- pWin->pStart = pWin->pEnd = 0;
- pWin->eType = TK_ROWS;
- pWin->eStart = TK_UNBOUNDED;
- pWin->eEnd = TK_CURRENT;
- }else
-
- if( pFunc->zName==dense_rankName || pFunc->zName==rankName
- || pFunc->zName==percent_rankName || pFunc->zName==cume_distName
- ){
- sqlite3ExprDelete(db, pWin->pStart);
- sqlite3ExprDelete(db, pWin->pEnd);
- pWin->pStart = pWin->pEnd = 0;
- pWin->eType = TK_RANGE;
- pWin->eStart = TK_UNBOUNDED;
- pWin->eEnd = TK_CURRENT;
+ }else{
+ struct WindowUpdate {
+ const char *zFunc;
+ int eFrmType;
+ int eStart;
+ int eEnd;
+ } aUp[] = {
+ { row_numberName, TK_ROWS, TK_UNBOUNDED, TK_CURRENT },
+ { dense_rankName, TK_RANGE, TK_UNBOUNDED, TK_CURRENT },
+ { rankName, TK_RANGE, TK_UNBOUNDED, TK_CURRENT },
+ { percent_rankName, TK_GROUPS, TK_CURRENT, TK_UNBOUNDED },
+ { cume_distName, TK_GROUPS, TK_FOLLOWING, TK_UNBOUNDED },
+ { ntileName, TK_ROWS, TK_CURRENT, TK_UNBOUNDED },
+ { leadName, TK_ROWS, TK_UNBOUNDED, TK_UNBOUNDED },
+ { lagName, TK_ROWS, TK_UNBOUNDED, TK_CURRENT },
+ };
+ int i;
+ for(i=0; izName==aUp[i].zFunc ){
+ sqlite3ExprDelete(db, pWin->pStart);
+ sqlite3ExprDelete(db, pWin->pEnd);
+ pWin->pEnd = pWin->pStart = 0;
+ pWin->eFrmType = aUp[i].eFrmType;
+ pWin->eStart = aUp[i].eStart;
+ pWin->eEnd = aUp[i].eEnd;
+ pWin->eExclude = 0;
+ if( pWin->eStart==TK_FOLLOWING ){
+ pWin->pStart = sqlite3Expr(db, TK_INTEGER, "1");
+ }
+ break;
+ }
+ }
}
}
pWin->pFunc = pFunc;
}
@@ -779,10 +924,11 @@
/* Assign a cursor number for the ephemeral table used to buffer rows.
** The OpenEphemeral instruction is coded later, after it is known how
** many columns the table will have. */
pMWin->iEphCsr = pParse->nTab++;
+ pParse->nTab += 3;
selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, &pSublist);
selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, &pSublist);
pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0);
@@ -834,10 +980,13 @@
p->selFlags &= ~SF_Aggregate;
sqlite3SelectPrep(pParse, pSub, 0);
}
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, pSublist->nExpr);
+ sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr);
+ sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+2, pMWin->iEphCsr);
+ sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+3, pMWin->iEphCsr);
}else{
sqlite3SelectDelete(db, pSub);
}
if( db->mallocFailed ) rc = SQLITE_NOMEM;
}
@@ -854,10 +1003,11 @@
sqlite3ExprListDelete(db, p->pPartition);
sqlite3ExprListDelete(db, p->pOrderBy);
sqlite3ExprDelete(db, p->pEnd);
sqlite3ExprDelete(db, p->pStart);
sqlite3DbFree(db, p->zName);
+ sqlite3DbFree(db, p->zBase);
sqlite3DbFree(db, p);
}
}
/*
@@ -890,34 +1040,32 @@
/*
** Allocate and return a new Window object describing a Window Definition.
*/
Window *sqlite3WindowAlloc(
Parse *pParse, /* Parsing context */
- int eType, /* Frame type. TK_RANGE or TK_ROWS */
+ int eType, /* Frame type. TK_RANGE, TK_ROWS, TK_GROUPS, or 0 */
int eStart, /* Start type: CURRENT, PRECEDING, FOLLOWING, UNBOUNDED */
Expr *pStart, /* Start window size if TK_PRECEDING or FOLLOWING */
int eEnd, /* End type: CURRENT, FOLLOWING, TK_UNBOUNDED, PRECEDING */
- Expr *pEnd /* End window size if TK_FOLLOWING or PRECEDING */
+ Expr *pEnd, /* End window size if TK_FOLLOWING or PRECEDING */
+ u8 eExclude /* EXCLUDE clause */
){
Window *pWin = 0;
+ int bImplicitFrame = 0;
/* Parser assures the following: */
- assert( eType==TK_RANGE || eType==TK_ROWS );
+ assert( eType==0 || eType==TK_RANGE || eType==TK_ROWS || eType==TK_GROUPS );
assert( eStart==TK_CURRENT || eStart==TK_PRECEDING
|| eStart==TK_UNBOUNDED || eStart==TK_FOLLOWING );
assert( eEnd==TK_CURRENT || eEnd==TK_FOLLOWING
|| eEnd==TK_UNBOUNDED || eEnd==TK_PRECEDING );
assert( (eStart==TK_PRECEDING || eStart==TK_FOLLOWING)==(pStart!=0) );
assert( (eEnd==TK_FOLLOWING || eEnd==TK_PRECEDING)==(pEnd!=0) );
-
- /* If a frame is declared "RANGE" (not "ROWS"), then it may not use
- ** either " PRECEDING" or " FOLLOWING".
- */
- if( eType==TK_RANGE && (pStart!=0 || pEnd!=0) ){
- sqlite3ErrorMsg(pParse, "RANGE must use only UNBOUNDED or CURRENT ROW");
- goto windowAllocErr;
+ if( eType==0 ){
+ bImplicitFrame = 1;
+ eType = TK_RANGE;
}
/* Additionally, the
** starting boundary type may not occur earlier in the following list than
** the ending boundary type:
@@ -933,28 +1081,96 @@
** frame boundary.
*/
if( (eStart==TK_CURRENT && eEnd==TK_PRECEDING)
|| (eStart==TK_FOLLOWING && (eEnd==TK_PRECEDING || eEnd==TK_CURRENT))
){
- sqlite3ErrorMsg(pParse, "unsupported frame delimiter for ROWS");
+ sqlite3ErrorMsg(pParse, "unsupported frame specification");
goto windowAllocErr;
}
pWin = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
if( pWin==0 ) goto windowAllocErr;
- pWin->eType = eType;
+ pWin->eFrmType = eType;
pWin->eStart = eStart;
pWin->eEnd = eEnd;
+ if( eExclude==0 && OptimizationDisabled(pParse->db, SQLITE_QueryFlattener) ){
+ eExclude = TK_NO;
+ }
+ pWin->eExclude = eExclude;
+ pWin->bImplicitFrame = bImplicitFrame;
pWin->pEnd = sqlite3WindowOffsetExpr(pParse, pEnd);
pWin->pStart = sqlite3WindowOffsetExpr(pParse, pStart);
return pWin;
windowAllocErr:
sqlite3ExprDelete(pParse->db, pEnd);
sqlite3ExprDelete(pParse->db, pStart);
return 0;
}
+
+/*
+** Attach PARTITION and ORDER BY clauses pPartition and pOrderBy to window
+** pWin. Also, if parameter pBase is not NULL, set pWin->zBase to the
+** equivalent nul-terminated string.
+*/
+Window *sqlite3WindowAssemble(
+ Parse *pParse,
+ Window *pWin,
+ ExprList *pPartition,
+ ExprList *pOrderBy,
+ Token *pBase
+){
+ if( pWin ){
+ pWin->pPartition = pPartition;
+ pWin->pOrderBy = pOrderBy;
+ if( pBase ){
+ pWin->zBase = sqlite3DbStrNDup(pParse->db, pBase->z, pBase->n);
+ }
+ }else{
+ sqlite3ExprListDelete(pParse->db, pPartition);
+ sqlite3ExprListDelete(pParse->db, pOrderBy);
+ }
+ return pWin;
+}
+
+/*
+** Window *pWin has just been created from a WINDOW clause. Tokne pBase
+** is the base window. Earlier windows from the same WINDOW clause are
+** stored in the linked list starting at pWin->pNextWin. This function
+** either updates *pWin according to the base specification, or else
+** leaves an error in pParse.
+*/
+void sqlite3WindowChain(Parse *pParse, Window *pWin, Window *pList){
+ if( pWin->zBase ){
+ sqlite3 *db = pParse->db;
+ Window *pExist = windowFind(pParse, pList, pWin->zBase);
+ if( pExist ){
+ const char *zErr = 0;
+ /* Check for errors */
+ if( pWin->pPartition ){
+ zErr = "PARTITION clause";
+ }else if( pExist->pOrderBy && pWin->pOrderBy ){
+ zErr = "ORDER BY clause";
+ }else if( pExist->bImplicitFrame==0 ){
+ zErr = "frame specification";
+ }
+ if( zErr ){
+ sqlite3ErrorMsg(pParse,
+ "cannot override %s of window: %s", zErr, pWin->zBase
+ );
+ }else{
+ pWin->pPartition = sqlite3ExprListDup(db, pExist->pPartition, 0);
+ if( pExist->pOrderBy ){
+ assert( pWin->pOrderBy==0 );
+ pWin->pOrderBy = sqlite3ExprListDup(db, pExist->pOrderBy, 0);
+ }
+ sqlite3DbFree(db, pWin->zBase);
+ pWin->zBase = 0;
+ }
+ }
+ }
+}
/*
** Attach window object pWin to expression p.
*/
void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
@@ -980,13 +1196,14 @@
/*
** Return 0 if the two window objects are identical, or non-zero otherwise.
** Identical window objects can be processed in a single scan.
*/
int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2){
- if( p1->eType!=p2->eType ) return 1;
+ if( p1->eFrmType!=p2->eFrmType ) return 1;
if( p1->eStart!=p2->eStart ) return 1;
if( p1->eEnd!=p2->eEnd ) return 1;
+ if( p1->eExclude!=p2->eExclude ) return 1;
if( sqlite3ExprCompare(pParse, p1->pStart, p2->pStart, -1) ) return 1;
if( sqlite3ExprCompare(pParse, p1->pEnd, p2->pEnd, -1) ) return 1;
if( sqlite3ExprListCompare(p1->pPartition, p2->pPartition, -1) ) return 1;
if( sqlite3ExprListCompare(p1->pOrderBy, p2->pOrderBy, -1) ) return 1;
return 0;
@@ -999,16 +1216,31 @@
** and initialize registers and cursors used by sqlite3WindowCodeStep().
*/
void sqlite3WindowCodeInit(Parse *pParse, Window *pMWin){
Window *pWin;
Vdbe *v = sqlite3GetVdbe(pParse);
- int nPart = (pMWin->pPartition ? pMWin->pPartition->nExpr : 0);
- nPart += (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);
- if( nPart ){
+
+ /* Allocate registers to use for PARTITION BY values, if any. Initialize
+ ** said registers to NULL. */
+ if( pMWin->pPartition ){
+ int nExpr = pMWin->pPartition->nExpr;
pMWin->regPart = pParse->nMem+1;
- pParse->nMem += nPart;
- sqlite3VdbeAddOp3(v, OP_Null, 0, pMWin->regPart, pMWin->regPart+nPart-1);
+ pParse->nMem += nExpr;
+ sqlite3VdbeAddOp3(v, OP_Null, 0, pMWin->regPart, pMWin->regPart+nExpr-1);
+ }
+
+ pMWin->regOne = ++pParse->nMem;
+ sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regOne);
+
+ if( pMWin->eExclude ){
+ pMWin->regStartRowid = ++pParse->nMem;
+ pMWin->regEndRowid = ++pParse->nMem;
+ pMWin->csrApp = pParse->nTab++;
+ sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regStartRowid);
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regEndRowid);
+ sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->csrApp, pMWin->iEphCsr);
+ return;
}
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
FuncDef *p = pWin->pFunc;
if( (p->funcFlags & SQLITE_FUNC_MINMAX) && pWin->eStart!=TK_UNBOUNDED ){
@@ -1033,50 +1265,71 @@
sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
}
else if( p->zName==nth_valueName || p->zName==first_valueName ){
/* Allocate two registers at pWin->regApp. These will be used to
** store the start and end index of the current frame. */
- assert( pMWin->iEphCsr );
pWin->regApp = pParse->nMem+1;
pWin->csrApp = pParse->nTab++;
pParse->nMem += 2;
sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);
}
else if( p->zName==leadName || p->zName==lagName ){
- assert( pMWin->iEphCsr );
pWin->csrApp = pParse->nTab++;
sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);
}
}
}
+
+#define WINDOW_STARTING_INT 0
+#define WINDOW_ENDING_INT 1
+#define WINDOW_NTH_VALUE_INT 2
+#define WINDOW_STARTING_NUM 3
+#define WINDOW_ENDING_NUM 4
/*
** A "PRECEDING " (eCond==0) or "FOLLOWING " (eCond==1) or the
** value of the second argument to nth_value() (eCond==2) has just been
** evaluated and the result left in register reg. This function generates VM
** code to check that the value is a non-negative integer and throws an
** exception if it is not.
*/
-static void windowCheckIntValue(Parse *pParse, int reg, int eCond){
+static void windowCheckValue(Parse *pParse, int reg, int eCond){
static const char *azErr[] = {
"frame starting offset must be a non-negative integer",
"frame ending offset must be a non-negative integer",
- "second argument to nth_value must be a positive integer"
+ "second argument to nth_value must be a positive integer",
+ "frame starting offset must be a non-negative number",
+ "frame ending offset must be a non-negative number",
};
- static int aOp[] = { OP_Ge, OP_Ge, OP_Gt };
+ static int aOp[] = { OP_Ge, OP_Ge, OP_Gt, OP_Ge, OP_Ge };
Vdbe *v = sqlite3GetVdbe(pParse);
int regZero = sqlite3GetTempReg(pParse);
- assert( eCond==0 || eCond==1 || eCond==2 );
+ assert( eCond>=0 && eCond=WINDOW_STARTING_NUM ){
+ int regString = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC);
+ sqlite3VdbeAddOp3(v, OP_Ge, regString, sqlite3VdbeCurrentAddr(v)+2, reg);
+ sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC|SQLITE_JUMPIFNULL);
+ VdbeCoverage(v);
+ assert( eCond==3 || eCond==4 );
+ VdbeCoverageIf(v, eCond==3);
+ VdbeCoverageIf(v, eCond==4);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_MustBeInt, reg, sqlite3VdbeCurrentAddr(v)+2);
+ VdbeCoverage(v);
+ assert( eCond==0 || eCond==1 || eCond==2 );
+ VdbeCoverageIf(v, eCond==0);
+ VdbeCoverageIf(v, eCond==1);
+ VdbeCoverageIf(v, eCond==2);
+ }
sqlite3VdbeAddOp3(v, aOp[eCond], regZero, sqlite3VdbeCurrentAddr(v)+2, reg);
- VdbeCoverageNeverNullIf(v, eCond==0);
- VdbeCoverageNeverNullIf(v, eCond==1);
+ VdbeCoverageNeverNullIf(v, eCond==0); /* NULL case captured by */
+ VdbeCoverageNeverNullIf(v, eCond==1); /* the OP_MustBeInt */
VdbeCoverageNeverNullIf(v, eCond==2);
+ VdbeCoverageNeverNullIf(v, eCond==3); /* NULL case caught by */
+ VdbeCoverageNeverNullIf(v, eCond==4); /* the OP_Ge */
sqlite3MayAbort(pParse);
sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_ERROR, OE_Abort);
sqlite3VdbeAppendP4(v, (void*)azErr[eCond], P4_STATIC);
sqlite3ReleaseTempReg(pParse, regZero);
}
@@ -1112,41 +1365,32 @@
static void windowAggStep(
Parse *pParse,
Window *pMWin, /* Linked list of window functions */
int csr, /* Read arguments from this cursor */
int bInverse, /* True to invoke xInverse instead of xStep */
- int reg, /* Array of registers */
- int regPartSize /* Register containing size of partition */
+ int reg /* Array of registers */
){
Vdbe *v = sqlite3GetVdbe(pParse);
Window *pWin;
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
- int flags = pWin->pFunc->funcFlags;
+ FuncDef *pFunc = pWin->pFunc;
int regArg;
int nArg = windowArgCount(pWin);
+ int i;
- if( csr>=0 ){
- int i;
- for(i=0; izName!=nth_valueName ){
sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i);
- }
- regArg = reg;
- if( flags & SQLITE_FUNC_WINDOW_SIZE ){
- if( nArg==0 ){
- regArg = regPartSize;
- }else{
- sqlite3VdbeAddOp2(v, OP_SCopy, regPartSize, reg+nArg);
- }
- nArg++;
- }
- }else{
- assert( !(flags & SQLITE_FUNC_WINDOW_SIZE) );
- regArg = reg + pWin->iArgCol;
- }
-
- if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX)
- && pWin->eStart!=TK_UNBOUNDED
+ }else{
+ sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+i, reg+i);
+ }
+ }
+ regArg = reg;
+
+ if( pMWin->regStartRowid==0
+ && (pFunc->funcFlags & SQLITE_FUNC_MINMAX)
+ && (pWin->eStart!=TK_UNBOUNDED)
){
int addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regArg);
VdbeCoverage(v);
if( bInverse==0 ){
sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1, 1);
@@ -1159,151 +1403,223 @@
sqlite3VdbeAddOp1(v, OP_Delete, pWin->csrApp);
sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
}
sqlite3VdbeJumpHere(v, addrIsNull);
}else if( pWin->regApp ){
- assert( pWin->pFunc->zName==nth_valueName
- || pWin->pFunc->zName==first_valueName
+ assert( pFunc->zName==nth_valueName
+ || pFunc->zName==first_valueName
);
assert( bInverse==0 || bInverse==1 );
sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1);
- }else if( pWin->pFunc->zName==leadName
- || pWin->pFunc->zName==lagName
- ){
- /* no-op */
- }else{
+ }else if( pFunc->xSFunc!=noopStepFunc ){
int addrIf = 0;
if( pWin->pFilter ){
int regTmp;
assert( nArg==0 || nArg==pWin->pOwner->x.pList->nExpr );
assert( nArg || pWin->pOwner->x.pList==0 );
- if( csr>0 ){
- regTmp = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
- }else{
- regTmp = regArg + nArg;
- }
+ regTmp = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
VdbeCoverage(v);
- if( csr>0 ){
- sqlite3ReleaseTempReg(pParse, regTmp);
- }
+ sqlite3ReleaseTempReg(pParse, regTmp);
}
- if( pWin->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
+ if( pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
CollSeq *pColl;
assert( nArg>0 );
pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr);
sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ);
}
sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep,
bInverse, regArg, pWin->regAccum);
- sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
+ sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF);
sqlite3VdbeChangeP5(v, (u8)nArg);
if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
}
}
}
+
+typedef struct WindowCodeArg WindowCodeArg;
+typedef struct WindowCsrAndReg WindowCsrAndReg;
+struct WindowCsrAndReg {
+ int csr;
+ int reg;
+};
+
+struct WindowCodeArg {
+ Parse *pParse;
+ Window *pMWin;
+ Vdbe *pVdbe;
+ int regGosub;
+ int addrGosub;
+ int regArg;
+ int eDelete;
+
+ WindowCsrAndReg start;
+ WindowCsrAndReg current;
+ WindowCsrAndReg end;
+};
+
+/*
+** Values that may be passed as the second argument to windowCodeOp().
+*/
+#define WINDOW_RETURN_ROW 1
+#define WINDOW_AGGINVERSE 2
+#define WINDOW_AGGSTEP 3
+
+/*
+** Generate VM code to read the window frames peer values from cursor csr into
+** an array of registers starting at reg.
+*/
+static void windowReadPeerValues(
+ WindowCodeArg *p,
+ int csr,
+ int reg
+){
+ Window *pMWin = p->pMWin;
+ ExprList *pOrderBy = pMWin->pOrderBy;
+ if( pOrderBy ){
+ Vdbe *v = sqlite3GetVdbe(p->pParse);
+ ExprList *pPart = pMWin->pPartition;
+ int iColOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0);
+ int i;
+ for(i=0; inExpr; i++){
+ sqlite3VdbeAddOp3(v, OP_Column, csr, iColOff+i, reg+i);
+ }
+ }
+}
/*
-** Generate VM code to invoke either xValue() (bFinal==0) or xFinalize()
-** (bFinal==1) for each window function in the linked list starting at
+** Generate VM code to invoke either xValue() (bFin==0) or xFinalize()
+** (bFin==1) for each window function in the linked list starting at
** pMWin. Or, for built-in window-functions that do not use the standard
** API, generate the equivalent VM code.
*/
-static void windowAggFinal(Parse *pParse, Window *pMWin, int bFinal){
+static void windowAggFinal(WindowCodeArg *p, int bFin){
+ Parse *pParse = p->pParse;
+ Window *pMWin = p->pMWin;
Vdbe *v = sqlite3GetVdbe(pParse);
Window *pWin;
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
- if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX)
- && pWin->eStart!=TK_UNBOUNDED
+ if( pMWin->regStartRowid==0
+ && (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX)
+ && (pWin->eStart!=TK_UNBOUNDED)
){
sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
sqlite3VdbeAddOp1(v, OP_Last, pWin->csrApp);
VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_Column, pWin->csrApp, 0, pWin->regResult);
sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
- if( bFinal ){
- sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp);
- }
}else if( pWin->regApp ){
+ assert( pMWin->regStartRowid==0 );
}else{
- if( bFinal ){
- sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, windowArgCount(pWin));
+ int nArg = windowArgCount(pWin);
+ if( bFin ){
+ sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, nArg);
sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult);
sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
}else{
- sqlite3VdbeAddOp3(v, OP_AggValue, pWin->regAccum, windowArgCount(pWin),
- pWin->regResult);
+ sqlite3VdbeAddOp3(v, OP_AggValue,pWin->regAccum,nArg,pWin->regResult);
sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
}
}
}
}
/*
-** This function generates VM code to invoke the sub-routine at address
-** lblFlushPart once for each partition with the entire partition cached in
-** the Window.iEphCsr temp table.
+** Generate code to calculate the current values of all window functions in the
+** p->pMWin list by doing a full scan of the current window frame. Store the
+** results in the Window.regResult registers, ready to return the upper
+** layer.
*/
-static void windowPartitionCache(
- Parse *pParse,
- Select *p, /* The rewritten SELECT statement */
- WhereInfo *pWInfo, /* WhereInfo to call WhereEnd() on */
- int regFlushPart, /* Register to use with Gosub lblFlushPart */
- int lblFlushPart, /* Subroutine to Gosub to */
- int *pRegSize /* OUT: Register containing partition size */
-){
- Window *pMWin = p->pWin;
- Vdbe *v = sqlite3GetVdbe(pParse);
- int iSubCsr = p->pSrc->a[0].iCursor;
- int nSub = p->pSrc->a[0].pTab->nCol;
- int k;
-
- int reg = pParse->nMem+1;
- int regRecord = reg+nSub;
- int regRowid = regRecord+1;
-
- *pRegSize = regRowid;
- pParse->nMem += nSub + 2;
-
- /* Load the column values for the row returned by the sub-select
- ** into an array of registers starting at reg. */
- for(k=0; kpPartition ){
+static void windowFullScan(WindowCodeArg *p){
+ Window *pWin;
+ Parse *pParse = p->pParse;
+ Window *pMWin = p->pMWin;
+ Vdbe *v = p->pVdbe;
+
+ int regCRowid = 0; /* Current rowid value */
+ int regCPeer = 0; /* Current peer values */
+ int regRowid = 0; /* AggStep rowid value */
+ int regPeer = 0; /* AggStep peer values */
+
+ int nPeer;
+ int lblNext;
+ int lblBrk;
+ int addrNext;
+ int csr = pMWin->csrApp;
+
+ nPeer = (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);
+
+ lblNext = sqlite3VdbeMakeLabel(pParse);
+ lblBrk = sqlite3VdbeMakeLabel(pParse);
+
+ regCRowid = sqlite3GetTempReg(pParse);
+ regRowid = sqlite3GetTempReg(pParse);
+ if( nPeer ){
+ regCPeer = sqlite3GetTempRange(pParse, nPeer);
+ regPeer = sqlite3GetTempRange(pParse, nPeer);
+ }
+
+ sqlite3VdbeAddOp2(v, OP_Rowid, pMWin->iEphCsr, regCRowid);
+ windowReadPeerValues(p, pMWin->iEphCsr, regCPeer);
+
+ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
+ sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
+ }
+
+ sqlite3VdbeAddOp3(v, OP_SeekGE, csr, lblBrk, pMWin->regStartRowid);
+ VdbeCoverage(v);
+ addrNext = sqlite3VdbeCurrentAddr(v);
+ sqlite3VdbeAddOp2(v, OP_Rowid, csr, regRowid);
+ sqlite3VdbeAddOp3(v, OP_Gt, pMWin->regEndRowid, lblBrk, regRowid);
+ VdbeCoverageNeverNull(v);
+
+ if( pMWin->eExclude==TK_CURRENT ){
+ sqlite3VdbeAddOp3(v, OP_Eq, regCRowid, lblNext, regRowid);
+ VdbeCoverageNeverNull(v);
+ }else if( pMWin->eExclude!=TK_NO ){
int addr;
- ExprList *pPart = pMWin->pPartition;
- int nPart = pPart->nExpr;
- int regNewPart = reg + pMWin->nBufferCol;
- KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
-
- addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart,nPart);
- sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
- sqlite3VdbeAddOp3(v, OP_Jump, addr+2, addr+4, addr+2);
- VdbeCoverageEqNe(v);
- sqlite3VdbeAddOp3(v, OP_Copy, regNewPart, pMWin->regPart, nPart-1);
- sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart);
- VdbeComment((v, "call flush_partition"));
- }
-
- /* Buffer the current row in the ephemeral table. */
- sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid);
- sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid);
-
- /* End of the input loop */
- sqlite3WhereEnd(pWInfo);
-
- /* Invoke "flush_partition" to deal with the final (or only) partition */
- sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart);
- VdbeComment((v, "call flush_partition"));
+ int addrEq = 0;
+ KeyInfo *pKeyInfo = 0;
+
+ if( pMWin->pOrderBy ){
+ pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pMWin->pOrderBy, 0, 0);
+ }
+ if( pMWin->eExclude==TK_TIES ){
+ addrEq = sqlite3VdbeAddOp3(v, OP_Eq, regCRowid, 0, regRowid);
+ VdbeCoverageNeverNull(v);
+ }
+ if( pKeyInfo ){
+ windowReadPeerValues(p, csr, regPeer);
+ sqlite3VdbeAddOp3(v, OP_Compare, regPeer, regCPeer, nPeer);
+ sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
+ addr = sqlite3VdbeCurrentAddr(v)+1;
+ sqlite3VdbeAddOp3(v, OP_Jump, addr, lblNext, addr);
+ VdbeCoverageEqNe(v);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, lblNext);
+ }
+ if( addrEq ) sqlite3VdbeJumpHere(v, addrEq);
+ }
+
+ windowAggStep(pParse, pMWin, csr, 0, p->regArg);
+
+ sqlite3VdbeResolveLabel(v, lblNext);
+ sqlite3VdbeAddOp2(v, OP_Next, csr, addrNext);
+ VdbeCoverage(v);
+ sqlite3VdbeJumpHere(v, addrNext-1);
+ sqlite3VdbeJumpHere(v, addrNext+1);
+ sqlite3ReleaseTempReg(pParse, regRowid);
+ sqlite3ReleaseTempReg(pParse, regCRowid);
+ if( nPeer ){
+ sqlite3ReleaseTempRange(pParse, regPeer, nPeer);
+ sqlite3ReleaseTempRange(pParse, regCPeer, nPeer);
+ }
+
+ windowAggFinal(p, 1);
}
/*
** Invoke the sub-routine at regGosub (generated by code in select.c) to
** return the current row of Window.iEphCsr. If all window functions are
@@ -1315,114 +1631,78 @@
** nth_value()
** first_value()
** lag()
** lead()
*/
-static void windowReturnOneRow(
- Parse *pParse,
- Window *pMWin,
- int regGosub,
- int addrGosub
-){
- Vdbe *v = sqlite3GetVdbe(pParse);
- Window *pWin;
- for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
- FuncDef *pFunc = pWin->pFunc;
- if( pFunc->zName==nth_valueName
- || pFunc->zName==first_valueName
- ){
- int csr = pWin->csrApp;
- int lbl = sqlite3VdbeMakeLabel(pParse);
- int tmpReg = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
-
- if( pFunc->zName==nth_valueName ){
- sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+1,tmpReg);
- windowCheckIntValue(pParse, tmpReg, 2);
- }else{
- sqlite3VdbeAddOp2(v, OP_Integer, 1, tmpReg);
- }
- sqlite3VdbeAddOp3(v, OP_Add, tmpReg, pWin->regApp, tmpReg);
- sqlite3VdbeAddOp3(v, OP_Gt, pWin->regApp+1, lbl, tmpReg);
- VdbeCoverageNeverNull(v);
- sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, 0, tmpReg);
- VdbeCoverageNeverTaken(v);
- sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
- sqlite3VdbeResolveLabel(v, lbl);
- sqlite3ReleaseTempReg(pParse, tmpReg);
- }
- else if( pFunc->zName==leadName || pFunc->zName==lagName ){
- int nArg = pWin->pOwner->x.pList->nExpr;
- int iEph = pMWin->iEphCsr;
- int csr = pWin->csrApp;
- int lbl = sqlite3VdbeMakeLabel(pParse);
- int tmpReg = sqlite3GetTempReg(pParse);
-
- if( nArg<3 ){
- sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
- }else{
- sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+2, pWin->regResult);
- }
- sqlite3VdbeAddOp2(v, OP_Rowid, iEph, tmpReg);
- if( nArg<2 ){
- int val = (pFunc->zName==leadName ? 1 : -1);
- sqlite3VdbeAddOp2(v, OP_AddImm, tmpReg, val);
- }else{
- int op = (pFunc->zName==leadName ? OP_Add : OP_Subtract);
- int tmpReg2 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+1, tmpReg2);
- sqlite3VdbeAddOp3(v, op, tmpReg2, tmpReg, tmpReg);
- sqlite3ReleaseTempReg(pParse, tmpReg2);
- }
-
- sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, lbl, tmpReg);
- VdbeCoverage(v);
- sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
- sqlite3VdbeResolveLabel(v, lbl);
- sqlite3ReleaseTempReg(pParse, tmpReg);
- }
- }
- sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
-}
-
-/*
-** Invoke the code generated by windowReturnOneRow() and, optionally, the
-** xInverse() function for each window function, for one or more rows
-** from the Window.iEphCsr temp table. This routine generates VM code
-** similar to:
-**
-** while( regCtr>0 ){
-** regCtr--;
-** windowReturnOneRow()
-** if( bInverse ){
-** AggInverse
-** }
-** Next (Window.iEphCsr)
-** }
-*/
-static void windowReturnRows(
- Parse *pParse,
- Window *pMWin, /* List of window functions */
- int regCtr, /* Register containing number of rows */
- int regGosub, /* Register for Gosub addrGosub */
- int addrGosub, /* Address of sub-routine for ReturnOneRow */
- int regInvArg, /* Array of registers for xInverse args */
- int regInvSize /* Register containing size of partition */
-){
- int addr;
- Vdbe *v = sqlite3GetVdbe(pParse);
- windowAggFinal(pParse, pMWin, 0);
- addr = sqlite3VdbeAddOp3(v, OP_IfPos, regCtr, sqlite3VdbeCurrentAddr(v)+2 ,1);
- VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
- windowReturnOneRow(pParse, pMWin, regGosub, addrGosub);
- if( regInvArg ){
- windowAggStep(pParse, pMWin, pMWin->iEphCsr, 1, regInvArg, regInvSize);
- }
- sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, addr);
- VdbeCoverage(v);
- sqlite3VdbeJumpHere(v, addr+1); /* The OP_Goto */
+static void windowReturnOneRow(WindowCodeArg *p){
+ Window *pMWin = p->pMWin;
+ Vdbe *v = p->pVdbe;
+
+ if( pMWin->regStartRowid ){
+ windowFullScan(p);
+ }else{
+ Parse *pParse = p->pParse;
+ Window *pWin;
+
+ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
+ FuncDef *pFunc = pWin->pFunc;
+ if( pFunc->zName==nth_valueName
+ || pFunc->zName==first_valueName
+ ){
+ int csr = pWin->csrApp;
+ int lbl = sqlite3VdbeMakeLabel(pParse);
+ int tmpReg = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
+
+ if( pFunc->zName==nth_valueName ){
+ sqlite3VdbeAddOp3(v, OP_Column,pMWin->iEphCsr,pWin->iArgCol+1,tmpReg);
+ windowCheckValue(pParse, tmpReg, 2);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Integer, 1, tmpReg);
+ }
+ sqlite3VdbeAddOp3(v, OP_Add, tmpReg, pWin->regApp, tmpReg);
+ sqlite3VdbeAddOp3(v, OP_Gt, pWin->regApp+1, lbl, tmpReg);
+ VdbeCoverageNeverNull(v);
+ sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, 0, tmpReg);
+ VdbeCoverageNeverTaken(v);
+ sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
+ sqlite3VdbeResolveLabel(v, lbl);
+ sqlite3ReleaseTempReg(pParse, tmpReg);
+ }
+ else if( pFunc->zName==leadName || pFunc->zName==lagName ){
+ int nArg = pWin->pOwner->x.pList->nExpr;
+ int csr = pWin->csrApp;
+ int lbl = sqlite3VdbeMakeLabel(pParse);
+ int tmpReg = sqlite3GetTempReg(pParse);
+ int iEph = pMWin->iEphCsr;
+
+ if( nArg<3 ){
+ sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
+ }else{
+ sqlite3VdbeAddOp3(v, OP_Column, iEph,pWin->iArgCol+2,pWin->regResult);
+ }
+ sqlite3VdbeAddOp2(v, OP_Rowid, iEph, tmpReg);
+ if( nArg<2 ){
+ int val = (pFunc->zName==leadName ? 1 : -1);
+ sqlite3VdbeAddOp2(v, OP_AddImm, tmpReg, val);
+ }else{
+ int op = (pFunc->zName==leadName ? OP_Add : OP_Subtract);
+ int tmpReg2 = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+1, tmpReg2);
+ sqlite3VdbeAddOp3(v, op, tmpReg2, tmpReg, tmpReg);
+ sqlite3ReleaseTempReg(pParse, tmpReg2);
+ }
+
+ sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, lbl, tmpReg);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
+ sqlite3VdbeResolveLabel(v, lbl);
+ sqlite3ReleaseTempReg(pParse, tmpReg);
+ }
+ }
+ }
+ sqlite3VdbeAddOp2(v, OP_Gosub, p->regGosub, p->addrGosub);
}
/*
** Generate code to set the accumulator register for each window function
** in the linked list passed as the second argument to NULL. And perform
@@ -1436,693 +1716,269 @@
Window *pWin;
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
FuncDef *pFunc = pWin->pFunc;
sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
nArg = MAX(nArg, windowArgCount(pWin));
- if( pFunc->zName==nth_valueName
- || pFunc->zName==first_valueName
- ){
- sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
- }
-
- if( (pFunc->funcFlags & SQLITE_FUNC_MINMAX) && pWin->csrApp ){
- assert( pWin->eStart!=TK_UNBOUNDED );
- sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
+ if( pMWin->regStartRowid==0 ){
+ if( pFunc->zName==nth_valueName || pFunc->zName==first_valueName ){
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp);
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
+ }
+
+ if( (pFunc->funcFlags & SQLITE_FUNC_MINMAX) && pWin->csrApp ){
+ assert( pWin->eStart!=TK_UNBOUNDED );
+ sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp);
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
+ }
}
}
regArg = pParse->nMem+1;
pParse->nMem += nArg;
return regArg;
}
-
-/*
-** This function does the work of sqlite3WindowCodeStep() for all "ROWS"
-** window frame types except for "BETWEEN UNBOUNDED PRECEDING AND CURRENT
-** ROW". Pseudo-code for each follows.
-**
-** ROWS BETWEEN PRECEDING AND FOLLOWING
-**
-** ...
-** if( new partition ){
-** Gosub flush_partition
-** }
-** Insert (record in eph-table)
-** sqlite3WhereEnd()
-** Gosub flush_partition
-**
-** flush_partition:
-** Once {
-** OpenDup (iEphCsr -> csrStart)
-** OpenDup (iEphCsr -> csrEnd)
-** }
-** regStart = // PRECEDING expression
-** regEnd = // FOLLOWING expression
-** if( regStart<0 || regEnd<0 ){ error! }
-** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done
-** Next(csrEnd) // if EOF skip Aggstep
-** Aggstep (csrEnd)
-** if( (regEnd--)<=0 ){
-** AggFinal (xValue)
-** Gosub addrGosub
-** Next(csr) // if EOF goto flush_partition_done
-** if( (regStart--)<=0 ){
-** AggInverse (csrStart)
-** Next(csrStart)
-** }
-** }
-** flush_partition_done:
-** ResetSorter (csr)
-** Return
-**
-** ROWS BETWEEN PRECEDING AND CURRENT ROW
-** ROWS BETWEEN CURRENT ROW AND FOLLOWING
-** ROWS BETWEEN UNBOUNDED PRECEDING AND FOLLOWING
-**
-** These are similar to the above. For "CURRENT ROW", intialize the
-** register to 0. For "UNBOUNDED PRECEDING" to infinity.
-**
-** ROWS BETWEEN PRECEDING AND UNBOUNDED FOLLOWING
-** ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
-**
-** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done
-** while( 1 ){
-** Next(csrEnd) // Exit while(1) at EOF
-** Aggstep (csrEnd)
-** }
-** while( 1 ){
-** AggFinal (xValue)
-** Gosub addrGosub
-** Next(csr) // if EOF goto flush_partition_done
-** if( (regStart--)<=0 ){
-** AggInverse (csrStart)
-** Next(csrStart)
-** }
-** }
-**
-** For the "CURRENT ROW AND UNBOUNDED FOLLOWING" case, the final if()
-** condition is always true (as if regStart were initialized to 0).
-**
-** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
-**
-** This is the only RANGE case handled by this routine. It modifies the
-** second while( 1 ) loop in "ROWS BETWEEN CURRENT ... UNBOUNDED..." to
-** be:
-**
-** while( 1 ){
-** AggFinal (xValue)
-** while( 1 ){
-** regPeer++
-** Gosub addrGosub
-** Next(csr) // if EOF goto flush_partition_done
-** if( new peer ) break;
-** }
-** while( (regPeer--)>0 ){
-** AggInverse (csrStart)
-** Next(csrStart)
-** }
-** }
-**
-** ROWS BETWEEN FOLLOWING AND FOLLOWING
-**
-** regEnd = regEnd - regStart
-** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done
-** Aggstep (csrEnd)
-** Next(csrEnd) // if EOF fall-through
-** if( (regEnd--)<=0 ){
-** if( (regStart--)<=0 ){
-** AggFinal (xValue)
-** Gosub addrGosub
-** Next(csr) // if EOF goto flush_partition_done
-** }
-** AggInverse (csrStart)
-** Next (csrStart)
-** }
-**
-** ROWS BETWEEN PRECEDING AND PRECEDING
-**
-** Replace the bit after "Rewind" in the above with:
-**
-** if( (regEnd--)<=0 ){
-** AggStep (csrEnd)
-** Next (csrEnd)
-** }
-** AggFinal (xValue)
-** Gosub addrGosub
-** Next(csr) // if EOF goto flush_partition_done
-** if( (regStart--)<=0 ){
-** AggInverse (csr2)
-** Next (csr2)
-** }
-**
-*/
-static void windowCodeRowExprStep(
- Parse *pParse,
- Select *p,
- WhereInfo *pWInfo,
- int regGosub,
- int addrGosub
-){
- Window *pMWin = p->pWin;
- Vdbe *v = sqlite3GetVdbe(pParse);
- int regFlushPart; /* Register for "Gosub flush_partition" */
- int lblFlushPart; /* Label for "Gosub flush_partition" */
- int lblFlushDone; /* Label for "Gosub flush_partition_done" */
-
- int regArg;
- int addr;
- int csrStart = pParse->nTab++;
- int csrEnd = pParse->nTab++;
- int regStart; /* Value of PRECEDING */
- int regEnd; /* Value of FOLLOWING */
- int addrGoto;
- int addrTop;
- int addrIfPos1 = 0;
- int addrIfPos2 = 0;
- int regSize = 0;
-
- assert( pMWin->eStart==TK_PRECEDING
- || pMWin->eStart==TK_CURRENT
- || pMWin->eStart==TK_FOLLOWING
- || pMWin->eStart==TK_UNBOUNDED
- );
- assert( pMWin->eEnd==TK_FOLLOWING
- || pMWin->eEnd==TK_CURRENT
- || pMWin->eEnd==TK_UNBOUNDED
- || pMWin->eEnd==TK_PRECEDING
- );
-
- /* Allocate register and label for the "flush_partition" sub-routine. */
- regFlushPart = ++pParse->nMem;
- lblFlushPart = sqlite3VdbeMakeLabel(pParse);
- lblFlushDone = sqlite3VdbeMakeLabel(pParse);
-
- regStart = ++pParse->nMem;
- regEnd = ++pParse->nMem;
-
- windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, ®Size);
-
- addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
-
- /* Start of "flush_partition" */
- sqlite3VdbeResolveLabel(v, lblFlushPart);
- sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+3);
- VdbeCoverage(v);
- VdbeComment((v, "Flush_partition subroutine"));
- sqlite3VdbeAddOp2(v, OP_OpenDup, csrStart, pMWin->iEphCsr);
- sqlite3VdbeAddOp2(v, OP_OpenDup, csrEnd, pMWin->iEphCsr);
-
- /* If either regStart or regEnd are not non-negative integers, throw
- ** an exception. */
- if( pMWin->pStart ){
- sqlite3ExprCode(pParse, pMWin->pStart, regStart);
- windowCheckIntValue(pParse, regStart, 0);
- }
- if( pMWin->pEnd ){
- sqlite3ExprCode(pParse, pMWin->pEnd, regEnd);
- windowCheckIntValue(pParse, regEnd, 1);
- }
-
- /* If this is "ROWS FOLLOWING AND ROWS FOLLOWING", do:
- **
- ** if( regEndpEnd && pMWin->eStart==TK_FOLLOWING ){
- assert( pMWin->pStart!=0 );
- assert( pMWin->eEnd==TK_FOLLOWING );
- sqlite3VdbeAddOp3(v, OP_Ge, regStart, sqlite3VdbeCurrentAddr(v)+2, regEnd);
- VdbeCoverageNeverNull(v);
- sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart);
- sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regEnd);
- }
-
- if( pMWin->pStart && pMWin->eEnd==TK_PRECEDING ){
- assert( pMWin->pEnd!=0 );
- assert( pMWin->eStart==TK_PRECEDING );
- sqlite3VdbeAddOp3(v, OP_Le, regStart, sqlite3VdbeCurrentAddr(v)+3, regEnd);
- VdbeCoverageNeverNull(v);
- sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart);
- sqlite3VdbeAddOp2(v, OP_Copy, regSize, regEnd);
- }
-
- /* Initialize the accumulator register for each window function to NULL */
- regArg = windowInitAccum(pParse, pMWin);
-
- sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr, lblFlushDone);
- VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Rewind, csrStart, lblFlushDone);
- VdbeCoverageNeverTaken(v);
- sqlite3VdbeChangeP5(v, 1);
- sqlite3VdbeAddOp2(v, OP_Rewind, csrEnd, lblFlushDone);
- VdbeCoverageNeverTaken(v);
- sqlite3VdbeChangeP5(v, 1);
-
- /* Invoke AggStep function for each window function using the row that
- ** csrEnd currently points to. Or, if csrEnd is already at EOF,
- ** do nothing. */
- addrTop = sqlite3VdbeCurrentAddr(v);
- if( pMWin->eEnd==TK_PRECEDING ){
- addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1);
- VdbeCoverage(v);
- }
- sqlite3VdbeAddOp2(v, OP_Next, csrEnd, sqlite3VdbeCurrentAddr(v)+2);
- VdbeCoverage(v);
- addr = sqlite3VdbeAddOp0(v, OP_Goto);
- windowAggStep(pParse, pMWin, csrEnd, 0, regArg, regSize);
- if( pMWin->eEnd==TK_UNBOUNDED ){
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
- sqlite3VdbeJumpHere(v, addr);
- addrTop = sqlite3VdbeCurrentAddr(v);
- }else{
- sqlite3VdbeJumpHere(v, addr);
- if( pMWin->eEnd==TK_PRECEDING ){
- sqlite3VdbeJumpHere(v, addrIfPos1);
- }
- }
-
- if( pMWin->eEnd==TK_FOLLOWING ){
- addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1);
- VdbeCoverage(v);
- }
- if( pMWin->eStart==TK_FOLLOWING ){
- addrIfPos2 = sqlite3VdbeAddOp3(v, OP_IfPos, regStart, 0 , 1);
- VdbeCoverage(v);
- }
- windowAggFinal(pParse, pMWin, 0);
- windowReturnOneRow(pParse, pMWin, regGosub, addrGosub);
- sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)+2);
- VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, lblFlushDone);
- if( pMWin->eStart==TK_FOLLOWING ){
- sqlite3VdbeJumpHere(v, addrIfPos2);
- }
-
- if( pMWin->eStart==TK_CURRENT
- || pMWin->eStart==TK_PRECEDING
- || pMWin->eStart==TK_FOLLOWING
- ){
- int lblSkipInverse = sqlite3VdbeMakeLabel(pParse);;
- if( pMWin->eStart==TK_PRECEDING ){
- sqlite3VdbeAddOp3(v, OP_IfPos, regStart, lblSkipInverse, 1);
- VdbeCoverage(v);
- }
- if( pMWin->eStart==TK_FOLLOWING ){
- sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+2);
- VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, lblSkipInverse);
- }else{
- sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+1);
- VdbeCoverageAlwaysTaken(v);
- }
- windowAggStep(pParse, pMWin, csrStart, 1, regArg, regSize);
- sqlite3VdbeResolveLabel(v, lblSkipInverse);
- }
- if( pMWin->eEnd==TK_FOLLOWING ){
- sqlite3VdbeJumpHere(v, addrIfPos1);
- }
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
-
- /* flush_partition_done: */
- sqlite3VdbeResolveLabel(v, lblFlushDone);
- sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
- sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);
- VdbeComment((v, "end flush_partition subroutine"));
-
- /* Jump to here to skip over flush_partition */
- sqlite3VdbeJumpHere(v, addrGoto);
-}
-
-/*
-** This function does the work of sqlite3WindowCodeStep() for cases that
-** would normally be handled by windowCodeDefaultStep() when there are
-** one or more built-in window-functions that require the entire partition
-** to be cached in a temp table before any rows can be returned. Additionally.
-** "RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING" is always handled by
-** this function.
-**
-** Pseudo-code corresponding to the VM code generated by this function
-** for each type of window follows.
-**
-** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
-**
-** flush_partition:
-** Once {
-** OpenDup (iEphCsr -> csrLead)
-** }
-** Integer ctr 0
-** foreach row (csrLead){
-** if( new peer ){
-** AggFinal (xValue)
-** for(i=0; i csrLead)
-** }
-** foreach row (csrLead) {
-** AggStep (csrLead)
-** }
-** foreach row (iEphCsr) {
-** Gosub addrGosub
-** }
-**
-** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
-**
-** flush_partition:
-** Once {
-** OpenDup (iEphCsr -> csrLead)
-** }
-** foreach row (csrLead){
-** AggStep (csrLead)
-** }
-** Rewind (csrLead)
-** Integer ctr 0
-** foreach row (csrLead){
-** if( new peer ){
-** AggFinal (xValue)
-** for(i=0; ipWin;
- Vdbe *v = sqlite3GetVdbe(pParse);
- int k;
- int addr;
- ExprList *pPart = pMWin->pPartition;
- ExprList *pOrderBy = pMWin->pOrderBy;
- int nPeer = pOrderBy ? pOrderBy->nExpr : 0;
- int regNewPeer;
-
- int addrGoto; /* Address of Goto used to jump flush_par.. */
- int addrNext; /* Jump here for next iteration of loop */
- int regFlushPart;
- int lblFlushPart;
- int csrLead;
- int regCtr;
- int regArg; /* Register array to martial function args */
- int regSize;
- int lblEmpty;
- int bReverse = pMWin->pOrderBy && pMWin->eStart==TK_CURRENT
- && pMWin->eEnd==TK_UNBOUNDED;
-
- assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT)
- || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED)
- || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT)
- || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED)
- );
-
- lblEmpty = sqlite3VdbeMakeLabel(pParse);
- regNewPeer = pParse->nMem+1;
- pParse->nMem += nPeer;
-
- /* Allocate register and label for the "flush_partition" sub-routine. */
- regFlushPart = ++pParse->nMem;
- lblFlushPart = sqlite3VdbeMakeLabel(pParse);
-
- csrLead = pParse->nTab++;
- regCtr = ++pParse->nMem;
-
- windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, ®Size);
- addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
-
- /* Start of "flush_partition" */
- sqlite3VdbeResolveLabel(v, lblFlushPart);
- sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+2);
- VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_OpenDup, csrLead, pMWin->iEphCsr);
-
- /* Initialize the accumulator register for each window function to NULL */
- regArg = windowInitAccum(pParse, pMWin);
-
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regCtr);
- sqlite3VdbeAddOp2(v, OP_Rewind, csrLead, lblEmpty);
- VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr, lblEmpty);
- VdbeCoverageNeverTaken(v);
-
- if( bReverse ){
- int addr2 = sqlite3VdbeCurrentAddr(v);
- windowAggStep(pParse, pMWin, csrLead, 0, regArg, regSize);
- sqlite3VdbeAddOp2(v, OP_Next, csrLead, addr2);
- VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Rewind, csrLead, lblEmpty);
- VdbeCoverageNeverTaken(v);
- }
- addrNext = sqlite3VdbeCurrentAddr(v);
-
- if( pOrderBy && (pMWin->eEnd==TK_CURRENT || pMWin->eStart==TK_CURRENT) ){
- int bCurrent = (pMWin->eStart==TK_CURRENT);
- int addrJump = 0; /* Address of OP_Jump below */
- if( pMWin->eType==TK_RANGE ){
- int iOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0);
- int regPeer = pMWin->regPart + (pPart ? pPart->nExpr : 0);
- KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);
- for(k=0; kiEphCsr);
- sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);
-
- /* Jump to here to skip over flush_partition */
- sqlite3VdbeJumpHere(v, addrGoto);
-}
-
-
-/*
-** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
-**
-** ...
-** if( new partition ){
-** AggFinal (xFinalize)
-** Gosub addrGosub
-** ResetSorter eph-table
-** }
-** else if( new peer ){
-** AggFinal (xValue)
-** Gosub addrGosub
-** ResetSorter eph-table
-** }
-** AggStep
-** Insert (record into eph-table)
-** sqlite3WhereEnd()
-** AggFinal (xFinalize)
-** Gosub addrGosub
-**
-** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
-**
-** As above, except take no action for a "new peer". Invoke
-** the sub-routine once only for each partition.
-**
-** RANGE BETWEEN CURRENT ROW AND CURRENT ROW
-**
-** As above, except that the "new peer" condition is handled in the
-** same way as "new partition" (so there is no "else if" block).
-**
-** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
-**
-** As above, except assume every row is a "new peer".
-*/
-static void windowCodeDefaultStep(
- Parse *pParse,
- Select *p,
- WhereInfo *pWInfo,
- int regGosub,
- int addrGosub
-){
- Window *pMWin = p->pWin;
- Vdbe *v = sqlite3GetVdbe(pParse);
- int k;
- int iSubCsr = p->pSrc->a[0].iCursor;
- int nSub = p->pSrc->a[0].pTab->nCol;
- int reg = pParse->nMem+1;
- int regRecord = reg+nSub;
- int regRowid = regRecord+1;
- int addr;
- ExprList *pPart = pMWin->pPartition;
- ExprList *pOrderBy = pMWin->pOrderBy;
-
- assert( pMWin->eType==TK_RANGE
- || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT)
- );
-
- assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT)
- || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED)
- || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT)
- || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED && !pOrderBy)
- );
-
- if( pMWin->eEnd==TK_UNBOUNDED ){
- pOrderBy = 0;
- }
-
- pParse->nMem += nSub + 2;
-
- /* Load the individual column values of the row returned by
- ** the sub-select into an array of registers. */
- for(k=0; knExpr : 0);
- int addrGoto = 0;
- int addrJump = 0;
- int nPeer = (pOrderBy ? pOrderBy->nExpr : 0);
-
- if( pPart ){
- int regNewPart = reg + pMWin->nBufferCol;
- KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
- addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart,nPart);
- sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
- addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
- VdbeCoverageEqNe(v);
- windowAggFinal(pParse, pMWin, 1);
- if( pOrderBy ){
- addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
- }
- }
-
- if( pOrderBy ){
- int regNewPeer = reg + pMWin->nBufferCol + nPart;
- int regPeer = pMWin->regPart + nPart;
-
- if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
- if( pMWin->eType==TK_RANGE ){
- KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);
- addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPeer, regPeer, nPeer);
- sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
- addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
- VdbeCoverage(v);
- }else{
- addrJump = 0;
- }
- windowAggFinal(pParse, pMWin, pMWin->eStart==TK_CURRENT);
- if( addrGoto ) sqlite3VdbeJumpHere(v, addrGoto);
- }
-
- sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3);
- VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
- sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1);
- VdbeCoverage(v);
-
- sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
- sqlite3VdbeAddOp3(
- v, OP_Copy, reg+pMWin->nBufferCol, pMWin->regPart, nPart+nPeer-1
- );
-
- if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
- }
-
- /* Invoke step function for window functions */
- windowAggStep(pParse, pMWin, -1, 0, reg, 0);
-
- /* Buffer the current row in the ephemeral table. */
- if( pMWin->nBufferCol>0 ){
- sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, pMWin->nBufferCol, regRecord);
- }else{
- sqlite3VdbeAddOp2(v, OP_Blob, 0, regRecord);
- sqlite3VdbeAppendP4(v, (void*)"", 0);
- }
- sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid);
- sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid);
-
- /* End the database scan loop. */
- sqlite3WhereEnd(pWInfo);
-
- windowAggFinal(pParse, pMWin, 1);
- sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3);
- VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
- sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1);
- VdbeCoverage(v);
-}
+/*
+** Return true if the current frame should be cached in the ephemeral table,
+** even if there are no xInverse() calls required.
+*/
+static int windowCacheFrame(Window *pMWin){
+ Window *pWin;
+ if( pMWin->regStartRowid ) return 1;
+ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
+ FuncDef *pFunc = pWin->pFunc;
+ if( (pFunc->zName==nth_valueName)
+ || (pFunc->zName==first_valueName)
+ || (pFunc->zName==leadName)
+ || (pFunc->zName==lagName)
+ ){
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*
+** regOld and regNew are each the first register in an array of size
+** pOrderBy->nExpr. This function generates code to compare the two
+** arrays of registers using the collation sequences and other comparison
+** parameters specified by pOrderBy.
+**
+** If the two arrays are not equal, the contents of regNew is copied to
+** regOld and control falls through. Otherwise, if the contents of the arrays
+** are equal, an OP_Goto is executed. The address of the OP_Goto is returned.
+*/
+static void windowIfNewPeer(
+ Parse *pParse,
+ ExprList *pOrderBy,
+ int regNew, /* First in array of new values */
+ int regOld, /* First in array of old values */
+ int addr /* Jump here */
+){
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ if( pOrderBy ){
+ int nVal = pOrderBy->nExpr;
+ KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);
+ sqlite3VdbeAddOp3(v, OP_Compare, regOld, regNew, nVal);
+ sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
+ sqlite3VdbeAddOp3(v, OP_Jump,
+ sqlite3VdbeCurrentAddr(v)+1, addr, sqlite3VdbeCurrentAddr(v)+1
+ );
+ VdbeCoverageEqNe(v);
+ sqlite3VdbeAddOp3(v, OP_Copy, regNew, regOld, nVal-1);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
+ }
+}
+
+/*
+** This function is called as part of generating VM programs for RANGE
+** offset PRECEDING/FOLLOWING frame boundaries. Assuming "ASC" order for
+** the ORDER BY term in the window, it generates code equivalent to:
+**
+** if( csr1.peerVal + regVal >= csr2.peerVal ) goto lbl;
+**
+** A special type of arithmetic is used such that if csr.peerVal is not
+** a numeric type (real or integer), then the result of the addition is
+** a copy of csr1.peerVal.
+*/
+static void windowCodeRangeTest(
+ WindowCodeArg *p,
+ int op, /* OP_Ge or OP_Gt */
+ int csr1,
+ int regVal,
+ int csr2,
+ int lbl
+){
+ Parse *pParse = p->pParse;
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ int reg1 = sqlite3GetTempReg(pParse);
+ int reg2 = sqlite3GetTempReg(pParse);
+ int arith = OP_Add;
+ int addrGe;
+
+ int regString = ++pParse->nMem;
+
+ assert( op==OP_Ge || op==OP_Gt || op==OP_Le );
+ assert( p->pMWin->pOrderBy && p->pMWin->pOrderBy->nExpr==1 );
+ if( p->pMWin->pOrderBy->a[0].sortOrder ){
+ switch( op ){
+ case OP_Ge: op = OP_Le; break;
+ case OP_Gt: op = OP_Lt; break;
+ default: assert( op==OP_Le ); op = OP_Ge; break;
+ }
+ arith = OP_Subtract;
+ }
+
+ windowReadPeerValues(p, csr1, reg1);
+ windowReadPeerValues(p, csr2, reg2);
+
+ /* Check if the peer value for csr1 value is a text or blob by comparing
+ ** it to the smallest possible string - ''. If it is, jump over the
+ ** OP_Add or OP_Subtract operation and proceed directly to the comparison. */
+ sqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC);
+ addrGe = sqlite3VdbeAddOp3(v, OP_Ge, regString, 0, reg1);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, arith, regVal, reg1, reg1);
+ sqlite3VdbeJumpHere(v, addrGe);
+ sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1); VdbeCoverage(v);
+ sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
+ assert( op==OP_Ge || op==OP_Gt || op==OP_Lt || op==OP_Le );
+ testcase(op==OP_Ge); VdbeCoverageIf(v, op==OP_Ge);
+ testcase(op==OP_Lt); VdbeCoverageIf(v, op==OP_Lt);
+ testcase(op==OP_Le); VdbeCoverageIf(v, op==OP_Le);
+ testcase(op==OP_Gt); VdbeCoverageIf(v, op==OP_Gt);
+
+ sqlite3ReleaseTempReg(pParse, reg1);
+ sqlite3ReleaseTempReg(pParse, reg2);
+}
+
+/*
+** Helper function for sqlite3WindowCodeStep(). Each call to this function
+** generates VM code for a single RETURN_ROW, AGGSTEP or AGGINVERSE
+** operation. Refer to the header comment for sqlite3WindowCodeStep() for
+** details.
+*/
+static int windowCodeOp(
+ WindowCodeArg *p, /* Context object */
+ int op, /* WINDOW_RETURN_ROW, AGGSTEP or AGGINVERSE */
+ int regCountdown, /* Register for OP_IfPos countdown */
+ int jumpOnEof /* Jump here if stepped cursor reaches EOF */
+){
+ int csr, reg;
+ Parse *pParse = p->pParse;
+ Window *pMWin = p->pMWin;
+ int ret = 0;
+ Vdbe *v = p->pVdbe;
+ int addrIf = 0;
+ int addrContinue = 0;
+ int addrGoto = 0;
+ int bPeer = (pMWin->eFrmType!=TK_ROWS);
+
+ int lblDone = sqlite3VdbeMakeLabel(pParse);
+ int addrNextRange = 0;
+
+ /* Special case - WINDOW_AGGINVERSE is always a no-op if the frame
+ ** starts with UNBOUNDED PRECEDING. */
+ if( op==WINDOW_AGGINVERSE && pMWin->eStart==TK_UNBOUNDED ){
+ assert( regCountdown==0 && jumpOnEof==0 );
+ return 0;
+ }
+
+ if( regCountdown>0 ){
+ if( pMWin->eFrmType==TK_RANGE ){
+ addrNextRange = sqlite3VdbeCurrentAddr(v);
+ assert( op==WINDOW_AGGINVERSE || op==WINDOW_AGGSTEP );
+ if( op==WINDOW_AGGINVERSE ){
+ if( pMWin->eStart==TK_FOLLOWING ){
+ windowCodeRangeTest(
+ p, OP_Le, p->current.csr, regCountdown, p->start.csr, lblDone
+ );
+ }else{
+ windowCodeRangeTest(
+ p, OP_Ge, p->start.csr, regCountdown, p->current.csr, lblDone
+ );
+ }
+ }else{
+ windowCodeRangeTest(
+ p, OP_Gt, p->end.csr, regCountdown, p->current.csr, lblDone
+ );
+ }
+ }else{
+ addrIf = sqlite3VdbeAddOp3(v, OP_IfPos, regCountdown, 0, 1);
+ VdbeCoverage(v);
+ }
+ }
+
+ if( op==WINDOW_RETURN_ROW && pMWin->regStartRowid==0 ){
+ windowAggFinal(p, 0);
+ }
+ addrContinue = sqlite3VdbeCurrentAddr(v);
+ switch( op ){
+ case WINDOW_RETURN_ROW:
+ csr = p->current.csr;
+ reg = p->current.reg;
+ windowReturnOneRow(p);
+ break;
+
+ case WINDOW_AGGINVERSE:
+ csr = p->start.csr;
+ reg = p->start.reg;
+ if( pMWin->regStartRowid ){
+ assert( pMWin->regEndRowid );
+ sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regStartRowid, 1);
+ }else{
+ windowAggStep(pParse, pMWin, csr, 1, p->regArg);
+ }
+ break;
+
+ default:
+ assert( op==WINDOW_AGGSTEP );
+ csr = p->end.csr;
+ reg = p->end.reg;
+ if( pMWin->regStartRowid ){
+ assert( pMWin->regEndRowid );
+ sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regEndRowid, 1);
+ }else{
+ windowAggStep(pParse, pMWin, csr, 0, p->regArg);
+ }
+ break;
+ }
+
+ if( op==p->eDelete ){
+ sqlite3VdbeAddOp1(v, OP_Delete, csr);
+ sqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION);
+ }
+
+ if( jumpOnEof ){
+ sqlite3VdbeAddOp2(v, OP_Next, csr, sqlite3VdbeCurrentAddr(v)+2);
+ VdbeCoverage(v);
+ ret = sqlite3VdbeAddOp0(v, OP_Goto);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Next, csr, sqlite3VdbeCurrentAddr(v)+1+bPeer);
+ VdbeCoverage(v);
+ if( bPeer ){
+ addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
+ }
+ }
+
+ if( bPeer ){
+ int nReg = (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);
+ int regTmp = (nReg ? sqlite3GetTempRange(pParse, nReg) : 0);
+ windowReadPeerValues(p, csr, regTmp);
+ windowIfNewPeer(pParse, pMWin->pOrderBy, regTmp, reg, addrContinue);
+ sqlite3ReleaseTempRange(pParse, regTmp, nReg);
+ }
+
+ if( addrNextRange ){
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNextRange);
+ }
+ sqlite3VdbeResolveLabel(v, lblDone);
+ if( addrGoto ) sqlite3VdbeJumpHere(v, addrGoto);
+ if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
+ return ret;
+}
+
/*
** Allocate and return a duplicate of the Window object indicated by the
** third argument. Set the Window.pOwner field of the new object to
** pOwner.
@@ -2135,13 +1991,14 @@
pNew->zName = sqlite3DbStrDup(db, p->zName);
pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
pNew->pFunc = p->pFunc;
pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
- pNew->eType = p->eType;
+ pNew->eFrmType = p->eFrmType;
pNew->eEnd = p->eEnd;
pNew->eStart = p->eStart;
+ pNew->eExclude = p->eExclude;
pNew->pStart = sqlite3ExprDup(db, p->pStart, 0);
pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0);
pNew->pOwner = pOwner;
}
}
@@ -2163,94 +2020,679 @@
pp = &((*pp)->pNextWin);
}
return pRet;
}
+
+/*
+** Return true if it can be determined at compile time that expression
+** pExpr evaluates to a value that, when cast to an integer, is greater
+** than zero. False otherwise.
+**
+** If an OOM error occurs, this function sets the Parse.db.mallocFailed
+** flag and returns zero.
+*/
+static int windowExprGtZero(Parse *pParse, Expr *pExpr){
+ int ret = 0;
+ sqlite3 *db = pParse->db;
+ sqlite3_value *pVal = 0;
+ sqlite3ValueFromExpr(db, pExpr, db->enc, SQLITE_AFF_NUMERIC, &pVal);
+ if( pVal && sqlite3_value_int(pVal)>0 ){
+ ret = 1;
+ }
+ sqlite3ValueFree(pVal);
+ return ret;
+}
/*
** sqlite3WhereBegin() has already been called for the SELECT statement
** passed as the second argument when this function is invoked. It generates
-** code to populate the Window.regResult register for each window function and
-** invoke the sub-routine at instruction addrGosub once for each row.
-** This function calls sqlite3WhereEnd() before returning.
+** code to populate the Window.regResult register for each window function
+** and invoke the sub-routine at instruction addrGosub once for each row.
+** sqlite3WhereEnd() is always called before returning.
+**
+** This function handles several different types of window frames, which
+** require slightly different processing. The following pseudo code is
+** used to implement window frames of the form:
+**
+** ROWS BETWEEN PRECEDING AND FOLLOWING
+**
+** Other window frame types use variants of the following:
+**
+** ... loop started by sqlite3WhereBegin() ...
+** if( new partition ){
+** Gosub flush
+** }
+** Insert new row into eph table.
+**
+** if( first row of partition ){
+** // Rewind three cursors, all open on the eph table.
+** Rewind(csrEnd);
+** Rewind(csrStart);
+** Rewind(csrCurrent);
+**
+** regEnd = // FOLLOWING expression
+** regStart = // PRECEDING expression
+** }else{
+** // First time this branch is taken, the eph table contains two
+** // rows. The first row in the partition, which all three cursors
+** // currently point to, and the following row.
+** AGGSTEP
+** if( (regEnd--)<=0 ){
+** RETURN_ROW
+** if( (regStart--)<=0 ){
+** AGGINVERSE
+** }
+** }
+** }
+** }
+** flush:
+** AGGSTEP
+** while( 1 ){
+** RETURN ROW
+** if( csrCurrent is EOF ) break;
+** if( (regStart--)<=0 ){
+** AggInverse(csrStart)
+** Next(csrStart)
+** }
+** }
+**
+** The pseudo-code above uses the following shorthand:
+**
+** AGGSTEP: invoke the aggregate xStep() function for each window function
+** with arguments read from the current row of cursor csrEnd, then
+** step cursor csrEnd forward one row (i.e. sqlite3BtreeNext()).
+**
+** RETURN_ROW: return a row to the caller based on the contents of the
+** current row of csrCurrent and the current state of all
+** aggregates. Then step cursor csrCurrent forward one row.
+**
+** AGGINVERSE: invoke the aggregate xInverse() function for each window
+** functions with arguments read from the current row of cursor
+** csrStart. Then step csrStart forward one row.
+**
+** There are two other ROWS window frames that are handled significantly
+** differently from the above - "BETWEEN PRECEDING AND PRECEDING"
+** and "BETWEEN FOLLOWING AND FOLLOWING". These are special
+** cases because they change the order in which the three cursors (csrStart,
+** csrCurrent and csrEnd) iterate through the ephemeral table. Cases that
+** use UNBOUNDED or CURRENT ROW are much simpler variations on one of these
+** three.
+**
+** ROWS BETWEEN PRECEDING AND PRECEDING
+**
+** ... loop started by sqlite3WhereBegin() ...
+** if( new partition ){
+** Gosub flush
+** }
+** Insert new row into eph table.
+** if( first row of partition ){
+** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
+** regEnd =
+** regStart =
+** }else{
+** if( (regEnd--)<=0 ){
+** AGGSTEP
+** }
+** RETURN_ROW
+** if( (regStart--)<=0 ){
+** AGGINVERSE
+** }
+** }
+** }
+** flush:
+** if( (regEnd--)<=0 ){
+** AGGSTEP
+** }
+** RETURN_ROW
+**
+**
+** ROWS BETWEEN FOLLOWING AND FOLLOWING
+**
+** ... loop started by sqlite3WhereBegin() ...
+** if( new partition ){
+** Gosub flush
+** }
+** Insert new row into eph table.
+** if( first row of partition ){
+** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
+** regEnd =
+** regStart = regEnd -
+** }else{
+** AGGSTEP
+** if( (regEnd--)<=0 ){
+** RETURN_ROW
+** }
+** if( (regStart--)<=0 ){
+** AGGINVERSE
+** }
+** }
+** }
+** flush:
+** AGGSTEP
+** while( 1 ){
+** if( (regEnd--)<=0 ){
+** RETURN_ROW
+** if( eof ) break;
+** }
+** if( (regStart--)<=0 ){
+** AGGINVERSE
+** if( eof ) break
+** }
+** }
+** while( !eof csrCurrent ){
+** RETURN_ROW
+** }
+**
+** For the most part, the patterns above are adapted to support UNBOUNDED by
+** assuming that it is equivalent to "infinity PRECEDING/FOLLOWING" and
+** CURRENT ROW by assuming that it is equivilent to "0 PRECEDING/FOLLOWING".
+** This is optimized of course - branches that will never be taken and
+** conditions that are always true are omitted from the VM code. The only
+** exceptional case is:
+**
+** ROWS BETWEEN FOLLOWING AND UNBOUNDED FOLLOWING
+**
+** ... loop started by sqlite3WhereBegin() ...
+** if( new partition ){
+** Gosub flush
+** }
+** Insert new row into eph table.
+** if( first row of partition ){
+** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
+** regStart =
+** }else{
+** AGGSTEP
+** }
+** }
+** flush:
+** AGGSTEP
+** while( 1 ){
+** if( (regStart--)<=0 ){
+** AGGINVERSE
+** if( eof ) break
+** }
+** RETURN_ROW
+** }
+** while( !eof csrCurrent ){
+** RETURN_ROW
+** }
+**
+** Also requiring special handling are the cases:
+**
+** ROWS BETWEEN PRECEDING AND PRECEDING
+** ROWS BETWEEN FOLLOWING AND FOLLOWING
+**
+** when (expr1 < expr2). This is detected at runtime, not by this function.
+** To handle this case, the pseudo-code programs depicted above are modified
+** slightly to be:
+**
+** ... loop started by sqlite3WhereBegin() ...
+** if( new partition ){
+** Gosub flush
+** }
+** Insert new row into eph table.
+** if( first row of partition ){
+** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
+** regEnd =
+** regStart =
+** if( regEnd < regStart ){
+** RETURN_ROW
+** delete eph table contents
+** continue
+** }
+** ...
+**
+** The new "continue" statement in the above jumps to the next iteration
+** of the outer loop - the one started by sqlite3WhereBegin().
+**
+** The various GROUPS cases are implemented using the same patterns as
+** ROWS. The VM code is modified slightly so that:
+**
+** 1. The else branch in the main loop is only taken if the row just
+** added to the ephemeral table is the start of a new group. In
+** other words, it becomes:
+**
+** ... loop started by sqlite3WhereBegin() ...
+** if( new partition ){
+** Gosub flush
+** }
+** Insert new row into eph table.
+** if( first row of partition ){
+** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
+** regEnd =
+** regStart =
+** }else if( new group ){
+** ...
+** }
+** }
+**
+** 2. Instead of processing a single row, each RETURN_ROW, AGGSTEP or
+** AGGINVERSE step processes the current row of the relevant cursor and
+** all subsequent rows belonging to the same group.
+**
+** RANGE window frames are a little different again. As for GROUPS, the
+** main loop runs once per group only. And RETURN_ROW, AGGSTEP and AGGINVERSE
+** deal in groups instead of rows. As for ROWS and GROUPS, there are three
+** basic cases:
+**
+** RANGE BETWEEN PRECEDING AND FOLLOWING
+**
+** ... loop started by sqlite3WhereBegin() ...
+** if( new partition ){
+** Gosub flush
+** }
+** Insert new row into eph table.
+** if( first row of partition ){
+** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
+** regEnd =
+** regStart =
+** }else{
+** AGGSTEP
+** while( (csrCurrent.key + regEnd) < csrEnd.key ){
+** RETURN_ROW
+** while( csrStart.key + regStart) < csrCurrent.key ){
+** AGGINVERSE
+** }
+** }
+** }
+** }
+** flush:
+** AGGSTEP
+** while( 1 ){
+** RETURN ROW
+** if( csrCurrent is EOF ) break;
+** while( csrStart.key + regStart) < csrCurrent.key ){
+** AGGINVERSE
+** }
+** }
+** }
+**
+** In the above notation, "csr.key" means the current value of the ORDER BY
+** expression (there is only ever 1 for a RANGE that uses an FOLLOWING
+** or PRECEDING AND PRECEDING
+**
+** ... loop started by sqlite3WhereBegin() ...
+** if( new partition ){
+** Gosub flush
+** }
+** Insert new row into eph table.
+** if( first row of partition ){
+** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
+** regEnd =
+** regStart =
+** }else{
+** while( (csrEnd.key + regEnd) <= csrCurrent.key ){
+** AGGSTEP
+** }
+** RETURN_ROW
+** while( (csrStart.key + regStart) < csrCurrent.key ){
+** AGGINVERSE
+** }
+** }
+** }
+** flush:
+** while( (csrEnd.key + regEnd) <= csrCurrent.key ){
+** AGGSTEP
+** }
+** RETURN_ROW
+**
+** RANGE BETWEEN FOLLOWING AND FOLLOWING
+**
+** ... loop started by sqlite3WhereBegin() ...
+** if( new partition ){
+** Gosub flush
+** }
+** Insert new row into eph table.
+** if( first row of partition ){
+** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
+** regEnd =
+** regStart =
+** }else{
+** AGGSTEP
+** while( (csrCurrent.key + regEnd) < csrEnd.key ){
+** while( (csrCurrent.key + regStart) > csrStart.key ){
+** AGGINVERSE
+** }
+** RETURN_ROW
+** }
+** }
+** }
+** flush:
+** AGGSTEP
+** while( 1 ){
+** while( (csrCurrent.key + regStart) > csrStart.key ){
+** AGGINVERSE
+** if( eof ) break "while( 1 )" loop.
+** }
+** RETURN_ROW
+** }
+** while( !eof csrCurrent ){
+** RETURN_ROW
+** }
+**
+** The text above leaves out many details. Refer to the code and comments
+** below for a more complete picture.
*/
void sqlite3WindowCodeStep(
Parse *pParse, /* Parse context */
Select *p, /* Rewritten SELECT statement */
WhereInfo *pWInfo, /* Context returned by sqlite3WhereBegin() */
int regGosub, /* Register for OP_Gosub */
int addrGosub /* OP_Gosub here to return each row */
){
Window *pMWin = p->pWin;
-
- /* There are three different functions that may be used to do the work
- ** of this one, depending on the window frame and the specific built-in
- ** window functions used (if any).
- **
- ** windowCodeRowExprStep() handles all "ROWS" window frames, except for:
- **
- ** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
- **
- ** The exception is because windowCodeRowExprStep() implements all window
- ** frame types by caching the entire partition in a temp table, and
- ** "ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW" is easy enough to
- ** implement without such a cache.
- **
- ** windowCodeCacheStep() is used for:
- **
- ** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
- **
- ** It is also used for anything not handled by windowCodeRowExprStep()
- ** that invokes a built-in window function that requires the entire
- ** partition to be cached in a temp table before any rows are returned
- ** (e.g. nth_value() or percent_rank()).
- **
- ** Finally, assuming there is no built-in window function that requires
- ** the partition to be cached, windowCodeDefaultStep() is used for:
- **
- ** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
- ** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
- ** RANGE BETWEEN CURRENT ROW AND CURRENT ROW
- ** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
- **
- ** windowCodeDefaultStep() is the only one of the three functions that
- ** does not cache each partition in a temp table before beginning to
- ** return rows.
- */
- if( pMWin->eType==TK_ROWS
- && (pMWin->eStart!=TK_UNBOUNDED||pMWin->eEnd!=TK_CURRENT||!pMWin->pOrderBy)
- ){
- VdbeModuleComment((pParse->pVdbe, "Begin RowExprStep()"));
- windowCodeRowExprStep(pParse, p, pWInfo, regGosub, addrGosub);
- }else{
- Window *pWin;
- int bCache = 0; /* True to use CacheStep() */
-
- if( pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED ){
- bCache = 1;
- }else{
- for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
- FuncDef *pFunc = pWin->pFunc;
- if( (pFunc->funcFlags & SQLITE_FUNC_WINDOW_SIZE)
- || (pFunc->zName==nth_valueName)
- || (pFunc->zName==first_valueName)
- || (pFunc->zName==leadName)
- || (pFunc->zName==lagName)
- ){
- bCache = 1;
- break;
- }
- }
- }
-
- /* Otherwise, call windowCodeDefaultStep(). */
- if( bCache ){
- VdbeModuleComment((pParse->pVdbe, "Begin CacheStep()"));
- windowCodeCacheStep(pParse, p, pWInfo, regGosub, addrGosub);
- }else{
- VdbeModuleComment((pParse->pVdbe, "Begin DefaultStep()"));
- windowCodeDefaultStep(pParse, p, pWInfo, regGosub, addrGosub);
- }
+ ExprList *pOrderBy = pMWin->pOrderBy;
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ int csrWrite; /* Cursor used to write to eph. table */
+ int csrInput = p->pSrc->a[0].iCursor; /* Cursor of sub-select */
+ int nInput = p->pSrc->a[0].pTab->nCol; /* Number of cols returned by sub */
+ int iInput; /* To iterate through sub cols */
+ int addrNe; /* Address of OP_Ne */
+ int addrGosubFlush = 0; /* Address of OP_Gosub to flush: */
+ int addrInteger = 0; /* Address of OP_Integer */
+ int addrEmpty; /* Address of OP_Rewind in flush: */
+ int regStart = 0; /* Value of PRECEDING */
+ int regEnd = 0; /* Value of FOLLOWING */
+ int regNew; /* Array of registers holding new input row */
+ int regRecord; /* regNew array in record form */
+ int regRowid; /* Rowid for regRecord in eph table */
+ int regNewPeer = 0; /* Peer values for new row (part of regNew) */
+ int regPeer = 0; /* Peer values for current row */
+ int regFlushPart = 0; /* Register for "Gosub flush_partition" */
+ WindowCodeArg s; /* Context object for sub-routines */
+ int lblWhereEnd; /* Label just before sqlite3WhereEnd() code */
+
+ assert( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_CURRENT
+ || pMWin->eStart==TK_FOLLOWING || pMWin->eStart==TK_UNBOUNDED
+ );
+ assert( pMWin->eEnd==TK_FOLLOWING || pMWin->eEnd==TK_CURRENT
+ || pMWin->eEnd==TK_UNBOUNDED || pMWin->eEnd==TK_PRECEDING
+ );
+ assert( pMWin->eExclude==0 || pMWin->eExclude==TK_CURRENT
+ || pMWin->eExclude==TK_GROUP || pMWin->eExclude==TK_TIES
+ || pMWin->eExclude==TK_NO
+ );
+
+ lblWhereEnd = sqlite3VdbeMakeLabel(pParse);
+
+ /* Fill in the context object */
+ memset(&s, 0, sizeof(WindowCodeArg));
+ s.pParse = pParse;
+ s.pMWin = pMWin;
+ s.pVdbe = v;
+ s.regGosub = regGosub;
+ s.addrGosub = addrGosub;
+ s.current.csr = pMWin->iEphCsr;
+ csrWrite = s.current.csr+1;
+ s.start.csr = s.current.csr+2;
+ s.end.csr = s.current.csr+3;
+
+ /* Figure out when rows may be deleted from the ephemeral table. There
+ ** are four options - they may never be deleted (eDelete==0), they may
+ ** be deleted as soon as they are no longer part of the window frame
+ ** (eDelete==WINDOW_AGGINVERSE), they may be deleted as after the row
+ ** has been returned to the caller (WINDOW_RETURN_ROW), or they may
+ ** be deleted after they enter the frame (WINDOW_AGGSTEP). */
+ switch( pMWin->eStart ){
+ case TK_FOLLOWING:
+ if( pMWin->eFrmType!=TK_RANGE
+ && windowExprGtZero(pParse, pMWin->pStart)
+ ){
+ s.eDelete = WINDOW_RETURN_ROW;
+ }
+ break;
+ case TK_UNBOUNDED:
+ if( windowCacheFrame(pMWin)==0 ){
+ if( pMWin->eEnd==TK_PRECEDING ){
+ if( pMWin->eFrmType!=TK_RANGE
+ && windowExprGtZero(pParse, pMWin->pEnd)
+ ){
+ s.eDelete = WINDOW_AGGSTEP;
+ }
+ }else{
+ s.eDelete = WINDOW_RETURN_ROW;
+ }
+ }
+ break;
+ default:
+ s.eDelete = WINDOW_AGGINVERSE;
+ break;
+ }
+
+ /* Allocate registers for the array of values from the sub-query, the
+ ** samve values in record form, and the rowid used to insert said record
+ ** into the ephemeral table. */
+ regNew = pParse->nMem+1;
+ pParse->nMem += nInput;
+ regRecord = ++pParse->nMem;
+ regRowid = ++pParse->nMem;
+
+ /* If the window frame contains an " PRECEDING" or " FOLLOWING"
+ ** clause, allocate registers to store the results of evaluating each
+ ** . */
+ if( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_FOLLOWING ){
+ regStart = ++pParse->nMem;
+ }
+ if( pMWin->eEnd==TK_PRECEDING || pMWin->eEnd==TK_FOLLOWING ){
+ regEnd = ++pParse->nMem;
+ }
+
+ /* If this is not a "ROWS BETWEEN ..." frame, then allocate arrays of
+ ** registers to store copies of the ORDER BY expressions (peer values)
+ ** for the main loop, and for each cursor (start, current and end). */
+ if( pMWin->eFrmType!=TK_ROWS ){
+ int nPeer = (pOrderBy ? pOrderBy->nExpr : 0);
+ regNewPeer = regNew + pMWin->nBufferCol;
+ if( pMWin->pPartition ) regNewPeer += pMWin->pPartition->nExpr;
+ regPeer = pParse->nMem+1; pParse->nMem += nPeer;
+ s.start.reg = pParse->nMem+1; pParse->nMem += nPeer;
+ s.current.reg = pParse->nMem+1; pParse->nMem += nPeer;
+ s.end.reg = pParse->nMem+1; pParse->nMem += nPeer;
+ }
+
+ /* Load the column values for the row returned by the sub-select
+ ** into an array of registers starting at regNew. Assemble them into
+ ** a record in register regRecord. */
+ for(iInput=0; iInputpPartition ){
+ int addr;
+ ExprList *pPart = pMWin->pPartition;
+ int nPart = pPart->nExpr;
+ int regNewPart = regNew + pMWin->nBufferCol;
+ KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
+
+ regFlushPart = ++pParse->nMem;
+ addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart, nPart);
+ sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
+ sqlite3VdbeAddOp3(v, OP_Jump, addr+2, addr+4, addr+2);
+ VdbeCoverageEqNe(v);
+ addrGosubFlush = sqlite3VdbeAddOp1(v, OP_Gosub, regFlushPart);
+ VdbeComment((v, "call flush_partition"));
+ sqlite3VdbeAddOp3(v, OP_Copy, regNewPart, pMWin->regPart, nPart-1);
+ }
+
+ /* Insert the new row into the ephemeral table */
+ sqlite3VdbeAddOp2(v, OP_NewRowid, csrWrite, regRowid);
+ sqlite3VdbeAddOp3(v, OP_Insert, csrWrite, regRecord, regRowid);
+ addrNe = sqlite3VdbeAddOp3(v, OP_Ne, pMWin->regOne, 0, regRowid);
+ VdbeCoverageNeverNull(v);
+
+ /* This block is run for the first row of each partition */
+ s.regArg = windowInitAccum(pParse, pMWin);
+
+ if( regStart ){
+ sqlite3ExprCode(pParse, pMWin->pStart, regStart);
+ windowCheckValue(pParse, regStart, 0 + (pMWin->eFrmType==TK_RANGE ? 3 : 0));
+ }
+ if( regEnd ){
+ sqlite3ExprCode(pParse, pMWin->pEnd, regEnd);
+ windowCheckValue(pParse, regEnd, 1 + (pMWin->eFrmType==TK_RANGE ? 3 : 0));
+ }
+
+ if( pMWin->eStart==pMWin->eEnd && regStart ){
+ int op = ((pMWin->eStart==TK_FOLLOWING) ? OP_Ge : OP_Le);
+ int addrGe = sqlite3VdbeAddOp3(v, op, regStart, 0, regEnd);
+ VdbeCoverageNeverNullIf(v, op==OP_Ge); /* NeverNull because bound */
+ VdbeCoverageNeverNullIf(v, op==OP_Le); /* values previously checked */
+ windowAggFinal(&s, 0);
+ sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1);
+ VdbeCoverageNeverTaken(v);
+ windowReturnOneRow(&s);
+ sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr);
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd);
+ sqlite3VdbeJumpHere(v, addrGe);
+ }
+ if( pMWin->eStart==TK_FOLLOWING && pMWin->eFrmType!=TK_RANGE && regEnd ){
+ assert( pMWin->eEnd==TK_FOLLOWING );
+ sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regStart);
+ }
+
+ if( pMWin->eStart!=TK_UNBOUNDED ){
+ sqlite3VdbeAddOp2(v, OP_Rewind, s.start.csr, 1);
+ VdbeCoverageNeverTaken(v);
+ }
+ sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1);
+ VdbeCoverageNeverTaken(v);
+ sqlite3VdbeAddOp2(v, OP_Rewind, s.end.csr, 1);
+ VdbeCoverageNeverTaken(v);
+ if( regPeer && pOrderBy ){
+ sqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, pOrderBy->nExpr-1);
+ sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.start.reg, pOrderBy->nExpr-1);
+ sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.current.reg, pOrderBy->nExpr-1);
+ sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.end.reg, pOrderBy->nExpr-1);
+ }
+
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd);
+
+ sqlite3VdbeJumpHere(v, addrNe);
+ if( regPeer ){
+ windowIfNewPeer(pParse, pOrderBy, regNewPeer, regPeer, lblWhereEnd);
+ }
+ if( pMWin->eStart==TK_FOLLOWING ){
+ windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
+ if( pMWin->eEnd!=TK_UNBOUNDED ){
+ if( pMWin->eFrmType==TK_RANGE ){
+ int lbl = sqlite3VdbeMakeLabel(pParse);
+ int addrNext = sqlite3VdbeCurrentAddr(v);
+ windowCodeRangeTest(&s, OP_Ge, s.current.csr, regEnd, s.end.csr, lbl);
+ windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
+ windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext);
+ sqlite3VdbeResolveLabel(v, lbl);
+ }else{
+ windowCodeOp(&s, WINDOW_RETURN_ROW, regEnd, 0);
+ windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
+ }
+ }
+ }else
+ if( pMWin->eEnd==TK_PRECEDING ){
+ windowCodeOp(&s, WINDOW_AGGSTEP, regEnd, 0);
+ windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
+ windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
+ }else{
+ int addr = 0;
+ windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
+ if( pMWin->eEnd!=TK_UNBOUNDED ){
+ if( pMWin->eFrmType==TK_RANGE ){
+ int lbl = 0;
+ addr = sqlite3VdbeCurrentAddr(v);
+ if( regEnd ){
+ lbl = sqlite3VdbeMakeLabel(pParse);
+ windowCodeRangeTest(&s, OP_Ge, s.current.csr, regEnd, s.end.csr, lbl);
+ }
+ windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
+ windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
+ if( regEnd ){
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
+ sqlite3VdbeResolveLabel(v, lbl);
+ }
+ }else{
+ if( regEnd ){
+ addr = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0, 1);
+ VdbeCoverage(v);
+ }
+ windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
+ windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
+ if( regEnd ) sqlite3VdbeJumpHere(v, addr);
+ }
+ }
+ }
+
+ /* End of the main input loop */
+ sqlite3VdbeResolveLabel(v, lblWhereEnd);
+ sqlite3WhereEnd(pWInfo);
+
+ /* Fall through */
+ if( pMWin->pPartition ){
+ addrInteger = sqlite3VdbeAddOp2(v, OP_Integer, 0, regFlushPart);
+ sqlite3VdbeJumpHere(v, addrGosubFlush);
+ }
+
+ addrEmpty = sqlite3VdbeAddOp1(v, OP_Rewind, csrWrite);
+ VdbeCoverage(v);
+ if( pMWin->eEnd==TK_PRECEDING ){
+ windowCodeOp(&s, WINDOW_AGGSTEP, regEnd, 0);
+ windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
+ }else if( pMWin->eStart==TK_FOLLOWING ){
+ int addrStart;
+ int addrBreak1;
+ int addrBreak2;
+ int addrBreak3;
+ windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
+ if( pMWin->eFrmType==TK_RANGE ){
+ addrStart = sqlite3VdbeCurrentAddr(v);
+ addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 1);
+ addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1);
+ }else
+ if( pMWin->eEnd==TK_UNBOUNDED ){
+ addrStart = sqlite3VdbeCurrentAddr(v);
+ addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, regStart, 1);
+ addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, 0, 1);
+ }else{
+ assert( pMWin->eEnd==TK_FOLLOWING );
+ addrStart = sqlite3VdbeCurrentAddr(v);
+ addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, regEnd, 1);
+ addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 1);
+ }
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart);
+ sqlite3VdbeJumpHere(v, addrBreak2);
+ addrStart = sqlite3VdbeCurrentAddr(v);
+ addrBreak3 = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1);
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart);
+ sqlite3VdbeJumpHere(v, addrBreak1);
+ sqlite3VdbeJumpHere(v, addrBreak3);
+ }else{
+ int addrBreak;
+ int addrStart;
+ windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
+ addrStart = sqlite3VdbeCurrentAddr(v);
+ addrBreak = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1);
+ windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart);
+ sqlite3VdbeJumpHere(v, addrBreak);
+ }
+ sqlite3VdbeJumpHere(v, addrEmpty);
+
+ sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr);
+ if( pMWin->pPartition ){
+ if( pMWin->regStartRowid ){
+ sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regStartRowid);
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regEndRowid);
+ }
+ sqlite3VdbeChangeP1(v, addrInteger, sqlite3VdbeCurrentAddr(v));
+ sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);
}
}
#endif /* SQLITE_OMIT_WINDOWFUNC */
Index: test/bestindex1.test
==================================================================
--- test/bestindex1.test
+++ test/bestindex1.test
@@ -263,8 +263,65 @@
1 0 ValueA 1 0 ValueA
2 0 ValueA 2 0 ValueA
3 0 ValueB 3 0 ValueB
4 0 ValueB 4 0 ValueB
}
+
+#-------------------------------------------------------------------------
+# If there is an IN(..) condition in the WHERE clause of a query on a
+# virtual table, the xBestIndex method is first invoked with the IN(...)
+# represented by a "usable" SQLITE_INDEX_CONSTRAINT_EQ constraint. If
+# the virtual table elects to use the IN(...) constraint, then the
+# xBestIndex method is invoked again, this time with the IN(...) marked
+# as "not usable". Depending on the relative costs of the two plans as
+# defined by the virtual table implementation, and the cardinality of the
+# IN(...) operator, SQLite chooses the most efficient plan.
+#
+# At one point the second invocation of xBestIndex() was only being made
+# for join queries. The following tests check that this problem has been
+# fixed.
+#
+proc vtab_command {method args} {
+ switch -- $method {
+ xConnect {
+ return "CREATE TABLE t1(a, b, c, d)"
+ }
+
+ xBestIndex {
+ set clist [lindex $args 0]
+ lappend ::bestindex_calls $clist
+ set ret "cost 1000000 idxnum 555"
+ for {set i 0} {$i < [llength $clist]} {incr i} {
+ array set C [lindex $clist $i]
+ if {$C(usable)} { lappend ret use $i }
+ }
+ return $ret
+ }
+ }
+ return {}
+}
+
+do_execsql_test 4.0 {
+ CREATE VIRTUAL TABLE x1 USING tcl(vtab_command);
+} {}
+
+do_test 4.1 {
+ set ::bestindex_calls [list]
+ execsql {
+ SELECT * FROM x1 WHERE a=? AND b BETWEEN ? AND ? AND c IN (1, 2, 3, 4);
+ }
+ set ::bestindex_calls
+} [list \
+ [list {op eq column 0 usable 1} \
+ {op eq column 2 usable 1} \
+ {op ge column 1 usable 1} \
+ {op le column 1 usable 1} \
+ ] \
+ [list {op eq column 0 usable 1} \
+ {op eq column 2 usable 0} \
+ {op ge column 1 usable 1} \
+ {op le column 1 usable 1}
+ ]
+]
finish_test
Index: test/createtab.test
==================================================================
--- test/createtab.test
+++ test/createtab.test
@@ -10,11 +10,10 @@
#***********************************************************************
# This file implements regression tests for SQLite library. The
# focus of this file is testing that it is OK to create new tables
# and indices while creating existing tables and indices.
#
-# $Id: createtab.test,v 1.3 2007/09/12 17:01:45 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable autovacuum {
@@ -140,7 +139,16 @@
}
} {t1 t2 t3 t4}
integrity_check createtab-$av.40
}
+
+# 2019-03-31 Ensure that a proper error is returned for an index
+# with too many columns.
+#
+do_test createtab-3.1 {
+ db eval {DROP TABLE IF EXISTS t1;}
+ set sql "CREATE TABLE t1(x,UNIQUE(x[string repeat ,x 100000]))"
+ catchsql $sql
+} {1 {too many columns in index}}
finish_test
Index: test/fts3atoken.test
==================================================================
--- test/fts3atoken.test
+++ test/fts3atoken.test
@@ -84,15 +84,52 @@
INSERT INTO t1(content) VALUES('That the colt from ol regret had got');
SELECT content FROM t1 WHERE content MATCH 'movement'
}
} {{There was movement at the station}}
+unset -nocomplain simple blah2name simplename
+set simplename "simple"
+set blah2name "blah2"
+set simple [db one {SELECT fts3_tokenizer('simple')}]
sqlite3_db_config db SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 0
do_catchsql_test 1.6 {
SELECT fts3_tokenizer('blah', fts3_tokenizer('simple')) IS NULL;
} {1 {fts3tokenize disabled}}
+do_test fts3atoken-1.7 {
+ execsql {
+ SELECT fts3_tokenizer('blah2', $simple) IS NULL;
+ }
+} {1}
+
+# With ENABLE_FTS3_TOKENIZER off, the fts3_tokenzer(1) function
+# returns NULL unless the first parameter is a bound parameter.
+# If the first parameter is a bound parameter, then fts3_tokenizer(1)
+# returns the actual pointer value as a BLOB.
+#
+do_test fts3atoken-1.8 {
+ execsql {
+ SELECT fts3_tokenizer($blah2name) == fts3_tokenizer($simplename),
+ typeof(fts3_tokenizer($blah2name)),
+ typeof(fts3_tokenizer('blah2')),
+ typeof(fts3_tokenizer($simplename)),
+ typeof(fts3_tokenizer('simple'));
+ }
+} {1 blob null blob null}
+# With ENABLE_FTS3_TOKENIZER on, fts3_tokenizer() always returns
+# the BLOB pointer, regardless the parameter
+#
+sqlite3_db_config db SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1
+do_test fts3atoken-1.9 {
+ execsql {
+ SELECT fts3_tokenizer('blah2') == fts3_tokenizer('simple'),
+ typeof(fts3_tokenizer($blah2name)),
+ typeof(fts3_tokenizer('blah2')),
+ typeof(fts3_tokenizer($simplename)),
+ typeof(fts3_tokenizer('simple'));
+ }
+} {1 blob blob blob blob}
#--------------------------------------------------------------------------
# Test cases fts3atoken-2.* test error cases in the scalar function based
# API for getting and setting tokenizers.
#
Index: test/func.test
==================================================================
--- test/func.test
+++ test/func.test
@@ -1389,6 +1389,34 @@
# Test char().
#
do_execsql_test func-31.1 {
SELECT char(), length(char()), typeof(char())
} {{} 0 text}
+
+# sqlite3_value_frombind()
+#
+do_execsql_test func-32.100 {
+ SELECT test_frombind(1,2,3,4);
+} {0}
+do_execsql_test func-32.110 {
+ SELECT test_frombind(1,2,?,4);
+} {4}
+do_execsql_test func-32.120 {
+ SELECT test_frombind(1,(?),4,?+7);
+} {2}
+do_execsql_test func-32.130 {
+ DROP TABLE IF EXISTS t1;
+ CREATE TABLE t1(a,b,c,e,f);
+ INSERT INTO t1 VALUES(1,2.5,'xyz',x'e0c1b2a3',null);
+ SELECT test_frombind(a,b,c,e,f,$xyz) FROM t1;
+} {32}
+do_execsql_test func-32.140 {
+ SELECT test_frombind(a,b,c,e,f,$xyz+f) FROM t1;
+} {0}
+do_execsql_test func-32.150 {
+ SELECT test_frombind(x.a,y.b,x.c,:123,y.e,x.f,$xyz+y.f) FROM t1 x, t1 y;
+} {8}
+
+
+
+
finish_test
Index: test/fuzzdata8.db
==================================================================
--- test/fuzzdata8.db
+++ test/fuzzdata8.db
cannot compute difference between binary files
Index: test/permutations.test
==================================================================
--- test/permutations.test
+++ test/permutations.test
@@ -1030,17 +1030,19 @@
]
test_suite "no_optimization" -description {
Run test scripts with optimizations disabled using the
sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS) interface.
-} -files {
- where.test where2.test where3.test where4.test where5.test
- where6.test where7.test where8.test where9.test
- whereA.test whereB.test wherelimit.test
- select1.test select2.test select3.test select4.test select5.test
- select7.test select8.test selectA.test selectC.test
-} -dbconfig {
+} -files [
+ test_set \
+ [glob -nocomplain $::testdir/window*.test] \
+ where.test where2.test where3.test where4.test where5.test \
+ where6.test where7.test where8.test where9.test \
+ whereA.test whereB.test wherelimit.test \
+ select1.test select2.test select3.test select4.test select5.test \
+ select7.test select8.test selectA.test selectC.test
+] -dbconfig {
optimization_control $::dbhandle all 0
}
test_suite "prepare" -description {
Run tests with the db connection using sqlite3_prepare() instead of _v2().
Index: test/pg_common.tcl
==================================================================
--- test/pg_common.tcl
+++ test/pg_common.tcl
@@ -38,21 +38,30 @@
lappend lSql $frag
}
#puts $lSql
set ret ""
+ set nChar 0
foreach stmt $lSql {
set res [pg_exec $::db $stmt]
set err [pg_result $res -error]
if {$err!=""} { error $err }
+
for {set i 0} {$i < [pg_result $res -numTuples]} {incr i} {
- if {$i==0} {
- set ret [pg_result $res -getTuple 0]
+ set t [pg_result $res -getTuple $i]
+ set nNew [string length $t]
+ if {$nChar>0 && ($nChar+$nNew+3)>75} {
+ append ret "\n "
+ set nChar 0
} else {
- append ret " [pg_result $res -getTuple $i]"
+ if {$nChar>0} {
+ append ret " "
+ incr nChar 3
+ }
}
- # lappend ret {*}[pg_result $res -getTuple $i]
+ incr nChar $nNew
+ append ret $t
}
pg_result $res -clear
}
set ret
@@ -59,15 +68,31 @@
}
proc execsql_test {tn sql} {
set res [execsql $sql]
set sql [string map {string_agg group_concat} $sql]
+ set sql [string map [list {NULLS FIRST} {}] $sql]
+ set sql [string map [list {NULLS LAST} {}] $sql]
puts $::fd "do_execsql_test $tn {"
puts $::fd " [string trim $sql]"
puts $::fd "} {$res}"
puts $::fd ""
}
+
+proc errorsql_test {tn sql} {
+ set rc [catch {execsql $sql} msg]
+ if {$rc==0} {
+ error "errorsql_test SQL did not cause an error!"
+ }
+ set msg [lindex [split [string trim $msg] "\n"] 0]
+ puts $::fd "# PG says $msg"
+ set sql [string map {string_agg group_concat} $sql]
+ puts $::fd "do_test $tn { catch { execsql {"
+ puts $::fd " [string trim $sql]"
+ puts $::fd "} } } 1"
+ puts $::fd ""
+}
# Same as [execsql_test], except coerce all results to floating point values
# with two decimal points.
#
proc execsql_float_test {tn sql} {
@@ -86,14 +111,16 @@
set myres {}
foreach r [db eval {$sql}] {
lappend myres [format $F [set r]]
}
set res2 {$res2}
+ set i 0
foreach r [set myres] r2 [set res2] {
if {[set r]<([set r2]-$T) || [set r]>([set r2]+$T)} {
error "list element [set i] does not match: got=[set r] expected=[set r2]"
}
+ incr i
}
set {} {}
} {}
}]
}
Index: test/tester.tcl
==================================================================
--- test/tester.tcl
+++ test/tester.tcl
@@ -574,10 +574,14 @@
}
if {$cmdlinearg(verbose)==""} {
set cmdlinearg(verbose) 1
}
+
+ if {[info commands vdbe_coverage]!=""} {
+ vdbe_coverage start
+ }
}
# Update the soft-heap-limit each time this script is run. In that
# way if an individual test file changes the soft-heap-limit, it
# will be reset at the start of the next test file.
@@ -1319,10 +1323,13 @@
output2 "Writing leaks.tcl..."
sqlite3_memdebug_log sync
memdebug_log_sql leaks.tcl
}
}
+ if {[info commands vdbe_coverage]!=""} {
+ vdbe_coverage_report
+ }
catch {
foreach f [glob -nocomplain test.db-*-journal] {
forcedelete $f
}
}
@@ -1331,10 +1338,43 @@
forcedelete $f
}
}
exit [expr {$nErr>0}]
}
+
+proc vdbe_coverage_report {} {
+ puts "Writing vdbe coverage report to vdbe_coverage.txt"
+ set lSrc [list]
+ set iLine 0
+ if {[file exists ../sqlite3.c]} {
+ set fd [open ../sqlite3.c]
+ set iLine
+ while { ![eof $fd] } {
+ set line [gets $fd]
+ incr iLine
+ if {[regexp {^/\** Begin file (.*\.c) \**/} $line -> file]} {
+ lappend lSrc [list $iLine $file]
+ }
+ }
+ close $fd
+ }
+ set fd [open vdbe_coverage.txt w]
+ foreach miss [vdbe_coverage report] {
+ foreach {line branch never} $miss {}
+ set nextfile ""
+ while {[llength $lSrc]>0 && [lindex $lSrc 0 0] < $line} {
+ set nextfile [lindex $lSrc 0 1]
+ set lSrc [lrange $lSrc 1 end]
+ }
+ if {$nextfile != ""} {
+ puts $fd ""
+ puts $fd "### $nextfile ###"
+ }
+ puts $fd "Vdbe branch $line: never $never (path $branch)"
+ }
+ close $fd
+}
# Display memory statistics for analysis and debugging purposes.
#
proc show_memstats {} {
set x [sqlite3_status SQLITE_STATUS_MEMORY_USED 0]
Index: test/window1.test
==================================================================
--- test/window1.test
+++ test/window1.test
@@ -717,35 +717,371 @@
do_execsql_test 17.3 {
SELECT 10+sum(a) OVER (ORDER BY a)
FROM t8
ORDER BY 10+sum(a) OVER (ORDER BY a) DESC;
} {16 13 11}
+
#-------------------------------------------------------------------------
+# Test error cases from chaining window definitions.
#
reset_db
do_execsql_test 18.0 {
+ DROP TABLE IF EXISTS t1;
+ CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c TEXT, d INTEGER);
+ INSERT INTO t1 VALUES(1, 'odd', 'one', 1);
+ INSERT INTO t1 VALUES(2, 'even', 'two', 2);
+ INSERT INTO t1 VALUES(3, 'odd', 'three', 3);
+ INSERT INTO t1 VALUES(4, 'even', 'four', 4);
+ INSERT INTO t1 VALUES(5, 'odd', 'five', 5);
+ INSERT INTO t1 VALUES(6, 'even', 'six', 6);
+}
+
+foreach {tn sql error} {
+ 1 {
+ SELECT c, sum(d) OVER win2 FROM t1
+ WINDOW win1 AS (ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING),
+ win2 AS (win1 ORDER BY b)
+ } {cannot override frame specification of window: win1}
+
+ 2 {
+ SELECT c, sum(d) OVER win2 FROM t1
+ WINDOW win1 AS (),
+ win2 AS (win4 ORDER BY b)
+ } {no such window: win4}
+
+ 3 {
+ SELECT c, sum(d) OVER win2 FROM t1
+ WINDOW win1 AS (),
+ win2 AS (win1 PARTITION BY d)
+ } {cannot override PARTITION clause of window: win1}
+
+ 4 {
+ SELECT c, sum(d) OVER win2 FROM t1
+ WINDOW win1 AS (ORDER BY b),
+ win2 AS (win1 ORDER BY d)
+ } {cannot override ORDER BY clause of window: win1}
+} {
+ do_catchsql_test 18.1.$tn $sql [list 1 $error]
+}
+
+foreach {tn sql error} {
+ 1 {
+ SELECT c, sum(d) OVER (win1 ORDER BY b) FROM t1
+ WINDOW win1 AS (ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
+ } {cannot override frame specification of window: win1}
+
+ 2 {
+ SELECT c, sum(d) OVER (win4 ORDER BY b) FROM t1
+ WINDOW win1 AS ()
+ } {no such window: win4}
+
+ 3 {
+ SELECT c, sum(d) OVER (win1 PARTITION BY d) FROM t1
+ WINDOW win1 AS ()
+ } {cannot override PARTITION clause of window: win1}
+
+ 4 {
+ SELECT c, sum(d) OVER (win1 ORDER BY d) FROM t1
+ WINDOW win1 AS (ORDER BY b)
+ } {cannot override ORDER BY clause of window: win1}
+} {
+ do_catchsql_test 18.2.$tn $sql [list 1 $error]
+}
+
+do_execsql_test 18.3.1 {
+ SELECT group_concat(c, '.') OVER (PARTITION BY b ORDER BY c)
+ FROM t1
+} {four four.six four.six.two five five.one five.one.three}
+
+do_execsql_test 18.3.2 {
+ SELECT group_concat(c, '.') OVER (win1 ORDER BY c)
+ FROM t1
+ WINDOW win1 AS (PARTITION BY b)
+} {four four.six four.six.two five five.one five.one.three}
+
+do_execsql_test 18.3.3 {
+ SELECT group_concat(c, '.') OVER win2
+ FROM t1
+ WINDOW win1 AS (PARTITION BY b),
+ win2 AS (win1 ORDER BY c)
+} {four four.six four.six.two five five.one five.one.three}
+
+do_execsql_test 18.3.4 {
+ SELECT group_concat(c, '.') OVER (win2)
+ FROM t1
+ WINDOW win1 AS (PARTITION BY b),
+ win2 AS (win1 ORDER BY c)
+} {four four.six four.six.two five five.one five.one.three}
+
+do_execsql_test 18.3.5 {
+ SELECT group_concat(c, '.') OVER win5
+ FROM t1
+ WINDOW win1 AS (PARTITION BY b),
+ win2 AS (win1),
+ win3 AS (win2),
+ win4 AS (win3),
+ win5 AS (win4 ORDER BY c)
+} {four four.six four.six.two five five.one five.one.three}
+
+#-------------------------------------------------------------------------
+# Test RANGE PRECEDING/FOLLOWING when there are string, blob
+# and NULL values in the dataset.
+#
+reset_db
+do_execsql_test 19.0 {
+ CREATE TABLE t1(a, b);
+ INSERT INTO t1 VALUES
+ (1, 1), (2, 2), (3, 3), (4, 4), (5, 5),
+ ('a', 6), ('b', 7), ('c', 8), ('d', 9), ('e', 10);
+}
+do_execsql_test 19.1 {
+ SELECT a, sum(b) OVER (ORDER BY a) FROM t1;
+} {1 1 2 3 3 6 4 10 5 15 a 21 b 28 c 36 d 45 e 55}
+
+do_execsql_test 19.2.1 {
+ SELECT a, sum(b) OVER (
+ ORDER BY a RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING
+ ) FROM t1;
+} {1 3 2 6 3 9 4 12 5 9 a 6 b 7 c 8 d 9 e 10}
+do_execsql_test 19.2.2 {
+ SELECT a, sum(b) OVER (
+ ORDER BY a DESC RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING
+ ) FROM t1 ORDER BY a ASC;
+} {1 3 2 6 3 9 4 12 5 9 a 6 b 7 c 8 d 9 e 10}
+
+do_execsql_test 19.3.1 {
+ SELECT a, sum(b) OVER (
+ ORDER BY a RANGE BETWEEN 2 PRECEDING AND 1 FOLLOWING
+ ) FROM t1;
+} {1 3 2 6 3 10 4 14 5 12 a 6 b 7 c 8 d 9 e 10}
+do_execsql_test 19.3.2 {
+ SELECT a, sum(b) OVER (
+ ORDER BY a DESC RANGE BETWEEN 1 PRECEDING AND 2 FOLLOWING
+ ) FROM t1 ORDER BY a ASC;
+} {1 3 2 6 3 10 4 14 5 12 a 6 b 7 c 8 d 9 e 10}
+
+
+reset_db
+do_execsql_test 20.0 {
+ CREATE TABLE t1(a, b);
+ INSERT INTO t1 VALUES
+ (NULL, 100), (NULL, 100),
+ (1, 1), (2, 2), (3, 3), (4, 4), (5, 5),
+ ('a', 6), ('b', 7), ('c', 8), ('d', 9), ('e', 10);
+}
+do_execsql_test 20.1 {
+ SELECT a, sum(b) OVER (ORDER BY a) FROM t1;
+} {
+ {} 200 {} 200 1 201 2 203 3 206 4 210 5 215
+ a 221 b 228 c 236 d 245 e 255
+}
+
+do_execsql_test 20.2.1 {
+ SELECT a, sum(b) OVER (
+ ORDER BY a RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING
+ ) FROM t1;
+} {{} 200 {} 200 1 3 2 6 3 9 4 12 5 9 a 6 b 7 c 8 d 9 e 10}
+do_execsql_test 20.2.2 {
+ SELECT a, sum(b) OVER (
+ ORDER BY a DESC RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING
+ ) FROM t1 ORDER BY a ASC;
+} {{} 200 {} 200 1 3 2 6 3 9 4 12 5 9 a 6 b 7 c 8 d 9 e 10}
+
+do_execsql_test 20.3.1 {
+ SELECT a, sum(b) OVER (
+ ORDER BY a RANGE BETWEEN 2 PRECEDING AND 1 FOLLOWING
+ ) FROM t1;
+} {{} 200 {} 200 1 3 2 6 3 10 4 14 5 12 a 6 b 7 c 8 d 9 e 10}
+do_execsql_test 20.3.2 {
+ SELECT a, sum(b) OVER (
+ ORDER BY a DESC RANGE BETWEEN 1 PRECEDING AND 2 FOLLOWING
+ ) FROM t1 ORDER BY a ASC;
+} {{} 200 {} 200 1 3 2 6 3 10 4 14 5 12 a 6 b 7 c 8 d 9 e 10}
+
+#-------------------------------------------------------------------------
+do_execsql_test 21.0 {
+ CREATE TABLE keyword_tab(
+ current, exclude, filter, following, groups, no, others, over,
+ partition, preceding, range, ties, unbounded, window
+ );
+}
+do_execsql_test 21.1 {
+ SELECT
+ current, exclude, filter, following, groups, no, others, over,
+ partition, preceding, range, ties, unbounded, window
+ FROM keyword_tab
+}
+
+#-------------------------------------------------------------------------
+foreach {tn expr err} {
+ 1 4.5 0
+ 2 NULL 1
+ 3 0.0 0
+ 4 0.1 0
+ 5 -0.1 1
+ 6 '' 1
+ 7 '2.0' 0
+ 8 '2.0x' 1
+ 9 x'1234' 1
+ 10 '1.2' 0
+} {
+ set res {0 1}
+ if {$err} {set res {1 {frame starting offset must be a non-negative number}} }
+ do_catchsql_test 22.$tn.1 "
+ WITH a(x, y) AS ( VALUES(1, 2) )
+ SELECT sum(x) OVER (
+ ORDER BY y RANGE BETWEEN $expr PRECEDING AND UNBOUNDED FOLLOWING
+ ) FROM a
+ " $res
+
+ set res {0 1}
+ if {$err} {set res {1 {frame ending offset must be a non-negative number}} }
+ do_catchsql_test 22.$tn.2 "
+ WITH a(x, y) AS ( VALUES(1, 2) )
+ SELECT sum(x) OVER (
+ ORDER BY y RANGE BETWEEN UNBOUNDED PRECEDING AND $expr FOLLOWING
+ ) FROM a
+ " $res
+}
+
+#-------------------------------------------------------------------------
+reset_db
+do_execsql_test 23.0 {
+ CREATE TABLE t5(a, b, c);
+ CREATE INDEX t5ab ON t5(a, b);
+}
+
+proc do_ordercount_test {tn sql nOrderBy} {
+ set plan [execsql "EXPLAIN QUERY PLAN $sql"]
+ uplevel [list do_test $tn [list regexp -all ORDER $plan] $nOrderBy]
+}
+
+do_ordercount_test 23.1 {
+ SELECT
+ sum(c) OVER (ORDER BY a, b),
+ sum(c) OVER (PARTITION BY a ORDER BY b)
+ FROM t5
+} 0
+
+do_ordercount_test 23.2 {
+ SELECT
+ sum(c) OVER (ORDER BY b, a),
+ sum(c) OVER (PARTITION BY b ORDER BY a)
+ FROM t5
+} 1
+
+do_ordercount_test 23.3 {
+ SELECT
+ sum(c) OVER (ORDER BY b, a),
+ sum(c) OVER (ORDER BY c, b)
+ FROM t5
+} 2
+
+do_ordercount_test 23.4 {
+ SELECT
+ sum(c) OVER (ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW),
+ sum(c) OVER (ORDER BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW),
+ sum(c) OVER (ORDER BY b GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
+ FROM t5
+} 1
+
+do_ordercount_test 23.5 {
+ SELECT
+ sum(c) OVER (ORDER BY b+1 ROWS UNBOUNDED PRECEDING),
+ sum(c) OVER (ORDER BY b+1 RANGE UNBOUNDED PRECEDING),
+ sum(c) OVER (ORDER BY b+1 GROUPS UNBOUNDED PRECEDING)
+ FROM t5
+} 1
+
+do_ordercount_test 23.6 {
+ SELECT
+ sum(c) OVER (ORDER BY b+1 ROWS UNBOUNDED PRECEDING),
+ sum(c) OVER (ORDER BY b+2 RANGE UNBOUNDED PRECEDING),
+ sum(c) OVER (ORDER BY b+3 GROUPS UNBOUNDED PRECEDING)
+ FROM t5
+} 3
+
+do_execsql_test 24.1 {
+ SELECT sum(44) OVER ()
+} {44}
+
+do_execsql_test 24.2 {
+ SELECT lead(44) OVER ()
+} {{}}
+
+#-------------------------------------------------------------------------
+#
+reset_db
+do_execsql_test 25.0 {
CREATE TABLE t1 ( t1_id INTEGER PRIMARY KEY );
CREATE TABLE t2 ( t2_id INTEGER PRIMARY KEY );
CREATE TABLE t3 ( t3_id INTEGER PRIMARY KEY );
INSERT INTO t1 VALUES(1), (3), (5);
INSERT INTO t2 VALUES (3), (5);
INSERT INTO t3 VALUES(10), (11), (12);
}
-do_execsql_test 18.1 {
+do_execsql_test 25.1 {
SELECT t1.* FROM t1, t2 WHERE
t1_id=t2_id AND t1_id IN (
SELECT t1_id + row_number() OVER ( ORDER BY t1_id ) FROM t3
)
}
-do_execsql_test 18.2 {
+do_execsql_test 25.2 {
SELECT t1.* FROM t1, t2 WHERE
t1_id=t2_id AND t1_id IN (
SELECT row_number() OVER ( ORDER BY t1_id ) FROM t3
)
} {3}
+#-------------------------------------------------------------------------
+reset_db
+do_execsql_test 26.0 {
+ CREATE TABLE t1(x);
+ CREATE TABLE t2(c);
+}
+
+do_execsql_test 26.1 {
+ SELECT ( SELECT row_number() OVER () FROM ( SELECT c FROM t1 ) ) FROM t2
+} {}
+
+do_execsql_test 26.2 {
+ INSERT INTO t1 VALUES(1), (2), (3), (4);
+ INSERT INTO t2 VALUES(2), (6), (8), (4);
+ SELECT c, c IN (
+ SELECT row_number() OVER () FROM ( SELECT c FROM t1 )
+ ) FROM t2
+} {2 1 6 0 8 0 4 1}
+
+do_execsql_test 26.3 {
+ DELETE FROM t1;
+ DELETE FROM t2;
+
+ INSERT INTO t2 VALUES(1), (2), (3), (4);
+ INSERT INTO t1 VALUES(1), (1), (2), (3), (3), (3), (3), (4), (4);
+
+ SELECT c, c IN (
+ SELECT row_number() OVER () FROM ( SELECT 1 FROM t1 WHERE x=c )
+ ) FROM t2
+} {1 1 2 0 3 1 4 0}
+
+#-------------------------------------------------------------------------
+reset_db
+do_execsql_test 27.0 {
+ CREATE TABLE t1(x);
+ INSERT INTO t1 VALUES(NULL), (1), (2), (3), (4), (5);
+}
+do_execsql_test 27.1 {
+ SELECT min(x) FROM t1;
+} {1}
+do_execsql_test 27.2 {
+ SELECT min(x) OVER win FROM t1
+ WINDOW win AS (ORDER BY rowid ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
+} {1 1 1 2 3 4}
+
finish_test
+
+
Index: test/window3.tcl
==================================================================
--- test/window3.tcl
+++ test/window3.tcl
@@ -19,11 +19,10 @@
execsql_test 1.0 {
DROP TABLE IF EXISTS t2;
CREATE TABLE t2(a INTEGER PRIMARY KEY, b INTEGER);
INSERT INTO t2(a, b) VALUES
- (1,0), (2,74), (3,41), (4,74), (5,23), (6,99), (7,26), (8,33), (9,2),
(10,89), (11,81), (12,96), (13,59), (14,38), (15,68), (16,39), (17,62),
(18,91), (19,46), (20,6), (21,99), (22,97), (23,27), (24,46), (25,78),
(26,54), (27,97), (28,8), (29,67), (30,29), (31,93), (32,84), (33,77),
(34,23), (35,16), (36,16), (37,93), (38,65), (39,35), (40,47), (41,7),
(42,86), (43,74), (44,61), (45,91), (46,85), (47,24), (48,85), (49,43),
@@ -71,10 +70,15 @@
13 "ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING"
14 "ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING"
15 "ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING"
16 "ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING"
17 "ROWS BETWEEN 4 FOLLOWING AND UNBOUNDED FOLLOWING"
+
+ 18 "ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW"
+ 19 "ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE TIES"
+ 20 "ROWS BETWEEN 4 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE GROUP"
+
} {
execsql_test 1.$tn.2.1 "SELECT max(b) OVER ( ORDER BY a $window ) FROM t2"
execsql_test 1.$tn.2.2 "SELECT min(b) OVER ( ORDER BY a $window ) FROM t2"
execsql_test 1.$tn.3.1 "
@@ -304,10 +308,32 @@
SELECT string_agg(CAST(b AS TEXT), '.') OVER ( ORDER BY b%10,a $window ) FROM t2
"
execsql_test 1.$tn.14.6 "
SELECT string_agg(CAST(b AS TEXT), '.') OVER (PARTITION BY b%2,a ORDER BY b%10 $window) FROM t2
"
+
+ execsql_test 1.$tn.14.7 "
+ SELECT string_agg(CAST(b AS TEXT), '.') OVER (win1 ORDER BY b%10 $window)
+ FROM t2
+ WINDOW win1 AS (PARTITION BY b%2,a)
+ ORDER BY 1
+ "
+
+ execsql_test 1.$tn.14.8 "
+ SELECT string_agg(CAST(b AS TEXT), '.') OVER (win1 $window)
+ FROM t2
+ WINDOW win1 AS (PARTITION BY b%2,a ORDER BY b%10)
+ ORDER BY 1
+ "
+
+ execsql_test 1.$tn.14.9 "
+ SELECT string_agg(CAST(b AS TEXT), '.') OVER win2
+ FROM t2
+ WINDOW win1 AS (PARTITION BY b%2,a ORDER BY b%10),
+ win2 AS (win1 $window)
+ ORDER BY 1
+ "
execsql_test 1.$tn.15.1 "
SELECT count(*) OVER win, string_agg(CAST(b AS TEXT), '.')
FILTER (WHERE a%2=0) OVER win FROM t2
WINDOW win AS (ORDER BY a $window)
Index: test/window3.test
==================================================================
--- test/window3.test
+++ test/window3.test
cannot compute difference between binary files
Index: test/window4.tcl
==================================================================
--- test/window4.tcl
+++ test/window4.tcl
@@ -1,6 +1,6 @@
-# 2018 May 19
+## 2018 May 19
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
Index: test/window4.test
==================================================================
--- test/window4.test
+++ test/window4.test
@@ -148,11 +148,12 @@
do_execsql_test 2.4.1 {
SELECT group_concat(b, '.') OVER (
ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
) FROM t4
-} {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}
+} {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}
do_execsql_test 3.0 {
DROP TABLE IF EXISTS t5;
CREATE TABLE t5(a INTEGER PRIMARY KEY, b TEXT, c TEXT, d INTEGER);
INSERT INTO t5 VALUES(1, 'A', 'one', 5);
@@ -1222,14 +1223,16 @@
set myres {}
foreach r [db eval {SELECT x, percent_rank() OVER (PARTITION BY x ORDER BY x) FROM t2}] {
lappend myres [format %.4f [set r]]
}
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}
+ set i 0
foreach r [set myres] r2 [set res2] {
if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} {
error "list element [set i] does not match: got=[set r] expected=[set r2]"
}
+ incr i
}
set {} {}
} {}
do_execsql_test 9.4 {
@@ -1245,14 +1248,16 @@
set myres {}
foreach r [db eval {SELECT percent_rank() OVER () FROM t1}] {
lappend myres [format %.4f [set r]]
}
set res2 {0.0000 0.0000 0.0000}
+ set i 0
foreach r [set myres] r2 [set res2] {
if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} {
error "list element [set i] does not match: got=[set r] expected=[set r2]"
}
+ incr i
}
set {} {}
} {}
@@ -1260,14 +1265,16 @@
set myres {}
foreach r [db eval {SELECT cume_dist() OVER () FROM t1}] {
lappend myres [format %.4f [set r]]
}
set res2 {1.0000 1.0000 1.0000}
+ set i 0
foreach r [set myres] r2 [set res2] {
if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} {
error "list element [set i] does not match: got=[set r] expected=[set r2]"
}
+ incr i
}
set {} {}
} {}
do_execsql_test 10.0 {
Index: test/window6.test
==================================================================
--- test/window6.test
+++ test/window6.test
@@ -217,21 +217,21 @@
SELECT x, group_concat(x) OVER (ORDER BY x ROWS 2 PRECEDING)
FROM c;
} {
1 1 2 1,2 3 1,2,3 4 2,3,4 5 3,4,5
}
-do_catchsql_test 9.1 {
- WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5)
- SELECT x, group_concat(x) OVER (ORDER BY x RANGE 2 PRECEDING)
- FROM c;
-} {1 {RANGE must use only UNBOUNDED or CURRENT ROW}}
-
-do_catchsql_test 9.2 {
- WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5)
- SELECT x, group_concat(x) OVER (ORDER BY x RANGE BETWEEN UNBOUNDED PRECEDING AND 2 FOLLOWING)
- FROM c;
-} {1 {RANGE must use only UNBOUNDED or CURRENT ROW}}
+#do_catchsql_test 9.1 {
+# WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5)
+# SELECT x, group_concat(x) OVER (ORDER BY x RANGE 2 PRECEDING)
+# FROM c;
+#} {1 {RANGE must use only UNBOUNDED or CURRENT ROW}}
+#
+#do_catchsql_test 9.2 {
+# WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5)
+# SELECT x, group_concat(x) OVER (ORDER BY x RANGE BETWEEN UNBOUNDED PRECEDING AND 2 FOLLOWING)
+# FROM c;
+#} {1 {RANGE must use only UNBOUNDED or CURRENT ROW}}
do_catchsql_test 9.3 {
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5)
SELECT count(DISTINCT x) OVER (ORDER BY x) FROM c;
} {1 {DISTINCT is not supported for window functions}}
@@ -260,11 +260,11 @@
do_catchsql_test 9.7.$tn "
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5)
SELECT count() OVER (
ORDER BY x ROWS $frame
) FROM c;
- " {1 {unsupported frame delimiter for ROWS}}
+ " {1 {unsupported frame specification}}
}
do_catchsql_test 9.8.1 {
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<5)
SELECT count() OVER (
@@ -334,7 +334,38 @@
FROM t1 ORDER BY a;
} {
10 ten 10 15 fifteen 25 20 {} 65 20 {} 65
25 {} 90 30 thirty 150 30 thirty 150 50 {} 200
}
+
+do_execsql_test 11.3.1 {
+ SELECT a, sum(a) OVER win FROM t1
+ WINDOW win AS (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
+} {
+ 10 10 15 25 20 45 20 65 25 90 30 120 30 150 50 200
+}
+do_execsql_test 11.3.2 {
+ SELECT a, sum(a) OVER win FROM t1
+ WINDOW win AS (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 0 FOLLOWING)
+} {
+ 10 10 15 25 20 45 20 65 25 90 30 120 30 150 50 200
+}
+do_execsql_test 11.3.3 {
+ SELECT a, sum(a) OVER win FROM t1
+ WINDOW win AS (ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING)
+} {
+ 10 10 15 25 20 45 20 65 25 90 30 120 30 150 50 200
+}
+
+do_execsql_test 11.4.1 {
+ SELECT y, group_concat(y, '.') OVER win FROM t3
+ WINDOW win AS (
+ ORDER BY y RANGE BETWEEN UNBOUNDED PRECEDING AND 10 PRECEDING
+ );
+} {
+ fifteen fifteen
+ ten fifteen.ten
+ thirty fifteen.ten.thirty
+}
finish_test
+
ADDED test/window7.tcl
Index: test/window7.tcl
==================================================================
--- /dev/null
+++ test/window7.tcl
@@ -0,0 +1,91 @@
+# 2018 May 19
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+#
+
+source [file join [file dirname $argv0] pg_common.tcl]
+
+#=========================================================================
+
+start_test window7 "2019 March 01"
+ifcapable !windowfunc
+
+execsql_test 1.0 {
+ DROP TABLE IF EXISTS t3;
+ CREATE TABLE t3(a INTEGER, b INTEGER);
+ INSERT INTO t3 VALUES
+ (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8),
+ (9, 9), (0, 10), (1, 11), (2, 12), (3, 13), (4, 14), (5, 15), (6, 16),
+ (7, 17), (8, 18), (9, 19), (0, 20), (1, 21), (2, 22), (3, 23), (4, 24),
+ (5, 25), (6, 26), (7, 27), (8, 28), (9, 29), (0, 30), (1, 31), (2, 32),
+ (3, 33), (4, 34), (5, 35), (6, 36), (7, 37), (8, 38), (9, 39), (0, 40),
+ (1, 41), (2, 42), (3, 43), (4, 44), (5, 45), (6, 46), (7, 47), (8, 48),
+ (9, 49), (0, 50), (1, 51), (2, 52), (3, 53), (4, 54), (5, 55), (6, 56),
+ (7, 57), (8, 58), (9, 59), (0, 60), (1, 61), (2, 62), (3, 63), (4, 64),
+ (5, 65), (6, 66), (7, 67), (8, 68), (9, 69), (0, 70), (1, 71), (2, 72),
+ (3, 73), (4, 74), (5, 75), (6, 76), (7, 77), (8, 78), (9, 79), (0, 80),
+ (1, 81), (2, 82), (3, 83), (4, 84), (5, 85), (6, 86), (7, 87), (8, 88),
+ (9, 89), (0, 90), (1, 91), (2, 92), (3, 93), (4, 94), (5, 95), (6, 96),
+ (7, 97), (8, 98), (9, 99), (0, 100);
+}
+
+execsql_test 1.1 {
+ SELECT a, sum(b) FROM t3 GROUP BY a ORDER BY 1;
+}
+
+execsql_test 1.2 {
+ SELECT a, sum(b) OVER (
+ ORDER BY a GROUPS BETWEEN CURRENT ROW AND CURRENT ROW
+ ) FROM t3 ORDER BY 1;
+}
+
+execsql_test 1.3 {
+ SELECT a, sum(b) OVER (
+ ORDER BY a GROUPS BETWEEN 0 PRECEDING AND 0 FOLLOWING
+ ) FROM t3 ORDER BY 1;
+}
+
+execsql_test 1.4 {
+ SELECT a, sum(b) OVER (
+ ORDER BY a GROUPS BETWEEN 2 PRECEDING AND 2 FOLLOWING
+ ) FROM t3 ORDER BY 1;
+}
+
+execsql_test 1.5 {
+ SELECT a, sum(b) OVER (
+ ORDER BY a RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING
+ ) FROM t3 ORDER BY 1;
+}
+
+execsql_test 1.6 {
+ SELECT a, sum(b) OVER (
+ ORDER BY a RANGE BETWEEN 2 PRECEDING AND 2 FOLLOWING
+ ) FROM t3 ORDER BY 1;
+}
+
+execsql_test 1.7 {
+ SELECT a, sum(b) OVER (
+ ORDER BY a RANGE BETWEEN 2 PRECEDING AND 1 FOLLOWING
+ ) FROM t3 ORDER BY 1;
+}
+
+execsql_test 1.8.1 {
+ SELECT a, sum(b) OVER (
+ ORDER BY a RANGE BETWEEN 0 PRECEDING AND 1 FOLLOWING
+ ) FROM t3 ORDER BY 1;
+}
+execsql_test 1.8.2 {
+ SELECT a, sum(b) OVER (
+ ORDER BY a DESC RANGE BETWEEN 0 PRECEDING AND 1 FOLLOWING
+ ) FROM t3 ORDER BY 1;
+}
+
+finish_test
+
ADDED test/window7.test
Index: test/window7.test
==================================================================
--- /dev/null
+++ test/window7.test
@@ -0,0 +1,94 @@
+# 2019 March 01
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+# This file implements regression tests for SQLite library.
+#
+
+####################################################
+# DO NOT EDIT! THIS FILE IS AUTOMATICALLY GENERATED!
+####################################################
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set testprefix window7
+
+ifcapable !windowfunc { finish_test ; return }
+do_execsql_test 1.0 {
+ DROP TABLE IF EXISTS t3;
+ CREATE TABLE t3(a INTEGER, b INTEGER);
+ INSERT INTO t3 VALUES
+ (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8),
+ (9, 9), (0, 10), (1, 11), (2, 12), (3, 13), (4, 14), (5, 15), (6, 16),
+ (7, 17), (8, 18), (9, 19), (0, 20), (1, 21), (2, 22), (3, 23), (4, 24),
+ (5, 25), (6, 26), (7, 27), (8, 28), (9, 29), (0, 30), (1, 31), (2, 32),
+ (3, 33), (4, 34), (5, 35), (6, 36), (7, 37), (8, 38), (9, 39), (0, 40),
+ (1, 41), (2, 42), (3, 43), (4, 44), (5, 45), (6, 46), (7, 47), (8, 48),
+ (9, 49), (0, 50), (1, 51), (2, 52), (3, 53), (4, 54), (5, 55), (6, 56),
+ (7, 57), (8, 58), (9, 59), (0, 60), (1, 61), (2, 62), (3, 63), (4, 64),
+ (5, 65), (6, 66), (7, 67), (8, 68), (9, 69), (0, 70), (1, 71), (2, 72),
+ (3, 73), (4, 74), (5, 75), (6, 76), (7, 77), (8, 78), (9, 79), (0, 80),
+ (1, 81), (2, 82), (3, 83), (4, 84), (5, 85), (6, 86), (7, 87), (8, 88),
+ (9, 89), (0, 90), (1, 91), (2, 92), (3, 93), (4, 94), (5, 95), (6, 96),
+ (7, 97), (8, 98), (9, 99), (0, 100);
+} {}
+
+do_execsql_test 1.1 {
+ SELECT a, sum(b) FROM t3 GROUP BY a ORDER BY 1;
+} {0 550 1 460 2 470 3 480 4 490 5 500 6 510 7 520 8 530 9 540}
+
+do_execsql_test 1.2 {
+ SELECT a, sum(b) OVER (
+ ORDER BY a GROUPS BETWEEN CURRENT ROW AND CURRENT ROW
+ ) FROM t3 ORDER BY 1;
+} {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}
+
+do_execsql_test 1.3 {
+ SELECT a, sum(b) OVER (
+ ORDER BY a GROUPS BETWEEN 0 PRECEDING AND 0 FOLLOWING
+ ) FROM t3 ORDER BY 1;
+} {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}
+
+do_execsql_test 1.4 {
+ SELECT a, sum(b) OVER (
+ ORDER BY a GROUPS BETWEEN 2 PRECEDING AND 2 FOLLOWING
+ ) FROM t3 ORDER BY 1;
+} {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}
+
+do_execsql_test 1.5 {
+ SELECT a, sum(b) OVER (
+ ORDER BY a RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING
+ ) FROM t3 ORDER BY 1;
+} {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}
+
+do_execsql_test 1.6 {
+ SELECT a, sum(b) OVER (
+ ORDER BY a RANGE BETWEEN 2 PRECEDING AND 2 FOLLOWING
+ ) FROM t3 ORDER BY 1;
+} {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}
+
+do_execsql_test 1.7 {
+ SELECT a, sum(b) OVER (
+ ORDER BY a RANGE BETWEEN 2 PRECEDING AND 1 FOLLOWING
+ ) FROM t3 ORDER BY 1;
+} {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}
+
+do_execsql_test 1.8.1 {
+ SELECT a, sum(b) OVER (
+ ORDER BY a RANGE BETWEEN 0 PRECEDING AND 1 FOLLOWING
+ ) FROM t3 ORDER BY 1;
+} {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}
+
+do_execsql_test 1.8.2 {
+ SELECT a, sum(b) OVER (
+ ORDER BY a DESC RANGE BETWEEN 0 PRECEDING AND 1 FOLLOWING
+ ) FROM t3 ORDER BY 1;
+} {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}
+
+finish_test
ADDED test/window8.tcl
Index: test/window8.tcl
==================================================================
--- /dev/null
+++ test/window8.tcl
@@ -0,0 +1,274 @@
+# 2018 May 19
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+#
+
+source [file join [file dirname $argv0] pg_common.tcl]
+
+#=========================================================================
+
+start_test window8 "2019 March 01"
+ifcapable !windowfunc
+
+execsql_test 1.0 {
+ DROP TABLE IF EXISTS t3;
+ CREATE TABLE t3(a TEXT, b TEXT, c INTEGER);
+ INSERT INTO t3 VALUES
+ ('HH', 'bb', 355), ('CC', 'aa', 158), ('BB', 'aa', 399),
+ ('FF', 'bb', 938), ('HH', 'aa', 480), ('FF', 'bb', 870),
+ ('JJ', 'aa', 768), ('JJ', 'aa', 899), ('GG', 'bb', 929),
+ ('II', 'bb', 421), ('GG', 'bb', 844), ('FF', 'bb', 574),
+ ('CC', 'bb', 822), ('GG', 'bb', 938), ('BB', 'aa', 660),
+ ('HH', 'aa', 979), ('BB', 'bb', 792), ('DD', 'aa', 845),
+ ('JJ', 'bb', 354), ('FF', 'bb', 295), ('JJ', 'aa', 234),
+ ('BB', 'bb', 840), ('AA', 'aa', 934), ('EE', 'aa', 113),
+ ('AA', 'bb', 309), ('BB', 'aa', 412), ('AA', 'aa', 911),
+ ('AA', 'bb', 572), ('II', 'aa', 398), ('II', 'bb', 250),
+ ('II', 'aa', 652), ('BB', 'bb', 633), ('AA', 'aa', 239),
+ ('FF', 'aa', 670), ('BB', 'bb', 705), ('HH', 'bb', 963),
+ ('CC', 'bb', 346), ('II', 'bb', 671), ('BB', 'aa', 247),
+ ('AA', 'aa', 223), ('GG', 'aa', 480), ('HH', 'aa', 790),
+ ('FF', 'aa', 208), ('BB', 'bb', 711), ('EE', 'aa', 777),
+ ('DD', 'bb', 716), ('CC', 'aa', 759), ('CC', 'aa', 430),
+ ('CC', 'aa', 607), ('DD', 'bb', 794), ('GG', 'aa', 148),
+ ('GG', 'aa', 634), ('JJ', 'bb', 257), ('DD', 'bb', 959),
+ ('FF', 'bb', 726), ('BB', 'aa', 762), ('JJ', 'bb', 336),
+ ('GG', 'aa', 335), ('HH', 'bb', 330), ('GG', 'bb', 160),
+ ('JJ', 'bb', 839), ('FF', 'aa', 618), ('BB', 'aa', 393),
+ ('EE', 'bb', 629), ('FF', 'aa', 667), ('AA', 'bb', 870),
+ ('FF', 'bb', 102), ('JJ', 'aa', 113), ('DD', 'aa', 224),
+ ('AA', 'bb', 627), ('HH', 'bb', 730), ('II', 'bb', 443),
+ ('HH', 'bb', 133), ('EE', 'bb', 252), ('II', 'bb', 805),
+ ('BB', 'bb', 786), ('EE', 'bb', 768), ('HH', 'bb', 683),
+ ('DD', 'bb', 238), ('DD', 'aa', 256);
+}
+
+foreach {tn frame} {
+ 1 { GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING }
+ 2 { GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW }
+ 3 { GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING }
+ 4 { GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING }
+ 5 { GROUPS BETWEEN 1 PRECEDING AND 2 PRECEDING }
+ 6 { GROUPS BETWEEN 2 PRECEDING AND 1 PRECEDING }
+ 7 { GROUPS BETWEEN 3 PRECEDING AND 1 PRECEDING }
+ 8 { GROUPS BETWEEN 3 PRECEDING AND 0 PRECEDING }
+ 9 { GROUPS BETWEEN 2 PRECEDING AND CURRENT ROW }
+ 10 { GROUPS BETWEEN 3 PRECEDING AND 0 FOLLOWING }
+ 11 { GROUPS BETWEEN 2 PRECEDING AND UNBOUNDED FOLLOWING }
+ 12 { GROUPS BETWEEN CURRENT ROW AND 0 FOLLOWING }
+ 13 { GROUPS BETWEEN CURRENT ROW AND 1 FOLLOWING }
+ 14 { GROUPS BETWEEN CURRENT ROW AND 100 FOLLOWING }
+ 15 { GROUPS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING }
+ 16 { GROUPS BETWEEN 0 FOLLOWING AND 0 FOLLOWING }
+ 17 { GROUPS BETWEEN 1 FOLLOWING AND 0 FOLLOWING }
+ 18 { GROUPS BETWEEN 1 FOLLOWING AND 5 FOLLOWING }
+ 19 { GROUPS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING }
+
+} {
+ execsql_test 1.$tn.1 "
+ SELECT a, b, sum(c) OVER (ORDER BY a $frame) FROM t3 ORDER BY 1, 2, 3;
+ "
+ execsql_test 1.$tn.2 "
+ SELECT a, b, sum(c) OVER (ORDER BY a,b $frame) FROM t3 ORDER BY 1, 2, 3;
+ "
+ execsql_test 1.$tn.3 "
+ SELECT a, b, rank() OVER (ORDER BY a $frame) FROM t3 ORDER BY 1, 2, 3;
+ "
+ execsql_test 1.$tn.4 "
+ SELECT a, b, max(c) OVER (ORDER BY a,b $frame) FROM t3 ORDER BY 1, 2, 3;
+ "
+ execsql_test 1.$tn.5 "
+ SELECT a, b, min(c) OVER (ORDER BY a,b $frame) FROM t3 ORDER BY 1, 2, 3;
+ "
+
+ set f2 "$frame EXCLUDE CURRENT ROW"
+
+ execsql_test 1.$tn.6 "
+ SELECT a, b, sum(c) OVER (ORDER BY a $f2) FROM t3 ORDER BY 1, 2, 3;
+ "
+ execsql_test 1.$tn.7 "
+ SELECT a, b, sum(c) OVER (ORDER BY a,b $f2) FROM t3 ORDER BY 1, 2, 3;
+ "
+
+ execsql_test 1.$tn.8 "
+ SELECT a, b,
+ sum(c) OVER (ORDER BY a $f2),
+ sum(c) OVER (ORDER BY a $frame),
+ sum(c) OVER (ORDER BY a,b $f2),
+ sum(c) OVER (ORDER BY a,b $frame)
+ FROM t3 ORDER BY 1, 2, 3;
+ "
+}
+
+
+foreach {tn ex} {
+ 1 { EXCLUDE NO OTHERS }
+ 2 { EXCLUDE CURRENT ROW }
+ 3 { EXCLUDE GROUP }
+ 4 { EXCLUDE TIES }
+} {
+ execsql_test 2.$tn.1 "
+ SELECT row_number() OVER win
+ FROM t3
+ WINDOW win AS (
+ ORDER BY c, b, a
+ ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING $ex
+ )
+ "
+
+ execsql_test 2.$tn.2 "
+ SELECT nth_value(c, 14) OVER win
+ FROM t3
+ WINDOW win AS (
+ ORDER BY c, b, a
+ ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING $ex
+ )
+ "
+
+ execsql_test 2.$tn.3 "
+ SELECT min(c) OVER win, max(c) OVER win, sum(c) OVER win FROM t3
+ WINDOW win AS (
+ ORDER BY c, b, a
+ ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW $ex
+ ) ORDER BY a, b, c;
+ "
+}
+
+==========
+
+execsql_test 3.0 {
+ DROP TABLE IF EXISTS t1;
+ CREATE TABLE t1(a REAL, b INTEGER);
+ INSERT INTO t1 VALUES
+ (5, 10), (10, 20), (13, 26), (13, 26),
+ (15, 30), (20, 40), (22,80), (30, 90);
+}
+
+foreach {tn frame} {
+ 1 { ORDER BY a RANGE BETWEEN 5 PRECEDING AND 5 FOLLOWING }
+ 2 { ORDER BY a RANGE BETWEEN 10 PRECEDING AND 5 PRECEDING }
+ 3 { ORDER BY a RANGE BETWEEN 2 FOLLOWING AND 3 FOLLOWING }
+ 4 { ORDER BY a DESC RANGE BETWEEN 5 PRECEDING AND 5 FOLLOWING }
+ 5 { ORDER BY a DESC RANGE BETWEEN 10 PRECEDING AND 5 PRECEDING }
+ 6 { ORDER BY a DESC RANGE BETWEEN 2 FOLLOWING AND 3 FOLLOWING }
+
+ 7 { ORDER BY a RANGE BETWEEN 5.1 PRECEDING AND 5.3 FOLLOWING }
+ 8 { ORDER BY a RANGE BETWEEN 10.2 PRECEDING AND 5.4 PRECEDING }
+ 9 { ORDER BY a RANGE BETWEEN 2.6 FOLLOWING AND 3.5 FOLLOWING }
+ 10 { ORDER BY a DESC RANGE BETWEEN 5.7 PRECEDING AND 5.8 FOLLOWING }
+ 11 { ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND 5.9 PRECEDING }
+ 12 { ORDER BY a DESC RANGE BETWEEN 2.1 FOLLOWING AND UNBOUNDED FOLLOWING }
+ 13 { ORDER BY a RANGE 5.1 PRECEDING }
+} {
+ execsql_test 3.$tn "
+ SELECT CAST(a AS INTEGER), sum(b) OVER win FROM t1 WINDOW win AS ($frame)
+ "
+}
+
+==========
+
+execsql_test 4.0 {
+ DROP TABLE IF EXISTS t1;
+ CREATE TABLE t1(a INTEGER, b INTEGER);
+ INSERT INTO t1 VALUES
+ (NULL, 1), (NULL, 2), (NULL, 3), (10, 4), (10, 5);
+}
+
+execsql_test 4.1.1 {
+ SELECT sum(b) OVER (
+ ORDER BY a RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING
+ ) FROM t1 ORDER BY 1;
+}
+execsql_test 4.1.2 {
+ SELECT sum(b) OVER (
+ ORDER BY a DESC RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING
+ ) FROM t1 ORDER BY 1;
+}
+
+execsql_test 4.2.1 {
+ SELECT sum(b) OVER (
+ ORDER BY a RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING
+ ) FROM t1 ORDER BY 1 NULLS FIRST;
+}
+
+execsql_test 4.2.2 {
+ SELECT sum(b) OVER (
+ ORDER BY a DESC RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING
+ ) FROM t1 ORDER BY 1 NULLS FIRST;
+}
+
+execsql_test 4.3.1 {
+ SELECT sum(b) OVER (
+ ORDER BY a NULLS FIRST RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING
+ ) FROM t1 ORDER BY 1 NULLS FIRST;
+}
+
+execsql_test 4.4.1 {
+ SELECT sum(b) OVER (
+ ORDER BY a NULLS FIRST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
+ ) FROM t1 ORDER BY 1 NULLS FIRST;
+}
+
+execsql_test 4.4.2 {
+ SELECT sum(b) OVER (
+ ORDER BY a DESC NULLS LAST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
+ ) FROM t1 ORDER BY 1 NULLS FIRST;
+}
+
+==========
+
+execsql_test 5.0 {
+ INSERT INTO t3 VALUES
+ (NULL, 'bb', 355), (NULL, 'cc', 158), (NULL, 'aa', 399),
+ ('JJ', NULL, 839), ('FF', NULL, 618), ('BB', NULL, 393),
+ (NULL, 'bb', 629), (NULL, NULL, 667), (NULL, NULL, 870);
+}
+
+foreach {tn ex} {
+ 1 { EXCLUDE NO OTHERS }
+ 2 { EXCLUDE CURRENT ROW }
+ 3 { EXCLUDE GROUP }
+ 4 { EXCLUDE TIES }
+} {
+ foreach {tn2 frame} {
+ 1 { RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING }
+ 2 { ORDER BY a NULLS FIRST
+ RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING }
+ 3 { PARTITION BY coalesce(a, '')
+ RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING }
+ 4 { ORDER BY a NULLS FIRST GROUPS 6 PRECEDING }
+ 5 { ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING }
+ 6 { ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING }
+ 7 { ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST
+ ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING }
+ } {
+ execsql_test 5.$tn.$tn2.1 "
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( $frame $ex )
+ ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
+ "
+
+ execsql_test 5.$tn.$tn2.2 "
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( $frame $ex )
+ ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST
+ "
+ }
+}
+
+finish_test
+
+
ADDED test/window8.test
Index: test/window8.test
==================================================================
--- /dev/null
+++ test/window8.test
@@ -0,0 +1,4851 @@
+# 2019 March 01
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+# This file implements regression tests for SQLite library.
+#
+
+####################################################
+# DO NOT EDIT! THIS FILE IS AUTOMATICALLY GENERATED!
+####################################################
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set testprefix window8
+
+ifcapable !windowfunc { finish_test ; return }
+do_execsql_test 1.0 {
+ DROP TABLE IF EXISTS t3;
+ CREATE TABLE t3(a TEXT, b TEXT, c INTEGER);
+ INSERT INTO t3 VALUES
+ ('HH', 'bb', 355), ('CC', 'aa', 158), ('BB', 'aa', 399),
+ ('FF', 'bb', 938), ('HH', 'aa', 480), ('FF', 'bb', 870),
+ ('JJ', 'aa', 768), ('JJ', 'aa', 899), ('GG', 'bb', 929),
+ ('II', 'bb', 421), ('GG', 'bb', 844), ('FF', 'bb', 574),
+ ('CC', 'bb', 822), ('GG', 'bb', 938), ('BB', 'aa', 660),
+ ('HH', 'aa', 979), ('BB', 'bb', 792), ('DD', 'aa', 845),
+ ('JJ', 'bb', 354), ('FF', 'bb', 295), ('JJ', 'aa', 234),
+ ('BB', 'bb', 840), ('AA', 'aa', 934), ('EE', 'aa', 113),
+ ('AA', 'bb', 309), ('BB', 'aa', 412), ('AA', 'aa', 911),
+ ('AA', 'bb', 572), ('II', 'aa', 398), ('II', 'bb', 250),
+ ('II', 'aa', 652), ('BB', 'bb', 633), ('AA', 'aa', 239),
+ ('FF', 'aa', 670), ('BB', 'bb', 705), ('HH', 'bb', 963),
+ ('CC', 'bb', 346), ('II', 'bb', 671), ('BB', 'aa', 247),
+ ('AA', 'aa', 223), ('GG', 'aa', 480), ('HH', 'aa', 790),
+ ('FF', 'aa', 208), ('BB', 'bb', 711), ('EE', 'aa', 777),
+ ('DD', 'bb', 716), ('CC', 'aa', 759), ('CC', 'aa', 430),
+ ('CC', 'aa', 607), ('DD', 'bb', 794), ('GG', 'aa', 148),
+ ('GG', 'aa', 634), ('JJ', 'bb', 257), ('DD', 'bb', 959),
+ ('FF', 'bb', 726), ('BB', 'aa', 762), ('JJ', 'bb', 336),
+ ('GG', 'aa', 335), ('HH', 'bb', 330), ('GG', 'bb', 160),
+ ('JJ', 'bb', 839), ('FF', 'aa', 618), ('BB', 'aa', 393),
+ ('EE', 'bb', 629), ('FF', 'aa', 667), ('AA', 'bb', 870),
+ ('FF', 'bb', 102), ('JJ', 'aa', 113), ('DD', 'aa', 224),
+ ('AA', 'bb', 627), ('HH', 'bb', 730), ('II', 'bb', 443),
+ ('HH', 'bb', 133), ('EE', 'bb', 252), ('II', 'bb', 805),
+ ('BB', 'bb', 786), ('EE', 'bb', 768), ('HH', 'bb', 683),
+ ('DD', 'bb', 238), ('DD', 'aa', 256);
+} {}
+
+do_execsql_test 1.1.1 {
+ SELECT a, b, sum(c) OVER (ORDER BY a GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb {} AA bb {} AA bb {}
+ AA bb {} BB aa 4685 BB aa 4685 BB aa 4685 BB aa 4685 BB aa 4685
+ BB aa 4685 BB bb 4685 BB bb 4685 BB bb 4685 BB bb 4685 BB bb 4685
+ BB bb 4685 CC aa 12025 CC aa 12025 CC aa 12025 CC aa 12025
+ CC bb 12025 CC bb 12025 DD aa 15147 DD aa 15147 DD aa 15147
+ DD bb 15147 DD bb 15147 DD bb 15147 DD bb 15147 EE aa 19179
+ EE aa 19179 EE bb 19179 EE bb 19179 EE bb 19179 FF aa 21718
+ FF aa 21718 FF aa 21718 FF aa 21718 FF bb 21718 FF bb 21718
+ FF bb 21718 FF bb 21718 FF bb 21718 FF bb 21718 GG aa 27386
+ GG aa 27386 GG aa 27386 GG aa 27386 GG bb 27386 GG bb 27386
+ GG bb 27386 GG bb 27386 HH aa 31854 HH aa 31854 HH aa 31854
+ HH bb 31854 HH bb 31854 HH bb 31854 HH bb 31854 HH bb 31854
+ HH bb 31854 II aa 37297 II aa 37297 II bb 37297 II bb 37297
+ II bb 37297 II bb 37297 II bb 37297 JJ aa 40937 JJ aa 40937
+ JJ aa 40937 JJ aa 40937 JJ bb 40937 JJ bb 40937 JJ bb 40937
+ JJ bb 40937}
+
+do_execsql_test 1.1.2 {
+ SELECT a, b, sum(c) OVER (ORDER BY a,b GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb 2307 AA bb 2307
+ AA bb 2307 AA bb 2307 BB aa 4685 BB aa 4685 BB aa 4685 BB aa 4685
+ BB aa 4685 BB aa 4685 BB bb 7558 BB bb 7558 BB bb 7558 BB bb 7558
+ BB bb 7558 BB bb 7558 CC aa 12025 CC aa 12025 CC aa 12025
+ CC aa 12025 CC bb 13979 CC bb 13979 DD aa 15147 DD aa 15147
+ DD aa 15147 DD bb 16472 DD bb 16472 DD bb 16472 DD bb 16472
+ EE aa 19179 EE aa 19179 EE bb 20069 EE bb 20069 EE bb 20069
+ FF aa 21718 FF aa 21718 FF aa 21718 FF aa 21718 FF bb 23881
+ FF bb 23881 FF bb 23881 FF bb 23881 FF bb 23881 FF bb 23881
+ GG aa 27386 GG aa 27386 GG aa 27386 GG aa 27386 GG bb 28983
+ GG bb 28983 GG bb 28983 GG bb 28983 HH aa 31854 HH aa 31854
+ HH aa 31854 HH bb 34103 HH bb 34103 HH bb 34103 HH bb 34103
+ HH bb 34103 HH bb 34103 II aa 37297 II aa 37297 II bb 38347
+ II bb 38347 II bb 38347 II bb 38347 II bb 38347 JJ aa 40937
+ JJ aa 40937 JJ aa 40937 JJ aa 40937 JJ bb 42951 JJ bb 42951
+ JJ bb 42951 JJ bb 42951}
+
+do_execsql_test 1.1.3 {
+ SELECT a, b, rank() OVER (ORDER BY a GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 1 AA aa 1 AA aa 1 AA aa 1 AA bb 1 AA bb 1 AA bb 1
+ AA bb 1 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9
+ BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 CC aa 21
+ CC aa 21 CC aa 21 CC aa 21 CC bb 21 CC bb 21 DD aa 27 DD aa 27
+ DD aa 27 DD bb 27 DD bb 27 DD bb 27 DD bb 27 EE aa 34 EE aa 34
+ EE bb 34 EE bb 34 EE bb 34 FF aa 39 FF aa 39 FF aa 39 FF aa 39
+ FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 GG aa 49
+ GG aa 49 GG aa 49 GG aa 49 GG bb 49 GG bb 49 GG bb 49 GG bb 49
+ HH aa 57 HH aa 57 HH aa 57 HH bb 57 HH bb 57 HH bb 57 HH bb 57
+ HH bb 57 HH bb 57 II aa 66 II aa 66 II bb 66 II bb 66 II bb 66
+ II bb 66 II bb 66 JJ aa 73 JJ aa 73 JJ aa 73 JJ aa 73 JJ bb 73
+ JJ bb 73 JJ bb 73 JJ bb 73}
+
+do_execsql_test 1.1.4 {
+ SELECT a, b, max(c) OVER (ORDER BY a,b GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb 934 AA bb 934
+ AA bb 934 AA bb 934 BB aa 934 BB aa 934 BB aa 934 BB aa 934
+ BB aa 934 BB aa 934 BB bb 934 BB bb 934 BB bb 934 BB bb 934
+ BB bb 934 BB bb 934 CC aa 934 CC aa 934 CC aa 934 CC aa 934
+ CC bb 934 CC bb 934 DD aa 934 DD aa 934 DD aa 934 DD bb 934
+ DD bb 934 DD bb 934 DD bb 934 EE aa 959 EE aa 959 EE bb 959
+ EE bb 959 EE bb 959 FF aa 959 FF aa 959 FF aa 959 FF aa 959
+ FF bb 959 FF bb 959 FF bb 959 FF bb 959 FF bb 959 FF bb 959
+ GG aa 959 GG aa 959 GG aa 959 GG aa 959 GG bb 959 GG bb 959
+ GG bb 959 GG bb 959 HH aa 959 HH aa 959 HH aa 959 HH bb 979
+ HH bb 979 HH bb 979 HH bb 979 HH bb 979 HH bb 979 II aa 979
+ II aa 979 II bb 979 II bb 979 II bb 979 II bb 979 II bb 979
+ JJ aa 979 JJ aa 979 JJ aa 979 JJ aa 979 JJ bb 979 JJ bb 979
+ JJ bb 979 JJ bb 979}
+
+do_execsql_test 1.1.5 {
+ SELECT a, b, min(c) OVER (ORDER BY a,b GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb 223 AA bb 223
+ AA bb 223 AA bb 223 BB aa 223 BB aa 223 BB aa 223 BB aa 223
+ BB aa 223 BB aa 223 BB bb 223 BB bb 223 BB bb 223 BB bb 223
+ BB bb 223 BB bb 223 CC aa 223 CC aa 223 CC aa 223 CC aa 223
+ CC bb 158 CC bb 158 DD aa 158 DD aa 158 DD aa 158 DD bb 158
+ DD bb 158 DD bb 158 DD bb 158 EE aa 158 EE aa 158 EE bb 113
+ EE bb 113 EE bb 113 FF aa 113 FF aa 113 FF aa 113 FF aa 113
+ FF bb 113 FF bb 113 FF bb 113 FF bb 113 FF bb 113 FF bb 113
+ GG aa 102 GG aa 102 GG aa 102 GG aa 102 GG bb 102 GG bb 102
+ GG bb 102 GG bb 102 HH aa 102 HH aa 102 HH aa 102 HH bb 102
+ HH bb 102 HH bb 102 HH bb 102 HH bb 102 HH bb 102 II aa 102
+ II aa 102 II bb 102 II bb 102 II bb 102 II bb 102 II bb 102
+ JJ aa 102 JJ aa 102 JJ aa 102 JJ aa 102 JJ bb 102 JJ bb 102
+ JJ bb 102 JJ bb 102}
+
+do_execsql_test 1.1.6 {
+ 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;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb {} AA bb {} AA bb {}
+ AA bb {} BB aa 4685 BB aa 4685 BB aa 4685 BB aa 4685 BB aa 4685
+ BB aa 4685 BB bb 4685 BB bb 4685 BB bb 4685 BB bb 4685 BB bb 4685
+ BB bb 4685 CC aa 12025 CC aa 12025 CC aa 12025 CC aa 12025
+ CC bb 12025 CC bb 12025 DD aa 15147 DD aa 15147 DD aa 15147
+ DD bb 15147 DD bb 15147 DD bb 15147 DD bb 15147 EE aa 19179
+ EE aa 19179 EE bb 19179 EE bb 19179 EE bb 19179 FF aa 21718
+ FF aa 21718 FF aa 21718 FF aa 21718 FF bb 21718 FF bb 21718
+ FF bb 21718 FF bb 21718 FF bb 21718 FF bb 21718 GG aa 27386
+ GG aa 27386 GG aa 27386 GG aa 27386 GG bb 27386 GG bb 27386
+ GG bb 27386 GG bb 27386 HH aa 31854 HH aa 31854 HH aa 31854
+ HH bb 31854 HH bb 31854 HH bb 31854 HH bb 31854 HH bb 31854
+ HH bb 31854 II aa 37297 II aa 37297 II bb 37297 II bb 37297
+ II bb 37297 II bb 37297 II bb 37297 JJ aa 40937 JJ aa 40937
+ JJ aa 40937 JJ aa 40937 JJ bb 40937 JJ bb 40937 JJ bb 40937
+ JJ bb 40937}
+
+do_execsql_test 1.1.7 {
+ 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;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb 2307 AA bb 2307
+ AA bb 2307 AA bb 2307 BB aa 4685 BB aa 4685 BB aa 4685 BB aa 4685
+ BB aa 4685 BB aa 4685 BB bb 7558 BB bb 7558 BB bb 7558 BB bb 7558
+ BB bb 7558 BB bb 7558 CC aa 12025 CC aa 12025 CC aa 12025
+ CC aa 12025 CC bb 13979 CC bb 13979 DD aa 15147 DD aa 15147
+ DD aa 15147 DD bb 16472 DD bb 16472 DD bb 16472 DD bb 16472
+ EE aa 19179 EE aa 19179 EE bb 20069 EE bb 20069 EE bb 20069
+ FF aa 21718 FF aa 21718 FF aa 21718 FF aa 21718 FF bb 23881
+ FF bb 23881 FF bb 23881 FF bb 23881 FF bb 23881 FF bb 23881
+ GG aa 27386 GG aa 27386 GG aa 27386 GG aa 27386 GG bb 28983
+ GG bb 28983 GG bb 28983 GG bb 28983 HH aa 31854 HH aa 31854
+ HH aa 31854 HH bb 34103 HH bb 34103 HH bb 34103 HH bb 34103
+ HH bb 34103 HH bb 34103 II aa 37297 II aa 37297 II bb 38347
+ II bb 38347 II bb 38347 II bb 38347 II bb 38347 JJ aa 40937
+ JJ aa 40937 JJ aa 40937 JJ aa 40937 JJ bb 42951 JJ bb 42951
+ JJ bb 42951 JJ bb 42951}
+
+do_execsql_test 1.1.8 {
+ SELECT a, b,
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING )
+ FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} {} {} {} AA aa {} {} {} {} AA aa {} {} {} {}
+ AA aa {} {} {} {} AA bb {} {} 2307 2307 AA bb {} {} 2307 2307
+ AA bb {} {} 2307 2307 AA bb {} {} 2307 2307 BB aa 4685 4685 4685 4685
+ BB aa 4685 4685 4685 4685 BB aa 4685 4685 4685 4685
+ BB aa 4685 4685 4685 4685 BB aa 4685 4685 4685 4685
+ BB aa 4685 4685 4685 4685 BB bb 4685 4685 7558 7558
+ BB bb 4685 4685 7558 7558 BB bb 4685 4685 7558 7558
+ BB bb 4685 4685 7558 7558 BB bb 4685 4685 7558 7558
+ BB bb 4685 4685 7558 7558 CC aa 12025 12025 12025 12025
+ CC aa 12025 12025 12025 12025 CC aa 12025 12025 12025 12025
+ CC aa 12025 12025 12025 12025 CC bb 12025 12025 13979 13979
+ CC bb 12025 12025 13979 13979 DD aa 15147 15147 15147 15147
+ DD aa 15147 15147 15147 15147 DD aa 15147 15147 15147 15147
+ DD bb 15147 15147 16472 16472 DD bb 15147 15147 16472 16472
+ DD bb 15147 15147 16472 16472 DD bb 15147 15147 16472 16472
+ EE aa 19179 19179 19179 19179 EE aa 19179 19179 19179 19179
+ EE bb 19179 19179 20069 20069 EE bb 19179 19179 20069 20069
+ EE bb 19179 19179 20069 20069 FF aa 21718 21718 21718 21718
+ FF aa 21718 21718 21718 21718 FF aa 21718 21718 21718 21718
+ FF aa 21718 21718 21718 21718 FF bb 21718 21718 23881 23881
+ FF bb 21718 21718 23881 23881 FF bb 21718 21718 23881 23881
+ FF bb 21718 21718 23881 23881 FF bb 21718 21718 23881 23881
+ FF bb 21718 21718 23881 23881 GG aa 27386 27386 27386 27386
+ GG aa 27386 27386 27386 27386 GG aa 27386 27386 27386 27386
+ GG aa 27386 27386 27386 27386 GG bb 27386 27386 28983 28983
+ GG bb 27386 27386 28983 28983 GG bb 27386 27386 28983 28983
+ GG bb 27386 27386 28983 28983 HH aa 31854 31854 31854 31854
+ HH aa 31854 31854 31854 31854 HH aa 31854 31854 31854 31854
+ HH bb 31854 31854 34103 34103 HH bb 31854 31854 34103 34103
+ HH bb 31854 31854 34103 34103 HH bb 31854 31854 34103 34103
+ HH bb 31854 31854 34103 34103 HH bb 31854 31854 34103 34103
+ II aa 37297 37297 37297 37297 II aa 37297 37297 37297 37297
+ II bb 37297 37297 38347 38347 II bb 37297 37297 38347 38347
+ II bb 37297 37297 38347 38347 II bb 37297 37297 38347 38347
+ II bb 37297 37297 38347 38347 JJ aa 40937 40937 40937 40937
+ JJ aa 40937 40937 40937 40937 JJ aa 40937 40937 40937 40937
+ JJ aa 40937 40937 40937 40937 JJ bb 40937 40937 42951 42951
+ JJ bb 40937 40937 42951 42951 JJ bb 40937 40937 42951 42951
+ JJ bb 40937 40937 42951 42951}
+
+do_execsql_test 1.2.1 {
+ SELECT a, b, sum(c) OVER (ORDER BY a GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 4685 AA aa 4685 AA aa 4685 AA aa 4685 AA bb 4685 AA bb 4685
+ AA bb 4685 AA bb 4685 BB aa 12025 BB aa 12025 BB aa 12025
+ BB aa 12025 BB aa 12025 BB aa 12025 BB bb 12025 BB bb 12025
+ BB bb 12025 BB bb 12025 BB bb 12025 BB bb 12025 CC aa 15147
+ CC aa 15147 CC aa 15147 CC aa 15147 CC bb 15147 CC bb 15147
+ DD aa 19179 DD aa 19179 DD aa 19179 DD bb 19179 DD bb 19179
+ DD bb 19179 DD bb 19179 EE aa 21718 EE aa 21718 EE bb 21718
+ EE bb 21718 EE bb 21718 FF aa 27386 FF aa 27386 FF aa 27386
+ FF aa 27386 FF bb 27386 FF bb 27386 FF bb 27386 FF bb 27386
+ FF bb 27386 FF bb 27386 GG aa 31854 GG aa 31854 GG aa 31854
+ GG aa 31854 GG bb 31854 GG bb 31854 GG bb 31854 GG bb 31854
+ HH aa 37297 HH aa 37297 HH aa 37297 HH bb 37297 HH bb 37297
+ HH bb 37297 HH bb 37297 HH bb 37297 HH bb 37297 II aa 40937
+ II aa 40937 II bb 40937 II bb 40937 II bb 40937 II bb 40937
+ II bb 40937 JJ aa 44737 JJ aa 44737 JJ aa 44737 JJ aa 44737
+ JJ bb 44737 JJ bb 44737 JJ bb 44737 JJ bb 44737}
+
+do_execsql_test 1.2.2 {
+ SELECT a, b, sum(c) OVER (ORDER BY a,b GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 2307 AA aa 2307 AA aa 2307 AA aa 2307 AA bb 4685 AA bb 4685
+ AA bb 4685 AA bb 4685 BB aa 7558 BB aa 7558 BB aa 7558 BB aa 7558
+ BB aa 7558 BB aa 7558 BB bb 12025 BB bb 12025 BB bb 12025
+ BB bb 12025 BB bb 12025 BB bb 12025 CC aa 13979 CC aa 13979
+ CC aa 13979 CC aa 13979 CC bb 15147 CC bb 15147 DD aa 16472
+ DD aa 16472 DD aa 16472 DD bb 19179 DD bb 19179 DD bb 19179
+ DD bb 19179 EE aa 20069 EE aa 20069 EE bb 21718 EE bb 21718
+ EE bb 21718 FF aa 23881 FF aa 23881 FF aa 23881 FF aa 23881
+ FF bb 27386 FF bb 27386 FF bb 27386 FF bb 27386 FF bb 27386
+ FF bb 27386 GG aa 28983 GG aa 28983 GG aa 28983 GG aa 28983
+ GG bb 31854 GG bb 31854 GG bb 31854 GG bb 31854 HH aa 34103
+ HH aa 34103 HH aa 34103 HH bb 37297 HH bb 37297 HH bb 37297
+ HH bb 37297 HH bb 37297 HH bb 37297 II aa 38347 II aa 38347
+ II bb 40937 II bb 40937 II bb 40937 II bb 40937 II bb 40937
+ JJ aa 42951 JJ aa 42951 JJ aa 42951 JJ aa 42951 JJ bb 44737
+ JJ bb 44737 JJ bb 44737 JJ bb 44737}
+
+do_execsql_test 1.2.3 {
+ SELECT a, b, rank() OVER (ORDER BY a GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 1 AA aa 1 AA aa 1 AA aa 1 AA bb 1 AA bb 1 AA bb 1
+ AA bb 1 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9
+ BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 CC aa 21
+ CC aa 21 CC aa 21 CC aa 21 CC bb 21 CC bb 21 DD aa 27 DD aa 27
+ DD aa 27 DD bb 27 DD bb 27 DD bb 27 DD bb 27 EE aa 34 EE aa 34
+ EE bb 34 EE bb 34 EE bb 34 FF aa 39 FF aa 39 FF aa 39 FF aa 39
+ FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 GG aa 49
+ GG aa 49 GG aa 49 GG aa 49 GG bb 49 GG bb 49 GG bb 49 GG bb 49
+ HH aa 57 HH aa 57 HH aa 57 HH bb 57 HH bb 57 HH bb 57 HH bb 57
+ HH bb 57 HH bb 57 II aa 66 II aa 66 II bb 66 II bb 66 II bb 66
+ II bb 66 II bb 66 JJ aa 73 JJ aa 73 JJ aa 73 JJ aa 73 JJ bb 73
+ JJ bb 73 JJ bb 73 JJ bb 73}
+
+do_execsql_test 1.2.4 {
+ SELECT a, b, max(c) OVER (ORDER BY a,b GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 934 AA aa 934 AA aa 934 AA aa 934 AA bb 934 AA bb 934
+ AA bb 934 AA bb 934 BB aa 934 BB aa 934 BB aa 934 BB aa 934
+ BB aa 934 BB aa 934 BB bb 934 BB bb 934 BB bb 934 BB bb 934
+ BB bb 934 BB bb 934 CC aa 934 CC aa 934 CC aa 934 CC aa 934
+ CC bb 934 CC bb 934 DD aa 934 DD aa 934 DD aa 934 DD bb 959
+ DD bb 959 DD bb 959 DD bb 959 EE aa 959 EE aa 959 EE bb 959
+ EE bb 959 EE bb 959 FF aa 959 FF aa 959 FF aa 959 FF aa 959
+ FF bb 959 FF bb 959 FF bb 959 FF bb 959 FF bb 959 FF bb 959
+ GG aa 959 GG aa 959 GG aa 959 GG aa 959 GG bb 959 GG bb 959
+ GG bb 959 GG bb 959 HH aa 979 HH aa 979 HH aa 979 HH bb 979
+ HH bb 979 HH bb 979 HH bb 979 HH bb 979 HH bb 979 II aa 979
+ II aa 979 II bb 979 II bb 979 II bb 979 II bb 979 II bb 979
+ JJ aa 979 JJ aa 979 JJ aa 979 JJ aa 979 JJ bb 979 JJ bb 979
+ JJ bb 979 JJ bb 979}
+
+do_execsql_test 1.2.5 {
+ SELECT a, b, min(c) OVER (ORDER BY a,b GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 223 AA aa 223 AA aa 223 AA aa 223 AA bb 223 AA bb 223
+ AA bb 223 AA bb 223 BB aa 223 BB aa 223 BB aa 223 BB aa 223
+ BB aa 223 BB aa 223 BB bb 223 BB bb 223 BB bb 223 BB bb 223
+ BB bb 223 BB bb 223 CC aa 158 CC aa 158 CC aa 158 CC aa 158
+ CC bb 158 CC bb 158 DD aa 158 DD aa 158 DD aa 158 DD bb 158
+ DD bb 158 DD bb 158 DD bb 158 EE aa 113 EE aa 113 EE bb 113
+ EE bb 113 EE bb 113 FF aa 113 FF aa 113 FF aa 113 FF aa 113
+ FF bb 102 FF bb 102 FF bb 102 FF bb 102 FF bb 102 FF bb 102
+ GG aa 102 GG aa 102 GG aa 102 GG aa 102 GG bb 102 GG bb 102
+ GG bb 102 GG bb 102 HH aa 102 HH aa 102 HH aa 102 HH bb 102
+ HH bb 102 HH bb 102 HH bb 102 HH bb 102 HH bb 102 II aa 102
+ II aa 102 II bb 102 II bb 102 II bb 102 II bb 102 II bb 102
+ JJ aa 102 JJ aa 102 JJ aa 102 JJ aa 102 JJ bb 102 JJ bb 102
+ JJ bb 102 JJ bb 102}
+
+do_execsql_test 1.2.6 {
+ 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;
+} {AA aa 3751 AA aa 3774 AA aa 4446 AA aa 4462 AA bb 3815 AA bb 4058
+ AA bb 4113 AA bb 4376 BB aa 11263 BB aa 11365 BB aa 11613
+ BB aa 11626 BB aa 11632 BB aa 11778 BB bb 11185 BB bb 11233
+ BB bb 11239 BB bb 11314 BB bb 11320 BB bb 11392 CC aa 14388
+ CC aa 14540 CC aa 14717 CC aa 14989 CC bb 14325 CC bb 14801
+ DD aa 18334 DD aa 18923 DD aa 18955 DD bb 18220 DD bb 18385
+ DD bb 18463 DD bb 18941 EE aa 20941 EE aa 21605 EE bb 20950
+ EE bb 21089 EE bb 21466 FF aa 26716 FF aa 26719 FF aa 26768
+ FF aa 27178 FF bb 26448 FF bb 26516 FF bb 26660 FF bb 26812
+ FF bb 27091 FF bb 27284 GG aa 31220 GG aa 31374 GG aa 31519
+ GG aa 31706 GG bb 30916 GG bb 30925 GG bb 31010 GG bb 31694
+ HH aa 36318 HH aa 36507 HH aa 36817 HH bb 36334 HH bb 36567
+ HH bb 36614 HH bb 36942 HH bb 36967 HH bb 37164 II aa 40285
+ II aa 40539 II bb 40132 II bb 40266 II bb 40494 II bb 40516
+ II bb 40687 JJ aa 43838 JJ aa 43969 JJ aa 44503 JJ aa 44624
+ JJ bb 43898 JJ bb 44383 JJ bb 44401 JJ bb 44480}
+
+do_execsql_test 1.2.7 {
+ 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;
+} {AA aa 1373 AA aa 1396 AA aa 2068 AA aa 2084 AA bb 3815 AA bb 4058
+ AA bb 4113 AA bb 4376 BB aa 6796 BB aa 6898 BB aa 7146 BB aa 7159
+ BB aa 7165 BB aa 7311 BB bb 11185 BB bb 11233 BB bb 11239
+ BB bb 11314 BB bb 11320 BB bb 11392 CC aa 13220 CC aa 13372
+ CC aa 13549 CC aa 13821 CC bb 14325 CC bb 14801 DD aa 15627
+ DD aa 16216 DD aa 16248 DD bb 18220 DD bb 18385 DD bb 18463
+ DD bb 18941 EE aa 19292 EE aa 19956 EE bb 20950 EE bb 21089
+ EE bb 21466 FF aa 23211 FF aa 23214 FF aa 23263 FF aa 23673
+ FF bb 26448 FF bb 26516 FF bb 26660 FF bb 26812 FF bb 27091
+ FF bb 27284 GG aa 28349 GG aa 28503 GG aa 28648 GG aa 28835
+ GG bb 30916 GG bb 30925 GG bb 31010 GG bb 31694 HH aa 33124
+ HH aa 33313 HH aa 33623 HH bb 36334 HH bb 36567 HH bb 36614
+ HH bb 36942 HH bb 36967 HH bb 37164 II aa 37695 II aa 37949
+ II bb 40132 II bb 40266 II bb 40494 II bb 40516 II bb 40687
+ JJ aa 42052 JJ aa 42183 JJ aa 42717 JJ aa 42838 JJ bb 43898
+ JJ bb 44383 JJ bb 44401 JJ bb 44480}
+
+do_execsql_test 1.2.8 {
+ SELECT a, b,
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW )
+ FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 3751 4685 1373 2307 AA aa 3774 4685 1396 2307
+ AA aa 4446 4685 2068 2307 AA aa 4462 4685 2084 2307
+ AA bb 3815 4685 3815 4685 AA bb 4058 4685 4058 4685
+ AA bb 4113 4685 4113 4685 AA bb 4376 4685 4376 4685
+ BB aa 11263 12025 6796 7558 BB aa 11365 12025 6898 7558
+ BB aa 11613 12025 7146 7558 BB aa 11626 12025 7159 7558
+ BB aa 11632 12025 7165 7558 BB aa 11778 12025 7311 7558
+ BB bb 11185 12025 11185 12025 BB bb 11233 12025 11233 12025
+ BB bb 11239 12025 11239 12025 BB bb 11314 12025 11314 12025
+ BB bb 11320 12025 11320 12025 BB bb 11392 12025 11392 12025
+ CC aa 14388 15147 13220 13979 CC aa 14540 15147 13372 13979
+ CC aa 14717 15147 13549 13979 CC aa 14989 15147 13821 13979
+ CC bb 14325 15147 14325 15147 CC bb 14801 15147 14801 15147
+ DD aa 18334 19179 15627 16472 DD aa 18923 19179 16216 16472
+ DD aa 18955 19179 16248 16472 DD bb 18220 19179 18220 19179
+ DD bb 18385 19179 18385 19179 DD bb 18463 19179 18463 19179
+ DD bb 18941 19179 18941 19179 EE aa 20941 21718 19292 20069
+ EE aa 21605 21718 19956 20069 EE bb 20950 21718 20950 21718
+ EE bb 21089 21718 21089 21718 EE bb 21466 21718 21466 21718
+ FF aa 26716 27386 23211 23881 FF aa 26719 27386 23214 23881
+ FF aa 26768 27386 23263 23881 FF aa 27178 27386 23673 23881
+ FF bb 26448 27386 26448 27386 FF bb 26516 27386 26516 27386
+ FF bb 26660 27386 26660 27386 FF bb 26812 27386 26812 27386
+ FF bb 27091 27386 27091 27386 FF bb 27284 27386 27284 27386
+ GG aa 31220 31854 28349 28983 GG aa 31374 31854 28503 28983
+ GG aa 31519 31854 28648 28983 GG aa 31706 31854 28835 28983
+ GG bb 30916 31854 30916 31854 GG bb 30925 31854 30925 31854
+ GG bb 31010 31854 31010 31854 GG bb 31694 31854 31694 31854
+ HH aa 36318 37297 33124 34103 HH aa 36507 37297 33313 34103
+ HH aa 36817 37297 33623 34103 HH bb 36334 37297 36334 37297
+ HH bb 36567 37297 36567 37297 HH bb 36614 37297 36614 37297
+ HH bb 36942 37297 36942 37297 HH bb 36967 37297 36967 37297
+ HH bb 37164 37297 37164 37297 II aa 40285 40937 37695 38347
+ II aa 40539 40937 37949 38347 II bb 40132 40937 40132 40937
+ II bb 40266 40937 40266 40937 II bb 40494 40937 40494 40937
+ II bb 40516 40937 40516 40937 II bb 40687 40937 40687 40937
+ JJ aa 43838 44737 42052 42951 JJ aa 43969 44737 42183 42951
+ JJ aa 44503 44737 42717 42951 JJ aa 44624 44737 42838 42951
+ JJ bb 43898 44737 43898 44737 JJ bb 44383 44737 44383 44737
+ JJ bb 44401 44737 44401 44737 JJ bb 44480 44737 44480 44737}
+
+do_execsql_test 1.3.1 {
+ SELECT a, b, sum(c) OVER (ORDER BY a GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 12025 AA aa 12025 AA aa 12025 AA aa 12025 AA bb 12025
+ AA bb 12025 AA bb 12025 AA bb 12025 BB aa 15147 BB aa 15147
+ BB aa 15147 BB aa 15147 BB aa 15147 BB aa 15147 BB bb 15147
+ BB bb 15147 BB bb 15147 BB bb 15147 BB bb 15147 BB bb 15147
+ CC aa 19179 CC aa 19179 CC aa 19179 CC aa 19179 CC bb 19179
+ CC bb 19179 DD aa 21718 DD aa 21718 DD aa 21718 DD bb 21718
+ DD bb 21718 DD bb 21718 DD bb 21718 EE aa 27386 EE aa 27386
+ EE bb 27386 EE bb 27386 EE bb 27386 FF aa 31854 FF aa 31854
+ FF aa 31854 FF aa 31854 FF bb 31854 FF bb 31854 FF bb 31854
+ FF bb 31854 FF bb 31854 FF bb 31854 GG aa 37297 GG aa 37297
+ GG aa 37297 GG aa 37297 GG bb 37297 GG bb 37297 GG bb 37297
+ GG bb 37297 HH aa 40937 HH aa 40937 HH aa 40937 HH bb 40937
+ HH bb 40937 HH bb 40937 HH bb 40937 HH bb 40937 HH bb 40937
+ II aa 44737 II aa 44737 II bb 44737 II bb 44737 II bb 44737
+ II bb 44737 II bb 44737 JJ aa 44737 JJ aa 44737 JJ aa 44737
+ JJ aa 44737 JJ bb 44737 JJ bb 44737 JJ bb 44737 JJ bb 44737}
+
+do_execsql_test 1.3.2 {
+ SELECT a, b, sum(c) OVER (ORDER BY a,b GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 4685 AA aa 4685 AA aa 4685 AA aa 4685 AA bb 7558 AA bb 7558
+ AA bb 7558 AA bb 7558 BB aa 12025 BB aa 12025 BB aa 12025
+ BB aa 12025 BB aa 12025 BB aa 12025 BB bb 13979 BB bb 13979
+ BB bb 13979 BB bb 13979 BB bb 13979 BB bb 13979 CC aa 15147
+ CC aa 15147 CC aa 15147 CC aa 15147 CC bb 16472 CC bb 16472
+ DD aa 19179 DD aa 19179 DD aa 19179 DD bb 20069 DD bb 20069
+ DD bb 20069 DD bb 20069 EE aa 21718 EE aa 21718 EE bb 23881
+ EE bb 23881 EE bb 23881 FF aa 27386 FF aa 27386 FF aa 27386
+ FF aa 27386 FF bb 28983 FF bb 28983 FF bb 28983 FF bb 28983
+ FF bb 28983 FF bb 28983 GG aa 31854 GG aa 31854 GG aa 31854
+ GG aa 31854 GG bb 34103 GG bb 34103 GG bb 34103 GG bb 34103
+ HH aa 37297 HH aa 37297 HH aa 37297 HH bb 38347 HH bb 38347
+ HH bb 38347 HH bb 38347 HH bb 38347 HH bb 38347 II aa 40937
+ II aa 40937 II bb 42951 II bb 42951 II bb 42951 II bb 42951
+ II bb 42951 JJ aa 44737 JJ aa 44737 JJ aa 44737 JJ aa 44737
+ JJ bb 44737 JJ bb 44737 JJ bb 44737 JJ bb 44737}
+
+do_execsql_test 1.3.3 {
+ SELECT a, b, rank() OVER (ORDER BY a GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 1 AA aa 1 AA aa 1 AA aa 1 AA bb 1 AA bb 1 AA bb 1
+ AA bb 1 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9
+ BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 CC aa 21
+ CC aa 21 CC aa 21 CC aa 21 CC bb 21 CC bb 21 DD aa 27 DD aa 27
+ DD aa 27 DD bb 27 DD bb 27 DD bb 27 DD bb 27 EE aa 34 EE aa 34
+ EE bb 34 EE bb 34 EE bb 34 FF aa 39 FF aa 39 FF aa 39 FF aa 39
+ FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 GG aa 49
+ GG aa 49 GG aa 49 GG aa 49 GG bb 49 GG bb 49 GG bb 49 GG bb 49
+ HH aa 57 HH aa 57 HH aa 57 HH bb 57 HH bb 57 HH bb 57 HH bb 57
+ HH bb 57 HH bb 57 II aa 66 II aa 66 II bb 66 II bb 66 II bb 66
+ II bb 66 II bb 66 JJ aa 73 JJ aa 73 JJ aa 73 JJ aa 73 JJ bb 73
+ JJ bb 73 JJ bb 73 JJ bb 73}
+
+do_execsql_test 1.3.4 {
+ SELECT a, b, max(c) OVER (ORDER BY a,b GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 934 AA aa 934 AA aa 934 AA aa 934 AA bb 934 AA bb 934
+ AA bb 934 AA bb 934 BB aa 934 BB aa 934 BB aa 934 BB aa 934
+ BB aa 934 BB aa 934 BB bb 934 BB bb 934 BB bb 934 BB bb 934
+ BB bb 934 BB bb 934 CC aa 934 CC aa 934 CC aa 934 CC aa 934
+ CC bb 934 CC bb 934 DD aa 959 DD aa 959 DD aa 959 DD bb 959
+ DD bb 959 DD bb 959 DD bb 959 EE aa 959 EE aa 959 EE bb 959
+ EE bb 959 EE bb 959 FF aa 959 FF aa 959 FF aa 959 FF aa 959
+ FF bb 959 FF bb 959 FF bb 959 FF bb 959 FF bb 959 FF bb 959
+ GG aa 959 GG aa 959 GG aa 959 GG aa 959 GG bb 979 GG bb 979
+ GG bb 979 GG bb 979 HH aa 979 HH aa 979 HH aa 979 HH bb 979
+ HH bb 979 HH bb 979 HH bb 979 HH bb 979 HH bb 979 II aa 979
+ II aa 979 II bb 979 II bb 979 II bb 979 II bb 979 II bb 979
+ JJ aa 979 JJ aa 979 JJ aa 979 JJ aa 979 JJ bb 979 JJ bb 979
+ JJ bb 979 JJ bb 979}
+
+do_execsql_test 1.3.5 {
+ SELECT a, b, min(c) OVER (ORDER BY a,b GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 223 AA aa 223 AA aa 223 AA aa 223 AA bb 223 AA bb 223
+ AA bb 223 AA bb 223 BB aa 223 BB aa 223 BB aa 223 BB aa 223
+ BB aa 223 BB aa 223 BB bb 158 BB bb 158 BB bb 158 BB bb 158
+ BB bb 158 BB bb 158 CC aa 158 CC aa 158 CC aa 158 CC aa 158
+ CC bb 158 CC bb 158 DD aa 158 DD aa 158 DD aa 158 DD bb 113
+ DD bb 113 DD bb 113 DD bb 113 EE aa 113 EE aa 113 EE bb 113
+ EE bb 113 EE bb 113 FF aa 102 FF aa 102 FF aa 102 FF aa 102
+ FF bb 102 FF bb 102 FF bb 102 FF bb 102 FF bb 102 FF bb 102
+ GG aa 102 GG aa 102 GG aa 102 GG aa 102 GG bb 102 GG bb 102
+ GG bb 102 GG bb 102 HH aa 102 HH aa 102 HH aa 102 HH bb 102
+ HH bb 102 HH bb 102 HH bb 102 HH bb 102 HH bb 102 II aa 102
+ II aa 102 II bb 102 II bb 102 II bb 102 II bb 102 II bb 102
+ JJ aa 102 JJ aa 102 JJ aa 102 JJ aa 102 JJ bb 102 JJ bb 102
+ JJ bb 102 JJ bb 102}
+
+do_execsql_test 1.3.6 {
+ 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;
+} {AA aa 11091 AA aa 11114 AA aa 11786 AA aa 11802 AA bb 11155
+ AA bb 11398 AA bb 11453 AA bb 11716 BB aa 14385 BB aa 14487
+ BB aa 14735 BB aa 14748 BB aa 14754 BB aa 14900 BB bb 14307
+ BB bb 14355 BB bb 14361 BB bb 14436 BB bb 14442 BB bb 14514
+ CC aa 18420 CC aa 18572 CC aa 18749 CC aa 19021 CC bb 18357
+ CC bb 18833 DD aa 20873 DD aa 21462 DD aa 21494 DD bb 20759
+ DD bb 20924 DD bb 21002 DD bb 21480 EE aa 26609 EE aa 27273
+ EE bb 26618 EE bb 26757 EE bb 27134 FF aa 31184 FF aa 31187
+ FF aa 31236 FF aa 31646 FF bb 30916 FF bb 30984 FF bb 31128
+ FF bb 31280 FF bb 31559 FF bb 31752 GG aa 36663 GG aa 36817
+ GG aa 36962 GG aa 37149 GG bb 36359 GG bb 36368 GG bb 36453
+ GG bb 37137 HH aa 39958 HH aa 40147 HH aa 40457 HH bb 39974
+ HH bb 40207 HH bb 40254 HH bb 40582 HH bb 40607 HH bb 40804
+ II aa 44085 II aa 44339 II bb 43932 II bb 44066 II bb 44294
+ II bb 44316 II bb 44487 JJ aa 43838 JJ aa 43969 JJ aa 44503
+ JJ aa 44624 JJ bb 43898 JJ bb 44383 JJ bb 44401 JJ bb 44480}
+
+do_execsql_test 1.3.7 {
+ 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;
+} {AA aa 3751 AA aa 3774 AA aa 4446 AA aa 4462 AA bb 6688 AA bb 6931
+ AA bb 6986 AA bb 7249 BB aa 11263 BB aa 11365 BB aa 11613
+ BB aa 11626 BB aa 11632 BB aa 11778 BB bb 13139 BB bb 13187
+ BB bb 13193 BB bb 13268 BB bb 13274 BB bb 13346 CC aa 14388
+ CC aa 14540 CC aa 14717 CC aa 14989 CC bb 15650 CC bb 16126
+ DD aa 18334 DD aa 18923 DD aa 18955 DD bb 19110 DD bb 19275
+ DD bb 19353 DD bb 19831 EE aa 20941 EE aa 21605 EE bb 23113
+ EE bb 23252 EE bb 23629 FF aa 26716 FF aa 26719 FF aa 26768
+ FF aa 27178 FF bb 28045 FF bb 28113 FF bb 28257 FF bb 28409
+ FF bb 28688 FF bb 28881 GG aa 31220 GG aa 31374 GG aa 31519
+ GG aa 31706 GG bb 33165 GG bb 33174 GG bb 33259 GG bb 33943
+ HH aa 36318 HH aa 36507 HH aa 36817 HH bb 37384 HH bb 37617
+ HH bb 37664 HH bb 37992 HH bb 38017 HH bb 38214 II aa 40285
+ II aa 40539 II bb 42146 II bb 42280 II bb 42508 II bb 42530
+ II bb 42701 JJ aa 43838 JJ aa 43969 JJ aa 44503 JJ aa 44624
+ JJ bb 43898 JJ bb 44383 JJ bb 44401 JJ bb 44480}
+
+do_execsql_test 1.3.8 {
+ SELECT a, b,
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING ),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING )
+ FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 11091 12025 3751 4685 AA aa 11114 12025 3774 4685
+ AA aa 11786 12025 4446 4685 AA aa 11802 12025 4462 4685
+ AA bb 11155 12025 6688 7558 AA bb 11398 12025 6931 7558
+ AA bb 11453 12025 6986 7558 AA bb 11716 12025 7249 7558
+ BB aa 14385 15147 11263 12025 BB aa 14487 15147 11365 12025
+ BB aa 14735 15147 11613 12025 BB aa 14748 15147 11626 12025
+ BB aa 14754 15147 11632 12025 BB aa 14900 15147 11778 12025
+ BB bb 14307 15147 13139 13979 BB bb 14355 15147 13187 13979
+ BB bb 14361 15147 13193 13979 BB bb 14436 15147 13268 13979
+ BB bb 14442 15147 13274 13979 BB bb 14514 15147 13346 13979
+ CC aa 18420 19179 14388 15147 CC aa 18572 19179 14540 15147
+ CC aa 18749 19179 14717 15147 CC aa 19021 19179 14989 15147
+ CC bb 18357 19179 15650 16472 CC bb 18833 19179 16126 16472
+ DD aa 20873 21718 18334 19179 DD aa 21462 21718 18923 19179
+ DD aa 21494 21718 18955 19179 DD bb 20759 21718 19110 20069
+ DD bb 20924 21718 19275 20069 DD bb 21002 21718 19353 20069
+ DD bb 21480 21718 19831 20069 EE aa 26609 27386 20941 21718
+ EE aa 27273 27386 21605 21718 EE bb 26618 27386 23113 23881
+ EE bb 26757 27386 23252 23881 EE bb 27134 27386 23629 23881
+ FF aa 31184 31854 26716 27386 FF aa 31187 31854 26719 27386
+ FF aa 31236 31854 26768 27386 FF aa 31646 31854 27178 27386
+ FF bb 30916 31854 28045 28983 FF bb 30984 31854 28113 28983
+ FF bb 31128 31854 28257 28983 FF bb 31280 31854 28409 28983
+ FF bb 31559 31854 28688 28983 FF bb 31752 31854 28881 28983
+ GG aa 36663 37297 31220 31854 GG aa 36817 37297 31374 31854
+ GG aa 36962 37297 31519 31854 GG aa 37149 37297 31706 31854
+ GG bb 36359 37297 33165 34103 GG bb 36368 37297 33174 34103
+ GG bb 36453 37297 33259 34103 GG bb 37137 37297 33943 34103
+ HH aa 39958 40937 36318 37297 HH aa 40147 40937 36507 37297
+ HH aa 40457 40937 36817 37297 HH bb 39974 40937 37384 38347
+ HH bb 40207 40937 37617 38347 HH bb 40254 40937 37664 38347
+ HH bb 40582 40937 37992 38347 HH bb 40607 40937 38017 38347
+ HH bb 40804 40937 38214 38347 II aa 44085 44737 40285 40937
+ II aa 44339 44737 40539 40937 II bb 43932 44737 42146 42951
+ II bb 44066 44737 42280 42951 II bb 44294 44737 42508 42951
+ II bb 44316 44737 42530 42951 II bb 44487 44737 42701 42951
+ JJ aa 43838 44737 43838 44737 JJ aa 43969 44737 43969 44737
+ JJ aa 44503 44737 44503 44737 JJ aa 44624 44737 44624 44737
+ JJ bb 43898 44737 43898 44737 JJ bb 44383 44737 44383 44737
+ JJ bb 44401 44737 44401 44737 JJ bb 44480 44737 44480 44737}
+
+do_execsql_test 1.4.1 {
+ SELECT a, b, sum(c) OVER (ORDER BY a GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 44737 AA aa 44737 AA aa 44737 AA aa 44737 AA bb 44737
+ AA bb 44737 AA bb 44737 AA bb 44737 BB aa 44737 BB aa 44737
+ BB aa 44737 BB aa 44737 BB aa 44737 BB aa 44737 BB bb 44737
+ BB bb 44737 BB bb 44737 BB bb 44737 BB bb 44737 BB bb 44737
+ CC aa 44737 CC aa 44737 CC aa 44737 CC aa 44737 CC bb 44737
+ CC bb 44737 DD aa 44737 DD aa 44737 DD aa 44737 DD bb 44737
+ DD bb 44737 DD bb 44737 DD bb 44737 EE aa 44737 EE aa 44737
+ EE bb 44737 EE bb 44737 EE bb 44737 FF aa 44737 FF aa 44737
+ FF aa 44737 FF aa 44737 FF bb 44737 FF bb 44737 FF bb 44737
+ FF bb 44737 FF bb 44737 FF bb 44737 GG aa 44737 GG aa 44737
+ GG aa 44737 GG aa 44737 GG bb 44737 GG bb 44737 GG bb 44737
+ GG bb 44737 HH aa 44737 HH aa 44737 HH aa 44737 HH bb 44737
+ HH bb 44737 HH bb 44737 HH bb 44737 HH bb 44737 HH bb 44737
+ II aa 44737 II aa 44737 II bb 44737 II bb 44737 II bb 44737
+ II bb 44737 II bb 44737 JJ aa 44737 JJ aa 44737 JJ aa 44737
+ JJ aa 44737 JJ bb 44737 JJ bb 44737 JJ bb 44737 JJ bb 44737}
+
+do_execsql_test 1.4.2 {
+ SELECT a, b, sum(c) OVER (ORDER BY a,b GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 44737 AA aa 44737 AA aa 44737 AA aa 44737 AA bb 44737
+ AA bb 44737 AA bb 44737 AA bb 44737 BB aa 44737 BB aa 44737
+ BB aa 44737 BB aa 44737 BB aa 44737 BB aa 44737 BB bb 44737
+ BB bb 44737 BB bb 44737 BB bb 44737 BB bb 44737 BB bb 44737
+ CC aa 44737 CC aa 44737 CC aa 44737 CC aa 44737 CC bb 44737
+ CC bb 44737 DD aa 44737 DD aa 44737 DD aa 44737 DD bb 44737
+ DD bb 44737 DD bb 44737 DD bb 44737 EE aa 44737 EE aa 44737
+ EE bb 44737 EE bb 44737 EE bb 44737 FF aa 44737 FF aa 44737
+ FF aa 44737 FF aa 44737 FF bb 44737 FF bb 44737 FF bb 44737
+ FF bb 44737 FF bb 44737 FF bb 44737 GG aa 44737 GG aa 44737
+ GG aa 44737 GG aa 44737 GG bb 44737 GG bb 44737 GG bb 44737
+ GG bb 44737 HH aa 44737 HH aa 44737 HH aa 44737 HH bb 44737
+ HH bb 44737 HH bb 44737 HH bb 44737 HH bb 44737 HH bb 44737
+ II aa 44737 II aa 44737 II bb 44737 II bb 44737 II bb 44737
+ II bb 44737 II bb 44737 JJ aa 44737 JJ aa 44737 JJ aa 44737
+ JJ aa 44737 JJ bb 44737 JJ bb 44737 JJ bb 44737 JJ bb 44737}
+
+do_execsql_test 1.4.3 {
+ SELECT a, b, rank() OVER (ORDER BY a GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 1 AA aa 1 AA aa 1 AA aa 1 AA bb 1 AA bb 1 AA bb 1
+ AA bb 1 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9
+ BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 CC aa 21
+ CC aa 21 CC aa 21 CC aa 21 CC bb 21 CC bb 21 DD aa 27 DD aa 27
+ DD aa 27 DD bb 27 DD bb 27 DD bb 27 DD bb 27 EE aa 34 EE aa 34
+ EE bb 34 EE bb 34 EE bb 34 FF aa 39 FF aa 39 FF aa 39 FF aa 39
+ FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 GG aa 49
+ GG aa 49 GG aa 49 GG aa 49 GG bb 49 GG bb 49 GG bb 49 GG bb 49
+ HH aa 57 HH aa 57 HH aa 57 HH bb 57 HH bb 57 HH bb 57 HH bb 57
+ HH bb 57 HH bb 57 II aa 66 II aa 66 II bb 66 II bb 66 II bb 66
+ II bb 66 II bb 66 JJ aa 73 JJ aa 73 JJ aa 73 JJ aa 73 JJ bb 73
+ JJ bb 73 JJ bb 73 JJ bb 73}
+
+do_execsql_test 1.4.4 {
+ SELECT a, b, max(c) OVER (ORDER BY a,b GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 979 AA aa 979 AA aa 979 AA aa 979 AA bb 979 AA bb 979
+ AA bb 979 AA bb 979 BB aa 979 BB aa 979 BB aa 979 BB aa 979
+ BB aa 979 BB aa 979 BB bb 979 BB bb 979 BB bb 979 BB bb 979
+ BB bb 979 BB bb 979 CC aa 979 CC aa 979 CC aa 979 CC aa 979
+ CC bb 979 CC bb 979 DD aa 979 DD aa 979 DD aa 979 DD bb 979
+ DD bb 979 DD bb 979 DD bb 979 EE aa 979 EE aa 979 EE bb 979
+ EE bb 979 EE bb 979 FF aa 979 FF aa 979 FF aa 979 FF aa 979
+ FF bb 979 FF bb 979 FF bb 979 FF bb 979 FF bb 979 FF bb 979
+ GG aa 979 GG aa 979 GG aa 979 GG aa 979 GG bb 979 GG bb 979
+ GG bb 979 GG bb 979 HH aa 979 HH aa 979 HH aa 979 HH bb 979
+ HH bb 979 HH bb 979 HH bb 979 HH bb 979 HH bb 979 II aa 979
+ II aa 979 II bb 979 II bb 979 II bb 979 II bb 979 II bb 979
+ JJ aa 979 JJ aa 979 JJ aa 979 JJ aa 979 JJ bb 979 JJ bb 979
+ JJ bb 979 JJ bb 979}
+
+do_execsql_test 1.4.5 {
+ SELECT a, b, min(c) OVER (ORDER BY a,b GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 102 AA aa 102 AA aa 102 AA aa 102 AA bb 102 AA bb 102
+ AA bb 102 AA bb 102 BB aa 102 BB aa 102 BB aa 102 BB aa 102
+ BB aa 102 BB aa 102 BB bb 102 BB bb 102 BB bb 102 BB bb 102
+ BB bb 102 BB bb 102 CC aa 102 CC aa 102 CC aa 102 CC aa 102
+ CC bb 102 CC bb 102 DD aa 102 DD aa 102 DD aa 102 DD bb 102
+ DD bb 102 DD bb 102 DD bb 102 EE aa 102 EE aa 102 EE bb 102
+ EE bb 102 EE bb 102 FF aa 102 FF aa 102 FF aa 102 FF aa 102
+ FF bb 102 FF bb 102 FF bb 102 FF bb 102 FF bb 102 FF bb 102
+ GG aa 102 GG aa 102 GG aa 102 GG aa 102 GG bb 102 GG bb 102
+ GG bb 102 GG bb 102 HH aa 102 HH aa 102 HH aa 102 HH bb 102
+ HH bb 102 HH bb 102 HH bb 102 HH bb 102 HH bb 102 II aa 102
+ II aa 102 II bb 102 II bb 102 II bb 102 II bb 102 II bb 102
+ JJ aa 102 JJ aa 102 JJ aa 102 JJ aa 102 JJ bb 102 JJ bb 102
+ JJ bb 102 JJ bb 102}
+
+do_execsql_test 1.4.6 {
+ 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;
+} {AA aa 43803 AA aa 43826 AA aa 44498 AA aa 44514 AA bb 43867
+ AA bb 44110 AA bb 44165 AA bb 44428 BB aa 43975 BB aa 44077
+ BB aa 44325 BB aa 44338 BB aa 44344 BB aa 44490 BB bb 43897
+ BB bb 43945 BB bb 43951 BB bb 44026 BB bb 44032 BB bb 44104
+ CC aa 43978 CC aa 44130 CC aa 44307 CC aa 44579 CC bb 43915
+ CC bb 44391 DD aa 43892 DD aa 44481 DD aa 44513 DD bb 43778
+ DD bb 43943 DD bb 44021 DD bb 44499 EE aa 43960 EE aa 44624
+ EE bb 43969 EE bb 44108 EE bb 44485 FF aa 44067 FF aa 44070
+ FF aa 44119 FF aa 44529 FF bb 43799 FF bb 43867 FF bb 44011
+ FF bb 44163 FF bb 44442 FF bb 44635 GG aa 44103 GG aa 44257
+ GG aa 44402 GG aa 44589 GG bb 43799 GG bb 43808 GG bb 43893
+ GG bb 44577 HH aa 43758 HH aa 43947 HH aa 44257 HH bb 43774
+ HH bb 44007 HH bb 44054 HH bb 44382 HH bb 44407 HH bb 44604
+ II aa 44085 II aa 44339 II bb 43932 II bb 44066 II bb 44294
+ II bb 44316 II bb 44487 JJ aa 43838 JJ aa 43969 JJ aa 44503
+ JJ aa 44624 JJ bb 43898 JJ bb 44383 JJ bb 44401 JJ bb 44480}
+
+do_execsql_test 1.4.7 {
+ 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;
+} {AA aa 43803 AA aa 43826 AA aa 44498 AA aa 44514 AA bb 43867
+ AA bb 44110 AA bb 44165 AA bb 44428 BB aa 43975 BB aa 44077
+ BB aa 44325 BB aa 44338 BB aa 44344 BB aa 44490 BB bb 43897
+ BB bb 43945 BB bb 43951 BB bb 44026 BB bb 44032 BB bb 44104
+ CC aa 43978 CC aa 44130 CC aa 44307 CC aa 44579 CC bb 43915
+ CC bb 44391 DD aa 43892 DD aa 44481 DD aa 44513 DD bb 43778
+ DD bb 43943 DD bb 44021 DD bb 44499 EE aa 43960 EE aa 44624
+ EE bb 43969 EE bb 44108 EE bb 44485 FF aa 44067 FF aa 44070
+ FF aa 44119 FF aa 44529 FF bb 43799 FF bb 43867 FF bb 44011
+ FF bb 44163 FF bb 44442 FF bb 44635 GG aa 44103 GG aa 44257
+ GG aa 44402 GG aa 44589 GG bb 43799 GG bb 43808 GG bb 43893
+ GG bb 44577 HH aa 43758 HH aa 43947 HH aa 44257 HH bb 43774
+ HH bb 44007 HH bb 44054 HH bb 44382 HH bb 44407 HH bb 44604
+ II aa 44085 II aa 44339 II bb 43932 II bb 44066 II bb 44294
+ II bb 44316 II bb 44487 JJ aa 43838 JJ aa 43969 JJ aa 44503
+ JJ aa 44624 JJ bb 43898 JJ bb 44383 JJ bb 44401 JJ bb 44480}
+
+do_execsql_test 1.4.8 {
+ SELECT a, b,
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING )
+ FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 43803 44737 43803 44737 AA aa 43826 44737 43826 44737
+ AA aa 44498 44737 44498 44737 AA aa 44514 44737 44514 44737
+ AA bb 43867 44737 43867 44737 AA bb 44110 44737 44110 44737
+ AA bb 44165 44737 44165 44737 AA bb 44428 44737 44428 44737
+ BB aa 43975 44737 43975 44737 BB aa 44077 44737 44077 44737
+ BB aa 44325 44737 44325 44737 BB aa 44338 44737 44338 44737
+ BB aa 44344 44737 44344 44737 BB aa 44490 44737 44490 44737
+ BB bb 43897 44737 43897 44737 BB bb 43945 44737 43945 44737
+ BB bb 43951 44737 43951 44737 BB bb 44026 44737 44026 44737
+ BB bb 44032 44737 44032 44737 BB bb 44104 44737 44104 44737
+ CC aa 43978 44737 43978 44737 CC aa 44130 44737 44130 44737
+ CC aa 44307 44737 44307 44737 CC aa 44579 44737 44579 44737
+ CC bb 43915 44737 43915 44737 CC bb 44391 44737 44391 44737
+ DD aa 43892 44737 43892 44737 DD aa 44481 44737 44481 44737
+ DD aa 44513 44737 44513 44737 DD bb 43778 44737 43778 44737
+ DD bb 43943 44737 43943 44737 DD bb 44021 44737 44021 44737
+ DD bb 44499 44737 44499 44737 EE aa 43960 44737 43960 44737
+ EE aa 44624 44737 44624 44737 EE bb 43969 44737 43969 44737
+ EE bb 44108 44737 44108 44737 EE bb 44485 44737 44485 44737
+ FF aa 44067 44737 44067 44737 FF aa 44070 44737 44070 44737
+ FF aa 44119 44737 44119 44737 FF aa 44529 44737 44529 44737
+ FF bb 43799 44737 43799 44737 FF bb 43867 44737 43867 44737
+ FF bb 44011 44737 44011 44737 FF bb 44163 44737 44163 44737
+ FF bb 44442 44737 44442 44737 FF bb 44635 44737 44635 44737
+ GG aa 44103 44737 44103 44737 GG aa 44257 44737 44257 44737
+ GG aa 44402 44737 44402 44737 GG aa 44589 44737 44589 44737
+ GG bb 43799 44737 43799 44737 GG bb 43808 44737 43808 44737
+ GG bb 43893 44737 43893 44737 GG bb 44577 44737 44577 44737
+ HH aa 43758 44737 43758 44737 HH aa 43947 44737 43947 44737
+ HH aa 44257 44737 44257 44737 HH bb 43774 44737 43774 44737
+ HH bb 44007 44737 44007 44737 HH bb 44054 44737 44054 44737
+ HH bb 44382 44737 44382 44737 HH bb 44407 44737 44407 44737
+ HH bb 44604 44737 44604 44737 II aa 44085 44737 44085 44737
+ II aa 44339 44737 44339 44737 II bb 43932 44737 43932 44737
+ II bb 44066 44737 44066 44737 II bb 44294 44737 44294 44737
+ II bb 44316 44737 44316 44737 II bb 44487 44737 44487 44737
+ JJ aa 43838 44737 43838 44737 JJ aa 43969 44737 43969 44737
+ JJ aa 44503 44737 44503 44737 JJ aa 44624 44737 44624 44737
+ JJ bb 43898 44737 43898 44737 JJ bb 44383 44737 44383 44737
+ JJ bb 44401 44737 44401 44737 JJ bb 44480 44737 44480 44737}
+
+do_execsql_test 1.5.1 {
+ SELECT a, b, sum(c) OVER (ORDER BY a GROUPS BETWEEN 1 PRECEDING AND 2 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb {} AA bb {} AA bb {}
+ AA bb {} BB aa {} BB aa {} BB aa {} BB aa {} BB aa {} BB aa {}
+ BB bb {} BB bb {} BB bb {} BB bb {} BB bb {} BB bb {} CC aa {}
+ CC aa {} CC aa {} CC aa {} CC bb {} CC bb {} DD aa {} DD aa {}
+ DD aa {} DD bb {} DD bb {} DD bb {} DD bb {} EE aa {} EE aa {}
+ EE bb {} EE bb {} EE bb {} FF aa {} FF aa {} FF aa {} FF aa {}
+ FF bb {} FF bb {} FF bb {} FF bb {} FF bb {} FF bb {} GG aa {}
+ GG aa {} GG aa {} GG aa {} GG bb {} GG bb {} GG bb {} GG bb {}
+ HH aa {} HH aa {} HH aa {} HH bb {} HH bb {} HH bb {} HH bb {}
+ HH bb {} HH bb {} II aa {} II aa {} II bb {} II bb {} II bb {}
+ II bb {} II bb {} JJ aa {} JJ aa {} JJ aa {} JJ aa {} JJ bb {}
+ JJ bb {} JJ bb {} JJ bb {}}
+
+do_execsql_test 1.5.2 {
+ SELECT a, b, sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 1 PRECEDING AND 2 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb {} AA bb {} AA bb {}
+ AA bb {} BB aa {} BB aa {} BB aa {} BB aa {} BB aa {} BB aa {}
+ BB bb {} BB bb {} BB bb {} BB bb {} BB bb {} BB bb {} CC aa {}
+ CC aa {} CC aa {} CC aa {} CC bb {} CC bb {} DD aa {} DD aa {}
+ DD aa {} DD bb {} DD bb {} DD bb {} DD bb {} EE aa {} EE aa {}
+ EE bb {} EE bb {} EE bb {} FF aa {} FF aa {} FF aa {} FF aa {}
+ FF bb {} FF bb {} FF bb {} FF bb {} FF bb {} FF bb {} GG aa {}
+ GG aa {} GG aa {} GG aa {} GG bb {} GG bb {} GG bb {} GG bb {}
+ HH aa {} HH aa {} HH aa {} HH bb {} HH bb {} HH bb {} HH bb {}
+ HH bb {} HH bb {} II aa {} II aa {} II bb {} II bb {} II bb {}
+ II bb {} II bb {} JJ aa {} JJ aa {} JJ aa {} JJ aa {} JJ bb {}
+ JJ bb {} JJ bb {} JJ bb {}}
+
+do_execsql_test 1.5.3 {
+ SELECT a, b, rank() OVER (ORDER BY a GROUPS BETWEEN 1 PRECEDING AND 2 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 1 AA aa 1 AA aa 1 AA aa 1 AA bb 1 AA bb 1 AA bb 1
+ AA bb 1 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9
+ BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 CC aa 21
+ CC aa 21 CC aa 21 CC aa 21 CC bb 21 CC bb 21 DD aa 27 DD aa 27
+ DD aa 27 DD bb 27 DD bb 27 DD bb 27 DD bb 27 EE aa 34 EE aa 34
+ EE bb 34 EE bb 34 EE bb 34 FF aa 39 FF aa 39 FF aa 39 FF aa 39
+ FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 GG aa 49
+ GG aa 49 GG aa 49 GG aa 49 GG bb 49 GG bb 49 GG bb 49 GG bb 49
+ HH aa 57 HH aa 57 HH aa 57 HH bb 57 HH bb 57 HH bb 57 HH bb 57
+ HH bb 57 HH bb 57 II aa 66 II aa 66 II bb 66 II bb 66 II bb 66
+ II bb 66 II bb 66 JJ aa 73 JJ aa 73 JJ aa 73 JJ aa 73 JJ bb 73
+ JJ bb 73 JJ bb 73 JJ bb 73}
+
+do_execsql_test 1.5.4 {
+ SELECT a, b, max(c) OVER (ORDER BY a,b GROUPS BETWEEN 1 PRECEDING AND 2 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb {} AA bb {} AA bb {}
+ AA bb {} BB aa {} BB aa {} BB aa {} BB aa {} BB aa {} BB aa {}
+ BB bb {} BB bb {} BB bb {} BB bb {} BB bb {} BB bb {} CC aa {}
+ CC aa {} CC aa {} CC aa {} CC bb {} CC bb {} DD aa {} DD aa {}
+ DD aa {} DD bb {} DD bb {} DD bb {} DD bb {} EE aa {} EE aa {}
+ EE bb {} EE bb {} EE bb {} FF aa {} FF aa {} FF aa {} FF aa {}
+ FF bb {} FF bb {} FF bb {} FF bb {} FF bb {} FF bb {} GG aa {}
+ GG aa {} GG aa {} GG aa {} GG bb {} GG bb {} GG bb {} GG bb {}
+ HH aa {} HH aa {} HH aa {} HH bb {} HH bb {} HH bb {} HH bb {}
+ HH bb {} HH bb {} II aa {} II aa {} II bb {} II bb {} II bb {}
+ II bb {} II bb {} JJ aa {} JJ aa {} JJ aa {} JJ aa {} JJ bb {}
+ JJ bb {} JJ bb {} JJ bb {}}
+
+do_execsql_test 1.5.5 {
+ SELECT a, b, min(c) OVER (ORDER BY a,b GROUPS BETWEEN 1 PRECEDING AND 2 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb {} AA bb {} AA bb {}
+ AA bb {} BB aa {} BB aa {} BB aa {} BB aa {} BB aa {} BB aa {}
+ BB bb {} BB bb {} BB bb {} BB bb {} BB bb {} BB bb {} CC aa {}
+ CC aa {} CC aa {} CC aa {} CC bb {} CC bb {} DD aa {} DD aa {}
+ DD aa {} DD bb {} DD bb {} DD bb {} DD bb {} EE aa {} EE aa {}
+ EE bb {} EE bb {} EE bb {} FF aa {} FF aa {} FF aa {} FF aa {}
+ FF bb {} FF bb {} FF bb {} FF bb {} FF bb {} FF bb {} GG aa {}
+ GG aa {} GG aa {} GG aa {} GG bb {} GG bb {} GG bb {} GG bb {}
+ HH aa {} HH aa {} HH aa {} HH bb {} HH bb {} HH bb {} HH bb {}
+ HH bb {} HH bb {} II aa {} II aa {} II bb {} II bb {} II bb {}
+ II bb {} II bb {} JJ aa {} JJ aa {} JJ aa {} JJ aa {} JJ bb {}
+ JJ bb {} JJ bb {} JJ bb {}}
+
+do_execsql_test 1.5.6 {
+ 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;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb {} AA bb {} AA bb {}
+ AA bb {} BB aa {} BB aa {} BB aa {} BB aa {} BB aa {} BB aa {}
+ BB bb {} BB bb {} BB bb {} BB bb {} BB bb {} BB bb {} CC aa {}
+ CC aa {} CC aa {} CC aa {} CC bb {} CC bb {} DD aa {} DD aa {}
+ DD aa {} DD bb {} DD bb {} DD bb {} DD bb {} EE aa {} EE aa {}
+ EE bb {} EE bb {} EE bb {} FF aa {} FF aa {} FF aa {} FF aa {}
+ FF bb {} FF bb {} FF bb {} FF bb {} FF bb {} FF bb {} GG aa {}
+ GG aa {} GG aa {} GG aa {} GG bb {} GG bb {} GG bb {} GG bb {}
+ HH aa {} HH aa {} HH aa {} HH bb {} HH bb {} HH bb {} HH bb {}
+ HH bb {} HH bb {} II aa {} II aa {} II bb {} II bb {} II bb {}
+ II bb {} II bb {} JJ aa {} JJ aa {} JJ aa {} JJ aa {} JJ bb {}
+ JJ bb {} JJ bb {} JJ bb {}}
+
+do_execsql_test 1.5.7 {
+ 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;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb {} AA bb {} AA bb {}
+ AA bb {} BB aa {} BB aa {} BB aa {} BB aa {} BB aa {} BB aa {}
+ BB bb {} BB bb {} BB bb {} BB bb {} BB bb {} BB bb {} CC aa {}
+ CC aa {} CC aa {} CC aa {} CC bb {} CC bb {} DD aa {} DD aa {}
+ DD aa {} DD bb {} DD bb {} DD bb {} DD bb {} EE aa {} EE aa {}
+ EE bb {} EE bb {} EE bb {} FF aa {} FF aa {} FF aa {} FF aa {}
+ FF bb {} FF bb {} FF bb {} FF bb {} FF bb {} FF bb {} GG aa {}
+ GG aa {} GG aa {} GG aa {} GG bb {} GG bb {} GG bb {} GG bb {}
+ HH aa {} HH aa {} HH aa {} HH bb {} HH bb {} HH bb {} HH bb {}
+ HH bb {} HH bb {} II aa {} II aa {} II bb {} II bb {} II bb {}
+ II bb {} II bb {} JJ aa {} JJ aa {} JJ aa {} JJ aa {} JJ bb {}
+ JJ bb {} JJ bb {} JJ bb {}}
+
+do_execsql_test 1.5.8 {
+ SELECT a, b,
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN 1 PRECEDING AND 2 PRECEDING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN 1 PRECEDING AND 2 PRECEDING ),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 1 PRECEDING AND 2 PRECEDING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 1 PRECEDING AND 2 PRECEDING )
+ FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} {} {} {} AA aa {} {} {} {} AA aa {} {} {} {}
+ AA aa {} {} {} {} AA bb {} {} {} {} AA bb {} {} {} {}
+ AA bb {} {} {} {} AA bb {} {} {} {} BB aa {} {} {} {}
+ BB aa {} {} {} {} BB aa {} {} {} {} BB aa {} {} {} {}
+ BB aa {} {} {} {} BB aa {} {} {} {} BB bb {} {} {} {}
+ BB bb {} {} {} {} BB bb {} {} {} {} BB bb {} {} {} {}
+ BB bb {} {} {} {} BB bb {} {} {} {} CC aa {} {} {} {}
+ CC aa {} {} {} {} CC aa {} {} {} {} CC aa {} {} {} {}
+ CC bb {} {} {} {} CC bb {} {} {} {} DD aa {} {} {} {}
+ DD aa {} {} {} {} DD aa {} {} {} {} DD bb {} {} {} {}
+ DD bb {} {} {} {} DD bb {} {} {} {} DD bb {} {} {} {}
+ EE aa {} {} {} {} EE aa {} {} {} {} EE bb {} {} {} {}
+ EE bb {} {} {} {} EE bb {} {} {} {} FF aa {} {} {} {}
+ FF aa {} {} {} {} FF aa {} {} {} {} FF aa {} {} {} {}
+ FF bb {} {} {} {} FF bb {} {} {} {} FF bb {} {} {} {}
+ FF bb {} {} {} {} FF bb {} {} {} {} FF bb {} {} {} {}
+ GG aa {} {} {} {} GG aa {} {} {} {} GG aa {} {} {} {}
+ GG aa {} {} {} {} GG bb {} {} {} {} GG bb {} {} {} {}
+ GG bb {} {} {} {} GG bb {} {} {} {} HH aa {} {} {} {}
+ HH aa {} {} {} {} HH aa {} {} {} {} HH bb {} {} {} {}
+ HH bb {} {} {} {} HH bb {} {} {} {} HH bb {} {} {} {}
+ HH bb {} {} {} {} HH bb {} {} {} {} II aa {} {} {} {}
+ II aa {} {} {} {} II bb {} {} {} {} II bb {} {} {} {}
+ II bb {} {} {} {} II bb {} {} {} {} II bb {} {} {} {}
+ JJ aa {} {} {} {} JJ aa {} {} {} {} JJ aa {} {} {} {}
+ JJ aa {} {} {} {} JJ bb {} {} {} {} JJ bb {} {} {} {}
+ JJ bb {} {} {} {} JJ bb {} {} {} {}}
+
+do_execsql_test 1.6.1 {
+ SELECT a, b, sum(c) OVER (ORDER BY a GROUPS BETWEEN 2 PRECEDING AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb {} AA bb {} AA bb {}
+ AA bb {} BB aa 4685 BB aa 4685 BB aa 4685 BB aa 4685 BB aa 4685
+ BB aa 4685 BB bb 4685 BB bb 4685 BB bb 4685 BB bb 4685 BB bb 4685
+ BB bb 4685 CC aa 12025 CC aa 12025 CC aa 12025 CC aa 12025
+ CC bb 12025 CC bb 12025 DD aa 10462 DD aa 10462 DD aa 10462
+ DD bb 10462 DD bb 10462 DD bb 10462 DD bb 10462 EE aa 7154
+ EE aa 7154 EE bb 7154 EE bb 7154 EE bb 7154 FF aa 6571 FF aa 6571
+ FF aa 6571 FF aa 6571 FF bb 6571 FF bb 6571 FF bb 6571 FF bb 6571
+ FF bb 6571 FF bb 6571 GG aa 8207 GG aa 8207 GG aa 8207 GG aa 8207
+ GG bb 8207 GG bb 8207 GG bb 8207 GG bb 8207 HH aa 10136
+ HH aa 10136 HH aa 10136 HH bb 10136 HH bb 10136 HH bb 10136
+ HH bb 10136 HH bb 10136 HH bb 10136 II aa 9911 II aa 9911
+ II bb 9911 II bb 9911 II bb 9911 II bb 9911 II bb 9911 JJ aa 9083
+ JJ aa 9083 JJ aa 9083 JJ aa 9083 JJ bb 9083 JJ bb 9083 JJ bb 9083
+ JJ bb 9083}
+
+do_execsql_test 1.6.2 {
+ SELECT a, b, sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 2 PRECEDING AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb 2307 AA bb 2307
+ AA bb 2307 AA bb 2307 BB aa 4685 BB aa 4685 BB aa 4685 BB aa 4685
+ BB aa 4685 BB aa 4685 BB bb 5251 BB bb 5251 BB bb 5251 BB bb 5251
+ BB bb 5251 BB bb 5251 CC aa 7340 CC aa 7340 CC aa 7340 CC aa 7340
+ CC bb 6421 CC bb 6421 DD aa 3122 DD aa 3122 DD aa 3122 DD bb 2493
+ DD bb 2493 DD bb 2493 DD bb 2493 EE aa 4032 EE aa 4032 EE bb 3597
+ EE bb 3597 EE bb 3597 FF aa 2539 FF aa 2539 FF aa 2539 FF aa 2539
+ FF bb 3812 FF bb 3812 FF bb 3812 FF bb 3812 FF bb 3812 FF bb 3812
+ GG aa 5668 GG aa 5668 GG aa 5668 GG aa 5668 GG bb 5102 GG bb 5102
+ GG bb 5102 GG bb 5102 HH aa 4468 HH aa 4468 HH aa 4468 HH bb 5120
+ HH bb 5120 HH bb 5120 HH bb 5120 HH bb 5120 HH bb 5120 II aa 5443
+ II aa 5443 II bb 4244 II bb 4244 II bb 4244 II bb 4244 II bb 4244
+ JJ aa 3640 JJ aa 3640 JJ aa 3640 JJ aa 3640 JJ bb 4604 JJ bb 4604
+ JJ bb 4604 JJ bb 4604}
+
+do_execsql_test 1.6.3 {
+ SELECT a, b, rank() OVER (ORDER BY a GROUPS BETWEEN 2 PRECEDING AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 1 AA aa 1 AA aa 1 AA aa 1 AA bb 1 AA bb 1 AA bb 1
+ AA bb 1 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9
+ BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 CC aa 21
+ CC aa 21 CC aa 21 CC aa 21 CC bb 21 CC bb 21 DD aa 27 DD aa 27
+ DD aa 27 DD bb 27 DD bb 27 DD bb 27 DD bb 27 EE aa 34 EE aa 34
+ EE bb 34 EE bb 34 EE bb 34 FF aa 39 FF aa 39 FF aa 39 FF aa 39
+ FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 GG aa 49
+ GG aa 49 GG aa 49 GG aa 49 GG bb 49 GG bb 49 GG bb 49 GG bb 49
+ HH aa 57 HH aa 57 HH aa 57 HH bb 57 HH bb 57 HH bb 57 HH bb 57
+ HH bb 57 HH bb 57 II aa 66 II aa 66 II bb 66 II bb 66 II bb 66
+ II bb 66 II bb 66 JJ aa 73 JJ aa 73 JJ aa 73 JJ aa 73 JJ bb 73
+ JJ bb 73 JJ bb 73 JJ bb 73}
+
+do_execsql_test 1.6.4 {
+ SELECT a, b, max(c) OVER (ORDER BY a,b GROUPS BETWEEN 2 PRECEDING AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb 934 AA bb 934
+ AA bb 934 AA bb 934 BB aa 934 BB aa 934 BB aa 934 BB aa 934
+ BB aa 934 BB aa 934 BB bb 870 BB bb 870 BB bb 870 BB bb 870
+ BB bb 870 BB bb 870 CC aa 840 CC aa 840 CC aa 840 CC aa 840
+ CC bb 840 CC bb 840 DD aa 822 DD aa 822 DD aa 822 DD bb 845
+ DD bb 845 DD bb 845 DD bb 845 EE aa 959 EE aa 959 EE bb 959
+ EE bb 959 EE bb 959 FF aa 777 FF aa 777 FF aa 777 FF aa 777
+ FF bb 768 FF bb 768 FF bb 768 FF bb 768 FF bb 768 FF bb 768
+ GG aa 938 GG aa 938 GG aa 938 GG aa 938 GG bb 938 GG bb 938
+ GG bb 938 GG bb 938 HH aa 938 HH aa 938 HH aa 938 HH bb 979
+ HH bb 979 HH bb 979 HH bb 979 HH bb 979 HH bb 979 II aa 979
+ II aa 979 II bb 963 II bb 963 II bb 963 II bb 963 II bb 963
+ JJ aa 805 JJ aa 805 JJ aa 805 JJ aa 805 JJ bb 899 JJ bb 899
+ JJ bb 899 JJ bb 899}
+
+do_execsql_test 1.6.5 {
+ SELECT a, b, min(c) OVER (ORDER BY a,b GROUPS BETWEEN 2 PRECEDING AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb 223 AA bb 223
+ AA bb 223 AA bb 223 BB aa 223 BB aa 223 BB aa 223 BB aa 223
+ BB aa 223 BB aa 223 BB bb 247 BB bb 247 BB bb 247 BB bb 247
+ BB bb 247 BB bb 247 CC aa 247 CC aa 247 CC aa 247 CC aa 247
+ CC bb 158 CC bb 158 DD aa 158 DD aa 158 DD aa 158 DD bb 224
+ DD bb 224 DD bb 224 DD bb 224 EE aa 224 EE aa 224 EE bb 113
+ EE bb 113 EE bb 113 FF aa 113 FF aa 113 FF aa 113 FF aa 113
+ FF bb 208 FF bb 208 FF bb 208 FF bb 208 FF bb 208 FF bb 208
+ GG aa 102 GG aa 102 GG aa 102 GG aa 102 GG bb 102 GG bb 102
+ GG bb 102 GG bb 102 HH aa 148 HH aa 148 HH aa 148 HH bb 160
+ HH bb 160 HH bb 160 HH bb 160 HH bb 160 HH bb 160 II aa 133
+ II aa 133 II bb 133 II bb 133 II bb 133 II bb 133 II bb 133
+ JJ aa 250 JJ aa 250 JJ aa 250 JJ aa 250 JJ bb 113 JJ bb 113
+ JJ bb 113 JJ bb 113}
+
+do_execsql_test 1.6.6 {
+ 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;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb {} AA bb {} AA bb {}
+ AA bb {} BB aa 4685 BB aa 4685 BB aa 4685 BB aa 4685 BB aa 4685
+ BB aa 4685 BB bb 4685 BB bb 4685 BB bb 4685 BB bb 4685 BB bb 4685
+ BB bb 4685 CC aa 12025 CC aa 12025 CC aa 12025 CC aa 12025
+ CC bb 12025 CC bb 12025 DD aa 10462 DD aa 10462 DD aa 10462
+ DD bb 10462 DD bb 10462 DD bb 10462 DD bb 10462 EE aa 7154
+ EE aa 7154 EE bb 7154 EE bb 7154 EE bb 7154 FF aa 6571 FF aa 6571
+ FF aa 6571 FF aa 6571 FF bb 6571 FF bb 6571 FF bb 6571 FF bb 6571
+ FF bb 6571 FF bb 6571 GG aa 8207 GG aa 8207 GG aa 8207 GG aa 8207
+ GG bb 8207 GG bb 8207 GG bb 8207 GG bb 8207 HH aa 10136
+ HH aa 10136 HH aa 10136 HH bb 10136 HH bb 10136 HH bb 10136
+ HH bb 10136 HH bb 10136 HH bb 10136 II aa 9911 II aa 9911
+ II bb 9911 II bb 9911 II bb 9911 II bb 9911 II bb 9911 JJ aa 9083
+ JJ aa 9083 JJ aa 9083 JJ aa 9083 JJ bb 9083 JJ bb 9083 JJ bb 9083
+ JJ bb 9083}
+
+do_execsql_test 1.6.7 {
+ 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;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb 2307 AA bb 2307
+ AA bb 2307 AA bb 2307 BB aa 4685 BB aa 4685 BB aa 4685 BB aa 4685
+ BB aa 4685 BB aa 4685 BB bb 5251 BB bb 5251 BB bb 5251 BB bb 5251
+ BB bb 5251 BB bb 5251 CC aa 7340 CC aa 7340 CC aa 7340 CC aa 7340
+ CC bb 6421 CC bb 6421 DD aa 3122 DD aa 3122 DD aa 3122 DD bb 2493
+ DD bb 2493 DD bb 2493 DD bb 2493 EE aa 4032 EE aa 4032 EE bb 3597
+ EE bb 3597 EE bb 3597 FF aa 2539 FF aa 2539 FF aa 2539 FF aa 2539
+ FF bb 3812 FF bb 3812 FF bb 3812 FF bb 3812 FF bb 3812 FF bb 3812
+ GG aa 5668 GG aa 5668 GG aa 5668 GG aa 5668 GG bb 5102 GG bb 5102
+ GG bb 5102 GG bb 5102 HH aa 4468 HH aa 4468 HH aa 4468 HH bb 5120
+ HH bb 5120 HH bb 5120 HH bb 5120 HH bb 5120 HH bb 5120 II aa 5443
+ II aa 5443 II bb 4244 II bb 4244 II bb 4244 II bb 4244 II bb 4244
+ JJ aa 3640 JJ aa 3640 JJ aa 3640 JJ aa 3640 JJ bb 4604 JJ bb 4604
+ JJ bb 4604 JJ bb 4604}
+
+do_execsql_test 1.6.8 {
+ SELECT a, b,
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN 2 PRECEDING AND 1 PRECEDING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN 2 PRECEDING AND 1 PRECEDING ),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 2 PRECEDING AND 1 PRECEDING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 2 PRECEDING AND 1 PRECEDING )
+ FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} {} {} {} AA aa {} {} {} {} AA aa {} {} {} {}
+ AA aa {} {} {} {} AA bb {} {} 2307 2307 AA bb {} {} 2307 2307
+ AA bb {} {} 2307 2307 AA bb {} {} 2307 2307 BB aa 4685 4685 4685 4685
+ BB aa 4685 4685 4685 4685 BB aa 4685 4685 4685 4685
+ BB aa 4685 4685 4685 4685 BB aa 4685 4685 4685 4685
+ BB aa 4685 4685 4685 4685 BB bb 4685 4685 5251 5251
+ BB bb 4685 4685 5251 5251 BB bb 4685 4685 5251 5251
+ BB bb 4685 4685 5251 5251 BB bb 4685 4685 5251 5251
+ BB bb 4685 4685 5251 5251 CC aa 12025 12025 7340 7340
+ CC aa 12025 12025 7340 7340 CC aa 12025 12025 7340 7340
+ CC aa 12025 12025 7340 7340 CC bb 12025 12025 6421 6421
+ CC bb 12025 12025 6421 6421 DD aa 10462 10462 3122 3122
+ DD aa 10462 10462 3122 3122 DD aa 10462 10462 3122 3122
+ DD bb 10462 10462 2493 2493 DD bb 10462 10462 2493 2493
+ DD bb 10462 10462 2493 2493 DD bb 10462 10462 2493 2493
+ EE aa 7154 7154 4032 4032 EE aa 7154 7154 4032 4032
+ EE bb 7154 7154 3597 3597 EE bb 7154 7154 3597 3597
+ EE bb 7154 7154 3597 3597 FF aa 6571 6571 2539 2539
+ FF aa 6571 6571 2539 2539 FF aa 6571 6571 2539 2539
+ FF aa 6571 6571 2539 2539 FF bb 6571 6571 3812 3812
+ FF bb 6571 6571 3812 3812 FF bb 6571 6571 3812 3812
+ FF bb 6571 6571 3812 3812 FF bb 6571 6571 3812 3812
+ FF bb 6571 6571 3812 3812 GG aa 8207 8207 5668 5668
+ GG aa 8207 8207 5668 5668 GG aa 8207 8207 5668 5668
+ GG aa 8207 8207 5668 5668 GG bb 8207 8207 5102 5102
+ GG bb 8207 8207 5102 5102 GG bb 8207 8207 5102 5102
+ GG bb 8207 8207 5102 5102 HH aa 10136 10136 4468 4468
+ HH aa 10136 10136 4468 4468 HH aa 10136 10136 4468 4468
+ HH bb 10136 10136 5120 5120 HH bb 10136 10136 5120 5120
+ HH bb 10136 10136 5120 5120 HH bb 10136 10136 5120 5120
+ HH bb 10136 10136 5120 5120 HH bb 10136 10136 5120 5120
+ II aa 9911 9911 5443 5443 II aa 9911 9911 5443 5443
+ II bb 9911 9911 4244 4244 II bb 9911 9911 4244 4244
+ II bb 9911 9911 4244 4244 II bb 9911 9911 4244 4244
+ II bb 9911 9911 4244 4244 JJ aa 9083 9083 3640 3640
+ JJ aa 9083 9083 3640 3640 JJ aa 9083 9083 3640 3640
+ JJ aa 9083 9083 3640 3640 JJ bb 9083 9083 4604 4604
+ JJ bb 9083 9083 4604 4604 JJ bb 9083 9083 4604 4604
+ JJ bb 9083 9083 4604 4604}
+
+do_execsql_test 1.7.1 {
+ SELECT a, b, sum(c) OVER (ORDER BY a GROUPS BETWEEN 3 PRECEDING AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb {} AA bb {} AA bb {}
+ AA bb {} BB aa 4685 BB aa 4685 BB aa 4685 BB aa 4685 BB aa 4685
+ BB aa 4685 BB bb 4685 BB bb 4685 BB bb 4685 BB bb 4685 BB bb 4685
+ BB bb 4685 CC aa 12025 CC aa 12025 CC aa 12025 CC aa 12025
+ CC bb 12025 CC bb 12025 DD aa 15147 DD aa 15147 DD aa 15147
+ DD bb 15147 DD bb 15147 DD bb 15147 DD bb 15147 EE aa 14494
+ EE aa 14494 EE bb 14494 EE bb 14494 EE bb 14494 FF aa 9693
+ FF aa 9693 FF aa 9693 FF aa 9693 FF bb 9693 FF bb 9693 FF bb 9693
+ FF bb 9693 FF bb 9693 FF bb 9693 GG aa 12239 GG aa 12239
+ GG aa 12239 GG aa 12239 GG bb 12239 GG bb 12239 GG bb 12239
+ GG bb 12239 HH aa 12675 HH aa 12675 HH aa 12675 HH bb 12675
+ HH bb 12675 HH bb 12675 HH bb 12675 HH bb 12675 HH bb 12675
+ II aa 15579 II aa 15579 II bb 15579 II bb 15579 II bb 15579
+ II bb 15579 II bb 15579 JJ aa 13551 JJ aa 13551 JJ aa 13551
+ JJ aa 13551 JJ bb 13551 JJ bb 13551 JJ bb 13551 JJ bb 13551}
+
+do_execsql_test 1.7.2 {
+ SELECT a, b, sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 3 PRECEDING AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb 2307 AA bb 2307
+ AA bb 2307 AA bb 2307 BB aa 4685 BB aa 4685 BB aa 4685 BB aa 4685
+ BB aa 4685 BB aa 4685 BB bb 7558 BB bb 7558 BB bb 7558 BB bb 7558
+ BB bb 7558 BB bb 7558 CC aa 9718 CC aa 9718 CC aa 9718 CC aa 9718
+ CC bb 9294 CC bb 9294 DD aa 7589 DD aa 7589 DD aa 7589 DD bb 4447
+ DD bb 4447 DD bb 4447 DD bb 4447 EE aa 5200 EE aa 5200 EE bb 4922
+ EE bb 4922 EE bb 4922 FF aa 5246 FF aa 5246 FF aa 5246 FF aa 5246
+ FF bb 4702 FF bb 4702 FF bb 4702 FF bb 4702 FF bb 4702 FF bb 4702
+ GG aa 7317 GG aa 7317 GG aa 7317 GG aa 7317 GG bb 7265 GG bb 7265
+ GG bb 7265 GG bb 7265 HH aa 7973 HH aa 7973 HH aa 7973 HH bb 6717
+ HH bb 6717 HH bb 6717 HH bb 6717 HH bb 6717 HH bb 6717 II aa 8314
+ II aa 8314 II bb 6493 II bb 6493 II bb 6493 II bb 6493 II bb 6493
+ JJ aa 6834 JJ aa 6834 JJ aa 6834 JJ aa 6834 JJ bb 5654 JJ bb 5654
+ JJ bb 5654 JJ bb 5654}
+
+do_execsql_test 1.7.3 {
+ SELECT a, b, rank() OVER (ORDER BY a GROUPS BETWEEN 3 PRECEDING AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 1 AA aa 1 AA aa 1 AA aa 1 AA bb 1 AA bb 1 AA bb 1
+ AA bb 1 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9
+ BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 CC aa 21
+ CC aa 21 CC aa 21 CC aa 21 CC bb 21 CC bb 21 DD aa 27 DD aa 27
+ DD aa 27 DD bb 27 DD bb 27 DD bb 27 DD bb 27 EE aa 34 EE aa 34
+ EE bb 34 EE bb 34 EE bb 34 FF aa 39 FF aa 39 FF aa 39 FF aa 39
+ FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 GG aa 49
+ GG aa 49 GG aa 49 GG aa 49 GG bb 49 GG bb 49 GG bb 49 GG bb 49
+ HH aa 57 HH aa 57 HH aa 57 HH bb 57 HH bb 57 HH bb 57 HH bb 57
+ HH bb 57 HH bb 57 II aa 66 II aa 66 II bb 66 II bb 66 II bb 66
+ II bb 66 II bb 66 JJ aa 73 JJ aa 73 JJ aa 73 JJ aa 73 JJ bb 73
+ JJ bb 73 JJ bb 73 JJ bb 73}
+
+do_execsql_test 1.7.4 {
+ SELECT a, b, max(c) OVER (ORDER BY a,b GROUPS BETWEEN 3 PRECEDING AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb 934 AA bb 934
+ AA bb 934 AA bb 934 BB aa 934 BB aa 934 BB aa 934 BB aa 934
+ BB aa 934 BB aa 934 BB bb 934 BB bb 934 BB bb 934 BB bb 934
+ BB bb 934 BB bb 934 CC aa 870 CC aa 870 CC aa 870 CC aa 870
+ CC bb 840 CC bb 840 DD aa 840 DD aa 840 DD aa 840 DD bb 845
+ DD bb 845 DD bb 845 DD bb 845 EE aa 959 EE aa 959 EE bb 959
+ EE bb 959 EE bb 959 FF aa 959 FF aa 959 FF aa 959 FF aa 959
+ FF bb 777 FF bb 777 FF bb 777 FF bb 777 FF bb 777 FF bb 777
+ GG aa 938 GG aa 938 GG aa 938 GG aa 938 GG bb 938 GG bb 938
+ GG bb 938 GG bb 938 HH aa 938 HH aa 938 HH aa 938 HH bb 979
+ HH bb 979 HH bb 979 HH bb 979 HH bb 979 HH bb 979 II aa 979
+ II aa 979 II bb 979 II bb 979 II bb 979 II bb 979 II bb 979
+ JJ aa 963 JJ aa 963 JJ aa 963 JJ aa 963 JJ bb 899 JJ bb 899
+ JJ bb 899 JJ bb 899}
+
+do_execsql_test 1.7.5 {
+ SELECT a, b, min(c) OVER (ORDER BY a,b GROUPS BETWEEN 3 PRECEDING AND 1 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb 223 AA bb 223
+ AA bb 223 AA bb 223 BB aa 223 BB aa 223 BB aa 223 BB aa 223
+ BB aa 223 BB aa 223 BB bb 223 BB bb 223 BB bb 223 BB bb 223
+ BB bb 223 BB bb 223 CC aa 247 CC aa 247 CC aa 247 CC aa 247
+ CC bb 158 CC bb 158 DD aa 158 DD aa 158 DD aa 158 DD bb 158
+ DD bb 158 DD bb 158 DD bb 158 EE aa 224 EE aa 224 EE bb 113
+ EE bb 113 EE bb 113 FF aa 113 FF aa 113 FF aa 113 FF aa 113
+ FF bb 113 FF bb 113 FF bb 113 FF bb 113 FF bb 113 FF bb 113
+ GG aa 102 GG aa 102 GG aa 102 GG aa 102 GG bb 102 GG bb 102
+ GG bb 102 GG bb 102 HH aa 102 HH aa 102 HH aa 102 HH bb 148
+ HH bb 148 HH bb 148 HH bb 148 HH bb 148 HH bb 148 II aa 133
+ II aa 133 II bb 133 II bb 133 II bb 133 II bb 133 II bb 133
+ JJ aa 133 JJ aa 133 JJ aa 133 JJ aa 133 JJ bb 113 JJ bb 113
+ JJ bb 113 JJ bb 113}
+
+do_execsql_test 1.7.6 {
+ 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;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb {} AA bb {} AA bb {}
+ AA bb {} BB aa 4685 BB aa 4685 BB aa 4685 BB aa 4685 BB aa 4685
+ BB aa 4685 BB bb 4685 BB bb 4685 BB bb 4685 BB bb 4685 BB bb 4685
+ BB bb 4685 CC aa 12025 CC aa 12025 CC aa 12025 CC aa 12025
+ CC bb 12025 CC bb 12025 DD aa 15147 DD aa 15147 DD aa 15147
+ DD bb 15147 DD bb 15147 DD bb 15147 DD bb 15147 EE aa 14494
+ EE aa 14494 EE bb 14494 EE bb 14494 EE bb 14494 FF aa 9693
+ FF aa 9693 FF aa 9693 FF aa 9693 FF bb 9693 FF bb 9693 FF bb 9693
+ FF bb 9693 FF bb 9693 FF bb 9693 GG aa 12239 GG aa 12239
+ GG aa 12239 GG aa 12239 GG bb 12239 GG bb 12239 GG bb 12239
+ GG bb 12239 HH aa 12675 HH aa 12675 HH aa 12675 HH bb 12675
+ HH bb 12675 HH bb 12675 HH bb 12675 HH bb 12675 HH bb 12675
+ II aa 15579 II aa 15579 II bb 15579 II bb 15579 II bb 15579
+ II bb 15579 II bb 15579 JJ aa 13551 JJ aa 13551 JJ aa 13551
+ JJ aa 13551 JJ bb 13551 JJ bb 13551 JJ bb 13551 JJ bb 13551}
+
+do_execsql_test 1.7.7 {
+ 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;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb 2307 AA bb 2307
+ AA bb 2307 AA bb 2307 BB aa 4685 BB aa 4685 BB aa 4685 BB aa 4685
+ BB aa 4685 BB aa 4685 BB bb 7558 BB bb 7558 BB bb 7558 BB bb 7558
+ BB bb 7558 BB bb 7558 CC aa 9718 CC aa 9718 CC aa 9718 CC aa 9718
+ CC bb 9294 CC bb 9294 DD aa 7589 DD aa 7589 DD aa 7589 DD bb 4447
+ DD bb 4447 DD bb 4447 DD bb 4447 EE aa 5200 EE aa 5200 EE bb 4922
+ EE bb 4922 EE bb 4922 FF aa 5246 FF aa 5246 FF aa 5246 FF aa 5246
+ FF bb 4702 FF bb 4702 FF bb 4702 FF bb 4702 FF bb 4702 FF bb 4702
+ GG aa 7317 GG aa 7317 GG aa 7317 GG aa 7317 GG bb 7265 GG bb 7265
+ GG bb 7265 GG bb 7265 HH aa 7973 HH aa 7973 HH aa 7973 HH bb 6717
+ HH bb 6717 HH bb 6717 HH bb 6717 HH bb 6717 HH bb 6717 II aa 8314
+ II aa 8314 II bb 6493 II bb 6493 II bb 6493 II bb 6493 II bb 6493
+ JJ aa 6834 JJ aa 6834 JJ aa 6834 JJ aa 6834 JJ bb 5654 JJ bb 5654
+ JJ bb 5654 JJ bb 5654}
+
+do_execsql_test 1.7.8 {
+ SELECT a, b,
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN 3 PRECEDING AND 1 PRECEDING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN 3 PRECEDING AND 1 PRECEDING ),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 3 PRECEDING AND 1 PRECEDING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 3 PRECEDING AND 1 PRECEDING )
+ FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} {} {} {} AA aa {} {} {} {} AA aa {} {} {} {}
+ AA aa {} {} {} {} AA bb {} {} 2307 2307 AA bb {} {} 2307 2307
+ AA bb {} {} 2307 2307 AA bb {} {} 2307 2307 BB aa 4685 4685 4685 4685
+ BB aa 4685 4685 4685 4685 BB aa 4685 4685 4685 4685
+ BB aa 4685 4685 4685 4685 BB aa 4685 4685 4685 4685
+ BB aa 4685 4685 4685 4685 BB bb 4685 4685 7558 7558
+ BB bb 4685 4685 7558 7558 BB bb 4685 4685 7558 7558
+ BB bb 4685 4685 7558 7558 BB bb 4685 4685 7558 7558
+ BB bb 4685 4685 7558 7558 CC aa 12025 12025 9718 9718
+ CC aa 12025 12025 9718 9718 CC aa 12025 12025 9718 9718
+ CC aa 12025 12025 9718 9718 CC bb 12025 12025 9294 9294
+ CC bb 12025 12025 9294 9294 DD aa 15147 15147 7589 7589
+ DD aa 15147 15147 7589 7589 DD aa 15147 15147 7589 7589
+ DD bb 15147 15147 4447 4447 DD bb 15147 15147 4447 4447
+ DD bb 15147 15147 4447 4447 DD bb 15147 15147 4447 4447
+ EE aa 14494 14494 5200 5200 EE aa 14494 14494 5200 5200
+ EE bb 14494 14494 4922 4922 EE bb 14494 14494 4922 4922
+ EE bb 14494 14494 4922 4922 FF aa 9693 9693 5246 5246
+ FF aa 9693 9693 5246 5246 FF aa 9693 9693 5246 5246
+ FF aa 9693 9693 5246 5246 FF bb 9693 9693 4702 4702
+ FF bb 9693 9693 4702 4702 FF bb 9693 9693 4702 4702
+ FF bb 9693 9693 4702 4702 FF bb 9693 9693 4702 4702
+ FF bb 9693 9693 4702 4702 GG aa 12239 12239 7317 7317
+ GG aa 12239 12239 7317 7317 GG aa 12239 12239 7317 7317
+ GG aa 12239 12239 7317 7317 GG bb 12239 12239 7265 7265
+ GG bb 12239 12239 7265 7265 GG bb 12239 12239 7265 7265
+ GG bb 12239 12239 7265 7265 HH aa 12675 12675 7973 7973
+ HH aa 12675 12675 7973 7973 HH aa 12675 12675 7973 7973
+ HH bb 12675 12675 6717 6717 HH bb 12675 12675 6717 6717
+ HH bb 12675 12675 6717 6717 HH bb 12675 12675 6717 6717
+ HH bb 12675 12675 6717 6717 HH bb 12675 12675 6717 6717
+ II aa 15579 15579 8314 8314 II aa 15579 15579 8314 8314
+ II bb 15579 15579 6493 6493 II bb 15579 15579 6493 6493
+ II bb 15579 15579 6493 6493 II bb 15579 15579 6493 6493
+ II bb 15579 15579 6493 6493 JJ aa 13551 13551 6834 6834
+ JJ aa 13551 13551 6834 6834 JJ aa 13551 13551 6834 6834
+ JJ aa 13551 13551 6834 6834 JJ bb 13551 13551 5654 5654
+ JJ bb 13551 13551 5654 5654 JJ bb 13551 13551 5654 5654
+ JJ bb 13551 13551 5654 5654}
+
+do_execsql_test 1.8.1 {
+ SELECT a, b, sum(c) OVER (ORDER BY a GROUPS BETWEEN 3 PRECEDING AND 0 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 4685 AA aa 4685 AA aa 4685 AA aa 4685 AA bb 4685 AA bb 4685
+ AA bb 4685 AA bb 4685 BB aa 12025 BB aa 12025 BB aa 12025
+ BB aa 12025 BB aa 12025 BB aa 12025 BB bb 12025 BB bb 12025
+ BB bb 12025 BB bb 12025 BB bb 12025 BB bb 12025 CC aa 15147
+ CC aa 15147 CC aa 15147 CC aa 15147 CC bb 15147 CC bb 15147
+ DD aa 19179 DD aa 19179 DD aa 19179 DD bb 19179 DD bb 19179
+ DD bb 19179 DD bb 19179 EE aa 17033 EE aa 17033 EE bb 17033
+ EE bb 17033 EE bb 17033 FF aa 15361 FF aa 15361 FF aa 15361
+ FF aa 15361 FF bb 15361 FF bb 15361 FF bb 15361 FF bb 15361
+ FF bb 15361 FF bb 15361 GG aa 16707 GG aa 16707 GG aa 16707
+ GG aa 16707 GG bb 16707 GG bb 16707 GG bb 16707 GG bb 16707
+ HH aa 18118 HH aa 18118 HH aa 18118 HH bb 18118 HH bb 18118
+ HH bb 18118 HH bb 18118 HH bb 18118 HH bb 18118 II aa 19219
+ II aa 19219 II bb 19219 II bb 19219 II bb 19219 II bb 19219
+ II bb 19219 JJ aa 17351 JJ aa 17351 JJ aa 17351 JJ aa 17351
+ JJ bb 17351 JJ bb 17351 JJ bb 17351 JJ bb 17351}
+
+do_execsql_test 1.8.2 {
+ SELECT a, b, sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 3 PRECEDING AND 0 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 2307 AA aa 2307 AA aa 2307 AA aa 2307 AA bb 4685 AA bb 4685
+ AA bb 4685 AA bb 4685 BB aa 7558 BB aa 7558 BB aa 7558 BB aa 7558
+ BB aa 7558 BB aa 7558 BB bb 12025 BB bb 12025 BB bb 12025
+ BB bb 12025 BB bb 12025 BB bb 12025 CC aa 11672 CC aa 11672
+ CC aa 11672 CC aa 11672 CC bb 10462 CC bb 10462 DD aa 8914
+ DD aa 8914 DD aa 8914 DD bb 7154 DD bb 7154 DD bb 7154 DD bb 7154
+ EE aa 6090 EE aa 6090 EE bb 6571 EE bb 6571 EE bb 6571 FF aa 7409
+ FF aa 7409 FF aa 7409 FF aa 7409 FF bb 8207 FF bb 8207 FF bb 8207
+ FF bb 8207 FF bb 8207 FF bb 8207 GG aa 8914 GG aa 8914 GG aa 8914
+ GG aa 8914 GG bb 10136 GG bb 10136 GG bb 10136 GG bb 10136
+ HH aa 10222 HH aa 10222 HH aa 10222 HH bb 9911 HH bb 9911
+ HH bb 9911 HH bb 9911 HH bb 9911 HH bb 9911 II aa 9364 II aa 9364
+ II bb 9083 II bb 9083 II bb 9083 II bb 9083 II bb 9083 JJ aa 8848
+ JJ aa 8848 JJ aa 8848 JJ aa 8848 JJ bb 7440 JJ bb 7440 JJ bb 7440
+ JJ bb 7440}
+
+do_execsql_test 1.8.3 {
+ SELECT a, b, rank() OVER (ORDER BY a GROUPS BETWEEN 3 PRECEDING AND 0 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 1 AA aa 1 AA aa 1 AA aa 1 AA bb 1 AA bb 1 AA bb 1
+ AA bb 1 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9
+ BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 CC aa 21
+ CC aa 21 CC aa 21 CC aa 21 CC bb 21 CC bb 21 DD aa 27 DD aa 27
+ DD aa 27 DD bb 27 DD bb 27 DD bb 27 DD bb 27 EE aa 34 EE aa 34
+ EE bb 34 EE bb 34 EE bb 34 FF aa 39 FF aa 39 FF aa 39 FF aa 39
+ FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 GG aa 49
+ GG aa 49 GG aa 49 GG aa 49 GG bb 49 GG bb 49 GG bb 49 GG bb 49
+ HH aa 57 HH aa 57 HH aa 57 HH bb 57 HH bb 57 HH bb 57 HH bb 57
+ HH bb 57 HH bb 57 II aa 66 II aa 66 II bb 66 II bb 66 II bb 66
+ II bb 66 II bb 66 JJ aa 73 JJ aa 73 JJ aa 73 JJ aa 73 JJ bb 73
+ JJ bb 73 JJ bb 73 JJ bb 73}
+
+do_execsql_test 1.8.4 {
+ SELECT a, b, max(c) OVER (ORDER BY a,b GROUPS BETWEEN 3 PRECEDING AND 0 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 934 AA aa 934 AA aa 934 AA aa 934 AA bb 934 AA bb 934
+ AA bb 934 AA bb 934 BB aa 934 BB aa 934 BB aa 934 BB aa 934
+ BB aa 934 BB aa 934 BB bb 934 BB bb 934 BB bb 934 BB bb 934
+ BB bb 934 BB bb 934 CC aa 870 CC aa 870 CC aa 870 CC aa 870
+ CC bb 840 CC bb 840 DD aa 845 DD aa 845 DD aa 845 DD bb 959
+ DD bb 959 DD bb 959 DD bb 959 EE aa 959 EE aa 959 EE bb 959
+ EE bb 959 EE bb 959 FF aa 959 FF aa 959 FF aa 959 FF aa 959
+ FF bb 938 FF bb 938 FF bb 938 FF bb 938 FF bb 938 FF bb 938
+ GG aa 938 GG aa 938 GG aa 938 GG aa 938 GG bb 938 GG bb 938
+ GG bb 938 GG bb 938 HH aa 979 HH aa 979 HH aa 979 HH bb 979
+ HH bb 979 HH bb 979 HH bb 979 HH bb 979 HH bb 979 II aa 979
+ II aa 979 II bb 979 II bb 979 II bb 979 II bb 979 II bb 979
+ JJ aa 963 JJ aa 963 JJ aa 963 JJ aa 963 JJ bb 899 JJ bb 899
+ JJ bb 899 JJ bb 899}
+
+do_execsql_test 1.8.5 {
+ SELECT a, b, min(c) OVER (ORDER BY a,b GROUPS BETWEEN 3 PRECEDING AND 0 PRECEDING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 223 AA aa 223 AA aa 223 AA aa 223 AA bb 223 AA bb 223
+ AA bb 223 AA bb 223 BB aa 223 BB aa 223 BB aa 223 BB aa 223
+ BB aa 223 BB aa 223 BB bb 223 BB bb 223 BB bb 223 BB bb 223
+ BB bb 223 BB bb 223 CC aa 158 CC aa 158 CC aa 158 CC aa 158
+ CC bb 158 CC bb 158 DD aa 158 DD aa 158 DD aa 158 DD bb 158
+ DD bb 158 DD bb 158 DD bb 158 EE aa 113 EE aa 113 EE bb 113
+ EE bb 113 EE bb 113 FF aa 113 FF aa 113 FF aa 113 FF aa 113
+ FF bb 102 FF bb 102 FF bb 102 FF bb 102 FF bb 102 FF bb 102
+ GG aa 102 GG aa 102 GG aa 102 GG aa 102 GG bb 102 GG bb 102
+ GG bb 102 GG bb 102 HH aa 102 HH aa 102 HH aa 102 HH bb 133
+ HH bb 133 HH bb 133 HH bb 133 HH bb 133 HH bb 133 II aa 133
+ II aa 133 II bb 133 II bb 133 II bb 133 II bb 133 II bb 133
+ JJ aa 113 JJ aa 113 JJ aa 113 JJ aa 113 JJ bb 113 JJ bb 113
+ JJ bb 113 JJ bb 113}
+
+do_execsql_test 1.8.6 {
+ 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;
+} {AA aa 3751 AA aa 3774 AA aa 4446 AA aa 4462 AA bb 3815 AA bb 4058
+ AA bb 4113 AA bb 4376 BB aa 11263 BB aa 11365 BB aa 11613
+ BB aa 11626 BB aa 11632 BB aa 11778 BB bb 11185 BB bb 11233
+ BB bb 11239 BB bb 11314 BB bb 11320 BB bb 11392 CC aa 14388
+ CC aa 14540 CC aa 14717 CC aa 14989 CC bb 14325 CC bb 14801
+ DD aa 18334 DD aa 18923 DD aa 18955 DD bb 18220 DD bb 18385
+ DD bb 18463 DD bb 18941 EE aa 16256 EE aa 16920 EE bb 16265
+ EE bb 16404 EE bb 16781 FF aa 14691 FF aa 14694 FF aa 14743
+ FF aa 15153 FF bb 14423 FF bb 14491 FF bb 14635 FF bb 14787
+ FF bb 15066 FF bb 15259 GG aa 16073 GG aa 16227 GG aa 16372
+ GG aa 16559 GG bb 15769 GG bb 15778 GG bb 15863 GG bb 16547
+ HH aa 17139 HH aa 17328 HH aa 17638 HH bb 17155 HH bb 17388
+ HH bb 17435 HH bb 17763 HH bb 17788 HH bb 17985 II aa 18567
+ II aa 18821 II bb 18414 II bb 18548 II bb 18776 II bb 18798
+ II bb 18969 JJ aa 16452 JJ aa 16583 JJ aa 17117 JJ aa 17238
+ JJ bb 16512 JJ bb 16997 JJ bb 17015 JJ bb 17094}
+
+do_execsql_test 1.8.7 {
+ 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;
+} {AA aa 1373 AA aa 1396 AA aa 2068 AA aa 2084 AA bb 3815 AA bb 4058
+ AA bb 4113 AA bb 4376 BB aa 6796 BB aa 6898 BB aa 7146 BB aa 7159
+ BB aa 7165 BB aa 7311 BB bb 11185 BB bb 11233 BB bb 11239
+ BB bb 11314 BB bb 11320 BB bb 11392 CC aa 10913 CC aa 11065
+ CC aa 11242 CC aa 11514 CC bb 9640 CC bb 10116 DD aa 8069
+ DD aa 8658 DD aa 8690 DD bb 6195 DD bb 6360 DD bb 6438 DD bb 6916
+ EE aa 5313 EE aa 5977 EE bb 5803 EE bb 5942 EE bb 6319 FF aa 6739
+ FF aa 6742 FF aa 6791 FF aa 7201 FF bb 7269 FF bb 7337 FF bb 7481
+ FF bb 7633 FF bb 7912 FF bb 8105 GG aa 8280 GG aa 8434 GG aa 8579
+ GG aa 8766 GG bb 9198 GG bb 9207 GG bb 9292 GG bb 9976 HH aa 9243
+ HH aa 9432 HH aa 9742 HH bb 8948 HH bb 9181 HH bb 9228 HH bb 9556
+ HH bb 9581 HH bb 9778 II aa 8712 II aa 8966 II bb 8278 II bb 8412
+ II bb 8640 II bb 8662 II bb 8833 JJ aa 7949 JJ aa 8080 JJ aa 8614
+ JJ aa 8735 JJ bb 6601 JJ bb 7086 JJ bb 7104 JJ bb 7183}
+
+do_execsql_test 1.8.8 {
+ SELECT a, b,
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN 3 PRECEDING AND 0 PRECEDING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN 3 PRECEDING AND 0 PRECEDING ),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 3 PRECEDING AND 0 PRECEDING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 3 PRECEDING AND 0 PRECEDING )
+ FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 3751 4685 1373 2307 AA aa 3774 4685 1396 2307
+ AA aa 4446 4685 2068 2307 AA aa 4462 4685 2084 2307
+ AA bb 3815 4685 3815 4685 AA bb 4058 4685 4058 4685
+ AA bb 4113 4685 4113 4685 AA bb 4376 4685 4376 4685
+ BB aa 11263 12025 6796 7558 BB aa 11365 12025 6898 7558
+ BB aa 11613 12025 7146 7558 BB aa 11626 12025 7159 7558
+ BB aa 11632 12025 7165 7558 BB aa 11778 12025 7311 7558
+ BB bb 11185 12025 11185 12025 BB bb 11233 12025 11233 12025
+ BB bb 11239 12025 11239 12025 BB bb 11314 12025 11314 12025
+ BB bb 11320 12025 11320 12025 BB bb 11392 12025 11392 12025
+ CC aa 14388 15147 10913 11672 CC aa 14540 15147 11065 11672
+ CC aa 14717 15147 11242 11672 CC aa 14989 15147 11514 11672
+ CC bb 14325 15147 9640 10462 CC bb 14801 15147 10116 10462
+ DD aa 18334 19179 8069 8914 DD aa 18923 19179 8658 8914
+ DD aa 18955 19179 8690 8914 DD bb 18220 19179 6195 7154
+ DD bb 18385 19179 6360 7154 DD bb 18463 19179 6438 7154
+ DD bb 18941 19179 6916 7154 EE aa 16256 17033 5313 6090
+ EE aa 16920 17033 5977 6090 EE bb 16265 17033 5803 6571
+ EE bb 16404 17033 5942 6571 EE bb 16781 17033 6319 6571
+ FF aa 14691 15361 6739 7409 FF aa 14694 15361 6742 7409
+ FF aa 14743 15361 6791 7409 FF aa 15153 15361 7201 7409
+ FF bb 14423 15361 7269 8207 FF bb 14491 15361 7337 8207
+ FF bb 14635 15361 7481 8207 FF bb 14787 15361 7633 8207
+ FF bb 15066 15361 7912 8207 FF bb 15259 15361 8105 8207
+ GG aa 16073 16707 8280 8914 GG aa 16227 16707 8434 8914
+ GG aa 16372 16707 8579 8914 GG aa 16559 16707 8766 8914
+ GG bb 15769 16707 9198 10136 GG bb 15778 16707 9207 10136
+ GG bb 15863 16707 9292 10136 GG bb 16547 16707 9976 10136
+ HH aa 17139 18118 9243 10222 HH aa 17328 18118 9432 10222
+ HH aa 17638 18118 9742 10222 HH bb 17155 18118 8948 9911
+ HH bb 17388 18118 9181 9911 HH bb 17435 18118 9228 9911
+ HH bb 17763 18118 9556 9911 HH bb 17788 18118 9581 9911
+ HH bb 17985 18118 9778 9911 II aa 18567 19219 8712 9364
+ II aa 18821 19219 8966 9364 II bb 18414 19219 8278 9083
+ II bb 18548 19219 8412 9083 II bb 18776 19219 8640 9083
+ II bb 18798 19219 8662 9083 II bb 18969 19219 8833 9083
+ JJ aa 16452 17351 7949 8848 JJ aa 16583 17351 8080 8848
+ JJ aa 17117 17351 8614 8848 JJ aa 17238 17351 8735 8848
+ JJ bb 16512 17351 6601 7440 JJ bb 16997 17351 7086 7440
+ JJ bb 17015 17351 7104 7440 JJ bb 17094 17351 7183 7440}
+
+do_execsql_test 1.9.1 {
+ SELECT a, b, sum(c) OVER (ORDER BY a GROUPS BETWEEN 2 PRECEDING AND CURRENT ROW ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 4685 AA aa 4685 AA aa 4685 AA aa 4685 AA bb 4685 AA bb 4685
+ AA bb 4685 AA bb 4685 BB aa 12025 BB aa 12025 BB aa 12025
+ BB aa 12025 BB aa 12025 BB aa 12025 BB bb 12025 BB bb 12025
+ BB bb 12025 BB bb 12025 BB bb 12025 BB bb 12025 CC aa 15147
+ CC aa 15147 CC aa 15147 CC aa 15147 CC bb 15147 CC bb 15147
+ DD aa 14494 DD aa 14494 DD aa 14494 DD bb 14494 DD bb 14494
+ DD bb 14494 DD bb 14494 EE aa 9693 EE aa 9693 EE bb 9693
+ EE bb 9693 EE bb 9693 FF aa 12239 FF aa 12239 FF aa 12239
+ FF aa 12239 FF bb 12239 FF bb 12239 FF bb 12239 FF bb 12239
+ FF bb 12239 FF bb 12239 GG aa 12675 GG aa 12675 GG aa 12675
+ GG aa 12675 GG bb 12675 GG bb 12675 GG bb 12675 GG bb 12675
+ HH aa 15579 HH aa 15579 HH aa 15579 HH bb 15579 HH bb 15579
+ HH bb 15579 HH bb 15579 HH bb 15579 HH bb 15579 II aa 13551
+ II aa 13551 II bb 13551 II bb 13551 II bb 13551 II bb 13551
+ II bb 13551 JJ aa 12883 JJ aa 12883 JJ aa 12883 JJ aa 12883
+ JJ bb 12883 JJ bb 12883 JJ bb 12883 JJ bb 12883}
+
+do_execsql_test 1.9.2 {
+ SELECT a, b, sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 2 PRECEDING AND CURRENT ROW ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 2307 AA aa 2307 AA aa 2307 AA aa 2307 AA bb 4685 AA bb 4685
+ AA bb 4685 AA bb 4685 BB aa 7558 BB aa 7558 BB aa 7558 BB aa 7558
+ BB aa 7558 BB aa 7558 BB bb 9718 BB bb 9718 BB bb 9718 BB bb 9718
+ BB bb 9718 BB bb 9718 CC aa 9294 CC aa 9294 CC aa 9294 CC aa 9294
+ CC bb 7589 CC bb 7589 DD aa 4447 DD aa 4447 DD aa 4447 DD bb 5200
+ DD bb 5200 DD bb 5200 DD bb 5200 EE aa 4922 EE aa 4922 EE bb 5246
+ EE bb 5246 EE bb 5246 FF aa 4702 FF aa 4702 FF aa 4702 FF aa 4702
+ FF bb 7317 FF bb 7317 FF bb 7317 FF bb 7317 FF bb 7317 FF bb 7317
+ GG aa 7265 GG aa 7265 GG aa 7265 GG aa 7265 GG bb 7973 GG bb 7973
+ GG bb 7973 GG bb 7973 HH aa 6717 HH aa 6717 HH aa 6717 HH bb 8314
+ HH bb 8314 HH bb 8314 HH bb 8314 HH bb 8314 HH bb 8314 II aa 6493
+ II aa 6493 II bb 6834 II bb 6834 II bb 6834 II bb 6834 II bb 6834
+ JJ aa 5654 JJ aa 5654 JJ aa 5654 JJ aa 5654 JJ bb 6390 JJ bb 6390
+ JJ bb 6390 JJ bb 6390}
+
+do_execsql_test 1.9.3 {
+ SELECT a, b, rank() OVER (ORDER BY a GROUPS BETWEEN 2 PRECEDING AND CURRENT ROW ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 1 AA aa 1 AA aa 1 AA aa 1 AA bb 1 AA bb 1 AA bb 1
+ AA bb 1 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9
+ BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 CC aa 21
+ CC aa 21 CC aa 21 CC aa 21 CC bb 21 CC bb 21 DD aa 27 DD aa 27
+ DD aa 27 DD bb 27 DD bb 27 DD bb 27 DD bb 27 EE aa 34 EE aa 34
+ EE bb 34 EE bb 34 EE bb 34 FF aa 39 FF aa 39 FF aa 39 FF aa 39
+ FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 GG aa 49
+ GG aa 49 GG aa 49 GG aa 49 GG bb 49 GG bb 49 GG bb 49 GG bb 49
+ HH aa 57 HH aa 57 HH aa 57 HH bb 57 HH bb 57 HH bb 57 HH bb 57
+ HH bb 57 HH bb 57 II aa 66 II aa 66 II bb 66 II bb 66 II bb 66
+ II bb 66 II bb 66 JJ aa 73 JJ aa 73 JJ aa 73 JJ aa 73 JJ bb 73
+ JJ bb 73 JJ bb 73 JJ bb 73}
+
+do_execsql_test 1.9.4 {
+ SELECT a, b, max(c) OVER (ORDER BY a,b GROUPS BETWEEN 2 PRECEDING AND CURRENT ROW ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 934 AA aa 934 AA aa 934 AA aa 934 AA bb 934 AA bb 934
+ AA bb 934 AA bb 934 BB aa 934 BB aa 934 BB aa 934 BB aa 934
+ BB aa 934 BB aa 934 BB bb 870 BB bb 870 BB bb 870 BB bb 870
+ BB bb 870 BB bb 870 CC aa 840 CC aa 840 CC aa 840 CC aa 840
+ CC bb 840 CC bb 840 DD aa 845 DD aa 845 DD aa 845 DD bb 959
+ DD bb 959 DD bb 959 DD bb 959 EE aa 959 EE aa 959 EE bb 959
+ EE bb 959 EE bb 959 FF aa 777 FF aa 777 FF aa 777 FF aa 777
+ FF bb 938 FF bb 938 FF bb 938 FF bb 938 FF bb 938 FF bb 938
+ GG aa 938 GG aa 938 GG aa 938 GG aa 938 GG bb 938 GG bb 938
+ GG bb 938 GG bb 938 HH aa 979 HH aa 979 HH aa 979 HH bb 979
+ HH bb 979 HH bb 979 HH bb 979 HH bb 979 HH bb 979 II aa 979
+ II aa 979 II bb 963 II bb 963 II bb 963 II bb 963 II bb 963
+ JJ aa 899 JJ aa 899 JJ aa 899 JJ aa 899 JJ bb 899 JJ bb 899
+ JJ bb 899 JJ bb 899}
+
+do_execsql_test 1.9.5 {
+ SELECT a, b, min(c) OVER (ORDER BY a,b GROUPS BETWEEN 2 PRECEDING AND CURRENT ROW ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 223 AA aa 223 AA aa 223 AA aa 223 AA bb 223 AA bb 223
+ AA bb 223 AA bb 223 BB aa 223 BB aa 223 BB aa 223 BB aa 223
+ BB aa 223 BB aa 223 BB bb 247 BB bb 247 BB bb 247 BB bb 247
+ BB bb 247 BB bb 247 CC aa 158 CC aa 158 CC aa 158 CC aa 158
+ CC bb 158 CC bb 158 DD aa 158 DD aa 158 DD aa 158 DD bb 224
+ DD bb 224 DD bb 224 DD bb 224 EE aa 113 EE aa 113 EE bb 113
+ EE bb 113 EE bb 113 FF aa 113 FF aa 113 FF aa 113 FF aa 113
+ FF bb 102 FF bb 102 FF bb 102 FF bb 102 FF bb 102 FF bb 102
+ GG aa 102 GG aa 102 GG aa 102 GG aa 102 GG bb 102 GG bb 102
+ GG bb 102 GG bb 102 HH aa 148 HH aa 148 HH aa 148 HH bb 133
+ HH bb 133 HH bb 133 HH bb 133 HH bb 133 HH bb 133 II aa 133
+ II aa 133 II bb 133 II bb 133 II bb 133 II bb 133 II bb 133
+ JJ aa 113 JJ aa 113 JJ aa 113 JJ aa 113 JJ bb 113 JJ bb 113
+ JJ bb 113 JJ bb 113}
+
+do_execsql_test 1.9.6 {
+ 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;
+} {AA aa 3751 AA aa 3774 AA aa 4446 AA aa 4462 AA bb 3815 AA bb 4058
+ AA bb 4113 AA bb 4376 BB aa 11263 BB aa 11365 BB aa 11613
+ BB aa 11626 BB aa 11632 BB aa 11778 BB bb 11185 BB bb 11233
+ BB bb 11239 BB bb 11314 BB bb 11320 BB bb 11392 CC aa 14388
+ CC aa 14540 CC aa 14717 CC aa 14989 CC bb 14325 CC bb 14801
+ DD aa 13649 DD aa 14238 DD aa 14270 DD bb 13535 DD bb 13700
+ DD bb 13778 DD bb 14256 EE aa 8916 EE aa 9580 EE bb 8925
+ EE bb 9064 EE bb 9441 FF aa 11569 FF aa 11572 FF aa 11621
+ FF aa 12031 FF bb 11301 FF bb 11369 FF bb 11513 FF bb 11665
+ FF bb 11944 FF bb 12137 GG aa 12041 GG aa 12195 GG aa 12340
+ GG aa 12527 GG bb 11737 GG bb 11746 GG bb 11831 GG bb 12515
+ HH aa 14600 HH aa 14789 HH aa 15099 HH bb 14616 HH bb 14849
+ HH bb 14896 HH bb 15224 HH bb 15249 HH bb 15446 II aa 12899
+ II aa 13153 II bb 12746 II bb 12880 II bb 13108 II bb 13130
+ II bb 13301 JJ aa 11984 JJ aa 12115 JJ aa 12649 JJ aa 12770
+ JJ bb 12044 JJ bb 12529 JJ bb 12547 JJ bb 12626}
+
+do_execsql_test 1.9.7 {
+ 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;
+} {AA aa 1373 AA aa 1396 AA aa 2068 AA aa 2084 AA bb 3815 AA bb 4058
+ AA bb 4113 AA bb 4376 BB aa 6796 BB aa 6898 BB aa 7146 BB aa 7159
+ BB aa 7165 BB aa 7311 BB bb 8878 BB bb 8926 BB bb 8932 BB bb 9007
+ BB bb 9013 BB bb 9085 CC aa 8535 CC aa 8687 CC aa 8864 CC aa 9136
+ CC bb 6767 CC bb 7243 DD aa 3602 DD aa 4191 DD aa 4223 DD bb 4241
+ DD bb 4406 DD bb 4484 DD bb 4962 EE aa 4145 EE aa 4809 EE bb 4478
+ EE bb 4617 EE bb 4994 FF aa 4032 FF aa 4035 FF aa 4084 FF aa 4494
+ FF bb 6379 FF bb 6447 FF bb 6591 FF bb 6743 FF bb 7022 FF bb 7215
+ GG aa 6631 GG aa 6785 GG aa 6930 GG aa 7117 GG bb 7035 GG bb 7044
+ GG bb 7129 GG bb 7813 HH aa 5738 HH aa 5927 HH aa 6237 HH bb 7351
+ HH bb 7584 HH bb 7631 HH bb 7959 HH bb 7984 HH bb 8181 II aa 5841
+ II aa 6095 II bb 6029 II bb 6163 II bb 6391 II bb 6413 II bb 6584
+ JJ aa 4755 JJ aa 4886 JJ aa 5420 JJ aa 5541 JJ bb 5551 JJ bb 6036
+ JJ bb 6054 JJ bb 6133}
+
+do_execsql_test 1.9.8 {
+ SELECT a, b,
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN 2 PRECEDING AND CURRENT ROW EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN 2 PRECEDING AND CURRENT ROW ),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 2 PRECEDING AND CURRENT ROW EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 2 PRECEDING AND CURRENT ROW )
+ FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 3751 4685 1373 2307 AA aa 3774 4685 1396 2307
+ AA aa 4446 4685 2068 2307 AA aa 4462 4685 2084 2307
+ AA bb 3815 4685 3815 4685 AA bb 4058 4685 4058 4685
+ AA bb 4113 4685 4113 4685 AA bb 4376 4685 4376 4685
+ BB aa 11263 12025 6796 7558 BB aa 11365 12025 6898 7558
+ BB aa 11613 12025 7146 7558 BB aa 11626 12025 7159 7558
+ BB aa 11632 12025 7165 7558 BB aa 11778 12025 7311 7558
+ BB bb 11185 12025 8878 9718 BB bb 11233 12025 8926 9718
+ BB bb 11239 12025 8932 9718 BB bb 11314 12025 9007 9718
+ BB bb 11320 12025 9013 9718 BB bb 11392 12025 9085 9718
+ CC aa 14388 15147 8535 9294 CC aa 14540 15147 8687 9294
+ CC aa 14717 15147 8864 9294 CC aa 14989 15147 9136 9294
+ CC bb 14325 15147 6767 7589 CC bb 14801 15147 7243 7589
+ DD aa 13649 14494 3602 4447 DD aa 14238 14494 4191 4447
+ DD aa 14270 14494 4223 4447 DD bb 13535 14494 4241 5200
+ DD bb 13700 14494 4406 5200 DD bb 13778 14494 4484 5200
+ DD bb 14256 14494 4962 5200 EE aa 8916 9693 4145 4922
+ EE aa 9580 9693 4809 4922 EE bb 8925 9693 4478 5246
+ EE bb 9064 9693 4617 5246 EE bb 9441 9693 4994 5246
+ FF aa 11569 12239 4032 4702 FF aa 11572 12239 4035 4702
+ FF aa 11621 12239 4084 4702 FF aa 12031 12239 4494 4702
+ FF bb 11301 12239 6379 7317 FF bb 11369 12239 6447 7317
+ FF bb 11513 12239 6591 7317 FF bb 11665 12239 6743 7317
+ FF bb 11944 12239 7022 7317 FF bb 12137 12239 7215 7317
+ GG aa 12041 12675 6631 7265 GG aa 12195 12675 6785 7265
+ GG aa 12340 12675 6930 7265 GG aa 12527 12675 7117 7265
+ GG bb 11737 12675 7035 7973 GG bb 11746 12675 7044 7973
+ GG bb 11831 12675 7129 7973 GG bb 12515 12675 7813 7973
+ HH aa 14600 15579 5738 6717 HH aa 14789 15579 5927 6717
+ HH aa 15099 15579 6237 6717 HH bb 14616 15579 7351 8314
+ HH bb 14849 15579 7584 8314 HH bb 14896 15579 7631 8314
+ HH bb 15224 15579 7959 8314 HH bb 15249 15579 7984 8314
+ HH bb 15446 15579 8181 8314 II aa 12899 13551 5841 6493
+ II aa 13153 13551 6095 6493 II bb 12746 13551 6029 6834
+ II bb 12880 13551 6163 6834 II bb 13108 13551 6391 6834
+ II bb 13130 13551 6413 6834 II bb 13301 13551 6584 6834
+ JJ aa 11984 12883 4755 5654 JJ aa 12115 12883 4886 5654
+ JJ aa 12649 12883 5420 5654 JJ aa 12770 12883 5541 5654
+ JJ bb 12044 12883 5551 6390 JJ bb 12529 12883 6036 6390
+ JJ bb 12547 12883 6054 6390 JJ bb 12626 12883 6133 6390}
+
+do_execsql_test 1.10.1 {
+ SELECT a, b, sum(c) OVER (ORDER BY a GROUPS BETWEEN 3 PRECEDING AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 4685 AA aa 4685 AA aa 4685 AA aa 4685 AA bb 4685 AA bb 4685
+ AA bb 4685 AA bb 4685 BB aa 12025 BB aa 12025 BB aa 12025
+ BB aa 12025 BB aa 12025 BB aa 12025 BB bb 12025 BB bb 12025
+ BB bb 12025 BB bb 12025 BB bb 12025 BB bb 12025 CC aa 15147
+ CC aa 15147 CC aa 15147 CC aa 15147 CC bb 15147 CC bb 15147
+ DD aa 19179 DD aa 19179 DD aa 19179 DD bb 19179 DD bb 19179
+ DD bb 19179 DD bb 19179 EE aa 17033 EE aa 17033 EE bb 17033
+ EE bb 17033 EE bb 17033 FF aa 15361 FF aa 15361 FF aa 15361
+ FF aa 15361 FF bb 15361 FF bb 15361 FF bb 15361 FF bb 15361
+ FF bb 15361 FF bb 15361 GG aa 16707 GG aa 16707 GG aa 16707
+ GG aa 16707 GG bb 16707 GG bb 16707 GG bb 16707 GG bb 16707
+ HH aa 18118 HH aa 18118 HH aa 18118 HH bb 18118 HH bb 18118
+ HH bb 18118 HH bb 18118 HH bb 18118 HH bb 18118 II aa 19219
+ II aa 19219 II bb 19219 II bb 19219 II bb 19219 II bb 19219
+ II bb 19219 JJ aa 17351 JJ aa 17351 JJ aa 17351 JJ aa 17351
+ JJ bb 17351 JJ bb 17351 JJ bb 17351 JJ bb 17351}
+
+do_execsql_test 1.10.2 {
+ SELECT a, b, sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 3 PRECEDING AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 2307 AA aa 2307 AA aa 2307 AA aa 2307 AA bb 4685 AA bb 4685
+ AA bb 4685 AA bb 4685 BB aa 7558 BB aa 7558 BB aa 7558 BB aa 7558
+ BB aa 7558 BB aa 7558 BB bb 12025 BB bb 12025 BB bb 12025
+ BB bb 12025 BB bb 12025 BB bb 12025 CC aa 11672 CC aa 11672
+ CC aa 11672 CC aa 11672 CC bb 10462 CC bb 10462 DD aa 8914
+ DD aa 8914 DD aa 8914 DD bb 7154 DD bb 7154 DD bb 7154 DD bb 7154
+ EE aa 6090 EE aa 6090 EE bb 6571 EE bb 6571 EE bb 6571 FF aa 7409
+ FF aa 7409 FF aa 7409 FF aa 7409 FF bb 8207 FF bb 8207 FF bb 8207
+ FF bb 8207 FF bb 8207 FF bb 8207 GG aa 8914 GG aa 8914 GG aa 8914
+ GG aa 8914 GG bb 10136 GG bb 10136 GG bb 10136 GG bb 10136
+ HH aa 10222 HH aa 10222 HH aa 10222 HH bb 9911 HH bb 9911
+ HH bb 9911 HH bb 9911 HH bb 9911 HH bb 9911 II aa 9364 II aa 9364
+ II bb 9083 II bb 9083 II bb 9083 II bb 9083 II bb 9083 JJ aa 8848
+ JJ aa 8848 JJ aa 8848 JJ aa 8848 JJ bb 7440 JJ bb 7440 JJ bb 7440
+ JJ bb 7440}
+
+do_execsql_test 1.10.3 {
+ SELECT a, b, rank() OVER (ORDER BY a GROUPS BETWEEN 3 PRECEDING AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 1 AA aa 1 AA aa 1 AA aa 1 AA bb 1 AA bb 1 AA bb 1
+ AA bb 1 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9
+ BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 CC aa 21
+ CC aa 21 CC aa 21 CC aa 21 CC bb 21 CC bb 21 DD aa 27 DD aa 27
+ DD aa 27 DD bb 27 DD bb 27 DD bb 27 DD bb 27 EE aa 34 EE aa 34
+ EE bb 34 EE bb 34 EE bb 34 FF aa 39 FF aa 39 FF aa 39 FF aa 39
+ FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 GG aa 49
+ GG aa 49 GG aa 49 GG aa 49 GG bb 49 GG bb 49 GG bb 49 GG bb 49
+ HH aa 57 HH aa 57 HH aa 57 HH bb 57 HH bb 57 HH bb 57 HH bb 57
+ HH bb 57 HH bb 57 II aa 66 II aa 66 II bb 66 II bb 66 II bb 66
+ II bb 66 II bb 66 JJ aa 73 JJ aa 73 JJ aa 73 JJ aa 73 JJ bb 73
+ JJ bb 73 JJ bb 73 JJ bb 73}
+
+do_execsql_test 1.10.4 {
+ SELECT a, b, max(c) OVER (ORDER BY a,b GROUPS BETWEEN 3 PRECEDING AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 934 AA aa 934 AA aa 934 AA aa 934 AA bb 934 AA bb 934
+ AA bb 934 AA bb 934 BB aa 934 BB aa 934 BB aa 934 BB aa 934
+ BB aa 934 BB aa 934 BB bb 934 BB bb 934 BB bb 934 BB bb 934
+ BB bb 934 BB bb 934 CC aa 870 CC aa 870 CC aa 870 CC aa 870
+ CC bb 840 CC bb 840 DD aa 845 DD aa 845 DD aa 845 DD bb 959
+ DD bb 959 DD bb 959 DD bb 959 EE aa 959 EE aa 959 EE bb 959
+ EE bb 959 EE bb 959 FF aa 959 FF aa 959 FF aa 959 FF aa 959
+ FF bb 938 FF bb 938 FF bb 938 FF bb 938 FF bb 938 FF bb 938
+ GG aa 938 GG aa 938 GG aa 938 GG aa 938 GG bb 938 GG bb 938
+ GG bb 938 GG bb 938 HH aa 979 HH aa 979 HH aa 979 HH bb 979
+ HH bb 979 HH bb 979 HH bb 979 HH bb 979 HH bb 979 II aa 979
+ II aa 979 II bb 979 II bb 979 II bb 979 II bb 979 II bb 979
+ JJ aa 963 JJ aa 963 JJ aa 963 JJ aa 963 JJ bb 899 JJ bb 899
+ JJ bb 899 JJ bb 899}
+
+do_execsql_test 1.10.5 {
+ SELECT a, b, min(c) OVER (ORDER BY a,b GROUPS BETWEEN 3 PRECEDING AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 223 AA aa 223 AA aa 223 AA aa 223 AA bb 223 AA bb 223
+ AA bb 223 AA bb 223 BB aa 223 BB aa 223 BB aa 223 BB aa 223
+ BB aa 223 BB aa 223 BB bb 223 BB bb 223 BB bb 223 BB bb 223
+ BB bb 223 BB bb 223 CC aa 158 CC aa 158 CC aa 158 CC aa 158
+ CC bb 158 CC bb 158 DD aa 158 DD aa 158 DD aa 158 DD bb 158
+ DD bb 158 DD bb 158 DD bb 158 EE aa 113 EE aa 113 EE bb 113
+ EE bb 113 EE bb 113 FF aa 113 FF aa 113 FF aa 113 FF aa 113
+ FF bb 102 FF bb 102 FF bb 102 FF bb 102 FF bb 102 FF bb 102
+ GG aa 102 GG aa 102 GG aa 102 GG aa 102 GG bb 102 GG bb 102
+ GG bb 102 GG bb 102 HH aa 102 HH aa 102 HH aa 102 HH bb 133
+ HH bb 133 HH bb 133 HH bb 133 HH bb 133 HH bb 133 II aa 133
+ II aa 133 II bb 133 II bb 133 II bb 133 II bb 133 II bb 133
+ JJ aa 113 JJ aa 113 JJ aa 113 JJ aa 113 JJ bb 113 JJ bb 113
+ JJ bb 113 JJ bb 113}
+
+do_execsql_test 1.10.6 {
+ 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;
+} {AA aa 3751 AA aa 3774 AA aa 4446 AA aa 4462 AA bb 3815 AA bb 4058
+ AA bb 4113 AA bb 4376 BB aa 11263 BB aa 11365 BB aa 11613
+ BB aa 11626 BB aa 11632 BB aa 11778 BB bb 11185 BB bb 11233
+ BB bb 11239 BB bb 11314 BB bb 11320 BB bb 11392 CC aa 14388
+ CC aa 14540 CC aa 14717 CC aa 14989 CC bb 14325 CC bb 14801
+ DD aa 18334 DD aa 18923 DD aa 18955 DD bb 18220 DD bb 18385
+ DD bb 18463 DD bb 18941 EE aa 16256 EE aa 16920 EE bb 16265
+ EE bb 16404 EE bb 16781 FF aa 14691 FF aa 14694 FF aa 14743
+ FF aa 15153 FF bb 14423 FF bb 14491 FF bb 14635 FF bb 14787
+ FF bb 15066 FF bb 15259 GG aa 16073 GG aa 16227 GG aa 16372
+ GG aa 16559 GG bb 15769 GG bb 15778 GG bb 15863 GG bb 16547
+ HH aa 17139 HH aa 17328 HH aa 17638 HH bb 17155 HH bb 17388
+ HH bb 17435 HH bb 17763 HH bb 17788 HH bb 17985 II aa 18567
+ II aa 18821 II bb 18414 II bb 18548 II bb 18776 II bb 18798
+ II bb 18969 JJ aa 16452 JJ aa 16583 JJ aa 17117 JJ aa 17238
+ JJ bb 16512 JJ bb 16997 JJ bb 17015 JJ bb 17094}
+
+do_execsql_test 1.10.7 {
+ 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;
+} {AA aa 1373 AA aa 1396 AA aa 2068 AA aa 2084 AA bb 3815 AA bb 4058
+ AA bb 4113 AA bb 4376 BB aa 6796 BB aa 6898 BB aa 7146 BB aa 7159
+ BB aa 7165 BB aa 7311 BB bb 11185 BB bb 11233 BB bb 11239
+ BB bb 11314 BB bb 11320 BB bb 11392 CC aa 10913 CC aa 11065
+ CC aa 11242 CC aa 11514 CC bb 9640 CC bb 10116 DD aa 8069
+ DD aa 8658 DD aa 8690 DD bb 6195 DD bb 6360 DD bb 6438 DD bb 6916
+ EE aa 5313 EE aa 5977 EE bb 5803 EE bb 5942 EE bb 6319 FF aa 6739
+ FF aa 6742 FF aa 6791 FF aa 7201 FF bb 7269 FF bb 7337 FF bb 7481
+ FF bb 7633 FF bb 7912 FF bb 8105 GG aa 8280 GG aa 8434 GG aa 8579
+ GG aa 8766 GG bb 9198 GG bb 9207 GG bb 9292 GG bb 9976 HH aa 9243
+ HH aa 9432 HH aa 9742 HH bb 8948 HH bb 9181 HH bb 9228 HH bb 9556
+ HH bb 9581 HH bb 9778 II aa 8712 II aa 8966 II bb 8278 II bb 8412
+ II bb 8640 II bb 8662 II bb 8833 JJ aa 7949 JJ aa 8080 JJ aa 8614
+ JJ aa 8735 JJ bb 6601 JJ bb 7086 JJ bb 7104 JJ bb 7183}
+
+do_execsql_test 1.10.8 {
+ SELECT a, b,
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN 3 PRECEDING AND 0 FOLLOWING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN 3 PRECEDING AND 0 FOLLOWING ),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 3 PRECEDING AND 0 FOLLOWING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 3 PRECEDING AND 0 FOLLOWING )
+ FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 3751 4685 1373 2307 AA aa 3774 4685 1396 2307
+ AA aa 4446 4685 2068 2307 AA aa 4462 4685 2084 2307
+ AA bb 3815 4685 3815 4685 AA bb 4058 4685 4058 4685
+ AA bb 4113 4685 4113 4685 AA bb 4376 4685 4376 4685
+ BB aa 11263 12025 6796 7558 BB aa 11365 12025 6898 7558
+ BB aa 11613 12025 7146 7558 BB aa 11626 12025 7159 7558
+ BB aa 11632 12025 7165 7558 BB aa 11778 12025 7311 7558
+ BB bb 11185 12025 11185 12025 BB bb 11233 12025 11233 12025
+ BB bb 11239 12025 11239 12025 BB bb 11314 12025 11314 12025
+ BB bb 11320 12025 11320 12025 BB bb 11392 12025 11392 12025
+ CC aa 14388 15147 10913 11672 CC aa 14540 15147 11065 11672
+ CC aa 14717 15147 11242 11672 CC aa 14989 15147 11514 11672
+ CC bb 14325 15147 9640 10462 CC bb 14801 15147 10116 10462
+ DD aa 18334 19179 8069 8914 DD aa 18923 19179 8658 8914
+ DD aa 18955 19179 8690 8914 DD bb 18220 19179 6195 7154
+ DD bb 18385 19179 6360 7154 DD bb 18463 19179 6438 7154
+ DD bb 18941 19179 6916 7154 EE aa 16256 17033 5313 6090
+ EE aa 16920 17033 5977 6090 EE bb 16265 17033 5803 6571
+ EE bb 16404 17033 5942 6571 EE bb 16781 17033 6319 6571
+ FF aa 14691 15361 6739 7409 FF aa 14694 15361 6742 7409
+ FF aa 14743 15361 6791 7409 FF aa 15153 15361 7201 7409
+ FF bb 14423 15361 7269 8207 FF bb 14491 15361 7337 8207
+ FF bb 14635 15361 7481 8207 FF bb 14787 15361 7633 8207
+ FF bb 15066 15361 7912 8207 FF bb 15259 15361 8105 8207
+ GG aa 16073 16707 8280 8914 GG aa 16227 16707 8434 8914
+ GG aa 16372 16707 8579 8914 GG aa 16559 16707 8766 8914
+ GG bb 15769 16707 9198 10136 GG bb 15778 16707 9207 10136
+ GG bb 15863 16707 9292 10136 GG bb 16547 16707 9976 10136
+ HH aa 17139 18118 9243 10222 HH aa 17328 18118 9432 10222
+ HH aa 17638 18118 9742 10222 HH bb 17155 18118 8948 9911
+ HH bb 17388 18118 9181 9911 HH bb 17435 18118 9228 9911
+ HH bb 17763 18118 9556 9911 HH bb 17788 18118 9581 9911
+ HH bb 17985 18118 9778 9911 II aa 18567 19219 8712 9364
+ II aa 18821 19219 8966 9364 II bb 18414 19219 8278 9083
+ II bb 18548 19219 8412 9083 II bb 18776 19219 8640 9083
+ II bb 18798 19219 8662 9083 II bb 18969 19219 8833 9083
+ JJ aa 16452 17351 7949 8848 JJ aa 16583 17351 8080 8848
+ JJ aa 17117 17351 8614 8848 JJ aa 17238 17351 8735 8848
+ JJ bb 16512 17351 6601 7440 JJ bb 16997 17351 7086 7440
+ JJ bb 17015 17351 7104 7440 JJ bb 17094 17351 7183 7440}
+
+do_execsql_test 1.11.1 {
+ SELECT a, b, sum(c) OVER (ORDER BY a GROUPS BETWEEN 2 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 44737 AA aa 44737 AA aa 44737 AA aa 44737 AA bb 44737
+ AA bb 44737 AA bb 44737 AA bb 44737 BB aa 44737 BB aa 44737
+ BB aa 44737 BB aa 44737 BB aa 44737 BB aa 44737 BB bb 44737
+ BB bb 44737 BB bb 44737 BB bb 44737 BB bb 44737 BB bb 44737
+ CC aa 44737 CC aa 44737 CC aa 44737 CC aa 44737 CC bb 44737
+ CC bb 44737 DD aa 40052 DD aa 40052 DD aa 40052 DD bb 40052
+ DD bb 40052 DD bb 40052 DD bb 40052 EE aa 32712 EE aa 32712
+ EE bb 32712 EE bb 32712 EE bb 32712 FF aa 29590 FF aa 29590
+ FF aa 29590 FF aa 29590 FF bb 29590 FF bb 29590 FF bb 29590
+ FF bb 29590 FF bb 29590 FF bb 29590 GG aa 25558 GG aa 25558
+ GG aa 25558 GG aa 25558 GG bb 25558 GG bb 25558 GG bb 25558
+ GG bb 25558 HH aa 23019 HH aa 23019 HH aa 23019 HH bb 23019
+ HH bb 23019 HH bb 23019 HH bb 23019 HH bb 23019 HH bb 23019
+ II aa 17351 II aa 17351 II bb 17351 II bb 17351 II bb 17351
+ II bb 17351 II bb 17351 JJ aa 12883 JJ aa 12883 JJ aa 12883
+ JJ aa 12883 JJ bb 12883 JJ bb 12883 JJ bb 12883 JJ bb 12883}
+
+do_execsql_test 1.11.2 {
+ SELECT a, b, sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 2 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 44737 AA aa 44737 AA aa 44737 AA aa 44737 AA bb 44737
+ AA bb 44737 AA bb 44737 AA bb 44737 BB aa 44737 BB aa 44737
+ BB aa 44737 BB aa 44737 BB aa 44737 BB aa 44737 BB bb 42430
+ BB bb 42430 BB bb 42430 BB bb 42430 BB bb 42430 BB bb 42430
+ CC aa 40052 CC aa 40052 CC aa 40052 CC aa 40052 CC bb 37179
+ CC bb 37179 DD aa 32712 DD aa 32712 DD aa 32712 DD bb 30758
+ DD bb 30758 DD bb 30758 DD bb 30758 EE aa 29590 EE aa 29590
+ EE bb 28265 EE bb 28265 EE bb 28265 FF aa 25558 FF aa 25558
+ FF aa 25558 FF aa 25558 FF bb 24668 FF bb 24668 FF bb 24668
+ FF bb 24668 FF bb 24668 FF bb 24668 GG aa 23019 GG aa 23019
+ GG aa 23019 GG aa 23019 GG bb 20856 GG bb 20856 GG bb 20856
+ GG bb 20856 HH aa 17351 HH aa 17351 HH aa 17351 HH bb 15754
+ HH bb 15754 HH bb 15754 HH bb 15754 HH bb 15754 HH bb 15754
+ II aa 12883 II aa 12883 II bb 10634 II bb 10634 II bb 10634
+ II bb 10634 II bb 10634 JJ aa 7440 JJ aa 7440 JJ aa 7440
+ JJ aa 7440 JJ bb 6390 JJ bb 6390 JJ bb 6390 JJ bb 6390}
+
+do_execsql_test 1.11.3 {
+ SELECT a, b, rank() OVER (ORDER BY a GROUPS BETWEEN 2 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 1 AA aa 1 AA aa 1 AA aa 1 AA bb 1 AA bb 1 AA bb 1
+ AA bb 1 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9
+ BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 CC aa 21
+ CC aa 21 CC aa 21 CC aa 21 CC bb 21 CC bb 21 DD aa 27 DD aa 27
+ DD aa 27 DD bb 27 DD bb 27 DD bb 27 DD bb 27 EE aa 34 EE aa 34
+ EE bb 34 EE bb 34 EE bb 34 FF aa 39 FF aa 39 FF aa 39 FF aa 39
+ FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 GG aa 49
+ GG aa 49 GG aa 49 GG aa 49 GG bb 49 GG bb 49 GG bb 49 GG bb 49
+ HH aa 57 HH aa 57 HH aa 57 HH bb 57 HH bb 57 HH bb 57 HH bb 57
+ HH bb 57 HH bb 57 II aa 66 II aa 66 II bb 66 II bb 66 II bb 66
+ II bb 66 II bb 66 JJ aa 73 JJ aa 73 JJ aa 73 JJ aa 73 JJ bb 73
+ JJ bb 73 JJ bb 73 JJ bb 73}
+
+do_execsql_test 1.11.4 {
+ SELECT a, b, max(c) OVER (ORDER BY a,b GROUPS BETWEEN 2 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 979 AA aa 979 AA aa 979 AA aa 979 AA bb 979 AA bb 979
+ AA bb 979 AA bb 979 BB aa 979 BB aa 979 BB aa 979 BB aa 979
+ BB aa 979 BB aa 979 BB bb 979 BB bb 979 BB bb 979 BB bb 979
+ BB bb 979 BB bb 979 CC aa 979 CC aa 979 CC aa 979 CC aa 979
+ CC bb 979 CC bb 979 DD aa 979 DD aa 979 DD aa 979 DD bb 979
+ DD bb 979 DD bb 979 DD bb 979 EE aa 979 EE aa 979 EE bb 979
+ EE bb 979 EE bb 979 FF aa 979 FF aa 979 FF aa 979 FF aa 979
+ FF bb 979 FF bb 979 FF bb 979 FF bb 979 FF bb 979 FF bb 979
+ GG aa 979 GG aa 979 GG aa 979 GG aa 979 GG bb 979 GG bb 979
+ GG bb 979 GG bb 979 HH aa 979 HH aa 979 HH aa 979 HH bb 979
+ HH bb 979 HH bb 979 HH bb 979 HH bb 979 HH bb 979 II aa 979
+ II aa 979 II bb 963 II bb 963 II bb 963 II bb 963 II bb 963
+ JJ aa 899 JJ aa 899 JJ aa 899 JJ aa 899 JJ bb 899 JJ bb 899
+ JJ bb 899 JJ bb 899}
+
+do_execsql_test 1.11.5 {
+ SELECT a, b, min(c) OVER (ORDER BY a,b GROUPS BETWEEN 2 PRECEDING AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 102 AA aa 102 AA aa 102 AA aa 102 AA bb 102 AA bb 102
+ AA bb 102 AA bb 102 BB aa 102 BB aa 102 BB aa 102 BB aa 102
+ BB aa 102 BB aa 102 BB bb 102 BB bb 102 BB bb 102 BB bb 102
+ BB bb 102 BB bb 102 CC aa 102 CC aa 102 CC aa 102 CC aa 102
+ CC bb 102 CC bb 102 DD aa 102 DD aa 102 DD aa 102 DD bb 102
+ DD bb 102 DD bb 102 DD bb 102 EE aa 102 EE aa 102 EE bb 102
+ EE bb 102 EE bb 102 FF aa 102 FF aa 102 FF aa 102 FF aa 102
+ FF bb 102 FF bb 102 FF bb 102 FF bb 102 FF bb 102 FF bb 102
+ GG aa 102 GG aa 102 GG aa 102 GG aa 102 GG bb 102 GG bb 102
+ GG bb 102 GG bb 102 HH aa 113 HH aa 113 HH aa 113 HH bb 113
+ HH bb 113 HH bb 113 HH bb 113 HH bb 113 HH bb 113 II aa 113
+ II aa 113 II bb 113 II bb 113 II bb 113 II bb 113 II bb 113
+ JJ aa 113 JJ aa 113 JJ aa 113 JJ aa 113 JJ bb 113 JJ bb 113
+ JJ bb 113 JJ bb 113}
+
+do_execsql_test 1.11.6 {
+ 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;
+} {AA aa 43803 AA aa 43826 AA aa 44498 AA aa 44514 AA bb 43867
+ AA bb 44110 AA bb 44165 AA bb 44428 BB aa 43975 BB aa 44077
+ BB aa 44325 BB aa 44338 BB aa 44344 BB aa 44490 BB bb 43897
+ BB bb 43945 BB bb 43951 BB bb 44026 BB bb 44032 BB bb 44104
+ CC aa 43978 CC aa 44130 CC aa 44307 CC aa 44579 CC bb 43915
+ CC bb 44391 DD aa 39207 DD aa 39796 DD aa 39828 DD bb 39093
+ DD bb 39258 DD bb 39336 DD bb 39814 EE aa 31935 EE aa 32599
+ EE bb 31944 EE bb 32083 EE bb 32460 FF aa 28920 FF aa 28923
+ FF aa 28972 FF aa 29382 FF bb 28652 FF bb 28720 FF bb 28864
+ FF bb 29016 FF bb 29295 FF bb 29488 GG aa 24924 GG aa 25078
+ GG aa 25223 GG aa 25410 GG bb 24620 GG bb 24629 GG bb 24714
+ GG bb 25398 HH aa 22040 HH aa 22229 HH aa 22539 HH bb 22056
+ HH bb 22289 HH bb 22336 HH bb 22664 HH bb 22689 HH bb 22886
+ II aa 16699 II aa 16953 II bb 16546 II bb 16680 II bb 16908
+ II bb 16930 II bb 17101 JJ aa 11984 JJ aa 12115 JJ aa 12649
+ JJ aa 12770 JJ bb 12044 JJ bb 12529 JJ bb 12547 JJ bb 12626}
+
+do_execsql_test 1.11.7 {
+ 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;
+} {AA aa 43803 AA aa 43826 AA aa 44498 AA aa 44514 AA bb 43867
+ AA bb 44110 AA bb 44165 AA bb 44428 BB aa 43975 BB aa 44077
+ BB aa 44325 BB aa 44338 BB aa 44344 BB aa 44490 BB bb 41590
+ BB bb 41638 BB bb 41644 BB bb 41719 BB bb 41725 BB bb 41797
+ CC aa 39293 CC aa 39445 CC aa 39622 CC aa 39894 CC bb 36357
+ CC bb 36833 DD aa 31867 DD aa 32456 DD aa 32488 DD bb 29799
+ DD bb 29964 DD bb 30042 DD bb 30520 EE aa 28813 EE aa 29477
+ EE bb 27497 EE bb 27636 EE bb 28013 FF aa 24888 FF aa 24891
+ FF aa 24940 FF aa 25350 FF bb 23730 FF bb 23798 FF bb 23942
+ FF bb 24094 FF bb 24373 FF bb 24566 GG aa 22385 GG aa 22539
+ GG aa 22684 GG aa 22871 GG bb 19918 GG bb 19927 GG bb 20012
+ GG bb 20696 HH aa 16372 HH aa 16561 HH aa 16871 HH bb 14791
+ HH bb 15024 HH bb 15071 HH bb 15399 HH bb 15424 HH bb 15621
+ II aa 12231 II aa 12485 II bb 9829 II bb 9963 II bb 10191
+ II bb 10213 II bb 10384 JJ aa 6541 JJ aa 6672 JJ aa 7206
+ JJ aa 7327 JJ bb 5551 JJ bb 6036 JJ bb 6054 JJ bb 6133}
+
+do_execsql_test 1.11.8 {
+ SELECT a, b,
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN 2 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN 2 PRECEDING AND UNBOUNDED FOLLOWING ),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 2 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 2 PRECEDING AND UNBOUNDED FOLLOWING )
+ FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 43803 44737 43803 44737 AA aa 43826 44737 43826 44737
+ AA aa 44498 44737 44498 44737 AA aa 44514 44737 44514 44737
+ AA bb 43867 44737 43867 44737 AA bb 44110 44737 44110 44737
+ AA bb 44165 44737 44165 44737 AA bb 44428 44737 44428 44737
+ BB aa 43975 44737 43975 44737 BB aa 44077 44737 44077 44737
+ BB aa 44325 44737 44325 44737 BB aa 44338 44737 44338 44737
+ BB aa 44344 44737 44344 44737 BB aa 44490 44737 44490 44737
+ BB bb 43897 44737 41590 42430 BB bb 43945 44737 41638 42430
+ BB bb 43951 44737 41644 42430 BB bb 44026 44737 41719 42430
+ BB bb 44032 44737 41725 42430 BB bb 44104 44737 41797 42430
+ CC aa 43978 44737 39293 40052 CC aa 44130 44737 39445 40052
+ CC aa 44307 44737 39622 40052 CC aa 44579 44737 39894 40052
+ CC bb 43915 44737 36357 37179 CC bb 44391 44737 36833 37179
+ DD aa 39207 40052 31867 32712 DD aa 39796 40052 32456 32712
+ DD aa 39828 40052 32488 32712 DD bb 39093 40052 29799 30758
+ DD bb 39258 40052 29964 30758 DD bb 39336 40052 30042 30758
+ DD bb 39814 40052 30520 30758 EE aa 31935 32712 28813 29590
+ EE aa 32599 32712 29477 29590 EE bb 31944 32712 27497 28265
+ EE bb 32083 32712 27636 28265 EE bb 32460 32712 28013 28265
+ FF aa 28920 29590 24888 25558 FF aa 28923 29590 24891 25558
+ FF aa 28972 29590 24940 25558 FF aa 29382 29590 25350 25558
+ FF bb 28652 29590 23730 24668 FF bb 28720 29590 23798 24668
+ FF bb 28864 29590 23942 24668 FF bb 29016 29590 24094 24668
+ FF bb 29295 29590 24373 24668 FF bb 29488 29590 24566 24668
+ GG aa 24924 25558 22385 23019 GG aa 25078 25558 22539 23019
+ GG aa 25223 25558 22684 23019 GG aa 25410 25558 22871 23019
+ GG bb 24620 25558 19918 20856 GG bb 24629 25558 19927 20856
+ GG bb 24714 25558 20012 20856 GG bb 25398 25558 20696 20856
+ HH aa 22040 23019 16372 17351 HH aa 22229 23019 16561 17351
+ HH aa 22539 23019 16871 17351 HH bb 22056 23019 14791 15754
+ HH bb 22289 23019 15024 15754 HH bb 22336 23019 15071 15754
+ HH bb 22664 23019 15399 15754 HH bb 22689 23019 15424 15754
+ HH bb 22886 23019 15621 15754 II aa 16699 17351 12231 12883
+ II aa 16953 17351 12485 12883 II bb 16546 17351 9829 10634
+ II bb 16680 17351 9963 10634 II bb 16908 17351 10191 10634
+ II bb 16930 17351 10213 10634 II bb 17101 17351 10384 10634
+ JJ aa 11984 12883 6541 7440 JJ aa 12115 12883 6672 7440
+ JJ aa 12649 12883 7206 7440 JJ aa 12770 12883 7327 7440
+ JJ bb 12044 12883 5551 6390 JJ bb 12529 12883 6036 6390
+ JJ bb 12547 12883 6054 6390 JJ bb 12626 12883 6133 6390}
+
+do_execsql_test 1.12.1 {
+ SELECT a, b, sum(c) OVER (ORDER BY a GROUPS BETWEEN CURRENT ROW AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 4685 AA aa 4685 AA aa 4685 AA aa 4685 AA bb 4685 AA bb 4685
+ AA bb 4685 AA bb 4685 BB aa 7340 BB aa 7340 BB aa 7340 BB aa 7340
+ BB aa 7340 BB aa 7340 BB bb 7340 BB bb 7340 BB bb 7340 BB bb 7340
+ BB bb 7340 BB bb 7340 CC aa 3122 CC aa 3122 CC aa 3122 CC aa 3122
+ CC bb 3122 CC bb 3122 DD aa 4032 DD aa 4032 DD aa 4032 DD bb 4032
+ DD bb 4032 DD bb 4032 DD bb 4032 EE aa 2539 EE aa 2539 EE bb 2539
+ EE bb 2539 EE bb 2539 FF aa 5668 FF aa 5668 FF aa 5668 FF aa 5668
+ FF bb 5668 FF bb 5668 FF bb 5668 FF bb 5668 FF bb 5668 FF bb 5668
+ GG aa 4468 GG aa 4468 GG aa 4468 GG aa 4468 GG bb 4468 GG bb 4468
+ GG bb 4468 GG bb 4468 HH aa 5443 HH aa 5443 HH aa 5443 HH bb 5443
+ HH bb 5443 HH bb 5443 HH bb 5443 HH bb 5443 HH bb 5443 II aa 3640
+ II aa 3640 II bb 3640 II bb 3640 II bb 3640 II bb 3640 II bb 3640
+ JJ aa 3800 JJ aa 3800 JJ aa 3800 JJ aa 3800 JJ bb 3800 JJ bb 3800
+ JJ bb 3800 JJ bb 3800}
+
+do_execsql_test 1.12.2 {
+ SELECT a, b, sum(c) OVER (ORDER BY a,b GROUPS BETWEEN CURRENT ROW AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 2307 AA aa 2307 AA aa 2307 AA aa 2307 AA bb 2378 AA bb 2378
+ AA bb 2378 AA bb 2378 BB aa 2873 BB aa 2873 BB aa 2873 BB aa 2873
+ BB aa 2873 BB aa 2873 BB bb 4467 BB bb 4467 BB bb 4467 BB bb 4467
+ BB bb 4467 BB bb 4467 CC aa 1954 CC aa 1954 CC aa 1954 CC aa 1954
+ CC bb 1168 CC bb 1168 DD aa 1325 DD aa 1325 DD aa 1325 DD bb 2707
+ DD bb 2707 DD bb 2707 DD bb 2707 EE aa 890 EE aa 890 EE bb 1649
+ EE bb 1649 EE bb 1649 FF aa 2163 FF aa 2163 FF aa 2163 FF aa 2163
+ FF bb 3505 FF bb 3505 FF bb 3505 FF bb 3505 FF bb 3505 FF bb 3505
+ GG aa 1597 GG aa 1597 GG aa 1597 GG aa 1597 GG bb 2871 GG bb 2871
+ GG bb 2871 GG bb 2871 HH aa 2249 HH aa 2249 HH aa 2249 HH bb 3194
+ HH bb 3194 HH bb 3194 HH bb 3194 HH bb 3194 HH bb 3194 II aa 1050
+ II aa 1050 II bb 2590 II bb 2590 II bb 2590 II bb 2590 II bb 2590
+ JJ aa 2014 JJ aa 2014 JJ aa 2014 JJ aa 2014 JJ bb 1786 JJ bb 1786
+ JJ bb 1786 JJ bb 1786}
+
+do_execsql_test 1.12.3 {
+ SELECT a, b, rank() OVER (ORDER BY a GROUPS BETWEEN CURRENT ROW AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 1 AA aa 1 AA aa 1 AA aa 1 AA bb 1 AA bb 1 AA bb 1
+ AA bb 1 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9
+ BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 CC aa 21
+ CC aa 21 CC aa 21 CC aa 21 CC bb 21 CC bb 21 DD aa 27 DD aa 27
+ DD aa 27 DD bb 27 DD bb 27 DD bb 27 DD bb 27 EE aa 34 EE aa 34
+ EE bb 34 EE bb 34 EE bb 34 FF aa 39 FF aa 39 FF aa 39 FF aa 39
+ FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 GG aa 49
+ GG aa 49 GG aa 49 GG aa 49 GG bb 49 GG bb 49 GG bb 49 GG bb 49
+ HH aa 57 HH aa 57 HH aa 57 HH bb 57 HH bb 57 HH bb 57 HH bb 57
+ HH bb 57 HH bb 57 II aa 66 II aa 66 II bb 66 II bb 66 II bb 66
+ II bb 66 II bb 66 JJ aa 73 JJ aa 73 JJ aa 73 JJ aa 73 JJ bb 73
+ JJ bb 73 JJ bb 73 JJ bb 73}
+
+do_execsql_test 1.12.4 {
+ SELECT a, b, max(c) OVER (ORDER BY a,b GROUPS BETWEEN CURRENT ROW AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 934 AA aa 934 AA aa 934 AA aa 934 AA bb 870 AA bb 870
+ AA bb 870 AA bb 870 BB aa 762 BB aa 762 BB aa 762 BB aa 762
+ BB aa 762 BB aa 762 BB bb 840 BB bb 840 BB bb 840 BB bb 840
+ BB bb 840 BB bb 840 CC aa 759 CC aa 759 CC aa 759 CC aa 759
+ CC bb 822 CC bb 822 DD aa 845 DD aa 845 DD aa 845 DD bb 959
+ DD bb 959 DD bb 959 DD bb 959 EE aa 777 EE aa 777 EE bb 768
+ EE bb 768 EE bb 768 FF aa 670 FF aa 670 FF aa 670 FF aa 670
+ FF bb 938 FF bb 938 FF bb 938 FF bb 938 FF bb 938 FF bb 938
+ GG aa 634 GG aa 634 GG aa 634 GG aa 634 GG bb 938 GG bb 938
+ GG bb 938 GG bb 938 HH aa 979 HH aa 979 HH aa 979 HH bb 963
+ HH bb 963 HH bb 963 HH bb 963 HH bb 963 HH bb 963 II aa 652
+ II aa 652 II bb 805 II bb 805 II bb 805 II bb 805 II bb 805
+ JJ aa 899 JJ aa 899 JJ aa 899 JJ aa 899 JJ bb 839 JJ bb 839
+ JJ bb 839 JJ bb 839}
+
+do_execsql_test 1.12.5 {
+ SELECT a, b, min(c) OVER (ORDER BY a,b GROUPS BETWEEN CURRENT ROW AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 223 AA aa 223 AA aa 223 AA aa 223 AA bb 309 AA bb 309
+ AA bb 309 AA bb 309 BB aa 247 BB aa 247 BB aa 247 BB aa 247
+ BB aa 247 BB aa 247 BB bb 633 BB bb 633 BB bb 633 BB bb 633
+ BB bb 633 BB bb 633 CC aa 158 CC aa 158 CC aa 158 CC aa 158
+ CC bb 346 CC bb 346 DD aa 224 DD aa 224 DD aa 224 DD bb 238
+ DD bb 238 DD bb 238 DD bb 238 EE aa 113 EE aa 113 EE bb 252
+ EE bb 252 EE bb 252 FF aa 208 FF aa 208 FF aa 208 FF aa 208
+ FF bb 102 FF bb 102 FF bb 102 FF bb 102 FF bb 102 FF bb 102
+ GG aa 148 GG aa 148 GG aa 148 GG aa 148 GG bb 160 GG bb 160
+ GG bb 160 GG bb 160 HH aa 480 HH aa 480 HH aa 480 HH bb 133
+ HH bb 133 HH bb 133 HH bb 133 HH bb 133 HH bb 133 II aa 398
+ II aa 398 II bb 250 II bb 250 II bb 250 II bb 250 II bb 250
+ JJ aa 113 JJ aa 113 JJ aa 113 JJ aa 113 JJ bb 257 JJ bb 257
+ JJ bb 257 JJ bb 257}
+
+do_execsql_test 1.12.6 {
+ 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;
+} {AA aa 3751 AA aa 3774 AA aa 4446 AA aa 4462 AA bb 3815 AA bb 4058
+ AA bb 4113 AA bb 4376 BB aa 6578 BB aa 6680 BB aa 6928 BB aa 6941
+ BB aa 6947 BB aa 7093 BB bb 6500 BB bb 6548 BB bb 6554 BB bb 6629
+ BB bb 6635 BB bb 6707 CC aa 2363 CC aa 2515 CC aa 2692 CC aa 2964
+ CC bb 2300 CC bb 2776 DD aa 3187 DD aa 3776 DD aa 3808 DD bb 3073
+ DD bb 3238 DD bb 3316 DD bb 3794 EE aa 1762 EE aa 2426 EE bb 1771
+ EE bb 1910 EE bb 2287 FF aa 4998 FF aa 5001 FF aa 5050 FF aa 5460
+ FF bb 4730 FF bb 4798 FF bb 4942 FF bb 5094 FF bb 5373 FF bb 5566
+ GG aa 3834 GG aa 3988 GG aa 4133 GG aa 4320 GG bb 3530 GG bb 3539
+ GG bb 3624 GG bb 4308 HH aa 4464 HH aa 4653 HH aa 4963 HH bb 4480
+ HH bb 4713 HH bb 4760 HH bb 5088 HH bb 5113 HH bb 5310 II aa 2988
+ II aa 3242 II bb 2835 II bb 2969 II bb 3197 II bb 3219 II bb 3390
+ JJ aa 2901 JJ aa 3032 JJ aa 3566 JJ aa 3687 JJ bb 2961 JJ bb 3446
+ JJ bb 3464 JJ bb 3543}
+
+do_execsql_test 1.12.7 {
+ 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;
+} {AA aa 1373 AA aa 1396 AA aa 2068 AA aa 2084 AA bb 1508 AA bb 1751
+ AA bb 1806 AA bb 2069 BB aa 2111 BB aa 2213 BB aa 2461 BB aa 2474
+ BB aa 2480 BB aa 2626 BB bb 3627 BB bb 3675 BB bb 3681 BB bb 3756
+ BB bb 3762 BB bb 3834 CC aa 1195 CC aa 1347 CC aa 1524 CC aa 1796
+ CC bb 346 CC bb 822 DD aa 480 DD aa 1069 DD aa 1101 DD bb 1748
+ DD bb 1913 DD bb 1991 DD bb 2469 EE aa 113 EE aa 777 EE bb 881
+ EE bb 1020 EE bb 1397 FF aa 1493 FF aa 1496 FF aa 1545 FF aa 1955
+ FF bb 2567 FF bb 2635 FF bb 2779 FF bb 2931 FF bb 3210 FF bb 3403
+ GG aa 963 GG aa 1117 GG aa 1262 GG aa 1449 GG bb 1933 GG bb 1942
+ GG bb 2027 GG bb 2711 HH aa 1270 HH aa 1459 HH aa 1769 HH bb 2231
+ HH bb 2464 HH bb 2511 HH bb 2839 HH bb 2864 HH bb 3061 II aa 398
+ II aa 652 II bb 1785 II bb 1919 II bb 2147 II bb 2169 II bb 2340
+ JJ aa 1115 JJ aa 1246 JJ aa 1780 JJ aa 1901 JJ bb 947 JJ bb 1432
+ JJ bb 1450 JJ bb 1529}
+
+do_execsql_test 1.12.8 {
+ SELECT a, b,
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN CURRENT ROW AND 0 FOLLOWING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN CURRENT ROW AND 0 FOLLOWING ),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN CURRENT ROW AND 0 FOLLOWING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN CURRENT ROW AND 0 FOLLOWING )
+ FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 3751 4685 1373 2307 AA aa 3774 4685 1396 2307
+ AA aa 4446 4685 2068 2307 AA aa 4462 4685 2084 2307
+ AA bb 3815 4685 1508 2378 AA bb 4058 4685 1751 2378
+ AA bb 4113 4685 1806 2378 AA bb 4376 4685 2069 2378
+ BB aa 6578 7340 2111 2873 BB aa 6680 7340 2213 2873
+ BB aa 6928 7340 2461 2873 BB aa 6941 7340 2474 2873
+ BB aa 6947 7340 2480 2873 BB aa 7093 7340 2626 2873
+ BB bb 6500 7340 3627 4467 BB bb 6548 7340 3675 4467
+ BB bb 6554 7340 3681 4467 BB bb 6629 7340 3756 4467
+ BB bb 6635 7340 3762 4467 BB bb 6707 7340 3834 4467
+ CC aa 2363 3122 1195 1954 CC aa 2515 3122 1347 1954
+ CC aa 2692 3122 1524 1954 CC aa 2964 3122 1796 1954
+ CC bb 2300 3122 346 1168 CC bb 2776 3122 822 1168
+ DD aa 3187 4032 480 1325 DD aa 3776 4032 1069 1325
+ DD aa 3808 4032 1101 1325 DD bb 3073 4032 1748 2707
+ DD bb 3238 4032 1913 2707 DD bb 3316 4032 1991 2707
+ DD bb 3794 4032 2469 2707 EE aa 1762 2539 113 890
+ EE aa 2426 2539 777 890 EE bb 1771 2539 881 1649
+ EE bb 1910 2539 1020 1649 EE bb 2287 2539 1397 1649
+ FF aa 4998 5668 1493 2163 FF aa 5001 5668 1496 2163
+ FF aa 5050 5668 1545 2163 FF aa 5460 5668 1955 2163
+ FF bb 4730 5668 2567 3505 FF bb 4798 5668 2635 3505
+ FF bb 4942 5668 2779 3505 FF bb 5094 5668 2931 3505
+ FF bb 5373 5668 3210 3505 FF bb 5566 5668 3403 3505
+ GG aa 3834 4468 963 1597 GG aa 3988 4468 1117 1597
+ GG aa 4133 4468 1262 1597 GG aa 4320 4468 1449 1597
+ GG bb 3530 4468 1933 2871 GG bb 3539 4468 1942 2871
+ GG bb 3624 4468 2027 2871 GG bb 4308 4468 2711 2871
+ HH aa 4464 5443 1270 2249 HH aa 4653 5443 1459 2249
+ HH aa 4963 5443 1769 2249 HH bb 4480 5443 2231 3194
+ HH bb 4713 5443 2464 3194 HH bb 4760 5443 2511 3194
+ HH bb 5088 5443 2839 3194 HH bb 5113 5443 2864 3194
+ HH bb 5310 5443 3061 3194 II aa 2988 3640 398 1050
+ II aa 3242 3640 652 1050 II bb 2835 3640 1785 2590
+ II bb 2969 3640 1919 2590 II bb 3197 3640 2147 2590
+ II bb 3219 3640 2169 2590 II bb 3390 3640 2340 2590
+ JJ aa 2901 3800 1115 2014 JJ aa 3032 3800 1246 2014
+ JJ aa 3566 3800 1780 2014 JJ aa 3687 3800 1901 2014
+ JJ bb 2961 3800 947 1786 JJ bb 3446 3800 1432 1786
+ JJ bb 3464 3800 1450 1786 JJ bb 3543 3800 1529 1786}
+
+do_execsql_test 1.13.1 {
+ SELECT a, b, sum(c) OVER (ORDER BY a GROUPS BETWEEN CURRENT ROW AND 1 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 12025 AA aa 12025 AA aa 12025 AA aa 12025 AA bb 12025
+ AA bb 12025 AA bb 12025 AA bb 12025 BB aa 10462 BB aa 10462
+ BB aa 10462 BB aa 10462 BB aa 10462 BB aa 10462 BB bb 10462
+ BB bb 10462 BB bb 10462 BB bb 10462 BB bb 10462 BB bb 10462
+ CC aa 7154 CC aa 7154 CC aa 7154 CC aa 7154 CC bb 7154 CC bb 7154
+ DD aa 6571 DD aa 6571 DD aa 6571 DD bb 6571 DD bb 6571 DD bb 6571
+ DD bb 6571 EE aa 8207 EE aa 8207 EE bb 8207 EE bb 8207 EE bb 8207
+ FF aa 10136 FF aa 10136 FF aa 10136 FF aa 10136 FF bb 10136
+ FF bb 10136 FF bb 10136 FF bb 10136 FF bb 10136 FF bb 10136
+ GG aa 9911 GG aa 9911 GG aa 9911 GG aa 9911 GG bb 9911 GG bb 9911
+ GG bb 9911 GG bb 9911 HH aa 9083 HH aa 9083 HH aa 9083 HH bb 9083
+ HH bb 9083 HH bb 9083 HH bb 9083 HH bb 9083 HH bb 9083 II aa 7440
+ II aa 7440 II bb 7440 II bb 7440 II bb 7440 II bb 7440 II bb 7440
+ JJ aa 3800 JJ aa 3800 JJ aa 3800 JJ aa 3800 JJ bb 3800 JJ bb 3800
+ JJ bb 3800 JJ bb 3800}
+
+do_execsql_test 1.13.2 {
+ SELECT a, b, sum(c) OVER (ORDER BY a,b GROUPS BETWEEN CURRENT ROW AND 1 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 4685 AA aa 4685 AA aa 4685 AA aa 4685 AA bb 5251 AA bb 5251
+ AA bb 5251 AA bb 5251 BB aa 7340 BB aa 7340 BB aa 7340 BB aa 7340
+ BB aa 7340 BB aa 7340 BB bb 6421 BB bb 6421 BB bb 6421 BB bb 6421
+ BB bb 6421 BB bb 6421 CC aa 3122 CC aa 3122 CC aa 3122 CC aa 3122
+ CC bb 2493 CC bb 2493 DD aa 4032 DD aa 4032 DD aa 4032 DD bb 3597
+ DD bb 3597 DD bb 3597 DD bb 3597 EE aa 2539 EE aa 2539 EE bb 3812
+ EE bb 3812 EE bb 3812 FF aa 5668 FF aa 5668 FF aa 5668 FF aa 5668
+ FF bb 5102 FF bb 5102 FF bb 5102 FF bb 5102 FF bb 5102 FF bb 5102
+ GG aa 4468 GG aa 4468 GG aa 4468 GG aa 4468 GG bb 5120 GG bb 5120
+ GG bb 5120 GG bb 5120 HH aa 5443 HH aa 5443 HH aa 5443 HH bb 4244
+ HH bb 4244 HH bb 4244 HH bb 4244 HH bb 4244 HH bb 4244 II aa 3640
+ II aa 3640 II bb 4604 II bb 4604 II bb 4604 II bb 4604 II bb 4604
+ JJ aa 3800 JJ aa 3800 JJ aa 3800 JJ aa 3800 JJ bb 1786 JJ bb 1786
+ JJ bb 1786 JJ bb 1786}
+
+do_execsql_test 1.13.3 {
+ SELECT a, b, rank() OVER (ORDER BY a GROUPS BETWEEN CURRENT ROW AND 1 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 1 AA aa 1 AA aa 1 AA aa 1 AA bb 1 AA bb 1 AA bb 1
+ AA bb 1 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9
+ BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 CC aa 21
+ CC aa 21 CC aa 21 CC aa 21 CC bb 21 CC bb 21 DD aa 27 DD aa 27
+ DD aa 27 DD bb 27 DD bb 27 DD bb 27 DD bb 27 EE aa 34 EE aa 34
+ EE bb 34 EE bb 34 EE bb 34 FF aa 39 FF aa 39 FF aa 39 FF aa 39
+ FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 GG aa 49
+ GG aa 49 GG aa 49 GG aa 49 GG bb 49 GG bb 49 GG bb 49 GG bb 49
+ HH aa 57 HH aa 57 HH aa 57 HH bb 57 HH bb 57 HH bb 57 HH bb 57
+ HH bb 57 HH bb 57 II aa 66 II aa 66 II bb 66 II bb 66 II bb 66
+ II bb 66 II bb 66 JJ aa 73 JJ aa 73 JJ aa 73 JJ aa 73 JJ bb 73
+ JJ bb 73 JJ bb 73 JJ bb 73}
+
+do_execsql_test 1.13.4 {
+ SELECT a, b, max(c) OVER (ORDER BY a,b GROUPS BETWEEN CURRENT ROW AND 1 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 934 AA aa 934 AA aa 934 AA aa 934 AA bb 870 AA bb 870
+ AA bb 870 AA bb 870 BB aa 840 BB aa 840 BB aa 840 BB aa 840
+ BB aa 840 BB aa 840 BB bb 840 BB bb 840 BB bb 840 BB bb 840
+ BB bb 840 BB bb 840 CC aa 822 CC aa 822 CC aa 822 CC aa 822
+ CC bb 845 CC bb 845 DD aa 959 DD aa 959 DD aa 959 DD bb 959
+ DD bb 959 DD bb 959 DD bb 959 EE aa 777 EE aa 777 EE bb 768
+ EE bb 768 EE bb 768 FF aa 938 FF aa 938 FF aa 938 FF aa 938
+ FF bb 938 FF bb 938 FF bb 938 FF bb 938 FF bb 938 FF bb 938
+ GG aa 938 GG aa 938 GG aa 938 GG aa 938 GG bb 979 GG bb 979
+ GG bb 979 GG bb 979 HH aa 979 HH aa 979 HH aa 979 HH bb 963
+ HH bb 963 HH bb 963 HH bb 963 HH bb 963 HH bb 963 II aa 805
+ II aa 805 II bb 899 II bb 899 II bb 899 II bb 899 II bb 899
+ JJ aa 899 JJ aa 899 JJ aa 899 JJ aa 899 JJ bb 839 JJ bb 839
+ JJ bb 839 JJ bb 839}
+
+do_execsql_test 1.13.5 {
+ SELECT a, b, min(c) OVER (ORDER BY a,b GROUPS BETWEEN CURRENT ROW AND 1 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 223 AA aa 223 AA aa 223 AA aa 223 AA bb 247 AA bb 247
+ AA bb 247 AA bb 247 BB aa 247 BB aa 247 BB aa 247 BB aa 247
+ BB aa 247 BB aa 247 BB bb 158 BB bb 158 BB bb 158 BB bb 158
+ BB bb 158 BB bb 158 CC aa 158 CC aa 158 CC aa 158 CC aa 158
+ CC bb 224 CC bb 224 DD aa 224 DD aa 224 DD aa 224 DD bb 113
+ DD bb 113 DD bb 113 DD bb 113 EE aa 113 EE aa 113 EE bb 208
+ EE bb 208 EE bb 208 FF aa 102 FF aa 102 FF aa 102 FF aa 102
+ FF bb 102 FF bb 102 FF bb 102 FF bb 102 FF bb 102 FF bb 102
+ GG aa 148 GG aa 148 GG aa 148 GG aa 148 GG bb 160 GG bb 160
+ GG bb 160 GG bb 160 HH aa 133 HH aa 133 HH aa 133 HH bb 133
+ HH bb 133 HH bb 133 HH bb 133 HH bb 133 HH bb 133 II aa 250
+ II aa 250 II bb 113 II bb 113 II bb 113 II bb 113 II bb 113
+ JJ aa 113 JJ aa 113 JJ aa 113 JJ aa 113 JJ bb 257 JJ bb 257
+ JJ bb 257 JJ bb 257}
+
+do_execsql_test 1.13.6 {
+ 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;
+} {AA aa 11091 AA aa 11114 AA aa 11786 AA aa 11802 AA bb 11155
+ AA bb 11398 AA bb 11453 AA bb 11716 BB aa 9700 BB aa 9802
+ BB aa 10050 BB aa 10063 BB aa 10069 BB aa 10215 BB bb 9622
+ BB bb 9670 BB bb 9676 BB bb 9751 BB bb 9757 BB bb 9829 CC aa 6395
+ CC aa 6547 CC aa 6724 CC aa 6996 CC bb 6332 CC bb 6808 DD aa 5726
+ DD aa 6315 DD aa 6347 DD bb 5612 DD bb 5777 DD bb 5855 DD bb 6333
+ EE aa 7430 EE aa 8094 EE bb 7439 EE bb 7578 EE bb 7955 FF aa 9466
+ FF aa 9469 FF aa 9518 FF aa 9928 FF bb 9198 FF bb 9266 FF bb 9410
+ FF bb 9562 FF bb 9841 FF bb 10034 GG aa 9277 GG aa 9431
+ GG aa 9576 GG aa 9763 GG bb 8973 GG bb 8982 GG bb 9067 GG bb 9751
+ HH aa 8104 HH aa 8293 HH aa 8603 HH bb 8120 HH bb 8353 HH bb 8400
+ HH bb 8728 HH bb 8753 HH bb 8950 II aa 6788 II aa 7042 II bb 6635
+ II bb 6769 II bb 6997 II bb 7019 II bb 7190 JJ aa 2901 JJ aa 3032
+ JJ aa 3566 JJ aa 3687 JJ bb 2961 JJ bb 3446 JJ bb 3464 JJ bb 3543}
+
+do_execsql_test 1.13.7 {
+ 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;
+} {AA aa 3751 AA aa 3774 AA aa 4446 AA aa 4462 AA bb 4381 AA bb 4624
+ AA bb 4679 AA bb 4942 BB aa 6578 BB aa 6680 BB aa 6928 BB aa 6941
+ BB aa 6947 BB aa 7093 BB bb 5581 BB bb 5629 BB bb 5635 BB bb 5710
+ BB bb 5716 BB bb 5788 CC aa 2363 CC aa 2515 CC aa 2692 CC aa 2964
+ CC bb 1671 CC bb 2147 DD aa 3187 DD aa 3776 DD aa 3808 DD bb 2638
+ DD bb 2803 DD bb 2881 DD bb 3359 EE aa 1762 EE aa 2426 EE bb 3044
+ EE bb 3183 EE bb 3560 FF aa 4998 FF aa 5001 FF aa 5050 FF aa 5460
+ FF bb 4164 FF bb 4232 FF bb 4376 FF bb 4528 FF bb 4807 FF bb 5000
+ GG aa 3834 GG aa 3988 GG aa 4133 GG aa 4320 GG bb 4182 GG bb 4191
+ GG bb 4276 GG bb 4960 HH aa 4464 HH aa 4653 HH aa 4963 HH bb 3281
+ HH bb 3514 HH bb 3561 HH bb 3889 HH bb 3914 HH bb 4111 II aa 2988
+ II aa 3242 II bb 3799 II bb 3933 II bb 4161 II bb 4183 II bb 4354
+ JJ aa 2901 JJ aa 3032 JJ aa 3566 JJ aa 3687 JJ bb 947 JJ bb 1432
+ JJ bb 1450 JJ bb 1529}
+
+do_execsql_test 1.13.8 {
+ SELECT a, b,
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN CURRENT ROW AND 1 FOLLOWING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN CURRENT ROW AND 1 FOLLOWING ),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN CURRENT ROW AND 1 FOLLOWING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN CURRENT ROW AND 1 FOLLOWING )
+ FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 11091 12025 3751 4685 AA aa 11114 12025 3774 4685
+ AA aa 11786 12025 4446 4685 AA aa 11802 12025 4462 4685
+ AA bb 11155 12025 4381 5251 AA bb 11398 12025 4624 5251
+ AA bb 11453 12025 4679 5251 AA bb 11716 12025 4942 5251
+ BB aa 9700 10462 6578 7340 BB aa 9802 10462 6680 7340
+ BB aa 10050 10462 6928 7340 BB aa 10063 10462 6941 7340
+ BB aa 10069 10462 6947 7340 BB aa 10215 10462 7093 7340
+ BB bb 9622 10462 5581 6421 BB bb 9670 10462 5629 6421
+ BB bb 9676 10462 5635 6421 BB bb 9751 10462 5710 6421
+ BB bb 9757 10462 5716 6421 BB bb 9829 10462 5788 6421
+ CC aa 6395 7154 2363 3122 CC aa 6547 7154 2515 3122
+ CC aa 6724 7154 2692 3122 CC aa 6996 7154 2964 3122
+ CC bb 6332 7154 1671 2493 CC bb 6808 7154 2147 2493
+ DD aa 5726 6571 3187 4032 DD aa 6315 6571 3776 4032
+ DD aa 6347 6571 3808 4032 DD bb 5612 6571 2638 3597
+ DD bb 5777 6571 2803 3597 DD bb 5855 6571 2881 3597
+ DD bb 6333 6571 3359 3597 EE aa 7430 8207 1762 2539
+ EE aa 8094 8207 2426 2539 EE bb 7439 8207 3044 3812
+ EE bb 7578 8207 3183 3812 EE bb 7955 8207 3560 3812
+ FF aa 9466 10136 4998 5668 FF aa 9469 10136 5001 5668
+ FF aa 9518 10136 5050 5668 FF aa 9928 10136 5460 5668
+ FF bb 9198 10136 4164 5102 FF bb 9266 10136 4232 5102
+ FF bb 9410 10136 4376 5102 FF bb 9562 10136 4528 5102
+ FF bb 9841 10136 4807 5102 FF bb 10034 10136 5000 5102
+ GG aa 9277 9911 3834 4468 GG aa 9431 9911 3988 4468
+ GG aa 9576 9911 4133 4468 GG aa 9763 9911 4320 4468
+ GG bb 8973 9911 4182 5120 GG bb 8982 9911 4191 5120
+ GG bb 9067 9911 4276 5120 GG bb 9751 9911 4960 5120
+ HH aa 8104 9083 4464 5443 HH aa 8293 9083 4653 5443
+ HH aa 8603 9083 4963 5443 HH bb 8120 9083 3281 4244
+ HH bb 8353 9083 3514 4244 HH bb 8400 9083 3561 4244
+ HH bb 8728 9083 3889 4244 HH bb 8753 9083 3914 4244
+ HH bb 8950 9083 4111 4244 II aa 6788 7440 2988 3640
+ II aa 7042 7440 3242 3640 II bb 6635 7440 3799 4604
+ II bb 6769 7440 3933 4604 II bb 6997 7440 4161 4604
+ II bb 7019 7440 4183 4604 II bb 7190 7440 4354 4604
+ JJ aa 2901 3800 2901 3800 JJ aa 3032 3800 3032 3800
+ JJ aa 3566 3800 3566 3800 JJ aa 3687 3800 3687 3800
+ JJ bb 2961 3800 947 1786 JJ bb 3446 3800 1432 1786
+ JJ bb 3464 3800 1450 1786 JJ bb 3543 3800 1529 1786}
+
+do_execsql_test 1.14.1 {
+ SELECT a, b, sum(c) OVER (ORDER BY a GROUPS BETWEEN CURRENT ROW AND 100 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 44737 AA aa 44737 AA aa 44737 AA aa 44737 AA bb 44737
+ AA bb 44737 AA bb 44737 AA bb 44737 BB aa 40052 BB aa 40052
+ BB aa 40052 BB aa 40052 BB aa 40052 BB aa 40052 BB bb 40052
+ BB bb 40052 BB bb 40052 BB bb 40052 BB bb 40052 BB bb 40052
+ CC aa 32712 CC aa 32712 CC aa 32712 CC aa 32712 CC bb 32712
+ CC bb 32712 DD aa 29590 DD aa 29590 DD aa 29590 DD bb 29590
+ DD bb 29590 DD bb 29590 DD bb 29590 EE aa 25558 EE aa 25558
+ EE bb 25558 EE bb 25558 EE bb 25558 FF aa 23019 FF aa 23019
+ FF aa 23019 FF aa 23019 FF bb 23019 FF bb 23019 FF bb 23019
+ FF bb 23019 FF bb 23019 FF bb 23019 GG aa 17351 GG aa 17351
+ GG aa 17351 GG aa 17351 GG bb 17351 GG bb 17351 GG bb 17351
+ GG bb 17351 HH aa 12883 HH aa 12883 HH aa 12883 HH bb 12883
+ HH bb 12883 HH bb 12883 HH bb 12883 HH bb 12883 HH bb 12883
+ II aa 7440 II aa 7440 II bb 7440 II bb 7440 II bb 7440 II bb 7440
+ II bb 7440 JJ aa 3800 JJ aa 3800 JJ aa 3800 JJ aa 3800 JJ bb 3800
+ JJ bb 3800 JJ bb 3800 JJ bb 3800}
+
+do_execsql_test 1.14.2 {
+ SELECT a, b, sum(c) OVER (ORDER BY a,b GROUPS BETWEEN CURRENT ROW AND 100 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 44737 AA aa 44737 AA aa 44737 AA aa 44737 AA bb 42430
+ AA bb 42430 AA bb 42430 AA bb 42430 BB aa 40052 BB aa 40052
+ BB aa 40052 BB aa 40052 BB aa 40052 BB aa 40052 BB bb 37179
+ BB bb 37179 BB bb 37179 BB bb 37179 BB bb 37179 BB bb 37179
+ CC aa 32712 CC aa 32712 CC aa 32712 CC aa 32712 CC bb 30758
+ CC bb 30758 DD aa 29590 DD aa 29590 DD aa 29590 DD bb 28265
+ DD bb 28265 DD bb 28265 DD bb 28265 EE aa 25558 EE aa 25558
+ EE bb 24668 EE bb 24668 EE bb 24668 FF aa 23019 FF aa 23019
+ FF aa 23019 FF aa 23019 FF bb 20856 FF bb 20856 FF bb 20856
+ FF bb 20856 FF bb 20856 FF bb 20856 GG aa 17351 GG aa 17351
+ GG aa 17351 GG aa 17351 GG bb 15754 GG bb 15754 GG bb 15754
+ GG bb 15754 HH aa 12883 HH aa 12883 HH aa 12883 HH bb 10634
+ HH bb 10634 HH bb 10634 HH bb 10634 HH bb 10634 HH bb 10634
+ II aa 7440 II aa 7440 II bb 6390 II bb 6390 II bb 6390 II bb 6390
+ II bb 6390 JJ aa 3800 JJ aa 3800 JJ aa 3800 JJ aa 3800 JJ bb 1786
+ JJ bb 1786 JJ bb 1786 JJ bb 1786}
+
+do_execsql_test 1.14.3 {
+ SELECT a, b, rank() OVER (ORDER BY a GROUPS BETWEEN CURRENT ROW AND 100 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 1 AA aa 1 AA aa 1 AA aa 1 AA bb 1 AA bb 1 AA bb 1
+ AA bb 1 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9
+ BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 CC aa 21
+ CC aa 21 CC aa 21 CC aa 21 CC bb 21 CC bb 21 DD aa 27 DD aa 27
+ DD aa 27 DD bb 27 DD bb 27 DD bb 27 DD bb 27 EE aa 34 EE aa 34
+ EE bb 34 EE bb 34 EE bb 34 FF aa 39 FF aa 39 FF aa 39 FF aa 39
+ FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 GG aa 49
+ GG aa 49 GG aa 49 GG aa 49 GG bb 49 GG bb 49 GG bb 49 GG bb 49
+ HH aa 57 HH aa 57 HH aa 57 HH bb 57 HH bb 57 HH bb 57 HH bb 57
+ HH bb 57 HH bb 57 II aa 66 II aa 66 II bb 66 II bb 66 II bb 66
+ II bb 66 II bb 66 JJ aa 73 JJ aa 73 JJ aa 73 JJ aa 73 JJ bb 73
+ JJ bb 73 JJ bb 73 JJ bb 73}
+
+do_execsql_test 1.14.4 {
+ SELECT a, b, max(c) OVER (ORDER BY a,b GROUPS BETWEEN CURRENT ROW AND 100 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 979 AA aa 979 AA aa 979 AA aa 979 AA bb 979 AA bb 979
+ AA bb 979 AA bb 979 BB aa 979 BB aa 979 BB aa 979 BB aa 979
+ BB aa 979 BB aa 979 BB bb 979 BB bb 979 BB bb 979 BB bb 979
+ BB bb 979 BB bb 979 CC aa 979 CC aa 979 CC aa 979 CC aa 979
+ CC bb 979 CC bb 979 DD aa 979 DD aa 979 DD aa 979 DD bb 979
+ DD bb 979 DD bb 979 DD bb 979 EE aa 979 EE aa 979 EE bb 979
+ EE bb 979 EE bb 979 FF aa 979 FF aa 979 FF aa 979 FF aa 979
+ FF bb 979 FF bb 979 FF bb 979 FF bb 979 FF bb 979 FF bb 979
+ GG aa 979 GG aa 979 GG aa 979 GG aa 979 GG bb 979 GG bb 979
+ GG bb 979 GG bb 979 HH aa 979 HH aa 979 HH aa 979 HH bb 963
+ HH bb 963 HH bb 963 HH bb 963 HH bb 963 HH bb 963 II aa 899
+ II aa 899 II bb 899 II bb 899 II bb 899 II bb 899 II bb 899
+ JJ aa 899 JJ aa 899 JJ aa 899 JJ aa 899 JJ bb 839 JJ bb 839
+ JJ bb 839 JJ bb 839}
+
+do_execsql_test 1.14.5 {
+ SELECT a, b, min(c) OVER (ORDER BY a,b GROUPS BETWEEN CURRENT ROW AND 100 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 102 AA aa 102 AA aa 102 AA aa 102 AA bb 102 AA bb 102
+ AA bb 102 AA bb 102 BB aa 102 BB aa 102 BB aa 102 BB aa 102
+ BB aa 102 BB aa 102 BB bb 102 BB bb 102 BB bb 102 BB bb 102
+ BB bb 102 BB bb 102 CC aa 102 CC aa 102 CC aa 102 CC aa 102
+ CC bb 102 CC bb 102 DD aa 102 DD aa 102 DD aa 102 DD bb 102
+ DD bb 102 DD bb 102 DD bb 102 EE aa 102 EE aa 102 EE bb 102
+ EE bb 102 EE bb 102 FF aa 102 FF aa 102 FF aa 102 FF aa 102
+ FF bb 102 FF bb 102 FF bb 102 FF bb 102 FF bb 102 FF bb 102
+ GG aa 113 GG aa 113 GG aa 113 GG aa 113 GG bb 113 GG bb 113
+ GG bb 113 GG bb 113 HH aa 113 HH aa 113 HH aa 113 HH bb 113
+ HH bb 113 HH bb 113 HH bb 113 HH bb 113 HH bb 113 II aa 113
+ II aa 113 II bb 113 II bb 113 II bb 113 II bb 113 II bb 113
+ JJ aa 113 JJ aa 113 JJ aa 113 JJ aa 113 JJ bb 257 JJ bb 257
+ JJ bb 257 JJ bb 257}
+
+do_execsql_test 1.14.6 {
+ 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;
+} {AA aa 43803 AA aa 43826 AA aa 44498 AA aa 44514 AA bb 43867
+ AA bb 44110 AA bb 44165 AA bb 44428 BB aa 39290 BB aa 39392
+ BB aa 39640 BB aa 39653 BB aa 39659 BB aa 39805 BB bb 39212
+ BB bb 39260 BB bb 39266 BB bb 39341 BB bb 39347 BB bb 39419
+ CC aa 31953 CC aa 32105 CC aa 32282 CC aa 32554 CC bb 31890
+ CC bb 32366 DD aa 28745 DD aa 29334 DD aa 29366 DD bb 28631
+ DD bb 28796 DD bb 28874 DD bb 29352 EE aa 24781 EE aa 25445
+ EE bb 24790 EE bb 24929 EE bb 25306 FF aa 22349 FF aa 22352
+ FF aa 22401 FF aa 22811 FF bb 22081 FF bb 22149 FF bb 22293
+ FF bb 22445 FF bb 22724 FF bb 22917 GG aa 16717 GG aa 16871
+ GG aa 17016 GG aa 17203 GG bb 16413 GG bb 16422 GG bb 16507
+ GG bb 17191 HH aa 11904 HH aa 12093 HH aa 12403 HH bb 11920
+ HH bb 12153 HH bb 12200 HH bb 12528 HH bb 12553 HH bb 12750
+ II aa 6788 II aa 7042 II bb 6635 II bb 6769 II bb 6997 II bb 7019
+ II bb 7190 JJ aa 2901 JJ aa 3032 JJ aa 3566 JJ aa 3687 JJ bb 2961
+ JJ bb 3446 JJ bb 3464 JJ bb 3543}
+
+do_execsql_test 1.14.7 {
+ 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;
+} {AA aa 43803 AA aa 43826 AA aa 44498 AA aa 44514 AA bb 41560
+ AA bb 41803 AA bb 41858 AA bb 42121 BB aa 39290 BB aa 39392
+ BB aa 39640 BB aa 39653 BB aa 39659 BB aa 39805 BB bb 36339
+ BB bb 36387 BB bb 36393 BB bb 36468 BB bb 36474 BB bb 36546
+ CC aa 31953 CC aa 32105 CC aa 32282 CC aa 32554 CC bb 29936
+ CC bb 30412 DD aa 28745 DD aa 29334 DD aa 29366 DD bb 27306
+ DD bb 27471 DD bb 27549 DD bb 28027 EE aa 24781 EE aa 25445
+ EE bb 23900 EE bb 24039 EE bb 24416 FF aa 22349 FF aa 22352
+ FF aa 22401 FF aa 22811 FF bb 19918 FF bb 19986 FF bb 20130
+ FF bb 20282 FF bb 20561 FF bb 20754 GG aa 16717 GG aa 16871
+ GG aa 17016 GG aa 17203 GG bb 14816 GG bb 14825 GG bb 14910
+ GG bb 15594 HH aa 11904 HH aa 12093 HH aa 12403 HH bb 9671
+ HH bb 9904 HH bb 9951 HH bb 10279 HH bb 10304 HH bb 10501
+ II aa 6788 II aa 7042 II bb 5585 II bb 5719 II bb 5947 II bb 5969
+ II bb 6140 JJ aa 2901 JJ aa 3032 JJ aa 3566 JJ aa 3687 JJ bb 947
+ JJ bb 1432 JJ bb 1450 JJ bb 1529}
+
+do_execsql_test 1.14.8 {
+ SELECT a, b,
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN CURRENT ROW AND 100 FOLLOWING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN CURRENT ROW AND 100 FOLLOWING ),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN CURRENT ROW AND 100 FOLLOWING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN CURRENT ROW AND 100 FOLLOWING )
+ FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 43803 44737 43803 44737 AA aa 43826 44737 43826 44737
+ AA aa 44498 44737 44498 44737 AA aa 44514 44737 44514 44737
+ AA bb 43867 44737 41560 42430 AA bb 44110 44737 41803 42430
+ AA bb 44165 44737 41858 42430 AA bb 44428 44737 42121 42430
+ BB aa 39290 40052 39290 40052 BB aa 39392 40052 39392 40052
+ BB aa 39640 40052 39640 40052 BB aa 39653 40052 39653 40052
+ BB aa 39659 40052 39659 40052 BB aa 39805 40052 39805 40052
+ BB bb 39212 40052 36339 37179 BB bb 39260 40052 36387 37179
+ BB bb 39266 40052 36393 37179 BB bb 39341 40052 36468 37179
+ BB bb 39347 40052 36474 37179 BB bb 39419 40052 36546 37179
+ CC aa 31953 32712 31953 32712 CC aa 32105 32712 32105 32712
+ CC aa 32282 32712 32282 32712 CC aa 32554 32712 32554 32712
+ CC bb 31890 32712 29936 30758 CC bb 32366 32712 30412 30758
+ DD aa 28745 29590 28745 29590 DD aa 29334 29590 29334 29590
+ DD aa 29366 29590 29366 29590 DD bb 28631 29590 27306 28265
+ DD bb 28796 29590 27471 28265 DD bb 28874 29590 27549 28265
+ DD bb 29352 29590 28027 28265 EE aa 24781 25558 24781 25558
+ EE aa 25445 25558 25445 25558 EE bb 24790 25558 23900 24668
+ EE bb 24929 25558 24039 24668 EE bb 25306 25558 24416 24668
+ FF aa 22349 23019 22349 23019 FF aa 22352 23019 22352 23019
+ FF aa 22401 23019 22401 23019 FF aa 22811 23019 22811 23019
+ FF bb 22081 23019 19918 20856 FF bb 22149 23019 19986 20856
+ FF bb 22293 23019 20130 20856 FF bb 22445 23019 20282 20856
+ FF bb 22724 23019 20561 20856 FF bb 22917 23019 20754 20856
+ GG aa 16717 17351 16717 17351 GG aa 16871 17351 16871 17351
+ GG aa 17016 17351 17016 17351 GG aa 17203 17351 17203 17351
+ GG bb 16413 17351 14816 15754 GG bb 16422 17351 14825 15754
+ GG bb 16507 17351 14910 15754 GG bb 17191 17351 15594 15754
+ HH aa 11904 12883 11904 12883 HH aa 12093 12883 12093 12883
+ HH aa 12403 12883 12403 12883 HH bb 11920 12883 9671 10634
+ HH bb 12153 12883 9904 10634 HH bb 12200 12883 9951 10634
+ HH bb 12528 12883 10279 10634 HH bb 12553 12883 10304 10634
+ HH bb 12750 12883 10501 10634 II aa 6788 7440 6788 7440
+ II aa 7042 7440 7042 7440 II bb 6635 7440 5585 6390
+ II bb 6769 7440 5719 6390 II bb 6997 7440 5947 6390
+ II bb 7019 7440 5969 6390 II bb 7190 7440 6140 6390
+ JJ aa 2901 3800 2901 3800 JJ aa 3032 3800 3032 3800
+ JJ aa 3566 3800 3566 3800 JJ aa 3687 3800 3687 3800
+ JJ bb 2961 3800 947 1786 JJ bb 3446 3800 1432 1786
+ JJ bb 3464 3800 1450 1786 JJ bb 3543 3800 1529 1786}
+
+do_execsql_test 1.15.1 {
+ SELECT a, b, sum(c) OVER (ORDER BY a GROUPS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 44737 AA aa 44737 AA aa 44737 AA aa 44737 AA bb 44737
+ AA bb 44737 AA bb 44737 AA bb 44737 BB aa 40052 BB aa 40052
+ BB aa 40052 BB aa 40052 BB aa 40052 BB aa 40052 BB bb 40052
+ BB bb 40052 BB bb 40052 BB bb 40052 BB bb 40052 BB bb 40052
+ CC aa 32712 CC aa 32712 CC aa 32712 CC aa 32712 CC bb 32712
+ CC bb 32712 DD aa 29590 DD aa 29590 DD aa 29590 DD bb 29590
+ DD bb 29590 DD bb 29590 DD bb 29590 EE aa 25558 EE aa 25558
+ EE bb 25558 EE bb 25558 EE bb 25558 FF aa 23019 FF aa 23019
+ FF aa 23019 FF aa 23019 FF bb 23019 FF bb 23019 FF bb 23019
+ FF bb 23019 FF bb 23019 FF bb 23019 GG aa 17351 GG aa 17351
+ GG aa 17351 GG aa 17351 GG bb 17351 GG bb 17351 GG bb 17351
+ GG bb 17351 HH aa 12883 HH aa 12883 HH aa 12883 HH bb 12883
+ HH bb 12883 HH bb 12883 HH bb 12883 HH bb 12883 HH bb 12883
+ II aa 7440 II aa 7440 II bb 7440 II bb 7440 II bb 7440 II bb 7440
+ II bb 7440 JJ aa 3800 JJ aa 3800 JJ aa 3800 JJ aa 3800 JJ bb 3800
+ JJ bb 3800 JJ bb 3800 JJ bb 3800}
+
+do_execsql_test 1.15.2 {
+ SELECT a, b, sum(c) OVER (ORDER BY a,b GROUPS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 44737 AA aa 44737 AA aa 44737 AA aa 44737 AA bb 42430
+ AA bb 42430 AA bb 42430 AA bb 42430 BB aa 40052 BB aa 40052
+ BB aa 40052 BB aa 40052 BB aa 40052 BB aa 40052 BB bb 37179
+ BB bb 37179 BB bb 37179 BB bb 37179 BB bb 37179 BB bb 37179
+ CC aa 32712 CC aa 32712 CC aa 32712 CC aa 32712 CC bb 30758
+ CC bb 30758 DD aa 29590 DD aa 29590 DD aa 29590 DD bb 28265
+ DD bb 28265 DD bb 28265 DD bb 28265 EE aa 25558 EE aa 25558
+ EE bb 24668 EE bb 24668 EE bb 24668 FF aa 23019 FF aa 23019
+ FF aa 23019 FF aa 23019 FF bb 20856 FF bb 20856 FF bb 20856
+ FF bb 20856 FF bb 20856 FF bb 20856 GG aa 17351 GG aa 17351
+ GG aa 17351 GG aa 17351 GG bb 15754 GG bb 15754 GG bb 15754
+ GG bb 15754 HH aa 12883 HH aa 12883 HH aa 12883 HH bb 10634
+ HH bb 10634 HH bb 10634 HH bb 10634 HH bb 10634 HH bb 10634
+ II aa 7440 II aa 7440 II bb 6390 II bb 6390 II bb 6390 II bb 6390
+ II bb 6390 JJ aa 3800 JJ aa 3800 JJ aa 3800 JJ aa 3800 JJ bb 1786
+ JJ bb 1786 JJ bb 1786 JJ bb 1786}
+
+do_execsql_test 1.15.3 {
+ SELECT a, b, rank() OVER (ORDER BY a GROUPS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 1 AA aa 1 AA aa 1 AA aa 1 AA bb 1 AA bb 1 AA bb 1
+ AA bb 1 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9
+ BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 CC aa 21
+ CC aa 21 CC aa 21 CC aa 21 CC bb 21 CC bb 21 DD aa 27 DD aa 27
+ DD aa 27 DD bb 27 DD bb 27 DD bb 27 DD bb 27 EE aa 34 EE aa 34
+ EE bb 34 EE bb 34 EE bb 34 FF aa 39 FF aa 39 FF aa 39 FF aa 39
+ FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 GG aa 49
+ GG aa 49 GG aa 49 GG aa 49 GG bb 49 GG bb 49 GG bb 49 GG bb 49
+ HH aa 57 HH aa 57 HH aa 57 HH bb 57 HH bb 57 HH bb 57 HH bb 57
+ HH bb 57 HH bb 57 II aa 66 II aa 66 II bb 66 II bb 66 II bb 66
+ II bb 66 II bb 66 JJ aa 73 JJ aa 73 JJ aa 73 JJ aa 73 JJ bb 73
+ JJ bb 73 JJ bb 73 JJ bb 73}
+
+do_execsql_test 1.15.4 {
+ SELECT a, b, max(c) OVER (ORDER BY a,b GROUPS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 979 AA aa 979 AA aa 979 AA aa 979 AA bb 979 AA bb 979
+ AA bb 979 AA bb 979 BB aa 979 BB aa 979 BB aa 979 BB aa 979
+ BB aa 979 BB aa 979 BB bb 979 BB bb 979 BB bb 979 BB bb 979
+ BB bb 979 BB bb 979 CC aa 979 CC aa 979 CC aa 979 CC aa 979
+ CC bb 979 CC bb 979 DD aa 979 DD aa 979 DD aa 979 DD bb 979
+ DD bb 979 DD bb 979 DD bb 979 EE aa 979 EE aa 979 EE bb 979
+ EE bb 979 EE bb 979 FF aa 979 FF aa 979 FF aa 979 FF aa 979
+ FF bb 979 FF bb 979 FF bb 979 FF bb 979 FF bb 979 FF bb 979
+ GG aa 979 GG aa 979 GG aa 979 GG aa 979 GG bb 979 GG bb 979
+ GG bb 979 GG bb 979 HH aa 979 HH aa 979 HH aa 979 HH bb 963
+ HH bb 963 HH bb 963 HH bb 963 HH bb 963 HH bb 963 II aa 899
+ II aa 899 II bb 899 II bb 899 II bb 899 II bb 899 II bb 899
+ JJ aa 899 JJ aa 899 JJ aa 899 JJ aa 899 JJ bb 839 JJ bb 839
+ JJ bb 839 JJ bb 839}
+
+do_execsql_test 1.15.5 {
+ SELECT a, b, min(c) OVER (ORDER BY a,b GROUPS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 102 AA aa 102 AA aa 102 AA aa 102 AA bb 102 AA bb 102
+ AA bb 102 AA bb 102 BB aa 102 BB aa 102 BB aa 102 BB aa 102
+ BB aa 102 BB aa 102 BB bb 102 BB bb 102 BB bb 102 BB bb 102
+ BB bb 102 BB bb 102 CC aa 102 CC aa 102 CC aa 102 CC aa 102
+ CC bb 102 CC bb 102 DD aa 102 DD aa 102 DD aa 102 DD bb 102
+ DD bb 102 DD bb 102 DD bb 102 EE aa 102 EE aa 102 EE bb 102
+ EE bb 102 EE bb 102 FF aa 102 FF aa 102 FF aa 102 FF aa 102
+ FF bb 102 FF bb 102 FF bb 102 FF bb 102 FF bb 102 FF bb 102
+ GG aa 113 GG aa 113 GG aa 113 GG aa 113 GG bb 113 GG bb 113
+ GG bb 113 GG bb 113 HH aa 113 HH aa 113 HH aa 113 HH bb 113
+ HH bb 113 HH bb 113 HH bb 113 HH bb 113 HH bb 113 II aa 113
+ II aa 113 II bb 113 II bb 113 II bb 113 II bb 113 II bb 113
+ JJ aa 113 JJ aa 113 JJ aa 113 JJ aa 113 JJ bb 257 JJ bb 257
+ JJ bb 257 JJ bb 257}
+
+do_execsql_test 1.15.6 {
+ 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;
+} {AA aa 43803 AA aa 43826 AA aa 44498 AA aa 44514 AA bb 43867
+ AA bb 44110 AA bb 44165 AA bb 44428 BB aa 39290 BB aa 39392
+ BB aa 39640 BB aa 39653 BB aa 39659 BB aa 39805 BB bb 39212
+ BB bb 39260 BB bb 39266 BB bb 39341 BB bb 39347 BB bb 39419
+ CC aa 31953 CC aa 32105 CC aa 32282 CC aa 32554 CC bb 31890
+ CC bb 32366 DD aa 28745 DD aa 29334 DD aa 29366 DD bb 28631
+ DD bb 28796 DD bb 28874 DD bb 29352 EE aa 24781 EE aa 25445
+ EE bb 24790 EE bb 24929 EE bb 25306 FF aa 22349 FF aa 22352
+ FF aa 22401 FF aa 22811 FF bb 22081 FF bb 22149 FF bb 22293
+ FF bb 22445 FF bb 22724 FF bb 22917 GG aa 16717 GG aa 16871
+ GG aa 17016 GG aa 17203 GG bb 16413 GG bb 16422 GG bb 16507
+ GG bb 17191 HH aa 11904 HH aa 12093 HH aa 12403 HH bb 11920
+ HH bb 12153 HH bb 12200 HH bb 12528 HH bb 12553 HH bb 12750
+ II aa 6788 II aa 7042 II bb 6635 II bb 6769 II bb 6997 II bb 7019
+ II bb 7190 JJ aa 2901 JJ aa 3032 JJ aa 3566 JJ aa 3687 JJ bb 2961
+ JJ bb 3446 JJ bb 3464 JJ bb 3543}
+
+do_execsql_test 1.15.7 {
+ 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;
+} {AA aa 43803 AA aa 43826 AA aa 44498 AA aa 44514 AA bb 41560
+ AA bb 41803 AA bb 41858 AA bb 42121 BB aa 39290 BB aa 39392
+ BB aa 39640 BB aa 39653 BB aa 39659 BB aa 39805 BB bb 36339
+ BB bb 36387 BB bb 36393 BB bb 36468 BB bb 36474 BB bb 36546
+ CC aa 31953 CC aa 32105 CC aa 32282 CC aa 32554 CC bb 29936
+ CC bb 30412 DD aa 28745 DD aa 29334 DD aa 29366 DD bb 27306
+ DD bb 27471 DD bb 27549 DD bb 28027 EE aa 24781 EE aa 25445
+ EE bb 23900 EE bb 24039 EE bb 24416 FF aa 22349 FF aa 22352
+ FF aa 22401 FF aa 22811 FF bb 19918 FF bb 19986 FF bb 20130
+ FF bb 20282 FF bb 20561 FF bb 20754 GG aa 16717 GG aa 16871
+ GG aa 17016 GG aa 17203 GG bb 14816 GG bb 14825 GG bb 14910
+ GG bb 15594 HH aa 11904 HH aa 12093 HH aa 12403 HH bb 9671
+ HH bb 9904 HH bb 9951 HH bb 10279 HH bb 10304 HH bb 10501
+ II aa 6788 II aa 7042 II bb 5585 II bb 5719 II bb 5947 II bb 5969
+ II bb 6140 JJ aa 2901 JJ aa 3032 JJ aa 3566 JJ aa 3687 JJ bb 947
+ JJ bb 1432 JJ bb 1450 JJ bb 1529}
+
+do_execsql_test 1.15.8 {
+ SELECT a, b,
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING )
+ FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 43803 44737 43803 44737 AA aa 43826 44737 43826 44737
+ AA aa 44498 44737 44498 44737 AA aa 44514 44737 44514 44737
+ AA bb 43867 44737 41560 42430 AA bb 44110 44737 41803 42430
+ AA bb 44165 44737 41858 42430 AA bb 44428 44737 42121 42430
+ BB aa 39290 40052 39290 40052 BB aa 39392 40052 39392 40052
+ BB aa 39640 40052 39640 40052 BB aa 39653 40052 39653 40052
+ BB aa 39659 40052 39659 40052 BB aa 39805 40052 39805 40052
+ BB bb 39212 40052 36339 37179 BB bb 39260 40052 36387 37179
+ BB bb 39266 40052 36393 37179 BB bb 39341 40052 36468 37179
+ BB bb 39347 40052 36474 37179 BB bb 39419 40052 36546 37179
+ CC aa 31953 32712 31953 32712 CC aa 32105 32712 32105 32712
+ CC aa 32282 32712 32282 32712 CC aa 32554 32712 32554 32712
+ CC bb 31890 32712 29936 30758 CC bb 32366 32712 30412 30758
+ DD aa 28745 29590 28745 29590 DD aa 29334 29590 29334 29590
+ DD aa 29366 29590 29366 29590 DD bb 28631 29590 27306 28265
+ DD bb 28796 29590 27471 28265 DD bb 28874 29590 27549 28265
+ DD bb 29352 29590 28027 28265 EE aa 24781 25558 24781 25558
+ EE aa 25445 25558 25445 25558 EE bb 24790 25558 23900 24668
+ EE bb 24929 25558 24039 24668 EE bb 25306 25558 24416 24668
+ FF aa 22349 23019 22349 23019 FF aa 22352 23019 22352 23019
+ FF aa 22401 23019 22401 23019 FF aa 22811 23019 22811 23019
+ FF bb 22081 23019 19918 20856 FF bb 22149 23019 19986 20856
+ FF bb 22293 23019 20130 20856 FF bb 22445 23019 20282 20856
+ FF bb 22724 23019 20561 20856 FF bb 22917 23019 20754 20856
+ GG aa 16717 17351 16717 17351 GG aa 16871 17351 16871 17351
+ GG aa 17016 17351 17016 17351 GG aa 17203 17351 17203 17351
+ GG bb 16413 17351 14816 15754 GG bb 16422 17351 14825 15754
+ GG bb 16507 17351 14910 15754 GG bb 17191 17351 15594 15754
+ HH aa 11904 12883 11904 12883 HH aa 12093 12883 12093 12883
+ HH aa 12403 12883 12403 12883 HH bb 11920 12883 9671 10634
+ HH bb 12153 12883 9904 10634 HH bb 12200 12883 9951 10634
+ HH bb 12528 12883 10279 10634 HH bb 12553 12883 10304 10634
+ HH bb 12750 12883 10501 10634 II aa 6788 7440 6788 7440
+ II aa 7042 7440 7042 7440 II bb 6635 7440 5585 6390
+ II bb 6769 7440 5719 6390 II bb 6997 7440 5947 6390
+ II bb 7019 7440 5969 6390 II bb 7190 7440 6140 6390
+ JJ aa 2901 3800 2901 3800 JJ aa 3032 3800 3032 3800
+ JJ aa 3566 3800 3566 3800 JJ aa 3687 3800 3687 3800
+ JJ bb 2961 3800 947 1786 JJ bb 3446 3800 1432 1786
+ JJ bb 3464 3800 1450 1786 JJ bb 3543 3800 1529 1786}
+
+do_execsql_test 1.16.1 {
+ SELECT a, b, sum(c) OVER (ORDER BY a GROUPS BETWEEN 0 FOLLOWING AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 4685 AA aa 4685 AA aa 4685 AA aa 4685 AA bb 4685 AA bb 4685
+ AA bb 4685 AA bb 4685 BB aa 7340 BB aa 7340 BB aa 7340 BB aa 7340
+ BB aa 7340 BB aa 7340 BB bb 7340 BB bb 7340 BB bb 7340 BB bb 7340
+ BB bb 7340 BB bb 7340 CC aa 3122 CC aa 3122 CC aa 3122 CC aa 3122
+ CC bb 3122 CC bb 3122 DD aa 4032 DD aa 4032 DD aa 4032 DD bb 4032
+ DD bb 4032 DD bb 4032 DD bb 4032 EE aa 2539 EE aa 2539 EE bb 2539
+ EE bb 2539 EE bb 2539 FF aa 5668 FF aa 5668 FF aa 5668 FF aa 5668
+ FF bb 5668 FF bb 5668 FF bb 5668 FF bb 5668 FF bb 5668 FF bb 5668
+ GG aa 4468 GG aa 4468 GG aa 4468 GG aa 4468 GG bb 4468 GG bb 4468
+ GG bb 4468 GG bb 4468 HH aa 5443 HH aa 5443 HH aa 5443 HH bb 5443
+ HH bb 5443 HH bb 5443 HH bb 5443 HH bb 5443 HH bb 5443 II aa 3640
+ II aa 3640 II bb 3640 II bb 3640 II bb 3640 II bb 3640 II bb 3640
+ JJ aa 3800 JJ aa 3800 JJ aa 3800 JJ aa 3800 JJ bb 3800 JJ bb 3800
+ JJ bb 3800 JJ bb 3800}
+
+do_execsql_test 1.16.2 {
+ SELECT a, b, sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 0 FOLLOWING AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 2307 AA aa 2307 AA aa 2307 AA aa 2307 AA bb 2378 AA bb 2378
+ AA bb 2378 AA bb 2378 BB aa 2873 BB aa 2873 BB aa 2873 BB aa 2873
+ BB aa 2873 BB aa 2873 BB bb 4467 BB bb 4467 BB bb 4467 BB bb 4467
+ BB bb 4467 BB bb 4467 CC aa 1954 CC aa 1954 CC aa 1954 CC aa 1954
+ CC bb 1168 CC bb 1168 DD aa 1325 DD aa 1325 DD aa 1325 DD bb 2707
+ DD bb 2707 DD bb 2707 DD bb 2707 EE aa 890 EE aa 890 EE bb 1649
+ EE bb 1649 EE bb 1649 FF aa 2163 FF aa 2163 FF aa 2163 FF aa 2163
+ FF bb 3505 FF bb 3505 FF bb 3505 FF bb 3505 FF bb 3505 FF bb 3505
+ GG aa 1597 GG aa 1597 GG aa 1597 GG aa 1597 GG bb 2871 GG bb 2871
+ GG bb 2871 GG bb 2871 HH aa 2249 HH aa 2249 HH aa 2249 HH bb 3194
+ HH bb 3194 HH bb 3194 HH bb 3194 HH bb 3194 HH bb 3194 II aa 1050
+ II aa 1050 II bb 2590 II bb 2590 II bb 2590 II bb 2590 II bb 2590
+ JJ aa 2014 JJ aa 2014 JJ aa 2014 JJ aa 2014 JJ bb 1786 JJ bb 1786
+ JJ bb 1786 JJ bb 1786}
+
+do_execsql_test 1.16.3 {
+ SELECT a, b, rank() OVER (ORDER BY a GROUPS BETWEEN 0 FOLLOWING AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 1 AA aa 1 AA aa 1 AA aa 1 AA bb 1 AA bb 1 AA bb 1
+ AA bb 1 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9
+ BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 CC aa 21
+ CC aa 21 CC aa 21 CC aa 21 CC bb 21 CC bb 21 DD aa 27 DD aa 27
+ DD aa 27 DD bb 27 DD bb 27 DD bb 27 DD bb 27 EE aa 34 EE aa 34
+ EE bb 34 EE bb 34 EE bb 34 FF aa 39 FF aa 39 FF aa 39 FF aa 39
+ FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 GG aa 49
+ GG aa 49 GG aa 49 GG aa 49 GG bb 49 GG bb 49 GG bb 49 GG bb 49
+ HH aa 57 HH aa 57 HH aa 57 HH bb 57 HH bb 57 HH bb 57 HH bb 57
+ HH bb 57 HH bb 57 II aa 66 II aa 66 II bb 66 II bb 66 II bb 66
+ II bb 66 II bb 66 JJ aa 73 JJ aa 73 JJ aa 73 JJ aa 73 JJ bb 73
+ JJ bb 73 JJ bb 73 JJ bb 73}
+
+do_execsql_test 1.16.4 {
+ SELECT a, b, max(c) OVER (ORDER BY a,b GROUPS BETWEEN 0 FOLLOWING AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 934 AA aa 934 AA aa 934 AA aa 934 AA bb 870 AA bb 870
+ AA bb 870 AA bb 870 BB aa 762 BB aa 762 BB aa 762 BB aa 762
+ BB aa 762 BB aa 762 BB bb 840 BB bb 840 BB bb 840 BB bb 840
+ BB bb 840 BB bb 840 CC aa 759 CC aa 759 CC aa 759 CC aa 759
+ CC bb 822 CC bb 822 DD aa 845 DD aa 845 DD aa 845 DD bb 959
+ DD bb 959 DD bb 959 DD bb 959 EE aa 777 EE aa 777 EE bb 768
+ EE bb 768 EE bb 768 FF aa 670 FF aa 670 FF aa 670 FF aa 670
+ FF bb 938 FF bb 938 FF bb 938 FF bb 938 FF bb 938 FF bb 938
+ GG aa 634 GG aa 634 GG aa 634 GG aa 634 GG bb 938 GG bb 938
+ GG bb 938 GG bb 938 HH aa 979 HH aa 979 HH aa 979 HH bb 963
+ HH bb 963 HH bb 963 HH bb 963 HH bb 963 HH bb 963 II aa 652
+ II aa 652 II bb 805 II bb 805 II bb 805 II bb 805 II bb 805
+ JJ aa 899 JJ aa 899 JJ aa 899 JJ aa 899 JJ bb 839 JJ bb 839
+ JJ bb 839 JJ bb 839}
+
+do_execsql_test 1.16.5 {
+ SELECT a, b, min(c) OVER (ORDER BY a,b GROUPS BETWEEN 0 FOLLOWING AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 223 AA aa 223 AA aa 223 AA aa 223 AA bb 309 AA bb 309
+ AA bb 309 AA bb 309 BB aa 247 BB aa 247 BB aa 247 BB aa 247
+ BB aa 247 BB aa 247 BB bb 633 BB bb 633 BB bb 633 BB bb 633
+ BB bb 633 BB bb 633 CC aa 158 CC aa 158 CC aa 158 CC aa 158
+ CC bb 346 CC bb 346 DD aa 224 DD aa 224 DD aa 224 DD bb 238
+ DD bb 238 DD bb 238 DD bb 238 EE aa 113 EE aa 113 EE bb 252
+ EE bb 252 EE bb 252 FF aa 208 FF aa 208 FF aa 208 FF aa 208
+ FF bb 102 FF bb 102 FF bb 102 FF bb 102 FF bb 102 FF bb 102
+ GG aa 148 GG aa 148 GG aa 148 GG aa 148 GG bb 160 GG bb 160
+ GG bb 160 GG bb 160 HH aa 480 HH aa 480 HH aa 480 HH bb 133
+ HH bb 133 HH bb 133 HH bb 133 HH bb 133 HH bb 133 II aa 398
+ II aa 398 II bb 250 II bb 250 II bb 250 II bb 250 II bb 250
+ JJ aa 113 JJ aa 113 JJ aa 113 JJ aa 113 JJ bb 257 JJ bb 257
+ JJ bb 257 JJ bb 257}
+
+do_execsql_test 1.16.6 {
+ 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;
+} {AA aa 3751 AA aa 3774 AA aa 4446 AA aa 4462 AA bb 3815 AA bb 4058
+ AA bb 4113 AA bb 4376 BB aa 6578 BB aa 6680 BB aa 6928 BB aa 6941
+ BB aa 6947 BB aa 7093 BB bb 6500 BB bb 6548 BB bb 6554 BB bb 6629
+ BB bb 6635 BB bb 6707 CC aa 2363 CC aa 2515 CC aa 2692 CC aa 2964
+ CC bb 2300 CC bb 2776 DD aa 3187 DD aa 3776 DD aa 3808 DD bb 3073
+ DD bb 3238 DD bb 3316 DD bb 3794 EE aa 1762 EE aa 2426 EE bb 1771
+ EE bb 1910 EE bb 2287 FF aa 4998 FF aa 5001 FF aa 5050 FF aa 5460
+ FF bb 4730 FF bb 4798 FF bb 4942 FF bb 5094 FF bb 5373 FF bb 5566
+ GG aa 3834 GG aa 3988 GG aa 4133 GG aa 4320 GG bb 3530 GG bb 3539
+ GG bb 3624 GG bb 4308 HH aa 4464 HH aa 4653 HH aa 4963 HH bb 4480
+ HH bb 4713 HH bb 4760 HH bb 5088 HH bb 5113 HH bb 5310 II aa 2988
+ II aa 3242 II bb 2835 II bb 2969 II bb 3197 II bb 3219 II bb 3390
+ JJ aa 2901 JJ aa 3032 JJ aa 3566 JJ aa 3687 JJ bb 2961 JJ bb 3446
+ JJ bb 3464 JJ bb 3543}
+
+do_execsql_test 1.16.7 {
+ 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;
+} {AA aa 1373 AA aa 1396 AA aa 2068 AA aa 2084 AA bb 1508 AA bb 1751
+ AA bb 1806 AA bb 2069 BB aa 2111 BB aa 2213 BB aa 2461 BB aa 2474
+ BB aa 2480 BB aa 2626 BB bb 3627 BB bb 3675 BB bb 3681 BB bb 3756
+ BB bb 3762 BB bb 3834 CC aa 1195 CC aa 1347 CC aa 1524 CC aa 1796
+ CC bb 346 CC bb 822 DD aa 480 DD aa 1069 DD aa 1101 DD bb 1748
+ DD bb 1913 DD bb 1991 DD bb 2469 EE aa 113 EE aa 777 EE bb 881
+ EE bb 1020 EE bb 1397 FF aa 1493 FF aa 1496 FF aa 1545 FF aa 1955
+ FF bb 2567 FF bb 2635 FF bb 2779 FF bb 2931 FF bb 3210 FF bb 3403
+ GG aa 963 GG aa 1117 GG aa 1262 GG aa 1449 GG bb 1933 GG bb 1942
+ GG bb 2027 GG bb 2711 HH aa 1270 HH aa 1459 HH aa 1769 HH bb 2231
+ HH bb 2464 HH bb 2511 HH bb 2839 HH bb 2864 HH bb 3061 II aa 398
+ II aa 652 II bb 1785 II bb 1919 II bb 2147 II bb 2169 II bb 2340
+ JJ aa 1115 JJ aa 1246 JJ aa 1780 JJ aa 1901 JJ bb 947 JJ bb 1432
+ JJ bb 1450 JJ bb 1529}
+
+do_execsql_test 1.16.8 {
+ SELECT a, b,
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN 0 FOLLOWING AND 0 FOLLOWING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN 0 FOLLOWING AND 0 FOLLOWING ),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 0 FOLLOWING AND 0 FOLLOWING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 0 FOLLOWING AND 0 FOLLOWING )
+ FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 3751 4685 1373 2307 AA aa 3774 4685 1396 2307
+ AA aa 4446 4685 2068 2307 AA aa 4462 4685 2084 2307
+ AA bb 3815 4685 1508 2378 AA bb 4058 4685 1751 2378
+ AA bb 4113 4685 1806 2378 AA bb 4376 4685 2069 2378
+ BB aa 6578 7340 2111 2873 BB aa 6680 7340 2213 2873
+ BB aa 6928 7340 2461 2873 BB aa 6941 7340 2474 2873
+ BB aa 6947 7340 2480 2873 BB aa 7093 7340 2626 2873
+ BB bb 6500 7340 3627 4467 BB bb 6548 7340 3675 4467
+ BB bb 6554 7340 3681 4467 BB bb 6629 7340 3756 4467
+ BB bb 6635 7340 3762 4467 BB bb 6707 7340 3834 4467
+ CC aa 2363 3122 1195 1954 CC aa 2515 3122 1347 1954
+ CC aa 2692 3122 1524 1954 CC aa 2964 3122 1796 1954
+ CC bb 2300 3122 346 1168 CC bb 2776 3122 822 1168
+ DD aa 3187 4032 480 1325 DD aa 3776 4032 1069 1325
+ DD aa 3808 4032 1101 1325 DD bb 3073 4032 1748 2707
+ DD bb 3238 4032 1913 2707 DD bb 3316 4032 1991 2707
+ DD bb 3794 4032 2469 2707 EE aa 1762 2539 113 890
+ EE aa 2426 2539 777 890 EE bb 1771 2539 881 1649
+ EE bb 1910 2539 1020 1649 EE bb 2287 2539 1397 1649
+ FF aa 4998 5668 1493 2163 FF aa 5001 5668 1496 2163
+ FF aa 5050 5668 1545 2163 FF aa 5460 5668 1955 2163
+ FF bb 4730 5668 2567 3505 FF bb 4798 5668 2635 3505
+ FF bb 4942 5668 2779 3505 FF bb 5094 5668 2931 3505
+ FF bb 5373 5668 3210 3505 FF bb 5566 5668 3403 3505
+ GG aa 3834 4468 963 1597 GG aa 3988 4468 1117 1597
+ GG aa 4133 4468 1262 1597 GG aa 4320 4468 1449 1597
+ GG bb 3530 4468 1933 2871 GG bb 3539 4468 1942 2871
+ GG bb 3624 4468 2027 2871 GG bb 4308 4468 2711 2871
+ HH aa 4464 5443 1270 2249 HH aa 4653 5443 1459 2249
+ HH aa 4963 5443 1769 2249 HH bb 4480 5443 2231 3194
+ HH bb 4713 5443 2464 3194 HH bb 4760 5443 2511 3194
+ HH bb 5088 5443 2839 3194 HH bb 5113 5443 2864 3194
+ HH bb 5310 5443 3061 3194 II aa 2988 3640 398 1050
+ II aa 3242 3640 652 1050 II bb 2835 3640 1785 2590
+ II bb 2969 3640 1919 2590 II bb 3197 3640 2147 2590
+ II bb 3219 3640 2169 2590 II bb 3390 3640 2340 2590
+ JJ aa 2901 3800 1115 2014 JJ aa 3032 3800 1246 2014
+ JJ aa 3566 3800 1780 2014 JJ aa 3687 3800 1901 2014
+ JJ bb 2961 3800 947 1786 JJ bb 3446 3800 1432 1786
+ JJ bb 3464 3800 1450 1786 JJ bb 3543 3800 1529 1786}
+
+do_execsql_test 1.17.1 {
+ SELECT a, b, sum(c) OVER (ORDER BY a GROUPS BETWEEN 1 FOLLOWING AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb {} AA bb {} AA bb {}
+ AA bb {} BB aa {} BB aa {} BB aa {} BB aa {} BB aa {} BB aa {}
+ BB bb {} BB bb {} BB bb {} BB bb {} BB bb {} BB bb {} CC aa {}
+ CC aa {} CC aa {} CC aa {} CC bb {} CC bb {} DD aa {} DD aa {}
+ DD aa {} DD bb {} DD bb {} DD bb {} DD bb {} EE aa {} EE aa {}
+ EE bb {} EE bb {} EE bb {} FF aa {} FF aa {} FF aa {} FF aa {}
+ FF bb {} FF bb {} FF bb {} FF bb {} FF bb {} FF bb {} GG aa {}
+ GG aa {} GG aa {} GG aa {} GG bb {} GG bb {} GG bb {} GG bb {}
+ HH aa {} HH aa {} HH aa {} HH bb {} HH bb {} HH bb {} HH bb {}
+ HH bb {} HH bb {} II aa {} II aa {} II bb {} II bb {} II bb {}
+ II bb {} II bb {} JJ aa {} JJ aa {} JJ aa {} JJ aa {} JJ bb {}
+ JJ bb {} JJ bb {} JJ bb {}}
+
+do_execsql_test 1.17.2 {
+ SELECT a, b, sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 1 FOLLOWING AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb {} AA bb {} AA bb {}
+ AA bb {} BB aa {} BB aa {} BB aa {} BB aa {} BB aa {} BB aa {}
+ BB bb {} BB bb {} BB bb {} BB bb {} BB bb {} BB bb {} CC aa {}
+ CC aa {} CC aa {} CC aa {} CC bb {} CC bb {} DD aa {} DD aa {}
+ DD aa {} DD bb {} DD bb {} DD bb {} DD bb {} EE aa {} EE aa {}
+ EE bb {} EE bb {} EE bb {} FF aa {} FF aa {} FF aa {} FF aa {}
+ FF bb {} FF bb {} FF bb {} FF bb {} FF bb {} FF bb {} GG aa {}
+ GG aa {} GG aa {} GG aa {} GG bb {} GG bb {} GG bb {} GG bb {}
+ HH aa {} HH aa {} HH aa {} HH bb {} HH bb {} HH bb {} HH bb {}
+ HH bb {} HH bb {} II aa {} II aa {} II bb {} II bb {} II bb {}
+ II bb {} II bb {} JJ aa {} JJ aa {} JJ aa {} JJ aa {} JJ bb {}
+ JJ bb {} JJ bb {} JJ bb {}}
+
+do_execsql_test 1.17.3 {
+ SELECT a, b, rank() OVER (ORDER BY a GROUPS BETWEEN 1 FOLLOWING AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 1 AA aa 1 AA aa 1 AA aa 1 AA bb 1 AA bb 1 AA bb 1
+ AA bb 1 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9
+ BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 CC aa 21
+ CC aa 21 CC aa 21 CC aa 21 CC bb 21 CC bb 21 DD aa 27 DD aa 27
+ DD aa 27 DD bb 27 DD bb 27 DD bb 27 DD bb 27 EE aa 34 EE aa 34
+ EE bb 34 EE bb 34 EE bb 34 FF aa 39 FF aa 39 FF aa 39 FF aa 39
+ FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 GG aa 49
+ GG aa 49 GG aa 49 GG aa 49 GG bb 49 GG bb 49 GG bb 49 GG bb 49
+ HH aa 57 HH aa 57 HH aa 57 HH bb 57 HH bb 57 HH bb 57 HH bb 57
+ HH bb 57 HH bb 57 II aa 66 II aa 66 II bb 66 II bb 66 II bb 66
+ II bb 66 II bb 66 JJ aa 73 JJ aa 73 JJ aa 73 JJ aa 73 JJ bb 73
+ JJ bb 73 JJ bb 73 JJ bb 73}
+
+do_execsql_test 1.17.4 {
+ SELECT a, b, max(c) OVER (ORDER BY a,b GROUPS BETWEEN 1 FOLLOWING AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb {} AA bb {} AA bb {}
+ AA bb {} BB aa {} BB aa {} BB aa {} BB aa {} BB aa {} BB aa {}
+ BB bb {} BB bb {} BB bb {} BB bb {} BB bb {} BB bb {} CC aa {}
+ CC aa {} CC aa {} CC aa {} CC bb {} CC bb {} DD aa {} DD aa {}
+ DD aa {} DD bb {} DD bb {} DD bb {} DD bb {} EE aa {} EE aa {}
+ EE bb {} EE bb {} EE bb {} FF aa {} FF aa {} FF aa {} FF aa {}
+ FF bb {} FF bb {} FF bb {} FF bb {} FF bb {} FF bb {} GG aa {}
+ GG aa {} GG aa {} GG aa {} GG bb {} GG bb {} GG bb {} GG bb {}
+ HH aa {} HH aa {} HH aa {} HH bb {} HH bb {} HH bb {} HH bb {}
+ HH bb {} HH bb {} II aa {} II aa {} II bb {} II bb {} II bb {}
+ II bb {} II bb {} JJ aa {} JJ aa {} JJ aa {} JJ aa {} JJ bb {}
+ JJ bb {} JJ bb {} JJ bb {}}
+
+do_execsql_test 1.17.5 {
+ SELECT a, b, min(c) OVER (ORDER BY a,b GROUPS BETWEEN 1 FOLLOWING AND 0 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb {} AA bb {} AA bb {}
+ AA bb {} BB aa {} BB aa {} BB aa {} BB aa {} BB aa {} BB aa {}
+ BB bb {} BB bb {} BB bb {} BB bb {} BB bb {} BB bb {} CC aa {}
+ CC aa {} CC aa {} CC aa {} CC bb {} CC bb {} DD aa {} DD aa {}
+ DD aa {} DD bb {} DD bb {} DD bb {} DD bb {} EE aa {} EE aa {}
+ EE bb {} EE bb {} EE bb {} FF aa {} FF aa {} FF aa {} FF aa {}
+ FF bb {} FF bb {} FF bb {} FF bb {} FF bb {} FF bb {} GG aa {}
+ GG aa {} GG aa {} GG aa {} GG bb {} GG bb {} GG bb {} GG bb {}
+ HH aa {} HH aa {} HH aa {} HH bb {} HH bb {} HH bb {} HH bb {}
+ HH bb {} HH bb {} II aa {} II aa {} II bb {} II bb {} II bb {}
+ II bb {} II bb {} JJ aa {} JJ aa {} JJ aa {} JJ aa {} JJ bb {}
+ JJ bb {} JJ bb {} JJ bb {}}
+
+do_execsql_test 1.17.6 {
+ SELECT a, b, sum(c) OVER (ORDER BY a GROUPS BETWEEN 1 FOLLOWING AND 0 FOLLOWING EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb {} AA bb {} AA bb {}
+ AA bb {} BB aa {} BB aa {} BB aa {} BB aa {} BB aa {} BB aa {}
+ BB bb {} BB bb {} BB bb {} BB bb {} BB bb {} BB bb {} CC aa {}
+ CC aa {} CC aa {} CC aa {} CC bb {} CC bb {} DD aa {} DD aa {}
+ DD aa {} DD bb {} DD bb {} DD bb {} DD bb {} EE aa {} EE aa {}
+ EE bb {} EE bb {} EE bb {} FF aa {} FF aa {} FF aa {} FF aa {}
+ FF bb {} FF bb {} FF bb {} FF bb {} FF bb {} FF bb {} GG aa {}
+ GG aa {} GG aa {} GG aa {} GG bb {} GG bb {} GG bb {} GG bb {}
+ HH aa {} HH aa {} HH aa {} HH bb {} HH bb {} HH bb {} HH bb {}
+ HH bb {} HH bb {} II aa {} II aa {} II bb {} II bb {} II bb {}
+ II bb {} II bb {} JJ aa {} JJ aa {} JJ aa {} JJ aa {} JJ bb {}
+ JJ bb {} JJ bb {} JJ bb {}}
+
+do_execsql_test 1.17.7 {
+ SELECT a, b, sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 1 FOLLOWING AND 0 FOLLOWING EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} AA aa {} AA aa {} AA aa {} AA bb {} AA bb {} AA bb {}
+ AA bb {} BB aa {} BB aa {} BB aa {} BB aa {} BB aa {} BB aa {}
+ BB bb {} BB bb {} BB bb {} BB bb {} BB bb {} BB bb {} CC aa {}
+ CC aa {} CC aa {} CC aa {} CC bb {} CC bb {} DD aa {} DD aa {}
+ DD aa {} DD bb {} DD bb {} DD bb {} DD bb {} EE aa {} EE aa {}
+ EE bb {} EE bb {} EE bb {} FF aa {} FF aa {} FF aa {} FF aa {}
+ FF bb {} FF bb {} FF bb {} FF bb {} FF bb {} FF bb {} GG aa {}
+ GG aa {} GG aa {} GG aa {} GG bb {} GG bb {} GG bb {} GG bb {}
+ HH aa {} HH aa {} HH aa {} HH bb {} HH bb {} HH bb {} HH bb {}
+ HH bb {} HH bb {} II aa {} II aa {} II bb {} II bb {} II bb {}
+ II bb {} II bb {} JJ aa {} JJ aa {} JJ aa {} JJ aa {} JJ bb {}
+ JJ bb {} JJ bb {} JJ bb {}}
+
+do_execsql_test 1.17.8 {
+ SELECT a, b,
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN 1 FOLLOWING AND 0 FOLLOWING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN 1 FOLLOWING AND 0 FOLLOWING ),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 1 FOLLOWING AND 0 FOLLOWING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 1 FOLLOWING AND 0 FOLLOWING )
+ FROM t3 ORDER BY 1, 2, 3;
+} {AA aa {} {} {} {} AA aa {} {} {} {} AA aa {} {} {} {}
+ AA aa {} {} {} {} AA bb {} {} {} {} AA bb {} {} {} {}
+ AA bb {} {} {} {} AA bb {} {} {} {} BB aa {} {} {} {}
+ BB aa {} {} {} {} BB aa {} {} {} {} BB aa {} {} {} {}
+ BB aa {} {} {} {} BB aa {} {} {} {} BB bb {} {} {} {}
+ BB bb {} {} {} {} BB bb {} {} {} {} BB bb {} {} {} {}
+ BB bb {} {} {} {} BB bb {} {} {} {} CC aa {} {} {} {}
+ CC aa {} {} {} {} CC aa {} {} {} {} CC aa {} {} {} {}
+ CC bb {} {} {} {} CC bb {} {} {} {} DD aa {} {} {} {}
+ DD aa {} {} {} {} DD aa {} {} {} {} DD bb {} {} {} {}
+ DD bb {} {} {} {} DD bb {} {} {} {} DD bb {} {} {} {}
+ EE aa {} {} {} {} EE aa {} {} {} {} EE bb {} {} {} {}
+ EE bb {} {} {} {} EE bb {} {} {} {} FF aa {} {} {} {}
+ FF aa {} {} {} {} FF aa {} {} {} {} FF aa {} {} {} {}
+ FF bb {} {} {} {} FF bb {} {} {} {} FF bb {} {} {} {}
+ FF bb {} {} {} {} FF bb {} {} {} {} FF bb {} {} {} {}
+ GG aa {} {} {} {} GG aa {} {} {} {} GG aa {} {} {} {}
+ GG aa {} {} {} {} GG bb {} {} {} {} GG bb {} {} {} {}
+ GG bb {} {} {} {} GG bb {} {} {} {} HH aa {} {} {} {}
+ HH aa {} {} {} {} HH aa {} {} {} {} HH bb {} {} {} {}
+ HH bb {} {} {} {} HH bb {} {} {} {} HH bb {} {} {} {}
+ HH bb {} {} {} {} HH bb {} {} {} {} II aa {} {} {} {}
+ II aa {} {} {} {} II bb {} {} {} {} II bb {} {} {} {}
+ II bb {} {} {} {} II bb {} {} {} {} II bb {} {} {} {}
+ JJ aa {} {} {} {} JJ aa {} {} {} {} JJ aa {} {} {} {}
+ JJ aa {} {} {} {} JJ bb {} {} {} {} JJ bb {} {} {} {}
+ JJ bb {} {} {} {} JJ bb {} {} {} {}}
+
+do_execsql_test 1.18.1 {
+ SELECT a, b, sum(c) OVER (ORDER BY a GROUPS BETWEEN 1 FOLLOWING AND 5 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 22701 AA aa 22701 AA aa 22701 AA aa 22701 AA bb 22701
+ AA bb 22701 AA bb 22701 AA bb 22701 BB aa 19829 BB aa 19829
+ BB aa 19829 BB aa 19829 BB aa 19829 BB aa 19829 BB bb 19829
+ BB bb 19829 BB bb 19829 BB bb 19829 BB bb 19829 BB bb 19829
+ CC aa 22150 CC aa 22150 CC aa 22150 CC aa 22150 CC bb 22150
+ CC bb 22150 DD aa 21758 DD aa 21758 DD aa 21758 DD bb 21758
+ DD bb 21758 DD bb 21758 DD bb 21758 EE aa 23019 EE aa 23019
+ EE bb 23019 EE bb 23019 EE bb 23019 FF aa 17351 FF aa 17351
+ FF aa 17351 FF aa 17351 FF bb 17351 FF bb 17351 FF bb 17351
+ FF bb 17351 FF bb 17351 FF bb 17351 GG aa 12883 GG aa 12883
+ GG aa 12883 GG aa 12883 GG bb 12883 GG bb 12883 GG bb 12883
+ GG bb 12883 HH aa 7440 HH aa 7440 HH aa 7440 HH bb 7440
+ HH bb 7440 HH bb 7440 HH bb 7440 HH bb 7440 HH bb 7440 II aa 3800
+ II aa 3800 II bb 3800 II bb 3800 II bb 3800 II bb 3800 II bb 3800
+ JJ aa {} JJ aa {} JJ aa {} JJ aa {} JJ bb {} JJ bb {} JJ bb {}
+ JJ bb {}}
+
+do_execsql_test 1.18.2 {
+ SELECT a, b, sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 1 FOLLOWING AND 5 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 12840 AA aa 12840 AA aa 12840 AA aa 12840 AA bb 11787
+ AA bb 11787 AA bb 11787 AA bb 11787 BB aa 11621 BB aa 11621
+ BB aa 11621 BB aa 11621 BB aa 11621 BB aa 11621 BB bb 8044
+ BB bb 8044 BB bb 8044 BB bb 8044 BB bb 8044 BB bb 8044 CC aa 7739
+ CC aa 7739 CC aa 7739 CC aa 7739 CC bb 8734 CC bb 8734
+ DD aa 10914 DD aa 10914 DD aa 10914 DD bb 9804 DD bb 9804
+ DD bb 9804 DD bb 9804 EE aa 11785 EE aa 11785 EE bb 12385
+ EE bb 12385 EE bb 12385 FF aa 13416 FF aa 13416 FF aa 13416
+ FF aa 13416 FF bb 10961 FF bb 10961 FF bb 10961 FF bb 10961
+ FF bb 10961 FF bb 10961 GG aa 11954 GG aa 11954 GG aa 11954
+ GG aa 11954 GG bb 11097 GG bb 11097 GG bb 11097 GG bb 11097
+ HH aa 10634 HH aa 10634 HH aa 10634 HH bb 7440 HH bb 7440
+ HH bb 7440 HH bb 7440 HH bb 7440 HH bb 7440 II aa 6390 II aa 6390
+ II bb 3800 II bb 3800 II bb 3800 II bb 3800 II bb 3800 JJ aa 1786
+ JJ aa 1786 JJ aa 1786 JJ aa 1786 JJ bb {} JJ bb {} JJ bb {}
+ JJ bb {}}
+
+do_execsql_test 1.18.3 {
+ SELECT a, b, rank() OVER (ORDER BY a GROUPS BETWEEN 1 FOLLOWING AND 5 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 1 AA aa 1 AA aa 1 AA aa 1 AA bb 1 AA bb 1 AA bb 1
+ AA bb 1 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9
+ BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 CC aa 21
+ CC aa 21 CC aa 21 CC aa 21 CC bb 21 CC bb 21 DD aa 27 DD aa 27
+ DD aa 27 DD bb 27 DD bb 27 DD bb 27 DD bb 27 EE aa 34 EE aa 34
+ EE bb 34 EE bb 34 EE bb 34 FF aa 39 FF aa 39 FF aa 39 FF aa 39
+ FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 GG aa 49
+ GG aa 49 GG aa 49 GG aa 49 GG bb 49 GG bb 49 GG bb 49 GG bb 49
+ HH aa 57 HH aa 57 HH aa 57 HH bb 57 HH bb 57 HH bb 57 HH bb 57
+ HH bb 57 HH bb 57 II aa 66 II aa 66 II bb 66 II bb 66 II bb 66
+ II bb 66 II bb 66 JJ aa 73 JJ aa 73 JJ aa 73 JJ aa 73 JJ bb 73
+ JJ bb 73 JJ bb 73 JJ bb 73}
+
+do_execsql_test 1.18.4 {
+ SELECT a, b, max(c) OVER (ORDER BY a,b GROUPS BETWEEN 1 FOLLOWING AND 5 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 870 AA aa 870 AA aa 870 AA aa 870 AA bb 845 AA bb 845
+ AA bb 845 AA bb 845 BB aa 959 BB aa 959 BB aa 959 BB aa 959
+ BB aa 959 BB aa 959 BB bb 959 BB bb 959 BB bb 959 BB bb 959
+ BB bb 959 BB bb 959 CC aa 959 CC aa 959 CC aa 959 CC aa 959
+ CC bb 959 CC bb 959 DD aa 959 DD aa 959 DD aa 959 DD bb 938
+ DD bb 938 DD bb 938 DD bb 938 EE aa 938 EE aa 938 EE bb 979
+ EE bb 979 EE bb 979 FF aa 979 FF aa 979 FF aa 979 FF aa 979
+ FF bb 979 FF bb 979 FF bb 979 FF bb 979 FF bb 979 FF bb 979
+ GG aa 979 GG aa 979 GG aa 979 GG aa 979 GG bb 979 GG bb 979
+ GG bb 979 GG bb 979 HH aa 963 HH aa 963 HH aa 963 HH bb 899
+ HH bb 899 HH bb 899 HH bb 899 HH bb 899 HH bb 899 II aa 899
+ II aa 899 II bb 899 II bb 899 II bb 899 II bb 899 II bb 899
+ JJ aa 839 JJ aa 839 JJ aa 839 JJ aa 839 JJ bb {} JJ bb {}
+ JJ bb {} JJ bb {}}
+
+do_execsql_test 1.18.5 {
+ SELECT a, b, min(c) OVER (ORDER BY a,b GROUPS BETWEEN 1 FOLLOWING AND 5 FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 158 AA aa 158 AA aa 158 AA aa 158 AA bb 158 AA bb 158
+ AA bb 158 AA bb 158 BB aa 158 BB aa 158 BB aa 158 BB aa 158
+ BB aa 158 BB aa 158 BB bb 113 BB bb 113 BB bb 113 BB bb 113
+ BB bb 113 BB bb 113 CC aa 113 CC aa 113 CC aa 113 CC aa 113
+ CC bb 113 CC bb 113 DD aa 102 DD aa 102 DD aa 102 DD bb 102
+ DD bb 102 DD bb 102 DD bb 102 EE aa 102 EE aa 102 EE bb 102
+ EE bb 102 EE bb 102 FF aa 102 FF aa 102 FF aa 102 FF aa 102
+ FF bb 133 FF bb 133 FF bb 133 FF bb 133 FF bb 133 FF bb 133
+ GG aa 133 GG aa 133 GG aa 133 GG aa 133 GG bb 113 GG bb 113
+ GG bb 113 GG bb 113 HH aa 113 HH aa 113 HH aa 113 HH bb 113
+ HH bb 113 HH bb 113 HH bb 113 HH bb 113 HH bb 113 II aa 113
+ II aa 113 II bb 113 II bb 113 II bb 113 II bb 113 II bb 113
+ JJ aa 257 JJ aa 257 JJ aa 257 JJ aa 257 JJ bb {} JJ bb {}
+ JJ bb {} JJ bb {}}
+
+do_execsql_test 1.18.6 {
+ SELECT a, b, sum(c) OVER (ORDER BY a GROUPS BETWEEN 1 FOLLOWING AND 5 FOLLOWING EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 22701 AA aa 22701 AA aa 22701 AA aa 22701 AA bb 22701
+ AA bb 22701 AA bb 22701 AA bb 22701 BB aa 19829 BB aa 19829
+ BB aa 19829 BB aa 19829 BB aa 19829 BB aa 19829 BB bb 19829
+ BB bb 19829 BB bb 19829 BB bb 19829 BB bb 19829 BB bb 19829
+ CC aa 22150 CC aa 22150 CC aa 22150 CC aa 22150 CC bb 22150
+ CC bb 22150 DD aa 21758 DD aa 21758 DD aa 21758 DD bb 21758
+ DD bb 21758 DD bb 21758 DD bb 21758 EE aa 23019 EE aa 23019
+ EE bb 23019 EE bb 23019 EE bb 23019 FF aa 17351 FF aa 17351
+ FF aa 17351 FF aa 17351 FF bb 17351 FF bb 17351 FF bb 17351
+ FF bb 17351 FF bb 17351 FF bb 17351 GG aa 12883 GG aa 12883
+ GG aa 12883 GG aa 12883 GG bb 12883 GG bb 12883 GG bb 12883
+ GG bb 12883 HH aa 7440 HH aa 7440 HH aa 7440 HH bb 7440
+ HH bb 7440 HH bb 7440 HH bb 7440 HH bb 7440 HH bb 7440 II aa 3800
+ II aa 3800 II bb 3800 II bb 3800 II bb 3800 II bb 3800 II bb 3800
+ JJ aa {} JJ aa {} JJ aa {} JJ aa {} JJ bb {} JJ bb {} JJ bb {}
+ JJ bb {}}
+
+do_execsql_test 1.18.7 {
+ SELECT a, b, sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 1 FOLLOWING AND 5 FOLLOWING EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 12840 AA aa 12840 AA aa 12840 AA aa 12840 AA bb 11787
+ AA bb 11787 AA bb 11787 AA bb 11787 BB aa 11621 BB aa 11621
+ BB aa 11621 BB aa 11621 BB aa 11621 BB aa 11621 BB bb 8044
+ BB bb 8044 BB bb 8044 BB bb 8044 BB bb 8044 BB bb 8044 CC aa 7739
+ CC aa 7739 CC aa 7739 CC aa 7739 CC bb 8734 CC bb 8734
+ DD aa 10914 DD aa 10914 DD aa 10914 DD bb 9804 DD bb 9804
+ DD bb 9804 DD bb 9804 EE aa 11785 EE aa 11785 EE bb 12385
+ EE bb 12385 EE bb 12385 FF aa 13416 FF aa 13416 FF aa 13416
+ FF aa 13416 FF bb 10961 FF bb 10961 FF bb 10961 FF bb 10961
+ FF bb 10961 FF bb 10961 GG aa 11954 GG aa 11954 GG aa 11954
+ GG aa 11954 GG bb 11097 GG bb 11097 GG bb 11097 GG bb 11097
+ HH aa 10634 HH aa 10634 HH aa 10634 HH bb 7440 HH bb 7440
+ HH bb 7440 HH bb 7440 HH bb 7440 HH bb 7440 II aa 6390 II aa 6390
+ II bb 3800 II bb 3800 II bb 3800 II bb 3800 II bb 3800 JJ aa 1786
+ JJ aa 1786 JJ aa 1786 JJ aa 1786 JJ bb {} JJ bb {} JJ bb {}
+ JJ bb {}}
+
+do_execsql_test 1.18.8 {
+ SELECT a, b,
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN 1 FOLLOWING AND 5 FOLLOWING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN 1 FOLLOWING AND 5 FOLLOWING ),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 1 FOLLOWING AND 5 FOLLOWING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 1 FOLLOWING AND 5 FOLLOWING )
+ FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 22701 22701 12840 12840 AA aa 22701 22701 12840 12840
+ AA aa 22701 22701 12840 12840 AA aa 22701 22701 12840 12840
+ AA bb 22701 22701 11787 11787 AA bb 22701 22701 11787 11787
+ AA bb 22701 22701 11787 11787 AA bb 22701 22701 11787 11787
+ BB aa 19829 19829 11621 11621 BB aa 19829 19829 11621 11621
+ BB aa 19829 19829 11621 11621 BB aa 19829 19829 11621 11621
+ BB aa 19829 19829 11621 11621 BB aa 19829 19829 11621 11621
+ BB bb 19829 19829 8044 8044 BB bb 19829 19829 8044 8044
+ BB bb 19829 19829 8044 8044 BB bb 19829 19829 8044 8044
+ BB bb 19829 19829 8044 8044 BB bb 19829 19829 8044 8044
+ CC aa 22150 22150 7739 7739 CC aa 22150 22150 7739 7739
+ CC aa 22150 22150 7739 7739 CC aa 22150 22150 7739 7739
+ CC bb 22150 22150 8734 8734 CC bb 22150 22150 8734 8734
+ DD aa 21758 21758 10914 10914 DD aa 21758 21758 10914 10914
+ DD aa 21758 21758 10914 10914 DD bb 21758 21758 9804 9804
+ DD bb 21758 21758 9804 9804 DD bb 21758 21758 9804 9804
+ DD bb 21758 21758 9804 9804 EE aa 23019 23019 11785 11785
+ EE aa 23019 23019 11785 11785 EE bb 23019 23019 12385 12385
+ EE bb 23019 23019 12385 12385 EE bb 23019 23019 12385 12385
+ FF aa 17351 17351 13416 13416 FF aa 17351 17351 13416 13416
+ FF aa 17351 17351 13416 13416 FF aa 17351 17351 13416 13416
+ FF bb 17351 17351 10961 10961 FF bb 17351 17351 10961 10961
+ FF bb 17351 17351 10961 10961 FF bb 17351 17351 10961 10961
+ FF bb 17351 17351 10961 10961 FF bb 17351 17351 10961 10961
+ GG aa 12883 12883 11954 11954 GG aa 12883 12883 11954 11954
+ GG aa 12883 12883 11954 11954 GG aa 12883 12883 11954 11954
+ GG bb 12883 12883 11097 11097 GG bb 12883 12883 11097 11097
+ GG bb 12883 12883 11097 11097 GG bb 12883 12883 11097 11097
+ HH aa 7440 7440 10634 10634 HH aa 7440 7440 10634 10634
+ HH aa 7440 7440 10634 10634 HH bb 7440 7440 7440 7440
+ HH bb 7440 7440 7440 7440 HH bb 7440 7440 7440 7440
+ HH bb 7440 7440 7440 7440 HH bb 7440 7440 7440 7440
+ HH bb 7440 7440 7440 7440 II aa 3800 3800 6390 6390
+ II aa 3800 3800 6390 6390 II bb 3800 3800 3800 3800
+ II bb 3800 3800 3800 3800 II bb 3800 3800 3800 3800
+ II bb 3800 3800 3800 3800 II bb 3800 3800 3800 3800
+ JJ aa {} {} 1786 1786 JJ aa {} {} 1786 1786 JJ aa {} {} 1786 1786
+ JJ aa {} {} 1786 1786 JJ bb {} {} {} {} JJ bb {} {} {} {}
+ JJ bb {} {} {} {} JJ bb {} {} {} {}}
+
+do_execsql_test 1.19.1 {
+ SELECT a, b, sum(c) OVER (ORDER BY a GROUPS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 40052 AA aa 40052 AA aa 40052 AA aa 40052 AA bb 40052
+ AA bb 40052 AA bb 40052 AA bb 40052 BB aa 32712 BB aa 32712
+ BB aa 32712 BB aa 32712 BB aa 32712 BB aa 32712 BB bb 32712
+ BB bb 32712 BB bb 32712 BB bb 32712 BB bb 32712 BB bb 32712
+ CC aa 29590 CC aa 29590 CC aa 29590 CC aa 29590 CC bb 29590
+ CC bb 29590 DD aa 25558 DD aa 25558 DD aa 25558 DD bb 25558
+ DD bb 25558 DD bb 25558 DD bb 25558 EE aa 23019 EE aa 23019
+ EE bb 23019 EE bb 23019 EE bb 23019 FF aa 17351 FF aa 17351
+ FF aa 17351 FF aa 17351 FF bb 17351 FF bb 17351 FF bb 17351
+ FF bb 17351 FF bb 17351 FF bb 17351 GG aa 12883 GG aa 12883
+ GG aa 12883 GG aa 12883 GG bb 12883 GG bb 12883 GG bb 12883
+ GG bb 12883 HH aa 7440 HH aa 7440 HH aa 7440 HH bb 7440
+ HH bb 7440 HH bb 7440 HH bb 7440 HH bb 7440 HH bb 7440 II aa 3800
+ II aa 3800 II bb 3800 II bb 3800 II bb 3800 II bb 3800 II bb 3800
+ JJ aa {} JJ aa {} JJ aa {} JJ aa {} JJ bb {} JJ bb {} JJ bb {}
+ JJ bb {}}
+
+do_execsql_test 1.19.2 {
+ SELECT a, b, sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 42430 AA aa 42430 AA aa 42430 AA aa 42430 AA bb 40052
+ AA bb 40052 AA bb 40052 AA bb 40052 BB aa 37179 BB aa 37179
+ BB aa 37179 BB aa 37179 BB aa 37179 BB aa 37179 BB bb 32712
+ BB bb 32712 BB bb 32712 BB bb 32712 BB bb 32712 BB bb 32712
+ CC aa 30758 CC aa 30758 CC aa 30758 CC aa 30758 CC bb 29590
+ CC bb 29590 DD aa 28265 DD aa 28265 DD aa 28265 DD bb 25558
+ DD bb 25558 DD bb 25558 DD bb 25558 EE aa 24668 EE aa 24668
+ EE bb 23019 EE bb 23019 EE bb 23019 FF aa 20856 FF aa 20856
+ FF aa 20856 FF aa 20856 FF bb 17351 FF bb 17351 FF bb 17351
+ FF bb 17351 FF bb 17351 FF bb 17351 GG aa 15754 GG aa 15754
+ GG aa 15754 GG aa 15754 GG bb 12883 GG bb 12883 GG bb 12883
+ GG bb 12883 HH aa 10634 HH aa 10634 HH aa 10634 HH bb 7440
+ HH bb 7440 HH bb 7440 HH bb 7440 HH bb 7440 HH bb 7440 II aa 6390
+ II aa 6390 II bb 3800 II bb 3800 II bb 3800 II bb 3800 II bb 3800
+ JJ aa 1786 JJ aa 1786 JJ aa 1786 JJ aa 1786 JJ bb {} JJ bb {}
+ JJ bb {} JJ bb {}}
+
+do_execsql_test 1.19.3 {
+ SELECT a, b, rank() OVER (ORDER BY a GROUPS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 1 AA aa 1 AA aa 1 AA aa 1 AA bb 1 AA bb 1 AA bb 1
+ AA bb 1 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9 BB aa 9
+ BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 BB bb 9 CC aa 21
+ CC aa 21 CC aa 21 CC aa 21 CC bb 21 CC bb 21 DD aa 27 DD aa 27
+ DD aa 27 DD bb 27 DD bb 27 DD bb 27 DD bb 27 EE aa 34 EE aa 34
+ EE bb 34 EE bb 34 EE bb 34 FF aa 39 FF aa 39 FF aa 39 FF aa 39
+ FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 FF bb 39 GG aa 49
+ GG aa 49 GG aa 49 GG aa 49 GG bb 49 GG bb 49 GG bb 49 GG bb 49
+ HH aa 57 HH aa 57 HH aa 57 HH bb 57 HH bb 57 HH bb 57 HH bb 57
+ HH bb 57 HH bb 57 II aa 66 II aa 66 II bb 66 II bb 66 II bb 66
+ II bb 66 II bb 66 JJ aa 73 JJ aa 73 JJ aa 73 JJ aa 73 JJ bb 73
+ JJ bb 73 JJ bb 73 JJ bb 73}
+
+do_execsql_test 1.19.4 {
+ SELECT a, b, max(c) OVER (ORDER BY a,b GROUPS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 979 AA aa 979 AA aa 979 AA aa 979 AA bb 979 AA bb 979
+ AA bb 979 AA bb 979 BB aa 979 BB aa 979 BB aa 979 BB aa 979
+ BB aa 979 BB aa 979 BB bb 979 BB bb 979 BB bb 979 BB bb 979
+ BB bb 979 BB bb 979 CC aa 979 CC aa 979 CC aa 979 CC aa 979
+ CC bb 979 CC bb 979 DD aa 979 DD aa 979 DD aa 979 DD bb 979
+ DD bb 979 DD bb 979 DD bb 979 EE aa 979 EE aa 979 EE bb 979
+ EE bb 979 EE bb 979 FF aa 979 FF aa 979 FF aa 979 FF aa 979
+ FF bb 979 FF bb 979 FF bb 979 FF bb 979 FF bb 979 FF bb 979
+ GG aa 979 GG aa 979 GG aa 979 GG aa 979 GG bb 979 GG bb 979
+ GG bb 979 GG bb 979 HH aa 963 HH aa 963 HH aa 963 HH bb 899
+ HH bb 899 HH bb 899 HH bb 899 HH bb 899 HH bb 899 II aa 899
+ II aa 899 II bb 899 II bb 899 II bb 899 II bb 899 II bb 899
+ JJ aa 839 JJ aa 839 JJ aa 839 JJ aa 839 JJ bb {} JJ bb {}
+ JJ bb {} JJ bb {}}
+
+do_execsql_test 1.19.5 {
+ SELECT a, b, min(c) OVER (ORDER BY a,b GROUPS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING ) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 102 AA aa 102 AA aa 102 AA aa 102 AA bb 102 AA bb 102
+ AA bb 102 AA bb 102 BB aa 102 BB aa 102 BB aa 102 BB aa 102
+ BB aa 102 BB aa 102 BB bb 102 BB bb 102 BB bb 102 BB bb 102
+ BB bb 102 BB bb 102 CC aa 102 CC aa 102 CC aa 102 CC aa 102
+ CC bb 102 CC bb 102 DD aa 102 DD aa 102 DD aa 102 DD bb 102
+ DD bb 102 DD bb 102 DD bb 102 EE aa 102 EE aa 102 EE bb 102
+ EE bb 102 EE bb 102 FF aa 102 FF aa 102 FF aa 102 FF aa 102
+ FF bb 113 FF bb 113 FF bb 113 FF bb 113 FF bb 113 FF bb 113
+ GG aa 113 GG aa 113 GG aa 113 GG aa 113 GG bb 113 GG bb 113
+ GG bb 113 GG bb 113 HH aa 113 HH aa 113 HH aa 113 HH bb 113
+ HH bb 113 HH bb 113 HH bb 113 HH bb 113 HH bb 113 II aa 113
+ II aa 113 II bb 113 II bb 113 II bb 113 II bb 113 II bb 113
+ JJ aa 257 JJ aa 257 JJ aa 257 JJ aa 257 JJ bb {} JJ bb {}
+ JJ bb {} JJ bb {}}
+
+do_execsql_test 1.19.6 {
+ SELECT a, b, sum(c) OVER (ORDER BY a GROUPS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 40052 AA aa 40052 AA aa 40052 AA aa 40052 AA bb 40052
+ AA bb 40052 AA bb 40052 AA bb 40052 BB aa 32712 BB aa 32712
+ BB aa 32712 BB aa 32712 BB aa 32712 BB aa 32712 BB bb 32712
+ BB bb 32712 BB bb 32712 BB bb 32712 BB bb 32712 BB bb 32712
+ CC aa 29590 CC aa 29590 CC aa 29590 CC aa 29590 CC bb 29590
+ CC bb 29590 DD aa 25558 DD aa 25558 DD aa 25558 DD bb 25558
+ DD bb 25558 DD bb 25558 DD bb 25558 EE aa 23019 EE aa 23019
+ EE bb 23019 EE bb 23019 EE bb 23019 FF aa 17351 FF aa 17351
+ FF aa 17351 FF aa 17351 FF bb 17351 FF bb 17351 FF bb 17351
+ FF bb 17351 FF bb 17351 FF bb 17351 GG aa 12883 GG aa 12883
+ GG aa 12883 GG aa 12883 GG bb 12883 GG bb 12883 GG bb 12883
+ GG bb 12883 HH aa 7440 HH aa 7440 HH aa 7440 HH bb 7440
+ HH bb 7440 HH bb 7440 HH bb 7440 HH bb 7440 HH bb 7440 II aa 3800
+ II aa 3800 II bb 3800 II bb 3800 II bb 3800 II bb 3800 II bb 3800
+ JJ aa {} JJ aa {} JJ aa {} JJ aa {} JJ bb {} JJ bb {} JJ bb {}
+ JJ bb {}}
+
+do_execsql_test 1.19.7 {
+ SELECT a, b, sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW) FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 42430 AA aa 42430 AA aa 42430 AA aa 42430 AA bb 40052
+ AA bb 40052 AA bb 40052 AA bb 40052 BB aa 37179 BB aa 37179
+ BB aa 37179 BB aa 37179 BB aa 37179 BB aa 37179 BB bb 32712
+ BB bb 32712 BB bb 32712 BB bb 32712 BB bb 32712 BB bb 32712
+ CC aa 30758 CC aa 30758 CC aa 30758 CC aa 30758 CC bb 29590
+ CC bb 29590 DD aa 28265 DD aa 28265 DD aa 28265 DD bb 25558
+ DD bb 25558 DD bb 25558 DD bb 25558 EE aa 24668 EE aa 24668
+ EE bb 23019 EE bb 23019 EE bb 23019 FF aa 20856 FF aa 20856
+ FF aa 20856 FF aa 20856 FF bb 17351 FF bb 17351 FF bb 17351
+ FF bb 17351 FF bb 17351 FF bb 17351 GG aa 15754 GG aa 15754
+ GG aa 15754 GG aa 15754 GG bb 12883 GG bb 12883 GG bb 12883
+ GG bb 12883 HH aa 10634 HH aa 10634 HH aa 10634 HH bb 7440
+ HH bb 7440 HH bb 7440 HH bb 7440 HH bb 7440 HH bb 7440 II aa 6390
+ II aa 6390 II bb 3800 II bb 3800 II bb 3800 II bb 3800 II bb 3800
+ JJ aa 1786 JJ aa 1786 JJ aa 1786 JJ aa 1786 JJ bb {} JJ bb {}
+ JJ bb {} JJ bb {}}
+
+do_execsql_test 1.19.8 {
+ SELECT a, b,
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a GROUPS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING ),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW),
+ sum(c) OVER (ORDER BY a,b GROUPS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING )
+ FROM t3 ORDER BY 1, 2, 3;
+} {AA aa 40052 40052 42430 42430 AA aa 40052 40052 42430 42430
+ AA aa 40052 40052 42430 42430 AA aa 40052 40052 42430 42430
+ AA bb 40052 40052 40052 40052 AA bb 40052 40052 40052 40052
+ AA bb 40052 40052 40052 40052 AA bb 40052 40052 40052 40052
+ BB aa 32712 32712 37179 37179 BB aa 32712 32712 37179 37179
+ BB aa 32712 32712 37179 37179 BB aa 32712 32712 37179 37179
+ BB aa 32712 32712 37179 37179 BB aa 32712 32712 37179 37179
+ BB bb 32712 32712 32712 32712 BB bb 32712 32712 32712 32712
+ BB bb 32712 32712 32712 32712 BB bb 32712 32712 32712 32712
+ BB bb 32712 32712 32712 32712 BB bb 32712 32712 32712 32712
+ CC aa 29590 29590 30758 30758 CC aa 29590 29590 30758 30758
+ CC aa 29590 29590 30758 30758 CC aa 29590 29590 30758 30758
+ CC bb 29590 29590 29590 29590 CC bb 29590 29590 29590 29590
+ DD aa 25558 25558 28265 28265 DD aa 25558 25558 28265 28265
+ DD aa 25558 25558 28265 28265 DD bb 25558 25558 25558 25558
+ DD bb 25558 25558 25558 25558 DD bb 25558 25558 25558 25558
+ DD bb 25558 25558 25558 25558 EE aa 23019 23019 24668 24668
+ EE aa 23019 23019 24668 24668 EE bb 23019 23019 23019 23019
+ EE bb 23019 23019 23019 23019 EE bb 23019 23019 23019 23019
+ FF aa 17351 17351 20856 20856 FF aa 17351 17351 20856 20856
+ FF aa 17351 17351 20856 20856 FF aa 17351 17351 20856 20856
+ FF bb 17351 17351 17351 17351 FF bb 17351 17351 17351 17351
+ FF bb 17351 17351 17351 17351 FF bb 17351 17351 17351 17351
+ FF bb 17351 17351 17351 17351 FF bb 17351 17351 17351 17351
+ GG aa 12883 12883 15754 15754 GG aa 12883 12883 15754 15754
+ GG aa 12883 12883 15754 15754 GG aa 12883 12883 15754 15754
+ GG bb 12883 12883 12883 12883 GG bb 12883 12883 12883 12883
+ GG bb 12883 12883 12883 12883 GG bb 12883 12883 12883 12883
+ HH aa 7440 7440 10634 10634 HH aa 7440 7440 10634 10634
+ HH aa 7440 7440 10634 10634 HH bb 7440 7440 7440 7440
+ HH bb 7440 7440 7440 7440 HH bb 7440 7440 7440 7440
+ HH bb 7440 7440 7440 7440 HH bb 7440 7440 7440 7440
+ HH bb 7440 7440 7440 7440 II aa 3800 3800 6390 6390
+ II aa 3800 3800 6390 6390 II bb 3800 3800 3800 3800
+ II bb 3800 3800 3800 3800 II bb 3800 3800 3800 3800
+ II bb 3800 3800 3800 3800 II bb 3800 3800 3800 3800
+ JJ aa {} {} 1786 1786 JJ aa {} {} 1786 1786 JJ aa {} {} 1786 1786
+ JJ aa {} {} 1786 1786 JJ bb {} {} {} {} JJ bb {} {} {} {}
+ JJ bb {} {} {} {} JJ bb {} {} {} {}}
+
+do_execsql_test 2.1.1 {
+ SELECT row_number() OVER win
+ FROM t3
+ WINDOW win AS (
+ ORDER BY c, b, a
+ ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS
+ )
+} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
+ 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
+ 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
+ 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
+ 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
+ 78 79 80}
+
+do_execsql_test 2.1.2 {
+ SELECT nth_value(c, 14) OVER win
+ FROM t3
+ WINDOW win AS (
+ ORDER BY c, b, a
+ ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS
+ )
+} {247 247 247 247 247 247 247 247 247 247 247 247 247
+ 247 247 247 247 247 247 247 247 247 247 247 247 247
+ 247 247 247 247 247 247 247 247 247 247 247 247 247
+ 247 247 247 247 247 247 247 247 247 247 247 247 247
+ 247 247 247 247 247 247 247 247 247 247 247 247 247
+ 247 247 247 247 247 247 247 247 247 247 247 247 247
+ 247 247}
+
+do_execsql_test 2.1.3 {
+ SELECT min(c) OVER win, max(c) OVER win, sum(c) OVER win FROM t3
+ WINDOW win AS (
+ ORDER BY c, b, a
+ ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS
+ ) ORDER BY a, b, c;
+} {102 223 1358 102 239 2293 102 911 38097 102 934 39960 102 309 4159
+ 102 572 10643 102 627 13069 102 870 35417 102 247 2540 102 393 6608
+ 102 399 7405 102 412 7817 102 660 16277 102 762 24077 102 633 14331
+ 102 705 19673 102 711 20384 102 786 27176 102 792 28758
+ 102 840 32858 102 158 767 102 430 8668 102 607 11824 102 759 23315
+ 102 346 5506 102 822 31179 102 224 1582 102 256 3298 102 845 34547
+ 102 238 2054 102 716 21100 102 794 29552 102 959 42795 102 113 215
+ 102 777 26390 102 252 3042 102 629 13698 102 768 25613 102 208 1135
+ 102 618 12442 102 667 16944 102 670 17614 102 102 102 102 295 3850
+ 102 574 11217 102 726 21826 102 870 36287 102 938 40898 102 148 609
+ 102 335 4824 102 480 9591 102 634 14965 102 160 927 102 844 33702
+ 102 929 39026 102 938 41836 102 480 10071 102 790 27966
+ 102 979 44737 102 133 461 102 330 4489 102 355 6215 102 683 18968
+ 102 730 22556 102 963 43758 102 398 7006 102 652 15617 102 250 2790
+ 102 421 8238 102 443 9111 102 671 18285 102 805 30357 102 113 328
+ 102 234 1816 102 768 24845 102 899 37186 102 257 3555 102 336 5160
+ 102 354 5860 102 839 32018}
+
+do_execsql_test 2.2.1 {
+ SELECT row_number() OVER win
+ FROM t3
+ WINDOW win AS (
+ ORDER BY c, b, a
+ ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW
+ )
+} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
+ 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
+ 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
+ 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
+ 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
+ 78 79 80}
+
+do_execsql_test 2.2.2 {
+ SELECT nth_value(c, 14) OVER win
+ FROM t3
+ WINDOW win AS (
+ ORDER BY c, b, a
+ ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW
+ )
+} {250 250 250 250 250 250 250 250 250 250 250 250 250
+ 250 247 247 247 247 247 247 247 247 247 247 247 247
+ 247 247 247 247 247 247 247 247 247 247 247 247 247
+ 247 247 247 247 247 247 247 247 247 247 247 247 247
+ 247 247 247 247 247 247 247 247 247 247 247 247 247
+ 247 247 247 247 247 247 247 247 247 247 247 247 247
+ 247 247}
+
+do_execsql_test 2.2.3 {
+ SELECT min(c) OVER win, max(c) OVER win, sum(c) OVER win FROM t3
+ WINDOW win AS (
+ ORDER BY c, b, a
+ ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE CURRENT ROW
+ ) ORDER BY a, b, c;
+} {102 208 1135 102 238 2054 102 899 37186 102 929 39026 102 295 3850
+ 102 480 10071 102 618 12442 102 845 34547 102 239 2293 102 355 6215
+ 102 398 7006 102 399 7405 102 652 15617 102 759 23315 102 629 13698
+ 102 683 18968 102 705 19673 102 777 26390 102 790 27966
+ 102 839 32018 102 148 609 102 421 8238 102 574 11217 102 730 22556
+ 102 336 5160 102 805 30357 102 223 1358 102 252 3042 102 844 33702
+ 102 234 1816 102 711 20384 102 792 28758 102 938 41836 102 102 102
+ 102 768 25613 102 250 2790 102 627 13069 102 768 24845 102 160 927
+ 102 607 11824 102 660 16277 102 667 16944 {} {} {} 102 257 3555
+ 102 572 10643 102 716 21100 102 870 35417 102 934 39960 102 133 461
+ 102 330 4489 102 443 9111 102 633 14331 102 158 767 102 840 32858
+ 102 911 38097 102 938 40898 102 480 9591 102 786 27176
+ 102 963 43758 102 113 328 102 309 4159 102 354 5860 102 671 18285
+ 102 726 21826 102 959 42795 102 393 6608 102 634 14965 102 247 2540
+ 102 412 7817 102 430 8668 102 670 17614 102 794 29552 102 113 215
+ 102 224 1582 102 762 24077 102 870 36287 102 256 3298 102 335 4824
+ 102 346 5506 102 822 31179}
+
+do_execsql_test 2.3.1 {
+ SELECT row_number() OVER win
+ FROM t3
+ WINDOW win AS (
+ ORDER BY c, b, a
+ ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE GROUP
+ )
+} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
+ 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
+ 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
+ 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
+ 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
+ 78 79 80}
+
+do_execsql_test 2.3.2 {
+ SELECT nth_value(c, 14) OVER win
+ FROM t3
+ WINDOW win AS (
+ ORDER BY c, b, a
+ ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE GROUP
+ )
+} {250 250 250 250 250 250 250 250 250 250 250 250 250
+ 250 247 247 247 247 247 247 247 247 247 247 247 247
+ 247 247 247 247 247 247 247 247 247 247 247 247 247
+ 247 247 247 247 247 247 247 247 247 247 247 247 247
+ 247 247 247 247 247 247 247 247 247 247 247 247 247
+ 247 247 247 247 247 247 247 247 247 247 247 247 247
+ 247 247}
+
+do_execsql_test 2.3.3 {
+ SELECT min(c) OVER win, max(c) OVER win, sum(c) OVER win FROM t3
+ WINDOW win AS (
+ ORDER BY c, b, a
+ ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE GROUP
+ ) ORDER BY a, b, c;
+} {102 208 1135 102 238 2054 102 899 37186 102 929 39026 102 295 3850
+ 102 480 10071 102 618 12442 102 845 34547 102 239 2293 102 355 6215
+ 102 398 7006 102 399 7405 102 652 15617 102 759 23315 102 629 13698
+ 102 683 18968 102 705 19673 102 777 26390 102 790 27966
+ 102 839 32018 102 148 609 102 421 8238 102 574 11217 102 730 22556
+ 102 336 5160 102 805 30357 102 223 1358 102 252 3042 102 844 33702
+ 102 234 1816 102 711 20384 102 792 28758 102 938 41836 102 102 102
+ 102 768 25613 102 250 2790 102 627 13069 102 768 24845 102 160 927
+ 102 607 11824 102 660 16277 102 667 16944 {} {} {} 102 257 3555
+ 102 572 10643 102 716 21100 102 870 35417 102 934 39960 102 133 461
+ 102 330 4489 102 443 9111 102 633 14331 102 158 767 102 840 32858
+ 102 911 38097 102 938 40898 102 480 9591 102 786 27176
+ 102 963 43758 102 113 328 102 309 4159 102 354 5860 102 671 18285
+ 102 726 21826 102 959 42795 102 393 6608 102 634 14965 102 247 2540
+ 102 412 7817 102 430 8668 102 670 17614 102 794 29552 102 113 215
+ 102 224 1582 102 762 24077 102 870 36287 102 256 3298 102 335 4824
+ 102 346 5506 102 822 31179}
+
+do_execsql_test 2.4.1 {
+ SELECT row_number() OVER win
+ FROM t3
+ WINDOW win AS (
+ ORDER BY c, b, a
+ ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE TIES
+ )
+} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
+ 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
+ 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
+ 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
+ 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
+ 78 79 80}
+
+do_execsql_test 2.4.2 {
+ SELECT nth_value(c, 14) OVER win
+ FROM t3
+ WINDOW win AS (
+ ORDER BY c, b, a
+ ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE TIES
+ )
+} {247 247 247 247 247 247 247 247 247 247 247 247 247
+ 247 247 247 247 247 247 247 247 247 247 247 247 247
+ 247 247 247 247 247 247 247 247 247 247 247 247 247
+ 247 247 247 247 247 247 247 247 247 247 247 247 247
+ 247 247 247 247 247 247 247 247 247 247 247 247 247
+ 247 247 247 247 247 247 247 247 247 247 247 247 247
+ 247 247}
+
+do_execsql_test 2.4.3 {
+ SELECT min(c) OVER win, max(c) OVER win, sum(c) OVER win FROM t3
+ WINDOW win AS (
+ ORDER BY c, b, a
+ ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE TIES
+ ) ORDER BY a, b, c;
+} {102 223 1358 102 239 2293 102 911 38097 102 934 39960 102 309 4159
+ 102 572 10643 102 627 13069 102 870 35417 102 247 2540 102 393 6608
+ 102 399 7405 102 412 7817 102 660 16277 102 762 24077 102 633 14331
+ 102 705 19673 102 711 20384 102 786 27176 102 792 28758
+ 102 840 32858 102 158 767 102 430 8668 102 607 11824 102 759 23315
+ 102 346 5506 102 822 31179 102 224 1582 102 256 3298 102 845 34547
+ 102 238 2054 102 716 21100 102 794 29552 102 959 42795 102 113 215
+ 102 777 26390 102 252 3042 102 629 13698 102 768 25613 102 208 1135
+ 102 618 12442 102 667 16944 102 670 17614 102 102 102 102 295 3850
+ 102 574 11217 102 726 21826 102 870 36287 102 938 40898 102 148 609
+ 102 335 4824 102 480 9591 102 634 14965 102 160 927 102 844 33702
+ 102 929 39026 102 938 41836 102 480 10071 102 790 27966
+ 102 979 44737 102 133 461 102 330 4489 102 355 6215 102 683 18968
+ 102 730 22556 102 963 43758 102 398 7006 102 652 15617 102 250 2790
+ 102 421 8238 102 443 9111 102 671 18285 102 805 30357 102 113 328
+ 102 234 1816 102 768 24845 102 899 37186 102 257 3555 102 336 5160
+ 102 354 5860 102 839 32018}
+
+#==========================================================================
+
+do_execsql_test 3.0 {
+ DROP TABLE IF EXISTS t1;
+ CREATE TABLE t1(a REAL, b INTEGER);
+ INSERT INTO t1 VALUES
+ (5, 10), (10, 20), (13, 26), (13, 26),
+ (15, 30), (20, 40), (22,80), (30, 90);
+} {}
+
+do_execsql_test 3.1 {
+ SELECT CAST(a AS INTEGER), sum(b) OVER win FROM t1 WINDOW win AS ( ORDER BY a RANGE BETWEEN 5 PRECEDING AND 5 FOLLOWING )
+} {5 30 10 112 13 102 13 102 15 142 20 150 22 120 30 90}
+
+do_execsql_test 3.2 {
+ SELECT CAST(a AS INTEGER), sum(b) OVER win FROM t1 WINDOW win AS ( ORDER BY a RANGE BETWEEN 10 PRECEDING AND 5 PRECEDING )
+} {5 {} 10 10 13 10 13 10 15 30 20 102 22 82 30 120}
+
+do_execsql_test 3.3 {
+ SELECT CAST(a AS INTEGER), sum(b) OVER win FROM t1 WINDOW win AS ( ORDER BY a RANGE BETWEEN 2 FOLLOWING AND 3 FOLLOWING )
+} {5 {} 10 52 13 30 13 30 15 {} 20 80 22 {} 30 {}}
+
+do_execsql_test 3.4 {
+ SELECT CAST(a AS INTEGER), sum(b) OVER win FROM t1 WINDOW win AS ( ORDER BY a DESC RANGE BETWEEN 5 PRECEDING AND 5 FOLLOWING )
+} {30 90 22 120 20 150 15 142 13 102 13 102 10 112 5 30}
+
+do_execsql_test 3.5 {
+ SELECT CAST(a AS INTEGER), sum(b) OVER win FROM t1 WINDOW win AS ( ORDER BY a DESC RANGE BETWEEN 10 PRECEDING AND 5 PRECEDING )
+} {30 {} 22 90 20 90 15 120 13 120 13 120 10 70 5 102}
+
+do_execsql_test 3.6 {
+ SELECT CAST(a AS INTEGER), sum(b) OVER win FROM t1 WINDOW win AS ( ORDER BY a DESC RANGE BETWEEN 2 FOLLOWING AND 3 FOLLOWING )
+} {30 {} 22 40 20 {} 15 52 13 20 13 20 10 {} 5 {}}
+
+do_execsql_test 3.7 {
+ SELECT CAST(a AS INTEGER), sum(b) OVER win FROM t1 WINDOW win AS ( ORDER BY a RANGE BETWEEN 5.1 PRECEDING AND 5.3 FOLLOWING )
+} {5 30 10 112 13 102 13 102 15 142 20 150 22 120 30 90}
+
+do_execsql_test 3.8 {
+ SELECT CAST(a AS INTEGER), sum(b) OVER win FROM t1 WINDOW win AS ( ORDER BY a RANGE BETWEEN 10.2 PRECEDING AND 5.4 PRECEDING )
+} {5 {} 10 {} 13 10 13 10 15 10 20 72 22 82 30 120}
+
+do_execsql_test 3.9 {
+ SELECT CAST(a AS INTEGER), sum(b) OVER win FROM t1 WINDOW win AS ( ORDER BY a RANGE BETWEEN 2.6 FOLLOWING AND 3.5 FOLLOWING )
+} {5 {} 10 52 13 {} 13 {} 15 {} 20 {} 22 {} 30 {}}
+
+do_execsql_test 3.10 {
+ SELECT CAST(a AS INTEGER), sum(b) OVER win FROM t1 WINDOW win AS ( ORDER BY a DESC RANGE BETWEEN 5.7 PRECEDING AND 5.8 FOLLOWING )
+} {30 90 22 120 20 150 15 142 13 102 13 102 10 112 5 30}
+
+do_execsql_test 3.11 {
+ SELECT CAST(a AS INTEGER), sum(b) OVER win FROM t1 WINDOW win AS ( ORDER BY a DESC RANGE BETWEEN UNBOUNDED PRECEDING AND 5.9 PRECEDING )
+} {30 {} 22 90 20 90 15 170 13 210 13 210 10 210 5 292}
+
+do_execsql_test 3.12 {
+ SELECT CAST(a AS INTEGER), sum(b) OVER win FROM t1 WINDOW win AS ( ORDER BY a DESC RANGE BETWEEN 2.1 FOLLOWING AND UNBOUNDED FOLLOWING )
+} {30 232 22 112 20 112 15 30 13 30 13 30 10 10 5 {}}
+
+do_execsql_test 3.13 {
+ SELECT CAST(a AS INTEGER), sum(b) OVER win FROM t1 WINDOW win AS ( ORDER BY a RANGE 5.1 PRECEDING )
+} {5 10 10 30 13 72 13 72 15 102 20 70 22 120 30 90}
+
+#==========================================================================
+
+do_execsql_test 4.0 {
+ DROP TABLE IF EXISTS t1;
+ CREATE TABLE t1(a INTEGER, b INTEGER);
+ INSERT INTO t1 VALUES
+ (NULL, 1), (NULL, 2), (NULL, 3), (10, 4), (10, 5);
+} {}
+
+do_execsql_test 4.1.1 {
+ SELECT sum(b) OVER (
+ ORDER BY a RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING
+ ) FROM t1 ORDER BY 1;
+} {6 6 6 9 9}
+
+do_execsql_test 4.1.2 {
+ SELECT sum(b) OVER (
+ ORDER BY a DESC RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING
+ ) FROM t1 ORDER BY 1;
+} {6 6 6 9 9}
+
+do_execsql_test 4.2.1 {
+ SELECT sum(b) OVER (
+ ORDER BY a RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING
+ ) FROM t1 ORDER BY 1 ;
+} {{} {} 6 6 6}
+
+do_execsql_test 4.2.2 {
+ SELECT sum(b) OVER (
+ ORDER BY a DESC RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING
+ ) FROM t1 ORDER BY 1 ;
+} {{} {} 6 6 6}
+
+do_execsql_test 4.3.1 {
+ SELECT sum(b) OVER (
+ ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING
+ ) FROM t1 ORDER BY 1 ;
+} {6 6 6 15 15}
+
+do_execsql_test 4.4.1 {
+ SELECT sum(b) OVER (
+ ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
+ ) FROM t1 ORDER BY 1 ;
+} {3 6 9 9 12}
+
+do_execsql_test 4.4.2 {
+ SELECT sum(b) OVER (
+ ORDER BY a DESC ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
+ ) FROM t1 ORDER BY 1 ;
+} {5 6 8 9 10}
+
+#==========================================================================
+
+do_execsql_test 5.0 {
+ INSERT INTO t3 VALUES
+ (NULL, 'bb', 355), (NULL, 'cc', 158), (NULL, 'aa', 399),
+ ('JJ', NULL, 839), ('FF', NULL, 618), ('BB', NULL, 393),
+ (NULL, 'bb', 629), (NULL, NULL, 667), (NULL, NULL, 870);
+} {}
+
+do_execsql_test 5.1.1.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS )
+ ORDER BY 1 , 2 , 3
+} {979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83
+ 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83
+ 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83
+ 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83
+ 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83
+ 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83
+ 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83
+ 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83
+ 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83
+ 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83
+ 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83
+ 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83
+ 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83
+ 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83
+ 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83}
+
+do_execsql_test 5.1.1.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS )
+ ORDER BY 1 , 2 , 3
+} {23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1
+ 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1
+ 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1
+ 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1
+ 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1
+ 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1
+ 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1
+ 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1
+ 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1
+ 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1
+ 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1
+ 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1
+ 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1
+ 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1
+ 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1}
+
+do_execsql_test 5.1.2.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY a
+ RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS )
+ ORDER BY 1 , 2 , 3
+} {899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9
+ 899 113 9 899 113 9 899 113 9 899 113 16 899 113 16 899 113 16
+ 899 113 16 899 113 16 899 113 16 899 113 16 979 102 44 979 102 44
+ 979 102 44 979 102 44 979 102 44 979 102 44 979 102 44 979 102 44
+ 979 102 44 979 102 44 979 102 44 979 102 49 979 102 49 979 102 49
+ 979 102 49 979 102 49 979 102 56 979 102 56 979 102 56 979 102 56
+ 979 102 56 979 102 56 979 102 56 979 102 62 979 102 62 979 102 62
+ 979 102 62 979 102 62 979 102 62 979 102 75 979 102 75 979 102 75
+ 979 102 75 979 102 75 979 102 75 979 102 75 979 102 75 979 102 75
+ 979 102 75 979 102 75 979 102 75 979 102 75 979 102 83 979 102 83
+ 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83
+ 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83
+ 979 113 25 979 113 25 979 113 25 979 113 25 979 113 25 979 113 25
+ 979 113 25 979 113 25 979 113 25 979 113 33 979 113 33 979 113 33
+ 979 113 33 979 113 33 979 113 33 979 113 33 979 113 33}
+
+do_execsql_test 5.1.2.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY a
+ RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS )
+ ORDER BY 1 , 2 , 3
+} {2947 81 11 2947 81 11 2947 81 11 2947 81 11 2947 81 11 2947 81 11
+ 2947 81 11 2947 81 11 2947 81 11 5287 74 10 5287 74 10 5287 74 10
+ 5287 74 10 5287 74 10 5287 74 10 5287 74 10 8400 65 9 8400 65 9
+ 8400 65 9 8400 65 9 8400 65 9 8400 65 9 8400 65 9 8400 65 9
+ 8400 65 9 9664 57 8 9664 57 8 9664 57 8 9664 57 8 9664 57 8
+ 9664 57 8 9664 57 8 9664 57 8 10626 46 7 10626 46 7 10626 46 7
+ 10626 46 7 10626 46 7 10626 46 7 10626 46 7 10626 46 7 10626 46 7
+ 10626 46 7 10626 46 7 12145 41 6 12145 41 6 12145 41 6 12145 41 6
+ 12145 41 6 13949 34 5 13949 34 5 13949 34 5 13949 34 5 13949 34 5
+ 13949 34 5 13949 34 5 15315 28 4 15315 28 4 15315 28 4 15315 28 4
+ 15315 28 4 15315 28 4 18796 15 3 18796 15 3 18796 15 3 18796 15 3
+ 18796 15 3 18796 15 3 18796 15 3 18796 15 3 18796 15 3 18796 15 3
+ 18796 15 3 18796 15 3 18796 15 3 21105 7 2 21105 7 2 21105 7 2
+ 21105 7 2 21105 7 2 21105 7 2 21105 7 2 21105 7 2 23155 1 1
+ 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1}
+
+do_execsql_test 5.1.3.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( PARTITION BY coalesce(a, '')
+ RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS )
+ ORDER BY 1 , 2 , 3
+} {777 113 5 777 113 5 777 113 5 777 113 5 777 113 5 805 250 7
+ 805 250 7 805 250 7 805 250 7 805 250 7 805 250 7 805 250 7
+ 822 158 6 822 158 6 822 158 6 822 158 6 822 158 6 822 158 6
+ 840 247 13 840 247 13 840 247 13 840 247 13 840 247 13 840 247 13
+ 840 247 13 840 247 13 840 247 13 840 247 13 840 247 13 840 247 13
+ 840 247 13 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0
+ 870 158 0 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9
+ 899 113 9 899 113 9 899 113 9 899 113 9 934 223 8 934 223 8
+ 934 223 8 934 223 8 934 223 8 934 223 8 934 223 8 934 223 8
+ 938 102 11 938 102 11 938 102 11 938 102 11 938 102 11 938 102 11
+ 938 102 11 938 102 11 938 102 11 938 102 11 938 102 11 938 148 8
+ 938 148 8 938 148 8 938 148 8 938 148 8 938 148 8 938 148 8
+ 938 148 8 959 224 7 959 224 7 959 224 7 959 224 7 959 224 7
+ 959 224 7 959 224 7 979 133 9 979 133 9 979 133 9 979 133 9
+ 979 133 9 979 133 9 979 133 9 979 133 9 979 133 9}
+
+do_execsql_test 5.1.3.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( PARTITION BY coalesce(a, '')
+ RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS )
+ ORDER BY 1 , 2 , 3
+} {962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1
+ 962 1 1 962 1 1 962 1 1 962 1 1 1264 1 1 1264 1 1 1264 1 1
+ 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1366 1 1 1366 1 1
+ 1366 1 1 1366 1 1 1366 1 1 1366 1 1 1519 1 1 1519 1 1 1519 1 1
+ 1519 1 1 1519 1 1 1804 1 1 1804 1 1 1804 1 1 1804 1 1 1804 1 1
+ 1804 1 1 1804 1 1 2050 1 1 2050 1 1 2050 1 1 2050 1 1 2050 1 1
+ 2050 1 1 2309 1 1 2309 1 1 2309 1 1 2309 1 1 2309 1 1 2309 1 1
+ 2309 1 1 2309 1 1 2340 1 1 2340 1 1 2340 1 1 2340 1 1 2340 1 1
+ 2340 1 1 2340 1 1 2947 1 1 2947 1 1 2947 1 1 2947 1 1 2947 1 1
+ 2947 1 1 2947 1 1 2947 1 1 2947 1 1 3113 1 1 3113 1 1 3113 1 1
+ 3113 1 1 3113 1 1 3113 1 1 3113 1 1 3113 1 1 3113 1 1 3481 1 1
+ 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1
+ 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1}
+
+do_execsql_test 5.1.4.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY a GROUPS 6 PRECEDING EXCLUDE NO OTHERS )
+ ORDER BY 1 , 2 , 3
+} {870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0
+ 934 158 8 934 158 8 934 158 8 934 158 8 934 158 8 934 158 8
+ 934 158 8 934 158 8 934 158 21 934 158 21 934 158 21 934 158 21
+ 934 158 21 934 158 21 934 158 21 934 158 21 934 158 21 934 158 21
+ 934 158 21 934 158 21 934 158 21 934 158 27 934 158 27 934 158 27
+ 934 158 27 934 158 27 934 158 27 959 102 50 959 102 50 959 102 50
+ 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50
+ 959 102 50 959 102 50 959 102 58 959 102 58 959 102 58 959 102 58
+ 959 102 58 959 102 58 959 102 58 959 102 58 959 113 39 959 113 39
+ 959 113 39 959 113 39 959 113 39 959 158 34 959 158 34 959 158 34
+ 959 158 34 959 158 34 959 158 34 959 158 34 979 102 53 979 102 53
+ 979 102 53 979 102 53 979 102 53 979 102 53 979 102 53 979 102 56
+ 979 102 56 979 102 56 979 102 56 979 102 56 979 102 56 979 102 56
+ 979 102 56 979 102 56 979 102 59 979 102 59 979 102 59 979 102 59
+ 979 102 59 979 102 59 979 102 59 979 102 59 979 102 59}
+
+do_execsql_test 5.1.4.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY a GROUPS 6 PRECEDING EXCLUDE NO OTHERS )
+ ORDER BY 1 , 2 , 3
+} {2050 1 1 2050 1 1 2050 1 1 2050 1 1 2050 1 1 2050 1 1 4359 7 2
+ 4359 7 2 4359 7 2 4359 7 2 4359 7 2 4359 7 2 4359 7 2 4359 7 2
+ 7840 15 3 7840 15 3 7840 15 3 7840 15 3 7840 15 3 7840 15 3
+ 7840 15 3 7840 15 3 7840 15 3 7840 15 3 7840 15 3 7840 15 3
+ 7840 15 3 9206 28 4 9206 28 4 9206 28 4 9206 28 4 9206 28 4
+ 9206 28 4 11010 34 5 11010 34 5 11010 34 5 11010 34 5 11010 34 5
+ 11010 34 5 11010 34 5 12368 74 10 12368 74 10 12368 74 10
+ 12368 74 10 12368 74 10 12368 74 10 12368 74 10 12529 41 6
+ 12529 41 6 12529 41 6 12529 41 6 12529 41 6 12705 57 8 12705 57 8
+ 12705 57 8 12705 57 8 12705 57 8 12705 57 8 12705 57 8 12705 57 8
+ 13491 46 7 13491 46 7 13491 46 7 13491 46 7 13491 46 7 13491 46 7
+ 13491 46 7 13491 46 7 13491 46 7 13491 46 7 13491 46 7 13509 65 9
+ 13509 65 9 13509 65 9 13509 65 9 13509 65 9 13509 65 9 13509 65 9
+ 13509 65 9 13509 65 9 13949 81 11 13949 81 11 13949 81 11
+ 13949 81 11 13949 81 11 13949 81 11 13949 81 11 13949 81 11
+ 13949 81 11}
+
+do_execsql_test 5.1.5.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY c RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE NO OTHERS )
+ ORDER BY 1 , 2 , 3
+} {102 102 1 113 113 2 113 113 2 133 133 1 148 148 1 160 158 2
+ 160 158 2 160 158 2 208 208 1 224 223 2 224 223 2 239 234 3
+ 239 234 3 239 234 3 252 247 3 257 247 5 257 247 5 257 250 4
+ 257 252 3 295 295 1 309 309 1 336 330 3 336 330 3 336 330 3
+ 346 346 1 355 354 2 355 354 2 355 354 2 399 393 4 399 393 4
+ 399 393 4 399 393 4 399 393 4 412 412 1 421 421 1 430 430 1
+ 443 443 1 480 480 2 480 480 2 574 572 2 574 572 2 607 607 1
+ 618 618 2 618 618 2 634 627 4 634 627 4 634 627 4 634 627 4
+ 634 629 3 652 652 1 667 660 2 671 667 3 671 667 3 671 667 3
+ 671 667 3 683 683 1 711 705 2 716 705 3 716 711 2 730 726 2
+ 730 726 2 762 759 2 768 759 4 768 762 3 768 762 3 777 777 1
+ 792 786 3 794 786 4 794 786 4 794 790 3 805 805 1 822 822 1
+ 845 839 5 845 839 5 845 839 5 845 839 5 845 839 5 870 870 2
+ 870 870 2 870 870 2 899 899 1 911 911 1 934 929 2 938 929 4
+ 938 934 3 938 934 3 963 959 2 963 959 2 979 979 1}
+
+do_execsql_test 5.1.5.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY c RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE NO OTHERS )
+ ORDER BY 1 , 2 , 3
+} {{} 1 1 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 25 23 {} 34 29
+ {} 36 31 {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 43 37 {} 43 37
+ {} 50 42 {} 60 51 {} 61 52 {} 64 55 {} 64 55 {} 67 57 {} 68 58
+ {} 69 59 {} 70 60 {} 72 62 {} 78 67 {} 78 67 {} 78 67 {} 85 72
+ {} 85 72 133 4 3 223 10 8 223 11 9 226 2 2 226 2 2 239 12 10
+ 239 13 11 239 14 12 247 15 13 257 18 16 257 19 17 295 20 18
+ 309 21 19 335 22 20 335 23 21 335 24 22 421 35 30 443 37 32
+ 504 16 14 504 17 15 607 42 36 683 56 47 710 26 24 710 27 25
+ 710 27 25 711 59 50 759 62 53 759 63 54 777 66 56 805 71 61
+ 899 81 68 911 82 69 929 83 70 929 84 71 979 89 75 1334 51 43
+ 1416 57 48 1416 58 49 1584 29 26 1584 29 26 1584 31 27 1584 32 28
+ 1584 32 28 1891 49 41 1922 87 73 1922 88 74 2005 52 44 2005 52 44
+ 2005 54 45 2005 55 46 2518 45 38 2518 46 39 2518 46 39 2518 48 40
+ 2523 73 63 2523 73 63 2523 75 64 2523 76 65 2523 77 66}
+
+do_execsql_test 5.1.6.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY c RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE NO OTHERS )
+ ORDER BY 1 , 2 , 3
+} {102 102 1 113 113 2 113 113 2 133 133 1 148 148 1 158 158 1
+ 158 158 1 160 160 1 208 208 1 223 223 1 224 224 1 234 234 1
+ 238 238 1 239 239 1 247 247 1 250 250 1 252 252 1 256 256 1
+ 257 257 1 295 295 1 309 309 1 330 330 1 335 335 1 336 336 1
+ 346 346 1 354 354 1 355 355 1 355 355 1 393 393 2 393 393 2
+ 398 398 1 399 399 1 399 399 1 412 412 1 421 421 1 430 430 1
+ 443 443 1 480 480 2 480 480 2 572 572 1 574 574 1 607 607 1
+ 618 618 2 618 618 2 627 627 1 629 629 1 629 629 1 633 633 1
+ 634 634 1 652 652 1 660 660 1 667 667 1 667 667 1 670 670 1
+ 671 671 1 683 683 1 705 705 1 711 711 1 716 716 1 726 726 1
+ 730 730 1 759 759 1 762 762 1 768 768 2 768 768 2 777 777 1
+ 786 786 1 790 790 1 792 792 1 794 794 1 805 805 1 822 822 1
+ 839 839 2 839 839 2 840 840 1 844 844 1 845 845 1 870 870 2
+ 870 870 2 870 870 2 899 899 1 911 911 1 929 929 1 934 934 1
+ 938 938 2 938 938 2 959 959 1 963 963 1 979 979 1}
+
+do_execsql_test 5.1.6.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY c RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE NO OTHERS )
+ ORDER BY 1 , 2 , 3
+} {{} 1 1 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 11 9 {} 12 10
+ {} 13 11 {} 16 14 {} 17 15 {} 18 16 {} 22 20 {} 24 22 {} 25 23
+ {} 26 24 {} 31 27 {} 34 29 {} 36 31 {} 38 33 {} 38 33 {} 40 34
+ {} 41 35 {} 43 37 {} 43 37 {} 49 41 {} 50 42 {} 51 43 {} 54 45
+ {} 59 50 {} 60 51 {} 61 52 {} 63 54 {} 64 55 {} 64 55 {} 67 57
+ {} 68 58 {} 69 59 {} 70 60 {} 72 62 {} 75 64 {} 76 65 {} 78 67
+ {} 78 67 {} 78 67 {} 84 71 {} 85 72 {} 85 72 133 4 3 223 10 8
+ 226 2 2 226 2 2 239 14 12 247 15 13 257 19 17 295 20 18
+ 309 21 19 335 23 21 421 35 30 443 37 32 607 42 36 627 45 38
+ 633 48 40 671 55 46 683 56 47 705 57 48 710 27 25 710 27 25
+ 711 58 49 759 62 53 777 66 56 786 29 26 786 29 26 798 32 28
+ 798 32 28 805 71 61 845 77 66 899 81 68 911 82 69 929 83 70
+ 959 87 73 963 88 74 979 89 75 1258 46 39 1258 46 39 1334 52 44
+ 1334 52 44 1678 73 63 1678 73 63}
+
+do_execsql_test 5.1.7.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY c , b , a
+ ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS )
+ ORDER BY 1 , 2 , 3
+} {979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83
+ 979 102 83 979 113 81 979 113 82 979 133 80 979 148 79 979 158 77
+ 979 158 78 979 160 77 979 208 76 979 223 75 979 224 74 979 234 73
+ 979 238 72 979 239 71 979 247 70 979 250 69 979 252 68 979 256 67
+ 979 257 66 979 295 65 979 309 64 979 330 63 979 335 62 979 336 61
+ 979 346 60 979 354 59 979 355 58 979 355 58 979 393 56 979 393 57
+ 979 398 55 979 399 54 979 399 54 979 412 53 979 421 52 979 430 51
+ 979 443 50 979 480 48 979 480 49 979 572 47 979 574 46 979 607 45
+ 979 618 43 979 618 44 979 627 42 979 629 41 979 629 41 979 633 40
+ 979 634 39 979 652 38 979 660 37 979 667 36 979 667 36 979 670 35
+ 979 671 34 979 683 33 979 705 32 979 711 31 979 716 30 979 726 29
+ 979 730 28 979 759 27 979 762 26 979 768 24 979 768 25 979 777 23
+ 979 786 22 979 790 21 979 792 20 979 794 19 979 805 18 979 822 17
+ 979 839 15 979 839 16 979 840 14 979 844 13 979 845 12 979 870 10
+ 979 870 11 979 870 11 979 899 9 979 911 8 979 929 7}
+
+do_execsql_test 5.1.7.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY c , b , a
+ ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS )
+ ORDER BY 1 , 2 , 3
+} {3830 89 89 4741 88 88 5640 84 84 5640 85 85 5640 86 86 5640 87 87
+ 6485 81 81 6485 82 82 6485 83 83 7324 80 80 8163 78 78 8163 79 79
+ 8968 73 73 8968 74 74 8968 75 75 8968 76 76 8968 77 77 9745 69 69
+ 9745 70 70 9745 71 71 9745 72 72 10504 65 65 10504 66 66
+ 10504 67 67 10504 68 68 11215 64 64 11920 63 63 12603 62 62
+ 13274 60 60 13274 61 61 13941 59 59 14608 55 55 14608 56 56
+ 14608 57 57 14608 58 58 15241 54 54 15870 53 53 16499 52 52
+ 17126 49 49 17126 50 50 17126 51 51 17733 44 44 17733 45 45
+ 17733 46 46 17733 47 47 17733 48 48 18176 42 42 18176 43 43
+ 18597 40 40 18597 41 41 18996 39 39 19395 37 37 19395 38 38
+ 19788 36 36 20181 35 35 20536 34 34 20891 30 30 20891 31 31
+ 20891 32 32 20891 33 33 21226 28 28 21226 29 29 21535 27 27
+ 21830 26 26 22087 22 22 22087 23 23 22087 24 24 22087 25 25
+ 22334 21 21 22573 17 17 22573 18 18 22573 19 19 22573 20 20
+ 22796 11 11 22796 12 12 22796 13 13 22796 14 14 22796 15 15
+ 22796 16 16 22929 10 10 23042 9 9 23155 1 1 23155 2 2 23155 3 3
+ 23155 4 4 23155 5 5 23155 6 6 23155 7 7 23155 8 8}
+
+do_execsql_test 5.2.1.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW )
+ ORDER BY 1 , 2 , 3
+} {963 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82
+ 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82
+ 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82
+ 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82
+ 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82
+ 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82
+ 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82
+ 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82
+ 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82
+ 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82
+ 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82
+ 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82
+ 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82
+ 979 102 82 979 102 82 979 102 82 979 102 82 979 102 83 979 102 83
+ 979 102 83 979 102 83 979 102 83 979 102 83 979 113 82}
+
+do_execsql_test 5.2.1.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW )
+ ORDER BY 1 , 2 , 3
+} {22176 1 1 22192 1 1 22196 1 1 22226 1 1 22244 1 1 22256 1 1
+ 22310 1 1 22316 1 1 22316 1 1 22350 1 1 22378 1 1 22396 1 1
+ 22444 1 1 22450 1 1 22472 1 1 22484 1 1 22488 1 1 22488 1 1
+ 22522 1 1 22526 1 1 22526 1 1 22528 1 1 22548 1 1 22712 1 1
+ 22734 1 1 22756 1 1 22756 1 1 22762 1 1 22762 1 1 22800 1 1
+ 22800 1 1 22820 1 1 22846 1 1 22860 1 1 22898 1 1 22908 1 1
+ 22916 1 1 22932 1 1 23022 1 1 23042 1 1 23042 1 1 23155 1 1
+ 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1
+ 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1
+ 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1
+ 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1
+ 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1
+ 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1
+ 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1
+ 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1}
+
+do_execsql_test 5.2.2.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY a
+ RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW )
+ ORDER BY 1 , 2 , 3
+} {839 113 8 899 113 8 899 113 8 899 113 8 899 113 8 899 113 8
+ 899 113 8 899 113 8 899 113 15 899 113 15 899 113 15 899 113 15
+ 899 113 15 899 113 15 899 113 15 899 234 8 963 113 24 979 102 43
+ 979 102 43 979 102 43 979 102 43 979 102 43 979 102 43 979 102 43
+ 979 102 43 979 102 43 979 102 43 979 102 48 979 102 48 979 102 48
+ 979 102 48 979 102 48 979 102 55 979 102 55 979 102 55 979 102 55
+ 979 102 55 979 102 55 979 102 55 979 102 61 979 102 61 979 102 61
+ 979 102 61 979 102 61 979 102 61 979 102 74 979 102 74 979 102 74
+ 979 102 74 979 102 74 979 102 74 979 102 74 979 102 74 979 102 74
+ 979 102 74 979 102 74 979 102 74 979 102 74 979 102 82 979 102 82
+ 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82
+ 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83
+ 979 113 24 979 113 24 979 113 24 979 113 24 979 113 24 979 113 24
+ 979 113 24 979 113 24 979 113 32 979 113 32 979 113 32 979 113 32
+ 979 113 32 979 113 32 979 113 32 979 113 32 979 113 43}
+
+do_execsql_test 5.2.2.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY a
+ RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW )
+ ORDER BY 1 , 2 , 3
+} {2048 81 11 2108 81 11 2108 81 11 2690 81 11 2834 81 11 2947 81 11
+ 2947 81 11 2947 81 11 2947 81 11 4482 74 10 4616 74 10 4844 74 10
+ 4866 74 10 5287 74 10 5287 74 10 5287 74 10 7421 65 9 7437 65 9
+ 7717 65 9 8045 65 9 8267 65 9 8400 65 9 8400 65 9 8400 65 9
+ 8400 65 9 8735 57 8 9329 57 8 9664 57 8 9664 57 8 9664 57 8
+ 9664 57 8 9664 57 8 9664 57 8 9959 46 7 10331 46 7 10626 46 7
+ 10626 46 7 10626 46 7 10626 46 7 10626 46 7 10626 46 7 10626 46 7
+ 10626 46 7 10626 46 7 11368 41 6 11516 41 6 12032 41 6 12145 41 6
+ 12145 41 6 12990 34 5 13104 34 5 13949 34 5 13949 34 5 13949 34 5
+ 13949 34 5 13949 34 5 14556 28 4 14708 28 4 15315 28 4 15315 28 4
+ 15315 28 4 15315 28 4 18085 15 3 18091 15 3 18163 15 3 18397 15 3
+ 18403 15 3 18403 15 3 18549 15 3 18796 15 3 18796 15 3 18796 15 3
+ 18796 15 3 18796 15 3 18796 15 3 20194 7 2 20478 7 2 20796 7 2
+ 20866 7 2 20882 7 2 21105 7 2 21105 7 2 21105 7 2 22488 1 1
+ 22526 1 1 22756 1 1 22800 1 1 23155 1 1 23155 1 1}
+
+do_execsql_test 5.2.3.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( PARTITION BY coalesce(a, '')
+ RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW )
+ ORDER BY 1 , 2 , 3
+} {667 158 0 671 250 6 759 158 5 768 113 4 777 113 4 777 113 4
+ 777 113 4 777 252 4 792 247 12 805 250 6 805 250 6 805 250 6
+ 805 250 6 805 250 6 805 398 6 822 158 5 822 158 5 822 158 5
+ 822 158 5 822 346 5 839 113 8 840 247 12 840 247 12 840 247 12
+ 840 247 12 840 247 12 840 247 12 840 247 12 840 247 12 840 247 12
+ 840 247 12 840 247 12 840 393 12 845 224 6 870 102 10 870 158 0
+ 870 158 0 870 158 0 870 158 0 870 355 0 899 113 8 899 113 8
+ 899 113 8 899 113 8 899 113 8 899 113 8 899 113 8 899 234 8
+ 911 223 7 929 148 7 934 223 7 934 223 7 934 223 7 934 223 7
+ 934 223 7 934 223 7 934 239 7 938 102 10 938 102 10 938 102 10
+ 938 102 10 938 102 10 938 102 10 938 102 10 938 102 10 938 102 10
+ 938 148 7 938 148 7 938 148 7 938 148 7 938 148 7 938 148 7
+ 938 160 7 938 208 10 959 224 6 959 224 6 959 224 6 959 224 6
+ 959 224 6 959 238 6 963 133 8 979 133 8 979 133 8 979 133 8
+ 979 133 8 979 133 8 979 133 8 979 133 8 979 330 8}
+
+do_execsql_test 5.2.3.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( PARTITION BY coalesce(a, '')
+ RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW )
+ ORDER BY 1 , 2 , 3
+} {295 1 1 335 1 1 607 1 1 667 1 1 742 1 1 759 1 1 845 1 1
+ 890 1 1 929 1 1 959 1 1 962 1 1 962 1 1 962 1 1 962 1 1
+ 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 1264 1 1 1264 1 1
+ 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1366 1 1 1366 1 1 1366 1 1
+ 1366 1 1 1383 1 1 1398 1 1 1406 1 1 1421 1 1 1519 1 1 1519 1 1
+ 1535 1 1 1651 1 1 1669 1 1 1682 1 1 1695 1 1 1804 1 1 1804 1 1
+ 1804 1 1 1804 1 1 1804 1 1 1897 1 1 1919 1 1 2000 1 1 2048 1 1
+ 2050 1 1 2050 1 1 2070 1 1 2086 1 1 2108 1 1 2108 1 1 2134 1 1
+ 2150 1 1 2309 1 1 2309 1 1 2309 1 1 2340 1 1 2340 1 1 2340 1 1
+ 2430 1 1 2690 1 1 2758 1 1 2770 1 1 2776 1 1 2834 1 1 2848 1 1
+ 2947 1 1 2947 1 1 2947 1 1 2947 1 1 2980 1 1 3082 1 1 3088 1 1
+ 3088 1 1 3113 1 1 3113 1 1 3113 1 1 3113 1 1 3234 1 1 3481 1 1
+ 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1}
+
+do_execsql_test 5.2.4.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY a GROUPS 6 PRECEDING EXCLUDE CURRENT ROW )
+ ORDER BY 1 , 2 , 3
+} {667 158 0 870 158 0 870 158 0 870 158 0 870 158 0 870 355 0
+ 911 158 7 934 158 7 934 158 7 934 158 7 934 158 7 934 158 7
+ 934 158 7 934 158 7 934 158 20 934 158 20 934 158 20 934 158 20
+ 934 158 20 934 158 20 934 158 20 934 158 20 934 158 20 934 158 20
+ 934 158 20 934 158 20 934 158 20 934 158 26 934 158 26 934 158 26
+ 934 158 26 934 158 26 934 158 26 934 158 33 959 102 49 959 102 49
+ 959 102 49 959 102 49 959 102 49 959 102 49 959 102 49 959 102 49
+ 959 102 49 959 102 49 959 102 57 959 102 57 959 102 57 959 102 57
+ 959 102 57 959 102 57 959 102 57 959 102 57 959 113 38 959 113 38
+ 959 113 38 959 113 38 959 113 49 959 158 33 959 158 33 959 158 33
+ 959 158 33 959 158 33 959 158 33 959 158 38 963 102 58 979 102 52
+ 979 102 52 979 102 52 979 102 52 979 102 52 979 102 52 979 102 52
+ 979 102 55 979 102 55 979 102 55 979 102 55 979 102 55 979 102 55
+ 979 102 55 979 102 55 979 102 55 979 102 58 979 102 58 979 102 58
+ 979 102 58 979 102 58 979 102 58 979 102 58 979 102 58}
+
+do_execsql_test 5.2.4.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY a GROUPS 6 PRECEDING EXCLUDE CURRENT ROW )
+ ORDER BY 1 , 2 , 3
+} {1383 1 1 1421 1 1 1651 1 1 1695 1 1 2050 1 1 2050 1 1 3448 7 2
+ 3732 7 2 4050 7 2 4120 7 2 4136 7 2 4359 7 2 4359 7 2 4359 7 2
+ 7129 15 3 7135 15 3 7207 15 3 7441 15 3 7447 15 3 7447 15 3
+ 7593 15 3 7840 15 3 7840 15 3 7840 15 3 7840 15 3 7840 15 3
+ 7840 15 3 8447 28 4 8599 28 4 9206 28 4 9206 28 4 9206 28 4
+ 9206 28 4 10051 34 5 10165 34 5 11010 34 5 11010 34 5 11010 34 5
+ 11010 34 5 11010 34 5 11563 74 10 11697 74 10 11752 41 6
+ 11776 57 8 11900 41 6 11925 74 10 11947 74 10 12368 74 10
+ 12368 74 10 12368 74 10 12370 57 8 12416 41 6 12529 41 6
+ 12529 41 6 12530 65 9 12546 65 9 12705 57 8 12705 57 8 12705 57 8
+ 12705 57 8 12705 57 8 12705 57 8 12824 46 7 12826 65 9
+ 13050 81 11 13110 81 11 13110 81 11 13154 65 9 13196 46 7
+ 13376 65 9 13491 46 7 13491 46 7 13491 46 7 13491 46 7 13491 46 7
+ 13491 46 7 13491 46 7 13491 46 7 13491 46 7 13509 65 9 13509 65 9
+ 13509 65 9 13509 65 9 13692 81 11 13836 81 11 13949 81 11
+ 13949 81 11 13949 81 11 13949 81 11}
+
+do_execsql_test 5.2.5.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY c RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE CURRENT ROW )
+ ORDER BY 1 , 2 , 3
+} {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 113 113 1
+ 113 113 1 158 158 1 160 158 1 160 158 2 223 223 1 224 224 1
+ 238 234 2 239 234 2 239 238 2 252 250 2 256 252 2 257 247 4
+ 257 247 4 257 250 3 335 330 2 336 330 2 336 335 2 355 354 1
+ 355 354 2 355 355 1 399 393 3 399 393 3 399 393 3 399 393 3
+ 399 393 4 480 480 1 480 480 1 572 572 1 574 574 1 618 618 1
+ 618 618 1 633 629 2 634 627 3 634 627 3 634 627 4 634 629 3
+ 667 667 1 670 667 2 671 667 2 671 667 2 671 667 3 711 711 1
+ 711 711 1 716 705 2 726 726 1 730 730 1 762 762 1 768 759 3
+ 768 762 2 768 762 2 792 790 2 792 790 2 794 786 3 794 786 3
+ 844 839 4 845 839 4 845 839 4 845 839 4 845 839 4 870 870 1
+ 870 870 1 870 870 2 934 934 1 938 929 3 938 934 2 938 934 2
+ 959 959 1 963 963 1}
+
+do_execsql_test 5.2.5.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY c RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE CURRENT ROW )
+ ORDER BY 1 , 2 , 3
+} {{} 1 1 {} 4 3 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 10 8
+ {} 14 12 {} 15 13 {} 19 17 {} 20 18 {} 21 19 {} 23 21 {} 25 23
+ {} 34 29 {} 35 30 {} 36 31 {} 37 32 {} 38 33 {} 38 33 {} 40 34
+ {} 41 35 {} 42 36 {} 43 37 {} 43 37 {} 50 42 {} 56 47 {} 60 51
+ {} 61 52 {} 62 53 {} 64 55 {} 64 55 {} 66 56 {} 67 57 {} 68 58
+ {} 69 59 {} 70 60 {} 71 61 {} 72 62 {} 78 67 {} 78 67 {} 78 67
+ {} 81 68 {} 82 69 {} 83 70 {} 85 72 {} 85 72 {} 89 75 113 2 2
+ 113 2 2 223 11 9 239 12 10 239 13 11 257 18 16 335 22 20
+ 335 24 22 355 27 25 355 27 25 504 16 14 504 17 15 705 58 49
+ 710 26 24 711 57 48 711 59 50 759 63 54 929 84 71 959 88 74
+ 963 87 73 1185 32 28 1185 32 28 1191 29 26 1191 29 26 1334 51 43
+ 1334 55 46 1338 52 44 1338 52 44 1584 31 27 1678 77 66 1684 73 63
+ 1684 73 63 1885 48 40 1889 46 39 1889 46 39 1891 45 38 1891 49 41
+ 2005 54 45 2523 75 64 2523 76 65}
+
+do_execsql_test 5.2.6.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY c RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE CURRENT ROW )
+ ORDER BY 1 , 2 , 3
+} {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 113 113 1
+ 113 113 1 158 158 0 158 158 1 355 355 0 355 355 1 393 393 1
+ 393 393 1 399 399 0 399 399 1 480 480 1 480 480 1 618 618 1
+ 618 618 1 629 629 0 629 629 1 667 667 0 667 667 1 768 768 1
+ 768 768 1 839 839 1 839 839 1 870 870 1 870 870 1 870 870 2
+ 938 938 1 938 938 1}
+
+do_execsql_test 5.2.6.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY c RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE CURRENT ROW )
+ ORDER BY 1 , 2 , 3
+} {{} 1 1 {} 4 3 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 10 8
+ {} 11 9 {} 12 10 {} 13 11 {} 14 12 {} 15 13 {} 16 14 {} 17 15
+ {} 18 16 {} 19 17 {} 20 18 {} 21 19 {} 22 20 {} 23 21 {} 24 22
+ {} 25 23 {} 26 24 {} 31 27 {} 34 29 {} 35 30 {} 36 31 {} 37 32
+ {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 42 36 {} 43 37 {} 43 37
+ {} 45 38 {} 48 40 {} 49 41 {} 50 42 {} 51 43 {} 54 45 {} 55 46
+ {} 56 47 {} 57 48 {} 58 49 {} 59 50 {} 60 51 {} 61 52 {} 62 53
+ {} 63 54 {} 64 55 {} 64 55 {} 66 56 {} 67 57 {} 68 58 {} 69 59
+ {} 70 60 {} 71 61 {} 72 62 {} 75 64 {} 76 65 {} 77 66 {} 78 67
+ {} 78 67 {} 78 67 {} 81 68 {} 82 69 {} 83 70 {} 84 71 {} 85 72
+ {} 85 72 {} 87 73 {} 88 74 {} 89 75 113 2 2 113 2 2 355 27 25
+ 355 27 25 393 29 26 393 29 26 399 32 28 399 32 28 629 46 39
+ 629 46 39 667 52 44 667 52 44 839 73 63 839 73 63}
+
+do_execsql_test 5.2.7.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY c , b , a
+ ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW )
+ ORDER BY 1 , 2 , 3
+} {963 929 6 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82
+ 979 102 83 979 113 80 979 113 81 979 113 82 979 133 79 979 148 78
+ 979 158 76 979 158 77 979 160 76 979 208 75 979 223 74 979 224 73
+ 979 234 72 979 238 71 979 239 70 979 247 69 979 250 68 979 252 67
+ 979 256 66 979 257 65 979 295 64 979 309 64 979 330 62 979 335 61
+ 979 336 60 979 346 59 979 354 59 979 355 57 979 355 57 979 393 55
+ 979 393 56 979 398 54 979 399 53 979 399 53 979 412 52 979 421 51
+ 979 430 50 979 443 49 979 480 47 979 480 48 979 572 47 979 574 45
+ 979 607 44 979 618 42 979 618 43 979 627 41 979 629 40 979 629 41
+ 979 633 39 979 634 38 979 652 37 979 660 36 979 667 35 979 667 35
+ 979 670 34 979 671 33 979 683 32 979 705 31 979 711 30 979 716 29
+ 979 726 28 979 730 27 979 759 26 979 762 25 979 768 23 979 768 24
+ 979 777 22 979 786 21 979 790 20 979 792 19 979 794 18 979 805 17
+ 979 822 17 979 839 14 979 839 15 979 840 13 979 844 12 979 845 11
+ 979 870 9 979 870 10 979 870 10 979 899 8 979 911 7}
+
+do_execsql_test 5.2.7.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY c , b , a
+ ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW )
+ ORDER BY 1 , 2 , 3
+} {2851 89 89 3778 88 88 4681 87 87 5556 83 83 5574 82 82 5586 81 81
+ 5640 84 84 5640 85 85 5640 86 86 7324 80 80 8123 77 77 8129 73 73
+ 8129 74 74 8163 78 78 8163 79 79 8940 71 71 8968 75 75 8968 76 76
+ 9727 66 66 9745 69 69 9745 70 70 9745 72 72 10504 65 65
+ 10504 67 67 10504 68 68 11215 64 64 11844 62 62 11920 63 63
+ 13274 60 60 13274 61 61 13897 58 58 13903 57 57 13925 56 56
+ 13937 55 55 13941 59 59 15203 53 53 15241 54 54 15832 52 52
+ 17100 48 48 17104 46 46 17104 47 47 17106 45 45 17126 49 49
+ 17126 50 50 17126 51 51 17569 42 42 17733 44 44 18176 43 43
+ 18597 40 40 18597 41 41 18952 37 37 18996 39 39 19395 38 38
+ 19760 35 35 19788 36 36 20492 32 32 20492 33 33 20498 30 30
+ 20536 34 34 20833 29 29 20871 28 28 20891 31 31 21180 27 27
+ 21752 23 23 21830 26 26 22025 21 21 22087 22 22 22087 24 24
+ 22087 25 25 22278 20 20 22316 19 19 22549 15 15 22557 14 14
+ 22573 17 17 22573 18 18 22706 10 10 22796 11 11 22796 12 12
+ 22796 13 13 22796 16 16 23022 4 4 23042 2 2 23042 3 3 23042 9 9
+ 23155 1 1 23155 5 5 23155 6 6 23155 7 7 23155 8 8}
+
+do_execsql_test 5.3.1.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP )
+ ORDER BY 1 , 2 , 3
+} {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0}
+
+do_execsql_test 5.3.1.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP )
+ ORDER BY 1 , 2 , 3
+} {{} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1}
+
+do_execsql_test 5.3.2.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY a
+ RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP )
+ ORDER BY 1 , 2 , 3
+} {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 899 113 9 899 113 9 899 113 9 899 113 9
+ 899 113 9 899 113 9 899 113 9 899 113 16 899 113 16 899 113 16
+ 899 113 16 899 113 16 899 113 16 899 113 16 899 113 16 899 113 16
+ 979 102 44 979 102 44 979 102 44 979 102 44 979 102 44 979 102 49
+ 979 102 49 979 102 49 979 102 49 979 102 49 979 102 49 979 102 49
+ 979 102 56 979 102 56 979 102 56 979 102 56 979 102 56 979 102 56
+ 979 102 62 979 102 62 979 102 62 979 102 62 979 102 62 979 102 62
+ 979 102 62 979 102 62 979 102 62 979 102 62 979 102 62 979 102 62
+ 979 102 62 979 102 75 979 102 75 979 102 75 979 102 75 979 102 75
+ 979 102 75 979 102 75 979 102 75 979 102 83 979 102 83 979 102 83
+ 979 102 83 979 102 83 979 102 83 979 113 25 979 113 25 979 113 25
+ 979 113 25 979 113 25 979 113 25 979 113 25 979 113 25 979 113 33
+ 979 113 33 979 113 33 979 113 33 979 113 33 979 113 33 979 113 33
+ 979 113 33 979 113 33 979 113 33 979 113 33}
+
+do_execsql_test 5.3.2.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY a
+ RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP )
+ ORDER BY 1 , 2 , 3
+} {{} 81 11 {} 81 11 {} 81 11 {} 81 11 {} 81 11 {} 81 11 {} 81 11
+ {} 81 11 {} 81 11 2947 74 10 2947 74 10 2947 74 10 2947 74 10
+ 2947 74 10 2947 74 10 2947 74 10 5287 65 9 5287 65 9 5287 65 9
+ 5287 65 9 5287 65 9 5287 65 9 5287 65 9 5287 65 9 5287 65 9
+ 8400 57 8 8400 57 8 8400 57 8 8400 57 8 8400 57 8 8400 57 8
+ 8400 57 8 8400 57 8 9664 46 7 9664 46 7 9664 46 7 9664 46 7
+ 9664 46 7 9664 46 7 9664 46 7 9664 46 7 9664 46 7 9664 46 7
+ 9664 46 7 10626 41 6 10626 41 6 10626 41 6 10626 41 6 10626 41 6
+ 12145 34 5 12145 34 5 12145 34 5 12145 34 5 12145 34 5 12145 34 5
+ 12145 34 5 13949 28 4 13949 28 4 13949 28 4 13949 28 4 13949 28 4
+ 13949 28 4 15315 15 3 15315 15 3 15315 15 3 15315 15 3 15315 15 3
+ 15315 15 3 15315 15 3 15315 15 3 15315 15 3 15315 15 3 15315 15 3
+ 15315 15 3 15315 15 3 18796 7 2 18796 7 2 18796 7 2 18796 7 2
+ 18796 7 2 18796 7 2 18796 7 2 18796 7 2 21105 1 1 21105 1 1
+ 21105 1 1 21105 1 1 21105 1 1 21105 1 1}
+
+do_execsql_test 5.3.3.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( PARTITION BY coalesce(a, '')
+ RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP )
+ ORDER BY 1 , 2 , 3
+} {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0}
+
+do_execsql_test 5.3.3.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( PARTITION BY coalesce(a, '')
+ RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP )
+ ORDER BY 1 , 2 , 3
+} {{} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1}
+
+do_execsql_test 5.3.4.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY a GROUPS 6 PRECEDING EXCLUDE GROUP )
+ ORDER BY 1 , 2 , 3
+} {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 870 158 0
+ 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0
+ 870 158 0 934 158 8 934 158 8 934 158 8 934 158 8 934 158 8
+ 934 158 8 934 158 8 934 158 8 934 158 8 934 158 8 934 158 8
+ 934 158 8 934 158 8 934 158 21 934 158 21 934 158 21 934 158 21
+ 934 158 21 934 158 21 934 158 27 934 158 27 934 158 27 934 158 27
+ 934 158 27 934 158 27 934 158 27 959 102 50 959 102 50 959 102 50
+ 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50
+ 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50
+ 959 102 50 959 102 50 959 113 39 959 113 39 959 113 39 959 113 39
+ 959 113 39 959 113 39 959 113 39 959 113 39 959 113 39 959 113 39
+ 959 113 39 959 158 34 959 158 34 959 158 34 959 158 34 959 158 34
+ 979 102 46 979 102 46 979 102 46 979 102 46 979 102 46 979 102 46
+ 979 102 46 979 102 47 979 102 47 979 102 47 979 102 47 979 102 47
+ 979 102 47 979 102 47 979 102 47 979 102 47}
+
+do_execsql_test 5.3.4.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY a GROUPS 6 PRECEDING EXCLUDE GROUP )
+ ORDER BY 1 , 2 , 3
+} {{} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 2050 7 2 2050 7 2
+ 2050 7 2 2050 7 2 2050 7 2 2050 7 2 2050 7 2 2050 7 2 4359 15 3
+ 4359 15 3 4359 15 3 4359 15 3 4359 15 3 4359 15 3 4359 15 3
+ 4359 15 3 4359 15 3 4359 15 3 4359 15 3 4359 15 3 4359 15 3
+ 7840 28 4 7840 28 4 7840 28 4 7840 28 4 7840 28 4 7840 28 4
+ 9206 34 5 9206 34 5 9206 34 5 9206 34 5 9206 34 5 9206 34 5
+ 9206 34 5 10028 74 10 10028 74 10 10028 74 10 10028 74 10
+ 10028 74 10 10028 74 10 10028 74 10 10396 65 9 10396 65 9
+ 10396 65 9 10396 65 9 10396 65 9 10396 65 9 10396 65 9 10396 65 9
+ 10396 65 9 11002 81 11 11002 81 11 11002 81 11 11002 81 11
+ 11002 81 11 11002 81 11 11002 81 11 11002 81 11 11002 81 11
+ 11010 41 6 11010 41 6 11010 41 6 11010 41 6 11010 41 6 11441 57 8
+ 11441 57 8 11441 57 8 11441 57 8 11441 57 8 11441 57 8 11441 57 8
+ 11441 57 8 12529 46 7 12529 46 7 12529 46 7 12529 46 7 12529 46 7
+ 12529 46 7 12529 46 7 12529 46 7 12529 46 7 12529 46 7 12529 46 7}
+
+do_execsql_test 5.3.5.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY c RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE GROUP )
+ ORDER BY 1 , 2 , 3
+} {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 158 158 1 160 160 1 160 160 1 223 223 1 224 224 1
+ 238 234 2 239 234 2 239 238 2 252 250 2 256 252 2 257 247 4
+ 257 247 4 257 250 3 335 330 2 336 330 2 336 335 2 354 354 1
+ 354 354 1 355 355 1 398 393 3 398 393 3 399 393 3 399 398 2
+ 399 398 2 572 572 1 574 574 1 633 629 2 634 627 3 634 627 3
+ 634 627 3 634 629 3 667 667 1 670 667 2 671 667 2 671 670 2
+ 671 670 2 711 711 1 711 711 1 716 705 2 726 726 1 730 730 1
+ 762 762 1 762 762 1 762 762 1 768 759 3 792 790 2 792 790 2
+ 794 786 3 794 786 3 844 839 4 845 839 4 845 839 4 845 840 3
+ 845 840 3 934 934 1 934 934 1 934 934 1 938 929 3 959 959 1
+ 963 963 1}
+
+do_execsql_test 5.3.5.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY c RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE GROUP )
+ ORDER BY 1 , 2 , 3
+} {{} 1 1 {} 2 2 {} 2 2 {} 4 3 {} 5 4 {} 6 5 {} 6 5 {} 8 6
+ {} 9 7 {} 10 8 {} 14 12 {} 15 13 {} 19 17 {} 20 18 {} 21 19
+ {} 23 21 {} 25 23 {} 27 25 {} 27 25 {} 34 29 {} 35 30 {} 36 31
+ {} 37 32 {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 42 36 {} 43 37
+ {} 43 37 {} 50 42 {} 56 47 {} 60 51 {} 61 52 {} 62 53 {} 64 55
+ {} 64 55 {} 66 56 {} 67 57 {} 68 58 {} 69 59 {} 70 60 {} 71 61
+ {} 72 62 {} 78 67 {} 78 67 {} 78 67 {} 81 68 {} 82 69 {} 83 70
+ {} 85 72 {} 85 72 {} 89 75 223 11 9 239 12 10 239 13 11
+ 257 18 16 335 22 20 335 24 22 504 16 14 504 17 15 671 52 44
+ 671 52 44 705 58 49 710 26 24 711 57 48 711 59 50 759 63 54
+ 786 32 28 786 32 28 798 29 26 798 29 26 845 73 63 845 73 63
+ 929 84 71 959 88 74 963 87 73 1260 46 39 1260 46 39 1334 51 43
+ 1334 55 46 1584 31 27 1678 77 66 1885 48 40 1891 45 38 1891 49 41
+ 2005 54 45 2523 75 64 2523 76 65}
+
+do_execsql_test 5.3.6.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY c RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE GROUP )
+ ORDER BY 1 , 2 , 3
+} {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0
+ {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0}
+
+do_execsql_test 5.3.6.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY c RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE GROUP )
+ ORDER BY 1 , 2 , 3
+} {{} 1 1 {} 2 2 {} 2 2 {} 4 3 {} 5 4 {} 6 5 {} 6 5 {} 8 6
+ {} 9 7 {} 10 8 {} 11 9 {} 12 10 {} 13 11 {} 14 12 {} 15 13
+ {} 16 14 {} 17 15 {} 18 16 {} 19 17 {} 20 18 {} 21 19 {} 22 20
+ {} 23 21 {} 24 22 {} 25 23 {} 26 24 {} 27 25 {} 27 25 {} 29 26
+ {} 29 26 {} 31 27 {} 32 28 {} 32 28 {} 34 29 {} 35 30 {} 36 31
+ {} 37 32 {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 42 36 {} 43 37
+ {} 43 37 {} 45 38 {} 46 39 {} 46 39 {} 48 40 {} 49 41 {} 50 42
+ {} 51 43 {} 52 44 {} 52 44 {} 54 45 {} 55 46 {} 56 47 {} 57 48
+ {} 58 49 {} 59 50 {} 60 51 {} 61 52 {} 62 53 {} 63 54 {} 64 55
+ {} 64 55 {} 66 56 {} 67 57 {} 68 58 {} 69 59 {} 70 60 {} 71 61
+ {} 72 62 {} 73 63 {} 73 63 {} 75 64 {} 76 65 {} 77 66 {} 78 67
+ {} 78 67 {} 78 67 {} 81 68 {} 82 69 {} 83 70 {} 84 71 {} 85 72
+ {} 85 72 {} 87 73 {} 88 74 {} 89 75}
+
+do_execsql_test 5.3.7.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY c , b , a
+ ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE GROUP )
+ ORDER BY 1 , 2 , 3
+} {963 929 6 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82
+ 979 102 83 979 113 80 979 113 81 979 113 82 979 133 79 979 148 78
+ 979 158 76 979 158 77 979 160 76 979 208 75 979 223 74 979 224 73
+ 979 234 72 979 238 71 979 239 70 979 247 69 979 250 68 979 252 67
+ 979 256 66 979 257 65 979 295 64 979 309 64 979 330 62 979 335 61
+ 979 336 60 979 346 59 979 354 59 979 355 57 979 355 57 979 393 55
+ 979 393 56 979 398 54 979 399 53 979 399 53 979 412 52 979 421 51
+ 979 430 50 979 443 49 979 480 47 979 480 48 979 572 47 979 574 45
+ 979 607 44 979 618 42 979 618 43 979 627 41 979 629 40 979 629 41
+ 979 633 39 979 634 38 979 652 37 979 660 36 979 667 35 979 667 35
+ 979 670 34 979 671 33 979 683 32 979 705 31 979 711 30 979 716 29
+ 979 726 28 979 730 27 979 759 26 979 762 25 979 768 23 979 768 24
+ 979 777 22 979 786 21 979 790 20 979 792 19 979 794 18 979 805 17
+ 979 822 17 979 839 14 979 839 15 979 840 13 979 844 12 979 845 11
+ 979 870 9 979 870 10 979 870 10 979 899 8 979 911 7}
+
+do_execsql_test 5.3.7.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY c , b , a
+ ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE GROUP )
+ ORDER BY 1 , 2 , 3
+} {2851 89 89 3778 88 88 4681 87 87 5556 83 83 5574 82 82 5586 81 81
+ 5640 84 84 5640 85 85 5640 86 86 7324 80 80 8123 77 77 8129 73 73
+ 8129 74 74 8163 78 78 8163 79 79 8940 71 71 8968 75 75 8968 76 76
+ 9727 66 66 9745 69 69 9745 70 70 9745 72 72 10504 65 65
+ 10504 67 67 10504 68 68 11215 64 64 11844 62 62 11920 63 63
+ 13274 60 60 13274 61 61 13897 58 58 13903 57 57 13925 56 56
+ 13937 55 55 13941 59 59 15203 53 53 15241 54 54 15832 52 52
+ 17100 48 48 17104 46 46 17104 47 47 17106 45 45 17126 49 49
+ 17126 50 50 17126 51 51 17569 42 42 17733 44 44 18176 43 43
+ 18597 40 40 18597 41 41 18952 37 37 18996 39 39 19395 38 38
+ 19760 35 35 19788 36 36 20492 32 32 20492 33 33 20498 30 30
+ 20536 34 34 20833 29 29 20871 28 28 20891 31 31 21180 27 27
+ 21752 23 23 21830 26 26 22025 21 21 22087 22 22 22087 24 24
+ 22087 25 25 22278 20 20 22316 19 19 22549 15 15 22557 14 14
+ 22573 17 17 22573 18 18 22706 10 10 22796 11 11 22796 12 12
+ 22796 13 13 22796 16 16 23022 4 4 23042 2 2 23042 3 3 23042 9 9
+ 23155 1 1 23155 5 5 23155 6 6 23155 7 7 23155 8 8}
+
+do_execsql_test 5.4.1.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES )
+ ORDER BY 1 , 2 , 3
+} {102 102 1 113 113 1 113 113 1 133 133 1 148 148 1 158 158 0
+ 158 158 1 160 160 1 208 208 1 223 223 1 224 224 1 234 234 1
+ 238 238 1 239 239 1 247 247 1 250 250 1 252 252 1 256 256 1
+ 257 257 1 295 295 1 309 309 1 330 330 1 335 335 1 336 336 1
+ 346 346 1 354 354 1 355 355 0 355 355 1 393 393 1 393 393 1
+ 398 398 1 399 399 0 399 399 1 412 412 1 421 421 1 430 430 1
+ 443 443 1 480 480 1 480 480 1 572 572 1 574 574 1 607 607 1
+ 618 618 1 618 618 1 627 627 1 629 629 0 629 629 1 633 633 1
+ 634 634 1 652 652 1 660 660 1 667 667 0 667 667 1 670 670 1
+ 671 671 1 683 683 1 705 705 1 711 711 1 716 716 1 726 726 1
+ 730 730 1 759 759 1 762 762 1 768 768 1 768 768 1 777 777 1
+ 786 786 1 790 790 1 792 792 1 794 794 1 805 805 1 822 822 1
+ 839 839 1 839 839 1 840 840 1 844 844 1 845 845 1 870 870 0
+ 870 870 1 870 870 1 899 899 1 911 911 1 929 929 1 934 934 1
+ 938 938 1 938 938 1 959 959 1 963 963 1 979 979 1}
+
+do_execsql_test 5.4.1.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES )
+ ORDER BY 1 , 2 , 3
+} {{} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ 113 1 1 113 1 1 133 1 1 223 1 1 239 1 1 247 1 1 257 1 1
+ 295 1 1 309 1 1 335 1 1 355 1 1 355 1 1 393 1 1 393 1 1
+ 399 1 1 399 1 1 421 1 1 443 1 1 607 1 1 627 1 1 629 1 1
+ 629 1 1 633 1 1 667 1 1 667 1 1 671 1 1 683 1 1 705 1 1
+ 711 1 1 759 1 1 777 1 1 805 1 1 839 1 1 839 1 1 845 1 1
+ 899 1 1 911 1 1 929 1 1 959 1 1 963 1 1 979 1 1}
+
+do_execsql_test 5.4.2.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY a
+ RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES )
+ ORDER BY 1 , 2 , 3
+} {113 113 1 234 234 1 257 257 1 336 336 1 354 354 1 768 768 1
+ 839 839 1 839 839 1 899 113 10 899 113 10 899 113 10 899 113 10
+ 899 113 10 899 113 10 899 113 10 899 113 17 899 113 17 899 113 17
+ 899 113 17 899 113 17 899 113 17 899 113 17 899 899 1 963 113 17
+ 979 102 34 979 102 45 979 102 45 979 102 45 979 102 45 979 102 45
+ 979 102 50 979 102 50 979 102 50 979 102 50 979 102 50 979 102 50
+ 979 102 50 979 102 57 979 102 57 979 102 57 979 102 57 979 102 57
+ 979 102 57 979 102 63 979 102 63 979 102 63 979 102 63 979 102 63
+ 979 102 63 979 102 63 979 102 63 979 102 63 979 102 63 979 102 63
+ 979 102 63 979 102 63 979 102 76 979 102 76 979 102 76 979 102 76
+ 979 102 76 979 102 76 979 102 76 979 102 76 979 102 83 979 102 83
+ 979 102 83 979 102 83 979 102 83 979 102 83 979 113 17 979 113 26
+ 979 113 26 979 113 26 979 113 26 979 113 26 979 113 26 979 113 26
+ 979 113 26 979 113 34 979 113 34 979 113 34 979 113 34 979 113 34
+ 979 113 34 979 113 34 979 113 34 979 113 34 979 113 34}
+
+do_execsql_test 5.4.2.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY a
+ RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES )
+ ORDER BY 1 , 2 , 3
+} {{} 81 11 {} 81 11 {} 81 11 {} 81 11 113 81 11 257 81 11
+ 839 81 11 839 81 11 899 81 11 2947 74 10 2947 74 10 2947 74 10
+ 3368 74 10 3390 74 10 3618 74 10 3752 74 10 5287 65 9 5287 65 9
+ 5287 65 9 5287 65 9 5420 65 9 5642 65 9 5970 65 9 6250 65 9
+ 6266 65 9 8400 57 8 8400 57 8 8400 57 8 8400 57 8 8400 57 8
+ 8400 57 8 8735 57 8 9329 57 8 9664 46 7 9664 46 7 9664 46 7
+ 9664 46 7 9664 46 7 9664 46 7 9664 46 7 9664 46 7 9664 46 7
+ 9959 46 7 10331 46 7 10626 41 6 10626 41 6 10739 41 6 11255 41 6
+ 11403 41 6 12145 34 5 12145 34 5 12145 34 5 12145 34 5 12145 34 5
+ 12990 34 5 13104 34 5 13949 28 4 13949 28 4 13949 28 4 13949 28 4
+ 14556 28 4 14708 28 4 15315 15 3 15315 15 3 15315 15 3 15315 15 3
+ 15315 15 3 15315 15 3 15562 15 3 15708 15 3 15708 15 3 15714 15 3
+ 15948 15 3 16020 15 3 16026 15 3 18796 7 2 18796 7 2 18796 7 2
+ 19019 7 2 19035 7 2 19105 7 2 19423 7 2 19707 7 2 21105 1 1
+ 21105 1 1 21460 1 1 21504 1 1 21734 1 1 21772 1 1}
+
+do_execsql_test 5.4.3.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( PARTITION BY coalesce(a, '')
+ RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES )
+ ORDER BY 1 , 2 , 3
+} {102 102 1 113 113 1 113 113 1 133 133 1 148 148 1 158 158 0
+ 158 158 1 160 160 1 208 208 1 223 223 1 224 224 1 234 234 1
+ 238 238 1 239 239 1 247 247 1 250 250 1 252 252 1 256 256 1
+ 257 257 1 295 295 1 309 309 1 330 330 1 335 335 1 336 336 1
+ 346 346 1 354 354 1 355 355 0 355 355 1 393 393 1 393 393 1
+ 398 398 1 399 399 0 399 399 1 412 412 1 421 421 1 430 430 1
+ 443 443 1 480 480 1 480 480 1 572 572 1 574 574 1 607 607 1
+ 618 618 1 618 618 1 627 627 1 629 629 0 629 629 1 633 633 1
+ 634 634 1 652 652 1 660 660 1 667 667 0 667 667 1 670 670 1
+ 671 671 1 683 683 1 705 705 1 711 711 1 716 716 1 726 726 1
+ 730 730 1 759 759 1 762 762 1 768 768 1 768 768 1 777 777 1
+ 786 786 1 790 790 1 792 792 1 794 794 1 805 805 1 822 822 1
+ 839 839 1 839 839 1 840 840 1 844 844 1 845 845 1 870 870 0
+ 870 870 1 870 870 1 899 899 1 911 911 1 929 929 1 934 934 1
+ 938 938 1 938 938 1 959 959 1 963 963 1 979 979 1}
+
+do_execsql_test 5.4.3.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( PARTITION BY coalesce(a, '')
+ RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES )
+ ORDER BY 1 , 2 , 3
+} {{} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1
+ 113 1 1 113 1 1 133 1 1 223 1 1 239 1 1 247 1 1 257 1 1
+ 295 1 1 309 1 1 335 1 1 355 1 1 355 1 1 393 1 1 393 1 1
+ 399 1 1 399 1 1 421 1 1 443 1 1 607 1 1 627 1 1 629 1 1
+ 629 1 1 633 1 1 667 1 1 667 1 1 671 1 1 683 1 1 705 1 1
+ 711 1 1 759 1 1 777 1 1 805 1 1 839 1 1 839 1 1 845 1 1
+ 899 1 1 911 1 1 929 1 1 959 1 1 963 1 1 979 1 1}
+
+do_execsql_test 5.4.4.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY a GROUPS 6 PRECEDING EXCLUDE TIES )
+ ORDER BY 1 , 2 , 3
+} {158 158 0 355 355 0 399 399 0 629 629 0 667 667 0 870 158 1
+ 870 158 1 870 158 1 870 158 1 870 158 1 870 158 1 870 870 0
+ 911 158 1 934 158 1 934 158 9 934 158 9 934 158 9 934 158 9
+ 934 158 9 934 158 9 934 158 9 934 158 9 934 158 9 934 158 9
+ 934 158 9 934 158 9 934 158 9 934 158 22 934 158 22 934 158 22
+ 934 158 22 934 158 22 934 158 22 934 158 28 934 158 28 934 158 28
+ 934 158 28 934 158 28 934 158 28 959 102 40 959 102 51 959 102 51
+ 959 102 51 959 102 51 959 102 51 959 102 51 959 102 51 959 102 51
+ 959 102 51 959 102 51 959 102 51 959 102 51 959 102 51 959 102 51
+ 959 102 51 959 113 35 959 113 40 959 113 40 959 113 40 959 113 40
+ 959 113 40 959 113 40 959 113 40 959 113 40 959 113 40 959 113 40
+ 959 158 28 959 158 35 959 158 35 959 158 35 959 158 35 963 102 51
+ 979 102 47 979 102 47 979 102 47 979 102 47 979 102 47 979 102 47
+ 979 102 47 979 102 48 979 102 48 979 102 48 979 102 48 979 102 48
+ 979 102 48 979 102 48 979 102 48 979 102 48 979 102 51}
+
+do_execsql_test 5.4.4.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY a GROUPS 6 PRECEDING EXCLUDE TIES )
+ ORDER BY 1 , 2 , 3
+} {{} 1 1 {} 1 1 355 1 1 399 1 1 629 1 1 667 1 1 2050 7 2
+ 2050 7 2 2050 7 2 2273 7 2 2289 7 2 2359 7 2 2677 7 2 2961 7 2
+ 4359 15 3 4359 15 3 4359 15 3 4359 15 3 4359 15 3 4359 15 3
+ 4606 15 3 4752 15 3 4752 15 3 4758 15 3 4992 15 3 5064 15 3
+ 5070 15 3 7840 28 4 7840 28 4 7840 28 4 7840 28 4 8447 28 4
+ 8599 28 4 9206 34 5 9206 34 5 9206 34 5 9206 34 5 9206 34 5
+ 10028 74 10 10028 74 10 10028 74 10 10051 34 5 10165 34 5
+ 10396 65 9 10396 65 9 10396 65 9 10396 65 9 10449 74 10
+ 10471 74 10 10529 65 9 10699 74 10 10751 65 9 10833 74 10
+ 11002 81 11 11002 81 11 11002 81 11 11002 81 11 11010 41 6
+ 11010 41 6 11079 65 9 11115 81 11 11123 41 6 11259 81 11
+ 11359 65 9 11375 65 9 11441 57 8 11441 57 8 11441 57 8 11441 57 8
+ 11441 57 8 11441 57 8 11639 41 6 11776 57 8 11787 41 6
+ 11841 81 11 11841 81 11 11901 81 11 12370 57 8 12529 46 7
+ 12529 46 7 12529 46 7 12529 46 7 12529 46 7 12529 46 7 12529 46 7
+ 12529 46 7 12529 46 7 12824 46 7 13196 46 7}
+
+do_execsql_test 5.4.5.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY c RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE TIES )
+ ORDER BY 1 , 2 , 3
+} {102 102 1 113 113 1 113 113 1 133 133 1 148 148 1 160 158 1
+ 160 158 2 160 158 2 208 208 1 224 223 2 224 223 2 239 234 3
+ 239 234 3 239 234 3 252 247 3 257 247 5 257 247 5 257 250 4
+ 257 252 3 295 295 1 309 309 1 336 330 3 336 330 3 336 330 3
+ 346 346 1 355 354 1 355 354 2 355 354 2 399 393 3 399 393 3
+ 399 393 3 399 393 4 399 393 4 412 412 1 421 421 1 430 430 1
+ 443 443 1 480 480 1 480 480 1 574 572 2 574 572 2 607 607 1
+ 618 618 1 618 618 1 634 627 3 634 627 4 634 627 4 634 627 4
+ 634 629 3 652 652 1 667 660 2 671 667 2 671 667 3 671 667 3
+ 671 667 3 683 683 1 711 705 2 716 705 3 716 711 2 730 726 2
+ 730 726 2 762 759 2 768 759 4 768 762 2 768 762 2 777 777 1
+ 792 786 3 794 786 4 794 786 4 794 790 3 805 805 1 822 822 1
+ 845 839 4 845 839 4 845 839 5 845 839 5 845 839 5 870 870 0
+ 870 870 1 870 870 1 899 899 1 911 911 1 934 929 2 938 929 4
+ 938 934 2 938 934 2 963 959 2 963 959 2 979 979 1}
+
+do_execsql_test 5.4.5.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY c RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE TIES )
+ ORDER BY 1 , 2 , 3
+} {{} 1 1 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 25 23 {} 34 29
+ {} 36 31 {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 43 37 {} 43 37
+ {} 50 42 {} 60 51 {} 61 52 {} 64 55 {} 64 55 {} 67 57 {} 68 58
+ {} 69 59 {} 70 60 {} 72 62 {} 78 67 {} 78 67 {} 78 67 {} 85 72
+ {} 85 72 113 2 2 113 2 2 133 4 3 223 10 8 223 11 9 239 12 10
+ 239 13 11 239 14 12 247 15 13 257 18 16 257 19 17 295 20 18
+ 309 21 19 335 22 20 335 23 21 335 24 22 355 27 25 355 27 25
+ 421 35 30 443 37 32 504 16 14 504 17 15 607 42 36 683 56 47
+ 710 26 24 711 59 50 759 62 53 759 63 54 777 66 56 805 71 61
+ 899 81 68 911 82 69 929 83 70 929 84 71 979 89 75 1185 32 28
+ 1185 32 28 1191 29 26 1191 29 26 1334 51 43 1338 52 44 1338 52 44
+ 1416 57 48 1416 58 49 1584 31 27 1684 73 63 1684 73 63 1889 46 39
+ 1889 46 39 1891 49 41 1922 87 73 1922 88 74 2005 54 45 2005 55 46
+ 2518 45 38 2518 48 40 2523 75 64 2523 76 65 2523 77 66}
+
+do_execsql_test 5.4.6.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY c RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE TIES )
+ ORDER BY 1 , 2 , 3
+} {102 102 1 113 113 1 113 113 1 133 133 1 148 148 1 158 158 0
+ 158 158 1 160 160 1 208 208 1 223 223 1 224 224 1 234 234 1
+ 238 238 1 239 239 1 247 247 1 250 250 1 252 252 1 256 256 1
+ 257 257 1 295 295 1 309 309 1 330 330 1 335 335 1 336 336 1
+ 346 346 1 354 354 1 355 355 0 355 355 1 393 393 1 393 393 1
+ 398 398 1 399 399 0 399 399 1 412 412 1 421 421 1 430 430 1
+ 443 443 1 480 480 1 480 480 1 572 572 1 574 574 1 607 607 1
+ 618 618 1 618 618 1 627 627 1 629 629 0 629 629 1 633 633 1
+ 634 634 1 652 652 1 660 660 1 667 667 0 667 667 1 670 670 1
+ 671 671 1 683 683 1 705 705 1 711 711 1 716 716 1 726 726 1
+ 730 730 1 759 759 1 762 762 1 768 768 1 768 768 1 777 777 1
+ 786 786 1 790 790 1 792 792 1 794 794 1 805 805 1 822 822 1
+ 839 839 1 839 839 1 840 840 1 844 844 1 845 845 1 870 870 0
+ 870 870 1 870 870 1 899 899 1 911 911 1 929 929 1 934 934 1
+ 938 938 1 938 938 1 959 959 1 963 963 1 979 979 1}
+
+do_execsql_test 5.4.6.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY c RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE TIES )
+ ORDER BY 1 , 2 , 3
+} {{} 1 1 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 11 9 {} 12 10
+ {} 13 11 {} 16 14 {} 17 15 {} 18 16 {} 22 20 {} 24 22 {} 25 23
+ {} 26 24 {} 31 27 {} 34 29 {} 36 31 {} 38 33 {} 38 33 {} 40 34
+ {} 41 35 {} 43 37 {} 43 37 {} 49 41 {} 50 42 {} 51 43 {} 54 45
+ {} 59 50 {} 60 51 {} 61 52 {} 63 54 {} 64 55 {} 64 55 {} 67 57
+ {} 68 58 {} 69 59 {} 70 60 {} 72 62 {} 75 64 {} 76 65 {} 78 67
+ {} 78 67 {} 78 67 {} 84 71 {} 85 72 {} 85 72 113 2 2 113 2 2
+ 133 4 3 223 10 8 239 14 12 247 15 13 257 19 17 295 20 18
+ 309 21 19 335 23 21 355 27 25 355 27 25 393 29 26 393 29 26
+ 399 32 28 399 32 28 421 35 30 443 37 32 607 42 36 627 45 38
+ 629 46 39 629 46 39 633 48 40 667 52 44 667 52 44 671 55 46
+ 683 56 47 705 57 48 711 58 49 759 62 53 777 66 56 805 71 61
+ 839 73 63 839 73 63 845 77 66 899 81 68 911 82 69 929 83 70
+ 959 87 73 963 88 74 979 89 75}
+
+do_execsql_test 5.4.7.1 {
+ SELECT max(c) OVER win,
+ min(c) OVER win,
+ count(a) OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY c , b , a
+ ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE TIES )
+ ORDER BY 1 , 2 , 3
+} {979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83
+ 979 102 83 979 113 81 979 113 82 979 133 80 979 148 79 979 158 77
+ 979 158 78 979 160 77 979 208 76 979 223 75 979 224 74 979 234 73
+ 979 238 72 979 239 71 979 247 70 979 250 69 979 252 68 979 256 67
+ 979 257 66 979 295 65 979 309 64 979 330 63 979 335 62 979 336 61
+ 979 346 60 979 354 59 979 355 58 979 355 58 979 393 56 979 393 57
+ 979 398 55 979 399 54 979 399 54 979 412 53 979 421 52 979 430 51
+ 979 443 50 979 480 48 979 480 49 979 572 47 979 574 46 979 607 45
+ 979 618 43 979 618 44 979 627 42 979 629 41 979 629 41 979 633 40
+ 979 634 39 979 652 38 979 660 37 979 667 36 979 667 36 979 670 35
+ 979 671 34 979 683 33 979 705 32 979 711 31 979 716 30 979 726 29
+ 979 730 28 979 759 27 979 762 26 979 768 24 979 768 25 979 777 23
+ 979 786 22 979 790 21 979 792 20 979 794 19 979 805 18 979 822 17
+ 979 839 15 979 839 16 979 840 14 979 844 13 979 845 12 979 870 10
+ 979 870 11 979 870 11 979 899 9 979 911 8 979 929 7}
+
+do_execsql_test 5.4.7.2 {
+ SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win,
+ rank() OVER win,
+ dense_rank() OVER win
+ FROM t3
+ WINDOW win AS ( ORDER BY c , b , a
+ ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE TIES )
+ ORDER BY 1 , 2 , 3
+} {3830 89 89 4741 88 88 5640 84 84 5640 85 85 5640 86 86 5640 87 87
+ 6485 81 81 6485 82 82 6485 83 83 7324 80 80 8163 78 78 8163 79 79
+ 8968 73 73 8968 74 74 8968 75 75 8968 76 76 8968 77 77 9745 69 69
+ 9745 70 70 9745 71 71 9745 72 72 10504 65 65 10504 66 66
+ 10504 67 67 10504 68 68 11215 64 64 11920 63 63 12603 62 62
+ 13274 60 60 13274 61 61 13941 59 59 14608 55 55 14608 56 56
+ 14608 57 57 14608 58 58 15241 54 54 15870 53 53 16499 52 52
+ 17126 49 49 17126 50 50 17126 51 51 17733 44 44 17733 45 45
+ 17733 46 46 17733 47 47 17733 48 48 18176 42 42 18176 43 43
+ 18597 40 40 18597 41 41 18996 39 39 19395 37 37 19395 38 38
+ 19788 36 36 20181 35 35 20536 34 34 20891 30 30 20891 31 31
+ 20891 32 32 20891 33 33 21226 28 28 21226 29 29 21535 27 27
+ 21830 26 26 22087 22 22 22087 23 23 22087 24 24 22087 25 25
+ 22334 21 21 22573 17 17 22573 18 18 22573 19 19 22573 20 20
+ 22796 11 11 22796 12 12 22796 13 13 22796 14 14 22796 15 15
+ 22796 16 16 22929 10 10 23042 9 9 23155 1 1 23155 2 2 23155 3 3
+ 23155 4 4 23155 5 5 23155 6 6 23155 7 7 23155 8 8}
+
+finish_test
ADDED test/windowerr.tcl
Index: test/windowerr.tcl
==================================================================
--- /dev/null
+++ test/windowerr.tcl
@@ -0,0 +1,69 @@
+# 2018 May 19
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+#
+
+source [file join [file dirname $argv0] pg_common.tcl]
+
+#=========================================================================
+
+start_test windowerr "2019 March 01"
+ifcapable !windowfunc
+
+execsql_test 1.0 {
+ DROP TABLE IF EXISTS t1;
+ CREATE TABLE t1(a INTEGER, b INTEGER);
+ INSERT INTO t1 VALUES(1, 1);
+ INSERT INTO t1 VALUES(2, 2);
+ INSERT INTO t1 VALUES(3, 3);
+ INSERT INTO t1 VALUES(4, 4);
+ INSERT INTO t1 VALUES(5, 5);
+}
+
+foreach {tn frame} {
+ 1 "ORDER BY a ROWS BETWEEN -1 PRECEDING AND 1 FOLLOWING"
+ 2 "ORDER BY a ROWS BETWEEN 1 PRECEDING AND -1 FOLLOWING"
+
+ 3 "ORDER BY a RANGE BETWEEN -1 PRECEDING AND 1 FOLLOWING"
+ 4 "ORDER BY a RANGE BETWEEN 1 PRECEDING AND -1 FOLLOWING"
+
+ 5 "ORDER BY a GROUPS BETWEEN -1 PRECEDING AND 1 FOLLOWING"
+ 6 "ORDER BY a GROUPS BETWEEN 1 PRECEDING AND -1 FOLLOWING"
+
+ 7 "ORDER BY a,b RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING"
+
+ 8 "PARTITION BY a RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING"
+} {
+ errorsql_test 1.$tn "
+ SELECT a, sum(b) OVER (
+ $frame
+ ) FROM t1 ORDER BY 1
+ "
+}
+errorsql_test 2.1 {
+ SELECT sum( sum(a) OVER () ) FROM t1;
+}
+
+errorsql_test 2.2 {
+ SELECT sum(a) OVER () AS xyz FROM t1 ORDER BY sum(xyz);
+}
+
+errorsql_test 3.0 {
+ SELECT sum(a) OVER win FROM t1
+ WINDOW win AS (ROWS BETWEEN 'hello' PRECEDING AND 10 FOLLOWING)
+}
+errorsql_test 3.2 {
+ SELECT sum(a) OVER win FROM t1
+ WINDOW win AS (ROWS BETWEEN 10 PRECEDING AND x'ABCD' FOLLOWING)
+}
+
+
+finish_test
+
ADDED test/windowerr.test
Index: test/windowerr.test
==================================================================
--- /dev/null
+++ test/windowerr.test
@@ -0,0 +1,111 @@
+# 2019 March 01
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+# This file implements regression tests for SQLite library.
+#
+
+####################################################
+# DO NOT EDIT! THIS FILE IS AUTOMATICALLY GENERATED!
+####################################################
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set testprefix windowerr
+
+ifcapable !windowfunc { finish_test ; return }
+do_execsql_test 1.0 {
+ DROP TABLE IF EXISTS t1;
+ CREATE TABLE t1(a INTEGER, b INTEGER);
+ INSERT INTO t1 VALUES(1, 1);
+ INSERT INTO t1 VALUES(2, 2);
+ INSERT INTO t1 VALUES(3, 3);
+ INSERT INTO t1 VALUES(4, 4);
+ INSERT INTO t1 VALUES(5, 5);
+} {}
+
+# PG says ERROR: frame starting offset must not be negative
+do_test 1.1 { catch { execsql {
+ SELECT a, sum(b) OVER (
+ ORDER BY a ROWS BETWEEN -1 PRECEDING AND 1 FOLLOWING
+ ) FROM t1 ORDER BY 1
+} } } 1
+
+# PG says ERROR: frame ending offset must not be negative
+do_test 1.2 { catch { execsql {
+ SELECT a, sum(b) OVER (
+ ORDER BY a ROWS BETWEEN 1 PRECEDING AND -1 FOLLOWING
+ ) FROM t1 ORDER BY 1
+} } } 1
+
+# PG says ERROR: invalid preceding or following size in window function
+do_test 1.3 { catch { execsql {
+ SELECT a, sum(b) OVER (
+ ORDER BY a RANGE BETWEEN -1 PRECEDING AND 1 FOLLOWING
+ ) FROM t1 ORDER BY 1
+} } } 1
+
+# PG says ERROR: invalid preceding or following size in window function
+do_test 1.4 { catch { execsql {
+ SELECT a, sum(b) OVER (
+ ORDER BY a RANGE BETWEEN 1 PRECEDING AND -1 FOLLOWING
+ ) FROM t1 ORDER BY 1
+} } } 1
+
+# PG says ERROR: frame starting offset must not be negative
+do_test 1.5 { catch { execsql {
+ SELECT a, sum(b) OVER (
+ ORDER BY a GROUPS BETWEEN -1 PRECEDING AND 1 FOLLOWING
+ ) FROM t1 ORDER BY 1
+} } } 1
+
+# PG says ERROR: frame ending offset must not be negative
+do_test 1.6 { catch { execsql {
+ SELECT a, sum(b) OVER (
+ ORDER BY a GROUPS BETWEEN 1 PRECEDING AND -1 FOLLOWING
+ ) FROM t1 ORDER BY 1
+} } } 1
+
+# PG says ERROR: RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column
+do_test 1.7 { catch { execsql {
+ SELECT a, sum(b) OVER (
+ ORDER BY a,b RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING
+ ) FROM t1 ORDER BY 1
+} } } 1
+
+# PG says ERROR: RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column
+do_test 1.8 { catch { execsql {
+ SELECT a, sum(b) OVER (
+ PARTITION BY a RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING
+ ) FROM t1 ORDER BY 1
+} } } 1
+
+# PG says ERROR: aggregate function calls cannot contain window function calls
+do_test 2.1 { catch { execsql {
+ SELECT sum( sum(a) OVER () ) FROM t1;
+} } } 1
+
+# PG says ERROR: column "xyz" does not exist
+do_test 2.2 { catch { execsql {
+ SELECT sum(a) OVER () AS xyz FROM t1 ORDER BY sum(xyz);
+} } } 1
+
+# PG says ERROR: invalid input syntax for integer: "hello"
+do_test 3.0 { catch { execsql {
+ SELECT sum(a) OVER win FROM t1
+ WINDOW win AS (ROWS BETWEEN 'hello' PRECEDING AND 10 FOLLOWING)
+} } } 1
+
+# PG says ERROR: argument of ROWS must be type bigint, not type bit
+do_test 3.2 { catch { execsql {
+ SELECT sum(a) OVER win FROM t1
+ WINDOW win AS (ROWS BETWEEN 10 PRECEDING AND x'ABCD' FOLLOWING)
+} } } 1
+
+finish_test
Index: test/windowfault.test
==================================================================
--- test/windowfault.test
+++ test/windowfault.test
@@ -26,11 +26,11 @@
INSERT INTO t1 VALUES(5, 6, 7, 8);
INSERT INTO t1 VALUES(9, 10, 11, 12);
}
faultsim_save_and_close
-do_faultsim_test 1 -start 1 -faults oom-* -prep {
+do_faultsim_test 1 -start 1 -faults oom-t* -prep {
faultsim_restore_and_reopen
} -body {
execsql {
SELECT row_number() OVER win,
rank() OVER win,
@@ -159,7 +159,68 @@
ORDER BY a;
}
} -test {
faultsim_test_result {0 {1 2 5 6 9 10}}
}
+
+#-------------------------------------------------------------------------
+# The following test causes a cursor in REQURESEEK state to be passed
+# to sqlite3BtreeDelete(). An error is simulated within the seek operation
+# to restore the cursors position.
+#
+reset_db
+set big [string repeat x 900]
+do_execsql_test 9.0 {
+ PRAGMA page_size = 512;
+ PRAGMA cache_size = 2;
+ CREATE TABLE t(x INTEGER PRIMARY KEY, y TEXT);
+ WITH s(i) AS (
+ VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<1900
+ )
+ INSERT INTO t(y) SELECT $big FROM s;
+}
+db close
+
+testvfs tvfs -default 1
+tvfs script vfs_callback
+tvfs filter xRead
+
+sqlite3 db test.db
+proc vfs_callback {method file args} {
+ if {$file=="" && [info exists ::tmp_read_fail]} {
+ incr ::tmp_read_fail -1
+ if {$::tmp_read_fail<=0} {
+ return "SQLITE_IOERR"
+ }
+ }
+ return "SQLITE_OK"
+}
+
+set FAULTSIM(tmpread) [list \
+ -injectstart tmpread_injectstart \
+ -injectstop tmpread_injectstop \
+ -injecterrlist {{1 {disk I/O error}}} \
+]
+proc tmpread_injectstart {iFail} {
+ set ::tmp_read_fail $iFail
+}
+proc tmpread_injectstop {} {
+ set ret [expr $::tmp_read_fail<=0]
+ unset -nocomplain ::tmp_read_fail
+ return $ret
+}
+
+do_faultsim_test 9 -end 25 -faults tmpread -body {
+ execsql {
+ SELECT sum(y) OVER win FROM t
+ WINDOW win AS (
+ ORDER BY x ROWS BETWEEN UNBOUNDED PRECEDING AND 1800 FOLLOWING
+ )
+ }
+} -test {
+ faultsim_test_result {0 {}}
+}
+
+catch {db close}
+tvfs delete
finish_test
Index: tool/dbtotxt.c
==================================================================
--- tool/dbtotxt.c
+++ tool/dbtotxt.c
@@ -49,11 +49,11 @@
unsigned char aLine[16]; /* A single line of the file */
unsigned char aHdr[100]; /* File header */
unsigned char bShow[256]; /* Characters ok to display */
memset(bShow, '.', sizeof(bShow));
for(i=' '; i<='~'; i++){
- if( i!='{' && i!='}' && i!='"' && i!='\\' ) bShow[i] = i;
+ if( i!='{' && i!='}' && i!='"' && i!='\\' ) bShow[i] = (unsigned char)i;
}
for(i=1; i |