]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Enhance the TreeView mechanism so that it shows the window function
authordrh <drh@noemail.net>
Tue, 10 Jul 2018 06:32:53 +0000 (06:32 +0000)
committerdrh <drh@noemail.net>
Tue, 10 Jul 2018 06:32:53 +0000 (06:32 +0000)
data structures as part of the abstract syntax tree.

FossilOrigin-Name: a2c0e1bec0d8a6f982572c4c5a8166319b8db0fe586057f7900f0ab72af6554e

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

index 5040ebb57d8594871bfd58d94755f5d5cfcec970..75f9e4c813bf984f5829554379885032d986eee7 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C New\sVDBE\scomments\sand\scoverage\smacros.
-D 2018-07-10T05:11:03.432
+C Enhance\sthe\sTreeView\smechanism\sso\sthat\sit\sshows\sthe\swindow\sfunction\ndata\sstructures\sas\spart\sof\sthe\sabstract\ssyntax\stree.
+D 2018-07-10T06:32:53.781
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F Makefile.in 0a3a6c81e6fcb969ff9106e882f0a08547014ba463cb6beca4c4efaecc924ee6
@@ -500,7 +500,7 @@ F src/shell.c.in f1c79c537117ee61317a5ed85cdbcb854998cd690eb34ab803779358a2ace78
 F src/sqlite.h.in 36f0b3f88241863530f4b7e57e673e19311dd609ec4edad83b23291928cdf853
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 9887b27e69c01e79c2cbe74ef73bf01af5b5703d6a7f0a4371e386d7249cb1c7
-F src/sqliteInt.h c14c850bf0c4dd3860cc5092f140ae9faf93b77737b3febf38454088e1ab3988
+F src/sqliteInt.h 7e24bfe3bf22df5516062f229fe181f9532ff44335d702c525420e060aad78da
 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
 F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -559,7 +559,7 @@ F src/test_window.c 0d19b33e7a262d3b55e85bc0fb84a70f503686cbd769939176162fe866ce
 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
 F src/tokenize.c 01e96d1b639c3eb0b9ef90616e766d453935c554f1f7aa86b6db937b79554b97
-F src/treeview.c 2c5c4bc0a443401db5fd621542150452ddf5055d38edd4eef868bc2b6bfb0260
+F src/treeview.c 2d0fa21befa82f5c1ec419d20ea73dd845faffeb27ee1df9828e742985c35729
 F src/trigger.c 4ace6d1d5ba9a89822deb287317f33c810440526eafe185c2d8a48c31df1e995
 F src/update.c 46dc24c6158446aaab45caee09b6d99327cb479268b83ffeb5b701823da3b67b
 F src/upsert.c 47edd408cc73f8d3c00a140550d1ad180b407c146285947969dd09874802bf88
@@ -1746,7 +1746,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 5023b1b85b883a716a5da673740b6effe214ee0490f4ca45f161bb8b04784366
-R 1d4ea7412d930566b30febcbbea41480
+P a9a307265b0626b3e9df69534c8eacf18413ea31784c9d931eadcff515d3dd84
+R 55502084a84a2e2884b7442095b4ff11
 U drh
