From: Tom Lane Date: Sat, 18 May 2002 21:38:41 +0000 (+0000) Subject: Add display of sort keys to the default EXPLAIN output. X-Git-Tag: REL7_3~1517 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=dd9af92c413827404e87d479a48c5eb696857423;p=postgresql Add display of sort keys to the default EXPLAIN output. --- diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index cb2b2d0f23..a7412b0e72 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -5,7 +5,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994-5, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.77 2002/05/12 20:10:02 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.78 2002/05/18 21:38:40 tgl Exp $ * */ @@ -56,6 +56,8 @@ static void show_upper_qual(List *qual, const char *qlabel, const char *outer_name, int outer_varno, Plan *outer_plan, const char *inner_name, int inner_varno, Plan *inner_plan, StringInfo str, int indent, ExplainState *es); +static void show_sort_keys(List *tlist, int nkeys, const char *qlabel, + StringInfo str, int indent, ExplainState *es); static Node *make_ors_ands_explicit(List *orclauses); static TextOutputState *begin_text_output(CommandDest dest, char *title); static void do_text_output(TextOutputState *tstate, char *aline); @@ -410,7 +412,7 @@ explain_outNode(StringInfo str, Plan *plan, Plan *outer_plan, } appendStringInfo(str, "\n"); - /* quals */ + /* quals, sort keys, etc */ switch (nodeTag(plan)) { case T_IndexScan: @@ -495,6 +497,11 @@ explain_outNode(StringInfo str, Plan *plan, Plan *outer_plan, "", 0, NULL, str, indent, es); break; + case T_Sort: + show_sort_keys(plan->targetlist, ((Sort *) plan)->keycount, + "Sort Key", + str, indent, es); + break; case T_Result: show_upper_qual((List *) ((Result *) plan)->resconstantqual, "One-Time Filter", @@ -731,6 +738,60 @@ show_upper_qual(List *qual, const char *qlabel, appendStringInfo(str, " %s: %s\n", qlabel, exprstr); } +/* + * Show the sort keys for a Sort node. + */ +static void +show_sort_keys(List *tlist, int nkeys, const char *qlabel, + StringInfo str, int indent, ExplainState *es) +{ + List *context; + bool useprefix; + int keyno; + List *tl; + char *exprstr; + int i; + + if (nkeys <= 0) + return; + + for (i = 0; i < indent; i++) + appendStringInfo(str, " "); + appendStringInfo(str, " %s: ", qlabel); + + /* + * In this routine we expect that the plan node's tlist has not been + * processed by set_plan_references(), so any Vars will contain valid + * varnos referencing the actual rtable. + */ + context = deparse_context_from_rtable(es->rtable); + useprefix = length(es->rtable) > 1; + + for (keyno = 1; keyno <= nkeys; keyno++) + { + /* find key expression in tlist */ + foreach(tl, tlist) + { + TargetEntry *target = (TargetEntry *) lfirst(tl); + + if (target->resdom->reskey == keyno) + { + /* Deparse the expression */ + exprstr = deparse_expression(target->expr, context, useprefix); + /* And add to str */ + if (keyno > 1) + appendStringInfo(str, ", "); + appendStringInfo(str, "%s", exprstr); + break; + } + } + if (tl == NIL) + elog(ERROR, "show_sort_keys: no tlist entry for key %d", keyno); + } + + appendStringInfo(str, "\n"); +} + /* * Indexscan qual lists have an implicit OR-of-ANDs structure. Make it * explicit so deparsing works properly. diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 88528b9a06..738efdb744 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -3,7 +3,7 @@ * back to source text * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.105 2002/05/17 01:19:18 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.106 2002/05/18 21:38:40 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -779,6 +779,27 @@ deparse_context_for_subplan(const char *name, List *tlist, return (Node *) rte; } +/* + * deparse_context_from_rtable - Build deparse context given a rangetable + * + * This is suitable for deparsing expressions that refer to only a single + * level of variables (no outer-reference Vars). + */ +List * +deparse_context_from_rtable(List *rtable) +{ + deparse_namespace *dpns; + + dpns = (deparse_namespace *) palloc(sizeof(deparse_namespace)); + + dpns->rtable = rtable; + dpns->outer_varno = dpns->inner_varno = 0; + dpns->outer_rte = dpns->inner_rte = NULL; + + /* Return a one-deep namespace stack */ + return makeList1(dpns); +} + /* ---------- * make_ruledef - reconstruct the CREATE RULE command * for a given pg_rewrite tuple diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 7a8d1fb387..6340aa2254 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: builtins.h,v 1.181 2002/05/12 20:10:05 tgl Exp $ + * $Id: builtins.h,v 1.182 2002/05/18 21:38:41 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -357,6 +357,7 @@ extern List *deparse_context_for_plan(int outer_varno, Node *outercontext, extern Node *deparse_context_for_rte(RangeTblEntry *rte); extern Node *deparse_context_for_subplan(const char *name, List *tlist, List *rtable); +extern List *deparse_context_from_rtable(List *rtable); extern const char *quote_identifier(const char *ident); extern char *quote_qualified_identifier(const char *namespace, const char *ident);