From d67442ccfd654f0f021ec4499804d681706dfc4e Mon Sep 17 00:00:00 2001 From: Tom Lane 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 e36a1450db..2e70fb67cd 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 151577ae2d..0d0cbbe788 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 1cf84f17a3..f85814cc0f 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 931ddeae7b..36229b158e 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 9436bd645b..2226a109a8 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 e383290fa4..40795016ab 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 34833ea530..c08a4151e3 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);