From c876d965f5e7a8b300f57d21de570cca291ac84a Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 30 Dec 2005 18:34:22 +0000 Subject: [PATCH] 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. --- src/backend/utils/adt/ruleutils.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index eaf4f19507..7c47054633 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -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; } /*