|
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 | constchar*outer_name,intouter_varno,Plan*outer_plan,
|
57 | 57 | constchar*inner_name,intinner_varno,Plan*inner_plan,
|
58 | 58 | StringInfostr,intindent,ExplainState*es);
|
| 59 | +staticvoidshow_sort_keys(List*tlist,intnkeys,constchar*qlabel, |
| 60 | +StringInfostr,intindent,ExplainState*es); |
59 | 61 | staticNode*make_ors_ands_explicit(List*orclauses);
|
60 | 62 | staticTextOutputState*begin_text_output(CommandDestdest,char*title);
|
61 | 63 | staticvoiddo_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 | caseT_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 | +caseT_Sort: |
| 501 | +show_sort_keys(plan->targetlist, ((Sort*)plan)->keycount, |
| 502 | +"Sort Key", |
| 503 | +str,indent,es); |
| 504 | +break; |
498 | 505 | caseT_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 | +staticvoid |
| 745 | +show_sort_keys(List*tlist,intnkeys,constchar*qlabel, |
| 746 | +StringInfostr,intindent,ExplainState*es) |
| 747 | +{ |
| 748 | +List*context; |
| 749 | +booluseprefix; |
| 750 | +intkeyno; |
| 751 | +List*tl; |
| 752 | +char*exprstr; |
| 753 | +inti; |
| 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.
|
|