Skip to content

Commit c6e81ae

Browse files
committed
Fix EXPLAIN so that it can drill down through multiple levels of subplan
when trying to locate the referent of a RECORD variable. This fixes the 'record type has not been registered' failure reported by Stefan Kaltenbrunner about a month ago. A side effect of the way I chose to fix it is that most variable references in join conditions will now be properly labeled with the variable's source table name, instead of the not-too-helpful 'outer' or 'inner' we used to use.
1 parent 74bdf96 commit c6e81ae

File tree

3 files changed

+113
-127
lines changed

3 files changed

+113
-127
lines changed

src/backend/commands/explain.c

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
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.146 2006/03/05 15:58:24 momjian Exp $
10+
* $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.147 2006/04/08 18:49:52 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -58,7 +58,7 @@ static void show_upper_qual(List *qual, const char *qlabel,
5858
const char *outer_name, int outer_varno, Plan *outer_plan,
5959
const char *inner_name, int inner_varno, Plan *inner_plan,
6060
StringInfo str, int indent, ExplainState *es);
61-
static void show_sort_keys(List *tlist, int nkeys, AttrNumber *keycols,
61+
static void show_sort_keys(Plan *sortplan, int nkeys, AttrNumber *keycols,
6262
const char *qlabel,
6363
StringInfo str, int indent, ExplainState *es);
6464

@@ -815,7 +815,7 @@ explain_outNode(StringInfo str,
815815
str, indent, es);
816816
break;
817817
case T_Sort:
818-
show_sort_keys(plan->targetlist,
818+
show_sort_keys(plan,
819819
((Sort *) plan)->numCols,
820820
((Sort *) plan)->sortColIdx,
821821
"Sort Key",
@@ -1030,8 +1030,6 @@ show_scan_qual(List *qual, const char *qlabel,
10301030
int scanrelid, Plan *outer_plan,
10311031
StringInfo str, int indent, ExplainState *es)
10321032
{
1033-
RangeTblEntry *rte;
1034-
Node *scancontext;
10351033
Node *outercontext;
10361034
List *context;
10371035
Node *node;
@@ -1045,11 +1043,6 @@ show_scan_qual(List *qual, const char *qlabel,
10451043
/* Convert AND list to explicit AND */
10461044
node = (Node *) make_ands_explicit(qual);
10471045

1048-
/* Generate deparse context */
1049-
Assert(scanrelid > 0 && scanrelid <= list_length(es->rtable));
1050-
rte = rt_fetch(scanrelid, es->rtable);
1051-
scancontext = deparse_context_for_rte(rte);
1052-
10531046
/*
10541047
* If we have an outer plan that is referenced by the qual, add it to the
10551048
* deparse context. If not, don't (so that we don't force prefixes
@@ -1061,18 +1054,17 @@ show_scan_qual(List *qual, const char *qlabel,
10611054

10621055
if (bms_is_member(OUTER, varnos))
10631056
outercontext = deparse_context_for_subplan("outer",
1064-
outer_plan->targetlist,
1065-
es->rtable);
1057+
(Node *) outer_plan);
10661058
else
10671059
outercontext = NULL;
10681060
bms_free(varnos);
10691061
}
10701062
else
10711063
outercontext = NULL;
10721064

1073-
context = deparse_context_for_plan(scanrelid, scancontext,
1074-
OUTER, outercontext,
1075-
NIL);
1065+
context = deparse_context_for_plan(OUTER, outercontext,
1066+
0, NULL,
1067+
es->rtable);
10761068

10771069
/* Deparse the expression */
10781070
exprstr = deparse_expression(node, context, (outercontext != NULL), false);
@@ -1106,19 +1098,17 @@ show_upper_qual(List *qual, const char *qlabel,
11061098
/* Generate deparse context */
11071099
if (outer_plan)
11081100
outercontext = deparse_context_for_subplan(outer_name,
1109-
outer_plan->targetlist,
1110-
es->rtable);
1101+
(Node *) outer_plan);
11111102
else
11121103
outercontext = NULL;
11131104
if (inner_plan)
11141105
innercontext = deparse_context_for_subplan(inner_name,
1115-
inner_plan->targetlist,
1116-
es->rtable);
1106+
(Node *) inner_plan);
11171107
else
11181108
innercontext = NULL;
11191109
context = deparse_context_for_plan(outer_varno, outercontext,
11201110
inner_varno, innercontext,
1121-
NIL);
1111+
es->rtable);
11221112

11231113
/* Deparse the expression */
11241114
node = (Node *) make_ands_explicit(qual);
@@ -1134,7 +1124,7 @@ show_upper_qual(List *qual, const char *qlabel,
11341124
* Show the sort keys for a Sort node.
11351125
*/
11361126
static void
1137-
show_sort_keys(List *tlist, int nkeys, AttrNumber *keycols,
1127+
show_sort_keys(Plan *sortplan, int nkeys, AttrNumber *keycols,
11381128
const char *qlabel,
11391129
StringInfo str, int indent, ExplainState *es)
11401130
{
@@ -1159,17 +1149,16 @@ show_sort_keys(List *tlist, int nkeys, AttrNumber *keycols,
11591149
* looking at a dummy tlist generated by prepunion.c; if there are Vars
11601150
* with zero varno, use the tlist itself to determine their names.
11611151
*/
1162-
varnos = pull_varnos((Node *) tlist);
1152+
varnos = pull_varnos((Node *) sortplan->targetlist);
11631153
if (bms_is_member(0, varnos))
11641154
{
11651155
Node *outercontext;
11661156

11671157
outercontext = deparse_context_for_subplan("sort",
1168-
tlist,
1169-
es->rtable);
1158+
(Node *) sortplan);
11701159
context = deparse_context_for_plan(0, outercontext,
11711160
0, NULL,
1172-
NIL);
1161+
es->rtable);
11731162
useprefix = false;
11741163
}
11751164
else
@@ -1185,7 +1174,7 @@ show_sort_keys(List *tlist, int nkeys, AttrNumber *keycols,
11851174
{
11861175
/* find key expression in tlist */
11871176
AttrNumber keyresno = keycols[keyno];
1188-
TargetEntry *target = get_tle_by_resno(tlist, keyresno);
1177+
TargetEntry *target = get_tle_by_resno(sortplan->targetlist, keyresno);
11891178

11901179
if (!target)
11911180
elog(ERROR, "no tlist entry for key %d", keyresno);

0 commit comments

Comments
 (0)