1 /*-------------------------------------------------------------------------
4 * renameatt() and renamerel() reside here.
6 * Copyright (c) 1994, Regents of the University of California
10 * $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.13 1998/07/26 04:30:24 scrappy Exp $
12 *-------------------------------------------------------------------------
16 #include <access/heapam.h>
17 #include <access/relscan.h>
18 #include <utils/builtins.h>
19 #include <catalog/catname.h>
20 #include <utils/syscache.h>
21 #include <catalog/indexing.h>
22 #include <catalog/catalog.h>
23 #include <commands/copy.h>
24 #include <commands/rename.h>
25 #include <executor/execdefs.h> /* for EXEC_{FOR,BACK,FDEBUG,BDEBUG} */
26 #include <miscadmin.h>
27 #include <utils/portal.h>
28 #include <tcop/dest.h>
29 #include <commands/command.h>
30 #include <utils/excid.h>
31 #include <utils/mcxt.h>
32 #include <catalog/pg_proc.h>
34 #include <catalog/pg_class_mb.h>
36 #include <catalog/pg_class.h>
38 #include <optimizer/internal.h>
39 #include <optimizer/prep.h> /* for find_all_inheritors */
41 #include <utils/acl.h>
42 #endif /* !NO_SECURITY */
44 #include <regex/utils.h>
50 * renameatt - changes the name of a attribute in a relation
52 * Attname attribute is changed in attribute catalog.
53 * No record of the previous attname is kept (correct?).
55 * get proper reldesc from relation catalog (if not arg)
56 * scan attribute catalog
57 * for name conflict (within rel)
58 * for original attribute (if not arg)
59 * modify attname in attribute tuple
60 * insert modified attribute in attribute catalog
61 * delete original attribute from attribute catalog
63 * XXX Renaming an indexed attribute must (eventually) also change
64 * the attribute name in the associated indexes.
67 renameatt(char *relname,
78 ItemPointerData oldTID;
79 Relation idescs[Num_pg_attr_indices];
82 * permissions checking. this would normally be done in utility.c,
83 * but this particular routine is recursive.
85 * normally, only the owner of a class can change its schema.
87 if (IsSystemRelationName(relname))
88 elog(ERROR, "renameatt: class \"%s\" is a system catalog",
91 if (!IsBootstrapProcessingMode() &&
92 !pg_ownercheck(userName, relname, RELNAME))
93 elog(ERROR, "renameatt: you do not own class \"%s\"",
98 * if the 'recurse' flag is set then we are supposed to rename this
99 * attribute in all classes that inherit from 'relname' (as well as in
102 * any permissions or problems with duplicate attributes will cause the
103 * whole transaction to abort, which is what we want -- all or
113 relrdesc = heap_openr(relname);
114 if (!RelationIsValid(relrdesc))
116 elog(ERROR, "renameatt: unknown relation: \"%s\"",
119 myrelid = relrdesc->rd_id;
120 heap_close(relrdesc);
122 /* this routine is actually in the planner */
123 children = find_all_inheritors(lconsi(myrelid, NIL), NIL);
127 * find_all_inheritors does the recursive search of the
128 * inheritance hierarchy, so all we have to do is process all of
129 * the relids in the list that it returns.
131 foreach(child, children)
135 childrelid = lfirsti(child);
136 if (childrelid == myrelid)
138 relrdesc = heap_open(childrelid);
139 if (!RelationIsValid(relrdesc))
141 elog(ERROR, "renameatt: can't find catalog entry for inheriting class with oid %d",
144 childname = (relrdesc->rd_rel->relname).data;
145 heap_close(relrdesc);
146 renameatt(childname, oldattname, newattname,
147 userName, 0); /* no more recursion! */
151 relrdesc = heap_openr(RelationRelationName);
152 reltup = ClassNameIndexScan(relrdesc, relname);
153 if (!PointerIsValid(reltup))
155 heap_close(relrdesc);
156 elog(ERROR, "renameatt: relation \"%s\" nonexistent",
160 heap_close(relrdesc);
162 attrdesc = heap_openr(AttributeRelationName);
163 oldatttup = AttributeNameIndexScan(attrdesc, reltup->t_oid, oldattname);
164 if (!PointerIsValid(oldatttup))
166 heap_close(attrdesc);
167 elog(ERROR, "renameatt: attribute \"%s\" nonexistent",
170 if (((AttributeTupleForm) GETSTRUCT(oldatttup))->attnum < 0)
172 elog(ERROR, "renameatt: system attribute \"%s\" not renamed",
176 newatttup = AttributeNameIndexScan(attrdesc, reltup->t_oid, newattname);
177 if (PointerIsValid(newatttup))
180 heap_close(attrdesc);
181 elog(ERROR, "renameatt: attribute \"%s\" exists",
185 namestrcpy(&(((AttributeTupleForm) (GETSTRUCT(oldatttup)))->attname),
187 oldTID = oldatttup->t_ctid;
189 /* insert "fixed" tuple */
190 heap_replace(attrdesc, &oldTID, oldatttup);
192 /* keep system catalog indices current */
193 CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs);
194 CatalogIndexInsert(idescs, Num_pg_attr_indices, attrdesc, oldatttup);
195 CatalogCloseIndices(Num_pg_attr_indices, idescs);
197 heap_close(attrdesc);
202 * renamerel - change the name of a relation
204 * Relname attribute is changed in relation catalog.
205 * No record of the previous relname is kept (correct?).
207 * scan relation catalog
209 * for original relation (if not arg)
210 * modify relname in relation tuple
211 * insert modified relation in relation catalog
212 * delete original relation from relation catalog
214 * XXX Will currently lose track of a relation if it is unable to
215 * properly replace the new relation tuple.
218 renamerel(char oldrelname[], char newrelname[])
220 Relation relrdesc; /* for RELATION relation */
223 ItemPointerData oldTID;
224 char oldpath[MAXPGPATH],
226 Relation idescs[Num_pg_class_indices];
228 if (IsSystemRelationName(oldrelname))
230 elog(ERROR, "renamerel: system relation \"%s\" not renamed",
234 if (IsSystemRelationName(newrelname))
236 elog(ERROR, "renamerel: Illegal class name: \"%s\" -- pg_ is reserved for system catalogs",
241 relrdesc = heap_openr(RelationRelationName);
242 oldreltup = ClassNameIndexScan(relrdesc, oldrelname);
244 if (!PointerIsValid(oldreltup))
246 heap_close(relrdesc);
247 elog(ERROR, "renamerel: relation \"%s\" does not exist",
251 newreltup = ClassNameIndexScan(relrdesc, newrelname);
252 if (PointerIsValid(newreltup))
255 heap_close(relrdesc);
256 elog(ERROR, "renamerel: relation \"%s\" exists",
260 /* rename the directory first, so if this fails the rename's not done */
261 strcpy(oldpath, relpath(oldrelname));
262 strcpy(newpath, relpath(newrelname));
263 if (rename(oldpath, newpath) < 0)
264 elog(ERROR, "renamerel: unable to rename file: %m");
266 memmove((char *) (((Form_pg_class) GETSTRUCT(oldreltup))->relname.data),
269 oldTID = oldreltup->t_ctid;
271 /* insert fixed rel tuple */
272 heap_replace(relrdesc, &oldTID, oldreltup);
274 /* keep the system catalog indices current */
275 CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
276 CatalogIndexInsert(idescs, Num_pg_class_indices, relrdesc, oldreltup);
277 CatalogCloseIndices(Num_pg_class_indices, idescs);
280 heap_close(relrdesc);