summaryrefslogtreecommitdiff
path: root/src/backend/nodes/print.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/nodes/print.c')
-rw-r--r--src/backend/nodes/print.c589
1 files changed, 0 insertions, 589 deletions
diff --git a/src/backend/nodes/print.c b/src/backend/nodes/print.c
deleted file mode 100644
index 4e81ed14f28..00000000000
--- a/src/backend/nodes/print.c
+++ /dev/null
@@ -1,589 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * print.c
- * various print routines (used mostly for debugging)
- *
- * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.56 2002/06/20 20:29:29 momjian Exp $
- *
- * HISTORY
- * AUTHOR DATE MAJOR EVENT
- * Andrew Yu Oct 26, 1994 file creation
- *
- *-------------------------------------------------------------------------
- */
-
-#include "postgres.h"
-
-#include "access/printtup.h"
-#include "catalog/pg_type.h"
-#include "lib/stringinfo.h"
-#include "nodes/print.h"
-#include "optimizer/clauses.h"
-#include "parser/parsetree.h"
-#include "utils/lsyscache.h"
-#include "utils/syscache.h"
-
-static char *plannode_type(Plan *p);
-
-/*
- * print
- * print contents of Node to stdout
- */
-void
-print(void *obj)
-{
- char *s;
- char *f;
-
- s = nodeToString(obj);
- f = format_node_dump(s);
- pfree(s);
- printf("%s\n", f);
- fflush(stdout);
- pfree(f);
-}
-
-/*
- * pprint
- * pretty-print contents of Node to stdout
- */
-void
-pprint(void *obj)
-{
- char *s;
- char *f;
-
- s = nodeToString(obj);
- f = pretty_format_node_dump(s);
- pfree(s);
- printf("%s\n", f);
- fflush(stdout);
- pfree(f);
-}
-
-/*
- * elog_node_display
- * send pretty-printed contents of Node to postmaster log
- */
-void
-elog_node_display(int lev, const char *title, void *obj, bool pretty)
-{
- char *s;
- char *f;
-
- s = nodeToString(obj);
- if (pretty)
- f = pretty_format_node_dump(s);
- else
- f = format_node_dump(s);
- pfree(s);
- elog(lev, "%s:\n%s", title, f);
- pfree(f);
-}
-
-/*
- * Format a nodeToString output for display on a terminal.
- *
- * The result is a palloc'd string.
- *
- * This version just tries to break at whitespace.
- */
-char *
-format_node_dump(const char *dump)
-{
-#define LINELEN 78
- char line[LINELEN+1];
- StringInfoData str;
- int i;
- int j;
- int k;
-
- initStringInfo(&str);
- i = 0;
- for (;;)
- {
- for (j = 0; j < LINELEN && dump[i] != '\0'; i++, j++)
- line[j] = dump[i];
- if (dump[i] == '\0')
- break;
- if (dump[i] == ' ')
- {
- /* ok to break at adjacent space */
- i++;
- }
- else
- {
- for (k = j-1; k > 0; k--)
- if (line[k] == ' ')
- break;
- if (k > 0)
- {
- /* back up; will reprint all after space */
- i -= (j-k-1);
- j = k;
- }
- }
- line[j] = '\0';
- appendStringInfo(&str, "%s\n", line);
- }
- if (j > 0)
- {
- line[j] = '\0';
- appendStringInfo(&str, "%s\n", line);
- }
- return str.data;
-#undef LINELEN
-}
-
-/*
- * Format a nodeToString output for display on a terminal.
- *
- * The result is a palloc'd string.
- *
- * This version tries to indent intelligently.
- */
-char *
-pretty_format_node_dump(const char *dump)
-{
-#define INDENTSTOP 3
-#define MAXINDENT 60
-#define LINELEN 78
- char line[LINELEN+1];
- StringInfoData str;
- int indentLev;
- int indentDist;
- int i;
- int j;
-
- initStringInfo(&str);
- indentLev = 0; /* logical indent level */
- indentDist = 0; /* physical indent distance */
- i = 0;
- for (;;)
- {
- for (j = 0; j < indentDist; j++)
- line[j] = ' ';
- for (; j < LINELEN && dump[i] != '\0'; i++, j++)
- {
- line[j] = dump[i];
- switch (line[j])
- {
- case '}':
- if (j != indentDist)
- {
- /* print data before the } */
- line[j] = '\0';
- appendStringInfo(&str, "%s\n", line);
- }
- /* print the } at indentDist */
- line[indentDist] = '}';
- line[indentDist+1] = '\0';
- appendStringInfo(&str, "%s\n", line);
- /* outdent */
- if (indentLev > 0)
- {
- indentLev--;
- indentDist = Min(indentLev * INDENTSTOP, MAXINDENT);
- }
- j = indentDist - 1;
- /* j will equal indentDist on next loop iteration */
- break;
- case ')':
- /* force line break after ')' */
- line[j + 1] = '\0';
- appendStringInfo(&str, "%s\n", line);
- j = indentDist - 1;
- break;
- case '{':
- /* force line break before { */
- if (j != indentDist)
- {
- line[j] = '\0';
- appendStringInfo(&str, "%s\n", line);
- }
- /* indent */
- indentLev++;
- indentDist = Min(indentLev * INDENTSTOP, MAXINDENT);
- for (j = 0; j < indentDist; j++)
- line[j] = ' ';
- line[j] = dump[i];
- break;
- case ':':
- /* force line break before : */
- if (j != indentDist)
- {
- line[j] = '\0';
- appendStringInfo(&str, "%s\n", line);
- }
- j = indentDist;
- line[j] = dump[i];
- break;
- }
- }
- line[j] = '\0';
- if (dump[i] == '\0')
- break;
- appendStringInfo(&str, "%s\n", line);
- }
- if (j > 0)
- appendStringInfo(&str, "%s\n", line);
- return str.data;
-#undef INDENTSTOP
-#undef MAXINDENT
-#undef LINELEN
-}
-
-/*
- * print_rt
- * print contents of range table
- */
-void
-print_rt(List *rtable)
-{
- List *l;
- int i = 1;
-
- printf("resno\trefname \trelid\tinFromCl\n");
- printf("-----\t---------\t-----\t--------\n");
- foreach(l, rtable)
- {
- RangeTblEntry *rte = lfirst(l);
-
- switch (rte->rtekind)
- {
- case RTE_RELATION:
- printf("%d\t%s\t%u",
- i, rte->eref->aliasname, rte->relid);
- break;
- case RTE_SUBQUERY:
- printf("%d\t%s\t[subquery]",
- i, rte->eref->aliasname);
- break;
- case RTE_FUNCTION:
- printf("%d\t%s\t[rangefunction]",
- i, rte->eref->aliasname);
- break;
- case RTE_JOIN:
- printf("%d\t%s\t[join]",
- i, rte->eref->aliasname);
- break;
- case RTE_SPECIAL:
- printf("%d\t%s\t[special]",
- i, rte->eref->aliasname);
- break;
- default:
- printf("%d\t%s\t[unknown rtekind]",
- i, rte->eref->aliasname);
- }
-
- printf("\t%s\t%s\n",
- (rte->inh ? "inh" : ""),
- (rte->inFromCl ? "inFromCl" : ""));
- i++;
- }
-}
-
-
-/*
- * print_expr
- * print an expression
- */
-void
-print_expr(Node *expr, List *rtable)
-{
- if (expr == NULL)
- {
- printf("<>");
- return;
- }
-
- if (IsA(expr, Var))
- {
- Var *var = (Var *) expr;
- char *relname,
- *attname;
-
- switch (var->varno)
- {
- case INNER:
- relname = "INNER";
- attname = "?";
- break;
- case OUTER:
- relname = "OUTER";
- attname = "?";
- break;
- default:
- {
- RangeTblEntry *rte;
-
- Assert(var->varno > 0 &&
- (int) var->varno <= length(rtable));
- rte = rt_fetch(var->varno, rtable);
- relname = rte->eref->aliasname;
- attname = get_rte_attribute_name(rte, var->varattno);
- }
- break;
- }
- printf("%s.%s", relname, attname);
- }
- else if (IsA(expr, Const))
- {
- Const *c = (Const *) expr;
- HeapTuple typeTup;
- Oid typoutput;
- Oid typelem;
- char *outputstr;
-
- if (c->constisnull)
- {
- printf("NULL");
- return;
- }
-
- typeTup = SearchSysCache(TYPEOID,
- ObjectIdGetDatum(c->consttype),
- 0, 0, 0);
- if (!HeapTupleIsValid(typeTup))
- elog(ERROR, "Cache lookup for type %u failed", c->consttype);
- typoutput = ((Form_pg_type) GETSTRUCT(typeTup))->typoutput;
- typelem = ((Form_pg_type) GETSTRUCT(typeTup))->typelem;
- ReleaseSysCache(typeTup);
-
- outputstr = DatumGetCString(OidFunctionCall3(typoutput,
- c->constvalue,
- ObjectIdGetDatum(typelem),
- Int32GetDatum(-1)));
- printf("%s", outputstr);
- pfree(outputstr);
- }
- else if (IsA(expr, Expr))
- {
- Expr *e = (Expr *) expr;
-
- if (is_opclause(expr))
- {
- char *opname;
-
- print_expr((Node *) get_leftop(e), rtable);
- opname = get_opname(((Oper *) e->oper)->opno);
- printf(" %s ", ((opname != NULL) ? opname : "(invalid operator)"));
- print_expr((Node *) get_rightop(e), rtable);
- }
- else
- printf("an expr");
- }
- else
- printf("not an expr");
-}
-
-/*
- * print_pathkeys -
- * pathkeys list of list of PathKeyItems
- */
-void
-print_pathkeys(List *pathkeys, List *rtable)
-{
- List *i,
- *k;
-
- printf("(");
- foreach(i, pathkeys)
- {
- List *pathkey = lfirst(i);
-
- printf("(");
- foreach(k, pathkey)
- {
- PathKeyItem *item = lfirst(k);
-
- print_expr(item->key, rtable);
- if (lnext(k))
- printf(", ");
- }
- printf(")");
- if (lnext(i))
- printf(", ");
- }
- printf(")\n");
-}
-
-/*
- * print_tl
- * print targetlist in a more legible way.
- */
-void
-print_tl(List *tlist, List *rtable)
-{
- List *tl;
-
- printf("(\n");
- foreach(tl, tlist)
- {
- TargetEntry *tle = lfirst(tl);
-
- printf("\t%d %s\t", tle->resdom->resno, tle->resdom->resname);
- if (tle->resdom->reskey != 0)
- printf("(%d):\t", tle->resdom->reskey);
- else
- printf(" :\t");
- print_expr(tle->expr, rtable);
- printf("\n");
- }
- printf(")\n");
-}
-
-/*
- * print_slot
- * print out the tuple with the given TupleTableSlot
- */
-void
-print_slot(TupleTableSlot *slot)
-{
- if (!slot->val)
- {
- printf("tuple is null.\n");
- return;
- }
- if (!slot->ttc_tupleDescriptor)
- {
- printf("no tuple descriptor.\n");
- return;
- }
-
- debugtup(slot->val, slot->ttc_tupleDescriptor, NULL);
-}
-
-static char *
-plannode_type(Plan *p)
-{
- switch (nodeTag(p))
- {
- case T_Plan:
- return "PLAN";
- case T_Result:
- return "RESULT";
- case T_Append:
- return "APPEND";
- case T_Scan:
- return "SCAN";
- case T_SeqScan:
- return "SEQSCAN";
- case T_IndexScan:
- return "INDEXSCAN";
- case T_TidScan:
- return "TIDSCAN";
- case T_SubqueryScan:
- return "SUBQUERYSCAN";
- case T_FunctionScan:
- return "FUNCTIONSCAN";
- case T_Join:
- return "JOIN";
- case T_NestLoop:
- return "NESTLOOP";
- case T_MergeJoin:
- return "MERGEJOIN";
- case T_HashJoin:
- return "HASHJOIN";
- case T_Material:
- return "MATERIAL";
- case T_Sort:
- return "SORT";
- case T_Agg:
- return "AGG";
- case T_Unique:
- return "UNIQUE";
- case T_SetOp:
- return "SETOP";
- case T_Limit:
- return "LIMIT";
- case T_Hash:
- return "HASH";
- case T_Group:
- return "GROUP";
- default:
- return "UNKNOWN";
- }
-}
-
-/*
- * Recursively prints a simple text description of the plan tree
- */
-void
-print_plan_recursive(Plan *p, Query *parsetree, int indentLevel, char *label)
-{
- int i;
- char extraInfo[NAMEDATALEN + 100];
-
- if (!p)
- return;
- for (i = 0; i < indentLevel; i++)
- printf(" ");
- printf("%s%s :c=%.2f..%.2f :r=%.0f :w=%d ", label, plannode_type(p),
- p->startup_cost, p->total_cost,
- p->plan_rows, p->plan_width);
- if (IsA(p, Scan) ||
- IsA(p, SeqScan))
- {
- RangeTblEntry *rte;
-
- rte = rt_fetch(((Scan *) p)->scanrelid, parsetree->rtable);
- StrNCpy(extraInfo, rte->eref->aliasname, NAMEDATALEN);
- }
- else if (IsA(p, IndexScan))
- {
- RangeTblEntry *rte;
-
- rte = rt_fetch(((IndexScan *) p)->scan.scanrelid, parsetree->rtable);
- StrNCpy(extraInfo, rte->eref->aliasname, NAMEDATALEN);
- }
- else if (IsA(p, FunctionScan))
- {
- RangeTblEntry *rte;
-
- rte = rt_fetch(((FunctionScan *) p)->scan.scanrelid, parsetree->rtable);
- StrNCpy(extraInfo, rte->eref->aliasname, NAMEDATALEN);
- }
- else
- extraInfo[0] = '\0';
- if (extraInfo[0] != '\0')
- printf(" ( %s )\n", extraInfo);
- else
- printf("\n");
- print_plan_recursive(p->lefttree, parsetree, indentLevel + 3, "l: ");
- print_plan_recursive(p->righttree, parsetree, indentLevel + 3, "r: ");
-
- if (IsA(p, Append))
- {
- List *lst;
- int whichplan = 0;
- Append *appendplan = (Append *) p;
-
- foreach(lst, appendplan->appendplans)
- {
- Plan *subnode = (Plan *) lfirst(lst);
-
- /*
- * I don't think we need to fiddle with the range table here,
- * bjm
- */
- print_plan_recursive(subnode, parsetree, indentLevel + 3, "a: ");
-
- whichplan++;
- }
- }
-}
-
-/* print_plan
- prints just the plan node types */
-
-void
-print_plan(Plan *p, Query *parsetree)
-{
- print_plan_recursive(p, parsetree, 0, "");
-}