Mop-up some infelicities in new relation lookup handling.
This commit is contained in:
parent
ea13a3fab2
commit
d67442ccfd
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user