mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
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:
116
src/treeview.c
116
src/treeview.c
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user