From fa2667d9546ccaff21e2221b4766eec1c160d482 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 v5 2/3] Make some static functions work on TupleDesc rather
 than Relation

---
 src/backend/optimizer/prep/preptlist.c | 23 ++++++++---------
 src/backend/optimizer/prep/prepunion.c | 45 ++++++++++++++++++----------------
 2 files changed, 36 insertions(+), 32 deletions(-)

diff --git a/src/backend/optimizer/prep/preptlist.c b/src/backend/optimizer/prep/preptlist.c
index 8603feef2b..b6e658fe81 100644
--- a/src/backend/optimizer/prep/preptlist.c
+++ b/src/backend/optimizer/prep/preptlist.c
@@ -54,7 +54,7 @@
 
 
 static List *expand_targetlist(List *tlist, int command_type,
-				  Index result_relation, Relation rel);
+				  Index result_relation, TupleDesc tupdesc);
 
 
 /*
@@ -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..d0d9812da6 100644
--- a/src/backend/optimizer/prep/prepunion.c
+++ b/src/backend/optimizer/prep/prepunion.c
@@ -113,10 +113,10 @@ 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,
-						  Index newvarno,
-						  List **translated_vars);
+static List *make_inh_translation_list(TupleDesc old_tupdesc,
+						  TupleDesc new_tupdesc,
+						  char *new_rel_name,
+						  Index newvarno);
 static Bitmapset *translate_col_privs(const Bitmapset *parent_privs,
 					List *translated_vars);
 static Node *adjust_appendrel_attrs_mutator(Node *node,
@@ -1730,8 +1730,11 @@ 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,
-								  &appinfo->translated_vars);
+		appinfo->translated_vars =
+			make_inh_translation_list(RelationGetDescr(parentrel),
+									  RelationGetDescr(childrel),
+									  RelationGetRelationName(childrel),
+									  childRTindex);
 		appinfo->parent_reloid = parentOID;
 		*appinfos = lappend(*appinfos, appinfo);
 
@@ -1788,22 +1791,23 @@ expand_single_inheritance_child(PlannerInfo *root, RangeTblEntry *parentrte,
 
 /*
  * make_inh_translation_list
- *	  Build the list of translations from parent Vars to child Vars for
- *	  an inheritance child.
+ *	  Build the list of translations from parent Vars ("old" rel) to child
+ *	  Vars ("new" rel) for an inheritance child.
  *
  * For paranoia's sake, we match type/collation as well as attribute name.
  */
-static void
-make_inh_translation_list(Relation oldrelation, Relation newrelation,
-						  Index newvarno,
-						  List **translated_vars)
+static List *
+make_inh_translation_list(TupleDesc old_tupdesc, TupleDesc new_tupdesc,
+						  char *new_rel_name,
+						  Index newvarno)
 {
 	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++)
 	{
@@ -1827,10 +1831,9 @@ make_inh_translation_list(Relation oldrelation, Relation newrelation,
 		attcollation = att->attcollation;
 
 		/*
-		 * When we are generating the "translation list" for the parent table
-		 * of an inheritance set, no need to search for matches.
+		 * When the tupledescs are identical, no need to search for matches.
 		 */
-		if (oldrelation == newrelation)
+		if (equal_tupdescs)
 		{
 			vars = lappend(vars, makeVar(newvarno,
 										 (AttrNumber) (old_attno + 1),
@@ -1867,16 +1870,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),
@@ -1886,7 +1889,7 @@ make_inh_translation_list(Relation oldrelation, Relation newrelation,
 									 0));
 	}
 
-	*translated_vars = vars;
+	return vars;
 }
 
 /*
-- 
2.11.0

