Skip to content

Commit c876d96

Browse files
committed
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.
1 parent 7211ff7 commit c876d96

File tree

1 file changed

+26
-4
lines changed

1 file changed

+26
-4
lines changed

src/backend/utils/adt/ruleutils.c

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* back to source text
44
*
55
* IDENTIFICATION
6-
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.211 2005/12/28 01:30:00 tgl Exp $
6+
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.212 2005/12/30 18:34:22 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -1525,8 +1525,15 @@ deparse_context_for_subplan(const char *name, List *tlist,
15251525
attrs = lappend(attrs, makeString(pstrdup(buf)));
15261526
}
15271527

1528-
rte->rtekind = RTE_SPECIAL; /* XXX */
1528+
/*
1529+
* We create an RTE_SPECIAL RangeTblEntry, and store the given tlist
1530+
* in its coldeflist field. This is a hack to make the tlist available
1531+
* to get_name_for_var_field(). RTE_SPECIAL nodes shouldn't appear in
1532+
* deparse contexts otherwise.
1533+
*/
1534+
rte->rtekind = RTE_SPECIAL;
15291535
rte->relid = InvalidOid;
1536+
rte->coldeflist = tlist;
15301537
rte->eref = makeAlias(name, attrs);
15311538
rte->inh = false;
15321539
rte->inFromCl = true;
@@ -2571,7 +2578,8 @@ get_names_for_var(Var *var, int levelsup, deparse_context *context,
25712578
* Note: this has essentially the same logic as the parser's
25722579
* expandRecordVariable() function, but we are dealing with a different
25732580
* representation of the input context, and we only need one field name not
2574-
* a TupleDesc.
2581+
* a TupleDesc. Also, we have a special case for RTE_SPECIAL so that we can
2582+
* deal with displaying RECORD-returning functions in subplan targetlists.
25752583
*/
25762584
static const char *
25772585
get_name_for_var_field(Var *var, int fieldno,
@@ -2602,7 +2610,6 @@ get_name_for_var_field(Var *var, int fieldno,
26022610
switch (rte->rtekind)
26032611
{
26042612
case RTE_RELATION:
2605-
case RTE_SPECIAL:
26062613

26072614
/*
26082615
* 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,
26632670
* its result columns as RECORD, which is not allowed.
26642671
*/
26652672
break;
2673+
case RTE_SPECIAL:
2674+
/*
2675+
* This case occurs during EXPLAIN when we are looking at a
2676+
* deparse context node set up by deparse_context_for_subplan().
2677+
* Look into the subplan's target list to get the referenced
2678+
* expression, and then pass it to get_expr_result_type().
2679+
*/
2680+
if (rte->coldeflist)
2681+
{
2682+
TargetEntry *ste = get_tle_by_resno(rte->coldeflist, attnum);
2683+
2684+
if (ste != NULL)
2685+
expr = (Node *) ste->expr;
2686+
}
2687+
break;
26662688
}
26672689

26682690
/*

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy