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",
198 pItem
->pTab
->zName
, pItem
->pTab
->nCol
, pItem
->pTab
, pItem
->colUsed
);
200 if( (pItem
->fg
.jointype
& (JT_LEFT
|JT_RIGHT
))==(JT_LEFT
|JT_RIGHT
) ){
201 sqlite3_str_appendf(&x
, " FULL-OUTER-JOIN");
202 }else if( pItem
->fg
.jointype
& JT_LEFT
){
203 sqlite3_str_appendf(&x
, " LEFT-JOIN");
204 }else if( pItem
->fg
.jointype
& JT_RIGHT
){
205 sqlite3_str_appendf(&x
, " RIGHT-JOIN");
206 }else if( pItem
->fg
.jointype
& JT_CROSS
){
207 sqlite3_str_appendf(&x
, " CROSS-JOIN");
209 if( pItem
->fg
.jointype
& JT_LTORJ
){
210 sqlite3_str_appendf(&x
, " LTORJ");
212 if( pItem
->fg
.fromDDL
){
213 sqlite3_str_appendf(&x
, " DDL");
215 if( pItem
->fg
.isCte
){
216 sqlite3_str_appendf(&x
, " CteUse=0x%p", pItem
->u2
.pCteUse
);
218 if( pItem
->fg
.isOn
|| (pItem
->fg
.isUsing
==0 && pItem
->u3
.pOn
!=0) ){
219 sqlite3_str_appendf(&x
, " ON");
221 if( pItem
->fg
.isTabFunc
) sqlite3_str_appendf(&x
, " isTabFunc");
222 if( pItem
->fg
.isCorrelated
) sqlite3_str_appendf(&x
, " isCorrelated");
223 if( pItem
->fg
.isMaterialized
) sqlite3_str_appendf(&x
, " isMaterialized");
224 if( pItem
->fg
.viaCoroutine
) sqlite3_str_appendf(&x
, " viaCoroutine");
225 if( pItem
->fg
.notCte
) sqlite3_str_appendf(&x
, " notCte");
226 if( pItem
->fg
.isNestedFrom
) sqlite3_str_appendf(&x
, " isNestedFrom");
228 sqlite3StrAccumFinish(&x
);
229 sqlite3TreeViewItem(pView
, zLine
, i
<pSrc
->nSrc
-1);
231 if( pItem
->pSelect
) n
++;
232 if( pItem
->fg
.isTabFunc
) n
++;
233 if( pItem
->fg
.isUsing
) n
++;
234 if( pItem
->fg
.isUsing
){
235 sqlite3TreeViewIdList(pView
, pItem
->u3
.pUsing
, (--n
)>0, "USING");
237 if( pItem
->pSelect
){
239 Table
*pTab
= pItem
->pTab
;
240 sqlite3TreeViewColumnList(pView
, pTab
->aCol
, pTab
->nCol
, 1);
242 assert( (int)pItem
->fg
.isNestedFrom
== IsNestedFrom(pItem
->pSelect
) );
243 sqlite3TreeViewSelect(pView
, pItem
->pSelect
, (--n
)>0);
245 if( pItem
->fg
.isTabFunc
){
246 sqlite3TreeViewExprList(pView
, pItem
->u1
.pFuncArg
, 0, "func-args:");
248 sqlite3TreeViewPop(&pView
);
253 ** Generate a human-readable description of a Select object.
255 void sqlite3TreeViewSelect(TreeView
*pView
, const Select
*p
, u8 moreToFollow
){
259 sqlite3TreeViewLine(pView
, "nil-SELECT");
262 sqlite3TreeViewPush(&pView
, moreToFollow
);
264 sqlite3TreeViewWith(pView
, p
->pWith
, 1);
266 sqlite3TreeViewPush(&pView
, 1);
269 if( p
->selFlags
& SF_WhereBegin
){
270 sqlite3TreeViewLine(pView
, "sqlite3WhereBegin()");
272 sqlite3TreeViewLine(pView
,
273 "SELECT%s%s (%u/%p) selFlags=0x%x nSelectRow=%d",
274 ((p
->selFlags
& SF_Distinct
) ? " DISTINCT" : ""),
275 ((p
->selFlags
& SF_Aggregate
) ? " agg_flag" : ""),
276 p
->selId
, p
, p
->selFlags
,
280 if( cnt
++ ) sqlite3TreeViewPop(&pView
);
285 if( p
->pSrc
&& p
->pSrc
->nSrc
) n
++;
287 if( p
->pGroupBy
) n
++;
288 if( p
->pHaving
) n
++;
289 if( p
->pOrderBy
) n
++;
291 #ifndef SQLITE_OMIT_WINDOWFUNC
293 if( p
->pWinDefn
) n
++;
297 sqlite3TreeViewExprList(pView
, p
->pEList
, n
>0, "result-set");
300 #ifndef SQLITE_OMIT_WINDOWFUNC
303 sqlite3TreeViewPush(&pView
, (n
--)>0);
304 sqlite3TreeViewLine(pView
, "window-functions");
305 for(pX
=p
->pWin
; pX
; pX
=pX
->pNextWin
){
306 sqlite3TreeViewWinFunc(pView
, pX
, pX
->pNextWin
!=0);
308 sqlite3TreeViewPop(&pView
);
311 if( p
->pSrc
&& p
->pSrc
->nSrc
){
312 sqlite3TreeViewPush(&pView
, (n
--)>0);
313 sqlite3TreeViewLine(pView
, "FROM");
314 sqlite3TreeViewSrcList(pView
, p
->pSrc
);
315 sqlite3TreeViewPop(&pView
);
318 sqlite3TreeViewItem(pView
, "WHERE", (n
--)>0);
319 sqlite3TreeViewExpr(pView
, p
->pWhere
, 0);
320 sqlite3TreeViewPop(&pView
);
323 sqlite3TreeViewExprList(pView
, p
->pGroupBy
, (n
--)>0, "GROUPBY");
326 sqlite3TreeViewItem(pView
, "HAVING", (n
--)>0);
327 sqlite3TreeViewExpr(pView
, p
->pHaving
, 0);
328 sqlite3TreeViewPop(&pView
);
330 #ifndef SQLITE_OMIT_WINDOWFUNC
333 sqlite3TreeViewItem(pView
, "WINDOW", (n
--)>0);
334 for(pX
=p
->pWinDefn
; pX
; pX
=pX
->pNextWin
){
335 sqlite3TreeViewWindow(pView
, pX
, pX
->pNextWin
!=0);
337 sqlite3TreeViewPop(&pView
);
341 sqlite3TreeViewExprList(pView
, p
->pOrderBy
, (n
--)>0, "ORDERBY");
344 sqlite3TreeViewItem(pView
, "LIMIT", (n
--)>0);
345 sqlite3TreeViewExpr(pView
, p
->pLimit
->pLeft
, p
->pLimit
->pRight
!=0);
346 if( p
->pLimit
->pRight
){
347 sqlite3TreeViewItem(pView
, "OFFSET", (n
--)>0);
348 sqlite3TreeViewExpr(pView
, p
->pLimit
->pRight
, 0);
349 sqlite3TreeViewPop(&pView
);
351 sqlite3TreeViewPop(&pView
);
354 const char *zOp
= "UNION";
356 case TK_ALL
: zOp
= "UNION ALL"; break;
357 case TK_INTERSECT
: zOp
= "INTERSECT"; break;
358 case TK_EXCEPT
: zOp
= "EXCEPT"; break;
360 sqlite3TreeViewItem(pView
, zOp
, 1);
364 sqlite3TreeViewPop(&pView
);
367 #ifndef SQLITE_OMIT_WINDOWFUNC
369 ** Generate a description of starting or stopping bounds
371 void sqlite3TreeViewBound(
372 TreeView
*pView
, /* View context */
373 u8 eBound
, /* UNBOUNDED, CURRENT, PRECEDING, FOLLOWING */
374 Expr
*pExpr
, /* Value for PRECEDING or FOLLOWING */
375 u8 moreToFollow
/* True if more to follow */
379 sqlite3TreeViewItem(pView
, "UNBOUNDED", moreToFollow
);
380 sqlite3TreeViewPop(&pView
);
384 sqlite3TreeViewItem(pView
, "CURRENT", moreToFollow
);
385 sqlite3TreeViewPop(&pView
);
389 sqlite3TreeViewItem(pView
, "PRECEDING", moreToFollow
);
390 sqlite3TreeViewExpr(pView
, pExpr
, 0);
391 sqlite3TreeViewPop(&pView
);
395 sqlite3TreeViewItem(pView
, "FOLLOWING", moreToFollow
);
396 sqlite3TreeViewExpr(pView
, pExpr
, 0);
397 sqlite3TreeViewPop(&pView
);
402 #endif /* SQLITE_OMIT_WINDOWFUNC */
404 #ifndef SQLITE_OMIT_WINDOWFUNC
406 ** Generate a human-readable explanation for a Window object
408 void sqlite3TreeViewWindow(TreeView
*pView
, const Window
*pWin
, u8 more
){
410 if( pWin
==0 ) return;
412 sqlite3TreeViewItem(pView
, "FILTER", 1);
413 sqlite3TreeViewExpr(pView
, pWin
->pFilter
, 0);
414 sqlite3TreeViewPop(&pView
);
415 if( pWin
->eFrmType
==TK_FILTER
) return;
417 sqlite3TreeViewPush(&pView
, more
);
419 sqlite3TreeViewLine(pView
, "OVER %s (%p)", pWin
->zName
, pWin
);
421 sqlite3TreeViewLine(pView
, "OVER (%p)", pWin
);
423 if( pWin
->zBase
) nElement
++;
424 if( pWin
->pOrderBy
) nElement
++;
425 if( pWin
->eFrmType
!=0 && pWin
->eFrmType
!=TK_FILTER
) nElement
++;
426 if( pWin
->eExclude
) nElement
++;
428 sqlite3TreeViewPush(&pView
, (--nElement
)>0);
429 sqlite3TreeViewLine(pView
, "window: %s", pWin
->zBase
);
430 sqlite3TreeViewPop(&pView
);
432 if( pWin
->pPartition
){
433 sqlite3TreeViewExprList(pView
, pWin
->pPartition
, nElement
>0,"PARTITION-BY");
435 if( pWin
->pOrderBy
){
436 sqlite3TreeViewExprList(pView
, pWin
->pOrderBy
, (--nElement
)>0, "ORDER-BY");
438 if( pWin
->eFrmType
!=0 && pWin
->eFrmType
!=TK_FILTER
){
440 const char *zFrmType
= "ROWS";
441 if( pWin
->eFrmType
==TK_RANGE
) zFrmType
= "RANGE";
442 if( pWin
->eFrmType
==TK_GROUPS
) zFrmType
= "GROUPS";
443 sqlite3_snprintf(sizeof(zBuf
),zBuf
,"%s%s",zFrmType
,
444 pWin
->bImplicitFrame
? " (implied)" : "");
445 sqlite3TreeViewItem(pView
, zBuf
, (--nElement
)>0);
446 sqlite3TreeViewBound(pView
, pWin
->eStart
, pWin
->pStart
, 1);
447 sqlite3TreeViewBound(pView
, pWin
->eEnd
, pWin
->pEnd
, 0);
448 sqlite3TreeViewPop(&pView
);
450 if( pWin
->eExclude
){
452 const char *zExclude
;
453 switch( pWin
->eExclude
){
454 case TK_NO
: zExclude
= "NO OTHERS"; break;
455 case TK_CURRENT
: zExclude
= "CURRENT ROW"; break;
456 case TK_GROUP
: zExclude
= "GROUP"; break;
457 case TK_TIES
: zExclude
= "TIES"; break;
459 sqlite3_snprintf(sizeof(zBuf
),zBuf
,"invalid(%d)", pWin
->eExclude
);
463 sqlite3TreeViewPush(&pView
, 0);
464 sqlite3TreeViewLine(pView
, "EXCLUDE %s", zExclude
);
465 sqlite3TreeViewPop(&pView
);
467 sqlite3TreeViewPop(&pView
);
469 #endif /* SQLITE_OMIT_WINDOWFUNC */
471 #ifndef SQLITE_OMIT_WINDOWFUNC
473 ** Generate a human-readable explanation for a Window Function object
475 void sqlite3TreeViewWinFunc(TreeView
*pView
, const Window
*pWin
, u8 more
){
476 if( pWin
==0 ) return;
477 sqlite3TreeViewPush(&pView
, more
);
478 sqlite3TreeViewLine(pView
, "WINFUNC %s(%d)",
479 pWin
->pWFunc
->zName
, pWin
->pWFunc
->nArg
);
480 sqlite3TreeViewWindow(pView
, pWin
, 0);
481 sqlite3TreeViewPop(&pView
);
483 #endif /* SQLITE_OMIT_WINDOWFUNC */
486 ** Generate a human-readable explanation of an expression tree.
488 void sqlite3TreeViewExpr(TreeView
*pView
, const Expr
*pExpr
, u8 moreToFollow
){
489 const char *zBinOp
= 0; /* Binary operator */
490 const char *zUniOp
= 0; /* Unary operator */
492 sqlite3TreeViewPush(&pView
, moreToFollow
);
494 sqlite3TreeViewLine(pView
, "nil");
495 sqlite3TreeViewPop(&pView
);
498 if( pExpr
->flags
|| pExpr
->affExpr
|| pExpr
->vvaFlags
|| pExpr
->pAggInfo
){
500 sqlite3StrAccumInit(&x
, 0, zFlgs
, sizeof(zFlgs
), 0);
501 sqlite3_str_appendf(&x
, " fg.af=%x.%c",
502 pExpr
->flags
, pExpr
->affExpr
? pExpr
->affExpr
: 'n');
503 if( ExprHasProperty(pExpr
, EP_OuterON
) ){
504 sqlite3_str_appendf(&x
, " outer.iJoin=%d", pExpr
->w
.iJoin
);
506 if( ExprHasProperty(pExpr
, EP_InnerON
) ){
507 sqlite3_str_appendf(&x
, " inner.iJoin=%d", pExpr
->w
.iJoin
);
509 if( ExprHasProperty(pExpr
, EP_FromDDL
) ){
510 sqlite3_str_appendf(&x
, " DDL");
512 if( ExprHasVVAProperty(pExpr
, EP_Immutable
) ){
513 sqlite3_str_appendf(&x
, " IMMUTABLE");
515 if( pExpr
->pAggInfo
!=0 ){
516 sqlite3_str_appendf(&x
, " agg-column[%d]", pExpr
->iAgg
);
518 sqlite3StrAccumFinish(&x
);
523 case TK_AGG_COLUMN
: {
524 sqlite3TreeViewLine(pView
, "AGG{%d:%d}%s",
525 pExpr
->iTable
, pExpr
->iColumn
, zFlgs
);
529 if( pExpr
->iTable
<0 ){
530 /* This only happens when coding check constraints */
533 sqlite3_snprintf(sizeof(zOp2
),zOp2
," op2=0x%02x",pExpr
->op2
);
537 sqlite3TreeViewLine(pView
, "COLUMN(%d)%s%s",
538 pExpr
->iColumn
, zFlgs
, zOp2
);
540 assert( ExprUseYTab(pExpr
) );
541 sqlite3TreeViewLine(pView
, "{%d:%d} pTab=%p%s",
542 pExpr
->iTable
, pExpr
->iColumn
,
543 pExpr
->y
.pTab
, zFlgs
);
545 if( ExprHasProperty(pExpr
, EP_FixedCol
) ){
546 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 0);
551 if( pExpr
->flags
& EP_IntValue
){
552 sqlite3TreeViewLine(pView
, "%d", pExpr
->u
.iValue
);
554 sqlite3TreeViewLine(pView
, "%s", pExpr
->u
.zToken
);
558 #ifndef SQLITE_OMIT_FLOATING_POINT
560 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
561 sqlite3TreeViewLine(pView
,"%s", pExpr
->u
.zToken
);
566 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
567 sqlite3TreeViewLine(pView
,"%Q", pExpr
->u
.zToken
);
571 sqlite3TreeViewLine(pView
,"NULL");
575 sqlite3TreeViewLine(pView
,"%s%s",
576 sqlite3ExprTruthValue(pExpr
) ? "TRUE" : "FALSE", zFlgs
);
579 #ifndef SQLITE_OMIT_BLOB_LITERAL
581 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
582 sqlite3TreeViewLine(pView
,"%s", pExpr
->u
.zToken
);
587 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
588 sqlite3TreeViewLine(pView
,"VARIABLE(%s,%d)",
589 pExpr
->u
.zToken
, pExpr
->iColumn
);
593 sqlite3TreeViewLine(pView
,"REGISTER(%d)", pExpr
->iTable
);
597 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
598 sqlite3TreeViewLine(pView
,"ID \"%w\"", pExpr
->u
.zToken
);
601 #ifndef SQLITE_OMIT_CAST
603 /* Expressions of the form: CAST(pLeft AS token) */
604 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
605 sqlite3TreeViewLine(pView
,"CAST %Q", pExpr
->u
.zToken
);
606 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 0);
609 #endif /* SQLITE_OMIT_CAST */
610 case TK_LT
: zBinOp
= "LT"; break;
611 case TK_LE
: zBinOp
= "LE"; break;
612 case TK_GT
: zBinOp
= "GT"; break;
613 case TK_GE
: zBinOp
= "GE"; break;
614 case TK_NE
: zBinOp
= "NE"; break;
615 case TK_EQ
: zBinOp
= "EQ"; break;
616 case TK_IS
: zBinOp
= "IS"; break;
617 case TK_ISNOT
: zBinOp
= "ISNOT"; break;
618 case TK_AND
: zBinOp
= "AND"; break;
619 case TK_OR
: zBinOp
= "OR"; break;
620 case TK_PLUS
: zBinOp
= "ADD"; break;
621 case TK_STAR
: zBinOp
= "MUL"; break;
622 case TK_MINUS
: zBinOp
= "SUB"; break;
623 case TK_REM
: zBinOp
= "REM"; break;
624 case TK_BITAND
: zBinOp
= "BITAND"; break;
625 case TK_BITOR
: zBinOp
= "BITOR"; break;
626 case TK_SLASH
: zBinOp
= "DIV"; break;
627 case TK_LSHIFT
: zBinOp
= "LSHIFT"; break;
628 case TK_RSHIFT
: zBinOp
= "RSHIFT"; break;
629 case TK_CONCAT
: zBinOp
= "CONCAT"; break;
630 case TK_DOT
: zBinOp
= "DOT"; break;
631 case TK_LIMIT
: zBinOp
= "LIMIT"; break;
633 case TK_UMINUS
: zUniOp
= "UMINUS"; break;
634 case TK_UPLUS
: zUniOp
= "UPLUS"; break;
635 case TK_BITNOT
: zUniOp
= "BITNOT"; break;
636 case TK_NOT
: zUniOp
= "NOT"; break;
637 case TK_ISNULL
: zUniOp
= "ISNULL"; break;
638 case TK_NOTNULL
: zUniOp
= "NOTNULL"; break;
642 const char *azOp
[] = {
643 "IS-FALSE", "IS-TRUE", "IS-NOT-FALSE", "IS-NOT-TRUE"
645 assert( pExpr
->op2
==TK_IS
|| pExpr
->op2
==TK_ISNOT
);
646 assert( pExpr
->pRight
);
647 assert( sqlite3ExprSkipCollateAndLikely(pExpr
->pRight
)->op
649 x
= (pExpr
->op2
==TK_ISNOT
)*2 + sqlite3ExprTruthValue(pExpr
->pRight
);
655 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
656 sqlite3TreeViewLine(pView
, "SPAN %Q", pExpr
->u
.zToken
);
657 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 0);
662 /* COLLATE operators without the EP_Collate flag are intended to
663 ** emulate collation associated with a table column. These show
664 ** up in the treeview output as "SOFT-COLLATE". Explicit COLLATE
665 ** operators that appear in the original SQL always have the
666 ** EP_Collate bit set and appear in treeview output as just "COLLATE" */
667 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
668 sqlite3TreeViewLine(pView
, "%sCOLLATE %Q%s",
669 !ExprHasProperty(pExpr
, EP_Collate
) ? "SOFT-" : "",
670 pExpr
->u
.zToken
, zFlgs
);
671 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 0);
675 case TK_AGG_FUNCTION
:
677 ExprList
*pFarg
; /* List of function arguments */
679 if( ExprHasProperty(pExpr
, EP_TokenOnly
) ){
683 assert( ExprUseXList(pExpr
) );
684 pFarg
= pExpr
->x
.pList
;
685 #ifndef SQLITE_OMIT_WINDOWFUNC
686 pWin
= IsWindowFunc(pExpr
) ? pExpr
->y
.pWin
: 0;
691 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
692 if( pExpr
->op
==TK_AGG_FUNCTION
){
693 sqlite3TreeViewLine(pView
, "AGG_FUNCTION%d %Q%s agg=%d[%d]/%p",
694 pExpr
->op2
, pExpr
->u
.zToken
, zFlgs
,
695 pExpr
->pAggInfo
? pExpr
->pAggInfo
->selId
: 0,
696 pExpr
->iAgg
, pExpr
->pAggInfo
);
697 }else if( pExpr
->op2
!=0 ){
700 sqlite3_snprintf(sizeof(zBuf
),zBuf
,"0x%02x",pExpr
->op2
);
702 if( pExpr
->op2
==NC_IsCheck
) zOp2
= "NC_IsCheck";
703 if( pExpr
->op2
==NC_IdxExpr
) zOp2
= "NC_IdxExpr";
704 if( pExpr
->op2
==NC_PartIdx
) zOp2
= "NC_PartIdx";
705 if( pExpr
->op2
==NC_GenCol
) zOp2
= "NC_GenCol";
706 sqlite3TreeViewLine(pView
, "FUNCTION %Q%s op2=%s",
707 pExpr
->u
.zToken
, zFlgs
, zOp2
);
709 sqlite3TreeViewLine(pView
, "FUNCTION %Q%s", pExpr
->u
.zToken
, zFlgs
);
712 sqlite3TreeViewExprList(pView
, pFarg
, pWin
!=0 || pExpr
->pLeft
, 0);
714 Expr
*pOB
= pExpr
->pLeft
;
715 assert( pOB
->op
==TK_ORDER
);
716 assert( ExprUseXList(pOB
) );
717 sqlite3TreeViewExprList(pView
, pOB
->x
.pList
, pWin
!=0, "ORDERBY");
720 #ifndef SQLITE_OMIT_WINDOWFUNC
722 sqlite3TreeViewWindow(pView
, pWin
, 0);
728 sqlite3TreeViewExprList(pView
, pExpr
->x
.pList
, 0, "ORDERBY");
731 #ifndef SQLITE_OMIT_SUBQUERY
733 assert( ExprUseXSelect(pExpr
) );
734 sqlite3TreeViewLine(pView
, "EXISTS-expr flags=0x%x", pExpr
->flags
);
735 sqlite3TreeViewSelect(pView
, pExpr
->x
.pSelect
, 0);
739 assert( ExprUseXSelect(pExpr
) );
740 sqlite3TreeViewLine(pView
, "subquery-expr flags=0x%x", pExpr
->flags
);
741 sqlite3TreeViewSelect(pView
, pExpr
->x
.pSelect
, 0);
745 sqlite3_str
*pStr
= sqlite3_str_new(0);
747 sqlite3_str_appendf(pStr
, "IN flags=0x%x", pExpr
->flags
);
748 if( pExpr
->iTable
) sqlite3_str_appendf(pStr
, " iTable=%d",pExpr
->iTable
);
749 if( ExprHasProperty(pExpr
, EP_Subrtn
) ){
750 sqlite3_str_appendf(pStr
, " subrtn(%d,%d)",
751 pExpr
->y
.sub
.regReturn
, pExpr
->y
.sub
.iAddr
);
753 z
= sqlite3_str_finish(pStr
);
754 sqlite3TreeViewLine(pView
, z
);
756 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 1);
757 if( ExprUseXSelect(pExpr
) ){
758 sqlite3TreeViewSelect(pView
, pExpr
->x
.pSelect
, 0);
760 sqlite3TreeViewExprList(pView
, pExpr
->x
.pList
, 0, 0);
764 #endif /* SQLITE_OMIT_SUBQUERY */
769 ** This is equivalent to
773 ** X is stored in pExpr->pLeft.
774 ** Y is stored in pExpr->pList->a[0].pExpr.
775 ** Z is stored in pExpr->pList->a[1].pExpr.
778 const Expr
*pX
, *pY
, *pZ
;
780 assert( ExprUseXList(pExpr
) );
781 assert( pExpr
->x
.pList
->nExpr
==2 );
782 pY
= pExpr
->x
.pList
->a
[0].pExpr
;
783 pZ
= pExpr
->x
.pList
->a
[1].pExpr
;
784 sqlite3TreeViewLine(pView
, "BETWEEN");
785 sqlite3TreeViewExpr(pView
, pX
, 1);
786 sqlite3TreeViewExpr(pView
, pY
, 1);
787 sqlite3TreeViewExpr(pView
, pZ
, 0);
791 /* If the opcode is TK_TRIGGER, then the expression is a reference
792 ** to a column in the new.* or old.* pseudo-tables available to
793 ** trigger programs. In this case Expr.iTable is set to 1 for the
794 ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn
795 ** is set to the column of the pseudo-table to read, or to -1 to
796 ** read the rowid field.
798 sqlite3TreeViewLine(pView
, "%s(%d)",
799 pExpr
->iTable
? "NEW" : "OLD", pExpr
->iColumn
);
803 sqlite3TreeViewLine(pView
, "CASE");
804 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 1);
805 assert( ExprUseXList(pExpr
) );
806 sqlite3TreeViewExprList(pView
, pExpr
->x
.pList
, 0, 0);
809 #ifndef SQLITE_OMIT_TRIGGER
811 const char *zType
= "unk";
812 switch( pExpr
->affExpr
){
813 case OE_Rollback
: zType
= "rollback"; break;
814 case OE_Abort
: zType
= "abort"; break;
815 case OE_Fail
: zType
= "fail"; break;
816 case OE_Ignore
: zType
= "ignore"; break;
818 assert( !ExprHasProperty(pExpr
, EP_IntValue
) );
819 sqlite3TreeViewLine(pView
, "RAISE %s(%Q)", zType
, pExpr
->u
.zToken
);
824 sqlite3TreeViewLine(pView
, "MATCH {%d:%d}%s",
825 pExpr
->iTable
, pExpr
->iColumn
, zFlgs
);
826 sqlite3TreeViewExpr(pView
, pExpr
->pRight
, 0);
830 char *z
= sqlite3_mprintf("VECTOR%s",zFlgs
);
831 assert( ExprUseXList(pExpr
) );
832 sqlite3TreeViewBareExprList(pView
, pExpr
->x
.pList
, z
);
836 case TK_SELECT_COLUMN
: {
837 sqlite3TreeViewLine(pView
, "SELECT-COLUMN %d of [0..%d]%s",
838 pExpr
->iColumn
, pExpr
->iTable
-1,
839 pExpr
->pRight
==pExpr
->pLeft
? " (SELECT-owner)" : "");
840 assert( ExprUseXSelect(pExpr
->pLeft
) );
841 sqlite3TreeViewSelect(pView
, pExpr
->pLeft
->x
.pSelect
, 0);
844 case TK_IF_NULL_ROW
: {
845 sqlite3TreeViewLine(pView
, "IF-NULL-ROW %d", pExpr
->iTable
);
846 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 0);
851 sqlite3TreeViewLine(pView
, "ERROR");
854 sqlite3TreeViewExpr(pView
, &tmp
, 0);
858 if( pExpr
->iColumn
<=0 ){
859 sqlite3TreeViewLine(pView
, "First FROM table rowid");
861 sqlite3TreeViewLine(pView
, "First FROM table column %d",
867 sqlite3TreeViewLine(pView
, "op=%d", pExpr
->op
);
872 sqlite3TreeViewLine(pView
, "%s%s", zBinOp
, zFlgs
);
873 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 1);
874 sqlite3TreeViewExpr(pView
, pExpr
->pRight
, 0);
876 sqlite3TreeViewLine(pView
, "%s%s", zUniOp
, zFlgs
);
877 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 0);
879 sqlite3TreeViewPop(&pView
);
884 ** Generate a human-readable explanation of an expression list.
886 void sqlite3TreeViewBareExprList(
888 const ExprList
*pList
,
891 if( zLabel
==0 || zLabel
[0]==0 ) zLabel
= "LIST";
893 sqlite3TreeViewLine(pView
, "%s (empty)", zLabel
);
896 sqlite3TreeViewLine(pView
, "%s", zLabel
);
897 for(i
=0; i
<pList
->nExpr
; i
++){
898 int j
= pList
->a
[i
].u
.x
.iOrderByCol
;
899 char *zName
= pList
->a
[i
].zEName
;
900 int moreToFollow
= i
<pList
->nExpr
- 1;
902 sqlite3TreeViewPush(&pView
, moreToFollow
);
904 sqlite3TreeViewLine(pView
, 0);
906 switch( pList
->a
[i
].fg
.eEName
){
908 fprintf(stdout
, "AS %s ", zName
);
911 fprintf(stdout
, "TABLE-ALIAS-NAME(\"%s\") ", zName
);
912 if( pList
->a
[i
].fg
.bUsed
) fprintf(stdout
, "(used) ");
913 if( pList
->a
[i
].fg
.bUsingTerm
) fprintf(stdout
, "(USING-term) ");
914 if( pList
->a
[i
].fg
.bNoExpand
) fprintf(stdout
, "(NoExpand) ");
917 fprintf(stdout
, "SPAN(\"%s\") ", zName
);
922 fprintf(stdout
, "iOrderByCol=%d", j
);
924 fprintf(stdout
, "\n");
927 sqlite3TreeViewExpr(pView
, pList
->a
[i
].pExpr
, moreToFollow
);
929 sqlite3TreeViewPop(&pView
);
934 void sqlite3TreeViewExprList(
936 const ExprList
*pList
,
940 sqlite3TreeViewPush(&pView
, moreToFollow
);
941 sqlite3TreeViewBareExprList(pView
, pList
, zLabel
);
942 sqlite3TreeViewPop(&pView
);
946 ** Generate a human-readable explanation of an id-list.
948 void sqlite3TreeViewBareIdList(
953 if( zLabel
==0 || zLabel
[0]==0 ) zLabel
= "LIST";
955 sqlite3TreeViewLine(pView
, "%s (empty)", zLabel
);
958 sqlite3TreeViewLine(pView
, "%s", zLabel
);
959 for(i
=0; i
<pList
->nId
; i
++){
960 char *zName
= pList
->a
[i
].zName
;
961 int moreToFollow
= i
<pList
->nId
- 1;
962 if( zName
==0 ) zName
= "(null)";
963 sqlite3TreeViewPush(&pView
, moreToFollow
);
964 sqlite3TreeViewLine(pView
, 0);
965 if( pList
->eU4
==EU4_NONE
){
966 fprintf(stdout
, "%s\n", zName
);
967 }else if( pList
->eU4
==EU4_IDX
){
968 fprintf(stdout
, "%s (%d)\n", zName
, pList
->a
[i
].u4
.idx
);
970 assert( pList
->eU4
==EU4_EXPR
);
971 if( pList
->a
[i
].u4
.pExpr
==0 ){
972 fprintf(stdout
, "%s (pExpr=NULL)\n", zName
);
974 fprintf(stdout
, "%s\n", zName
);
975 sqlite3TreeViewPush(&pView
, i
<pList
->nId
-1);
976 sqlite3TreeViewExpr(pView
, pList
->a
[i
].u4
.pExpr
, 0);
977 sqlite3TreeViewPop(&pView
);
980 sqlite3TreeViewPop(&pView
);
984 void sqlite3TreeViewIdList(
990 sqlite3TreeViewPush(&pView
, moreToFollow
);
991 sqlite3TreeViewBareIdList(pView
, pList
, zLabel
);
992 sqlite3TreeViewPop(&pView
);
996 ** Generate a human-readable explanation of a list of Upsert objects
998 void sqlite3TreeViewUpsert(
1000 const Upsert
*pUpsert
,
1003 if( pUpsert
==0 ) return;
1004 sqlite3TreeViewPush(&pView
, moreToFollow
);
1007 sqlite3TreeViewPush(&pView
, pUpsert
->pNextUpsert
!=0 || moreToFollow
);
1008 sqlite3TreeViewLine(pView
, "ON CONFLICT DO %s",
1009 pUpsert
->isDoUpdate
? "UPDATE" : "NOTHING");
1010 n
= (pUpsert
->pUpsertSet
!=0) + (pUpsert
->pUpsertWhere
!=0);
1011 sqlite3TreeViewExprList(pView
, pUpsert
->pUpsertTarget
, (n
--)>0, "TARGET");
1012 sqlite3TreeViewExprList(pView
, pUpsert
->pUpsertSet
, (n
--)>0, "SET");
1013 if( pUpsert
->pUpsertWhere
){
1014 sqlite3TreeViewItem(pView
, "WHERE", (n
--)>0);
1015 sqlite3TreeViewExpr(pView
, pUpsert
->pUpsertWhere
, 0);
1016 sqlite3TreeViewPop(&pView
);
1018 sqlite3TreeViewPop(&pView
);
1019 pUpsert
= pUpsert
->pNextUpsert
;
1021 sqlite3TreeViewPop(&pView
);
1024 #if TREETRACE_ENABLED
1026 ** Generate a human-readable diagram of the data structure that go
1027 ** into generating an DELETE statement.
1029 void sqlite3TreeViewDelete(
1031 const SrcList
*pTabList
,
1033 const ExprList
*pOrderBy
,
1035 const Trigger
*pTrigger
1038 TreeView
*pView
= 0;
1039 sqlite3TreeViewPush(&pView
, 0);
1040 sqlite3TreeViewLine(pView
, "DELETE");
1048 sqlite3TreeViewPush(&pView
, (--n
)>0);
1049 sqlite3TreeViewWith(pView
, pWith
, 0);
1050 sqlite3TreeViewPop(&pView
);
1053 sqlite3TreeViewPush(&pView
, (--n
)>0);
1054 sqlite3TreeViewLine(pView
, "FROM");
1055 sqlite3TreeViewSrcList(pView
, pTabList
);
1056 sqlite3TreeViewPop(&pView
);
1059 sqlite3TreeViewPush(&pView
, (--n
)>0);
1060 sqlite3TreeViewLine(pView
, "WHERE");
1061 sqlite3TreeViewExpr(pView
, pWhere
, 0);
1062 sqlite3TreeViewPop(&pView
);
1065 sqlite3TreeViewExprList(pView
, pOrderBy
, (--n
)>0, "ORDER-BY");
1068 sqlite3TreeViewPush(&pView
, (--n
)>0);
1069 sqlite3TreeViewLine(pView
, "LIMIT");
1070 sqlite3TreeViewExpr(pView
, pLimit
, 0);
1071 sqlite3TreeViewPop(&pView
);
1074 sqlite3TreeViewTrigger(pView
, pTrigger
, (--n
)>0, 1);
1076 sqlite3TreeViewPop(&pView
);
1078 #endif /* TREETRACE_ENABLED */
1080 #if TREETRACE_ENABLED
1082 ** Generate a human-readable diagram of the data structure that go
1083 ** into generating an INSERT statement.
1085 void sqlite3TreeViewInsert(
1087 const SrcList
*pTabList
,
1088 const IdList
*pColumnList
,
1089 const Select
*pSelect
,
1090 const ExprList
*pExprList
,
1092 const Upsert
*pUpsert
,
1093 const Trigger
*pTrigger
1095 TreeView
*pView
= 0;
1097 const char *zLabel
= "INSERT";
1099 case OE_Replace
: zLabel
= "REPLACE"; break;
1100 case OE_Ignore
: zLabel
= "INSERT OR IGNORE"; break;
1101 case OE_Rollback
: zLabel
= "INSERT OR ROLLBACK"; break;
1102 case OE_Abort
: zLabel
= "INSERT OR ABORT"; break;
1103 case OE_Fail
: zLabel
= "INSERT OR FAIL"; break;
1105 sqlite3TreeViewPush(&pView
, 0);
1106 sqlite3TreeViewLine(pView
, zLabel
);
1109 if( pColumnList
) n
++;
1111 if( pExprList
) n
++;
1115 sqlite3TreeViewPush(&pView
, (--n
)>0);
1116 sqlite3TreeViewWith(pView
, pWith
, 0);
1117 sqlite3TreeViewPop(&pView
);
1120 sqlite3TreeViewPush(&pView
, (--n
)>0);
1121 sqlite3TreeViewLine(pView
, "INTO");
1122 sqlite3TreeViewSrcList(pView
, pTabList
);
1123 sqlite3TreeViewPop(&pView
);
1126 sqlite3TreeViewIdList(pView
, pColumnList
, (--n
)>0, "COLUMNS");
1129 sqlite3TreeViewPush(&pView
, (--n
)>0);
1130 sqlite3TreeViewLine(pView
, "DATA-SOURCE");
1131 sqlite3TreeViewSelect(pView
, pSelect
, 0);
1132 sqlite3TreeViewPop(&pView
);
1135 sqlite3TreeViewExprList(pView
, pExprList
, (--n
)>0, "VALUES");
1138 sqlite3TreeViewPush(&pView
, (--n
)>0);
1139 sqlite3TreeViewLine(pView
, "UPSERT");
1140 sqlite3TreeViewUpsert(pView
, pUpsert
, 0);
1141 sqlite3TreeViewPop(&pView
);
1144 sqlite3TreeViewTrigger(pView
, pTrigger
, (--n
)>0, 1);
1146 sqlite3TreeViewPop(&pView
);
1148 #endif /* TREETRACE_ENABLED */
1150 #if TREETRACE_ENABLED
1152 ** Generate a human-readable diagram of the data structure that go
1153 ** into generating an UPDATE statement.
1155 void sqlite3TreeViewUpdate(
1157 const SrcList
*pTabList
,
1158 const ExprList
*pChanges
,
1161 const ExprList
*pOrderBy
,
1163 const Upsert
*pUpsert
,
1164 const Trigger
*pTrigger
1167 TreeView
*pView
= 0;
1168 const char *zLabel
= "UPDATE";
1170 case OE_Replace
: zLabel
= "UPDATE OR REPLACE"; break;
1171 case OE_Ignore
: zLabel
= "UPDATE OR IGNORE"; break;
1172 case OE_Rollback
: zLabel
= "UPDATE OR ROLLBACK"; break;
1173 case OE_Abort
: zLabel
= "UPDATE OR ABORT"; break;
1174 case OE_Fail
: zLabel
= "UPDATE OR FAIL"; break;
1176 sqlite3TreeViewPush(&pView
, 0);
1177 sqlite3TreeViewLine(pView
, zLabel
);
1187 sqlite3TreeViewPush(&pView
, (--n
)>0);
1188 sqlite3TreeViewWith(pView
, pWith
, 0);
1189 sqlite3TreeViewPop(&pView
);
1192 sqlite3TreeViewPush(&pView
, (--n
)>0);
1193 sqlite3TreeViewLine(pView
, "FROM");
1194 sqlite3TreeViewSrcList(pView
, pTabList
);
1195 sqlite3TreeViewPop(&pView
);
1198 sqlite3TreeViewExprList(pView
, pChanges
, (--n
)>0, "SET");
1201 sqlite3TreeViewPush(&pView
, (--n
)>0);
1202 sqlite3TreeViewLine(pView
, "WHERE");
1203 sqlite3TreeViewExpr(pView
, pWhere
, 0);
1204 sqlite3TreeViewPop(&pView
);
1207 sqlite3TreeViewExprList(pView
, pOrderBy
, (--n
)>0, "ORDER-BY");
1210 sqlite3TreeViewPush(&pView
, (--n
)>0);
1211 sqlite3TreeViewLine(pView
, "LIMIT");
1212 sqlite3TreeViewExpr(pView
, pLimit
, 0);
1213 sqlite3TreeViewPop(&pView
);
1216 sqlite3TreeViewPush(&pView
, (--n
)>0);
1217 sqlite3TreeViewLine(pView
, "UPSERT");
1218 sqlite3TreeViewUpsert(pView
, pUpsert
, 0);
1219 sqlite3TreeViewPop(&pView
);
1222 sqlite3TreeViewTrigger(pView
, pTrigger
, (--n
)>0, 1);
1224 sqlite3TreeViewPop(&pView
);
1226 #endif /* TREETRACE_ENABLED */
1228 #ifndef SQLITE_OMIT_TRIGGER
1230 ** Show a human-readable graph of a TriggerStep
1232 void sqlite3TreeViewTriggerStep(
1234 const TriggerStep
*pStep
,
1239 if( pStep
==0 ) return;
1240 sqlite3TreeViewPush(&pView
,
1241 moreToFollow
|| (showFullList
&& pStep
->pNext
!=0));
1243 if( cnt
++ && pStep
->pNext
==0 ){
1244 sqlite3TreeViewPop(&pView
);
1245 sqlite3TreeViewPush(&pView
, 0);
1247 sqlite3TreeViewLine(pView
, "%s", pStep
->zSpan
? pStep
->zSpan
: "RETURNING");
1248 }while( showFullList
&& (pStep
= pStep
->pNext
)!=0 );
1249 sqlite3TreeViewPop(&pView
);
1253 ** Show a human-readable graph of a Trigger
1255 void sqlite3TreeViewTrigger(
1257 const Trigger
*pTrigger
,
1262 if( pTrigger
==0 ) return;
1263 sqlite3TreeViewPush(&pView
,
1264 moreToFollow
|| (showFullList
&& pTrigger
->pNext
!=0));
1266 if( cnt
++ && pTrigger
->pNext
==0 ){
1267 sqlite3TreeViewPop(&pView
);
1268 sqlite3TreeViewPush(&pView
, 0);
1270 sqlite3TreeViewLine(pView
, "TRIGGER %s", pTrigger
->zName
);
1271 sqlite3TreeViewPush(&pView
, 0);
1272 sqlite3TreeViewTriggerStep(pView
, pTrigger
->step_list
, 0, 1);
1273 sqlite3TreeViewPop(&pView
);
1274 }while( showFullList
&& (pTrigger
= pTrigger
->pNext
)!=0 );
1275 sqlite3TreeViewPop(&pView
);
1277 #endif /* SQLITE_OMIT_TRIGGER */
1281 ** These simplified versions of the tree-view routines omit unnecessary
1282 ** parameters. These variants are intended to be used from a symbolic
1283 ** debugger, such as "gdb", during interactive debugging sessions.
1285 ** This routines are given external linkage so that they will always be
1286 ** accessible to the debugging, and to avoid warnings about unused
1287 ** functions. But these routines only exist in debugging builds, so they
1288 ** do not contaminate the interface.
1290 void sqlite3ShowExpr(const Expr
*p
){ sqlite3TreeViewExpr(0,p
,0); }
1291 void sqlite3ShowExprList(const ExprList
*p
){ sqlite3TreeViewExprList(0,p
,0,0);}
1292 void sqlite3ShowIdList(const IdList
*p
){ sqlite3TreeViewIdList(0,p
,0,0); }
1293 void sqlite3ShowSrcList(const SrcList
*p
){ sqlite3TreeViewSrcList(0,p
); }
1294 void sqlite3ShowSelect(const Select
*p
){ sqlite3TreeViewSelect(0,p
,0); }
1295 void sqlite3ShowWith(const With
*p
){ sqlite3TreeViewWith(0,p
,0); }
1296 void sqlite3ShowUpsert(const Upsert
*p
){ sqlite3TreeViewUpsert(0,p
,0); }
1297 #ifndef SQLITE_OMIT_TRIGGER
1298 void sqlite3ShowTriggerStep(const TriggerStep
*p
){
1299 sqlite3TreeViewTriggerStep(0,p
,0,0);
1301 void sqlite3ShowTriggerStepList(const TriggerStep
*p
){
1302 sqlite3TreeViewTriggerStep(0,p
,0,1);
1304 void sqlite3ShowTrigger(const Trigger
*p
){ sqlite3TreeViewTrigger(0,p
,0,0); }
1305 void sqlite3ShowTriggerList(const Trigger
*p
){ sqlite3TreeViewTrigger(0,p
,0,1);}
1307 #ifndef SQLITE_OMIT_WINDOWFUNC
1308 void sqlite3ShowWindow(const Window
*p
){ sqlite3TreeViewWindow(0,p
,0); }
1309 void sqlite3ShowWinFunc(const Window
*p
){ sqlite3TreeViewWinFunc(0,p
,0); }
1312 #endif /* SQLITE_DEBUG */