1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Improved TreeView display of Window objects.

Change the Window.eType field to Window.eFrmType to avoid confusion with
other "eType" values.

FossilOrigin-Name: ec2f207dedb223077bbd3e4584499250eb12219712c917e930acccfa2c46e23b
This commit is contained in:
drh
2019-03-28 13:03:41 +00:00
parent a2b6806b3e
commit fc15f4c528
5 changed files with 77 additions and 37 deletions

View File

@@ -1,5 +1,5 @@
C If\sthe\sstring\sformatter\sin\ssqlite3NestedParse()\sfails\sdue\sto\san\sover-length\nstring,\smake\ssure\sthis\serror\sis\srecorded\sby\sthe\sparser\sso\sthat\sit\sknows\sto\nfail. C Improved\sTreeView\sdisplay\sof\sWindow\sobjects.\nChange\sthe\sWindow.eType\sfield\sto\sWindow.eFrmType\sto\savoid\sconfusion\swith\nother\s"eType"\svalues.
D 2019-03-28T04:03:17.931 D 2019-03-28T13:03:41.454
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -521,7 +521,7 @@ F src/shell.c.in c1986496062f9dba4ed5b70db06b5e0f32e1954cdcfab0b30372c6c18679681
F src/sqlite.h.in f765fce74038607388d3a96cd7fad892f363bdcde24911565edf610ecf69534c F src/sqlite.h.in f765fce74038607388d3a96cd7fad892f363bdcde24911565edf610ecf69534c
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 960f1b86c3610fa23cb6a267572a97dcf286e77aa0dd3b9b23292ffaa1ea8683 F src/sqlite3ext.h 960f1b86c3610fa23cb6a267572a97dcf286e77aa0dd3b9b23292ffaa1ea8683
F src/sqliteInt.h 19641f2402ef4e45fd2e222f5a45bb24e3f89a519059d35ce2819f46ce5e1a1e F src/sqliteInt.h 773a43d21001311853e2e213f693ed5ac64c5ec2cf4c7fc492715421f244454f
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -580,7 +580,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c d3615f0cbe4db5949503bf5916f3cd4fa5de855d5b4ef560f3b6dd5629423a1e F src/tokenize.c d3615f0cbe4db5949503bf5916f3cd4fa5de855d5b4ef560f3b6dd5629423a1e
F src/treeview.c c6ff90da4cc1813ff2d9bb11f17d4d927db62c47e552faa1835edc47269d753d F src/treeview.c f41d6a62ff054277e068829859b0f6259fb6a9ebda2e87aa3a83b01f4cb3cc0b
F src/trigger.c bb034c08eca111e66a19cda045903a12547c1be2294b5570d794b869d9c44a73 F src/trigger.c bb034c08eca111e66a19cda045903a12547c1be2294b5570d794b869d9c44a73
F src/update.c 0b973357d88092140531e07ff641139c26fb4380b0b9f5ed98c5f7691b4604d1 F src/update.c 0b973357d88092140531e07ff641139c26fb4380b0b9f5ed98c5f7691b4604d1
F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4
@@ -605,7 +605,7 @@ F src/where.c 8a207cb2ca6b99e1edb1e4bbff9b0504385a759cbf66180d1deb34d80ca4b799
F src/whereInt.h 5f14db426ca46a83eabab1ae9aa6d4b8f27504ad35b64c290916289b1ddb2e88 F src/whereInt.h 5f14db426ca46a83eabab1ae9aa6d4b8f27504ad35b64c290916289b1ddb2e88
F src/wherecode.c 6fa4056c5ce019e4a8af33795906340176813cb3c1236f4b7b08df76a1b6287b F src/wherecode.c 6fa4056c5ce019e4a8af33795906340176813cb3c1236f4b7b08df76a1b6287b
F src/whereexpr.c 90859652920f153d2c03f075488744be2926625ebd36911bcbcb17d0d29c891c F src/whereexpr.c 90859652920f153d2c03f075488744be2926625ebd36911bcbcb17d0d29c891c
F src/window.c 2e3fdb046dfe32a0a30855b952152ea8f1cb5cffdccb2b9d6845ca1f3a4d3bdc F src/window.c 92b6d593a63f27b29360176f71eb5839562bdb7dae6effd35f4c69168ea5455d
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
@@ -1813,7 +1813,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P bbdbaf84a52937ccf877072a8b01b07f7b9c037c59ba54df72ca888d5404cbad P 85e53ff13300132250221de769a2aa7d92d81bb48d60f6e99000bc69a5b1e6fb
R a8b4e886cb7335563acdda9aaece2736 R 955959731aaddc58f4bc71017ffeeb76
U drh U drh
Z 5908e55b684ef19b846738ab0396e51d Z fae16977b4563395e6e67b312131bb19

