From d67442ccfd654f0f021ec4499804d681706dfc4e Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Fri, 29 Mar 2002 22:10:34 +0000
Subject: [PATCH] Mop-up some infelicities in new relation lookup handling.

---
 src/backend/access/index/genam.c |  3 +-
 src/backend/commands/cluster.c   | 44 ++++++++--------
 src/backend/commands/creatinh.c  | 11 ++--
 src/backend/commands/trigger.c   | 86 ++++++++++++--------------------
 src/backend/parser/parse_func.c  |  9 +---
 src/backend/tcop/utility.c       | 10 ++--
 src/include/commands/trigger.h   |  4 +-
 7 files changed, 70 insertions(+), 97 deletions(-)

diff --git a/src/backend/access/index/genam.c b/src/backend/access/index/genam.c
index e36a1450db3..2e70fb67cde 100644
--- a/src/backend/access/index/genam.c
+++ b/src/backend/access/index/genam.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/index/genam.c,v 1.31 2002/02/19 20:11:10 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/index/genam.c,v 1.32 2002/03/29 22:10:32 tgl Exp $
  *
  * NOTES
  *	  many of the old access method routines have been turned into
@@ -308,6 +308,7 @@ systable_beginscan(Relation rel,
 		Relation	irel;
 		unsigned	i;
 
+		/* We assume it's a system index, so index_openr is OK */
 		sysscan->irel = irel = index_openr(indexRelname);
 		/*
 		 * Change attribute numbers to be index column numbers.
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index 151577ae2d2..0d0cbbe7881 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.74 2002/03/29 19:06:03 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.75 2002/03/29 22:10:33 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -33,6 +33,7 @@
 #include "commands/rename.h"
 #include "miscadmin.h"
 #include "utils/builtins.h"
+#include "utils/lsyscache.h"
 #include "utils/syscache.h"
 #include "utils/temprel.h"
 
@@ -65,40 +66,35 @@ cluster(RangeVar *oldrelation, char *oldindexname)
 	bool		istemp;
 	char		NewHeapName[NAMEDATALEN];
 	char		NewIndexName[NAMEDATALEN];
-	RangeVar   *saveoldrelation;
-	RangeVar   *saveoldindex;
 	RangeVar   *NewHeap;
 	RangeVar   *NewIndex;
 
-	/*
-	 * FIXME SCHEMAS: The old code had the comment:
-	 * "Copy the arguments into local storage, just to be safe."
-	 * By using copyObject we are not using local storage.
-	 * Was that really necessary?
-	 */
-	saveoldrelation = copyObject(oldrelation);
-	saveoldindex = copyObject(oldrelation);
-	saveoldindex->relname = pstrdup(oldindexname);
-
 	/*
 	 * We grab exclusive access to the target rel and index for the
 	 * duration of the transaction.
 	 */
-	OldHeap = heap_openrv(saveoldrelation, AccessExclusiveLock);
+	OldHeap = heap_openrv(oldrelation, AccessExclusiveLock);
 	OIDOldHeap = RelationGetRelid(OldHeap);
 
-	OldIndex = index_openrv(saveoldindex);
-	LockRelation(OldIndex, AccessExclusiveLock);
-	OIDOldIndex = RelationGetRelid(OldIndex);
+	istemp = is_temp_rel_name(oldrelation->relname);
 
-	istemp = is_temp_rel_name(saveoldrelation->relname);
+	/*
+	 * The index is expected to be in the same namespace as the relation.
+	 */
+	OIDOldIndex = get_relname_relid(oldindexname,
+									RelationGetNamespace(OldHeap));
+	if (!OidIsValid(OIDOldIndex))
+		elog(ERROR, "CLUSTER: cannot find index \"%s\" for table \"%s\"",
+			 oldindexname, oldrelation->relname);
+	OldIndex = index_open(OIDOldIndex);
+	LockRelation(OldIndex, AccessExclusiveLock);
 
 	/*
 	 * Check that index is in fact an index on the given relation
 	 */
 	if (OldIndex->rd_index->indrelid != OIDOldHeap)
 		elog(ERROR, "CLUSTER: \"%s\" is not an index for table \"%s\"",
-			 saveoldindex->relname, saveoldrelation->relname);
+			 oldindexname, oldrelation->relname);
 
 	/* Drop relcache refcnts, but do NOT give up the locks */
 	heap_close(OldHeap, NoLock);