-Z a8f24d1ff4685d87f042dd3f45af12cc
+Z c5933f33cc5508d96ff93ada77827be8
index d0d5647ce8cc1c1fbb345d39a70ed13b7bd0d61b..4d5e5ad26d1f882da3cc4d50b4b7fb369edcdd8b 100644 (file)
@@ -1 +1 @@
-a9a307265b0626b3e9df69534c8eacf18413ea31784c9d931eadcff515d3dd84
\ No newline at end of file
+a2c0e1bec0d8a6f982572c4c5a8166319b8db0fe586057f7900f0ab72af6554e
\ No newline at end of file
index 448918a7f6f4ff77cf15eff0fd67cbbf94edde97..c15c19e80afde120ad0296114c22a50a619596e0 100644 (file)
@@ -3490,8 +3490,22 @@ struct TreeView {
 #endif /* SQLITE_DEBUG */
 
 /*
-** Object used to encode the OVER() clause attached to a window-function
-** invocation. And some fields used while generating VM code for the same.
+** This object is used in varioius 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.
+**
+**   (2) All window functions in a single SELECT form a linked-list
+**       attached to Select.pWin.  The Window.pFunc and Window.pExpr
+**       fields point back to the expression that is the window function.
+**
+**   (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.
 */
 struct Window {
   char *zName;            /* Name of window (may be NULL) */
@@ -3502,20 +3516,16 @@ struct Window {
   u8 eEnd;                /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */
   Expr *pStart;           /* Expression for "<expr> PRECEDING" */
   Expr *pEnd;             /* Expression for "<expr> FOLLOWING" */
-
   Window *pNextWin;       /* Next window function belonging to this SELECT */
-
-  Expr *pFilter;
-  FuncDef *pFunc;
-
+  Expr *pFilter;          /* The FILTER expression */
+  FuncDef *pFunc;         /* The function */
   int iEphCsr;            /* Temp table used by this window */
   int regAccum;
   int regResult;
-
   int csrApp;             /* Function cursor (used by min/max) */
   int regApp;             /* Function register (also used by min/max) */
-
-  int regPart;
+  int regPart;            /* First in a set of registers holding PARTITION BY
+                          ** and ORDER BY values for the window */
   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 */
@@ -3755,6 +3765,10 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
   void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);
   void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
   void sqlite3TreeViewWith(TreeView*, const With*, u8);
+#ifndef SQLITE_OMIT_WINDOWFUNC
+  void sqlite3TreeViewWindow(TreeView*, const Window*, u8);
+  void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8);
+#endif
 #endif
 
 
index 970d85eba4d277a288864625d28ce5986803dce5..1ece76f953f385db0bb42d226001c470a1d7004e 100644 (file)
@@ -165,8 +165,23 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
       if( p->pHaving ) n++;
       if( p->pOrderBy ) n++;
       if( p->pLimit ) n++;
+#ifndef SQLITE_OMIT_WINDOWFUNC
+      if( p->pWin ) n++;
+      if( p->pWinDefn ) n++;
+#endif
     }
     sqlite3TreeViewExprList(pView, p->pEList, (n--)>0, "result-set");
+#ifndef SQLITE_OMIT_WINDOWFUNC
+    if( p->pWin ){
+      Window *pX;
+      pView = sqlite3TreeViewPush(pView, (n--)>0);
+      sqlite3TreeViewLine(pView, "window-functions");
+      for(pX=p->pWin; pX; pX=pX->pNextWin){
+        sqlite3TreeViewWinFunc(pView, pX, pX->pNextWin!=0);
+      }
+      sqlite3TreeViewPop(pView);
+    }
+#endif
     if( p->pSrc && p->pSrc->nSrc ){
       int i;
       pView = sqlite3TreeViewPush(pView, (n--)>0);
@@ -216,6 +231,16 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
       sqlite3TreeViewExpr(pView, p->pHaving, 0);
       sqlite3TreeViewPop(pView);
     }
+#ifndef SQLITE_OMIT_WINDOWFUNC
+    if( p->pWinDefn ){
+      Window *pX;
+      sqlite3TreeViewItem(pView, "WINDOW", (n--)>0);
+      for(pX=p->pWinDefn; pX; pX=pX->pNextWin){
+        sqlite3TreeViewWindow(pView, pX, pX->pNextWin!=0);
+      }
+      sqlite3TreeViewPop(pView);
+    }
+#endif
     if( p->pOrderBy ){
       sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY");
     }
@@ -243,6 +268,83 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
   sqlite3TreeViewPop(pView);
 }
 
