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 void sqlite3TreeViewPush(TreeView
**pp
, u8 moreToFollow
){
30 *pp
= p
= sqlite3_malloc64( sizeof(*p
) );
32 memset(p
, 0, sizeof(*p
));
36 assert( moreToFollow
==0 || moreToFollow
==1 );
37 if( p
->iLevel
<(int)sizeof(p
->bLine
) ) p
->bLine
[p
->iLevel
] = moreToFollow
;
41 ** Finished with one layer of the tree
43 static void sqlite3TreeViewPop(TreeView
**pp
){
54 ** Generate a single line of output for the tree, with a prefix that contains
55 ** all the appropriate tree lines
57 void sqlite3TreeViewLine(TreeView
*p
, const char *zFormat
, ...){
62 sqlite3StrAccumInit(&acc
, 0, zBuf
, sizeof(zBuf
), 0);
64 for(i
=0; i
<p
->iLevel
&& i
<(int)sizeof(p
->bLine
)-1; i
++){
65 sqlite3_str_append(&acc
, p
->bLine
[i
] ? "| " : " ", 4);
67 sqlite3_str_append(&acc
, p
->bLine
[i
] ? "|-- " : "'-- ", 4);
70 va_start(ap
, zFormat
);
71 sqlite3_str_vappendf(&acc
, zFormat
, ap
);
73 assert( acc
.nChar
>0 || acc
.accError
);
74 sqlite3_str_append(&acc
, "\n", 1);
76 sqlite3StrAccumFinish(&acc
);
77 fprintf(stdout
,"%s", zBuf
);
82 ** Shorthand for starting a new tree item that consists of a single label
84 static void sqlite3TreeViewItem(TreeView
*p
, const char *zLabel
,u8 moreFollows
){
85 sqlite3TreeViewPush(&p
, moreFollows
);
86 sqlite3TreeViewLine(p
, "%s", zLabel
);
90 ** Show a list of Column objects in tree format.
92 void sqlite3TreeViewColumnList(
99 sqlite3TreeViewPush(&pView
, moreToFollow
);
100 sqlite3TreeViewLine(pView
, "COLUMNS");
101 for(i
=0; i
<nCol
; i
++){
102 u16 flg
= aCol
[i
].colFlags
;
103 int colMoreToFollow
= i
<(nCol
- 1);
104 sqlite3TreeViewPush(&pView
, colMoreToFollow
);
105 sqlite3TreeViewLine(pView
, 0);
106 printf(" %s", aCol
[i
].zCnName
);
107 switch( aCol
[i
].eCType
){
108 case COLTYPE_ANY
: printf(" ANY"); break;
109 case COLTYPE_BLOB
: printf(" BLOB"); break;
110 case COLTYPE_INT
: printf(" INT"); break;
111 case COLTYPE_INTEGER
: printf(" INTEGER"); break;
112 case COLTYPE_REAL
: printf(" REAL"); break;
113 case COLTYPE_TEXT
: printf(" TEXT"); break;
114 case COLTYPE_CUSTOM
: {
115 if( flg
& COLFLAG_HASTYPE
){
116 const char *z
= aCol
[i
].zCnName
;
123 if( flg
& COLFLAG_PRIMKEY
) printf(" PRIMARY KEY");
124 if( flg
& COLFLAG_HIDDEN
) printf(" HIDDEN");
125 #ifdef COLFLAG_NOEXPAND
126 if( flg
& COLFLAG_NOEXPAND
) printf(" NO-EXPAND");
128 if( flg
) printf(" flags=%04x", flg
);
131 sqlite3TreeViewPop(&pView
);
133 sqlite3TreeViewPop(&pView
);
137 ** Generate a human-readable description of a WITH clause.
139 void sqlite3TreeViewWith(TreeView
*pView
, const With
*pWith
, u8 moreToFollow
){
141 if( pWith
==0 ) return;
142 if( pWith
->nCte
==0 ) return;
144 sqlite3TreeViewLine(pView
, "WITH (0x%p, pOuter=0x%p)",pWith
,pWith
->pOuter
);
146 sqlite3TreeViewLine(pView
, "WITH (0x%p)", pWith
);
149 sqlite3TreeViewPush(&pView
, moreToFollow
);
150 for(i
=0; i
<pWith
->nCte
; i
++){
153 const struct Cte
*pCte
= &pWith
->a
[i
];
154 sqlite3StrAccumInit(&x
, 0, zLine
, sizeof(zLine
), 0);
155 sqlite3_str_appendf(&x
, "%s", pCte
->zName
);
156 if( pCte
->pCols
&& pCte
->pCols
->nExpr
>0 ){
159 for(j
=0; j
<pCte
->pCols
->nExpr
; j
++){
160 sqlite3_str_appendf(&x
, "%c%s", cSep
, pCte
->pCols
->a
[j
].zEName
);
163 sqlite3_str_appendf(&x
, ")");
165 if( pCte
->eM10d
!=M10d_Any
){
166 sqlite3_str_appendf(&x
, " %sMATERIALIZED",
167 pCte
->eM10d
==M10d_No
? "NOT " : "");
170 sqlite3_str_appendf(&x
, " (pUse=0x%p, nUse=%d)", pCte
->pUse
,
173 sqlite3StrAccumFinish(&x
);
174 sqlite3TreeViewItem(pView
, zLine
, i
<pWith
->nCte
-1);
175 sqlite3TreeViewSelect(pView
, pCte
->pSelect
, 0);
176 sqlite3TreeViewPop(&pView
);
178 sqlite3TreeViewPop(&pView
);
183 ** Generate a human-readable description of a SrcList object.
185 void sqlite3TreeViewSrcList(TreeView
*pView
, const SrcList
*pSrc
){
187 if( pSrc
==0 ) return;
188 for(i
=0; i
<pSrc
->nSrc
; i
++){
189 const SrcItem
*pItem
= &pSrc
->a
[i
];
193 sqlite3StrAccumInit(&x
, 0, zLine
, sizeof(zLine
), 0);
194 x
.printfFlags
|= SQLITE_PRINTF_INTERNAL
;
195 sqlite3_str_appendf(&x
, "{%d:*} %!S", pItem
->iCursor
, pItem
);
197 sqlite3_str_appendf(&x
, " tab=%Q nCol=%d ptr=%p used=%llx%s",
198 pItem
->pTab
->zName
, pItem
->pTab
->nCol
, pItem
->pTab
,
200 pItem
->fg
.rowidUsed
? "+rowid" : "");
202 if( (pItem
->fg
.jointype
& (JT_LEFT
|JT_RIGHT
))==(JT_LEFT
|JT_RIGHT
) ){
203 sqlite3_str_appendf(&x
, " FULL-OUTER-JOIN");
204 }else if( pItem
->fg
.jointype
& JT_LEFT
){
205 sqlite3_str_appendf(&x
, " LEFT-JOIN");
206 }else if( pItem
->fg
.jointype
& JT_RIGHT
){
207 sqlite3_str_appendf(&x
, " RIGHT-JOIN");
208 }else if( pItem
->fg
.jointype
& JT_CROSS
){
209 sqlite3_str_appendf(&x
, " CROSS-JOIN");
211 if( pItem
->fg
.jointype
& JT_LTORJ
){
212 sqlite3_str_appendf(&x
, " LTORJ");
214 if( pItem
->fg
.fromDDL
){
215 sqlite3_str_appendf(&x
, " DDL");
217 if( pItem
->fg
.isCte
){
218 sqlite3_str_appendf(&x
, " CteUse=0x%p", pItem
->u2
.pCteUse
);
220 if( pItem
->fg
.isOn
|| (pItem
->fg
.isUsing
==0 && pItem
->u3
.pOn
!=0) ){
221 sqlite3_str_appendf(&x
, " ON");
223 if( pItem
->fg
.isTabFunc
) sqlite3_str_appendf(&x
, " isTabFunc");
224 if( pItem
->fg
.isCorrelated
) sqlite3_str_appendf(&x
, " isCorrelated");
225 if( pItem
->fg
.isMaterialized
) sqlite3_str_appendf(&x
, " isMaterialized");
226 if( pItem
->fg
.viaCoroutine
) sqlite3_str_appendf(&x
, " viaCoroutine");
227 if( pItem
->fg
.notCte
) sqlite3_str_appendf(&x
, " notCte");
228 if( pItem
->fg
.isNestedFrom
) sqlite3_str_appendf(&x
, " isNestedFrom");
230 sqlite3StrAccumFinish(&x
);
231 sqlite3TreeViewItem(pView
, zLine
, i
<pSrc
->nSrc
-1);
233 if( pItem
->pSelect
) n
++;
234 if( pItem
->fg
.isTabFunc
) n
++;
235 if( pItem
->fg
.isUsing
) n
++;
236 if( pItem
->fg
.isUsing
){
237 sqlite3TreeViewIdList(pView
, pItem
->u3
.pUsing
, (--n
)>0, "USING");
239 if( pItem
->pSelect
){
240 sqlite3TreeViewPush(&pView
, i
+1<pSrc
->nSrc
);
242 Table
*pTab
= pItem
->pTab
;
243 sqlite3TreeViewColumnList(pView
, pTab
->aCol
, pTab
->nCol
, 1);
245 assert( (int)pItem
->fg
.isNestedFrom
== IsNestedFrom(pItem
->pSelect
) );
246 sqlite3TreeViewSelect(pView
, pItem
->pSelect
, (--n
)>0);
247 sqlite3TreeViewPop(&pView
);
249 if( pItem
->fg
.isTabFunc
){
250 sqlite3TreeViewExprList(pView
, pItem
->u1
.pFuncArg
, 0, "func-args:");
252 sqlite3TreeViewPop(&pView
);
257 ** Generate a human-readable description of a Select object.
259 void sqlite3TreeViewSelect(TreeView
*pView
, const Select
*p
, u8 moreToFollow
){
263 sqlite3TreeViewLine(pView
, "nil-SELECT");
266 sqlite3TreeViewPush(&pView
, moreToFollow
);
268 sqlite3TreeViewWith(pView
, p
->pWith
, 1);
270 sqlite3TreeViewPush(&pView
, 1);
273 if( p
->selFlags
& SF_WhereBegin
){
274 sqlite3TreeViewLine(pView
, "sqlite3WhereBegin()");
276 sqlite3TreeViewLine(pView
,
277 "SELECT%s%s (%u/%p) selFlags=0x%x nSelectRow=%d",
278 ((p
->selFlags
& SF_Distinct
) ? " DISTINCT" : ""),
279 ((p
->selFlags
& SF_Aggregate
) ? " agg_flag" : ""),
280 p
->selId
, p
, p
->selFlags
,
284 if( cnt
++ ) sqlite3TreeViewPop(&pView
);
289 if( p
->pSrc
&& p
->pSrc
->nSrc
) n
++;
291 if( p
->pGroupBy
) n
++;
292 if( p
->pHaving
) n
++;
293 if( p
->pOrderBy
) n
++;
295 #ifndef SQLITE_OMIT_WINDOWFUNC
297 if( p
->pWinDefn
) n
++;
301 sqlite3TreeViewExprList(pView
, p
->pEList
, n
>0, "result-set");
304 #ifndef SQLITE_OMIT_WINDOWFUNC
307 sqlite3TreeViewPush(&pView
, (n
--)>0);
308 sqlite3TreeViewLine(pView
, "window-functions");
309 for(pX
=p
->pWin
; pX
; pX
=pX
->pNextWin
){
310 sqlite3TreeViewWinFunc(pView
, pX
, pX
->pNextWin
!=0);
312 sqlite3TreeViewPop(&pView
);
315 if( p
->pSrc
&& p
->pSrc
->nSrc
){
316 sqlite3TreeViewPush(&pView
, (n
--)>0);
317 sqlite3TreeViewLine(pView
, "FROM");
318 sqlite3TreeViewSrcList(pView
, p
->pSrc
);
319 sqlite3TreeViewPop(&pView
);
322 sqlite3TreeViewItem(pView
, "WHERE", (n
--)>0);
323 sqlite3TreeViewExpr(pView
, p
->pWhere
, 0);
324 sqlite3TreeViewPop(&pView
);
327 sqlite3TreeViewExprList(pView
, p
->pGroupBy
, (n
--)>0, "GROUPBY");
330 sqlite3TreeViewItem(pView
, "HAVING", (n
--)>0);
331 sqlite3TreeViewExpr(pView
, p
->pHaving
, 0);
332 sqlite3TreeViewPop(&pView
);
334 #ifndef SQLITE_OMIT_WINDOWFUNC
337 sqlite3TreeViewItem(pView
, "WINDOW", (n
--)>0);
338 for(pX
=p
->pWinDefn
; pX
; pX
=pX
->pNextWin
){
339 sqlite3TreeViewWindow(pView
, pX
, pX
->pNextWin
!=0);
341 sqlite3TreeViewPop(&pView
);
345 sqlite3TreeViewExprList(pView
, p
->pOrderBy
, (n
--)>0, "ORDERBY");
348 sqlite3TreeViewItem(pView
, "LIMIT", (n
--)>0);
349 sqlite3TreeViewExpr(pView
, p
->pLimit
->pLeft
, p
->pLimit
->pRight
!=0);
350 if( p
->pLimit
->pRight
){
351 sqlite3TreeViewItem(pView
, "OFFSET", 0);
352 sqlite3TreeViewExpr(pView
, p
->pLimit
->pRight
, 0);
353 sqlite3TreeViewPop(&pView
);
355 sqlite3TreeViewPop(&pView
);
358 const char *zOp
= "UNION";
360 case TK_ALL
: zOp
= "UNION ALL"; break;
361 case TK_INTERSECT
: zOp
= "INTERSECT"; break;
362 case TK_EXCEPT
: zOp
= "EXCEPT"; break;
364 sqlite3TreeViewItem(pView
, zOp
, 1);
368 sqlite3TreeViewPop(&pView
);
371 #ifndef SQLITE_OMIT_WINDOWFUNC
373 ** Generate a description of starting or stopping bounds
375 void sqlite3TreeViewBound(
376 TreeView
*pView
, /* View context */
377 u8 eBound
, /* UNBOUNDED, CURRENT, PRECEDING, FOLLOWING */
378 Expr
*pExpr
, /* Value for PRECEDING or FOLLOWING */
379 u8 moreToFollow
/* True if more to follow */
383 sqlite3TreeViewItem(pView
, "UNBOUNDED", moreToFollow
);
384 sqlite3TreeViewPop(&pView
);
388 sqlite3TreeViewItem(pView
, "CURRENT", moreToFollow
);
389 sqlite3TreeViewPop(&pView
);
393 sqlite3TreeViewItem(pView
, "PRECEDING", moreToFollow
);
394 sqlite3TreeViewExpr(pView
, pExpr
, 0);
395 sqlite3TreeViewPop(&pView
);
399 sqlite3TreeViewItem(pView
, "FOLLOWING", moreToFollow
);
400 sqlite3TreeViewExpr(pView
, pExpr
, 0);
401 sqlite3TreeViewPop(&pView
);
406 #endif /* SQLITE_OMIT_WINDOWFUNC */
408 #ifndef SQLITE_OMIT_WINDOWFUNC
410 ** Generate a human-readable explanation for a Window object
412 void sqlite3TreeViewWindow(TreeView
*pView
, const Window
*pWin
, u8 more
){
414 if( pWin
==0 ) return;
416 sqlite3TreeViewItem(pView
, "FILTER", 1);
417 sqlite3TreeViewExpr(pView
, pWin
->pFilter
, 0);
418 sqlite3TreeViewPop(&pView
);
419 if( pWin
->eFrmType
==TK_FILTER
) return;
421 sqlite3TreeViewPush(&pView
, more
);
423 sqlite3TreeViewLine(pView
, "OVER %s (%p)", pWin
->zName
, pWin
);
425 sqlite3TreeViewLine(pView
, "OVER (%p)", pWin
);
427 if( pWin
->zBase
) nElement
++;
428 if( pWin
->pOrderBy
) nElement
++;
429 if( pWin
->eFrmType
!=0 && pWin
->eFrmType
!=TK_FILTER
) nElement
++;
430 if( pWin
->eExclude
) nElement
++;
432 sqlite3TreeViewPush(&pView
, (--nElement
)>0);
433 sqlite3TreeViewLine(pView
, "window: %s", pWin
->zBase
);
434 sqlite3TreeViewPop(&pView
);
436 if( pWin
->pPartition
){
437 sqlite3TreeViewExprList(pView
, pWin
->pPartition
, nElement
>0,"PARTITION-BY");
439 if( pWin
->pOrderBy
){
440 sqlite3TreeViewExprList(pView
, pWin
->pOrderBy
, (--nElement
)>0, "ORDER-BY");
442 if( pWin
->eFrmType
!=0 && pWin
->eFrmType
!=TK_FILTER
){
444 const char *zFrmType
= "ROWS";
445 if( pWin
->eFrmType
==TK_RANGE
) zFrmType
= "RANGE";
446 if( pWin
->eFrmType
==TK_GROUPS
) zFrmType
= "GROUPS";
447 sqlite3_snprintf(sizeof(zBuf
),zBuf
,"%s%s",zFrmType
,
448 pWin
->bImplicitFrame
? " (implied)" : "");
449 sqlite3TreeViewItem(pView
, zBuf
, (--nElement
)>0);
450 sqlite3TreeViewBound(pView
, pWin
->eStart
, pWin
->pStart
, 1);
451 sqlite3TreeViewBound(pView
, pWin
->eEnd
, pWin
->pEnd
, 0);
452 sqlite3TreeViewPop(&pView
);
454 if( pWin
->eExclude
){
456 const char *zExclude
;
457 switch( pWin
->eExclude
){
458 case TK_NO
: zExclude
= "NO OTHERS"; break;
459 case TK_CURRENT
: zExclude
= "CURRENT ROW"; break;
460 case TK_GROUP
: zExclude
= "GROUP"; break;
461 case TK_TIES
: zExclude
= "TIES"; break;
463 sqlite3_snprintf(sizeof(zBuf
),zBuf
,"invalid(%d)", pWin
->eExclude
);
467 sqlite3TreeViewPush(&pView
, 0);
468 sqlite3TreeViewLine(pView
, "EXCLUDE %s", zExclude
);
469 sqlite3TreeViewPop(&pView
);
471 sqlite3TreeViewPop(&pView
);
473 #endif /* SQLITE_OMIT_WINDOWFUNC */
475 #ifndef SQLITE_OMIT_WINDOWFUNC
477 ** Generate a human-readable explanation for a Window Function object
479 void sqlite3TreeViewWinFunc(TreeView
*pView
, const Window
*pWin
, u8 more
){
480 if( pWin
==0 ) return;
481 sqlite3TreeViewPush(&pView
, more
);
482 sqlite3TreeViewLine(pView
, "WINFUNC %s(%d)",
483 pWin
->pWFunc
->zName
, pWin
->pWFunc
->nArg
);
484 sqlite3TreeViewWindow(pView
, pWin
, 0);
485 sqlite3TreeViewPop(&pView
);
487 #endif /* SQLITE_OMIT_WINDOWFUNC */
490 ** Generate a human-readable explanation of an expression tree.
492 void sqlite3TreeViewExpr(TreeView
*pView
, const Expr
*pExpr
, u8 moreToFollow
){
493 const char *zBinOp
= 0; /* Binary operator */
494 const char *zUniOp
= 0; /* Unary operator */
496 sqlite3TreeViewPush(&pView
, moreToFollow
);
498 sqlite3TreeViewLine(pView
, "nil");
499 sqlite3TreeViewPop(&pView
);
502 if( pExpr
->flags
|| pExpr
->affExpr
|| pExpr
->vvaFlags
|| pExpr
->pAggInfo
){
504 sqlite3StrAccumInit(&x
, 0, zFlgs
, sizeof(zFlgs
), 0);
505 sqlite3_str_appendf(&x
, " fg.af=%x.%c",
506 pExpr
->flags
, pExpr
->affExpr
? pExpr
->affExpr
: 'n');
507 if( ExprHasProperty(pExpr
, EP_OuterON
) ){
508 sqlite3_str_appendf(&x
, " outer.iJoin=%d", pExpr
->w
.iJoin
);
510 if( ExprHasProperty(pExpr
, EP_InnerON
) ){
511 sqlite3_str_appendf(&x
, " inner.iJoin=%d", pExpr
->w
.iJoin
);
513 if( ExprHasProperty(pExpr
, EP_FromDDL
) ){
514 sqlite3_str_appendf(&x
, " DDL");
516 if( ExprHasVVAProperty(pExpr
, EP_Immutable
) ){
517 sqlite3_str_appendf(&x
, " IMMUTABLE");
519 if( pExpr
->pAggInfo
!=0 ){
520 sqlite3_str_appendf(&x
, " agg-column[%d]", pExpr
->iAgg
);
522 sqlite3StrAccumFinish(&x
);
527 case TK_AGG_COLUMN
: {
528 sqlite3TreeViewLine(pView
, "AGG{%d:%d}%s",
529 pExpr
->iTable
, pExpr
->iColumn
, zFlgs
);
533 if( pExpr
->iTable
<0 ){
534 /* This only happens when coding check constraints */
537 sqlite3_snprintf(sizeof(zOp2
),zOp2
," op2=0x%02x",pExpr
->op2
);
541 sqlite3TreeViewLine(pView
, "COLUMN(%d)%s%s",
542 pExpr
->iColumn
, zFlgs
, zOp2
);
544 assert( ExprUseYTab(pExpr
) );
545 sqlite3TreeViewLine(pView
, "{%d:%d} pTab=%p%s",
546 pExpr
->iTable
, pExpr
->iColumn
,
547 pExpr
->y
.pTab
, zFlgs
);
549 if( ExprHasProperty(pExpr
, EP_FixedCol
) ){
550 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 0);
555 if( pExpr
->flags
& EP_IntValue
){
556 sqlite3TreeViewLine(pView
, "%d", pExpr
->u
.iValue
);
558 sqlite3TreeViewLine(pView
, "%s", pExpr
->u
.zToken
);
562 #ifndef SQLITE_OMIT_FLOATING_POINT
564 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
565 sqlite3TreeViewLine(pView
,"%s", pExpr
->u
.zToken
);
570 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
571 sqlite3TreeViewLine(pView
,"%Q", pExpr
->u
.zToken
);
575 sqlite3TreeViewLine(pView
,"NULL");
579 sqlite3TreeViewLine(pView
,"%s%s",
580 sqlite3ExprTruthValue(pExpr
) ? "TRUE" : "FALSE", zFlgs
);
583 #ifndef SQLITE_OMIT_BLOB_LITERAL
585 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
586 sqlite3TreeViewLine(pView
,"%s", pExpr
->u
.zToken
);
591 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
592 sqlite3TreeViewLine(pView
,"VARIABLE(%s,%d)",
593 pExpr
->u
.zToken
, pExpr
->iColumn
);
597 sqlite3TreeViewLine(pView
,"REGISTER(%d)", pExpr
->iTable
);
601 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
602 sqlite3TreeViewLine(pView
,"ID \"%w\"", pExpr
->u
.zToken
);
605 #ifndef SQLITE_OMIT_CAST
607 /* Expressions of the form: CAST(pLeft AS token) */
608 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
609 sqlite3TreeViewLine(pView
,"CAST %Q", pExpr
->u
.zToken
);
610 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 0);
613 #endif /* SQLITE_OMIT_CAST */
614 case TK_LT
: zBinOp
= "LT"; break;
615 case TK_LE
: zBinOp
= "LE"; break;
616 case TK_GT
: zBinOp
= "GT"; break;
617 case TK_GE
: zBinOp
= "GE"; break;
618 case TK_NE
: zBinOp
= "NE"; break;
619 case TK_EQ
: zBinOp
= "EQ"; break;
620 case TK_IS
: zBinOp
= "IS"; break;
621 case TK_ISNOT
: zBinOp
= "ISNOT"; break;
622 case TK_AND
: zBinOp
= "AND"; break;
623 case TK_OR
: zBinOp
= "OR"; break;
624 case TK_PLUS
: zBinOp
= "ADD"; break;
625 case TK_STAR
: zBinOp
= "MUL"; break;
626 case TK_MINUS
: zBinOp
= "SUB"; break;
627 case TK_REM
: zBinOp
= "REM"; break;
628 case TK_BITAND
: zBinOp
= "BITAND"; break;
629 case TK_BITOR
: zBinOp
= "BITOR"; break;
630 case TK_SLASH
: zBinOp
= "DIV"; break;
631 case TK_LSHIFT
: zBinOp
= "LSHIFT"; break;
632 case TK_RSHIFT
: zBinOp
= "RSHIFT"; break;
633 case TK_CONCAT
: zBinOp
= "CONCAT"; break;
634 case TK_DOT
: zBinOp
= "DOT"; break;
635 case TK_LIMIT
: zBinOp
= "LIMIT"; break;
637 case TK_UMINUS
: zUniOp
= "UMINUS"; break;
638 case TK_UPLUS
: zUniOp
= "UPLUS"; break;
639 case TK_BITNOT
: zUniOp
= "BITNOT"; break;
640 case TK_NOT
: zUniOp
= "NOT"; break;
641 case TK_ISNULL
: zUniOp
= "ISNULL"; break;
642 case TK_NOTNULL
: zUniOp
= "NOTNULL"; break;
646 const char *azOp
[] = {
647 "IS-FALSE", "IS-TRUE", "IS-NOT-FALSE", "IS-NOT-TRUE"
649 assert( pExpr
->op2
==TK_IS
|| pExpr
->op2
==TK_ISNOT
);
650 assert( pExpr
->pRight
);
651 assert( sqlite3ExprSkipCollateAndLikely(pExpr
->pRight
)->op
653 x
= (pExpr
->op2
==TK_ISNOT
)*2 + sqlite3ExprTruthValue(pExpr
->pRight
);
659 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
660 sqlite3TreeViewLine(pView
, "SPAN %Q", pExpr
->u
.zToken
);
661 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 0);
666 /* COLLATE operators without the EP_Collate flag are intended to
667 ** emulate collation associated with a table column. These show
668 ** up in the treeview output as "SOFT-COLLATE". Explicit COLLATE
669 ** operators that appear in the original SQL always have the
670 ** EP_Collate bit set and appear in treeview output as just "COLLATE" */
671 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
672 sqlite3TreeViewLine(pView
, "%sCOLLATE %Q%s",
673 !ExprHasProperty(pExpr
, EP_Collate
) ? "SOFT-" : "",
674 pExpr
->u
.zToken
, zFlgs
);
675 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 0);
679 case TK_AGG_FUNCTION
:
681 ExprList
*pFarg
; /* List of function arguments */
683 if( ExprHasProperty(pExpr
, EP_TokenOnly
) ){
687 assert( ExprUseXList(pExpr
) );
688 pFarg
= pExpr
->x
.pList
;
689 #ifndef SQLITE_OMIT_WINDOWFUNC
690 pWin
= IsWindowFunc(pExpr
) ? pExpr
->y
.pWin
: 0;
695 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
696 if( pExpr
->op
==TK_AGG_FUNCTION
){
697 sqlite3TreeViewLine(pView
, "AGG_FUNCTION%d %Q%s agg=%d[%d]/%p",
698 pExpr
->op2
, pExpr
->u
.zToken
, zFlgs
,
699 pExpr
->pAggInfo
? pExpr
->pAggInfo
->selId
: 0,
700 pExpr
->iAgg
, pExpr
->pAggInfo
);
701 }else if( pExpr
->op2
!=0 ){
704 sqlite3_snprintf(sizeof(zBuf
),zBuf
,"0x%02x",pExpr
->op2
);
706 if( pExpr
->op2
==NC_IsCheck
) zOp2
= "NC_IsCheck";
707 if( pExpr
->op2
==NC_IdxExpr
) zOp2
= "NC_IdxExpr";
708 if( pExpr
->op2
==NC_PartIdx
) zOp2
= "NC_PartIdx";
709 if( pExpr
->op2
==NC_GenCol
) zOp2
= "NC_GenCol";
710 sqlite3TreeViewLine(pView
, "FUNCTION %Q%s op2=%s",
711 pExpr
->u
.zToken
, zFlgs
, zOp2
);
713 sqlite3TreeViewLine(pView
, "FUNCTION %Q%s", pExpr
->u
.zToken
, zFlgs
);
716 sqlite3TreeViewExprList(pView
, pFarg
, pWin
!=0 || pExpr
->pLeft
, 0);
718 Expr
*pOB
= pExpr
->pLeft
;
719 assert( pOB
->op
==TK_ORDER
);
720 assert( ExprUseXList(pOB
) );
721 sqlite3TreeViewExprList(pView
, pOB
->x
.pList
, pWin
!=0, "ORDERBY");
724 #ifndef SQLITE_OMIT_WINDOWFUNC
726 sqlite3TreeViewWindow(pView
, pWin
, 0);
732 sqlite3TreeViewExprList(pView
, pExpr
->x
.pList
, 0, "ORDERBY");
735 #ifndef SQLITE_OMIT_SUBQUERY
737 assert( ExprUseXSelect(pExpr
) );
738 sqlite3TreeViewLine(pView
, "EXISTS-expr flags=0x%x", pExpr
->flags
);
739 sqlite3TreeViewSelect(pView
, pExpr
->x
.pSelect
, 0);
743 assert( ExprUseXSelect(pExpr
) );
744 sqlite3TreeViewLine(pView
, "subquery-expr flags=0x%x", pExpr
->flags
);
745 sqlite3TreeViewSelect(pView
, pExpr
->x
.pSelect
, 0);
749 sqlite3_str
*pStr
= sqlite3_str_new(0);
751 sqlite3_str_appendf(pStr
, "IN flags=0x%x", pExpr
->flags
);
752 if( pExpr
->iTable
) sqlite3_str_appendf(pStr
, " iTable=%d",pExpr
->iTable
);
753 if( ExprHasProperty(pExpr
, EP_Subrtn
) ){
754 sqlite3_str_appendf(pStr
, " subrtn(%d,%d)",
755 pExpr
->y
.sub
.regReturn
, pExpr
->y
.sub
.iAddr
);
757 z
= sqlite3_str_finish(pStr
);
758 sqlite3TreeViewLine(pView
, z
);
760 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 1);
761 if( ExprUseXSelect(pExpr
) ){
762 sqlite3TreeViewSelect(pView
, pExpr
->x
.pSelect
, 0);
764 sqlite3TreeViewExprList(pView
, pExpr
->x
.pList
, 0, 0);
768 #endif /* SQLITE_OMIT_SUBQUERY */
773 ** This is equivalent to
777 ** X is stored in pExpr->pLeft.
778 ** Y is stored in pExpr->pList->a[0].pExpr.
779 ** Z is stored in pExpr->pList->a[1].pExpr.
782 const Expr
*pX
, *pY
, *pZ
;
784 assert( ExprUseXList(pExpr
) );
785 assert( pExpr
->x
.pList
->nExpr
==2 );
786 pY
= pExpr
->x
.pList
->a
[0].pExpr
;
787 pZ
= pExpr
->x
.pList
->a
[1].pExpr
;
788 sqlite3TreeViewLine(pView
, "BETWEEN%s", zFlgs
);
789 sqlite3TreeViewExpr(pView
, pX
, 1);
790 sqlite3TreeViewExpr(pView
, pY
, 1);
791 sqlite3TreeViewExpr(pView
, pZ
, 0);
795 /* If the opcode is TK_TRIGGER, then the expression is a reference
796 ** to a column in the new.* or old.* pseudo-tables available to
797 ** trigger programs. In this case Expr.iTable is set to 1 for the
798 ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn
799 ** is set to the column of the pseudo-table to read, or to -1 to
800 ** read the rowid field.
802 sqlite3TreeViewLine(pView
, "%s(%d)",
803 pExpr
->iTable
? "NEW" : "OLD", pExpr
->iColumn
);
807 sqlite3TreeViewLine(pView
, "CASE");
808 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 1);
809 assert( ExprUseXList(pExpr
) );
810 sqlite3TreeViewExprList(pView
, pExpr
->x
.pList
, 0, 0);
813 #ifndef SQLITE_OMIT_TRIGGER
815 const char *zType
= "unk";
816 switch( pExpr
->affExpr
){
817 case OE_Rollback
: zType
= "rollback"; break;
818 case OE_Abort
: zType
= "abort"; break;
819 case OE_Fail
: zType
= "fail"; break;
820 case OE_Ignore
: zType
= "ignore"; break;
822 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
823 sqlite3TreeViewLine(pView
, "RAISE %s(%Q)", zType
, pExpr
->u
.zToken
);
828 sqlite3TreeViewLine(pView
, "MATCH {%d:%d}%s",
829 pExpr
->iTable
, pExpr
->iColumn
, zFlgs
);
830 sqlite3TreeViewExpr(pView
, pExpr
->pRight
, 0);
834 char *z
= sqlite3_mprintf("VECTOR%s",zFlgs
);
835 assert( ExprUseXList(pExpr
) );
836 sqlite3TreeViewBareExprList(pView
, pExpr
->x
.pList
, z
);
840 case TK_SELECT_COLUMN
: {
841 sqlite3TreeViewLine(pView
, "SELECT-COLUMN %d of [0..%d]%s",
842 pExpr
->iColumn
, pExpr
->iTable
-1,
843 pExpr
->pRight
==pExpr
->pLeft
? " (SELECT-owner)" : "");
844 assert( ExprUseXSelect(pExpr
->pLeft
) );
845 sqlite3TreeViewSelect(pView
, pExpr
->pLeft
->x
.pSelect
, 0);
848 case TK_IF_NULL_ROW
: {
849 sqlite3TreeViewLine(pView
, "IF-NULL-ROW %d", pExpr
->iTable
);
850 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 0);
855 sqlite3TreeViewLine(pView
, "ERROR");
858 sqlite3TreeViewExpr(pView
, &tmp
, 0);
862 if( pExpr
->iColumn
<=0 ){
863 sqlite3TreeViewLine(pView
, "First FROM table rowid");
865 sqlite3TreeViewLine(pView
, "First FROM table column %d",
871 sqlite3TreeViewLine(pView
, "op=%d", pExpr
->op
);
876 sqlite3TreeViewLine(pView
, "%s%s", zBinOp
, zFlgs
);
877 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 1);
878 sqlite3TreeViewExpr(pView
, pExpr
->pRight
, 0);
880 sqlite3TreeViewLine(pView
, "%s%s", zUniOp
, zFlgs
);
881 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 0);
883 sqlite3TreeViewPop(&pView
);
888 ** Generate a human-readable explanation of an expression list.
890 void sqlite3TreeViewBareExprList(
892 const ExprList
*pList
,
895 if( zLabel
==0 || zLabel
[0]==0 ) zLabel
= "LIST";
897 sqlite3TreeViewLine(pView
, "%s (empty)", zLabel
);
900 sqlite3TreeViewLine(pView
, "%s", zLabel
);
901 for(i
=0; i
<pList
->nExpr
; i
++){
902 int j
= pList
->a
[i
].u
.x
.iOrderByCol
;
903 char *zName
= pList
->a
[i
].zEName
;
904 int moreToFollow
= i
<pList
->nExpr
- 1;
906 sqlite3TreeViewPush(&pView
, moreToFollow
);
908 sqlite3TreeViewLine(pView
, 0);
910 switch( pList
->a
[i
].fg
.eEName
){
912 fprintf(stdout
, "AS %s ", zName
);
915 fprintf(stdout
, "TABLE-ALIAS-NAME(\"%s\") ", zName
);
916 if( pList
->a
[i
].fg
.bUsed
) fprintf(stdout
, "(used) ");
917 if( pList
->a
[i
].fg
.bUsingTerm
) fprintf(stdout
, "(USING-term) ");
918 if( pList
->a
[i
].fg
.bNoExpand
) fprintf(stdout
, "(NoExpand) ");
921 fprintf(stdout
, "SPAN(\"%s\") ", zName
);
926 fprintf(stdout
, "iOrderByCol=%d", j
);
928 fprintf(stdout
, "\n");
931 sqlite3TreeViewExpr(pView
, pList
->a
[i
].pExpr
, moreToFollow
);
933 sqlite3TreeViewPop(&pView
);
938 void sqlite3TreeViewExprList(
940 const ExprList
*pList
,
944 sqlite3TreeViewPush(&pView
, moreToFollow
);
945 sqlite3TreeViewBareExprList(pView
, pList
, zLabel
);
946 sqlite3TreeViewPop(&pView
);
950 ** Generate a human-readable explanation of an id-list.
952 void sqlite3TreeViewBareIdList(
957 if( zLabel
==0 || zLabel
[0]==0 ) zLabel
= "LIST";
959 sqlite3TreeViewLine(pView
, "%s (empty)", zLabel
);
962 sqlite3TreeViewLine(pView
, "%s", zLabel
);
963 for(i
=0; i
<pList
->nId
; i
++){
964 char *zName
= pList
->a
[i
].zName
;
965 int moreToFollow
= i
<pList
->nId
- 1;
966 if( zName
==0 ) zName
= "(null)";
967 sqlite3TreeViewPush(&pView
, moreToFollow
);
968 sqlite3TreeViewLine(pView
, 0);
969 if( pList
->eU4
==EU4_NONE
){
970 fprintf(stdout
, "%s\n", zName
);
971 }else if( pList
->eU4
==EU4_IDX
){
972 fprintf(stdout
, "%s (%d)\n", zName
, pList
->a
[i
].u4
.idx
);
974 assert( pList
->eU4
==EU4_EXPR
);
975 if( pList
->a
[i
].u4
.pExpr
==0 ){
976 fprintf(stdout
, "%s (pExpr=NULL)\n", zName
);
978 fprintf(stdout
, "%s\n", zName
);
979 sqlite3TreeViewPush(&pView
, i
<pList
->nId
-1);
980 sqlite3TreeViewExpr(pView
, pList
->a
[i
].u4
.pExpr
, 0);
981 sqlite3TreeViewPop(&pView
);
984 sqlite3TreeViewPop(&pView
);
988 void sqlite3TreeViewIdList(
994 sqlite3TreeViewPush(&pView
, moreToFollow
);
995 sqlite3TreeViewBareIdList(pView
, pList
, zLabel
);
996 sqlite3TreeViewPop(&pView
);
1000 ** Generate a human-readable explanation of a list of Upsert objects
1002 void sqlite3TreeViewUpsert(
1004 const Upsert
*pUpsert
,
1007 if( pUpsert
==0 ) return;
1008 sqlite3TreeViewPush(&pView
, moreToFollow
);
1011 sqlite3TreeViewPush(&pView
, pUpsert
->pNextUpsert
!=0 || moreToFollow
);
1012 sqlite3TreeViewLine(pView
, "ON CONFLICT DO %s",
1013 pUpsert
->isDoUpdate
? "UPDATE" : "NOTHING");
1014 n
= (pUpsert
->pUpsertSet
!=0) + (pUpsert
->pUpsertWhere
!=0);
1015 sqlite3TreeViewExprList(pView
, pUpsert
->pUpsertTarget
, (n
--)>0, "TARGET");
1016 sqlite3TreeViewExprList(pView
, pUpsert
->pUpsertSet
, (n
--)>0, "SET");
1017 if( pUpsert
->pUpsertWhere
){
1018 sqlite3TreeViewItem(pView
, "WHERE", (n
--)>0);
1019 sqlite3TreeViewExpr(pView
, pUpsert
->pUpsertWhere
, 0);
1020 sqlite3TreeViewPop(&pView
);
1022 sqlite3TreeViewPop(&pView
);
1023 pUpsert
= pUpsert
->pNextUpsert
;
1025 sqlite3TreeViewPop(&pView
);
1028 #if TREETRACE_ENABLED
1030 ** Generate a human-readable diagram of the data structure that go
1031 ** into generating an DELETE statement.
1033 void sqlite3TreeViewDelete(
1035 const SrcList
*pTabList
,
1037 const ExprList
*pOrderBy
,
1039 const Trigger
*pTrigger
1042 TreeView
*pView
= 0;
1043 sqlite3TreeViewPush(&pView
, 0);
1044 sqlite3TreeViewLine(pView
, "DELETE");
1052 sqlite3TreeViewPush(&pView
, (--n
)>0);
1053 sqlite3TreeViewWith(pView
, pWith
, 0);
1054 sqlite3TreeViewPop(&pView
);
1057 sqlite3TreeViewPush(&pView
, (--n
)>0);
1058 sqlite3TreeViewLine(pView
, "FROM");
1059 sqlite3TreeViewSrcList(pView
, pTabList
);
1060 sqlite3TreeViewPop(&pView
);
1063 sqlite3TreeViewPush(&pView
, (--n
)>0);
1064 sqlite3TreeViewLine(pView
, "WHERE");
1065 sqlite3TreeViewExpr(pView
, pWhere
, 0);
1066 sqlite3TreeViewPop(&pView
);
1069 sqlite3TreeViewExprList(pView
, pOrderBy
, (--n
)>0, "ORDER-BY");
1072 sqlite3TreeViewPush(&pView
, (--n
)>0);
1073 sqlite3TreeViewLine(pView
, "LIMIT");
1074 sqlite3TreeViewExpr(pView
, pLimit
, 0);
1075 sqlite3TreeViewPop(&pView
);
1078 sqlite3TreeViewTrigger(pView
, pTrigger
, (--n
)>0, 1);
1080 sqlite3TreeViewPop(&pView
);
1082 #endif /* TREETRACE_ENABLED */
1084 #if TREETRACE_ENABLED
1086 ** Generate a human-readable diagram of the data structure that go
1087 ** into generating an INSERT statement.
1089 void sqlite3TreeViewInsert(
1091 const SrcList
*pTabList
,
1092 const IdList
*pColumnList
,
1093 const Select
*pSelect
,
1094 const ExprList
*pExprList
,
1096 const Upsert
*pUpsert
,
1097 const Trigger
*pTrigger
1099 TreeView
*pView
= 0;
1101 const char *zLabel
= "INSERT";
1103 case OE_Replace
: zLabel
= "REPLACE"; break;
1104 case OE_Ignore
: zLabel
= "INSERT OR IGNORE"; break;
1105 case OE_Rollback
: zLabel
= "INSERT OR ROLLBACK"; break;
1106 case OE_Abort
: zLabel
= "INSERT OR ABORT"; break;
1107 case OE_Fail
: zLabel
= "INSERT OR FAIL"; break;
1109 sqlite3TreeViewPush(&pView
, 0);
1110 sqlite3TreeViewLine(pView
, zLabel
);
1113 if( pColumnList
) n
++;
1115 if( pExprList
) n
++;
1119 sqlite3TreeViewPush(&pView
, (--n
)>0);
1120 sqlite3TreeViewWith(pView
, pWith
, 0);
1121 sqlite3TreeViewPop(&pView
);
1124 sqlite3TreeViewPush(&pView
, (--n
)>0);
1125 sqlite3TreeViewLine(pView
, "INTO");
1126 sqlite3TreeViewSrcList(pView
, pTabList
);
1127 sqlite3TreeViewPop(&pView
);
1130 sqlite3TreeViewIdList(pView
, pColumnList
, (--n
)>0, "COLUMNS");
1133 sqlite3TreeViewPush(&pView
, (--n
)>0);
1134 sqlite3TreeViewLine(pView
, "DATA-SOURCE");
1135 sqlite3TreeViewSelect(pView
, pSelect
, 0);
1136 sqlite3TreeViewPop(&pView
);
1139 sqlite3TreeViewExprList(pView
, pExprList
, (--n
)>0, "VALUES");
1142 sqlite3TreeViewPush(&pView
, (--n
)>0);
1143 sqlite3TreeViewLine(pView
, "UPSERT");
1144 sqlite3TreeViewUpsert(pView
, pUpsert
, 0);
1145 sqlite3TreeViewPop(&pView
);
1148 sqlite3TreeViewTrigger(pView
, pTrigger
, (--n
)>0, 1);
1150 sqlite3TreeViewPop(&pView
);
1152 #endif /* TREETRACE_ENABLED */
1154 #if TREETRACE_ENABLED
1156 ** Generate a human-readable diagram of the data structure that go
1157 ** into generating an UPDATE statement.
1159 void sqlite3TreeViewUpdate(
1161 const SrcList
*pTabList
,
1162 const ExprList
*pChanges
,
1165 const ExprList
*pOrderBy
,
1167 const Upsert
*pUpsert
,
1168 const Trigger
*pTrigger
1171 TreeView
*pView
= 0;
1172 const char *zLabel
= "UPDATE";
1174 case OE_Replace
: zLabel
= "UPDATE OR REPLACE"; break;
1175 case OE_Ignore
: zLabel
= "UPDATE OR IGNORE"; break;
1176 case OE_Rollback
: zLabel
= "UPDATE OR ROLLBACK"; break;
1177 case OE_Abort
: zLabel
= "UPDATE OR ABORT"; break;
1178 case OE_Fail
: zLabel
= "UPDATE OR FAIL"; break;
1180 sqlite3TreeViewPush(&pView
, 0);
1181 sqlite3TreeViewLine(pView
, zLabel
);
1191 sqlite3TreeViewPush(&pView
, (--n
)>0);
1192 sqlite3TreeViewWith(pView
, pWith
, 0);
1193 sqlite3TreeViewPop(&pView
);
1196 sqlite3TreeViewPush(&pView
, (--n
)>0);
1197 sqlite3TreeViewLine(pView
, "FROM");
1198 sqlite3TreeViewSrcList(pView
, pTabList
);
1199 sqlite3TreeViewPop(&pView
);
1202 sqlite3TreeViewExprList(pView
, pChanges
, (--n
)>0, "SET");
1205 sqlite3TreeViewPush(&pView
, (--n
)>0);
1206 sqlite3TreeViewLine(pView
, "WHERE");
1207 sqlite3TreeViewExpr(pView
, pWhere
, 0);
1208 sqlite3TreeViewPop(&pView
);
1211 sqlite3TreeViewExprList(pView
, pOrderBy
, (--n
)>0, "ORDER-BY");
1214 sqlite3TreeViewPush(&pView
, (--n
)>0);
1215 sqlite3TreeViewLine(pView
, "LIMIT");
1216 sqlite3TreeViewExpr(pView
, pLimit
, 0);
1217 sqlite3TreeViewPop(&pView
);
1220 sqlite3TreeViewPush(&pView
, (--n
)>0);
1221 sqlite3TreeViewLine(pView
, "UPSERT");
1222 sqlite3TreeViewUpsert(pView
, pUpsert
, 0);
1223 sqlite3TreeViewPop(&pView
);
1226 sqlite3TreeViewTrigger(pView
, pTrigger
, (--n
)>0, 1);
1228 sqlite3TreeViewPop(&pView
);
1230 #endif /* TREETRACE_ENABLED */
1232 #ifndef SQLITE_OMIT_TRIGGER
1234 ** Show a human-readable graph of a TriggerStep
1236 void sqlite3TreeViewTriggerStep(
1238 const TriggerStep
*pStep
,
1243 if( pStep
==0 ) return;
1244 sqlite3TreeViewPush(&pView
,
1245 moreToFollow
|| (showFullList
&& pStep
->pNext
!=0));
1247 if( cnt
++ && pStep
->pNext
==0 ){
1248 sqlite3TreeViewPop(&pView
);
1249 sqlite3TreeViewPush(&pView
, 0);
1251 sqlite3TreeViewLine(pView
, "%s", pStep
->zSpan
? pStep
->zSpan
: "RETURNING");
1252 }while( showFullList
&& (pStep
= pStep
->pNext
)!=0 );
1253 sqlite3TreeViewPop(&pView
);
1257 ** Show a human-readable graph of a Trigger
1259 void sqlite3TreeViewTrigger(
1261 const Trigger
*pTrigger
,
1266 if( pTrigger
==0 ) return;
1267 sqlite3TreeViewPush(&pView
,
1268 moreToFollow
|| (showFullList
&& pTrigger
->pNext
!=0));
1270 if( cnt
++ && pTrigger
->pNext
==0 ){
1271 sqlite3TreeViewPop(&pView
);
1272 sqlite3TreeViewPush(&pView
, 0);
1274 sqlite3TreeViewLine(pView
, "TRIGGER %s", pTrigger
->zName
);
1275 sqlite3TreeViewPush(&pView
, 0);
1276 sqlite3TreeViewTriggerStep(pView
, pTrigger
->step_list
, 0, 1);
1277 sqlite3TreeViewPop(&pView
);
1278 }while( showFullList
&& (pTrigger
= pTrigger
->pNext
)!=0 );
1279 sqlite3TreeViewPop(&pView
);
1281 #endif /* SQLITE_OMIT_TRIGGER */
1285 ** These simplified versions of the tree-view routines omit unnecessary
1286 ** parameters. These variants are intended to be used from a symbolic
1287 ** debugger, such as "gdb", during interactive debugging sessions.
1289 ** This routines are given external linkage so that they will always be
1290 ** accessible to the debugging, and to avoid warnings about unused
1291 ** functions. But these routines only exist in debugging builds, so they
1292 ** do not contaminate the interface.
1294 void sqlite3ShowExpr(const Expr
*p
){ sqlite3TreeViewExpr(0,p
,0); }
1295 void sqlite3ShowExprList(const ExprList
*p
){ sqlite3TreeViewExprList(0,p
,0,0);}
1296 void sqlite3ShowIdList(const IdList
*p
){ sqlite3TreeViewIdList(0,p
,0,0); }
1297 void sqlite3ShowSrcList(const SrcList
*p
){ sqlite3TreeViewSrcList(0,p
); }
1298 void sqlite3ShowSelect(const Select
*p
){ sqlite3TreeViewSelect(0,p
,0); }
1299 void sqlite3ShowWith(const With
*p
){ sqlite3TreeViewWith(0,p
,0); }
1300 void sqlite3ShowUpsert(const Upsert
*p
){ sqlite3TreeViewUpsert(0,p
,0); }
1301 #ifndef SQLITE_OMIT_TRIGGER
1302 void sqlite3ShowTriggerStep(const TriggerStep
*p
){
1303 sqlite3TreeViewTriggerStep(0,p
,0,0);
1305 void sqlite3ShowTriggerStepList(const TriggerStep
*p
){
1306 sqlite3TreeViewTriggerStep(0,p
,0,1);
1308 void sqlite3ShowTrigger(const Trigger
*p
){ sqlite3TreeViewTrigger(0,p
,0,0); }
1309 void sqlite3ShowTriggerList(const Trigger
*p
){ sqlite3TreeViewTrigger(0,p
,0,1);}
1311 #ifndef SQLITE_OMIT_WINDOWFUNC
1312 void sqlite3ShowWindow(const Window
*p
){ sqlite3TreeViewWindow(0,p
,0); }
1313 void sqlite3ShowWinFunc(const Window
*p
){ sqlite3TreeViewWinFunc(0,p
,0); }
1316 #endif /* SQLITE_DEBUG */