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 );
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
].zName
);
112 sqlite3_str_appendf(&x
, ")");
114 sqlite3_str_appendf(&x
, " AS");
115 sqlite3StrAccumFinish(&x
);
116 sqlite3TreeViewItem(pView
, zLine
, i
<pWith
->nCte
-1);
117 sqlite3TreeViewSelect(pView
, pCte
->pSelect
, 0);
118 sqlite3TreeViewPop(pView
);
120 sqlite3TreeViewPop(pView
);
126 ** Generate a human-readable description of a Select object.
128 void sqlite3TreeViewSelect(TreeView
*pView
, const Select
*p
, u8 moreToFollow
){
132 sqlite3TreeViewLine(pView
, "nil-SELECT");
135 pView
= sqlite3TreeViewPush(pView
, moreToFollow
);
137 sqlite3TreeViewWith(pView
, p
->pWith
, 1);
139 sqlite3TreeViewPush(pView
, 1);
142 sqlite3TreeViewLine(pView
,
143 "SELECT%s%s (%u/%p) selFlags=0x%x nSelectRow=%d",
144 ((p
->selFlags
& SF_Distinct
) ? " DISTINCT" : ""),
145 ((p
->selFlags
& SF_Aggregate
) ? " agg_flag" : ""),
146 p
->selId
, p
, p
->selFlags
,
149 if( cnt
++ ) sqlite3TreeViewPop(pView
);
154 if( p
->pSrc
&& p
->pSrc
->nSrc
) n
++;
156 if( p
->pGroupBy
) n
++;
157 if( p
->pHaving
) n
++;
158 if( p
->pOrderBy
) n
++;
160 #ifndef SQLITE_OMIT_WINDOWFUNC
162 if( p
->pWinDefn
) n
++;
165 sqlite3TreeViewExprList(pView
, p
->pEList
, (n
--)>0, "result-set");
166 #ifndef SQLITE_OMIT_WINDOWFUNC
169 pView
= sqlite3TreeViewPush(pView
, (n
--)>0);
170 sqlite3TreeViewLine(pView
, "window-functions");
171 for(pX
=p
->pWin
; pX
; pX
=pX
->pNextWin
){
172 sqlite3TreeViewWinFunc(pView
, pX
, pX
->pNextWin
!=0);
174 sqlite3TreeViewPop(pView
);
177 if( p
->pSrc
&& p
->pSrc
->nSrc
){
179 pView
= sqlite3TreeViewPush(pView
, (n
--)>0);
180 sqlite3TreeViewLine(pView
, "FROM");
181 for(i
=0; i
<p
->pSrc
->nSrc
; i
++){
182 struct SrcList_item
*pItem
= &p
->pSrc
->a
[i
];
185 sqlite3StrAccumInit(&x
, 0, zLine
, sizeof(zLine
), 0);
186 sqlite3_str_appendf(&x
, "{%d,*}", pItem
->iCursor
);
187 if( pItem
->zDatabase
){
188 sqlite3_str_appendf(&x
, " %s.%s", pItem
->zDatabase
, pItem
->zName
);
189 }else if( pItem
->zName
){
190 sqlite3_str_appendf(&x
, " %s", pItem
->zName
);
193 sqlite3_str_appendf(&x
, " tabname=%Q", pItem
->pTab
->zName
);
196 sqlite3_str_appendf(&x
, " (AS %s)", pItem
->zAlias
);
198 if( pItem
->fg
.jointype
& JT_LEFT
){
199 sqlite3_str_appendf(&x
, " LEFT-JOIN");
201 sqlite3StrAccumFinish(&x
);
202 sqlite3TreeViewItem(pView
, zLine
, i
<p
->pSrc
->nSrc
-1);
203 if( pItem
->pSelect
){
204 sqlite3TreeViewSelect(pView
, pItem
->pSelect
, 0);
206 if( pItem
->fg
.isTabFunc
){
207 sqlite3TreeViewExprList(pView
, pItem
->u1
.pFuncArg
, 0, "func-args:");
209 sqlite3TreeViewPop(pView
);
211 sqlite3TreeViewPop(pView
);
214 sqlite3TreeViewItem(pView
, "WHERE", (n
--)>0);
215 sqlite3TreeViewExpr(pView
, p
->pWhere
, 0);
216 sqlite3TreeViewPop(pView
);
219 sqlite3TreeViewExprList(pView
, p
->pGroupBy
, (n
--)>0, "GROUPBY");
222 sqlite3TreeViewItem(pView
, "HAVING", (n
--)>0);
223 sqlite3TreeViewExpr(pView
, p
->pHaving
, 0);
224 sqlite3TreeViewPop(pView
);
226 #ifndef SQLITE_OMIT_WINDOWFUNC
229 sqlite3TreeViewItem(pView
, "WINDOW", (n
--)>0);
230 for(pX
=p
->pWinDefn
; pX
; pX
=pX
->pNextWin
){
231 sqlite3TreeViewWindow(pView
, pX
, pX
->pNextWin
!=0);
233 sqlite3TreeViewPop(pView
);
237 sqlite3TreeViewExprList(pView
, p
->pOrderBy
, (n
--)>0, "ORDERBY");
240 sqlite3TreeViewItem(pView
, "LIMIT", (n
--)>0);
241 sqlite3TreeViewExpr(pView
, p
->pLimit
->pLeft
, p
->pLimit
->pRight
!=0);
242 if( p
->pLimit
->pRight
){
243 sqlite3TreeViewItem(pView
, "OFFSET", (n
--)>0);
244 sqlite3TreeViewExpr(pView
, p
->pLimit
->pRight
, 0);
245 sqlite3TreeViewPop(pView
);
247 sqlite3TreeViewPop(pView
);
250 const char *zOp
= "UNION";
252 case TK_ALL
: zOp
= "UNION ALL"; break;
253 case TK_INTERSECT
: zOp
= "INTERSECT"; break;
254 case TK_EXCEPT
: zOp
= "EXCEPT"; break;
256 sqlite3TreeViewItem(pView
, zOp
, 1);
260 sqlite3TreeViewPop(pView
);
263 #ifndef SQLITE_OMIT_WINDOWFUNC
265 ** Generate a description of starting or stopping bounds
267 void sqlite3TreeViewBound(
268 TreeView
*pView
, /* View context */
269 u8 eBound
, /* UNBOUNDED, CURRENT, PRECEDING, FOLLOWING */
270 Expr
*pExpr
, /* Value for PRECEDING or FOLLOWING */
271 u8 moreToFollow
/* True if more to follow */
275 sqlite3TreeViewItem(pView
, "UNBOUNDED", moreToFollow
);
276 sqlite3TreeViewPop(pView
);
280 sqlite3TreeViewItem(pView
, "CURRENT", moreToFollow
);
281 sqlite3TreeViewPop(pView
);
285 sqlite3TreeViewItem(pView
, "PRECEDING", moreToFollow
);
286 sqlite3TreeViewExpr(pView
, pExpr
, 0);
287 sqlite3TreeViewPop(pView
);
291 sqlite3TreeViewItem(pView
, "FOLLOWING", moreToFollow
);
292 sqlite3TreeViewExpr(pView
, pExpr
, 0);
293 sqlite3TreeViewPop(pView
);
298 #endif /* SQLITE_OMIT_WINDOWFUNC */
300 #ifndef SQLITE_OMIT_WINDOWFUNC
302 ** Generate a human-readable explanation for a Window object
304 void sqlite3TreeViewWindow(TreeView
*pView
, const Window
*pWin
, u8 more
){
305 pView
= sqlite3TreeViewPush(pView
, more
);
307 sqlite3TreeViewLine(pView
, "OVER %s", pWin
->zName
);
309 sqlite3TreeViewLine(pView
, "OVER");
311 if( pWin
->pPartition
){
312 sqlite3TreeViewExprList(pView
, pWin
->pPartition
, 1, "PARTITION-BY");
314 if( pWin
->pOrderBy
){
315 sqlite3TreeViewExprList(pView
, pWin
->pOrderBy
, 1, "ORDER-BY");
318 sqlite3TreeViewItem(pView
, pWin
->eType
==TK_RANGE
? "RANGE" : "ROWS", 0);
319 sqlite3TreeViewBound(pView
, pWin
->eStart
, pWin
->pStart
, 1);
320 sqlite3TreeViewBound(pView
, pWin
->eEnd
, pWin
->pEnd
, 0);
321 sqlite3TreeViewPop(pView
);
323 sqlite3TreeViewPop(pView
);
325 #endif /* SQLITE_OMIT_WINDOWFUNC */
327 #ifndef SQLITE_OMIT_WINDOWFUNC
329 ** Generate a human-readable explanation for a Window Function object
331 void sqlite3TreeViewWinFunc(TreeView
*pView
, const Window
*pWin
, u8 more
){
332 pView
= sqlite3TreeViewPush(pView
, more
);
333 sqlite3TreeViewLine(pView
, "WINFUNC %s(%d)",
334 pWin
->pFunc
->zName
, pWin
->pFunc
->nArg
);
335 sqlite3TreeViewWindow(pView
, pWin
, 0);
336 sqlite3TreeViewPop(pView
);
338 #endif /* SQLITE_OMIT_WINDOWFUNC */
341 ** Generate a human-readable explanation of an expression tree.
343 void sqlite3TreeViewExpr(TreeView
*pView
, const Expr
*pExpr
, u8 moreToFollow
){
344 const char *zBinOp
= 0; /* Binary operator */
345 const char *zUniOp
= 0; /* Unary operator */
347 pView
= sqlite3TreeViewPush(pView
, moreToFollow
);
349 sqlite3TreeViewLine(pView
, "nil");
350 sqlite3TreeViewPop(pView
);
354 if( ExprHasProperty(pExpr
, EP_FromJoin
) ){
355 sqlite3_snprintf(sizeof(zFlgs
),zFlgs
," flags=0x%x iRJT=%d",
356 pExpr
->flags
, pExpr
->iRightJoinTable
);
358 sqlite3_snprintf(sizeof(zFlgs
),zFlgs
," flags=0x%x",pExpr
->flags
);
364 case TK_AGG_COLUMN
: {
365 sqlite3TreeViewLine(pView
, "AGG{%d:%d}%s",
366 pExpr
->iTable
, pExpr
->iColumn
, zFlgs
);
370 if( pExpr
->iTable
<0 ){
371 /* This only happens when coding check constraints */
372 sqlite3TreeViewLine(pView
, "COLUMN(%d)%s", pExpr
->iColumn
, zFlgs
);
374 sqlite3TreeViewLine(pView
, "{%d:%d}%s",
375 pExpr
->iTable
, pExpr
->iColumn
, zFlgs
);
380 if( pExpr
->flags
& EP_IntValue
){
381 sqlite3TreeViewLine(pView
, "%d", pExpr
->u
.iValue
);
383 sqlite3TreeViewLine(pView
, "%s", pExpr
->u
.zToken
);
387 #ifndef SQLITE_OMIT_FLOATING_POINT
389 sqlite3TreeViewLine(pView
,"%s", pExpr
->u
.zToken
);
394 sqlite3TreeViewLine(pView
,"%Q", pExpr
->u
.zToken
);
398 sqlite3TreeViewLine(pView
,"NULL");
402 sqlite3TreeViewLine(pView
,
403 sqlite3ExprTruthValue(pExpr
) ? "TRUE" : "FALSE");
406 #ifndef SQLITE_OMIT_BLOB_LITERAL
408 sqlite3TreeViewLine(pView
,"%s", pExpr
->u
.zToken
);
413 sqlite3TreeViewLine(pView
,"VARIABLE(%s,%d)",
414 pExpr
->u
.zToken
, pExpr
->iColumn
);
418 sqlite3TreeViewLine(pView
,"REGISTER(%d)", pExpr
->iTable
);
422 sqlite3TreeViewLine(pView
,"ID \"%w\"", pExpr
->u
.zToken
);
425 #ifndef SQLITE_OMIT_CAST
427 /* Expressions of the form: CAST(pLeft AS token) */
428 sqlite3TreeViewLine(pView
,"CAST %Q", pExpr
->u
.zToken
);
429 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 0);
432 #endif /* SQLITE_OMIT_CAST */
433 case TK_LT
: zBinOp
= "LT"; break;
434 case TK_LE
: zBinOp
= "LE"; break;
435 case TK_GT
: zBinOp
= "GT"; break;
436 case TK_GE
: zBinOp
= "GE"; break;
437 case TK_NE
: zBinOp
= "NE"; break;
438 case TK_EQ
: zBinOp
= "EQ"; break;
439 case TK_IS
: zBinOp
= "IS"; break;
440 case TK_ISNOT
: zBinOp
= "ISNOT"; break;
441 case TK_AND
: zBinOp
= "AND"; break;
442 case TK_OR
: zBinOp
= "OR"; break;
443 case TK_PLUS
: zBinOp
= "ADD"; break;
444 case TK_STAR
: zBinOp
= "MUL"; break;
445 case TK_MINUS
: zBinOp
= "SUB"; break;
446 case TK_REM
: zBinOp
= "REM"; break;
447 case TK_BITAND
: zBinOp
= "BITAND"; break;
448 case TK_BITOR
: zBinOp
= "BITOR"; break;
449 case TK_SLASH
: zBinOp
= "DIV"; break;
450 case TK_LSHIFT
: zBinOp
= "LSHIFT"; break;
451 case TK_RSHIFT
: zBinOp
= "RSHIFT"; break;
452 case TK_CONCAT
: zBinOp
= "CONCAT"; break;
453 case TK_DOT
: zBinOp
= "DOT"; break;
455 case TK_UMINUS
: zUniOp
= "UMINUS"; break;
456 case TK_UPLUS
: zUniOp
= "UPLUS"; break;
457 case TK_BITNOT
: zUniOp
= "BITNOT"; break;
458 case TK_NOT
: zUniOp
= "NOT"; break;
459 case TK_ISNULL
: zUniOp
= "ISNULL"; break;
460 case TK_NOTNULL
: zUniOp
= "NOTNULL"; break;
464 const char *azOp
[] = {
465 "IS-FALSE", "IS-TRUE", "IS-NOT-FALSE", "IS-NOT-TRUE"
467 assert( pExpr
->op2
==TK_IS
|| pExpr
->op2
==TK_ISNOT
);
468 assert( pExpr
->pRight
);
469 assert( pExpr
->pRight
->op
==TK_TRUEFALSE
);
470 x
= (pExpr
->op2
==TK_ISNOT
)*2 + sqlite3ExprTruthValue(pExpr
->pRight
);
476 sqlite3TreeViewLine(pView
, "SPAN %Q", pExpr
->u
.zToken
);
477 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 0);
482 sqlite3TreeViewLine(pView
, "COLLATE %Q", pExpr
->u
.zToken
);
483 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 0);
487 case TK_AGG_FUNCTION
:
489 ExprList
*pFarg
; /* List of function arguments */
491 if( ExprHasProperty(pExpr
, EP_TokenOnly
) ){
495 pFarg
= pExpr
->x
.pList
;
496 #ifndef SQLITE_OMIT_WINDOWFUNC
502 if( pExpr
->op
==TK_AGG_FUNCTION
){
503 sqlite3TreeViewLine(pView
, "AGG_FUNCTION%d %Q",
504 pExpr
->op2
, pExpr
->u
.zToken
);
506 sqlite3TreeViewLine(pView
, "FUNCTION %Q", pExpr
->u
.zToken
);
509 sqlite3TreeViewExprList(pView
, pFarg
, pWin
!=0, 0);
511 #ifndef SQLITe_OMIT_WINDOWFUNC
513 sqlite3TreeViewWindow(pView
, pWin
, 0);
518 #ifndef SQLITE_OMIT_SUBQUERY
520 sqlite3TreeViewLine(pView
, "EXISTS-expr flags=0x%x", pExpr
->flags
);
521 sqlite3TreeViewSelect(pView
, pExpr
->x
.pSelect
, 0);
525 sqlite3TreeViewLine(pView
, "SELECT-expr flags=0x%x", pExpr
->flags
);
526 sqlite3TreeViewSelect(pView
, pExpr
->x
.pSelect
, 0);
530 sqlite3TreeViewLine(pView
, "IN flags=0x%x", pExpr
->flags
);
531 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 1);
532 if( ExprHasProperty(pExpr
, EP_xIsSelect
) ){
533 sqlite3TreeViewSelect(pView
, pExpr
->x
.pSelect
, 0);
535 sqlite3TreeViewExprList(pView
, pExpr
->x
.pList
, 0, 0);
539 #endif /* SQLITE_OMIT_SUBQUERY */
544 ** This is equivalent to
548 ** X is stored in pExpr->pLeft.
549 ** Y is stored in pExpr->pList->a[0].pExpr.
550 ** Z is stored in pExpr->pList->a[1].pExpr.
553 Expr
*pX
= pExpr
->pLeft
;
554 Expr
*pY
= pExpr
->x
.pList
->a
[0].pExpr
;
555 Expr
*pZ
= pExpr
->x
.pList
->a
[1].pExpr
;
556 sqlite3TreeViewLine(pView
, "BETWEEN");
557 sqlite3TreeViewExpr(pView
, pX
, 1);
558 sqlite3TreeViewExpr(pView
, pY
, 1);
559 sqlite3TreeViewExpr(pView
, pZ
, 0);
563 /* If the opcode is TK_TRIGGER, then the expression is a reference
564 ** to a column in the new.* or old.* pseudo-tables available to
565 ** trigger programs. In this case Expr.iTable is set to 1 for the
566 ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn
567 ** is set to the column of the pseudo-table to read, or to -1 to
568 ** read the rowid field.
570 sqlite3TreeViewLine(pView
, "%s(%d)",
571 pExpr
->iTable
? "NEW" : "OLD", pExpr
->iColumn
);
575 sqlite3TreeViewLine(pView
, "CASE");
576 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 1);
577 sqlite3TreeViewExprList(pView
, pExpr
->x
.pList
, 0, 0);
580 #ifndef SQLITE_OMIT_TRIGGER
582 const char *zType
= "unk";
583 switch( pExpr
->affinity
){
584 case OE_Rollback
: zType
= "rollback"; break;
585 case OE_Abort
: zType
= "abort"; break;
586 case OE_Fail
: zType
= "fail"; break;
587 case OE_Ignore
: zType
= "ignore"; break;
589 sqlite3TreeViewLine(pView
, "RAISE %s(%Q)", zType
, pExpr
->u
.zToken
);
594 sqlite3TreeViewLine(pView
, "MATCH {%d:%d}%s",
595 pExpr
->iTable
, pExpr
->iColumn
, zFlgs
);
596 sqlite3TreeViewExpr(pView
, pExpr
->pRight
, 0);
600 sqlite3TreeViewBareExprList(pView
, pExpr
->x
.pList
, "VECTOR");
603 case TK_SELECT_COLUMN
: {
604 sqlite3TreeViewLine(pView
, "SELECT-COLUMN %d", pExpr
->iColumn
);
605 sqlite3TreeViewSelect(pView
, pExpr
->pLeft
->x
.pSelect
, 0);
608 case TK_IF_NULL_ROW
: {
609 sqlite3TreeViewLine(pView
, "IF-NULL-ROW %d", pExpr
->iTable
);
610 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 0);
614 sqlite3TreeViewLine(pView
, "op=%d", pExpr
->op
);
619 sqlite3TreeViewLine(pView
, "%s%s", zBinOp
, zFlgs
);
620 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 1);
621 sqlite3TreeViewExpr(pView
, pExpr
->pRight
, 0);
623 sqlite3TreeViewLine(pView
, "%s%s", zUniOp
, zFlgs
);
624 sqlite3TreeViewExpr(pView
, pExpr
->pLeft
, 0);
626 sqlite3TreeViewPop(pView
);
631 ** Generate a human-readable explanation of an expression list.
633 void sqlite3TreeViewBareExprList(
635 const ExprList
*pList
,
638 if( zLabel
==0 || zLabel
[0]==0 ) zLabel
= "LIST";
640 sqlite3TreeViewLine(pView
, "%s (empty)", zLabel
);
643 sqlite3TreeViewLine(pView
, "%s", zLabel
);
644 for(i
=0; i
<pList
->nExpr
; i
++){
645 int j
= pList
->a
[i
].u
.x
.iOrderByCol
;
646 char *zName
= pList
->a
[i
].zName
;
647 int moreToFollow
= i
<pList
->nExpr
- 1;
649 sqlite3TreeViewPush(pView
, moreToFollow
);
651 sqlite3TreeViewLine(pView
, 0);
653 fprintf(stdout
, "AS %s ", zName
);
656 fprintf(stdout
, "iOrderByCol=%d", j
);
658 fprintf(stdout
, "\n");
661 sqlite3TreeViewExpr(pView
, pList
->a
[i
].pExpr
, moreToFollow
);
663 sqlite3TreeViewPop(pView
);
668 void sqlite3TreeViewExprList(
670 const ExprList
*pList
,
674 pView
= sqlite3TreeViewPush(pView
, moreToFollow
);
675 sqlite3TreeViewBareExprList(pView
, pList
, zLabel
);
676 sqlite3TreeViewPop(pView
);
679 #endif /* SQLITE_DEBUG */