Enhance the TreeView mechanism so that it shows the window function

data structures as part of the abstract syntax tree.

FossilOrigin-Name: a2c0e1bec0d8a6f982572c4c5a8166319b8db0fe586057f7900f0ab72af6554e
This commit is contained in:
drh 2018-07-10 06:32:53 +00:00
parent 0b3b0dd1b1
commit a1fd4b520b
4 changed files with 147 additions and 19 deletions

View File

@ -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

View File

@ -1 +1 @@
a9a307265b0626b3e9df69534c8eacf18413ea31784c9d931eadcff515d3dd84
a2c0e1bec0d8a6f982572c4c5a8166319b8db0fe586057f7900f0ab72af6554e

View 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

View 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