77 * Portions Copyright (c) 1994-5, Regents of the University of California
88 *
99 * IDENTIFICATION
10- * $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.158 2007/02/22 23:44:24 tgl Exp $
10+ * $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.159 2007/02/23 21:59:44 tgl Exp $
1111 *
1212 *-------------------------------------------------------------------------
1313 */
@@ -49,11 +49,9 @@ static void explain_outNode(StringInfo str,
4949 Plan * outer_plan ,
5050 int indent , ExplainState * es );
5151static void show_scan_qual (List * qual , const char * qlabel ,
52- int scanrelid , Plan * outer_plan ,
52+ int scanrelid , Plan * outer_plan , Plan * inner_plan ,
5353 StringInfo str , int indent , ExplainState * es );
54- static void show_upper_qual (List * qual , const char * qlabel ,
55- const char * outer_name , Plan * outer_plan ,
56- const char * inner_name , Plan * inner_plan ,
54+ static void show_upper_qual (List * qual , const char * qlabel , Plan * plan ,
5755 StringInfo str , int indent , ExplainState * es );
5856static void show_sort_keys (Plan * sortplan , int nkeys , AttrNumber * keycols ,
5957 const char * qlabel ,
@@ -725,37 +723,44 @@ explain_outNode(StringInfo str,
725723 show_scan_qual (((IndexScan * ) plan )-> indexqualorig ,
726724 "Index Cond" ,
727725 ((Scan * ) plan )-> scanrelid ,
728- outer_plan ,
726+ outer_plan , NULL ,
729727 str , indent , es );
730728 show_scan_qual (plan -> qual ,
731729 "Filter" ,
732730 ((Scan * ) plan )-> scanrelid ,
733- outer_plan ,
731+ outer_plan , NULL ,
734732 str , indent , es );
735733 break ;
736734 case T_BitmapIndexScan :
737735 show_scan_qual (((BitmapIndexScan * ) plan )-> indexqualorig ,
738736 "Index Cond" ,
739737 ((Scan * ) plan )-> scanrelid ,
740- outer_plan ,
738+ outer_plan , NULL ,
741739 str , indent , es );
742740 break ;
743741 case T_BitmapHeapScan :
744742 /* XXX do we want to show this in production? */
745743 show_scan_qual (((BitmapHeapScan * ) plan )-> bitmapqualorig ,
746744 "Recheck Cond" ,
747745 ((Scan * ) plan )-> scanrelid ,
748- outer_plan ,
746+ outer_plan , NULL ,
749747 str , indent , es );
750748 /* FALL THRU */
751749 case T_SeqScan :
752- case T_SubqueryScan :
753750 case T_FunctionScan :
754751 case T_ValuesScan :
752+ show_scan_qual (plan -> qual ,
753+ "Filter" ,
754+ ((Scan * ) plan )-> scanrelid ,
755+ outer_plan , NULL ,
756+ str , indent , es );
757+ break ;
758+ case T_SubqueryScan :
755759 show_scan_qual (plan -> qual ,
756760 "Filter" ,
757761 ((Scan * ) plan )-> scanrelid ,
758762 outer_plan ,
763+ ((SubqueryScan * ) plan )-> subplan ,
759764 str , indent , es );
760765 break ;
761766 case T_TidScan :
@@ -771,67 +776,49 @@ explain_outNode(StringInfo str,
771776 show_scan_qual (tidquals ,
772777 "TID Cond" ,
773778 ((Scan * ) plan )-> scanrelid ,
774- outer_plan ,
779+ outer_plan , NULL ,
775780 str , indent , es );
776781 show_scan_qual (plan -> qual ,
777782 "Filter" ,
778783 ((Scan * ) plan )-> scanrelid ,
779- outer_plan ,
784+ outer_plan , NULL ,
780785 str , indent , es );
781786 }
782787 break ;
783788 case T_NestLoop :
784789 show_upper_qual (((NestLoop * ) plan )-> join .joinqual ,
785- "Join Filter" ,
786- "outer" , outerPlan (plan ),
787- "inner" , innerPlan (plan ),
790+ "Join Filter" , plan ,
788791 str , indent , es );
789792 show_upper_qual (plan -> qual ,
790- "Filter" ,
791- "outer" , outerPlan (plan ),
792- "inner" , innerPlan (plan ),
793+ "Filter" , plan ,
793794 str , indent , es );
794795 break ;
795796 case T_MergeJoin :
796797 show_upper_qual (((MergeJoin * ) plan )-> mergeclauses ,
797- "Merge Cond" ,
798- "outer" , outerPlan (plan ),
799- "inner" , innerPlan (plan ),
798+ "Merge Cond" , plan ,
800799 str , indent , es );
801800 show_upper_qual (((MergeJoin * ) plan )-> join .joinqual ,
802- "Join Filter" ,
803- "outer" , outerPlan (plan ),
804- "inner" , innerPlan (plan ),
801+ "Join Filter" , plan ,
805802 str , indent , es );
806803 show_upper_qual (plan -> qual ,
807- "Filter" ,
808- "outer" , outerPlan (plan ),
809- "inner" , innerPlan (plan ),
804+ "Filter" , plan ,
810805 str , indent , es );
811806 break ;
812807 case T_HashJoin :
813808 show_upper_qual (((HashJoin * ) plan )-> hashclauses ,
814- "Hash Cond" ,
815- "outer" , outerPlan (plan ),
816- "inner" , innerPlan (plan ),
809+ "Hash Cond" , plan ,
817810 str , indent , es );
818811 show_upper_qual (((HashJoin * ) plan )-> join .joinqual ,
819- "Join Filter" ,
820- "outer" , outerPlan (plan ),
821- "inner" , innerPlan (plan ),
812+ "Join Filter" , plan ,
822813 str , indent , es );
823814 show_upper_qual (plan -> qual ,
824- "Filter" ,
825- "outer" , outerPlan (plan ),
826- "inner" , innerPlan (plan ),
815+ "Filter" , plan ,
827816 str , indent , es );
828817 break ;
829818 case T_Agg :
830819 case T_Group :
831820 show_upper_qual (plan -> qual ,
832- "Filter" ,
833- "subplan" , outerPlan (plan ),
834- "" , NULL ,
821+ "Filter" , plan ,
835822 str , indent , es );
836823 break ;
837824 case T_Sort :
@@ -843,14 +830,10 @@ explain_outNode(StringInfo str,
843830 break ;
844831 case T_Result :
845832 show_upper_qual ((List * ) ((Result * ) plan )-> resconstantqual ,
846- "One-Time Filter" ,
847- "subplan" , outerPlan (plan ),
848- "" , NULL ,
833+ "One-Time Filter" , plan ,
849834 str , indent , es );
850835 show_upper_qual (plan -> qual ,
851- "Filter" ,
852- "subplan" , outerPlan (plan ),
853- "" , NULL ,
836+ "Filter" , plan ,
854837 str , indent , es );
855838 break ;
856839 default :
@@ -1032,14 +1015,18 @@ explain_outNode(StringInfo str,
10321015
10331016/*
10341017 * Show a qualifier expression for a scan plan node
1018+ *
1019+ * Note: outer_plan is the referent for any OUTER vars in the scan qual;
1020+ * this would be the outer side of a nestloop plan. inner_plan should be
1021+ * NULL except for a SubqueryScan plan node, where it should be the subplan.
10351022 */
10361023static void
10371024show_scan_qual (List * qual , const char * qlabel ,
1038- int scanrelid , Plan * outer_plan ,
1025+ int scanrelid , Plan * outer_plan , Plan * inner_plan ,
10391026 StringInfo str , int indent , ExplainState * es )
10401027{
1041- Node * outercontext ;
10421028 List * context ;
1029+ bool useprefix ;
10431030 Node * node ;
10441031 char * exprstr ;
10451032 int i ;
@@ -1051,31 +1038,14 @@ show_scan_qual(List *qual, const char *qlabel,
10511038 /* Convert AND list to explicit AND */
10521039 node = (Node * ) make_ands_explicit (qual );
10531040
1054- /*
1055- * If we have an outer plan that is referenced by the qual, add it to the
1056- * deparse context. If not, don't (so that we don't force prefixes
1057- * unnecessarily).
1058- */
1059- if (outer_plan )
1060- {
1061- Relids varnos = pull_varnos (node );
1062-
1063- if (bms_is_member (OUTER , varnos ))
1064- outercontext = deparse_context_for_subplan ("outer" ,
1065- (Node * ) outer_plan );
1066- else
1067- outercontext = NULL ;
1068- bms_free (varnos );
1069- }
1070- else
1071- outercontext = NULL ;
1072-
1073- context = deparse_context_for_plan (OUTER , outercontext ,
1074- 0 , NULL ,
1041+ /* Set up deparsing context */
1042+ context = deparse_context_for_plan ((Node * ) outer_plan ,
1043+ (Node * ) inner_plan ,
10751044 es -> rtable );
1045+ useprefix = (outer_plan != NULL || inner_plan != NULL );
10761046
10771047 /* Deparse the expression */
1078- exprstr = deparse_expression (node , context , ( outercontext != NULL ) , false);
1048+ exprstr = deparse_expression (node , context , useprefix , false);
10791049
10801050 /* And add to str */
10811051 for (i = 0 ; i < indent ; i ++ )
@@ -1087,16 +1057,11 @@ show_scan_qual(List *qual, const char *qlabel,
10871057 * Show a qualifier expression for an upper-level plan node
10881058 */
10891059static void
1090- show_upper_qual (List * qual , const char * qlabel ,
1091- const char * outer_name , Plan * outer_plan ,
1092- const char * inner_name , Plan * inner_plan ,
1060+ show_upper_qual (List * qual , const char * qlabel , Plan * plan ,
10931061 StringInfo str , int indent , ExplainState * es )
10941062{
10951063 List * context ;
1096- Node * outercontext ;
1097- Node * innercontext ;
1098- int outer_varno ;
1099- int inner_varno ;
1064+ bool useprefix ;
11001065 Node * node ;
11011066 char * exprstr ;
11021067 int i ;
@@ -1105,36 +1070,15 @@ show_upper_qual(List *qual, const char *qlabel,
11051070 if (qual == NIL )
11061071 return ;
11071072
1108- /* Generate deparse context */
1109- if (outer_plan )
1110- {
1111- outercontext = deparse_context_for_subplan (outer_name ,
1112- (Node * ) outer_plan );
1113- outer_varno = OUTER ;
1114- }
1115- else
1116- {
1117- outercontext = NULL ;
1118- outer_varno = 0 ;
1119- }
1120- if (inner_plan )
1121- {
1122- innercontext = deparse_context_for_subplan (inner_name ,
1123- (Node * ) inner_plan );
1124- inner_varno = INNER ;
1125- }
1126- else
1127- {
1128- innercontext = NULL ;
1129- inner_varno = 0 ;
1130- }
1131- context = deparse_context_for_plan (outer_varno , outercontext ,
1132- inner_varno , innercontext ,
1073+ /* Set up deparsing context */
1074+ context = deparse_context_for_plan ((Node * ) outerPlan (plan ),
1075+ (Node * ) innerPlan (plan ),
11331076 es -> rtable );
1077+ useprefix = list_length (es -> rtable ) > 1 ;
11341078
11351079 /* Deparse the expression */
11361080 node = (Node * ) make_ands_explicit (qual );
1137- exprstr = deparse_expression (node , context , ( inner_plan != NULL ) , false);
1081+ exprstr = deparse_expression (node , context , useprefix , false);
11381082
11391083 /* And add to str */
11401084 for (i = 0 ; i < indent ; i ++ )
@@ -1154,7 +1098,6 @@ show_sort_keys(Plan *sortplan, int nkeys, AttrNumber *keycols,
11541098 bool useprefix ;
11551099 int keyno ;
11561100 char * exprstr ;
1157- Relids varnos ;
11581101 int i ;
11591102
11601103 if (nkeys <= 0 )
@@ -1164,33 +1107,11 @@ show_sort_keys(Plan *sortplan, int nkeys, AttrNumber *keycols,
11641107 appendStringInfo (str , " " );
11651108 appendStringInfo (str , " %s: " , qlabel );
11661109
1167- /*
1168- * In this routine we expect that the plan node's tlist has not been
1169- * processed by set_plan_references(). Normally, any Vars will contain
1170- * valid varnos referencing the actual rtable. But we might instead be
1171- * looking at a dummy tlist generated by prepunion.c; if there are Vars
1172- * with zero varno, use the tlist itself to determine their names.
1173- */
1174- varnos = pull_varnos ((Node * ) sortplan -> targetlist );
1175- if (bms_is_member (0 , varnos ))
1176- {
1177- Node * outercontext ;
1178-
1179- outercontext = deparse_context_for_subplan ("sort" ,
1180- (Node * ) sortplan );
1181- context = deparse_context_for_plan (0 , outercontext ,
1182- 0 , NULL ,
1183- es -> rtable );
1184- useprefix = false;
1185- }
1186- else
1187- {
1188- context = deparse_context_for_plan (0 , NULL ,
1189- 0 , NULL ,
1190- es -> rtable );
1191- useprefix = list_length (es -> rtable ) > 1 ;
1192- }
1193- bms_free (varnos );
1110+ /* Set up deparsing context */
1111+ context = deparse_context_for_plan ((Node * ) outerPlan (sortplan ),
1112+ NULL , /* Sort has no innerPlan */
1113+ es -> rtable );
1114+ useprefix = list_length (es -> rtable ) > 1 ;
11941115
11951116 for (keyno = 0 ; keyno < nkeys ; keyno ++ )
11961117 {
0 commit comments