4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give.
11 *************************************************************************
13 ** This file contains C code to implement the TreeView debugging routines.
14 ** These routines print a parse tree to standard output for debugging and
17 ** The interfaces in this file is only available when compiling
20 #include "sqliteInt.h"
24 ** Add a new subitem to the tree. The moreToFollow flag indicates that this
25 ** is not the last item in the tree.
27 static TreeView
*sqlite3TreeViewPush(TreeView
*p
, u8 moreToFollow
){
29 p
= sqlite3_malloc64( sizeof(*p
) );
31 memset(p
, 0, sizeof(*p
));
35 assert( moreToFollow
==0 || moreToFollow
==1 );
36 if( p
->iLevel
<sizeof(p
->bLine
) ) p
->bLine
[p
->iLevel
] = moreToFollow
;
41 ** Finished with one layer of the tree
43 static void sqlite3TreeViewPop(TreeView
*p
){
46 if( p
->iLevel
<0 ) sqlite3_free(p
);
50 ** Generate a single line of output for the tree, with a prefix that contains
51 ** all the appropriate tree lines
53 static void sqlite3TreeViewLine(TreeView
*p
, const char *zFormat
, ...){
58 sqlite3StrAccumInit(&acc
, 0, zBuf
, sizeof(zBuf
), 0);
60 for(i
=0; i
<p
->iLevel
&& i
<sizeof(p
->bLine
)-1; i
++){
61 sqlite3_str_append(&acc
, p
->bLine
[i
] ? "| " : " ", 4);
63 sqlite3_str_append(&acc
, p
->bLine
[i
] ? "|-- " : "'-- ", 4);
66 va_start(ap
, zFormat
);
67 sqlite3_str_vappendf(&acc
, zFormat
, ap
);
69 assert( acc
.nChar
>0 || acc
.accError
);
70 sqlite3_str_append(&acc
, "\n", 1);
72 sqlite3StrAccumFinish(&acc
);
73 fprintf(stdout
,"%s", zBuf
);
78 ** Shorthand for starting a new tree item that consists of a single label
80 static void sqlite3TreeViewItem(TreeView
*p
, const char *zLabel
,u8 moreFollows
){
81 p
= sqlite3TreeViewPush(p
, moreFollows
);
82 sqlite3TreeViewLine(p
, "%s", zLabel
);
86 ** Generate a human-readable description of a WITH clause.
88 void sqlite3TreeViewWith(TreeView
*pView
, const With
*pWith
, u8 moreToFollow
){
90 if( pWith
==0 ) return;
91 if( pWith
->nCte
==0 ) return;
93 sqlite3TreeViewLine(pView
, "WITH (0x%p, pOuter=0x%p)",pWith
,pWith
->pOuter
);
95 sqlite3TreeViewLine(pView
, "WITH (0x%p)", pWith
);
98 pView
= sqlite3TreeViewPush(pView
, 1);
99 for(i
=0; i
<pWith
->nCte
; i
++){
102 const struct Cte
*pCte
= &pWith
->a
[i
];
103 sqlite3StrAccumInit(&x
, 0, zLine
, sizeof(zLine
), 0);
104 sqlite3_str_appendf(&x
, "%s", pCte
->zName
);
105 if( pCte
->pCols
&& pCte
->pCols
->nExpr
>0 ){
108 for(j
=0; j
<pCte
->pCols
->nExpr
; j
++){
109 sqlite3_str_appendf(&x
, "%c%s", cSep
, pCte
->pCols
->a
[j
].zEName
);
112 sqlite3_str_appendf(&x
, ")");
115 sqlite3_str_appendf(&x
, " (pUse=0x%p, nUse=%d)", pCte
->pUse
,
118 sqlite3StrAccumFinish(&x
);
119 sqlite3TreeViewItem(pView
, zLine
, i
<pWith
->nCte
-1);
120 sqlite3TreeViewSelect(pView
, pCte
->pSelect
, 0);
121 sqlite3TreeViewPop(pView
);
123 sqlite3TreeViewPop(pView
);
128 ** Generate a human-readable description of a SrcList object.
130 void sqlite3TreeViewSrcList(TreeView
*pView
, const SrcList
*pSrc
){
132 for(i
=0; i
<pSrc
->nSrc
; i
++){
133 const SrcItem
*pItem
= &pSrc
->a
[i
];
136 sqlite3StrAccumInit(&x
, 0, zLine
, sizeof(zLine
), 0);
137 x
.printfFlags
|= SQLITE_PRINTF_INTERNAL
;
138 sqlite3_str_appendf(&x
, "{%d:*} %!S", pItem
->iCursor
, pItem
);
140 sqlite3_str_appendf(&x
, " tab=%Q nCol=%d ptr=%p used=%llx",
141 pItem
->pTab
->zName
, pItem
->pTab
->nCol
, pItem
->pTab
, pItem
->colUsed
);
143 if( pItem
->fg
.jointype
& JT_LEFT
){
144 sqlite3_str_appendf(&x
, " LEFT-JOIN");
145 }else if( pItem
->fg
.jointype
& JT_CROSS
){
146 sqlite3_str_appendf(&x
, " CROSS-JOIN");
148 if( pItem
->fg
.fromDDL
){
149 sqlite3_str_appendf(&x
, " DDL");
151 if( pItem
->fg
.isCte
){
152 sqlite3_str_appendf(&x
, " CteUse=0x%p", pItem
->u2
.pCteUse
);
154 sqlite3StrAccumFinish(&x
);
155 sqlite3TreeViewItem(pView
, zLine
, i
<pSrc
->nSrc
-1);
156 if( pItem
->pSelect
){
157 sqlite3TreeViewSelect(pView
, pItem
->pSelect
, 0);
159 if( pItem
->fg
.isTabFunc
){
160 sqlite3TreeViewExprList(pView
, pItem
->u1
.pFuncArg
, 0, "func-args:");
162 sqlite3TreeViewPop(pView
);
167 ** Generate a human-readable description of a Select object.
169 void sqlite3TreeViewSelect(TreeView
*pView
, const Select
*p
, u8 moreToFollow
){
173 sqlite3TreeViewLine(pView
, "nil-SELECT");
176 pView
= sqlite3TreeViewPush(pView
, moreToFollow
);
178 sqlite3TreeViewWith(pView
, p
->pWith
, 1);
180 sqlite3TreeViewPush(pView
, 1);
183 if( p
->selFlags
& SF_WhereBegin
){
184 sqlite3TreeViewLine(pView
, "sqlite3WhereBegin()");
186 sqlite3TreeViewLine(pView
,
187 "SELECT%s%s (%u/%p) selFlags=0x%x nSelectRow=%d",
188 ((p
->selFlags
& SF_Distinct
) ? " DISTINCT" : ""),
189 ((p
->selFlags
& SF_Aggregate
) ? " agg_flag" : ""),
190 p
->selId
, p
, p
->selFlags
,
194 if( cnt
++ ) sqlite3TreeViewPop(pView
);
199 if( p
->pSrc
&& p
->pSrc
->nSrc
) n
++;
201 if( p
->pGroupBy
) n
++;
202 if( p
->pHaving
) n
++;
203 if( p
->pOrderBy
) n
++;
205 #ifndef SQLITE_OMIT_WINDOWFUNC
207 if( p
->pWinDefn
) n
++;
211 sqlite3TreeViewExprList(pView
, p
->pEList
, n
>0, "result-set");
214 #ifndef SQLITE_OMIT_WINDOWFUNC
217 pView
= sqlite3TreeViewPush(pView
, (n
--)>0);
218 sqlite3TreeViewLine(pView
, "window-functions");
219 for(pX
=p
->pWin
; pX
; pX
=pX
->pNextWin
){
220 sqlite3TreeViewWinFunc(pView
, pX
, pX
->pNextWin
!=0);
222 sqlite3TreeViewPop(pView
);
225 if( p
->pSrc
&& p
->pSrc
->nSrc
){
226 pView
= sqlite3TreeViewPush(pView
, (n
--)>0);
227 sqlite3TreeViewLine(pView
, "FROM");
228 sqlite3TreeViewSrcList(pView
, p
->pSrc
);
229 sqlite3TreeViewPop(pView
);
232 sqlite3TreeViewItem(pView
, "WHERE", (n
--)>0);
233 sqlite3TreeViewExpr(pView
, p
->pWhere
, 0);
234 sqlite3TreeViewPop(pView
);
237 sqlite3TreeViewExprList(pView
, p
->pGroupBy
, (n
--)>0, "GROUPBY");
240 sqlite3TreeViewItem(pView
, "HAVING", (n
--)>0);
241 sqlite3TreeViewExpr(pView
, p
->pHaving
, 0);
242 sqlite3TreeViewPop(pView
);
244 #ifndef SQLITE_OMIT_WINDOWFUNC
247 sqlite3TreeViewItem(pView
, "WINDOW", (n
--)>0);
248 for(pX
=p
->pWinDefn
; pX
; pX
=pX
->pNextWin
){
249 sqlite3TreeViewWindow(pView
, pX
, pX
->pNextWin
!=0);
251 sqlite3TreeViewPop(pView
);
255 sqlite3TreeViewExprList(pView
, p
->pOrderBy
, (n
--)>0, "ORDERBY");
258 sqlite3TreeViewItem(pView
, "LIMIT", (n
--)>0);
259 sqlite3TreeViewExpr(pView
, p
->pLimit
->pLeft
, p
->pLimit
->pRight
!=0);
260 if( p
->pLimit
->pRight
){
261 sqlite3TreeViewItem(pView
, "OFFSET", (n
--)>0);
262 sqlite3TreeViewExpr(pView
, p
->pLimit
->pRight
, 0);
263 sqlite3TreeViewPop(pView
);
265 sqlite3TreeViewPop(pView
);
268 const char *zOp
= "UNION";
270 case TK_ALL
: zOp
= "UNION ALL"; break;
271 case TK_INTERSECT
: zOp
= "INTERSECT"; break;
272 case TK_EXCEPT
: zOp
= "EXCEPT"; break;
274 sqlite3TreeViewItem(pView
, zOp
, 1);
278 sqlite3TreeViewPop(pView
);
281 #ifndef SQLITE_OMIT_WINDOWFUNC
283 ** Generate a description of starting or stopping bounds
285 void sqlite3TreeViewBound(
286 TreeView
*pView
, /* View context */
287 u8 eBound
, /* UNBOUNDED, CURRENT, PRECEDING, FOLLOWING */
288 Expr
*pExpr
, /* Value for PRECEDING or FOLLOWING */
289 u8 moreToFollow
/* True if more to follow */
293 sqlite3TreeViewItem(pView
, "UNBOUNDED", moreToFollow
);
294 sqlite3TreeViewPop(pView
);
298 sqlite3TreeViewItem(pView
, "CURRENT", moreToFollow
);
299 sqlite3TreeViewPop(pView
);
303 sqlite3TreeViewItem(pView
, "PRECEDING", moreToFollow
);
304 sqlite3TreeViewExpr(pView
, pExpr
, 0);
305 sqlite3TreeViewPop(pView
);
309 sqlite3TreeViewItem(pView
, "FOLLOWING", moreToFollow
);
310 sqlite3TreeViewExpr(pView
, pExpr
, 0);
311 sqlite3TreeViewPop(pView
);
316 #endif /* SQLITE_OMIT_WINDOWFUNC */
318 #ifndef SQLITE_OMIT_WINDOWFUNC
320 ** Generate a human-readable explanation for a Window object
322 void sqlite3TreeViewWindow(TreeView
*pView
, const Window
*pWin
, u8 more
){
325 sqlite3TreeViewItem(pView
, "FILTER", 1);
326 sqlite3TreeViewExpr(pView
, pWin
->pFilter
, 0);
327 sqlite3TreeViewPop(pView
);
329 pView
= sqlite3TreeViewPush(pView
, more
);
331 sqlite3TreeViewLine(pView
, "OVER %s (%p)", pWin
->zName
, pWin
);
333 sqlite3TreeViewLine(pView
, "OVER (%p)", pWin
);
335 if( pWin
->zBase
) nElement
++;
336 if( pWin
->pOrderBy
) nElement
++;
337 if( pWin
->eFrmType
) nElement
++;
338 if( pWin
->eExclude
) nElement
++;
340 sqlite3TreeViewPush(pView
, (--nElement
)>0);
341 sqlite3TreeViewLine(pView
, "window: %s", pWin
->zBase
);
342 sqlite3TreeViewPop(pView
);
344 if( pWin
->pPartition
){
345 sqlite3TreeViewExprList(pView
, pWin
->pPartition
, nElement
>0,"PARTITION-BY");
347 if( pWin
->pOrderBy
){
348 sqlite3TreeViewExprList(pView
, pWin
->pOrderBy
, (--nElement
)>0, "ORDER-BY");
350 if( pWin
->eFrmType
){
352 const char *zFrmType
= "ROWS";
353 if( pWin
->eFrmType
==TK_RANGE
) zFrmType
= "RANGE";
354 if( pWin
->eFrmType
==TK_GROUPS
) zFrmType
= "GROUPS";
355 sqlite3_snprintf(sizeof(zBuf
),zBuf
,"%s%s",zFrmType
,
356 pWin
->bImplicitFrame
? " (implied)" : "");
357 sqlite3TreeViewItem(pView
, zBuf
, (--nElement
)>0);
358 sqlite3TreeViewBound(pView
, pWin
->eStart
, pWin
->pStart
, 1);
359 sqlite3TreeViewBound(pView
, pWin
->eEnd
, pWin
->pEnd
, 0);
360 sqlite3TreeViewPop(pView
);
362 if( pWin
->eExclude
){
364 const char *zExclude
;
365 switch( pWin
->eExclude
){
366 case TK_NO
: zExclude
= "NO OTHERS"; break;
367 case TK_CURRENT
: zExclude
= "CURRENT ROW"; break;
368 case TK_GROUP
: zExclude
= "GROUP"; break;
369 case TK_TIES
: zExclude
= "TIES"; break;
371 sqlite3_snprintf(sizeof(zBuf
),zBuf
,"invalid(%d)", pWin
->eExclude
);
375 sqlite3TreeViewPush(pView
, 0);
376 sqlite3TreeViewLine(pView
, "EXCLUDE %s", zExclude
);
377 sqlite3TreeViewPop(pView
);
379 sqlite3TreeViewPop(pView
);
381 #endif /* SQLITE_OMIT_WINDOWFUNC */
383 #ifndef SQLITE_OMIT_WINDOWFUNC
385 ** Generate a human-readable explanation for a Window Function object
387 void sqlite3TreeViewWinFunc(TreeView
*pView
, const Window
*pWin
, u8 more
){
388 pView
= sqlite3TreeViewPush(pView
, more
);
389 sqlite3TreeViewLine(pView
, "WINFUNC %s(%d)",
390 pWin
->pFunc
->zName
, pWin
->pFunc
->nArg
);
391 sqlite3TreeViewWindow(pView
, pWin
, 0);
392 sqlite3TreeViewPop(pView
);
394 #endif /* SQLITE_OMIT_WINDOWFUNC */
397 ** Generate a human-readable explanation of an expression tree.
399 void sqlite3TreeViewExpr(TreeView
*pView
, const Expr
*pExpr
, u8 moreToFollow
){
400 const char *zBinOp
= 0; /* Binary operator */
401 const char *zUniOp
= 0; /* Unary operator */
403 pView
= sqlite3TreeViewPush(pView
, moreToFollow
);
405 sqlite3TreeViewLine(pView
, "nil");
406 sqlite3TreeViewPop(pView
);
409 if( pExpr
->flags
|| pExpr
->affExpr
|| pExpr
->vvaFlags
){
411 sqlite3StrAccumInit(&x
, 0, zFlgs
, sizeof(zFlgs
), 0);
412 sqlite3_str_appendf(&x
, " fg.af=%x.%c",
413 pExpr
->flags
, pExpr
->affExpr
? pExpr
->affExpr
: 'n');
414 if( ExprHasProperty(pExpr
, EP_FromJoin
) ){
415 sqlite3_str_appendf(&x
, " iRJT=%d", pExpr
->iRightJoinTable
);
417 if( ExprHasProperty(pExpr
, EP_FromDDL
) ){
418 sqlite3_str_appendf(&x
, " DDL");
420 if( ExprHasVVAProperty(pExpr
, EP_Immutable
) ){
421 sqlite3_str_appendf(&x
, " IMMUTABLE");
423 sqlite3StrAccumFinish(&x
);
428 case TK_AGG_COLUMN
: {
429 sqlite3TreeViewLine(pView
, "AGG{%d:%d}%s",
430 pExpr
->iTable
, pExpr
->iColumn
, zFlgs
);
434 if( pExpr
->iTable
<0 ){
435 /* This only happens when coding check constraints */
438 sqlite3_snprintf(sizeof(zOp2
),zOp2
," op2=0x%02x",pExpr
->op2
);
442 sqlite3TreeViewLine(pView
, "COLUMN(%d)%s%s",
443 pExpr
->iColumn
, zFlgs
, zOp2
);
445 assert( ExprUseYTab(pExpr
) );
446 sqlite3TreeViewLine(pView
, "{%d:%d} pTab=%p%s",
447 pExpr
->iTable
, pExpr
->iColumn
,
448 pExpr
->y
.pTab
, zFlgs
);
450 if( ExprHasProperty(pExpr
, EP_FixedCol
) ){
451 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 0);
456 if( pExpr
->flags
& EP_IntValue
){
457 sqlite3TreeViewLine(pView
, "%d", pExpr
->u
.iValue
);
459 sqlite3TreeViewLine(pView
, "%s", pExpr
->u
.zToken
);
463 #ifndef SQLITE_OMIT_FLOATING_POINT
465 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
466 sqlite3TreeViewLine(pView
,"%s", pExpr
->u
.zToken
);
471 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
472 sqlite3TreeViewLine(pView
,"%Q", pExpr
->u
.zToken
);
476 sqlite3TreeViewLine(pView
,"NULL");
480 sqlite3TreeViewLine(pView
,"%s%s",
481 sqlite3ExprTruthValue(pExpr
) ? "TRUE" : "FALSE", zFlgs
);
484 #ifndef SQLITE_OMIT_BLOB_LITERAL
486 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
487 sqlite3TreeViewLine(pView
,"%s", pExpr
->u
.zToken
);
492 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
493 sqlite3TreeViewLine(pView
,"VARIABLE(%s,%d)",
494 pExpr
->u
.zToken
, pExpr
->iColumn
);
498 sqlite3TreeViewLine(pView
,"REGISTER(%d)", pExpr
->iTable
);
502 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
503 sqlite3TreeViewLine(pView
,"ID \"%w\"", pExpr
->u
.zToken
);
506 #ifndef SQLITE_OMIT_CAST
508 /* Expressions of the form: CAST(pLeft AS token) */
509 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
510 sqlite3TreeViewLine(pView
,"CAST %Q", pExpr
->u
.zToken
);
511 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 0);
514 #endif /* SQLITE_OMIT_CAST */
515 case TK_LT
: zBinOp
= "LT"; break;
516 case TK_LE
: zBinOp
= "LE"; break;
517 case TK_GT
: zBinOp
= "GT"; break;
518 case TK_GE
: zBinOp
= "GE"; break;
519 case TK_NE
: zBinOp
= "NE"; break;
520 case TK_EQ
: zBinOp
= "EQ"; break;
521 case TK_IS
: zBinOp
= "IS"; break;
522 case TK_ISNOT
: zBinOp
= "ISNOT"; break;
523 case TK_AND
: zBinOp
= "AND"; break;
524 case TK_OR
: zBinOp
= "OR"; break;
525 case TK_PLUS
: zBinOp
= "ADD"; break;
526 case TK_STAR
: zBinOp
= "MUL"; break;
527 case TK_MINUS
: zBinOp
= "SUB"; break;
528 case TK_REM
: zBinOp
= "REM"; break;
529 case TK_BITAND
: zBinOp
= "BITAND"; break;
530 case TK_BITOR
: zBinOp
= "BITOR"; break;
531 case TK_SLASH
: zBinOp
= "DIV"; break;
532 case TK_LSHIFT
: zBinOp
= "LSHIFT"; break;
533 case TK_RSHIFT
: zBinOp
= "RSHIFT"; break;
534 case TK_CONCAT
: zBinOp
= "CONCAT"; break;
535 case TK_DOT
: zBinOp
= "DOT"; break;
536 case TK_LIMIT
: zBinOp
= "LIMIT"; break;
538 case TK_UMINUS
: zUniOp
= "UMINUS"; break;
539 case TK_UPLUS
: zUniOp
= "UPLUS"; break;
540 case TK_BITNOT
: zUniOp
= "BITNOT"; break;
541 case TK_NOT
: zUniOp
= "NOT"; break;
542 case TK_ISNULL
: zUniOp
= "ISNULL"; break;
543 case TK_NOTNULL
: zUniOp
= "NOTNULL"; break;
547 const char *azOp
[] = {
548 "IS-FALSE", "IS-TRUE", "IS-NOT-FALSE", "IS-NOT-TRUE"
550 assert( pExpr
->op2
==TK_IS
|| pExpr
->op2
==TK_ISNOT
);
551 assert( pExpr
->pRight
);
552 assert( sqlite3ExprSkipCollate(pExpr
->pRight
)->op
==TK_TRUEFALSE
);
553 x
= (pExpr
->op2
==TK_ISNOT
)*2 + sqlite3ExprTruthValue(pExpr
->pRight
);
559 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
560 sqlite3TreeViewLine(pView
, "SPAN %Q", pExpr
->u
.zToken
);
561 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 0);
566 /* COLLATE operators without the EP_Collate flag are intended to
567 ** emulate collation associated with a table column. These show
568 ** up in the treeview output as "SOFT-COLLATE". Explicit COLLATE
569 ** operators that appear in the original SQL always have the
570 ** EP_Collate bit set and appear in treeview output as just "COLLATE" */
571 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
572 sqlite3TreeViewLine(pView
, "%sCOLLATE %Q%s",
573 !ExprHasProperty(pExpr
, EP_Collate
) ? "SOFT-" : "",
574 pExpr
->u
.zToken
, zFlgs
);
575 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 0);
579 case TK_AGG_FUNCTION
:
581 ExprList
*pFarg
; /* List of function arguments */
583 if( ExprHasProperty(pExpr
, EP_TokenOnly
) ){
587 assert( ExprUseXList(pExpr
) );
588 pFarg
= pExpr
->x
.pList
;
589 #ifndef SQLITE_OMIT_WINDOWFUNC
590 pWin
= ExprHasProperty(pExpr
, EP_WinFunc
) ? pExpr
->y
.pWin
: 0;
595 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
596 if( pExpr
->op
==TK_AGG_FUNCTION
){
597 sqlite3TreeViewLine(pView
, "AGG_FUNCTION%d %Q%s agg=%d[%d]/%p",
598 pExpr
->op2
, pExpr
->u
.zToken
, zFlgs
,
599 pExpr
->pAggInfo
? pExpr
->pAggInfo
->selId
: 0,
600 pExpr
->iAgg
, pExpr
->pAggInfo
);
601 }else if( pExpr
->op2
!=0 ){
604 sqlite3_snprintf(sizeof(zBuf
),zBuf
,"0x%02x",pExpr
->op2
);
606 if( pExpr
->op2
==NC_IsCheck
) zOp2
= "NC_IsCheck";
607 if( pExpr
->op2
==NC_IdxExpr
) zOp2
= "NC_IdxExpr";
608 if( pExpr
->op2
==NC_PartIdx
) zOp2
= "NC_PartIdx";
609 if( pExpr
->op2
==NC_GenCol
) zOp2
= "NC_GenCol";
610 sqlite3TreeViewLine(pView
, "FUNCTION %Q%s op2=%s",
611 pExpr
->u
.zToken
, zFlgs
, zOp2
);
613 sqlite3TreeViewLine(pView
, "FUNCTION %Q%s", pExpr
->u
.zToken
, zFlgs
);
616 sqlite3TreeViewExprList(pView
, pFarg
, pWin
!=0, 0);
618 #ifndef SQLITE_OMIT_WINDOWFUNC
620 sqlite3TreeViewWindow(pView
, pWin
, 0);
625 #ifndef SQLITE_OMIT_SUBQUERY
627 assert( ExprUseXSelect(pExpr
) );
628 sqlite3TreeViewLine(pView
, "EXISTS-expr flags=0x%x", pExpr
->flags
);
629 sqlite3TreeViewSelect(pView
, pExpr
->x
.pSelect
, 0);
633 assert( ExprUseXSelect(pExpr
) );
634 sqlite3TreeViewLine(pView
, "subquery-expr flags=0x%x", pExpr
->flags
);
635 sqlite3TreeViewSelect(pView
, pExpr
->x
.pSelect
, 0);
639 sqlite3TreeViewLine(pView
, "IN flags=0x%x", pExpr
->flags
);
640 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 1);
641 if( ExprUseXSelect(pExpr
) ){
642 sqlite3TreeViewSelect(pView
, pExpr
->x
.pSelect
, 0);
644 sqlite3TreeViewExprList(pView
, pExpr
->x
.pList
, 0, 0);
648 #endif /* SQLITE_OMIT_SUBQUERY */
653 ** This is equivalent to
657 ** X is stored in pExpr->pLeft.
658 ** Y is stored in pExpr->pList->a[0].pExpr.
659 ** Z is stored in pExpr->pList->a[1].pExpr.
662 const Expr
*pX
, *pY
, *pZ
;
664 assert( ExprUseXList(pExpr
) );
665 assert( pExpr
->x
.pList
->nExpr
==2 );
666 pY
= pExpr
->x
.pList
->a
[0].pExpr
;
667 pZ
= pExpr
->x
.pList
->a
[1].pExpr
;
668 sqlite3TreeViewLine(pView
, "BETWEEN");
669 sqlite3TreeViewExpr(pView
, pX
, 1);
670 sqlite3TreeViewExpr(pView
, pY
, 1);
671 sqlite3TreeViewExpr(pView
, pZ
, 0);
675 /* If the opcode is TK_TRIGGER, then the expression is a reference
676 ** to a column in the new.* or old.* pseudo-tables available to
677 ** trigger programs. In this case Expr.iTable is set to 1 for the
678 ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn
679 ** is set to the column of the pseudo-table to read, or to -1 to
680 ** read the rowid field.
682 sqlite3TreeViewLine(pView
, "%s(%d)",
683 pExpr
->iTable
? "NEW" : "OLD", pExpr
->iColumn
);
687 sqlite3TreeViewLine(pView
, "CASE");
688 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 1);
689 assert( ExprUseXList(pExpr
) );
690 sqlite3TreeViewExprList(pView
, pExpr
->x
.pList
, 0, 0);
693 #ifndef SQLITE_OMIT_TRIGGER
695 const char *zType
= "unk";
696 switch( pExpr
->affExpr
){
697 case OE_Rollback
: zType
= "rollback"; break;
698 case OE_Abort
: zType
= "abort"; break;
699 case OE_Fail
: zType
= "fail"; break;
700 case OE_Ignore
: zType
= "ignore"; break;
702 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
703 sqlite3TreeViewLine(pView
, "RAISE %s(%Q)", zType
, pExpr
->u
.zToken
);
708 sqlite3TreeViewLine(pView
, "MATCH {%d:%d}%s",
709 pExpr
->iTable
, pExpr
->iColumn
, zFlgs
);
710 sqlite3TreeViewExpr(pView
, pExpr
->pRight
, 0);
714 char *z
= sqlite3_mprintf("VECTOR%s",zFlgs
);
715 assert( ExprUseXList(pExpr
) );
716 sqlite3TreeViewBareExprList(pView
, pExpr
->x
.pList
, z
);
720 case TK_SELECT_COLUMN
: {
721 sqlite3TreeViewLine(pView
, "SELECT-COLUMN %d of [0..%d]%s",
722 pExpr
->iColumn
, pExpr
->iTable
-1,
723 pExpr
->pRight
==pExpr
->pLeft
? " (SELECT-owner)" : "");
724 assert( ExprUseXSelect(pExpr
->pLeft
) );
725 sqlite3TreeViewSelect(pView
, pExpr
->pLeft
->x
.pSelect
, 0);
728 case TK_IF_NULL_ROW
: {
729 sqlite3TreeViewLine(pView
, "IF-NULL-ROW %d", pExpr
->iTable
);
730 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 0);
735 sqlite3TreeViewLine(pView
, "ERROR");
738 sqlite3TreeViewExpr(pView
, &tmp
, 0);
742 if( pExpr
->iColumn
<=0 ){
743 sqlite3TreeViewLine(pView
, "First FROM table rowid");
745 sqlite3TreeViewLine(pView
, "First FROM table column %d",
751 sqlite3TreeViewLine(pView
, "op=%d", pExpr
->op
);
756 sqlite3TreeViewLine(pView
, "%s%s", zBinOp
, zFlgs
);
757 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 1);
758 sqlite3TreeViewExpr(pView
, pExpr
->pRight
, 0);
760 sqlite3TreeViewLine(pView
, "%s%s", zUniOp
, zFlgs
);
761 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 0);
763 sqlite3TreeViewPop(pView
);
768 ** Generate a human-readable explanation of an expression list.
770 void sqlite3TreeViewBareExprList(
772 const ExprList
*pList
,
775 if( zLabel
==0 || zLabel
[0]==0 ) zLabel
= "LIST";
777 sqlite3TreeViewLine(pView
, "%s (empty)", zLabel
);
780 sqlite3TreeViewLine(pView
, "%s", zLabel
);
781 for(i
=0; i
<pList
->nExpr
; i
++){
782 int j
= pList
->a
[i
].u
.x
.iOrderByCol
;
783 char *zName
= pList
->a
[i
].zEName
;
784 int moreToFollow
= i
<pList
->nExpr
- 1;
785 if( pList
->a
[i
].eEName
!=ENAME_NAME
) zName
= 0;
787 sqlite3TreeViewPush(pView
, moreToFollow
);
789 sqlite3TreeViewLine(pView
, 0);
791 fprintf(stdout
, "AS %s ", zName
);
794 fprintf(stdout
, "iOrderByCol=%d", j
);
796 fprintf(stdout
, "\n");
799 sqlite3TreeViewExpr(pView
, pList
->a
[i
].pExpr
, moreToFollow
);
801 sqlite3TreeViewPop(pView
);
806 void sqlite3TreeViewExprList(
808 const ExprList
*pList
,
812 pView
= sqlite3TreeViewPush(pView
, moreToFollow
);
813 sqlite3TreeViewBareExprList(pView
, pList
, zLabel
);
814 sqlite3TreeViewPop(pView
);
817 #endif /* SQLITE_DEBUG */