@@ -133,17 +129,19 @@ cluster(RangeVar *oldrelation, char *oldindexname)
 
 	CommandCounterIncrement();
 
-	NewHeap = copyObject(saveoldrelation);
+	/* XXX ugly, and possibly wrong in the presence of schemas... */
+	/* would be better to pass OIDs to renamerel. */
+	NewHeap = copyObject(oldrelation);
 	NewHeap->relname = NewHeapName;
-	NewIndex = copyObject(saveoldindex);
+	NewIndex = copyObject(oldrelation);
 	NewIndex->relname = NewIndexName;
 	
-	renamerel(NewHeap, saveoldrelation->relname);
+	renamerel(NewHeap, oldrelation->relname);
 
 	/* This one might be unnecessary, but let's be safe. */
 	CommandCounterIncrement();
 
-	renamerel(NewIndex, saveoldindex->relname);
+	renamerel(NewIndex, oldindexname);
 }
 
 static Oid
diff --git a/src/backend/commands/creatinh.c b/src/backend/commands/creatinh.c
index 1cf84f17a3e..f85814cc0f4 100644
--- a/src/backend/commands/creatinh.c
+++ b/src/backend/commands/creatinh.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.93 2002/03/29 19:06:05 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.94 2002/03/29 22:10:33 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -260,13 +260,12 @@ RemoveRelation(const RangeVar *relation)
 void
 TruncateRelation(const RangeVar *relation)
 {
-	Oid			relid;
 	Relation	rel;
-
-	relid = RangeVarGetRelid(relation, false);
+	Oid			relid;
 
 	/* Grab exclusive lock in preparation for truncate */
-	rel = heap_open(relid, AccessExclusiveLock);
+	rel = heap_openrv(relation, AccessExclusiveLock);
+	relid = RelationGetRelid(rel);
 
 	if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
 		elog(ERROR, "TRUNCATE cannot be used on sequences. '%s' is a sequence",
@@ -280,7 +279,7 @@ TruncateRelation(const RangeVar *relation)
 		elog(ERROR, "TRUNCATE cannot be used on system tables. '%s' is a system table",
 			 RelationGetRelationName(rel));
 
-	if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
+	if (!pg_class_ownercheck(relid, GetUserId()))
 		elog(ERROR, "you do not own relation \"%s\"",
 			 RelationGetRelationName(rel));
 
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 931ddeae7b0..36229b158e2 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.108 2002/03/26 19:15:45 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.109 2002/03/29 22:10:33 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -18,6 +18,7 @@
 #include "catalog/catalog.h"
 #include "catalog/catname.h"
 #include "catalog/indexing.h"
+#include "catalog/namespace.h"
 #include "catalog/pg_language.h"
 #include "catalog/pg_proc.h"
 #include "catalog/pg_trigger.h"
@@ -29,6 +30,7 @@
 #include "utils/builtins.h"
 #include "utils/fmgroids.h"
 #include "utils/inval.h"
+#include "utils/lsyscache.h"
 #include "utils/syscache.h"
 
 
@@ -96,20 +98,10 @@ CreateTrigger(CreateTrigStmt *stmt)
 		stmt->trigname = constrtrigname;
 		sprintf(constrtrigname, "RI_ConstraintTrigger_%u", newoid());
 
-		if (stmt->constrrel == NULL)
-			constrrelid = InvalidOid;
+		if (stmt->constrrel != NULL)
+			constrrelid = RangeVarGetRelid(stmt->constrrel, false);
 		else
-		{
-			/*
-			 * NoLock is probably sufficient here, since we're only
-			 * interested in getting the relation's OID...
-			 */
-			Relation	conrel;
-
-			conrel = heap_openrv(stmt->constrrel, NoLock);
-			constrrelid = conrel->rd_id;
-			heap_close(conrel, NoLock);
-		}
+			constrrelid = InvalidOid;
 	}
 
 	TRIGGER_CLEAR_TYPE(tgtype);
@@ -310,8 +302,11 @@ CreateTrigger(CreateTrigStmt *stmt)
 	heap_close(rel, NoLock);
 }
 
+/*
+ * DropTrigger - drop an individual trigger by name
+ */
 void
