[prev in list] [next in list] [prev in thread] [next in thread]
List: pgsql-hackers
Subject: [HACKERS] explain refactoring v2
From: Robert Haas <robertmhaas () gmail ! com>
Date: 2009-05-30 21:33:07
Message-ID: 603c8f070905301433i1804ab9aqecb272a5679405b () mail ! gmail ! com
[Download RAW message or body]
Here's an updated version of my patch from last night.
http://archives.postgresql.org/message-id/603c8f070905292048y804d505wf701214e7b81fde7@mail.gmail.com
In addition to the changes mentioned there, this removes a completely
unused argument from show_scan_qual() and two redundant ones from
show_sort_keys().
I realize this may not be the most glamorous patch that any of you
have read in the last year...
...Robert
["explain_refactor_v2.patch" (text/x-diff)]
*** a/src/backend/commands/explain.c
--- b/src/backend/commands/explain.c
***************
*** 63,78 **** static void explain_outNode(StringInfo str,
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 *scan_plan, Plan *outer_plan,
StringInfo str, int indent, ExplainState *es);
static void show_upper_qual(List *qual, const char *qlabel, Plan *plan,
StringInfo str, int indent, ExplainState *es);
! static void show_sort_keys(Plan *sortplan, int nkeys, AttrNumber *keycols,
! const char *qlabel,
StringInfo str, int indent, ExplainState *es);
static void show_sort_info(SortState *sortstate,
StringInfo str, int indent, ExplainState *es);
static const char *explain_get_index_name(Oid indexId);
/*
--- 63,78 ----
static void show_plan_tlist(Plan *plan,
StringInfo str, int indent, ExplainState *es);
static void show_scan_qual(List *qual, const char *qlabel,
! Plan *scan_plan, Plan *outer_plan,
StringInfo str, int indent, ExplainState *es);
static void show_upper_qual(List *qual, const char *qlabel, Plan *plan,
StringInfo str, int indent, ExplainState *es);
! static void show_sort_keys(Plan *sortplan, const char *qlabel,
StringInfo str, int indent, ExplainState *es);
static void show_sort_info(SortState *sortstate,
StringInfo str, int indent, ExplainState *es);
static const char *explain_get_index_name(Oid indexId);
+ static void ExplainScanTarget(StringInfo str, Scan *plan, ExplainState *es);
/*
***************
*** 668,790 **** explain_outNode(StringInfo str,
case T_SeqScan:
case T_BitmapHeapScan:
case T_TidScan:
- if (((Scan *) plan)->scanrelid > 0)
- {
- RangeTblEntry *rte = rt_fetch(((Scan *) plan)->scanrelid,
- es->rtable);
- char *relname;
-
- /* Assume it's on a real relation */
- Assert(rte->rtekind == RTE_RELATION);
-
- /* We only show the rel name, not schema name */
- relname = get_rel_name(rte->relid);
-
- appendStringInfo(str, " on %s",
- quote_identifier(relname));
- if (strcmp(rte->eref->aliasname, relname) != 0)
- appendStringInfo(str, " %s",
- quote_identifier(rte->eref->aliasname));
- }
- break;
- case T_BitmapIndexScan:
- appendStringInfo(str, " on %s",
- explain_get_index_name(((BitmapIndexScan *) plan)->indexid));
- break;
case T_SubqueryScan:
- if (((Scan *) plan)->scanrelid > 0)
- {
- RangeTblEntry *rte = rt_fetch(((Scan *) plan)->scanrelid,
- es->rtable);
-
- appendStringInfo(str, " %s",
- quote_identifier(rte->eref->aliasname));
- }
- break;
case T_FunctionScan:
- if (((Scan *) plan)->scanrelid > 0)
- {
- RangeTblEntry *rte = rt_fetch(((Scan *) plan)->scanrelid,
- es->rtable);
- Node *funcexpr;
- char *proname;
-
- /* Assert it's on a RangeFunction */
- Assert(rte->rtekind == RTE_FUNCTION);
-
- /*
- * If the expression is still a function call, we can get the
- * real name of the function. Otherwise, punt (this can
- * happen if the optimizer simplified away the function call,
- * for example).
- */
- funcexpr = ((FunctionScan *) plan)->funcexpr;
- if (funcexpr && IsA(funcexpr, FuncExpr))
- {
- Oid funcid = ((FuncExpr *) funcexpr)->funcid;
-
- /* We only show the func name, not schema name */
- proname = get_func_name(funcid);
- }
- else
- proname = rte->eref->aliasname;
-
- appendStringInfo(str, " on %s",
- quote_identifier(proname));
- if (strcmp(rte->eref->aliasname, proname) != 0)
- appendStringInfo(str, " %s",
- quote_identifier(rte->eref->aliasname));
- }
- break;
case T_ValuesScan:
- if (((Scan *) plan)->scanrelid > 0)
- {
- RangeTblEntry *rte = rt_fetch(((Scan *) plan)->scanrelid,
- es->rtable);
- char *valsname;
-
- /* Assert it's on a values rte */
- Assert(rte->rtekind == RTE_VALUES);
-
- valsname = rte->eref->aliasname;
-
- appendStringInfo(str, " on %s",
- quote_identifier(valsname));
- }
- break;
case T_CteScan:
- if (((Scan *) plan)->scanrelid > 0)
- {
- RangeTblEntry *rte = rt_fetch(((Scan *) plan)->scanrelid,
- es->rtable);
-
- /* Assert it's on a non-self-reference CTE */
- Assert(rte->rtekind == RTE_CTE);
- Assert(!rte->self_reference);
-
- appendStringInfo(str, " on %s",
- quote_identifier(rte->ctename));
- if (strcmp(rte->eref->aliasname, rte->ctename) != 0)
- appendStringInfo(str, " %s",
- quote_identifier(rte->eref->aliasname));
- }
- break;
case T_WorkTableScan:
! if (((Scan *) plan)->scanrelid > 0)
! {
! RangeTblEntry *rte = rt_fetch(((Scan *) plan)->scanrelid,
! es->rtable);
!
! /* Assert it's on a self-reference CTE */
! Assert(rte->rtekind == RTE_CTE);
! Assert(rte->self_reference);
!
! appendStringInfo(str, " on %s",
! quote_identifier(rte->ctename));
! if (strcmp(rte->eref->aliasname, rte->ctename) != 0)
! appendStringInfo(str, " %s",
! quote_identifier(rte->eref->aliasname));
! }
break;
default:
break;
--- 668,683 ----
case T_SeqScan:
case T_BitmapHeapScan:
case T_TidScan:
case T_SubqueryScan:
case T_FunctionScan:
case T_ValuesScan:
case T_CteScan:
case T_WorkTableScan:
! ExplainScanTarget(str, (Scan *) plan, es);
! break;
! case T_BitmapIndexScan:
! appendStringInfo(str, " on %s",
! explain_get_index_name(((BitmapIndexScan *) plan)->indexid));
break;
default:
break;
***************
*** 825,843 **** explain_outNode(StringInfo str,
case T_IndexScan:
show_scan_qual(((IndexScan *) plan)->indexqualorig,
"Index Cond",
- ((Scan *) plan)->scanrelid,
plan, outer_plan,
str, indent, es);
show_scan_qual(plan->qual,
"Filter",
- ((Scan *) plan)->scanrelid,
plan, outer_plan,
str, indent, es);
break;
case T_BitmapIndexScan:
show_scan_qual(((BitmapIndexScan *) plan)->indexqualorig,
"Index Cond",
- ((Scan *) plan)->scanrelid,
plan, outer_plan,
str, indent, es);
break;
--- 718,733 ----
***************
*** 845,851 **** explain_outNode(StringInfo str,
/* XXX do we want to show this in production? */
show_scan_qual(((BitmapHeapScan *) plan)->bitmapqualorig,
"Recheck Cond",
- ((Scan *) plan)->scanrelid,
plan, outer_plan,
str, indent, es);
/* FALL THRU */
--- 735,740 ----
***************
*** 854,869 **** explain_outNode(StringInfo str,
case T_ValuesScan:
case T_CteScan:
case T_WorkTableScan:
- show_scan_qual(plan->qual,
- "Filter",
- ((Scan *) plan)->scanrelid,
- plan, outer_plan,
- str, indent, es);
- break;
case T_SubqueryScan:
show_scan_qual(plan->qual,
"Filter",
- ((Scan *) plan)->scanrelid,
plan, outer_plan,
str, indent, es);
break;
--- 743,751 ----
***************
*** 879,890 **** explain_outNode(StringInfo str,
tidquals = list_make1(make_orclause(tidquals));
show_scan_qual(tidquals,
"TID Cond",
- ((Scan *) plan)->scanrelid,
plan, outer_plan,
str, indent, es);
show_scan_qual(plan->qual,
"Filter",
- ((Scan *) plan)->scanrelid,
plan, outer_plan,
str, indent, es);
}
--- 761,770 ----
***************
*** 927,934 **** explain_outNode(StringInfo str,
break;
case T_Sort:
show_sort_keys(plan,
- ((Sort *) plan)->numCols,
- ((Sort *) plan)->sortColIdx,
"Sort Key",
str, indent, es);
show_sort_info((SortState *) planstate,
--- 807,812 ----
***************
*** 1179,1185 **** show_plan_tlist(Plan *plan,
*/
static void
show_scan_qual(List *qual, const char *qlabel,
! int scanrelid, Plan *scan_plan, Plan *outer_plan,
StringInfo str, int indent, ExplainState *es)
{
List *context;
--- 1057,1063 ----
*/
static void
show_scan_qual(List *qual, const char *qlabel,
! Plan *scan_plan, Plan *outer_plan,
StringInfo str, int indent, ExplainState *es)
{
List *context;
***************
*** 1249,1256 **** show_upper_qual(List *qual, const char *qlabel, Plan *plan,
* Show the sort keys for a Sort node.
*/
static void
! show_sort_keys(Plan *sortplan, int nkeys, AttrNumber *keycols,
! const char *qlabel,
StringInfo str, int indent, ExplainState *es)
{
List *context;
--- 1127,1133 ----
* Show the sort keys for a Sort node.
*/
static void
! show_sort_keys(Plan *sortplan, const char *qlabel,
StringInfo str, int indent, ExplainState *es)
{
List *context;
***************
*** 1258,1263 **** show_sort_keys(Plan *sortplan, int nkeys, AttrNumber *keycols,
--- 1135,1142 ----
int keyno;
char *exprstr;
int i;
+ int nkeys = ((Sort *) sortplan)->numCols;
+ AttrNumber *keycols = ((Sort *) sortplan)->sortColIdx;
if (nkeys <= 0)
return;
***************
*** 1340,1342 **** explain_get_index_name(Oid indexId)
--- 1219,1288 ----
}
return result;
}
+
+ /*
+ * Explain details for Scan nodes.
+ */
+ static void
+ ExplainScanTarget(StringInfo str, Scan *plan, ExplainState *es)
+ {
+ char *objectname = NULL;
+ Node *funcexpr;
+ RangeTblEntry *rte;
+
+ if (plan->scanrelid <= 0)
+ return;
+ rte = rt_fetch(plan->scanrelid, es->rtable);
+
+ switch (nodeTag(plan))
+ {
+ case T_IndexScan:
+ case T_SeqScan:
+ case T_BitmapHeapScan:
+ case T_TidScan:
+ /* Assert it's on a real relation */
+ Assert(rte->rtekind == RTE_RELATION);
+ objectname = get_rel_name(rte->relid);
+ break;
+ case T_FunctionScan:
+ /* Assert it's on a RangeFunction */
+ Assert(rte->rtekind == RTE_FUNCTION);
+
+ /*
+ * If the expression is still a function call, we can get the
+ * real name of the function. Otherwise, punt (this can
+ * happen if the optimizer simplified away the function call,
+ * for example).
+ */
+ funcexpr = ((FunctionScan *) plan)->funcexpr;
+ if (funcexpr && IsA(funcexpr, FuncExpr))
+ {
+ Oid funcid = ((FuncExpr *) funcexpr)->funcid;
+ objectname = get_func_name(funcid);
+ }
+ break;
+ case T_ValuesScan:
+ Assert(rte->rtekind == RTE_VALUES);
+ break;
+ case T_CteScan:
+ /* Assert it's on a non-self-reference CTE */
+ Assert(rte->rtekind == RTE_CTE);
+ Assert(!rte->self_reference);
+ objectname = rte->ctename;
+ break;
+ case T_WorkTableScan:
+ /* Assert it's on a self-reference CTE */
+ Assert(rte->rtekind == RTE_CTE);
+ Assert(rte->self_reference);
+ objectname = rte->ctename;
+ break;
+ default:
+ break;
+ }
+
+ appendStringInfoString(str, " on");
+ if (objectname != NULL)
+ appendStringInfo(str, " %s", quote_identifier(objectname));
+ if (objectname == NULL || strcmp(rte->eref->aliasname, objectname) != 0)
+ appendStringInfo(str, " %s", quote_identifier(rte->eref->aliasname));
+ }
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic