Repair EXPLAIN failure when trying to display a plan condition that involves

selection of a field from the result of a function returning RECORD.
I believe this case is new in 8.1; it's due to the addition of OUT parameters.
Per example from Michael Fuhr.
This commit is contained in:
Tom Lane 2005-12-30 18:34:22 +00:00
parent 7211ff7d32
commit c876d965f5
1 changed files with 26 additions and 4 deletions

View File

@ -3,7 +3,7 @@
* back to source text
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.211 2005/12/28 01:30:00 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.212 2005/12/30 18:34:22 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@ -1525,8 +1525,15 @@ deparse_context_for_subplan(const char *name, List *tlist,
attrs = lappend(attrs, makeString(pstrdup(buf)));
}
rte->rtekind = RTE_SPECIAL; /* XXX */
/*
* We create an RTE_SPECIAL RangeTblEntry, and store the given tlist
* in its coldeflist field. This is a hack to make the tlist available
* to get_name_for_var_field(). RTE_SPECIAL nodes shouldn't appear in
* deparse contexts otherwise.
*/
rte->rtekind = RTE_SPECIAL;
rte->relid = InvalidOid;
rte->coldeflist = tlist;
rte->eref = makeAlias(name, attrs);
rte->inh = false;
rte->inFromCl = true;
@ -2571,7 +2578,8 @@ get_names_for_var(Var *var, int levelsup, deparse_context *context,
* Note: this has essentially the same logic as the parser's
* expandRecordVariable() function, but we are dealing with a different
* representation of the input context, and we only need one field name not
* a TupleDesc.
* a TupleDesc. Also, we have a special case for RTE_SPECIAL so that we can
* deal with displaying RECORD-returning functions in subplan targetlists.
*/
static const char *
get_name_for_var_field(Var *var, int fieldno,
@ -2602,7 +2610,6 @@ get_name_for_var_field(Var *var, int fieldno,
switch (rte->rtekind)
{
case RTE_RELATION:
case RTE_SPECIAL:
/*
* This case should not occur: a column of a table shouldn't have
@ -2663,6 +2670,21 @@ get_name_for_var_field(Var *var, int fieldno,
* its result columns as RECORD, which is not allowed.
*/
break;
case RTE_SPECIAL:
/*
* This case occurs during EXPLAIN when we are looking at a
* deparse context node set up by deparse_context_for_subplan().
* Look into the subplan's target list to get the referenced
* expression, and then pass it to get_expr_result_type().
*/
if (rte->coldeflist)
{
TargetEntry *ste = get_tle_by_resno(rte->coldeflist, attnum);
if (ste != NULL)
expr = (Node *) ste->expr;
}
break;
}
/*