-DropTrigger(DropTrigStmt *stmt)
+DropTrigger(Oid relid, const char *trigname)
 {
 	Relation	rel;
 	Relation	tgrel;
@@ -320,21 +315,21 @@ DropTrigger(DropTrigStmt *stmt)
 	Relation	pgrel;
 	HeapTuple	tuple;
 	Relation	ridescs[Num_pg_class_indices];
+	int			remaining = 0;
 	int			found = 0;
-	int			tgfound = 0;
 
-	rel = heap_openrv(stmt->relation, AccessExclusiveLock);
+	rel = heap_open(relid, AccessExclusiveLock);
 
 	if (rel->rd_rel->relkind != RELKIND_RELATION)
 		elog(ERROR, "DropTrigger: relation \"%s\" is not a table",
-			 stmt->relation->relname);
+			 RelationGetRelationName(rel));
 
-	if (!allowSystemTableMods && IsSystemRelationName(stmt->relation->relname))
+	if (!allowSystemTableMods && IsSystemRelationName(RelationGetRelationName(rel)))
 		elog(ERROR, "DropTrigger: can't drop trigger for system relation %s",
-			 stmt->relation->relname);
+			 RelationGetRelationName(rel));
 
-	if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
-		elog(ERROR, "%s: %s", stmt->relation->relname,
+	if (!pg_class_ownercheck(relid, GetUserId()))
+		elog(ERROR, "%s: %s", RelationGetRelationName(rel),
 			 aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
 
 	/*
@@ -346,33 +341,33 @@ DropTrigger(DropTrigStmt *stmt)
 	tgrel = heap_openr(TriggerRelationName, RowExclusiveLock);
 	ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgrelid,
 						   F_OIDEQ,
-						   ObjectIdGetDatum(RelationGetRelid(rel)));
+						   ObjectIdGetDatum(relid));
 	tgscan = systable_beginscan(tgrel, TriggerRelidIndex, true,
 								SnapshotNow, 1, &key);
 	while (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
 	{
 		Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);
 
-		if (namestrcmp(&(pg_trigger->tgname), stmt->trigname) == 0)
+		if (namestrcmp(&(pg_trigger->tgname), trigname) == 0)
 		{
 			/* Delete any comments associated with this trigger */
 			DeleteComments(tuple->t_data->t_oid, RelationGetRelid(tgrel));
 
 			simple_heap_delete(tgrel, &tuple->t_self);
-			tgfound++;
+			found++;
 		}
 		else
-			found++;
+			remaining++;
 	}
 	systable_endscan(tgscan);
 	heap_close(tgrel, RowExclusiveLock);
 
-	if (tgfound == 0)
+	if (found == 0)
 		elog(ERROR, "DropTrigger: there is no trigger %s on relation %s",
-			 stmt->trigname, stmt->relation->relname);
-	if (tgfound > 1)
+			 trigname, RelationGetRelationName(rel));
+	if (found > 1)				/* shouldn't happen */
 		elog(NOTICE, "DropTrigger: found (and deleted) %d triggers %s on relation %s",
-			 tgfound, stmt->trigname, stmt->relation->relname);
+			 found, trigname, RelationGetRelationName(rel));
 
 	/*
 	 * Update relation's pg_class entry.  Crucial side-effect: other
@@ -381,13 +376,13 @@ DropTrigger(DropTrigStmt *stmt)
 	 */
 	pgrel = heap_openr(RelationRelationName, RowExclusiveLock);
 	tuple = SearchSysCacheCopy(RELOID,
-							   ObjectIdGetDatum(RelationGetRelid(rel)),
+							   ObjectIdGetDatum(relid),
 							   0, 0, 0);
 	if (!HeapTupleIsValid(tuple))
 		elog(ERROR, "DropTrigger: relation %s not found in pg_class",
-			 stmt->relation->relname);
+			 RelationGetRelationName(rel));
 
-	((Form_pg_class) GETSTRUCT(tuple))->reltriggers = found;
+	((Form_pg_class) GETSTRUCT(tuple))->reltriggers = remaining;
 	simple_heap_update(pgrel, &tuple->t_self, tuple);
 	CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs);
 	CatalogIndexInsert(ridescs, Num_pg_class_indices, pgrel, tuple);
