print.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:8k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * print.c
  4.  *   various print routines (used mostly for debugging)
  5.  *
  6.  * Copyright (c) 1994, Regents of the University of California
  7.  *
  8.  *
  9.  * IDENTIFICATION
  10.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/nodes/print.c,v 1.28 1999/05/25 16:09:10 momjian Exp $
  11.  *
  12.  * HISTORY
  13.  *   AUTHOR DATE MAJOR EVENT
  14.  *   Andrew Yu Oct 26, 1994 file creation
  15.  *
  16.  *-------------------------------------------------------------------------
  17.  */
  18. #include <stdio.h>
  19. #include <string.h>
  20. #include "postgres.h"
  21. #include "access/printtup.h"
  22. #include "nodes/pg_list.h"
  23. #include "nodes/execnodes.h"
  24. #include "nodes/parsenodes.h"
  25. #include "nodes/print.h"
  26. #include "parser/parsetree.h"
  27. #include "access/heapam.h"
  28. #include "utils/lsyscache.h"
  29. #include "nodes/nodes.h"
  30. #include "nodes/plannodes.h"
  31. #include "parser/parse_relation.h"
  32. #include "optimizer/clauses.h"
  33. static char *plannode_type(Plan *p);
  34. /*
  35.  * print
  36.  *   print contents of Node to stdout
  37.  */
  38. void
  39. print(void *obj)
  40. {
  41. char    *s;
  42. s = nodeToString(obj);
  43. printf("%sn", s);
  44. fflush(stdout);
  45. return;
  46. }
  47. /*
  48.  * pretty print hack extraordinaire.  -ay 10/94
  49.  */
  50. void
  51. pprint(void *obj)
  52. {
  53. char    *s;
  54. int i;
  55. char line[80];
  56. int indentLev;
  57. int j;
  58. s = nodeToString(obj);
  59. indentLev = 0;
  60. i = 0;
  61. for (;;)
  62. {
  63. for (j = 0; j < indentLev * 3; j++)
  64. line[j] = ' ';
  65. for (; j < 75 && s[i] != ''; i++, j++)
  66. {
  67. line[j] = s[i];
  68. switch (line[j])
  69. {
  70. case '}':
  71. if (j != indentLev * 3)
  72. {
  73. line[j] = '';
  74. printf("%sn", line);
  75. line[indentLev * 3] = '';
  76. printf("%s}n", line);
  77. }
  78. else
  79. {
  80. line[j] = '';
  81. printf("%s}n", line);
  82. }
  83. indentLev--;
  84. j = indentLev * 3 - 1; /* print the line before :
  85.  * and resets */
  86. break;
  87. case ')':
  88. line[j + 1] = '';
  89. printf("%sn", line);
  90. j = indentLev * 3 - 1;
  91. break;
  92. case '{':
  93. indentLev++;
  94. /* !!! FALLS THROUGH */
  95. case ':':
  96. if (j != 0)
  97. {
  98. line[j] = '';
  99. printf("%sn", line);
  100. /* print the line before : and resets */
  101. for (j = 0; j < indentLev * 3; j++)
  102. line[j] = ' ';
  103. }
  104. line[j] = s[i];
  105. break;
  106. }
  107. }
  108. line[j] = '';
  109. if (s[i] == '')
  110. break;
  111. printf("%sn", line);
  112. }
  113. if (j != 0)
  114. printf("%sn", line);
  115. fflush(stdout);
  116. return;
  117. }
  118. /*
  119.  * print_rt
  120.  *   print contents of range table
  121.  */
  122. void
  123. print_rt(List *rtable)
  124. {
  125. List    *l;
  126. int i = 1;
  127. printf("resnotrelname(refname)trelidtinFromCln");
  128. printf("-----t----------------t-----t--------n");
  129. foreach(l, rtable)
  130. {
  131. RangeTblEntry *rte = lfirst(l);
  132. printf("%dt%s(%s)t%ut%dt%sn",
  133.    i, rte->relname, rte->refname, rte->relid,
  134.    rte->inFromCl,
  135.    (rte->inh ? "inh" : ""));
  136. i++;
  137. }
  138. }
  139. /*
  140.  * print_expr
  141.  *   print an expression
  142.  */
  143. void
  144. print_expr(Node *expr, List *rtable)
  145. {
  146. if (expr == NULL)
  147. {
  148. printf("<>");
  149. return;
  150. }
  151. if (IsA(expr, Var))
  152. {
  153. Var    *var = (Var *) expr;
  154. RangeTblEntry *rt;
  155. char    *relname,
  156.    *attname;
  157. switch (var->varno)
  158. {
  159. case INNER:
  160. relname = "INNER";
  161. attname = "?";
  162. break;
  163. case OUTER:
  164. relname = "OUTER";
  165. attname = "?";
  166. break;
  167. default:
  168. {
  169. rt = rt_fetch(var->varno, rtable);
  170. relname = rt->relname;
  171. if (rt->refname)
  172. relname = rt->refname; /* table renamed */
  173. attname = get_attname(rt->relid, var->varattno);
  174. }
  175. break;
  176. }
  177. printf("%s.%s", relname, attname);
  178. }
  179. else if (IsA(expr, Expr))
  180. {
  181. Expr    *e = (Expr *) expr;
  182. if (is_opclause(expr))
  183. {
  184. char    *opname;
  185. print_expr((Node *) get_leftop(e), rtable);
  186. opname = get_opname(((Oper *) e->oper)->opno);
  187. printf(" %s ", ((opname != NULL) ? opname : "(invalid operator)"));
  188. print_expr((Node *) get_rightop(e), rtable);
  189. }
  190. else
  191. printf("an expr");
  192. }
  193. else
  194. printf("not an expr");
  195. }
  196. /*
  197.  * print_pathkeys -
  198.  *   pathkeys list of list of Var's
  199.  */
  200. void
  201. print_pathkeys(List *pathkeys, List *rtable)
  202. {
  203. List    *i,
  204.    *k;
  205. printf("(");
  206. foreach(i, pathkeys)
  207. {
  208. List    *pathkey = lfirst(i);
  209. printf("(");
  210. foreach(k, pathkey)
  211. {
  212. Node    *var = lfirst(k);
  213. print_expr(var, rtable);
  214. if (lnext(k))
  215. printf(", ");
  216. }
  217. printf(") ");
  218. if (lnext(i))
  219. printf(", ");
  220. }
  221. printf(")n");
  222. }
  223. /*
  224.  * print_tl
  225.  *   print targetlist in a more legible way.
  226.  */
  227. void
  228. print_tl(List *tlist, List *rtable)
  229. {
  230. List    *tl;
  231. printf("(n");
  232. foreach(tl, tlist)
  233. {
  234. TargetEntry *tle = lfirst(tl);
  235. printf("t%d %st", tle->resdom->resno, tle->resdom->resname);
  236. if (tle->resdom->reskey != 0)
  237. printf("(%d):t", tle->resdom->reskey);
  238. else
  239. printf("    :t");
  240. print_expr(tle->expr, rtable);
  241. printf("n");
  242. }
  243. printf(")n");
  244. }
  245. /*
  246.  * print_slot
  247.  *   print out the tuple with the given TupleTableSlot
  248.  */
  249. void
  250. print_slot(TupleTableSlot *slot)
  251. {
  252. if (!slot->val)
  253. {
  254. printf("tuple is null.n");
  255. return;
  256. }
  257. if (!slot->ttc_tupleDescriptor)
  258. {
  259. printf("no tuple descriptor.n");
  260. return;
  261. }
  262. debugtup(slot->val, slot->ttc_tupleDescriptor, NULL);
  263. }
  264. static char *
  265. plannode_type(Plan *p)
  266. {
  267. switch (nodeTag(p))
  268. {
  269. case T_Plan:
  270. return "PLAN";
  271. break;
  272. case T_Result:
  273. return "RESULT";
  274. break;
  275. case T_Append:
  276. return "APPEND";
  277. break;
  278. case T_Scan:
  279. return "SCAN";
  280. break;
  281. case T_SeqScan:
  282. return "SEQSCAN";
  283. break;
  284. case T_IndexScan:
  285. return "INDEXSCAN";
  286. break;
  287. case T_Join:
  288. return "JOIN";
  289. break;
  290. case T_NestLoop:
  291. return "NESTLOOP";
  292. break;
  293. case T_MergeJoin:
  294. return "MERGEJOIN";
  295. break;
  296. case T_HashJoin:
  297. return "HASHJOIN";
  298. break;
  299. case T_Noname:
  300. return "NONAME";
  301. break;
  302. case T_Material:
  303. return "MATERIAL";
  304. break;
  305. case T_Sort:
  306. return "SORT";
  307. break;
  308. case T_Agg:
  309. return "AGG";
  310. break;
  311. case T_Unique:
  312. return "UNIQUE";
  313. break;
  314. case T_Hash:
  315. return "HASH";
  316. break;
  317. case T_Choose:
  318. return "CHOOSE";
  319. break;
  320. case T_Group:
  321. return "GROUP";
  322. break;
  323. default:
  324. return "UNKNOWN";
  325. break;
  326. }
  327. }
  328. /*
  329.    prints the ascii description of the plan nodes
  330.    does this recursively by doing a depth-first traversal of the
  331.    plan tree.  for SeqScan and IndexScan, the name of the table is also
  332.    printed out
  333. */
  334. void
  335. print_plan_recursive(Plan *p, Query *parsetree, int indentLevel, char *label)
  336. {
  337. int i;
  338. char extraInfo[100];
  339. if (!p)
  340. return;
  341. for (i = 0; i < indentLevel; i++)
  342. printf(" ");
  343. printf("%s%s :c=%.4f :s=%d :w=%d ", label, plannode_type(p),
  344.    p->cost, p->plan_size, p->plan_width);
  345. if (IsA(p, Scan) ||IsA(p, SeqScan))
  346. {
  347. RangeTblEntry *rte;
  348. rte = rt_fetch(((Scan *) p)->scanrelid, parsetree->rtable);
  349. StrNCpy(extraInfo, rte->relname, NAMEDATALEN);
  350. }
  351. else if (IsA(p, IndexScan))
  352. {
  353. StrNCpy(extraInfo,
  354.    ((RangeTblEntry *) (nth(((IndexScan *) p)->scan.scanrelid - 1,
  355.    parsetree->rtable)))->relname,
  356. NAMEDATALEN);
  357. }
  358. else
  359. extraInfo[0] = '';
  360. if (extraInfo[0] != '')
  361. printf(" ( %s )n", extraInfo);
  362. else
  363. printf("n");
  364. print_plan_recursive(p->lefttree, parsetree, indentLevel + 3, "l: ");
  365. print_plan_recursive(p->righttree, parsetree, indentLevel + 3, "r: ");
  366. if (nodeTag(p) == T_Append)
  367. {
  368. List    *lst;
  369. int whichplan = 0;
  370. Append    *appendplan = (Append *) p;
  371. foreach(lst, appendplan->appendplans)
  372. {
  373. Plan    *subnode = (Plan *) lfirst(lst);
  374. /*
  375.  * I don't think we need to fiddle with the range table here,
  376.  * bjm
  377.  */
  378. print_plan_recursive(subnode, parsetree, indentLevel + 3, "a: ");
  379. whichplan++;
  380. }
  381. }
  382. }
  383. /* print_plan
  384.   prints just the plan node types */
  385. void
  386. print_plan(Plan *p, Query *parsetree)
  387. {
  388. print_plan_recursive(p, parsetree, 0, "");
  389. }