From 925ca9d7de97529591d83f7c7f6c9bdef66afeae Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sat, 21 Apr 2007 05:56:41 +0000
Subject: [PATCH] Tweak make_inh_translation_lists() to check the common case
 wherein parent and child attnums are the same, before it grovels through each
 and every child column looking for a name match.  Saves some time in large
 inheritance trees, per example from Greg.

---
 src/backend/optimizer/prep/prepunion.c | 51 ++++++++++++++++----------
 1 file changed, 31 insertions(+), 20 deletions(-)

diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c
index 5b4b312df11..2b273f738a8 100644
--- a/src/backend/optimizer/prep/prepunion.c
+++ b/src/backend/optimizer/prep/prepunion.c
@@ -22,7 +22,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.140 2007/03/17 00:11:04 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.141 2007/04/21 05:56:41 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -973,31 +973,42 @@ make_inh_translation_lists(Relation oldrelation, Relation newrelation,
 		 * Otherwise we have to search for the matching column by name.
 		 * There's no guarantee it'll have the same column position, because
 		 * of cases like ALTER TABLE ADD COLUMN and multiple inheritance.
+		 * However, in simple cases it will be the same column number, so
+		 * try that before we go groveling through all the columns.
+		 *
+		 * Note: the test for (att = ...) != NULL cannot fail, it's just a
+		 * notational device to include the assignment into the if-clause.
 		 */
-		for (new_attno = 0; new_attno < newnatts; new_attno++)
+		if (old_attno < newnatts &&
+			(att = new_tupdesc->attrs[old_attno]) != NULL &&
+			!att->attisdropped && att->attinhcount != 0 &&
+			strcmp(attname, NameStr(att->attname)) == 0)
+			new_attno = old_attno;
+		else
 		{
-			att = new_tupdesc->attrs[new_attno];
-			if (att->attisdropped || att->attinhcount == 0)
-				continue;
-			if (strcmp(attname, NameStr(att->attname)) != 0)
-				continue;
-			/* Found it, check type */
-			if (atttypid != att->atttypid || atttypmod != att->atttypmod)
-				elog(ERROR, "attribute \"%s\" of relation \"%s\" does not match parent's type",
+			for (new_attno = 0; new_attno < newnatts; new_attno++)
+			{
+				att = new_tupdesc->attrs[new_attno];
+				if (!att->attisdropped && att->attinhcount != 0 &&
+					strcmp(attname, NameStr(att->attname)) == 0)
+					break;
+			}
+			if (new_attno >= newnatts)
+				elog(ERROR, "could not find inherited attribute \"%s\" of relation \"%s\"",
 					 attname, RelationGetRelationName(newrelation));
-
-			numbers = lappend_int(numbers, new_attno + 1);
-			vars = lappend(vars, makeVar(newvarno,
-										 (AttrNumber) (new_attno + 1),
-										 atttypid,
-										 atttypmod,
-										 0));
-			break;
 		}
 
-		if (new_attno >= newnatts)
-			elog(ERROR, "could not find inherited attribute \"%s\" of relation \"%s\"",
+		/* Found it, check type */
+		if (atttypid != att->atttypid || atttypmod != att->atttypmod)
+			elog(ERROR, "attribute \"%s\" of relation \"%s\" does not match parent's type",
 				 attname, RelationGetRelationName(newrelation));
+
+		numbers = lappend_int(numbers, new_attno + 1);
+		vars = lappend(vars, makeVar(newvarno,
+									 (AttrNumber) (new_attno + 1),
+									 atttypid,
+									 atttypmod,
+									 0));
 	}
 
 	*col_mappings = numbers;
-- 
GitLab