From c59839ac6de8fcc41a70c06472a3e39a207002c9 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Mon, 22 Oct 2001 22:47:57 +0000
Subject: [PATCH] Consolidate tables of known system attributes into one table.

---
 src/backend/catalog/heap.c          | 41 ++++++++++++-----
 src/backend/parser/parse_relation.c | 68 +++++------------------------
 src/include/catalog/heap.h          |  8 ++--
 3 files changed, 47 insertions(+), 70 deletions(-)

diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 599e79a4ea6..89d3072f7bf 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.177 2001/10/06 23:21:43 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.178 2001/10/22 22:47:57 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -151,6 +151,7 @@ static Form_pg_attribute SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6, &a7};
 
 /*
  * This function returns a Form_pg_attribute pointer for a system attribute.
+ * Note that we elog if the presented attno is invalid.
  */
 Form_pg_attribute
 SystemAttributeDefinition(AttrNumber attno, bool relhasoids)
@@ -164,6 +165,30 @@ SystemAttributeDefinition(AttrNumber attno, bool relhasoids)
 	return SysAtt[-attno - 1];
 }
 
+/*
+ * If the given name is a system attribute name, return a Form_pg_attribute
+ * pointer for a prototype definition.  If not, return NULL.
+ */
+Form_pg_attribute
+SystemAttributeByName(const char *attname, bool relhasoids)
+{
+	int j;
+
+	for (j = 0; j < (int) lengthof(SysAtt); j++)
+	{
+		Form_pg_attribute att = SysAtt[j];
+
+		if (relhasoids || att->attnum != ObjectIdAttributeNumber)
+		{
+			if (strcmp(NameStr(att->attname), attname) == 0)
+				return att;
+		}
+	}
+
+	return NULL;
+}
+
+
 /* ----------------------------------------------------------------
  *				XXX END OF UGLY HARD CODED BADNESS XXX
  * ---------------------------------------------------------------- */
@@ -350,16 +375,10 @@ CheckAttributeNames(TupleDesc tupdesc, bool relhasoids)
 	 */
 	for (i = 0; i < natts; i++)
 	{
-		for (j = 0; j < (int) lengthof(SysAtt); j++)
-		{
-			if (relhasoids || SysAtt[j]->attnum != ObjectIdAttributeNumber)
-			{
-				if (strcmp(NameStr(SysAtt[j]->attname),
-						   NameStr(tupdesc->attrs[i]->attname)) == 0)
-					elog(ERROR, "name of column \"%s\" conflicts with an existing system column",
-						 NameStr(SysAtt[j]->attname));
-			}
-		}
+		if (SystemAttributeByName(NameStr(tupdesc->attrs[i]->attname),
+								  relhasoids) != NULL)
+			elog(ERROR, "name of column \"%s\" conflicts with an existing system column",
+				 NameStr(tupdesc->attrs[i]->attname));
 		if (tupdesc->attrs[i]->atttypid == UNKNOWNOID)
 			elog(NOTICE, "Attribute '%s' has an unknown type"
 				 "\n\tProceeding with relation creation anyway",
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
index 1cc3d19c78d..5077d092da4 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.56 2001/08/10 18:57:37 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.57 2001/10/22 22:47:57 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -18,6 +18,7 @@
 
 #include "access/heapam.h"
 #include "access/htup.h"
+#include "catalog/heap.h"
 #include "catalog/pg_type.h"
 #include "nodes/makefuncs.h"
 #include "parser/parsetree.h"
@@ -43,43 +44,6 @@ static int	specialAttNum(char *a);
 static void warnAutoRange(ParseState *pstate, char *refname);
 
 
-/*
- * Information defining the "system" attributes of every relation.
- */
-static struct
-{
-	char	   *attrname;		/* name of system attribute */
-	int			attrnum;		/* its attribute number (always < 0) */
-	Oid			attrtype;		/* its type id */
-}			special_attr[] =
-
-{
-	{
-		"ctid", SelfItemPointerAttributeNumber, TIDOID
-	},
-	{
-		"oid", ObjectIdAttributeNumber, OIDOID
-	},
-	{
-		"xmin", MinTransactionIdAttributeNumber, XIDOID
-	},
-	{
-		"cmin", MinCommandIdAttributeNumber, CIDOID
-	},
-	{
-		"xmax", MaxTransactionIdAttributeNumber, XIDOID
-	},
-	{
-		"cmax", MaxCommandIdAttributeNumber, CIDOID
-	},
-	{
-		"tableoid", TableOidAttributeNumber, OIDOID
-	}
-};
-
-#define SPECIALS ((int) lengthof(special_attr))
-
-
 /*
  * refnameRangeOrJoinEntry
  *	  Given a refname, look to see if it matches any RTE or join table.
@@ -1001,39 +965,31 @@ attnameAttNum(Relation rd, char *a)
 static int
 specialAttNum(char *a)
 {
-	int			i;
-
-	for (i = 0; i < SPECIALS; i++)
-		if (strcmp(special_attr[i].attrname, a) == 0)
-			return special_attr[i].attrnum;
+	Form_pg_attribute sysatt;
 
+	sysatt = SystemAttributeByName(a, true /* "oid" will be accepted */);
+	if (sysatt != NULL)
+		return sysatt->attnum;
 	return InvalidAttrNumber;
 }
 
 
-/* given attribute id, return type of that attribute */
 /*
+ * given attribute id, return type of that attribute
+ *
  *	This should only be used if the relation is already
  *	heap_open()'ed.  Use the cache version get_atttype()
  *	for access to non-opened relations.
- *
- * Note: we don't bother to check rd->rd_rel->relhasoids; we assume that
- * the caller will only ask about OID if that column has been found valid.
  */
 Oid
 attnumTypeId(Relation rd, int attid)
 {
-	if (attid < 0)
+	if (attid <= 0)
 	{
-		int			i;
+		Form_pg_attribute sysatt;
 
-		for (i = 0; i < SPECIALS; i++)
-		{
-			if (special_attr[i].attrnum == attid)
-				return special_attr[i].attrtype;
-		}
-		/* negative but not a valid system attr? */
-		elog(ERROR, "attnumTypeId: bogus attribute number %d", attid);
+		sysatt = SystemAttributeDefinition(attid, rd->rd_rel->relhasoids);
+		return sysatt->atttypid;
 	}
 
 	/*
diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h
index 2d08520bc90..8d7346fa05a 100644
--- a/src/include/catalog/heap.h
+++ b/src/include/catalog/heap.h
@@ -1,13 +1,13 @@
 /*-------------------------------------------------------------------------
  *
  * heap.h
- *	  prototypes for functions in lib/catalog/heap.c
+ *	  prototypes for functions in backend/catalog/heap.c
  *
  *
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: heap.h,v 1.37 2001/08/10 18:57:39 tgl Exp $
+ * $Id: heap.h,v 1.38 2001/10/22 22:47:57 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -47,8 +47,10 @@ extern void AddRelationRawConstraints(Relation rel,
 
 extern int RemoveCheckConstraint(Relation rel, const char *constrName, bool inh);
 
-
 extern Form_pg_attribute SystemAttributeDefinition(AttrNumber attno,
 												   bool relhasoids);
 
+extern Form_pg_attribute SystemAttributeByName(const char *attname,
+											   bool relhasoids);
+
 #endif	 /* HEAP_H */
-- 
GitLab