|
5 | 5 | * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
6 | 6 | * Portions Copyright (c) 1994-5, Regents of the University of California
|
7 | 7 | *
|
8 |
| - * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.77 2002/05/12 20:10:02 tgl Exp $ |
| 8 | + * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.78 2002/05/18 21:38:40 tgl Exp $ |
9 | 9 | *
|
10 | 10 | */
|
11 | 11 |
|
@@ -56,6 +56,8 @@ static void show_upper_qual(List *qual, const char *qlabel,
|
56 | 56 | const char *outer_name, int outer_varno, Plan *outer_plan,
|
57 | 57 | const char *inner_name, int inner_varno, Plan *inner_plan,
|
58 | 58 | StringInfo str, int indent, ExplainState *es);
|
| 59 | +static void show_sort_keys(List *tlist, int nkeys, const char *qlabel, |
| 60 | + StringInfo str, int indent, ExplainState *es); |
59 | 61 | static Node *make_ors_ands_explicit(List *orclauses);
|
60 | 62 | static TextOutputState *begin_text_output(CommandDest dest, char *title);
|
61 | 63 | static void do_text_output(TextOutputState *tstate, char *aline);
|
@@ -410,7 +412,7 @@ explain_outNode(StringInfo str, Plan *plan, Plan *outer_plan,
|
410 | 412 | }
|
411 | 413 | appendStringInfo(str, "\n");
|
412 | 414 |
|
413 |
| - /* quals */ |
| 415 | + /* quals, sort keys, etc */ |
414 | 416 | switch (nodeTag(plan))
|
415 | 417 | {
|
416 | 418 | case T_IndexScan:
|
@@ -495,6 +497,11 @@ explain_outNode(StringInfo str, Plan *plan, Plan *outer_plan,
|
495 | 497 | "", 0, NULL,
|
496 | 498 | str, indent, es);
|
497 | 499 | break;
|
| 500 | + case T_Sort: |
| 501 | + show_sort_keys(plan->targetlist, ((Sort *) plan)->keycount, |
| 502 | + "Sort Key", |
| 503 | + str, indent, es); |
| 504 | + break; |
498 | 505 | case T_Result:
|
499 | 506 | show_upper_qual((List *) ((Result *) plan)->resconstantqual,
|
500 | 507 | "One-Time Filter",
|
@@ -731,6 +738,60 @@ show_upper_qual(List *qual, const char *qlabel,
|
731 | 738 | appendStringInfo(str, " %s: %s\n", qlabel, exprstr);
|
732 | 739 | }
|
733 | 740 |
|
| 741 | +/* |
| 742 | + * Show the sort keys for a Sort node. |
| 743 | + */ |
| 744 | +static void |
| 745 | +show_sort_keys(List *tlist, int nkeys, const char *qlabel, |
| 746 | + StringInfo str, int indent, ExplainState *es) |
| 747 | +{ |
| 748 | + List *context; |
| 749 | + bool useprefix; |
| 750 | + int keyno; |
| 751 | + List *tl; |
| 752 | + char *exprstr; |
| 753 | + int i; |
| 754 | + |
| 755 | + if (nkeys <= 0) |
| 756 | + return; |
| 757 | + |
| 758 | + for (i = 0; i < indent; i++) |
| 759 | + appendStringInfo(str, " "); |
| 760 | + appendStringInfo(str, " %s: ", qlabel); |
| 761 | + |
| 762 | + /* |
| 763 | + * In this routine we expect that the plan node's tlist has not been |
| 764 | + * processed by set_plan_references(), so any Vars will contain valid |
| 765 | + * varnos referencing the actual rtable. |
| 766 | + */ |
| 767 | + context = deparse_context_from_rtable(es->rtable); |
| 768 | + useprefix = length(es->rtable) > 1; |
| 769 | + |
| 770 | + for (keyno = 1; keyno <= nkeys; keyno++) |
| 771 | + { |
| 772 | + /* find key expression in tlist */ |
| 773 | + foreach(tl, tlist) |
| 774 | + { |
| 775 | + TargetEntry *target = (TargetEntry *) lfirst(tl); |
| 776 | + |
| 777 | + if (target->resdom->reskey == keyno) |
| 778 | + { |
| 779 | + /* Deparse the expression */ |
| 780 | + exprstr = deparse_expression(target->expr, context, useprefix); |
| 781 | + /* And add to str */ |
| 782 | + if (keyno > 1) |
| 783 | + appendStringInfo(str, ", "); |
| 784 | + appendStringInfo(str, "%s", exprstr); |
| 785 | + break; |
| 786 | + } |
| 787 | + } |
| 788 | + if (tl == NIL) |
| 789 | + elog(ERROR, "show_sort_keys: no tlist entry for key %d", keyno); |
| 790 | + } |
| 791 | + |
| 792 | + appendStringInfo(str, "\n"); |
| 793 | +} |
| 794 | + |
734 | 795 | /*
|
735 | 796 | * Indexscan qual lists have an implicit OR-of-ANDs structure. Make it
|
736 | 797 | * explicit so deparsing works properly.
|
|
0 commit comments