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 * back to source text
* *
* IDENTIFICATION * 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. * 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))); 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->relid = InvalidOid;
rte->coldeflist = tlist;
rte->eref = makeAlias(name, attrs); rte->eref = makeAlias(name, attrs);
rte->inh = false; rte->inh = false;
rte->inFromCl = true; 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 * Note: this has essentially the same logic as the parser's
* expandRecordVariable() function, but we are dealing with a different * expandRecordVariable() function, but we are dealing with a different
* representation of the input context, and we only need one field name not * 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 * static const char *
get_name_for_var_field(Var *var, int fieldno, 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) switch (rte->rtekind)
{ {
case RTE_RELATION: case RTE_RELATION:
case RTE_SPECIAL:
/* /*
* This case should not occur: a column of a table shouldn't have * 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. * its result columns as RECORD, which is not allowed.
*/ */
break; 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;
} }
/* /*