@@ -395,12 +390,6 @@ DropTrigger(DropTrigStmt *stmt)
 	heap_freetuple(tuple);
 	heap_close(pgrel, RowExclusiveLock);
 
-	/*
-	 * We used to try to update the rel's relcache entry here, but that's
-	 * fairly pointless since it will happen as a byproduct of the
-	 * upcoming CommandCounterIncrement...
-	 */
-
 	/* Keep lock on target rel until end of xact */
 	heap_close(rel, NoLock);
 }
@@ -479,25 +468,12 @@ RelationRemoveTriggers(Relation rel)
 
 	while (HeapTupleIsValid(tup = systable_getnext(tgscan)))
 	{
-		Form_pg_trigger pg_trigger;
-		Relation	refrel;
-		DropTrigStmt *stmt = makeNode(DropTrigStmt);
-
-		pg_trigger = (Form_pg_trigger) GETSTRUCT(tup);
-
-		stmt->trigname = pstrdup(NameStr(pg_trigger->tgname));
-
-		/* May as well grab AccessExclusiveLock, since DropTrigger will. */
-		refrel = heap_open(pg_trigger->tgrelid, AccessExclusiveLock);
-		stmt->relation = makeNode(RangeVar);
-		/* XXX bogus: what about schema? */
-		stmt->relation->relname = pstrdup(RelationGetRelationName(refrel));
-		heap_close(refrel, NoLock);
+		Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(tup);
 
 		elog(NOTICE, "DROP TABLE implicitly drops referential integrity trigger from table \"%s\"",
-			stmt->relation->relname);
+			 get_temp_rel_by_physicalname(get_rel_name(pg_trigger->tgrelid)));
 
-		DropTrigger(stmt);
+		DropTrigger(pg_trigger->tgrelid, NameStr(pg_trigger->tgname));
 
 		/*
 		 * Need to do a command counter increment here to show up new
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index 9436bd645bd..2226a109a85 100644
--- a/src/backend/parser/parse_func.c
+++ b/src/backend/parser/parse_func.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.121 2002/03/29 19:06:11 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.122 2002/03/29 22:10:33 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1227,12 +1227,7 @@ find_inheritors(Oid relid, Oid **supervec)
 		foreach(elt, visited)
 		{
 			/* return the type id, rather than the relation id */
-			Relation	rd;
-
-			relid = lfirsti(elt);
-			rd = heap_open(relid, NoLock);
-			*relidvec++ = rd->rd_rel->reltype;
-			heap_close(rd, NoLock);
+			*relidvec++ = get_rel_type_id((Oid) lfirsti(elt));
 		}
 	}
 	else
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index e383290fa4d..40795016ab9 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.141 2002/03/29 19:06:13 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.142 2002/03/29 22:10:33 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -385,7 +385,6 @@ ProcessUtility(Node *parsetree,
 			{
 				RenameStmt *stmt = (RenameStmt *) parsetree;
 
-				relname = stmt->relation->relname;
 				CheckOwnership(stmt->relation, true);
 
 				/* ----------------
@@ -723,7 +722,12 @@ ProcessUtility(Node *parsetree,
 			break;
 
 		case T_DropTrigStmt:
-			DropTrigger((DropTrigStmt *) parsetree);
+			{
+				DropTrigStmt *stmt = (DropTrigStmt *) parsetree;
+
+				DropTrigger(RangeVarGetRelid(stmt->relation, false),
+							stmt->trigname);
+			}
 			break;
 
 		case T_CreatePLangStmt:
diff --git a/src/include/commands/trigger.h b/src/include/commands/trigger.h
index 34833ea5303..c08a4151e3a 100644
--- a/src/include/commands/trigger.h
+++ b/src/include/commands/trigger.h
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: trigger.h,v 1.32 2001/11/16 16:31:16 tgl Exp $
+ * $Id: trigger.h,v 1.33 2002/03/29 22:10:34 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -96,7 +96,7 @@ typedef struct TriggerData
 
 
 extern void CreateTrigger(CreateTrigStmt *stmt);
-extern void DropTrigger(DropTrigStmt *stmt);
+extern void DropTrigger(Oid relid, const char *trigname);
 extern void RelationRemoveTriggers(Relation rel);
 
 extern void RelationBuildTriggers(Relation relation);
-- 
GitLab