aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/explain.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/explain.c')
-rw-r--r--src/backend/commands/explain.c353
1 files changed, 184 insertions, 169 deletions
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index 7d1f34d0327..192076e3911 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* explain.c--
- * Explain the query execution plan
+ * Explain the query execution plan
*
* Copyright (c) 1994-5, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.10 1997/08/18 20:52:17 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.11 1997/09/07 04:40:49 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,7 +17,7 @@
#include <postgres.h>
#include <parser/catalog_utils.h>
-#include <parser/parse_query.h> /* for MakeTimeRange() */
+#include <parser/parse_query.h> /* for MakeTimeRange() */
#include <nodes/plannodes.h>
#include <tcop/tcopprot.h>
#include <lib/stringinfo.h>
@@ -25,79 +25,86 @@
#include <optimizer/planner.h>
#include <access/xact.h>
-typedef struct ExplainState {
- /* options */
- bool printCost; /* print cost */
- bool printNodes; /* do nodeToString() instead */
- /* other states */
- List *rtable; /* range table */
-} ExplainState;
+typedef struct ExplainState
+{
+ /* options */
+ bool printCost; /* print cost */
+ bool printNodes; /* do nodeToString() instead */
+ /* other states */
+ List *rtable; /* range table */
+} ExplainState;
-static char *Explain_PlanToString(Plan *plan, ExplainState *es);
+static char *Explain_PlanToString(Plan * plan, ExplainState * es);
/*
* ExplainQuery -
- * print out the execution plan for a given query
+ * print out the execution plan for a given query
*
*/
void
-ExplainQuery(Query *query, bool verbose, CommandDest dest)
+ExplainQuery(Query * query, bool verbose, CommandDest dest)
{
- char *s = NULL, *s2;
- Plan *plan;
- ExplainState *es;
- int len;
-
- if (IsAbortedTransactionBlockState()) {
- char *tag = "*ABORT STATE*";
- EndCommand(tag, dest);
-
- elog(NOTICE, "(transaction aborted): %s",
- "queries ignored until END");
-
- return;
- }
+ char *s = NULL,
+ *s2;
+ Plan *plan;
+ ExplainState *es;
+ int len;
- /* plan the queries (XXX we've ignored rewrite!!) */
- plan = planner(query);
+ if (IsAbortedTransactionBlockState())
+ {
+ char *tag = "*ABORT STATE*";
- /* pg_plan could have failed */
- if (plan == NULL)
- return;
+ EndCommand(tag, dest);
+
+ elog(NOTICE, "(transaction aborted): %s",
+ "queries ignored until END");
+
+ return;
+ }
- es = (ExplainState*)malloc(sizeof(ExplainState));
- memset(es, 0, sizeof(ExplainState));
+ /* plan the queries (XXX we've ignored rewrite!!) */
+ plan = planner(query);
- es->printCost = true; /* default */
+ /* pg_plan could have failed */
+ if (plan == NULL)
+ return;
- if (verbose)
- es->printNodes = true;
+ es = (ExplainState *) malloc(sizeof(ExplainState));
+ memset(es, 0, sizeof(ExplainState));
- es->rtable = query->rtable;
+ es->printCost = true; /* default */
- if (es->printNodes)
- s = nodeToString(plan);
+ if (verbose)
+ es->printNodes = true;
- if (es->printCost) {
- s2 = Explain_PlanToString(plan, es);
- if (s == NULL)
- s = s2;
- else {
- strcat(s, "\n\n");
- strcat(s, s2);
+ es->rtable = query->rtable;
+
+ if (es->printNodes)
+ s = nodeToString(plan);
+
+ if (es->printCost)
+ {
+ s2 = Explain_PlanToString(plan, es);
+ if (s == NULL)
+ s = s2;
+ else
+ {
+ strcat(s, "\n\n");
+ strcat(s, s2);
+ }
}
- }
-
- /* output the plan */
- len = strlen(s);
- elog(NOTICE, "QUERY PLAN:\n\n%.*s", ELOG_MAXLEN-64, s);
- len -= ELOG_MAXLEN-64;
- while (len > 0) {
- s += ELOG_MAXLEN-64;
- elog(NOTICE, "%.*s", ELOG_MAXLEN-64, s);
- len -= ELOG_MAXLEN-64;
- }
- free(es);
+
+ /* output the plan */
+ len = strlen(s);
+ elog(NOTICE, "QUERY PLAN:\n\n%.*s", ELOG_MAXLEN - 64, s);
+ len -= ELOG_MAXLEN - 64;
+ while (len > 0)
+ {
+ s += ELOG_MAXLEN - 64;
+ elog(NOTICE, "%.*s", ELOG_MAXLEN - 64, s);
+ len -= ELOG_MAXLEN - 64;
+ }
+ free(es);
}
/*****************************************************************************
@@ -106,122 +113,130 @@ ExplainQuery(Query *query, bool verbose, CommandDest dest)
/*
* explain_outNode -
- * converts a Node into ascii string and append it to 'str'
+ * converts a Node into ascii string and append it to 'str'
*/
static void
-explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es)
+explain_outNode(StringInfo str, Plan * plan, int indent, ExplainState * es)
{
- char *pname;
- char buf[1000];
- int i;
-
- if (plan==NULL) {
+ char *pname;
+ char buf[1000];
+ int i;
+
+ if (plan == NULL)
+ {
+ appendStringInfo(str, "\n");
+ return;
+ }
+
+ switch (nodeTag(plan))
+ {
+ case T_Result:
+ pname = "Result";
+ break;
+ case T_Append:
+ pname = "Append";
+ break;
+ case T_NestLoop:
+ pname = "Nested Loop";
+ break;
+ case T_MergeJoin:
+ pname = "Merge Join";
+ break;
+ case T_HashJoin:
+ pname = "Hash Join";
+ break;
+ case T_SeqScan:
+ pname = "Seq Scan";
+ break;
+ case T_IndexScan:
+ pname = "Index Scan";
+ break;
+ case T_Temp:
+ pname = "Temp Scan";
+ break;
+ case T_Sort:
+ pname = "Sort";
+ break;
+ case T_Group:
+ pname = "Group";
+ break;
+ case T_Agg:
+ pname = "Aggregate";
+ break;
+ case T_Unique:
+ pname = "Unique";
+ break;
+ case T_Hash:
+ pname = "Hash";
+ break;
+ case T_Tee:
+ pname = "Tee";
+ break;
+ default:
+ pname = "";
+ break;
+ }
+
+ for (i = 0; i < indent; i++)
+ appendStringInfo(str, " ");
+
+ appendStringInfo(str, pname);
+ switch (nodeTag(plan))
+ {
+ case T_SeqScan:
+ case T_IndexScan:
+ if (((Scan *) plan)->scanrelid > 0)
+ {
+ RangeTblEntry *rte = nth(((Scan *) plan)->scanrelid - 1, es->rtable);
+
+ sprintf(buf, " on %s", rte->refname);
+ appendStringInfo(str, buf);
+ }
+ break;
+ default:
+ break;
+ }
+ if (es->printCost)
+ {
+ sprintf(buf, " (cost=%.2f size=%d width=%d)",
+ plan->cost, plan->plan_size, plan->plan_width);
+ appendStringInfo(str, buf);
+ }
appendStringInfo(str, "\n");
- return;
- }
-
- switch(nodeTag(plan)) {
- case T_Result:
- pname = "Result";
- break;
- case T_Append:
- pname = "Append";
- break;
- case T_NestLoop:
- pname = "Nested Loop";
- break;
- case T_MergeJoin:
- pname = "Merge Join";
- break;
- case T_HashJoin:
- pname = "Hash Join";
- break;
- case T_SeqScan:
- pname = "Seq Scan";
- break;
- case T_IndexScan:
- pname = "Index Scan";
- break;
- case T_Temp:
- pname = "Temp Scan";
- break;
- case T_Sort:
- pname = "Sort";
- break;
- case T_Group:
- pname = "Group";
- break;
- case T_Agg:
- pname = "Aggregate";
- break;
- case T_Unique:
- pname = "Unique";
- break;
- case T_Hash:
- pname = "Hash";
- break;
- case T_Tee:
- pname = "Tee";
- break;
- default:
- pname = "";
- break;
- }
-
- for(i=0; i < indent; i++)
- appendStringInfo(str, " ");
-
- appendStringInfo(str, pname);
- switch(nodeTag(plan)) {
- case T_SeqScan:
- case T_IndexScan:
- if (((Scan*)plan)->scanrelid > 0) {
- RangeTblEntry *rte = nth(((Scan*)plan)->scanrelid-1, es->rtable);
- sprintf(buf, " on %s", rte->refname);
- appendStringInfo(str, buf);
+
+ /* lefttree */
+ if (outerPlan(plan))
+ {
+ for (i = 0; i < indent; i++)
+ appendStringInfo(str, " ");
+ appendStringInfo(str, " -> ");
+ explain_outNode(str, outerPlan(plan), indent + 1, es);
}
- break;
- default:
- break;
- }
- if (es->printCost) {
- sprintf(buf, " (cost=%.2f size=%d width=%d)",
- plan->cost, plan->plan_size, plan->plan_width);
- appendStringInfo(str, buf);
- }
- appendStringInfo(str, "\n");
-
- /* lefttree */
- if (outerPlan(plan)) {
- for(i=0; i < indent; i++)
- appendStringInfo(str, " ");
- appendStringInfo(str, " -> ");
- explain_outNode(str, outerPlan(plan), indent+1, es);
- }
-
- /* righttree */
- if (innerPlan(plan)) {
- for(i=0; i < indent; i++)
- appendStringInfo(str, " ");
- appendStringInfo(str, " -> ");
- explain_outNode(str, innerPlan(plan), indent+1, es);
- }
- return;
+
+ /* righttree */
+ if (innerPlan(plan))
+ {
+ for (i = 0; i < indent; i++)
+ appendStringInfo(str, " ");
+ appendStringInfo(str, " -> ");
+ explain_outNode(str, innerPlan(plan), indent + 1, es);
+ }
+ return;
}
-static char *
-Explain_PlanToString(Plan *plan, ExplainState *es)
+static char *
+Explain_PlanToString(Plan * plan, ExplainState * es)
{
- StringInfo str;
- char *s;
-
- if (plan==NULL)
- return "";
- Assert(plan!=NULL);
- str = makeStringInfo();
- explain_outNode(str, plan, 0, es);
- s = str->data;
- pfree(str);
-
- return s;
+ StringInfo str;
+ char *s;
+
+ if (plan == NULL)
+ return "";
+ Assert(plan != NULL);
+ str = makeStringInfo();
+ explain_outNode(str, plan, 0, es);
+ s = str->data;
+ pfree(str);
+
+ return s;
}