1 /*-------------------------------------------------------------------------
4 * various print routines (used mostly for debugging)
6 * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.41 2000/09/25 18:14:55 tgl Exp $
14 * AUTHOR DATE MAJOR EVENT
15 * Andrew Yu Oct 26, 1994 file creation
17 *-------------------------------------------------------------------------
22 #include "access/printtup.h"
23 #include "nodes/print.h"
24 #include "optimizer/clauses.h"
25 #include "parser/parsetree.h"
26 #include "utils/lsyscache.h"
28 static char *plannode_type(Plan *p);
32 * print contents of Node to stdout
39 s = nodeToString(obj);
46 * pretty print hack extraordinaire. -ay 10/94
57 s = nodeToString(obj);
63 for (j = 0; j < indentLev * 3; j++)
65 for (; j < 75 && s[i] != '\0'; i++, j++)
71 if (j != indentLev * 3)
75 line[indentLev * 3] = '\0';
76 printf("%s}\n", line);
81 printf("%s}\n", line);
84 j = indentLev * 3 - 1; /* print the line before :
90 j = indentLev * 3 - 1;
94 /* !!! FALLS THROUGH */
100 /* print the line before : and resets */
101 for (j = 0; j < indentLev * 3; j++)
111 printf("%s\n", line);
114 printf("%s\n", line);
121 * print contents of range table
124 print_rt(List *rtable)
129 printf("resno\trelname(refname)\trelid\tinFromCl\n");
130 printf("-----\t----------------\t-----\t--------\n");
133 RangeTblEntry *rte = lfirst(l);
135 printf("%d\t%s(%s)\t%u\t%d\t%s\n",
136 i, rte->relname, rte->eref->relname, rte->relid,
138 (rte->inh ? "inh" : ""));
146 * print an expression
149 print_expr(Node *expr, List *rtable)
159 Var *var = (Var *) expr;
177 Assert(var->varno > 0 &&
178 (int) var->varno <= length(rtable));
179 rte = rt_fetch(var->varno, rtable);
180 relname = rte->eref->relname;
181 attname = get_rte_attribute_name(rte, var->varattno);
185 printf("%s.%s", relname, attname);
187 else if (IsA(expr, Expr))
189 Expr *e = (Expr *) expr;
191 if (is_opclause(expr))
195 print_expr((Node *) get_leftop(e), rtable);
196 opname = get_opname(((Oper *) e->oper)->opno);
197 printf(" %s ", ((opname != NULL) ? opname : "(invalid operator)"));
198 print_expr((Node *) get_rightop(e), rtable);
204 printf("not an expr");
209 * pathkeys list of list of PathKeyItems
212 print_pathkeys(List *pathkeys, List *rtable)
220 List *pathkey = lfirst(i);
225 PathKeyItem *item = lfirst(k);
227 print_expr(item->key, rtable);
240 * print targetlist in a more legible way.
243 print_tl(List *tlist, List *rtable)
250 TargetEntry *tle = lfirst(tl);
252 printf("\t%d %s\t", tle->resdom->resno, tle->resdom->resname);
253 if (tle->resdom->reskey != 0)
254 printf("(%d):\t", tle->resdom->reskey);
257 print_expr(tle->expr, rtable);
265 * print out the tuple with the given TupleTableSlot
268 print_slot(TupleTableSlot *slot)
272 printf("tuple is null.\n");
275 if (!slot->ttc_tupleDescriptor)
277 printf("no tuple descriptor.\n");
281 debugtup(slot->val, slot->ttc_tupleDescriptor, NULL);
285 plannode_type(Plan *p)
347 prints the ascii description of the plan nodes
348 does this recursively by doing a depth-first traversal of the
349 plan tree. for SeqScan and IndexScan, the name of the table is also
354 print_plan_recursive(Plan *p, Query *parsetree, int indentLevel, char *label)
361 for (i = 0; i < indentLevel; i++)
363 printf("%s%s :c=%.2f..%.2f :r=%.0f :w=%d ", label, plannode_type(p),
364 p->startup_cost, p->total_cost,
365 p->plan_rows, p->plan_width);
366 if (IsA(p, Scan) ||IsA(p, SeqScan))
370 rte = rt_fetch(((Scan *) p)->scanrelid, parsetree->rtable);
371 StrNCpy(extraInfo, rte->relname, NAMEDATALEN);
373 else if (IsA(p, IndexScan))
376 ((RangeTblEntry *) (nth(((IndexScan *) p)->scan.scanrelid - 1,
377 parsetree->rtable)))->relname,
382 if (extraInfo[0] != '\0')
383 printf(" ( %s )\n", extraInfo);
386 print_plan_recursive(p->lefttree, parsetree, indentLevel + 3, "l: ");
387 print_plan_recursive(p->righttree, parsetree, indentLevel + 3, "r: ");
389 if (nodeTag(p) == T_Append)
393 Append *appendplan = (Append *) p;
395 foreach(lst, appendplan->appendplans)
397 Plan *subnode = (Plan *) lfirst(lst);
400 * I don't think we need to fiddle with the range table here,
403 print_plan_recursive(subnode, parsetree, indentLevel + 3, "a: ");
411 prints just the plan node types */
414 print_plan(Plan *p, Query *parsetree)
416 print_plan_recursive(p, parsetree, 0, "");