7
7
* Portions Copyright (c) 1994-5, Regents of the University of California
8
8
*
9
9
* 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 $
11
11
*
12
12
*-------------------------------------------------------------------------
13
13
*/
@@ -49,11 +49,9 @@ static void explain_outNode(StringInfo str,
49
49
Plan * outer_plan ,
50
50
int indent , ExplainState * es );
51
51
static void show_scan_qual (List * qual , const char * qlabel ,
52
- int scanrelid , Plan * outer_plan ,
52
+ int scanrelid , Plan * outer_plan , Plan * inner_plan ,
53
53
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 ,
57
55
StringInfo str , int indent , ExplainState * es );
58
56
static void show_sort_keys (Plan * sortplan , int nkeys , AttrNumber * keycols ,
59
57
const char * qlabel ,
@@ -725,37 +723,44 @@ explain_outNode(StringInfo str,
725
723
show_scan_qual (((IndexScan * ) plan )-> indexqualorig ,
726
724
"Index Cond" ,
727
725
((Scan * ) plan )-> scanrelid ,
728
- outer_plan ,
726
+ outer_plan , NULL ,
729
727
str , indent , es );
730
728
show_scan_qual (plan -> qual ,
731
729
"Filter" ,
732
730
((Scan * ) plan )-> scanrelid ,
733
- outer_plan ,
731
+ outer_plan , NULL ,
734
732
str , indent , es );
735
733
break ;
736
734
case T_BitmapIndexScan :
737
735
show_scan_qual (((BitmapIndexScan * ) plan )-> indexqualorig ,
738
736
"Index Cond" ,
739
737
((Scan * ) plan )-> scanrelid ,
740
- outer_plan ,
738
+ outer_plan , NULL ,
741
739
str , indent , es );
742
740
break ;
743
741
case T_BitmapHeapScan :
744
742
/* XXX do we want to show this in production? */
745
743
show_scan_qual (((BitmapHeapScan * ) plan )-> bitmapqualorig ,
746
744
"Recheck Cond" ,
747
745
((Scan * ) plan )-> scanrelid ,
748
- outer_plan ,
746
+ outer_plan , NULL ,
749
747
str , indent , es );
750
748
/* FALL THRU */
751
749
case T_SeqScan :
752
- case T_SubqueryScan :
753
750
case T_FunctionScan :
754
751
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 :
755
759
show_scan_qual (plan -> qual ,
756
760
"Filter" ,
757
761
((Scan * ) plan )-> scanrelid ,
758
762
outer_plan ,
763
+ ((SubqueryScan * ) plan )-> subplan ,
759
764
str , indent , es );
760
765
break ;
761
766
case T_TidScan :
@@ -771,67 +776,49 @@ explain_outNode(StringInfo str,
771
776
show_scan_qual (tidquals ,
772
777
"TID Cond" ,
773
778
((Scan * ) plan )-> scanrelid ,
774
- outer_plan ,
779
+ outer_plan , NULL ,
775
780
str , indent , es );
776
781
show_scan_qual (plan -> qual ,
777
782
"Filter" ,
778
783
((Scan * ) plan )-> scanrelid ,
779
- outer_plan ,
784
+ outer_plan , NULL ,
780
785
str , indent , es );
781
786
}
782
787
break ;
783
788
case T_NestLoop :
784
789
show_upper_qual (((NestLoop * ) plan )-> join .joinqual ,
785
- "Join Filter" ,
786
- "outer" , outerPlan (plan ),
787
- "inner" , innerPlan (plan ),
790
+ "Join Filter" , plan ,
788
791
str , indent , es );
789
792
show_upper_qual (plan -> qual ,
790
- "Filter" ,
791
- "outer" , outerPlan (plan ),
792
- "inner" , innerPlan (plan ),
793
+ "Filter" , plan ,
793
794
str , indent , es );
794
795
break ;
795
796
case T_MergeJoin :
796
797
show_upper_qual (((MergeJoin * ) plan )-> mergeclauses ,
797
- "Merge Cond" ,
798
- "outer" , outerPlan (plan ),
799
- "inner" , innerPlan (plan ),
798
+ "Merge Cond" , plan ,
800
799
str , indent , es );
801
800
show_upper_qual (((MergeJoin * ) plan )-> join .joinqual ,
802
- "Join Filter" ,
803
- "outer" , outerPlan (plan ),
804
- "inner" , innerPlan (plan ),
801
+ "Join Filter" , plan ,
805
802
str , indent , es );
806
803
show_upper_qual (plan -> qual ,
807
- "Filter" ,
808
- "outer" , outerPlan (plan ),
809
- "inner" , innerPlan (plan ),
804
+ "Filter" , plan ,
810
805
str , indent , es );
811
806
break ;
812
807
case T_HashJoin :
813
808
show_upper_qual (((HashJoin * ) plan )-> hashclauses ,
814
- "Hash Cond" ,
815
- "outer" , outerPlan (plan ),
816
- "inner" , innerPlan (plan ),
809
+ "Hash Cond" , plan ,
817
810
str , indent , es );
818
811
show_upper_qual (((HashJoin * ) plan )-> join .joinqual ,
819
- "Join Filter" ,
820
- "outer" , outerPlan (plan ),
821
- "inner" , innerPlan (plan ),
812
+ "Join Filter" , plan ,
822
813
str , indent , es );
823
814
show_upper_qual (plan -> qual ,
824
- "Filter" ,
825
- "outer" , outerPlan (plan ),
826
- "inner" , innerPlan (plan ),
815
+ "Filter" , plan ,
827
816
str , indent , es );
828
817
break ;
829
818
case T_Agg :
830
819
case T_Group :
831
820
show_upper_qual (plan -> qual ,
832
- "Filter" ,
833
- "subplan" , outerPlan (plan ),
834
- "" , NULL ,
821
+ "Filter" , plan ,
835
822
str , indent , es );
836
823
break ;
837
824
case T_Sort :
@@ -843,14 +830,10 @@ explain_outNode(StringInfo str,
843
830
break ;
844
831
case T_Result :
845
832
show_upper_qual ((List * ) ((Result * ) plan )-> resconstantqual ,
846
- "One-Time Filter" ,
847
- "subplan" , outerPlan (plan ),
848
- "" , NULL ,
833
+ "One-Time Filter" , plan ,
849
834
str , indent , es );
850
835
show_upper_qual (plan -> qual ,
851
- "Filter" ,
852
- "subplan" , outerPlan (plan ),
853
- "" , NULL ,
836
+ "Filter" , plan ,
854
837
str , indent , es );
855
838
break ;
856
839
default :
@@ -1032,14 +1015,18 @@ explain_outNode(StringInfo str,
1032
1015
1033
1016
/*
1034
1017
* 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.
1035
1022
*/
1036
1023
static void
1037
1024
show_scan_qual (List * qual , const char * qlabel ,
1038
- int scanrelid , Plan * outer_plan ,
1025
+ int scanrelid , Plan * outer_plan , Plan * inner_plan ,
1039
1026
StringInfo str , int indent , ExplainState * es )
1040
1027
{
1041
- Node * outercontext ;
1042
1028
List * context ;
1029
+ bool useprefix ;
1043
1030
Node * node ;
1044
1031
char * exprstr ;
1045
1032
int i ;
@@ -1051,31 +1038,14 @@ show_scan_qual(List *qual, const char *qlabel,
1051
1038
/* Convert AND list to explicit AND */
1052
1039
node = (Node * ) make_ands_explicit (qual );
1053
1040
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 ,
1075
1044
es -> rtable );
1045
+ useprefix = (outer_plan != NULL || inner_plan != NULL );
1076
1046
1077
1047
/* Deparse the expression */
1078
- exprstr = deparse_expression (node , context , ( outercontext != NULL ) , false);
1048
+ exprstr = deparse_expression (node , context , useprefix , false);
1079
1049
1080
1050
/* And add to str */
1081
1051
for (i = 0 ; i < indent ; i ++ )
@@ -1087,16 +1057,11 @@ show_scan_qual(List *qual, const char *qlabel,
1087
1057
* Show a qualifier expression for an upper-level plan node
1088
1058
*/
1089
1059
static 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 ,
1093
1061
StringInfo str , int indent , ExplainState * es )
1094
1062
{
1095
1063
List * context ;
1096
- Node * outercontext ;
1097
- Node * innercontext ;
1098
- int outer_varno ;
1099
- int inner_varno ;
1064
+ bool useprefix ;
1100
1065
Node * node ;
1101
1066
char * exprstr ;
1102
1067
int i ;
@@ -1105,36 +1070,15 @@ show_upper_qual(List *qual, const char *qlabel,
1105
1070
if (qual == NIL )
1106
1071
return ;
1107
1072
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 ),
1133
1076
es -> rtable );
1077
+ useprefix = list_length (es -> rtable ) > 1 ;
1134
1078
1135
1079
/* Deparse the expression */
1136
1080
node = (Node * ) make_ands_explicit (qual );
1137
- exprstr = deparse_expression (node , context , ( inner_plan != NULL ) , false);
1081
+ exprstr = deparse_expression (node , context , useprefix , false);
1138
1082
1139
1083
/* And add to str */
1140
1084
for (i = 0 ; i < indent ; i ++ )
@@ -1154,7 +1098,6 @@ show_sort_keys(Plan *sortplan, int nkeys, AttrNumber *keycols,
1154
1098
bool useprefix ;
1155
1099
int keyno ;
1156
1100
char * exprstr ;
1157
- Relids varnos ;
1158
1101
int i ;
1159
1102
1160
1103
if (nkeys <= 0 )
@@ -1164,33 +1107,11 @@ show_sort_keys(Plan *sortplan, int nkeys, AttrNumber *keycols,
1164
1107
appendStringInfo (str , " " );
1165
1108
appendStringInfo (str , " %s: " , qlabel );
1166
1109
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 ;
1194
1115
1195
1116
for (keyno = 0 ; keyno < nkeys ; keyno ++ )
1196
1117
{
0 commit comments