Commit c6e81aee authored by Tom Lane's avatar Tom Lane

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.
parent 74bdf965
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994-5, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.146 2006/03/05 15:58:24 momjian Exp $
* $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.147 2006/04/08 18:49:52 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -58,7 +58,7 @@ static void show_upper_qual(List *qual, const char *qlabel,
const char *outer_name, int outer_varno, Plan *outer_plan,
const char *inner_name, int inner_varno, Plan *inner_plan,
StringInfo str, int indent, ExplainState *es);
static void show_sort_keys(List *tlist, int nkeys, AttrNumber *keycols,
static void show_sort_keys(Plan *sortplan, int nkeys, AttrNumber *keycols,
const char *qlabel,
StringInfo str, int indent, ExplainState *es);
......@@ -815,7 +815,7 @@ explain_outNode(StringInfo str,
str, indent, es);
break;
case T_Sort:
show_sort_keys(plan->targetlist,
show_sort_keys(plan,
((Sort *) plan)->numCols,
((Sort *) plan)->sortColIdx,
"Sort Key",
......@@ -1030,8 +1030,6 @@ show_scan_qual(List *qual, const char *qlabel,
int scanrelid, Plan *outer_plan,
StringInfo str, int indent, ExplainState *es)
{
RangeTblEntry *rte;
Node *scancontext;
Node *outercontext;
List *context;
Node *node;
......@@ -1045,11 +1043,6 @@ show_scan_qual(List *qual, const char *qlabel,
/* Convert AND list to explicit AND */
node = (Node *) make_ands_explicit(qual);
/* Generate deparse context */
Assert(scanrelid > 0 && scanrelid <= list_length(es->rtable));
rte = rt_fetch(scanrelid, es->rtable);
scancontext = deparse_context_for_rte(rte);
/*
* If we have an outer plan that is referenced by the qual, add it to the
* deparse context. If not, don't (so that we don't force prefixes
......@@ -1061,8 +1054,7 @@ show_scan_qual(List *qual, const char *qlabel,
if (bms_is_member(OUTER, varnos))
outercontext = deparse_context_for_subplan("outer",
outer_plan->targetlist,
es->rtable);
(Node *) outer_plan);
else
outercontext = NULL;
bms_free(varnos);
......@@ -1070,9 +1062,9 @@ show_scan_qual(List *qual, const char *qlabel,
else
outercontext = NULL;
context = deparse_context_for_plan(scanrelid, scancontext,
OUTER, outercontext,
NIL);
context = deparse_context_for_plan(OUTER, outercontext,
0, NULL,
es->rtable);
/* Deparse the expression */
exprstr = deparse_expression(node, context, (outercontext != NULL), false);
......@@ -1106,19 +1098,17 @@ show_upper_qual(List *qual, const char *qlabel,
/* Generate deparse context */
if (outer_plan)
outercontext = deparse_context_for_subplan(outer_name,
outer_plan->targetlist,
es->rtable);
(Node *) outer_plan);
else
outercontext = NULL;
if (inner_plan)
innercontext = deparse_context_for_subplan(inner_name,
inner_plan->targetlist,
es->rtable);
(Node *) inner_plan);
else
innercontext = NULL;
context = deparse_context_for_plan(outer_varno, outercontext,
inner_varno, innercontext,
NIL);
es->rtable);
/* Deparse the expression */
node = (Node *) make_ands_explicit(qual);
......@@ -1134,7 +1124,7 @@ show_upper_qual(List *qual, const char *qlabel,
* Show the sort keys for a Sort node.
*/
static void
show_sort_keys(List *tlist, int nkeys, AttrNumber *keycols,
show_sort_keys(Plan *sortplan, int nkeys, AttrNumber *keycols,
const char *qlabel,
StringInfo str, int indent, ExplainState *es)
{
......@@ -1159,17 +1149,16 @@ show_sort_keys(List *tlist, int nkeys, AttrNumber *keycols,
* looking at a dummy tlist generated by prepunion.c; if there are Vars
* with zero varno, use the tlist itself to determine their names.
*/
varnos = pull_varnos((Node *) tlist);
varnos = pull_varnos((Node *) sortplan->targetlist);
if (bms_is_member(0, varnos))
{
Node *outercontext;
outercontext = deparse_context_for_subplan("sort",
tlist,
es->rtable);
(Node *) sortplan);
context = deparse_context_for_plan(0, outercontext,
0, NULL,
NIL);
es->rtable);
useprefix = false;
}
else
......@@ -1185,7 +1174,7 @@ show_sort_keys(List *tlist, int nkeys, AttrNumber *keycols,
{
/* find key expression in tlist */
AttrNumber keyresno = keycols[keyno];
TargetEntry *target = get_tle_by_resno(tlist, keyresno);
TargetEntry *target = get_tle_by_resno(sortplan->targetlist, keyresno);
if (!target)
elog(ERROR, "no tlist entry for key %d", keyresno);
......
This diff is collapsed.
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.278 2006/04/05 22:11:57 tgl Exp $
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.279 2006/04/08 18:49:52 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -526,9 +526,7 @@ extern List *deparse_context_for(const char *aliasname, Oid relid);
extern List *deparse_context_for_plan(int outer_varno, Node *outercontext,
int inner_varno, Node *innercontext,
List *rtable);
extern Node *deparse_context_for_rte(RangeTblEntry *rte);
extern Node *deparse_context_for_subplan(const char *name, List *tlist,
List *rtable);
extern Node *deparse_context_for_subplan(const char *name, Node *subplan);
extern const char *quote_identifier(const char *ident);
extern char *quote_qualified_identifier(const char *namespace,
const char *ident);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment