Add some code to EXPLAIN to show the targetlist (ie, output columns)
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 17 Apr 2008 18:30:18 +0000 (18:30 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 17 Apr 2008 18:30:18 +0000 (18:30 +0000)
of each plan node.  For the moment this is debug support only and is
not enabled unless EXPLAIN_PRINT_TLISTS is defined at build time.
Later I'll see about the idea of letting EXPLAIN VERBOSE do it.

src/backend/commands/explain.c

index d1511b2fe8c0460764ee3491d6abc151b8ab6f4e..768ae7797ef80a6e1393b29f3de3d053ad64a9b8 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994-5, Regents of the University of California
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.171 2008/03/26 18:48:59 alvherre Exp $
+ *   $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.172 2008/04/17 18:30:18 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -61,6 +61,8 @@ static void explain_outNode(StringInfo str,
                Plan *plan, PlanState *planstate,
                Plan *outer_plan,
                int indent, ExplainState *es);
+static void show_plan_tlist(Plan *plan,
+                           StringInfo str, int indent, ExplainState *es);
 static void show_scan_qual(List *qual, const char *qlabel,
               int scanrelid, Plan *outer_plan, Plan *inner_plan,
               StringInfo str, int indent, ExplainState *es);
@@ -443,7 +445,7 @@ explain_outNode(StringInfo str,
                Plan *outer_plan,
                int indent, ExplainState *es)
 {
-   char       *pname;
+   const char *pname;
    int         i;
 
    if (plan == NULL)
@@ -744,6 +746,9 @@ explain_outNode(StringInfo str,
        appendStringInfo(str, " (never executed)");
    appendStringInfoChar(str, '\n');
 
+   /* target list */
+   show_plan_tlist(plan, str, indent, es);
+
    /* quals, sort keys, etc */
    switch (nodeTag(plan))
    {
@@ -1043,6 +1048,56 @@ explain_outNode(StringInfo str,
    }
 }
 
+/*
+ * Show the targetlist of a plan node
+ */
+static void
+show_plan_tlist(Plan *plan,
+               StringInfo str, int indent, ExplainState *es)
+{
+#ifdef EXPLAIN_PRINT_TLISTS
+   List       *context;
+   bool        useprefix;
+   ListCell   *lc;
+   int         i;
+
+   /* No work if empty tlist (this occurs eg in bitmap indexscans) */
+   if (plan->targetlist == NIL)
+       return;
+   /* The tlist of an Append isn't real helpful, so suppress it */
+   if (IsA(plan, Append))
+       return;
+
+   /* Set up deparsing context */
+   context = deparse_context_for_plan((Node *) outerPlan(plan),
+                                      (Node *) innerPlan(plan),
+                                      es->rtable);
+   useprefix = list_length(es->rtable) > 1;
+
+   /* Emit line prefix */
+   for (i = 0; i < indent; i++)
+       appendStringInfo(str, "  ");
+   appendStringInfo(str, "  Output: ");
+
+   /* Deparse each non-junk result column */
+   i = 0;
+   foreach(lc, plan->targetlist)
+   {
+       TargetEntry *tle = (TargetEntry *) lfirst(lc);
+
+       if (tle->resjunk)
+           continue;
+       if (i++ > 0)
+           appendStringInfo(str, ", ");
+       appendStringInfoString(str,
+                              deparse_expression((Node *) tle->expr, context,
+                                                 useprefix, false));
+   }
+
+   appendStringInfoChar(str, '\n');
+#endif /* EXPLAIN_PRINT_TLISTS */
+}
+
 /*
  * Show a qualifier expression for a scan plan node
  *