mirror of
https://github.com/postgres/postgres.git
synced 2025-04-21 12:05:57 +03:00
Add display of sort keys to the default EXPLAIN output.
This commit is contained in:
parent
a5b370943e
commit
dd9af92c41
@ -5,7 +5,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994-5, Regents of the University of California
|
* 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 *outer_name, int outer_varno, Plan *outer_plan,
|
||||||
const char *inner_name, int inner_varno, Plan *inner_plan,
|
const char *inner_name, int inner_varno, Plan *inner_plan,
|
||||||
StringInfo str, int indent, ExplainState *es);
|
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 Node *make_ors_ands_explicit(List *orclauses);
|
||||||
static TextOutputState *begin_text_output(CommandDest dest, char *title);
|
static TextOutputState *begin_text_output(CommandDest dest, char *title);
|
||||||
static void do_text_output(TextOutputState *tstate, char *aline);
|
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");
|
appendStringInfo(str, "\n");
|
||||||
|
|
||||||
/* quals */
|
/* quals, sort keys, etc */
|
||||||
switch (nodeTag(plan))
|
switch (nodeTag(plan))
|
||||||
{
|
{
|
||||||
case T_IndexScan:
|
case T_IndexScan:
|
||||||
@ -495,6 +497,11 @@ explain_outNode(StringInfo str, Plan *plan, Plan *outer_plan,
|
|||||||
"", 0, NULL,
|
"", 0, NULL,
|
||||||
str, indent, es);
|
str, indent, es);
|
||||||
break;
|
break;
|
||||||
|
case T_Sort:
|
||||||
|
show_sort_keys(plan->targetlist, ((Sort *) plan)->keycount,
|
||||||
|
"Sort Key",
|
||||||
|
str, indent, es);
|
||||||
|
break;
|
||||||
case T_Result:
|
case T_Result:
|
||||||
show_upper_qual((List *) ((Result *) plan)->resconstantqual,
|
show_upper_qual((List *) ((Result *) plan)->resconstantqual,
|
||||||
"One-Time Filter",
|
"One-Time Filter",
|
||||||
@ -731,6 +738,60 @@ show_upper_qual(List *qual, const char *qlabel,
|
|||||||
appendStringInfo(str, " %s: %s\n", qlabel, exprstr);
|
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
|
* Indexscan qual lists have an implicit OR-of-ANDs structure. Make it
|
||||||
* explicit so deparsing works properly.
|
* explicit so deparsing works properly.
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* back to source text
|
* back to source text
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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.
|
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||||
*
|
*
|
||||||
@ -779,6 +779,27 @@ deparse_context_for_subplan(const char *name, List *tlist,
|
|||||||
return (Node *) rte;
|
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
|
* make_ruledef - reconstruct the CREATE RULE command
|
||||||
* for a given pg_rewrite tuple
|
* for a given pg_rewrite tuple
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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_rte(RangeTblEntry *rte);
|
||||||
extern Node *deparse_context_for_subplan(const char *name, List *tlist,
|
extern Node *deparse_context_for_subplan(const char *name, List *tlist,
|
||||||
List *rtable);
|
List *rtable);
|
||||||
|
extern List *deparse_context_from_rtable(List *rtable);
|
||||||
extern const char *quote_identifier(const char *ident);
|
extern const char *quote_identifier(const char *ident);
|
||||||
extern char *quote_qualified_identifier(const char *namespace,
|
extern char *quote_qualified_identifier(const char *namespace,
|
||||||
const char *ident);
|
const char *ident);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user