+#ifndef SQLITE_OMIT_WINDOWFUNC
+/*
+** Generate a description of starting or stopping bounds
+*/
+void sqlite3TreeViewBound(
+  TreeView *pView,        /* View context */
+  u8 eBound,              /* UNBOUNDED, CURRENT, PRECEDING, FOLLOWING */
+  Expr *pExpr,            /* Value for PRECEDING or FOLLOWING */
+  u8 moreToFollow         /* True if more to follow */
+){
+  switch( eBound ){
+    case TK_UNBOUNDED: {
+      sqlite3TreeViewItem(pView, "UNBOUNDED", moreToFollow);
+      sqlite3TreeViewPop(pView);
+      break;
+    }
+    case TK_CURRENT: {
+      sqlite3TreeViewItem(pView, "CURRENT", moreToFollow);
+      sqlite3TreeViewPop(pView);
+      break;
+    }
+    case TK_PRECEDING: {
+      sqlite3TreeViewItem(pView, "PRECEDING", moreToFollow);
+      sqlite3TreeViewExpr(pView, pExpr, 0);
+      sqlite3TreeViewPop(pView);
+      break;
+    }
+    case TK_FOLLOWING: {
+      sqlite3TreeViewItem(pView, "FOLLOWING", moreToFollow);
+      sqlite3TreeViewExpr(pView, pExpr, 0);
+      sqlite3TreeViewPop(pView);
+      break;
+    }
+  }
+}
+#endif /* SQLITE_OMIT_WINDOWFUNC */
+
+#ifndef SQLITE_OMIT_WINDOWFUNC
+/*
+** Generate a human-readable explanation for a Window object
+*/
+void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){
+  pView = sqlite3TreeViewPush(pView, more);
+  if( pWin->zName ){
+    sqlite3TreeViewLine(pView, "OVER %s", pWin->zName);
+  }else{
+    sqlite3TreeViewLine(pView, "OVER");
+  }
+  if( pWin->pPartition ){
+    sqlite3TreeViewExprList(pView, pWin->pPartition, 1, "PARTITION-BY");
+  }
+  if( pWin->pOrderBy ){
+    sqlite3TreeViewExprList(pView, pWin->pOrderBy, 1, "ORDER-BY");
+  }
+  if( pWin->eType ){
+    sqlite3TreeViewItem(pView, pWin->eType==TK_RANGE ? "RANGE" : "ROWS", 0);
+    sqlite3TreeViewBound(pView, pWin->eStart, pWin->pStart, 1);
+    sqlite3TreeViewBound(pView, pWin->eEnd, pWin->pEnd, 0);
+    sqlite3TreeViewPop(pView);
+  }
+  sqlite3TreeViewPop(pView);
+}
+#endif /* SQLITE_OMIT_WINDOWFUNC */
+
+#ifndef SQLITE_OMIT_WINDOWFUNC
+/*
+** Generate a human-readable explanation for a Window Function object
+*/
+void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){
+  pView = sqlite3TreeViewPush(pView, more);
+  sqlite3TreeViewLine(pView, "WINFUNC %s(%d)",
+                       pWin->pFunc->zName, pWin->pFunc->nArg);
+  sqlite3TreeViewWindow(pView, pWin, 0);
+  sqlite3TreeViewPop(pView);
+}
+#endif /* SQLITE_OMIT_WINDOWFUNC */
+
 /*
 ** Generate a human-readable explanation of an expression tree.
 */
@@ -393,10 +495,17 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
     case TK_AGG_FUNCTION:
     case TK_FUNCTION: {
       ExprList *pFarg;       /* List of function arguments */
+      Window *pWin;
       if( ExprHasProperty(pExpr, EP_TokenOnly) ){
         pFarg = 0;
+        pWin = 0;
       }else{
         pFarg = pExpr->x.pList;
+#ifndef SQLITE_OMIT_WINDOWFUNC
+        pWin = pExpr->pWin;
+#else
+        pWin = 0;
+#endif 
       }
       if( pExpr->op==TK_AGG_FUNCTION ){
         sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q",
@@ -405,8 +514,13 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
         sqlite3TreeViewLine(pView, "FUNCTION %Q", pExpr->u.zToken);
       }
       if( pFarg ){
-        sqlite3TreeViewExprList(pView, pFarg, 0, 0);
+        sqlite3TreeViewExprList(pView, pFarg, pWin!=0, 0);
       }
+#ifndef SQLITe_OMIT_WINDOWFUNC
+      if( pWin ){
+        sqlite3TreeViewWindow(pView, pWin, 0);
+      }
+#endif
       break;
     }
 #ifndef SQLITE_OMIT_SUBQUERY