Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2002-04-15 05:22:04 +0000
committerTom Lane2002-04-15 05:22:04 +0000
commit71dc300a375f4932693b064b161a400448c9bc2e (patch)
treeab20c095125a6eab33644befd187f936cf4fd093 /src/backend/commands/rename.c
parentab1ead6b9761531787c78e0c80daf98b421ac06f (diff)
The contents of command.c, creatinh.c, define.c, remove.c and rename.c
have been divided according to the type of object manipulated - so ALTER TABLE code is in tablecmds.c, aggregate commands in aggregatecmds.c and so on. A few common support routines remain in define.c (prototypes in src/include/commands/defrem.h). No code has been changed except for includes to reflect the new files. The prototypes for aggregatecmds.c, functioncmds.c, operatorcmds.c, and typecmds.c remain in src/include/commands/defrem.h. From John Gray <jgray@azuli.co.uk>
Diffstat (limited to 'src/backend/commands/rename.c')
-rw-r--r--src/backend/commands/rename.c591
1 files changed, 0 insertions, 591 deletions
diff --git a/src/backend/commands/rename.c b/src/backend/commands/rename.c
deleted file mode 100644
index 21db59b7f6b..00000000000
--- a/src/backend/commands/rename.c
+++ /dev/null
@@ -1,591 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * rename.c
- * renameatt() and renamerel() reside here.
- *
- * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.70 2002/04/12 20:38:24 tgl Exp $
- *
- *-------------------------------------------------------------------------
- */
-#include "postgres.h"
-
-#include <errno.h>
-
-#include "access/genam.h"
-#include "access/heapam.h"
-#include "access/itup.h"
-#include "catalog/catname.h"
-#include "catalog/pg_index.h"
-#include "catalog/pg_trigger.h"
-#include "catalog/pg_type.h"
-#include "catalog/heap.h"
-#include "catalog/indexing.h"
-#include "catalog/catalog.h"
-#include "commands/rename.h"
-#include "commands/trigger.h"
-#include "miscadmin.h"
-#include "storage/smgr.h"
-#include "optimizer/prep.h"
-#include "rewrite/rewriteDefine.h"
-#include "rewrite/rewriteSupport.h"
-#include "utils/acl.h"
-#include "utils/builtins.h"
-#include "utils/fmgroids.h"
-#include "utils/lsyscache.h"
-#include "utils/relcache.h"
-#include "utils/syscache.h"
-
-
-#define RI_TRIGGER_PK 1 /* is a trigger on the PK relation */
-#define RI_TRIGGER_FK 2 /* is a trigger on the FK relation */
-#define RI_TRIGGER_NONE 0 /* is not an RI trigger function */
-
-static int ri_trigger_type(Oid tgfoid);
-static void update_ri_trigger_args(Oid relid,
- const char *oldname,
- const char *newname,
- bool fk_scan,
- bool update_relname);
-
-
-/*
- * renameatt - changes the name of a attribute in a relation
- *
- * Attname attribute is changed in attribute catalog.
- * No record of the previous attname is kept (correct?).
- *
- * get proper relrelation from relation catalog (if not arg)
- * scan attribute catalog
- * for name conflict (within rel)
- * for original attribute (if not arg)
- * modify attname in attribute tuple
- * insert modified attribute in attribute catalog
- * delete original attribute from attribute catalog
- */
-void
-renameatt(Oid relid,
- const char *oldattname,
- const char *newattname,
- bool recurse)
-{
- Relation targetrelation;
- Relation attrelation;
- HeapTuple atttup;
- List *indexoidlist;
- List *indexoidscan;
-
- /*
- * Grab an exclusive lock on the target table, which we will NOT
- * release until end of transaction.
- */
- targetrelation = heap_open(relid, AccessExclusiveLock);
-
- /*
- * permissions checking. this would normally be done in utility.c,
- * but this particular routine is recursive.
- *
- * normally, only the owner of a class can change its schema.
- */
- if (!allowSystemTableMods
- && IsSystemRelation(targetrelation))
- elog(ERROR, "renameatt: class \"%s\" is a system catalog",
- RelationGetRelationName(targetrelation));
- if (!pg_class_ownercheck(relid, GetUserId()))
- elog(ERROR, "renameatt: you do not own class \"%s\"",
- RelationGetRelationName(targetrelation));
-
- /*
- * if the 'recurse' flag is set then we are supposed to rename this
- * attribute in all classes that inherit from 'relname' (as well as in
- * 'relname').
- *
- * any permissions or problems with duplicate attributes will cause the
- * whole transaction to abort, which is what we want -- all or
- * nothing.
- */
- if (recurse)
- {
- List *child,
- *children;
-
- /* this routine is actually in the planner */
- children = find_all_inheritors(relid);
-
- /*
- * find_all_inheritors does the recursive search of the
- * inheritance hierarchy, so all we have to do is process all of
- * the relids in the list that it returns.
- */
- foreach(child, children)
- {
- Oid childrelid = lfirsti(child);
-
- if (childrelid == relid)
- continue;
- /* note we need not recurse again! */
- renameatt(childrelid, oldattname, newattname, false);
- }
- }
-
- attrelation = heap_openr(AttributeRelationName, RowExclusiveLock);
-
- atttup = SearchSysCacheCopy(ATTNAME,
- ObjectIdGetDatum(relid),
- PointerGetDatum(oldattname),
- 0, 0);
- if (!HeapTupleIsValid(atttup))
- elog(ERROR, "renameatt: attribute \"%s\" does not exist", oldattname);
-
- if (((Form_pg_attribute) GETSTRUCT(atttup))->attnum < 0)
- elog(ERROR, "renameatt: system attribute \"%s\" not renamed", oldattname);
-
- /* should not already exist */
- if (SearchSysCacheExists(ATTNAME,
- ObjectIdGetDatum(relid),
- PointerGetDatum(newattname),
- 0, 0))
- elog(ERROR, "renameatt: attribute \"%s\" exists", newattname);
-
- StrNCpy(NameStr(((Form_pg_attribute) GETSTRUCT(atttup))->attname),
- newattname, NAMEDATALEN);
-
- simple_heap_update(attrelation, &atttup->t_self, atttup);
-
- /* keep system catalog indices current */
- {
- Relation irelations[Num_pg_attr_indices];
-
- CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, irelations);
- CatalogIndexInsert(irelations, Num_pg_attr_indices, attrelation, atttup);
- CatalogCloseIndices(Num_pg_attr_indices, irelations);
- }
-
- heap_freetuple(atttup);
-
- /*
- * Update column names of indexes that refer to the column being
- * renamed.
- */
- indexoidlist = RelationGetIndexList(targetrelation);
-
- foreach(indexoidscan, indexoidlist)
- {
- Oid indexoid = lfirsti(indexoidscan);
- HeapTuple indextup;
-
- /*
- * First check to see if index is a functional index. If so, its
- * column name is a function name and shouldn't be renamed here.
- */
- indextup = SearchSysCache(INDEXRELID,
- ObjectIdGetDatum(indexoid),
- 0, 0, 0);
- if (!HeapTupleIsValid(indextup))
- elog(ERROR, "renameatt: can't find index id %u", indexoid);
- if (OidIsValid(((Form_pg_index) GETSTRUCT(indextup))->indproc))
- {
- ReleaseSysCache(indextup);
- continue;
- }
- ReleaseSysCache(indextup);
-
- /*
- * Okay, look to see if any column name of the index matches the
- * old attribute name.
- */
- atttup = SearchSysCacheCopy(ATTNAME,
- ObjectIdGetDatum(indexoid),
- PointerGetDatum(oldattname),
- 0, 0);
- if (!HeapTupleIsValid(atttup))
- continue; /* Nope, so ignore it */
-
- /*
- * Update the (copied) attribute tuple.
- */
- StrNCpy(NameStr(((Form_pg_attribute) GETSTRUCT(atttup))->attname),
- newattname, NAMEDATALEN);
-
- simple_heap_update(attrelation, &atttup->t_self, atttup);
-
- /* keep system catalog indices current */
- {
- Relation irelations[Num_pg_attr_indices];
-
- CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, irelations);
- CatalogIndexInsert(irelations, Num_pg_attr_indices, attrelation, atttup);
- CatalogCloseIndices(Num_pg_attr_indices, irelations);
- }
- heap_freetuple(atttup);
- }
-
- freeList(indexoidlist);
-
- heap_close(attrelation, RowExclusiveLock);
-
- /*
- * Update att name in any RI triggers associated with the relation.
- */
- if (targetrelation->rd_rel->reltriggers > 0)
- {
- /* update tgargs column reference where att is primary key */
- update_ri_trigger_args(RelationGetRelid(targetrelation),
- oldattname, newattname,
- false, false);
- /* update tgargs column reference where att is foreign key */
- update_ri_trigger_args(RelationGetRelid(targetrelation),
- oldattname, newattname,
- true, false);
- }
-
- heap_close(targetrelation, NoLock); /* close rel but keep lock! */
-}
-
-/*
- * renamerel - change the name of a relation
- *
- * XXX - When renaming sequences, we don't bother to modify the
- * sequence name that is stored within the sequence itself
- * (this would cause problems with MVCC). In the future,
- * the sequence name should probably be removed from the
- * sequence, AFAIK there's no need for it to be there.
- */
-void
-renamerel(Oid relid, const char *newrelname)
-{
- Relation targetrelation;
- Relation relrelation; /* for RELATION relation */
- HeapTuple reltup;
- Oid namespaceId;
- char relkind;
- bool relhastriggers;
- Relation irelations[Num_pg_class_indices];
-
- /*
- * Grab an exclusive lock on the target table or index, which we will
- * NOT release until end of transaction.
- */
- targetrelation = relation_open(relid, AccessExclusiveLock);
-
- namespaceId = RelationGetNamespace(targetrelation);
-
- /* Validity checks */
- if (!allowSystemTableMods &&
- IsSystemRelation(targetrelation))
- elog(ERROR, "renamerel: system relation \"%s\" may not be renamed",
- RelationGetRelationName(targetrelation));
-
- relkind = targetrelation->rd_rel->relkind;
- relhastriggers = (targetrelation->rd_rel->reltriggers > 0);
-
- /*
- * Find relation's pg_class tuple, and make sure newrelname isn't in
- * use.
- */
- relrelation = heap_openr(RelationRelationName, RowExclusiveLock);
-
- reltup = SearchSysCacheCopy(RELOID,
- PointerGetDatum(relid),
- 0, 0, 0);
- if (!HeapTupleIsValid(reltup))
- elog(ERROR, "renamerel: relation \"%s\" does not exist",
- RelationGetRelationName(targetrelation));
-
- if (get_relname_relid(newrelname, namespaceId) != InvalidOid)
- elog(ERROR, "renamerel: relation \"%s\" exists", newrelname);
-
- /*
- * Update pg_class tuple with new relname. (Scribbling on reltup is
- * OK because it's a copy...)
- */
- StrNCpy(NameStr(((Form_pg_class) GETSTRUCT(reltup))->relname),
- newrelname, NAMEDATALEN);
-
- simple_heap_update(relrelation, &reltup->t_self, reltup);
-
- /* keep the system catalog indices current */
- CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, irelations);
- CatalogIndexInsert(irelations, Num_pg_class_indices, relrelation, reltup);
- CatalogCloseIndices(Num_pg_class_indices, irelations);
-
- heap_close(relrelation, NoLock);
- heap_freetuple(reltup);
-
- /*
- * Also rename the associated type, if any.
- */
- if (relkind != RELKIND_INDEX)
- TypeRename(RelationGetRelationName(targetrelation), namespaceId,
- newrelname);
-
- /*
- * If it's a view, must also rename the associated ON SELECT rule.
- */
- if (relkind == RELKIND_VIEW)
- {
- char *oldrulename,
- *newrulename;
-
- oldrulename = MakeRetrieveViewRuleName(RelationGetRelationName(targetrelation));
- newrulename = MakeRetrieveViewRuleName(newrelname);
- RenameRewriteRule(oldrulename, newrulename);
- }
-
- /*
- * Update rel name in any RI triggers associated with the relation.
- */
- if (relhastriggers)
- {
- /* update tgargs where relname is primary key */
- update_ri_trigger_args(relid,
- RelationGetRelationName(targetrelation),
- newrelname,
- false, true);
- /* update tgargs where relname is foreign key */
- update_ri_trigger_args(relid,
- RelationGetRelationName(targetrelation),
- newrelname,
- true, true);
- }
-
- /*
- * Close rel, but keep exclusive lock!
- */
- relation_close(targetrelation, NoLock);
-}
-
-/*
- * Given a trigger function OID, determine whether it is an RI trigger,
- * and if so whether it is attached to PK or FK relation.
- *
- * XXX this probably doesn't belong here; should be exported by
- * ri_triggers.c
- */
-static int
-ri_trigger_type(Oid tgfoid)
-{
- switch (tgfoid)
- {
- case F_RI_FKEY_CASCADE_DEL:
- case F_RI_FKEY_CASCADE_UPD:
- case F_RI_FKEY_RESTRICT_DEL:
- case F_RI_FKEY_RESTRICT_UPD:
- case F_RI_FKEY_SETNULL_DEL:
- case F_RI_FKEY_SETNULL_UPD:
- case F_RI_FKEY_SETDEFAULT_DEL:
- case F_RI_FKEY_SETDEFAULT_UPD:
- case F_RI_FKEY_NOACTION_DEL:
- case F_RI_FKEY_NOACTION_UPD:
- return RI_TRIGGER_PK;
-
- case F_RI_FKEY_CHECK_INS:
- case F_RI_FKEY_CHECK_UPD:
- return RI_TRIGGER_FK;
- }
-
- return RI_TRIGGER_NONE;
-}
-
-/*
- * Scan pg_trigger for RI triggers that are on the specified relation
- * (if fk_scan is false) or have it as the tgconstrrel (if fk_scan
- * is true). Update RI trigger args fields matching oldname to contain
- * newname instead. If update_relname is true, examine the relname
- * fields; otherwise examine the attname fields.
- */
-static void
-update_ri_trigger_args(Oid relid,
- const char *oldname,
- const char *newname,
- bool fk_scan,
- bool update_relname)
-{
- Relation tgrel;
- Relation irel;
- ScanKeyData skey[1];
- IndexScanDesc idxtgscan;
- RetrieveIndexResult idxres;
- Datum values[Natts_pg_trigger];
- char nulls[Natts_pg_trigger];
- char replaces[Natts_pg_trigger];
-
- tgrel = heap_openr(TriggerRelationName, RowExclusiveLock);
- if (fk_scan)
- irel = index_openr(TriggerConstrRelidIndex);
- else
- irel = index_openr(TriggerRelidIndex);
-
- ScanKeyEntryInitialize(&skey[0], 0x0,
- 1, /* always column 1 of index */
- F_OIDEQ,
- ObjectIdGetDatum(relid));
- idxtgscan = index_beginscan(irel, false, 1, skey);
-
- while ((idxres = index_getnext(idxtgscan, ForwardScanDirection)) != NULL)
- {
- HeapTupleData tupledata;
- Buffer buffer;
- HeapTuple tuple;
- Form_pg_trigger pg_trigger;
- bytea *val;
- bytea *newtgargs;
- bool isnull;
- int tg_type;
- bool examine_pk;
- bool changed;
- int tgnargs;
- int i;
- int newlen;
- const char *arga[RI_MAX_ARGUMENTS];
- const char *argp;
-
- tupledata.t_self = idxres->heap_iptr;
- heap_fetch(tgrel, SnapshotNow, &tupledata, &buffer, idxtgscan);
- pfree(idxres);
- if (!tupledata.t_data)
- continue;
- tuple = &tupledata;
- pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);
- tg_type = ri_trigger_type(pg_trigger->tgfoid);
- if (tg_type == RI_TRIGGER_NONE)
- {
- /* Not an RI trigger, forget it */
- ReleaseBuffer(buffer);
- continue;
- }
-
- /*
- * It is an RI trigger, so parse the tgargs bytea.
- *
- * NB: we assume the field will never be compressed or moved out of
- * line; so does trigger.c ...
- */
- tgnargs = pg_trigger->tgnargs;
- val = (bytea *) fastgetattr(tuple,
- Anum_pg_trigger_tgargs,
- tgrel->rd_att, &isnull);
- if (isnull || tgnargs < RI_FIRST_ATTNAME_ARGNO ||
- tgnargs > RI_MAX_ARGUMENTS)
- {
- /* This probably shouldn't happen, but ignore busted triggers */
- ReleaseBuffer(buffer);
- continue;
- }
- argp = (const char *) VARDATA(val);
- for (i = 0; i < tgnargs; i++)
- {
- arga[i] = argp;
- argp += strlen(argp) + 1;
- }
-
- /*
- * Figure out which item(s) to look at. If the trigger is
- * primary-key type and attached to my rel, I should look at the
- * PK fields; if it is foreign-key type and attached to my rel, I
- * should look at the FK fields. But the opposite rule holds when
- * examining triggers found by tgconstrrel search.
- */
- examine_pk = (tg_type == RI_TRIGGER_PK) == (!fk_scan);
-
- changed = false;
- if (update_relname)
- {
- /* Change the relname if needed */
- i = examine_pk ? RI_PK_RELNAME_ARGNO : RI_FK_RELNAME_ARGNO;
- if (strcmp(arga[i], oldname) == 0)
- {
- arga[i] = newname;
- changed = true;
- }
- }
- else
- {
- /* Change attname(s) if needed */
- i = examine_pk ? RI_FIRST_ATTNAME_ARGNO + RI_KEYPAIR_PK_IDX :
- RI_FIRST_ATTNAME_ARGNO + RI_KEYPAIR_FK_IDX;
- for (; i < tgnargs; i += 2)
- {
- if (strcmp(arga[i], oldname) == 0)
- {
- arga[i] = newname;
- changed = true;
- }
- }
- }
-
- if (!changed)
- {
- /* Don't need to update this tuple */
- ReleaseBuffer(buffer);
- continue;
- }
-
- /*
- * Construct modified tgargs bytea.
- */
- newlen = VARHDRSZ;
- for (i = 0; i < tgnargs; i++)
- newlen += strlen(arga[i]) + 1;
- newtgargs = (bytea *) palloc(newlen);
- VARATT_SIZEP(newtgargs) = newlen;
- newlen = VARHDRSZ;
- for (i = 0; i < tgnargs; i++)
- {
- strcpy(((char *) newtgargs) + newlen, arga[i]);
- newlen += strlen(arga[i]) + 1;
- }
-
- /*
- * Build modified tuple.
- */
- for (i = 0; i < Natts_pg_trigger; i++)
- {
- values[i] = (Datum) 0;
- replaces[i] = ' ';
- nulls[i] = ' ';
- }
- values[Anum_pg_trigger_tgargs - 1] = PointerGetDatum(newtgargs);
- replaces[Anum_pg_trigger_tgargs - 1] = 'r';
-
- tuple = heap_modifytuple(tuple, tgrel, values, nulls, replaces);
-
- /*
- * Now we can release hold on original tuple.
- */
- ReleaseBuffer(buffer);
-
- /*
- * Update pg_trigger and its indexes
- */
- simple_heap_update(tgrel, &tuple->t_self, tuple);
-
- {
- Relation irelations[Num_pg_attr_indices];
-
- CatalogOpenIndices(Num_pg_trigger_indices, Name_pg_trigger_indices, irelations);
- CatalogIndexInsert(irelations, Num_pg_trigger_indices, tgrel, tuple);
- CatalogCloseIndices(Num_pg_trigger_indices, irelations);
- }
-
- /* free up our scratch memory */
- pfree(newtgargs);
- heap_freetuple(tuple);
- }
-
- index_endscan(idxtgscan);
- index_close(irel);
-
- heap_close(tgrel, RowExclusiveLock);
-
- /*
- * Increment cmd counter to make updates visible; this is needed in
- * case the same tuple has to be updated again by next pass (can
- * happen in case of a self-referential FK relationship).
- */
- CommandCounterIncrement();
-}