From d5b3b7c252da2c2a25bd9b8de40a03f2d5f30081 Mon Sep 17 00:00:00 2001
From: Alvaro Herrera <alvherre@alvh.no-ip.org>
Date: Thu, 1 Mar 2018 19:58:50 -0300
Subject: [PATCH v3 1/3] Make some static functions work on TupleDesc rather
 than Relation

---
 src/backend/optimizer/prep/preptlist.c | 21 +++++++++++----------
 src/backend/optimizer/prep/prepunion.c | 26 ++++++++++++++++----------
 2 files changed, 27 insertions(+), 20 deletions(-)

diff --git a/src/backend/optimizer/prep/preptlist.c b/src/backend/optimizer/prep/preptlist.c
index 8603feef2b..8c94dd4f59 100644
--- a/src/backend/optimizer/prep/preptlist.c
+++ b/src/backend/optimizer/prep/preptlist.c
@@ -116,7 +116,8 @@ preprocess_targetlist(PlannerInfo *root)
 	tlist = parse->targetList;
 	if (command_type == CMD_INSERT || command_type == CMD_UPDATE)
 		tlist = expand_targetlist(tlist, command_type,
-								  result_relation, target_relation);
+								  result_relation,
+								  RelationGetDescr(target_relation));
 
 	/*
 	 * Add necessary junk columns for rowmarked rels.  These values are needed
@@ -230,7 +231,7 @@ preprocess_targetlist(PlannerInfo *root)
 			expand_targetlist(parse->onConflict->onConflictSet,
 							  CMD_UPDATE,
 							  result_relation,
-							  target_relation);
+							  RelationGetDescr(target_relation));
 
 	if (target_relation)
 		heap_close(target_relation, NoLock);
@@ -247,13 +248,13 @@ preprocess_targetlist(PlannerInfo *root)
 
 /*
  * expand_targetlist
- *	  Given a target list as generated by the parser and a result relation,
- *	  add targetlist entries for any missing attributes, and ensure the
- *	  non-junk attributes appear in proper field order.
+ *	  Given a target list as generated by the parser and a result relation's
+ *	  tuple descriptor, add targetlist entries for any missing attributes, and
+ *	  ensure the non-junk attributes appear in proper field order.
  */
 static List *
 expand_targetlist(List *tlist, int command_type,
-				  Index result_relation, Relation rel)
+				  Index result_relation, TupleDesc tupdesc)
 {
 	List	   *new_tlist = NIL;
 	ListCell   *tlist_item;
@@ -266,14 +267,14 @@ expand_targetlist(List *tlist, int command_type,
 	 * The rewriter should have already ensured that the TLEs are in correct
 	 * order; but we have to insert TLEs for any missing attributes.
 	 *
-	 * Scan the tuple description in the relation's relcache entry to make
-	 * sure we have all the user attributes in the right order.
+	 * Scan the tuple description to make sure we have all the user attributes
+	 * in the right order.
 	 */
-	numattrs = RelationGetNumberOfAttributes(rel);
+	numattrs = tupdesc->natts;
 
 	for (attrno = 1; attrno <= numattrs; attrno++)
 	{
-		Form_pg_attribute att_tup = TupleDescAttr(rel->rd_att, attrno - 1);
+		Form_pg_attribute att_tup = TupleDescAttr(tupdesc, attrno - 1);
 		TargetEntry *new_tle = NULL;
 
 		if (tlist_item != NULL)
diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c
index b586f941a8..7949829b31 100644
--- a/src/backend/optimizer/prep/prepunion.c
+++ b/src/backend/optimizer/prep/prepunion.c
@@ -113,8 +113,9 @@ static void expand_single_inheritance_child(PlannerInfo *root,
 								PlanRowMark *top_parentrc, Relation childrel,
 								List **appinfos, RangeTblEntry **childrte_p,
 								Index *childRTindex_p);
-static void make_inh_translation_list(Relation oldrelation,
-						  Relation newrelation,
+static void make_inh_translation_list(TupleDesc old_tupdesc,
+						  TupleDesc new_tupdesc,
+						  char *new_rel_name,
 						  Index newvarno,
 						  List **translated_vars);
 static Bitmapset *translate_col_privs(const Bitmapset *parent_privs,
@@ -1730,7 +1731,10 @@ expand_single_inheritance_child(PlannerInfo *root, RangeTblEntry *parentrte,
 		appinfo->child_relid = childRTindex;
 		appinfo->parent_reltype = parentrel->rd_rel->reltype;
 		appinfo->child_reltype = childrel->rd_rel->reltype;
-		make_inh_translation_list(parentrel, childrel, childRTindex,
+		make_inh_translation_list(RelationGetDescr(parentrel),
+								  RelationGetDescr(childrel),
+								  RelationGetRelationName(childrel),
+								  childRTindex,
 								  &appinfo->translated_vars);
 		appinfo->parent_reloid = parentOID;
 		*appinfos = lappend(*appinfos, appinfo);
@@ -1794,16 +1798,18 @@ expand_single_inheritance_child(PlannerInfo *root, RangeTblEntry *parentrte,
  * For paranoia's sake, we match type/collation as well as attribute name.
  */
 static void
-make_inh_translation_list(Relation oldrelation, Relation newrelation,
+make_inh_translation_list(TupleDesc old_tupdesc, TupleDesc new_tupdesc,
+						  char *new_rel_name,
 						  Index newvarno,
 						  List **translated_vars)
 {
 	List	   *vars = NIL;
-	TupleDesc	old_tupdesc = RelationGetDescr(oldrelation);
-	TupleDesc	new_tupdesc = RelationGetDescr(newrelation);
 	int			oldnatts = old_tupdesc->natts;
 	int			newnatts = new_tupdesc->natts;
 	int			old_attno;
+	bool		equal_tupdescs;
+
+	equal_tupdescs = equalTupleDescs(old_tupdesc, new_tupdesc);
 
 	for (old_attno = 0; old_attno < oldnatts; old_attno++)
 	{
@@ -1830,7 +1836,7 @@ make_inh_translation_list(Relation oldrelation, Relation newrelation,
 		 * When we are generating the "translation list" for the parent table
 		 * of an inheritance set, no need to search for matches.
 		 */
-		if (oldrelation == newrelation)
+		if (equal_tupdescs)
 		{
 			vars = lappend(vars, makeVar(newvarno,
 										 (AttrNumber) (old_attno + 1),
@@ -1867,16 +1873,16 @@ make_inh_translation_list(Relation oldrelation, Relation newrelation,
 			}
 			if (new_attno >= newnatts)
 				elog(ERROR, "could not find inherited attribute \"%s\" of relation \"%s\"",
-					 attname, RelationGetRelationName(newrelation));
+					 attname, new_rel_name);
 		}
 
 		/* Found it, check type and collation match */
 		if (atttypid != att->atttypid || atttypmod != att->atttypmod)
 			elog(ERROR, "attribute \"%s\" of relation \"%s\" does not match parent's type",
-				 attname, RelationGetRelationName(newrelation));
+				 attname, new_rel_name);
 		if (attcollation != att->attcollation)
 			elog(ERROR, "attribute \"%s\" of relation \"%s\" does not match parent's collation",
-				 attname, RelationGetRelationName(newrelation));
+				 attname, new_rel_name);
 
 		vars = lappend(vars, makeVar(newvarno,
 									 (AttrNumber) (new_attno + 1),
-- 
2.11.0

