]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Improved TreeView display of Window objects.
authordrh <drh@noemail.net>
Thu, 28 Mar 2019 13:03:41 +0000 (13:03 +0000)
committerdrh <drh@noemail.net>
Thu, 28 Mar 2019 13:03:41 +0000 (13:03 +0000)
Change the Window.eType field to Window.eFrmType to avoid confusion with
other "eType" values.

FossilOrigin-Name: ec2f207dedb223077bbd3e4584499250eb12219712c917e930acccfa2c46e23b

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

index af3eaf8f2636b25f9b6be584982a06d204c97653..2fc7b60fb8b71e9c83659fb49b2bfefe855b430f 100644 (file)
--- a/manifest
+++ b/manifest
@@ -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.
-D 2019-03-28T04:03:17.931
+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-28T13:03:41.454
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -521,7 +521,7 @@ F src/shell.c.in c1986496062f9dba4ed5b70db06b5e0f32e1954cdcfab0b30372c6c18679681
 F src/sqlite.h.in f765fce74038607388d3a96cd7fad892f363bdcde24911565edf610ecf69534c
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 960f1b86c3610fa23cb6a267572a97dcf286e77aa0dd3b9b23292ffaa1ea8683
-F src/sqliteInt.h 19641f2402ef4e45fd2e222f5a45bb24e3f89a519059d35ce2819f46ce5e1a1e
+F src/sqliteInt.h 773a43d21001311853e2e213f693ed5ac64c5ec2cf4c7fc492715421f244454f
 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
 F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -580,7 +580,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394
 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
 F src/tokenize.c d3615f0cbe4db5949503bf5916f3cd4fa5de855d5b4ef560f3b6dd5629423a1e
-F src/treeview.c c6ff90da4cc1813ff2d9bb11f17d4d927db62c47e552faa1835edc47269d753d
+F src/treeview.c f41d6a62ff054277e068829859b0f6259fb6a9ebda2e87aa3a83b01f4cb3cc0b
 F src/trigger.c bb034c08eca111e66a19cda045903a12547c1be2294b5570d794b869d9c44a73
 F src/update.c 0b973357d88092140531e07ff641139c26fb4380b0b9f5ed98c5f7691b4604d1
 F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4
@@ -605,7 +605,7 @@ F src/where.c 8a207cb2ca6b99e1edb1e4bbff9b0504385a759cbf66180d1deb34d80ca4b799
 F src/whereInt.h 5f14db426ca46a83eabab1ae9aa6d4b8f27504ad35b64c290916289b1ddb2e88
 F src/wherecode.c 6fa4056c5ce019e4a8af33795906340176813cb3c1236f4b7b08df76a1b6287b
 F src/whereexpr.c 90859652920f153d2c03f075488744be2926625ebd36911bcbcb17d0d29c891c
-F src/window.c 2e3fdb046dfe32a0a30855b952152ea8f1cb5cffdccb2b9d6845ca1f3a4d3bdc
+F src/window.c 92b6d593a63f27b29360176f71eb5839562bdb7dae6effd35f4c69168ea5455d
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
 F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
@@ -1813,7 +1813,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P bbdbaf84a52937ccf877072a8b01b07f7b9c037c59ba54df72ca888d5404cbad
-R a8b4e886cb7335563acdda9aaece2736
+P 85e53ff13300132250221de769a2aa7d92d81bb48d60f6e99000bc69a5b1e6fb
+R 955959731aaddc58f4bc71017ffeeb76
 U drh
