Thanks to visit codestin.com
Credit goes to github.com

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)