rename.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:7k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * rename.c
  4.  *   renameatt() and renamerel() reside here.
  5.  *
  6.  * Copyright (c) 1994, Regents of the University of California
  7.  *
  8.  *
  9.  * IDENTIFICATION
  10.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/commands/rename.c,v 1.25.2.1 1999/08/02 05:56:59 scrappy Exp $
  11.  *
  12.  *-------------------------------------------------------------------------
  13.  */
  14. #include "postgres.h"
  15. #include "access/heapam.h"
  16. #include "catalog/catname.h"
  17. #include "utils/syscache.h"
  18. #include "catalog/heap.h"
  19. #include "catalog/indexing.h"
  20. #include "catalog/catalog.h"
  21. #include "commands/rename.h"
  22. #include "miscadmin.h"
  23. #include "optimizer/prep.h"
  24. #include "utils/acl.h"
  25. /*
  26.  * renameatt - changes the name of a attribute in a relation
  27.  *
  28.  * Attname attribute is changed in attribute catalog.
  29.  * No record of the previous attname is kept (correct?).
  30.  *
  31.  * get proper relrelation from relation catalog (if not arg)
  32.  * scan attribute catalog
  33.  * for name conflict (within rel)
  34.  * for original attribute (if not arg)
  35.  * modify attname in attribute tuple
  36.  * insert modified attribute in attribute catalog
  37.  * delete original attribute from attribute catalog
  38.  *
  39.  * XXX Renaming an indexed attribute must (eventually) also change
  40.  * the attribute name in the associated indexes.
  41.  */
  42. void
  43. renameatt(char *relname,
  44.   char *oldattname,
  45.   char *newattname,
  46.   char *userName,
  47.   int recurse)
  48. {
  49. Relation attrelation;
  50. HeapTuple reltup,
  51. oldatttup,
  52. newatttup;
  53. Relation irelations[Num_pg_attr_indices];
  54. Oid relid;
  55. /*
  56.  * permissions checking.  this would normally be done in utility.c,
  57.  * but this particular routine is recursive.
  58.  *
  59.  * normally, only the owner of a class can change its schema.
  60.  */
  61. if (!allowSystemTableMods && IsSystemRelationName(relname))
  62. elog(ERROR, "renameatt: class "%s" is a system catalog",
  63.  relname);
  64. #ifndef NO_SECURITY
  65. if (!IsBootstrapProcessingMode() &&
  66. !pg_ownercheck(userName, relname, RELNAME))
  67. elog(ERROR, "renameatt: you do not own class "%s"",
  68.  relname);
  69. #endif
  70. /*
  71.  * if the 'recurse' flag is set then we are supposed to rename this
  72.  * attribute in all classes that inherit from 'relname' (as well as in
  73.  * 'relname').
  74.  *
  75.  * any permissions or problems with duplicate attributes will cause the
  76.  * whole transaction to abort, which is what we want -- all or
  77.  * nothing.
  78.  */
  79. if (recurse)
  80. {
  81. Oid myrelid,
  82. childrelid;
  83. List    *child,
  84.    *children;
  85. if ((myrelid = RelnameFindRelid(relname)) == InvalidOid)
  86. elog(ERROR, "renameatt: unknown relation: "%s"", relname);
  87. /* this routine is actually in the planner */
  88. children = find_all_inheritors(lconsi(myrelid, NIL), NIL);
  89. /*
  90.  * find_all_inheritors does the recursive search of the
  91.  * inheritance hierarchy, so all we have to do is process all of
  92.  * the relids in the list that it returns.
  93.  */
  94. foreach(child, children)
  95. {
  96. char childname[NAMEDATALEN];
  97. childrelid = lfirsti(child);
  98. if (childrelid == myrelid)
  99. continue;
  100. reltup = SearchSysCacheTuple(RELOID,
  101.  ObjectIdGetDatum(childrelid),
  102.  0, 0, 0);
  103. if (!HeapTupleIsValid(reltup))
  104. {
  105. elog(ERROR, "renameatt: can't find catalog entry for inheriting class with oid %u",
  106.  childrelid);
  107. }
  108. /* make copy of cache value, could disappear in call */
  109. StrNCpy(childname,
  110. ((Form_pg_class) GETSTRUCT(reltup))->relname.data,
  111. NAMEDATALEN);
  112. /* no more recursion! */
  113. renameatt(childname, oldattname, newattname, userName, 0);
  114. }
  115. }
  116. if ((relid = RelnameFindRelid(relname)) == InvalidOid)
  117. elog(ERROR, "renameatt: relation "%s" nonexistent", relname);
  118. oldatttup = SearchSysCacheTupleCopy(ATTNAME,
  119. ObjectIdGetDatum(relid),
  120. PointerGetDatum(oldattname),
  121. 0, 0);
  122. if (!HeapTupleIsValid(oldatttup))
  123. elog(ERROR, "renameatt: attribute "%s" nonexistent", oldattname);
  124. if (((Form_pg_attribute) GETSTRUCT(oldatttup))->attnum < 0)
  125. elog(ERROR, "renameatt: system attribute "%s" not renamed", oldattname);
  126. newatttup = SearchSysCacheTuple(ATTNAME,
  127. ObjectIdGetDatum(relid),
  128. PointerGetDatum(newattname),
  129. 0, 0);
  130. /* should not already exist */
  131. if (HeapTupleIsValid(newatttup))
  132. {
  133. pfree(oldatttup);
  134. elog(ERROR, "renameatt: attribute "%s" exists", newattname);
  135. }
  136. StrNCpy((((Form_pg_attribute) (GETSTRUCT(oldatttup)))->attname.data),
  137. newattname, NAMEDATALEN);
  138. attrelation = heap_openr(AttributeRelationName);
  139. heap_replace(attrelation, &oldatttup->t_self, oldatttup, NULL);
  140. /* keep system catalog indices current */
  141. CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, irelations);
  142. CatalogIndexInsert(irelations, Num_pg_attr_indices, attrelation, oldatttup);
  143. CatalogCloseIndices(Num_pg_attr_indices, irelations);
  144. pfree(oldatttup);
  145. heap_close(attrelation);
  146. }
  147. /*
  148.  * renamerel - change the name of a relation
  149.  *
  150.  * Relname attribute is changed in relation catalog.
  151.  * No record of the previous relname is kept (correct?).
  152.  *
  153.  * scan relation catalog
  154.  * for name conflict
  155.  * for original relation (if not arg)
  156.  * modify relname in relation tuple
  157.  * insert modified relation in relation catalog
  158.  * delete original relation from relation catalog
  159.  *
  160.  * XXX Will currently lose track of a relation if it is unable to
  161.  * properly replace the new relation tuple.
  162.  */
  163. void
  164. renamerel(char *oldrelname, char *newrelname)
  165. {
  166. int i;
  167. Relation relrelation; /* for RELATION relation */
  168. HeapTuple oldreltup;
  169. char oldpath[MAXPGPATH],
  170. newpath[MAXPGPATH],
  171. toldpath[MAXPGPATH + 10],
  172. tnewpath[MAXPGPATH + 10];
  173. Relation irelations[Num_pg_class_indices];
  174. if (!allowSystemTableMods && IsSystemRelationName(oldrelname))
  175. elog(ERROR, "renamerel: system relation "%s" not renamed",
  176.  oldrelname);
  177. if (!allowSystemTableMods && IsSystemRelationName(newrelname))
  178. elog(ERROR, "renamerel: Illegal class name: "%s" -- pg_ is reserved for system catalogs",
  179.  newrelname);
  180. oldreltup = SearchSysCacheTupleCopy(RELNAME,
  181. PointerGetDatum(oldrelname),
  182. 0, 0, 0);
  183. if (!HeapTupleIsValid(oldreltup))
  184. elog(ERROR, "renamerel: relation "%s" does not exist", oldrelname);
  185. if (RelnameFindRelid(newrelname) != InvalidOid)
  186. elog(ERROR, "renamerel: relation "%s" exists", newrelname);
  187. /* rename the path first, so if this fails the rename's not done */
  188. strcpy(oldpath, relpath(oldrelname));
  189. strcpy(newpath, relpath(newrelname));
  190. if (rename(oldpath, newpath) < 0)
  191. elog(ERROR, "renamerel: unable to rename file: %s", oldpath);
  192. for (i = 1;; i++)
  193. {
  194. sprintf(toldpath, "%s.%d", oldpath, i);
  195. sprintf(tnewpath, "%s.%d", newpath, i);
  196. if (rename(toldpath, tnewpath) < 0)
  197. break;
  198. }
  199. StrNCpy((((Form_pg_class) GETSTRUCT(oldreltup))->relname.data),
  200. newrelname, NAMEDATALEN);
  201. /* insert fixed rel tuple */
  202. relrelation = heap_openr(RelationRelationName);
  203. heap_replace(relrelation, &oldreltup->t_self, oldreltup, NULL);
  204. /* keep the system catalog indices current */
  205. CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, irelations);
  206. CatalogIndexInsert(irelations, Num_pg_class_indices, relrelation, oldreltup);
  207. CatalogCloseIndices(Num_pg_class_indices, irelations);
  208. heap_close(relrelation);
  209. }