View File

@@ -1 +1 @@
85e53ff13300132250221de769a2aa7d92d81bb48d60f6e99000bc69a5b1e6fb ec2f207dedb223077bbd3e4584499250eb12219712c917e930acccfa2c46e23b

View File

@@ -3535,7 +3535,7 @@ struct TreeView {
#endif /* SQLITE_DEBUG */ #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 ** (1) A single instance of this structure is attached to the
** the Expr.pWin field for each window function in an expression tree. ** the Expr.pWin field for each window function in an expression tree.
@@ -3550,18 +3550,18 @@ struct TreeView {
** object on a linked list attached to Select.pWinDefn. ** object on a linked list attached to Select.pWinDefn.
** **
** The uses (1) and (2) are really the same Window object that just happens ** 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 { struct Window {
char *zName; /* Name of window (may be NULL) */ char *zName; /* Name of window (may be NULL) */
char *zBase; /* Name of base window for chaining (may be NULL) */ char *zBase; /* Name of base window for chaining (may be NULL) */
ExprList *pPartition; /* PARTITION BY clause */ ExprList *pPartition; /* PARTITION BY clause */
ExprList *pOrderBy; /* ORDER 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 eStart; /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */
u8 eEnd; /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */ u8 eEnd; /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */
u8 bImplicitFrame; /* True if frame was implicitly specified */ u8 bImplicitFrame; /* True if frame was implicitly specified */
u8 eExclude; u8 eExclude; /* TK_NO, TK_CURRENT, TK_TIES, TK_GROUP, or 0 */
Expr *pStart; /* Expression for "<expr> PRECEDING" */ Expr *pStart; /* Expression for "<expr> PRECEDING" */
Expr *pEnd; /* Expression for "<expr> FOLLOWING" */ Expr *pEnd; /* Expression for "<expr> FOLLOWING" */
Window *pNextWin; /* Next window function belonging to this SELECT */ Window *pNextWin; /* Next window function belonging to this SELECT */

View File

@@ -309,24 +309,60 @@ void sqlite3TreeViewBound(
** Generate a human-readable explanation for a Window object ** Generate a human-readable explanation for a Window object
*/ */
void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){
int nElement = 0;
pView = sqlite3TreeViewPush(pView, more); pView = sqlite3TreeViewPush(pView, more);
if( pWin->zName ){ if( pWin->zName ){
sqlite3TreeViewLine(pView, "OVER %s", pWin->zName); sqlite3TreeViewLine(pView, "OVER %s", pWin->zName);
}else{ }else{
sqlite3TreeViewLine(pView, "OVER"); sqlite3TreeViewLine(pView, "OVER");
} }
if( pWin->pFilter ) nElement++;
if( pWin->zBase ) nElement++;
if( pWin->pOrderBy ) nElement++;
if( pWin->eFrmType ) nElement++;
if( pWin->eExclude ) nElement++;
if( pWin->pFilter ){
sqlite3TreeViewItem(pView, "FILTER", (--nElement)>0);
sqlite3TreeViewExpr(pView, pWin->pFilter, 0);
sqlite3TreeViewPop(pView);
}
if( pWin->zBase ){
sqlite3TreeViewPush(pView, (--nElement)>0);
sqlite3TreeViewLine(pView, "window: %s", pWin->zBase);
sqlite3TreeViewPop(pView);
}
if( pWin->pPartition ){ if( pWin->pPartition ){
sqlite3TreeViewExprList(pView, pWin->pPartition, 1, "PARTITION-BY"); sqlite3TreeViewExprList(pView, pWin->pPartition, nElement>0,"PARTITION-BY");
} }
if( pWin->pOrderBy ){ if( pWin->pOrderBy ){
sqlite3TreeViewExprList(pView, pWin->pOrderBy, 1, "ORDER-BY"); sqlite3TreeViewExprList(pView, pWin->pOrderBy, (--nElement)>0, "ORDER-BY");
} }
if( pWin->eType ){ if( pWin->eFrmType ){
sqlite3TreeViewItem(pView, pWin->eType==TK_RANGE ? "RANGE" : "ROWS", 0); const char *zFrmType = "ROWS";
if( pWin->eFrmType==TK_RANGE ) zFrmType = "RANGE";
if( pWin->eFrmType==TK_GROUPS ) zFrmType = "GROUPS";
sqlite3TreeViewItem(pView, zFrmType, (--nElement)>0);
sqlite3TreeViewBound(pView, pWin->eStart, pWin->pStart, 1); sqlite3TreeViewBound(pView, pWin->eStart, pWin->pStart, 1);
sqlite3TreeViewBound(pView, pWin->eEnd, pWin->pEnd, 0); sqlite3TreeViewBound(pView, pWin->eEnd, pWin->pEnd, 0);
sqlite3TreeViewPop(pView); 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); sqlite3TreeViewPop(pView);
} }
#endif /* SQLITE_OMIT_WINDOWFUNC */ #endif /* SQLITE_OMIT_WINDOWFUNC */

View File

@@ -662,7 +662,7 @@ void sqlite3WindowUpdate(
Window *pWin, /* Window frame to update */ Window *pWin, /* Window frame to update */
FuncDef *pFunc /* Window function definition */ FuncDef *pFunc /* Window function definition */
){ ){
if( pWin->zName && pWin->eType==0 ){ if( pWin->zName && pWin->eFrmType==0 ){
Window *p = windowFind(pParse, pList, pWin->zName); Window *p = windowFind(pParse, pList, pWin->zName);
if( p==0 ) return; if( p==0 ) return;
pWin->pPartition = sqlite3ExprListDup(pParse->db, p->pPartition, 0); pWin->pPartition = sqlite3ExprListDup(pParse->db, p->pPartition, 0);
@@ -671,12 +671,12 @@ void sqlite3WindowUpdate(
pWin->pEnd = sqlite3ExprDup(pParse->db, p->pEnd, 0); pWin->pEnd = sqlite3ExprDup(pParse->db, p->pEnd, 0);
pWin->eStart = p->eStart; pWin->eStart = p->eStart;
pWin->eEnd = p->eEnd; pWin->eEnd = p->eEnd;
pWin->eType = p->eType; pWin->eFrmType = p->eFrmType;
pWin->eExclude = p->eExclude; pWin->eExclude = p->eExclude;
}else{ }else{
sqlite3WindowChain(pParse, pWin, pList); sqlite3WindowChain(pParse, pWin, pList);
} }
if( (pWin->eType==TK_RANGE) if( (pWin->eFrmType==TK_RANGE)
&& (pWin->pStart || pWin->pEnd) && (pWin->pStart || pWin->pEnd)
&& (pWin->pOrderBy==0 || pWin->pOrderBy->nExpr!=1) && (pWin->pOrderBy==0 || pWin->pOrderBy->nExpr!=1)
){ ){
@@ -693,7 +693,7 @@ void sqlite3WindowUpdate(
}else{ }else{
struct WindowUpdate { struct WindowUpdate {
const char *zFunc; const char *zFunc;
int eType; int eFrmType;
int eStart; int eStart;
int eEnd; int eEnd;
} aUp[] = { } aUp[] = {
@@ -712,7 +712,7 @@ void sqlite3WindowUpdate(
sqlite3ExprDelete(db, pWin->pStart); sqlite3ExprDelete(db, pWin->pStart);
sqlite3ExprDelete(db, pWin->pEnd); sqlite3ExprDelete(db, pWin->pEnd);
pWin->pEnd = pWin->pStart = 0; pWin->pEnd = pWin->pStart = 0;
pWin->eType = aUp[i].eType; pWin->eFrmType = aUp[i].eFrmType;
pWin->eStart = aUp[i].eStart; pWin->eStart = aUp[i].eStart;
pWin->eEnd = aUp[i].eEnd; pWin->eEnd = aUp[i].eEnd;
pWin->eExclude = 0; pWin->eExclude = 0;
@@ -1042,7 +1042,7 @@ static Expr *sqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){
*/ */
Window *sqlite3WindowAlloc( Window *sqlite3WindowAlloc(
Parse *pParse, /* Parsing context */ 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 */ int eStart, /* Start type: CURRENT, PRECEDING, FOLLOWING, UNBOUNDED */
Expr *pStart, /* Start window size if TK_PRECEDING or FOLLOWING */ Expr *pStart, /* Start window size if TK_PRECEDING or FOLLOWING */
int eEnd, /* End type: CURRENT, FOLLOWING, TK_UNBOUNDED, PRECEDING */ int eEnd, /* End type: CURRENT, FOLLOWING, TK_UNBOUNDED, PRECEDING */
@@ -1089,7 +1089,7 @@ Window *sqlite3WindowAlloc(
pWin = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); pWin = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
if( pWin==0 ) goto windowAllocErr; if( pWin==0 ) goto windowAllocErr;
pWin->eType = eType; pWin->eFrmType = eType;
pWin->eStart = eStart; pWin->eStart = eStart;
pWin->eEnd = eEnd; pWin->eEnd = eEnd;
if( eExclude==0 && OptimizationDisabled(pParse->db, SQLITE_QueryFlattener) ){ if( eExclude==0 && OptimizationDisabled(pParse->db, SQLITE_QueryFlattener) ){
@@ -1198,7 +1198,7 @@ void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
** Identical window objects can be processed in a single scan. ** Identical window objects can be processed in a single scan.
*/ */
int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2){ 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->eStart!=p2->eStart ) return 1;
if( p1->eEnd!=p2->eEnd ) return 1; if( p1->eEnd!=p2->eEnd ) return 1;
if( p1->eExclude!=p2->eExclude ) return 1; if( p1->eExclude!=p2->eExclude ) return 1;
@@ -1861,7 +1861,7 @@ static int windowCodeOp(
int addrIf = 0; int addrIf = 0;
int addrContinue = 0; int addrContinue = 0;
int addrGoto = 0; int addrGoto = 0;
int bPeer = (pMWin->eType!=TK_ROWS); int bPeer = (pMWin->eFrmType!=TK_ROWS);
int lblDone = sqlite3VdbeMakeLabel(pParse); int lblDone = sqlite3VdbeMakeLabel(pParse);
int addrNextRange = 0; int addrNextRange = 0;
@@ -1874,7 +1874,7 @@ static int windowCodeOp(
} }
if( regCountdown>0 ){ if( regCountdown>0 ){
if( pMWin->eType==TK_RANGE ){ if( pMWin->eFrmType==TK_RANGE ){
addrNextRange = sqlite3VdbeCurrentAddr(v); addrNextRange = sqlite3VdbeCurrentAddr(v);
assert( op==WINDOW_AGGINVERSE || op==WINDOW_AGGSTEP ); assert( op==WINDOW_AGGINVERSE || op==WINDOW_AGGSTEP );
if( op==WINDOW_AGGINVERSE ){ if( op==WINDOW_AGGINVERSE ){
@@ -1983,7 +1983,7 @@ Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
pNew->pFunc = p->pFunc; pNew->pFunc = p->pFunc;
pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0); pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0); pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
pNew->eType = p->eType; pNew->eFrmType = p->eFrmType;
pNew->eEnd = p->eEnd; pNew->eEnd = p->eEnd;
pNew->eStart = p->eStart; pNew->eStart = p->eStart;
pNew->eExclude = p->eExclude; pNew->eExclude = p->eExclude;
@@ -2427,14 +2427,18 @@ void sqlite3WindowCodeStep(
** be deleted after they enter the frame (WINDOW_AGGSTEP). */ ** be deleted after they enter the frame (WINDOW_AGGSTEP). */
switch( pMWin->eStart ){ switch( pMWin->eStart ){
case TK_FOLLOWING: case TK_FOLLOWING:
if( pMWin->eType!=TK_RANGE && windowExprGtZero(pParse, pMWin->pStart) ){ if( pMWin->eFrmType!=TK_RANGE
&& windowExprGtZero(pParse, pMWin->pStart)
){
s.eDelete = WINDOW_RETURN_ROW; s.eDelete = WINDOW_RETURN_ROW;
} }
break; break;
case TK_UNBOUNDED: case TK_UNBOUNDED:
if( windowCacheFrame(pMWin)==0 ){ if( windowCacheFrame(pMWin)==0 ){
if( pMWin->eEnd==TK_PRECEDING ){ if( pMWin->eEnd==TK_PRECEDING ){
if( pMWin->eType!=TK_RANGE && windowExprGtZero(pParse, pMWin->pEnd) ){ if( pMWin->eFrmType!=TK_RANGE
&& windowExprGtZero(pParse, pMWin->pEnd)
){
s.eDelete = WINDOW_AGGSTEP; s.eDelete = WINDOW_AGGSTEP;
} }
}else{ }else{
@@ -2468,7 +2472,7 @@ void sqlite3WindowCodeStep(
/* If this is not a "ROWS BETWEEN ..." frame, then allocate arrays of /* If this is not a "ROWS BETWEEN ..." frame, then allocate arrays of
** registers to store copies of the ORDER BY expressions (peer values) ** registers to store copies of the ORDER BY expressions (peer values)
** for the main loop, and for each cursor (start, current and end). */ ** for the main loop, and for each cursor (start, current and end). */
if( pMWin->eType!=TK_ROWS ){ if( pMWin->eFrmType!=TK_ROWS ){
int nPeer = (pOrderBy ? pOrderBy->nExpr : 0); int nPeer = (pOrderBy ? pOrderBy->nExpr : 0);
regNewPeer = regNew + pMWin->nBufferCol; regNewPeer = regNew + pMWin->nBufferCol;
if( pMWin->pPartition ) regNewPeer += pMWin->pPartition->nExpr; if( pMWin->pPartition ) regNewPeer += pMWin->pPartition->nExpr;
@@ -2519,11 +2523,11 @@ void sqlite3WindowCodeStep(
if( regStart ){ if( regStart ){
sqlite3ExprCode(pParse, pMWin->pStart, regStart); sqlite3ExprCode(pParse, pMWin->pStart, regStart);
windowCheckValue(pParse, regStart, 0 + (pMWin->eType==TK_RANGE ? 3 : 0)); windowCheckValue(pParse, regStart, 0 + (pMWin->eFrmType==TK_RANGE ? 3 : 0));
} }
if( regEnd ){ if( regEnd ){
sqlite3ExprCode(pParse, pMWin->pEnd, regEnd); sqlite3ExprCode(pParse, pMWin->pEnd, regEnd);
windowCheckValue(pParse, regEnd, 1 + (pMWin->eType==TK_RANGE ? 3 : 0)); windowCheckValue(pParse, regEnd, 1 + (pMWin->eFrmType==TK_RANGE ? 3 : 0));
} }
if( pMWin->eStart==pMWin->eEnd && regStart ){ if( pMWin->eStart==pMWin->eEnd && regStart ){
@@ -2538,7 +2542,7 @@ void sqlite3WindowCodeStep(
sqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd); sqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd);
sqlite3VdbeJumpHere(v, addrGe); sqlite3VdbeJumpHere(v, addrGe);
} }
if( pMWin->eStart==TK_FOLLOWING && pMWin->eType!=TK_RANGE && regEnd ){ if( pMWin->eStart==TK_FOLLOWING && pMWin->eFrmType!=TK_RANGE && regEnd ){
assert( pMWin->eEnd==TK_FOLLOWING ); assert( pMWin->eEnd==TK_FOLLOWING );
sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regStart); sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regStart);
} }
@@ -2567,7 +2571,7 @@ void sqlite3WindowCodeStep(
if( pMWin->eStart==TK_FOLLOWING ){ if( pMWin->eStart==TK_FOLLOWING ){
windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0); windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
if( pMWin->eEnd!=TK_UNBOUNDED ){ if( pMWin->eEnd!=TK_UNBOUNDED ){
if( pMWin->eType==TK_RANGE ){ if( pMWin->eFrmType==TK_RANGE ){
int lbl = sqlite3VdbeMakeLabel(pParse); int lbl = sqlite3VdbeMakeLabel(pParse);
int addrNext = sqlite3VdbeCurrentAddr(v); int addrNext = sqlite3VdbeCurrentAddr(v);
windowCodeRangeTest(&s, OP_Ge, s.current.csr, regEnd, s.end.csr, lbl); windowCodeRangeTest(&s, OP_Ge, s.current.csr, regEnd, s.end.csr, lbl);
@@ -2589,7 +2593,7 @@ void sqlite3WindowCodeStep(
int addr = 0; int addr = 0;
windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0); windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
if( pMWin->eEnd!=TK_UNBOUNDED ){ if( pMWin->eEnd!=TK_UNBOUNDED ){
if( pMWin->eType==TK_RANGE ){ if( pMWin->eFrmType==TK_RANGE ){
int lbl = 0; int lbl = 0;
addr = sqlite3VdbeCurrentAddr(v); addr = sqlite3VdbeCurrentAddr(v);
if( regEnd ){ if( regEnd ){
@@ -2635,7 +2639,7 @@ void sqlite3WindowCodeStep(
int addrBreak2; int addrBreak2;
int addrBreak3; int addrBreak3;
windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0); windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
if( pMWin->eType==TK_RANGE ){ if( pMWin->eFrmType==TK_RANGE ){
addrStart = sqlite3VdbeCurrentAddr(v); addrStart = sqlite3VdbeCurrentAddr(v);
addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 1); addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 1);
addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1); addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1);