4949#include "utils/selfuncs.h"
5050
5151
52+ typedef struct
53+ {
54+ PlannerInfo * root ;
55+ AppendRelInfo * appinfo ;
56+ } adjust_appendrel_attrs_context ;
57+
5258static Plan * recurse_set_operations (Node * setOp , PlannerInfo * root ,
5359 double tuple_fraction ,
5460 List * colTypes , List * colCollations ,
@@ -99,7 +105,7 @@ static void make_inh_translation_list(Relation oldrelation,
99105static Bitmapset * translate_col_privs (const Bitmapset * parent_privs ,
100106 List * translated_vars );
101107static Node * adjust_appendrel_attrs_mutator (Node * node ,
102- AppendRelInfo * context );
108+ adjust_appendrel_attrs_context * context );
103109static Relids adjust_relid_set (Relids relids , Index oldrelid , Index newrelid );
104110static List * adjust_inherited_tlist (List * tlist ,
105111 AppendRelInfo * context );
@@ -1569,9 +1575,13 @@ translate_col_privs(const Bitmapset *parent_privs,
15691575 * maybe we should try to fold the two routines together.
15701576 */
15711577Node *
1572- adjust_appendrel_attrs (Node * node , AppendRelInfo * appinfo )
1578+ adjust_appendrel_attrs (PlannerInfo * root , Node * node , AppendRelInfo * appinfo )
15731579{
15741580 Node * result ;
1581+ adjust_appendrel_attrs_context context ;
1582+
1583+ context .root = root ;
1584+ context .appinfo = appinfo ;
15751585
15761586 /*
15771587 * Must be prepared to start with a Query or a bare expression tree.
@@ -1582,7 +1592,7 @@ adjust_appendrel_attrs(Node *node, AppendRelInfo *appinfo)
15821592
15831593 newnode = query_tree_mutator ((Query * ) node ,
15841594 adjust_appendrel_attrs_mutator ,
1585- (void * ) appinfo ,
1595+ (void * ) & context ,
15861596 QTW_IGNORE_RC_SUBQUERIES );
15871597 if (newnode -> resultRelation == appinfo -> parent_relid )
15881598 {
@@ -1596,37 +1606,40 @@ adjust_appendrel_attrs(Node *node, AppendRelInfo *appinfo)
15961606 result = (Node * ) newnode ;
15971607 }
15981608 else
1599- result = adjust_appendrel_attrs_mutator (node , appinfo );
1609+ result = adjust_appendrel_attrs_mutator (node , & context );
16001610
16011611 return result ;
16021612}
16031613
16041614static Node *
1605- adjust_appendrel_attrs_mutator (Node * node , AppendRelInfo * context )
1615+ adjust_appendrel_attrs_mutator (Node * node ,
1616+ adjust_appendrel_attrs_context * context )
16061617{
1618+ AppendRelInfo * appinfo = context -> appinfo ;
1619+
16071620 if (node == NULL )
16081621 return NULL ;
16091622 if (IsA (node , Var ))
16101623 {
16111624 Var * var = (Var * ) copyObject (node );
16121625
16131626 if (var -> varlevelsup == 0 &&
1614- var -> varno == context -> parent_relid )
1627+ var -> varno == appinfo -> parent_relid )
16151628 {
1616- var -> varno = context -> child_relid ;
1617- var -> varnoold = context -> child_relid ;
1629+ var -> varno = appinfo -> child_relid ;
1630+ var -> varnoold = appinfo -> child_relid ;
16181631 if (var -> varattno > 0 )
16191632 {
16201633 Node * newnode ;
16211634
1622- if (var -> varattno > list_length (context -> translated_vars ))
1635+ if (var -> varattno > list_length (appinfo -> translated_vars ))
16231636 elog (ERROR , "attribute %d of relation \"%s\" does not exist" ,
1624- var -> varattno , get_rel_name (context -> parent_reloid ));
1625- newnode = copyObject (list_nth (context -> translated_vars ,
1637+ var -> varattno , get_rel_name (appinfo -> parent_reloid ));
1638+ newnode = copyObject (list_nth (appinfo -> translated_vars ,
16261639 var -> varattno - 1 ));
16271640 if (newnode == NULL )
16281641 elog (ERROR , "attribute %d of relation \"%s\" does not exist" ,
1629- var -> varattno , get_rel_name (context -> parent_reloid ));
1642+ var -> varattno , get_rel_name (appinfo -> parent_reloid ));
16301643 return newnode ;
16311644 }
16321645 else if (var -> varattno == 0 )
@@ -1637,36 +1650,47 @@ adjust_appendrel_attrs_mutator(Node *node, AppendRelInfo *context)
16371650 * step to convert the tuple layout to the parent's rowtype.
16381651 * Otherwise we have to generate a RowExpr.
16391652 */
1640- if (OidIsValid (context -> child_reltype ))
1653+ if (OidIsValid (appinfo -> child_reltype ))
16411654 {
1642- Assert (var -> vartype == context -> parent_reltype );
1643- if (context -> parent_reltype != context -> child_reltype )
1655+ Assert (var -> vartype == appinfo -> parent_reltype );
1656+ if (appinfo -> parent_reltype != appinfo -> child_reltype )
16441657 {
16451658 ConvertRowtypeExpr * r = makeNode (ConvertRowtypeExpr );
16461659
16471660 r -> arg = (Expr * ) var ;
1648- r -> resulttype = context -> parent_reltype ;
1661+ r -> resulttype = appinfo -> parent_reltype ;
16491662 r -> convertformat = COERCE_IMPLICIT_CAST ;
16501663 r -> location = -1 ;
16511664 /* Make sure the Var node has the right type ID, too */
1652- var -> vartype = context -> child_reltype ;
1665+ var -> vartype = appinfo -> child_reltype ;
16531666 return (Node * ) r ;
16541667 }
16551668 }
16561669 else
16571670 {
16581671 /*
16591672 * Build a RowExpr containing the translated variables.
1673+ *
1674+ * In practice var->vartype will always be RECORDOID here,
1675+ * so we need to come up with some suitable column names.
1676+ * We use the parent RTE's column names.
1677+ *
1678+ * Note: we can't get here for inheritance cases, so there
1679+ * is no need to worry that translated_vars might contain
1680+ * some dummy NULLs.
16601681 */
16611682 RowExpr * rowexpr ;
16621683 List * fields ;
1684+ RangeTblEntry * rte ;
16631685
1664- fields = (List * ) copyObject (context -> translated_vars );
1686+ rte = rt_fetch (appinfo -> parent_relid ,
1687+ context -> root -> parse -> rtable );
1688+ fields = (List * ) copyObject (appinfo -> translated_vars );
16651689 rowexpr = makeNode (RowExpr );
16661690 rowexpr -> args = fields ;
16671691 rowexpr -> row_typeid = var -> vartype ;
16681692 rowexpr -> row_format = COERCE_IMPLICIT_CAST ;
1669- rowexpr -> colnames = NIL ;
1693+ rowexpr -> colnames = copyObject ( rte -> eref -> colnames ) ;
16701694 rowexpr -> location = -1 ;
16711695
16721696 return (Node * ) rowexpr ;
@@ -1680,16 +1704,16 @@ adjust_appendrel_attrs_mutator(Node *node, AppendRelInfo *context)
16801704 {
16811705 CurrentOfExpr * cexpr = (CurrentOfExpr * ) copyObject (node );
16821706
1683- if (cexpr -> cvarno == context -> parent_relid )
1684- cexpr -> cvarno = context -> child_relid ;
1707+ if (cexpr -> cvarno == appinfo -> parent_relid )
1708+ cexpr -> cvarno = appinfo -> child_relid ;
16851709 return (Node * ) cexpr ;
16861710 }
16871711 if (IsA (node , RangeTblRef ))
16881712 {
16891713 RangeTblRef * rtr = (RangeTblRef * ) copyObject (node );
16901714
1691- if (rtr -> rtindex == context -> parent_relid )
1692- rtr -> rtindex = context -> child_relid ;
1715+ if (rtr -> rtindex == appinfo -> parent_relid )
1716+ rtr -> rtindex = appinfo -> child_relid ;
16931717 return (Node * ) rtr ;
16941718 }
16951719 if (IsA (node , JoinExpr ))
@@ -1701,8 +1725,8 @@ adjust_appendrel_attrs_mutator(Node *node, AppendRelInfo *context)
17011725 adjust_appendrel_attrs_mutator ,
17021726 (void * ) context );
17031727 /* now fix JoinExpr's rtindex (probably never happens) */
1704- if (j -> rtindex == context -> parent_relid )
1705- j -> rtindex = context -> child_relid ;
1728+ if (j -> rtindex == appinfo -> parent_relid )
1729+ j -> rtindex = appinfo -> child_relid ;
17061730 return (Node * ) j ;
17071731 }
17081732 if (IsA (node , PlaceHolderVar ))
@@ -1716,8 +1740,8 @@ adjust_appendrel_attrs_mutator(Node *node, AppendRelInfo *context)
17161740 /* now fix PlaceHolderVar's relid sets */
17171741 if (phv -> phlevelsup == 0 )
17181742 phv -> phrels = adjust_relid_set (phv -> phrels ,
1719- context -> parent_relid ,
1720- context -> child_relid );
1743+ appinfo -> parent_relid ,
1744+ appinfo -> child_relid );
17211745 return (Node * ) phv ;
17221746 }
17231747 /* Shouldn't need to handle planner auxiliary nodes here */
@@ -1749,20 +1773,20 @@ adjust_appendrel_attrs_mutator(Node *node, AppendRelInfo *context)
17491773
17501774 /* adjust relid sets too */
17511775 newinfo -> clause_relids = adjust_relid_set (oldinfo -> clause_relids ,
1752- context -> parent_relid ,
1753- context -> child_relid );
1776+ appinfo -> parent_relid ,
1777+ appinfo -> child_relid );
17541778 newinfo -> required_relids = adjust_relid_set (oldinfo -> required_relids ,
1755- context -> parent_relid ,
1756- context -> child_relid );
1779+ appinfo -> parent_relid ,
1780+ appinfo -> child_relid );
17571781 newinfo -> nullable_relids = adjust_relid_set (oldinfo -> nullable_relids ,
1758- context -> parent_relid ,
1759- context -> child_relid );
1782+ appinfo -> parent_relid ,
1783+ appinfo -> child_relid );
17601784 newinfo -> left_relids = adjust_relid_set (oldinfo -> left_relids ,
1761- context -> parent_relid ,
1762- context -> child_relid );
1785+ appinfo -> parent_relid ,
1786+ appinfo -> child_relid );
17631787 newinfo -> right_relids = adjust_relid_set (oldinfo -> right_relids ,
1764- context -> parent_relid ,
1765- context -> child_relid );
1788+ appinfo -> parent_relid ,
1789+ appinfo -> child_relid );
17661790
17671791 /*
17681792 * Reset cached derivative fields, since these might need to have
0 commit comments