diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2005-12-30 18:34:27 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2005-12-30 18:34:27 +0000 |
commit | fff24e9b47c01ca190e2f27f30c619466b6a8e10 (patch) | |
tree | 07b232c8dbee3ec09af8f8ba349a767d2f6c5452 | |
parent | ff48fb9579a699092bb3623b885f5ecb94d54b94 (diff) | |
download | postgresql-fff24e9b47c01ca190e2f27f30c619466b6a8e10.tar.gz postgresql-fff24e9b47c01ca190e2f27f30c619466b6a8e10.zip |
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.
-rw-r--r-- | src/backend/utils/adt/ruleutils.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 58814451cfe..3e6e2ffac47 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.207.2.2 2005/12/10 19:21:17 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.207.2.3 2005/12/30 18:34:27 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -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; } /* |