From: Tom Lane Date: Fri, 30 Dec 2005 18:34:27 +0000 (+0000) Subject: Repair EXPLAIN failure when trying to display a plan condition that involves X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=202cf450cb9c228a3d22cabb378cdb59e5cb3f39;p=users%2Fbernd%2Fpostgres.git 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. --- diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 529f27d5a7..a36ab3ea6f 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -1526,8 +1526,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; @@ -2572,7 +2579,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, @@ -2603,7 +2611,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 @@ -2664,6 +2671,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; } /*