@@ -34,7 +34,7 @@ typedef struct
3434static void make_inh_translation_list (Relation oldrelation ,
3535 Relation newrelation ,
3636 Index newvarno ,
37- List * * translated_vars );
37+ AppendRelInfo * appinfo );
3838static Node * adjust_appendrel_attrs_mutator (Node * node ,
3939 adjust_appendrel_attrs_context * context );
4040static List * adjust_inherited_tlist (List * tlist ,
@@ -55,8 +55,7 @@ make_append_rel_info(Relation parentrel, Relation childrel,
5555 appinfo -> child_relid = childRTindex ;
5656 appinfo -> parent_reltype = parentrel -> rd_rel -> reltype ;
5757 appinfo -> child_reltype = childrel -> rd_rel -> reltype ;
58- make_inh_translation_list (parentrel , childrel , childRTindex ,
59- & appinfo -> translated_vars );
58+ make_inh_translation_list (parentrel , childrel , childRTindex , appinfo );
6059 appinfo -> parent_reloid = RelationGetRelid (parentrel );
6160
6261 return appinfo ;
@@ -65,16 +64,23 @@ make_append_rel_info(Relation parentrel, Relation childrel,
6564/*
6665 * make_inh_translation_list
6766 * Build the list of translations from parent Vars to child Vars for
68- * an inheritance child.
67+ * an inheritance child, as well as a reverse-translation array.
68+ *
69+ * The reverse-translation array has an entry for each child relation
70+ * column, which is either the 1-based index of the corresponding parent
71+ * column, or 0 if there's no match (that happens for dropped child columns,
72+ * as well as child columns beyond those of the parent, which are allowed in
73+ * traditional inheritance though not partitioning).
6974 *
7075 * For paranoia's sake, we match type/collation as well as attribute name.
7176 */
7277static void
7378make_inh_translation_list (Relation oldrelation , Relation newrelation ,
7479 Index newvarno ,
75- List * * translated_vars )
80+ AppendRelInfo * appinfo )
7681{
7782 List * vars = NIL ;
83+ AttrNumber * pcolnos ;
7884 TupleDesc old_tupdesc = RelationGetDescr (oldrelation );
7985 TupleDesc new_tupdesc = RelationGetDescr (newrelation );
8086 Oid new_relid = RelationGetRelid (newrelation );
@@ -83,6 +89,11 @@ make_inh_translation_list(Relation oldrelation, Relation newrelation,
8389 int old_attno ;
8490 int new_attno = 0 ;
8591
92+ /* Initialize reverse-translation array with all entries zero */
93+ appinfo -> num_child_cols = newnatts ;
94+ appinfo -> parent_colnos = pcolnos =
95+ (AttrNumber * ) palloc0 (newnatts * sizeof (AttrNumber ));
96+
8697 for (old_attno = 0 ; old_attno < oldnatts ; old_attno ++ )
8798 {
8899 Form_pg_attribute att ;
@@ -115,6 +126,7 @@ make_inh_translation_list(Relation oldrelation, Relation newrelation,
115126 atttypmod ,
116127 attcollation ,
117128 0 ));
129+ pcolnos [old_attno ] = old_attno + 1 ;
118130 continue ;
119131 }
120132
@@ -138,6 +150,7 @@ make_inh_translation_list(Relation oldrelation, Relation newrelation,
138150 elog (ERROR , "could not find inherited attribute \"%s\" of relation \"%s\"" ,
139151 attname , RelationGetRelationName (newrelation ));
140152 new_attno = ((Form_pg_attribute ) GETSTRUCT (newtup ))-> attnum - 1 ;
153+ Assert (new_attno >= 0 && new_attno < newnatts );
141154 ReleaseSysCache (newtup );
142155
143156 att = TupleDescAttr (new_tupdesc , new_attno );
@@ -157,10 +170,11 @@ make_inh_translation_list(Relation oldrelation, Relation newrelation,
157170 atttypmod ,
158171 attcollation ,
159172 0 ));
173+ pcolnos [new_attno ] = old_attno + 1 ;
160174 new_attno ++ ;
161175 }
162176
163- * translated_vars = vars ;
177+ appinfo -> translated_vars = vars ;
164178}
165179
166180/*
0 commit comments