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:
parent
7211ff7d32
commit
c876d965f5
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user