1 /*-------------------------------------------------------------------------
4 * various print routines (used mostly for debugging)
6 * Copyright (c) 1994, Regents of the University of California
10 * $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.27 1999/05/10 00:45:13 momjian Exp $
13 * AUTHOR DATE MAJOR EVENT
14 * Andrew Yu Oct 26, 1994 file creation
16 *-------------------------------------------------------------------------
23 #include "access/printtup.h"
24 #include "nodes/pg_list.h"
25 #include "nodes/execnodes.h"
26 #include "nodes/parsenodes.h"
27 #include "nodes/print.h"
28 #include "parser/parsetree.h"
29 #include "access/heapam.h"
30 #include "utils/lsyscache.h"
31 #include "nodes/nodes.h"
32 #include "nodes/plannodes.h"
33 #include "parser/parse_relation.h"
34 #include "optimizer/clauses.h"
36 static char *plannode_type(Plan *p);
40 * print contents of Node to stdout
47 s = nodeToString(obj);
54 * pretty print hack extraordinaire. -ay 10/94
65 s = nodeToString(obj);
71 for (j = 0; j < indentLev * 3; j++)
73 for (; j < 75 && s[i] != '\0'; i++, j++)
79 if (j != indentLev * 3)
83 line[indentLev * 3] = '\0';
84 printf("%s}\n", line);
89 printf("%s}\n", line);
92 j = indentLev * 3 - 1; /* print the line before :
98 j = indentLev * 3 - 1;
102 /* !!! FALLS THROUGH */
107 printf("%s\n", line);
108 /* print the line before : and resets */
109 for (j = 0; j < indentLev * 3; j++)
119 printf("%s\n", line);
122 printf("%s\n", line);
129 * print contents of range table
132 print_rt(List *rtable)
137 printf("resno\trelname(refname)\trelid\tinFromCl\n");
138 printf("-----\t----------------\t-----\t--------\n");
141 RangeTblEntry *rte = lfirst(l);
143 printf("%d\t%s(%s)\t%u\t%d\t%s\n",
144 i, rte->relname, rte->refname, rte->relid,
146 (rte->inh ? "inh" : ""));
154 * print an expression
157 print_expr(Node *expr, List *rtable)
167 Var *var = (Var *) expr;
184 rt = rt_fetch(var->varno, rtable);
185 relname = rt->relname;
187 relname = rt->refname; /* table renamed */
188 attname = get_attname(rt->relid, var->varattno);
192 printf("%s.%s", relname, attname);
194 else if (IsA(expr, Expr))
196 Expr *e = (Expr *) expr;
198 if (is_opclause(expr))
202 print_expr((Node *) get_leftop(e), rtable);
203 opname = get_opname(((Oper *) e->oper)->opno);
204 printf(" %s ", ((opname != NULL) ? opname : "(invalid operator)"));
205 print_expr((Node *) get_rightop(e), rtable);
211 printf("not an expr");
216 * pathkeys list of list of Var's
219 print_pathkeys(List *pathkeys, List *rtable)
226 List *pathkey = lfirst(i);
231 Node *var = lfirst(k);
232 print_expr(var, rtable);
245 * print targetlist in a more legible way.
248 print_tl(List *tlist, List *rtable)
255 TargetEntry *tle = lfirst(tl);
257 printf("\t%d %s\t", tle->resdom->resno, tle->resdom->resname);
258 if (tle->resdom->reskey != 0)
259 printf("(%d):\t", tle->resdom->reskey);
262 print_expr(tle->expr, rtable);
270 * print out the tuple with the given TupleTableSlot
273 print_slot(TupleTableSlot *slot)
277 printf("tuple is null.\n");
280 if (!slot->ttc_tupleDescriptor)
282 printf("no tuple descriptor.\n");
286 debugtup(slot->val, slot->ttc_tupleDescriptor, NULL);
290 plannode_type(Plan *p)
355 prints the ascii description of the plan nodes
356 does this recursively by doing a depth-first traversal of the
357 plan tree. for SeqScan and IndexScan, the name of the table is also
362 print_plan_recursive(Plan *p, Query *parsetree, int indentLevel, char *label)
369 for (i = 0; i < indentLevel; i++)
371 printf("%s%s :c=%.4f :s=%d :w=%d ", label, plannode_type(p),
372 p->cost, p->plan_size, p->plan_width);
373 if (IsA(p, Scan) ||IsA(p, SeqScan))
377 rte = rt_fetch(((Scan *) p)->scanrelid, parsetree->rtable);
378 StrNCpy(extraInfo, rte->relname, NAMEDATALEN);
380 else if (IsA(p, IndexScan))
383 ((RangeTblEntry *) (nth(((IndexScan *) p)->scan.scanrelid - 1,
384 parsetree->rtable)))->relname,
389 if (extraInfo[0] != '\0')
390 printf(" ( %s )\n", extraInfo);
393 print_plan_recursive(p->lefttree, parsetree, indentLevel + 3, "l: ");
394 print_plan_recursive(p->righttree, parsetree, indentLevel + 3, "r: ");
396 if (nodeTag(p) == T_Append)
400 Append *appendplan = (Append *) p;
402 foreach(lst, appendplan->appendplans)
404 Plan *subnode = (Plan *) lfirst(lst);
407 * I don't think we need to fiddle with the range table here,
410 print_plan_recursive(subnode, parsetree, indentLevel + 3, "a: ");
418 prints just the plan node types */
421 print_plan(Plan *p, Query *parsetree)
423 print_plan_recursive(p, parsetree, 0, "");