-Z 5908e55b684ef19b846738ab0396e51d
+Z fae16977b4563395e6e67b312131bb19
index 5a275b656fecd5b5cdd85fbcdfe614d9eac9c939..70aa3fbe7e34e2c638c0b86452deee087d7269f1 100644 (file)
@@ -1 +1 @@
-85e53ff13300132250221de769a2aa7d92d81bb48d60f6e99000bc69a5b1e6fb
\ No newline at end of file
+ec2f207dedb223077bbd3e4584499250eb12219712c917e930acccfa2c46e23b
\ No newline at end of file
index 2fa1d1aa3d2233c554a213faafadd81c5a73f1e5..13f2339dadfee09ca7d452864632b5d7cdad4fd2 100644 (file)
@@ -3535,7 +3535,7 @@ struct TreeView {
 #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.
@@ -3550,18 +3550,18 @@ struct TreeView {
 **       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;
+  u8 eExclude;            /* TK_NO, TK_CURRENT, TK_TIES, TK_GROUP, or 0 */
   Expr *pStart;           /* Expression for "<expr> PRECEDING" */
   Expr *pEnd;             /* Expression for "<expr> FOLLOWING" */
   Window *pNextWin;       /* Next window function belonging to this SELECT */
index 743c3b1298541da0401801140008c40ea88e88af..490c2c3cb0d0e680d6c16560a8077a5beed673e1 100644 (file)
@@ -309,24 +309,60 @@ void sqlite3TreeViewBound(
 ** Generate a human-readable explanation for a Window object
 */
 void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){
+  int nElement = 0;
   pView = sqlite3TreeViewPush(pView, more);
   if( pWin->zName ){
     sqlite3TreeViewLine(pView, "OVER %s", pWin->zName);
   }else{
     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 ){
-    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 ){
+    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->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 */
index 38ae5792ab13101bc03159d9f04761f494892527..000a179c8339d7b8872f552dd5c7e5163ea0560a 100644 (file)
@@ -662,7 +662,7 @@ void sqlite3WindowUpdate(
   Window *pWin,                   /* Window frame to update */
   FuncDef *pFunc                  /* Window function definition */
 ){
-  if( pWin->zName && pWin->eType==0 ){
+  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);
@@ -671,12 +671,12 @@ void sqlite3WindowUpdate(
     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->eType==TK_RANGE)
+  if( (pWin->eFrmType==TK_RANGE)
    && (pWin->pStart || pWin->pEnd) 
    && (pWin->pOrderBy==0 || pWin->pOrderBy->nExpr!=1)
   ){
@@ -693,7 +693,7 @@ void sqlite3WindowUpdate(
     }else{
       struct WindowUpdate {
         const char *zFunc;
-        int eType;
+        int eFrmType;
         int eStart;
         int eEnd;
       } aUp[] = {
@@ -712,7 +712,7 @@ void sqlite3WindowUpdate(
           sqlite3ExprDelete(db, pWin->pStart);
           sqlite3ExprDelete(db, pWin->pEnd);
           pWin->pEnd = pWin->pStart = 0;
-          pWin->eType = aUp[i].eType;
+          pWin->eFrmType = aUp[i].eFrmType;
           pWin->eStart = aUp[i].eStart;
           pWin->eEnd = aUp[i].eEnd;
           pWin->eExclude = 0;
@@ -1042,7 +1042,7 @@ static Expr *sqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){
 */
 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 */
@@ -1089,7 +1089,7 @@ Window *sqlite3WindowAlloc(
 
   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) ){
@@ -1198,7 +1198,7 @@ void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
 ** 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;
@@ -1861,7 +1861,7 @@ static int windowCodeOp(
   int addrIf = 0; 
   int addrContinue = 0;
   int addrGoto = 0;
-  int bPeer = (pMWin->eType!=TK_ROWS);
+  int bPeer = (pMWin->eFrmType!=TK_ROWS);
 
   int lblDone = sqlite3VdbeMakeLabel(pParse);
   int addrNextRange = 0;
@@ -1874,7 +1874,7 @@ static int windowCodeOp(
   }
 
   if( regCountdown>0 ){
-    if( pMWin->eType==TK_RANGE ){
+    if( pMWin->eFrmType==TK_RANGE ){
       addrNextRange = sqlite3VdbeCurrentAddr(v);
       assert( op==WINDOW_AGGINVERSE || op==WINDOW_AGGSTEP );
       if( op==WINDOW_AGGINVERSE ){
@@ -1983,7 +1983,7 @@ Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
       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;
@@ -2427,14 +2427,18 @@ void sqlite3WindowCodeStep(
   ** be deleted after they enter the frame (WINDOW_AGGSTEP). */
   switch( pMWin->eStart ){
     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;
       }
       break;
     case TK_UNBOUNDED:
       if( windowCacheFrame(pMWin)==0 ){
         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;
           }
         }else{
@@ -2468,7 +2472,7 @@ void sqlite3WindowCodeStep(
   /* 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->eType!=TK_ROWS ){
+  if( pMWin->eFrmType!=TK_ROWS ){
     int nPeer = (pOrderBy ? pOrderBy->nExpr : 0);
     regNewPeer = regNew + pMWin->nBufferCol;
     if( pMWin->pPartition ) regNewPeer += pMWin->pPartition->nExpr;
@@ -2519,11 +2523,11 @@ void sqlite3WindowCodeStep(
 
   if( 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 ){
     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 ){
@@ -2538,7 +2542,7 @@ void sqlite3WindowCodeStep(
     sqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd);
     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 );
     sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regStart);
   }
@@ -2567,7 +2571,7 @@ void sqlite3WindowCodeStep(
   if( pMWin->eStart==TK_FOLLOWING ){
     windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
     if( pMWin->eEnd!=TK_UNBOUNDED ){
-      if( pMWin->eType==TK_RANGE ){
+      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);
@@ -2589,7 +2593,7 @@ void sqlite3WindowCodeStep(
     int addr = 0;
     windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
     if( pMWin->eEnd!=TK_UNBOUNDED ){
-      if( pMWin->eType==TK_RANGE ){
+      if( pMWin->eFrmType==TK_RANGE ){
         int lbl = 0;
         addr = sqlite3VdbeCurrentAddr(v);
         if( regEnd ){
@@ -2635,7 +2639,7 @@ void sqlite3WindowCodeStep(
     int addrBreak2;
     int addrBreak3;
     windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
-    if( pMWin->eType==TK_RANGE ){
+    if( pMWin->eFrmType==TK_RANGE ){
       addrStart = sqlite3VdbeCurrentAddr(v);
       addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 1);
       addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1);