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

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * remove.c
  4.  *   POSTGRES remove (function | type | operator ) utilty code.
  5.  *
  6.  * Copyright (c) 1994, Regents of the University of California
  7.  *
  8.  *
  9.  * IDENTIFICATION
  10.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/commands/remove.c,v 1.33.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 "catalog/pg_language.h"
  18. #include "catalog/pg_proc.h"
  19. #include "catalog/pg_type.h"
  20. #include "commands/defrem.h"
  21. #include "miscadmin.h"
  22. #include "parser/parse_func.h"
  23. #include "utils/acl.h"
  24. #include "utils/syscache.h"
  25. /*
  26.  * RemoveOperator
  27.  * Deletes an operator.
  28.  *
  29.  * Exceptions:
  30.  * BadArg if name is invalid.
  31.  * BadArg if type1 is invalid.
  32.  * "WARN" if operator nonexistent.
  33.  * ...
  34.  */
  35. void
  36. RemoveOperator(char *operatorName, /* operator name */
  37.    char *typeName1, /* first type name */
  38.    char *typeName2) /* optional second type name */
  39. {
  40. Relation relation;
  41. HeapTuple tup;
  42. Oid typeId1 = InvalidOid;
  43. Oid typeId2 = InvalidOid;
  44. bool defined;
  45. char    *userName;
  46. char oprtype;
  47. if (typeName1)
  48. {
  49. typeId1 = TypeGet(typeName1, &defined);
  50. if (!OidIsValid(typeId1))
  51. {
  52. elog(ERROR, "RemoveOperator: type '%s' does not exist", typeName1);
  53. return;
  54. }
  55. }
  56. if (typeName2)
  57. {
  58. typeId2 = TypeGet(typeName2, &defined);
  59. if (!OidIsValid(typeId2))
  60. {
  61. elog(ERROR, "RemoveOperator: type '%s' does not exist", typeName2);
  62. return;
  63. }
  64. }
  65. if (OidIsValid(typeId1) && OidIsValid(typeId2))
  66. oprtype = 'b';
  67. else if (OidIsValid(typeId1))
  68. oprtype = 'l';
  69. else
  70. oprtype = 'r';
  71. tup = SearchSysCacheTupleCopy(OPRNAME,
  72.   PointerGetDatum(operatorName),
  73.   ObjectIdGetDatum(typeId1),
  74.   ObjectIdGetDatum(typeId2),
  75.   CharGetDatum(oprtype));
  76. relation = heap_openr(OperatorRelationName);
  77. if (HeapTupleIsValid(tup))
  78. {
  79. #ifndef NO_SECURITY
  80. userName = GetPgUserName();
  81. if (!pg_ownercheck(userName,
  82.    (char *) ObjectIdGetDatum(tup->t_data->t_oid),
  83.    OPROID))
  84. elog(ERROR, "RemoveOperator: operator '%s': permission denied",
  85.  operatorName);
  86. #endif
  87. heap_delete(relation, &tup->t_self, NULL);
  88. }
  89. else
  90. {
  91. if (OidIsValid(typeId1) && OidIsValid(typeId2))
  92. {
  93. elog(ERROR, "RemoveOperator: binary operator '%s' taking '%s' and '%s' does not exist",
  94.  operatorName,
  95.  typeName1,
  96.  typeName2);
  97. }
  98. else if (OidIsValid(typeId1))
  99. {
  100. elog(ERROR, "RemoveOperator: right unary operator '%s' taking '%s' does not exist",
  101.  operatorName,
  102.  typeName1);
  103. }
  104. else
  105. {
  106. elog(ERROR, "RemoveOperator: left unary operator '%s' taking '%s' does not exist",
  107.  operatorName,
  108.  typeName2);
  109. }
  110. }
  111. pfree(tup);
  112. heap_close(relation);
  113. }
  114. #ifdef NOTYET
  115. /*
  116.  * this stuff is to support removing all reference to a type
  117.  * don't use it  - pma 2/1/94
  118.  */
  119. /*
  120.  * SingleOpOperatorRemove
  121.  * Removes all operators that have operands or a result of type 'typeOid'.
  122.  */
  123. static void
  124. SingleOpOperatorRemove(Oid typeOid)
  125. {
  126. Relation rel;
  127. ScanKeyData key[3];
  128. HeapScanDesc scan;
  129. HeapTuple tup;
  130. static attnums[3] = {7, 8, 9}; /* left, right, return */
  131. int i;
  132. ScanKeyEntryInitialize(&key[0],
  133.    0, 0, F_OIDEQ, (Datum) typeOid);
  134. rel = heap_openr(OperatorRelationName);
  135. for (i = 0; i < 3; ++i)
  136. {
  137. key[0].sk_attno = attnums[i];
  138. scan = heap_beginscan(rel, 0, SnapshotNow, 1, key);
  139. while (HeapTupleIsValid(tup = heap_getnext(scan, 0)))
  140. heap_delete(rel, &tup->t_self, NULL);
  141. heap_endscan(scan);
  142. }
  143. heap_close(rel);
  144. }
  145. /*
  146.  * AttributeAndRelationRemove
  147.  * Removes all entries in the attribute and relation relations
  148.  * that contain entries of type 'typeOid'.
  149.  * Currently nothing calls this code, it is untested.
  150.  */
  151. static void
  152. AttributeAndRelationRemove(Oid typeOid)
  153. {
  154. struct oidlist
  155. {
  156. Oid reloid;
  157. struct oidlist *next;
  158. };
  159. struct oidlist *oidptr,
  160.    *optr;
  161. Relation rel;
  162. ScanKeyData key[1];
  163. HeapScanDesc scan;
  164. HeapTuple tup;
  165. /*
  166.  * Get the oid's of the relations to be removed by scanning the entire
  167.  * attribute relation. We don't need to remove the attributes here,
  168.  * because amdestroy will remove all attributes of the relation. XXX
  169.  * should check for duplicate relations
  170.  */
  171. ScanKeyEntryInitialize(&key[0],
  172.    0, 3, F_OIDEQ, (Datum) typeOid);
  173. oidptr = (struct oidlist *) palloc(sizeof(*oidptr));
  174. oidptr->next = NULL;
  175. optr = oidptr;
  176. rel = heap_openr(AttributeRelationName);
  177. scan = heap_beginscan(rel, 0, SnapshotNow, 1, key);
  178. while (HeapTupleIsValid(tup = heap_getnext(scan, 0)))
  179. {
  180. optr->reloid = ((Form_pg_attribute) GETSTRUCT(tup))->attrelid;
  181. optr->next = (struct oidlist *) palloc(sizeof(*oidptr));
  182. optr = optr->next;
  183. }
  184. optr->next = NULL;
  185. heap_endscan(scan);
  186. heap_close(rel);
  187. ScanKeyEntryInitialize(&key[0], 0,
  188.    ObjectIdAttributeNumber,
  189.    F_OIDEQ, (Datum) 0);
  190. optr = oidptr;
  191. rel = heap_openr(RelationRelationName);
  192. while (PointerIsValid((char *) optr->next))
  193. {
  194. key[0].sk_argument = (Datum) (optr++)->reloid;
  195. scan = heap_beginscan(rel, 0, SnapshotNow, 1, key);
  196. tup = heap_getnext(scan, 0);
  197. if (HeapTupleIsValid(tup))
  198. {
  199. char    *name;
  200. name = (((Form_pg_class) GETSTRUCT(tup))->relname).data;
  201. heap_destroy_with_catalog(name);
  202. }
  203. }
  204. heap_endscan(scan);
  205. heap_close(rel);
  206. }
  207. #endif  /* NOTYET */
  208. /*
  209.  * TypeRemove
  210.  * Removes the type 'typeName' and all attributes and relations that
  211.  * use it.
  212.  */
  213. void
  214. RemoveType(char *typeName) /* type name to be removed */
  215. {
  216. Relation relation;
  217. HeapTuple tup;
  218. Oid typeOid;
  219. char    *shadow_type;
  220. char    *userName;
  221. #ifndef NO_SECURITY
  222. userName = GetPgUserName();
  223. if (!pg_ownercheck(userName, typeName, TYPNAME))
  224. elog(ERROR, "RemoveType: type '%s': permission denied",
  225.  typeName);
  226. #endif
  227. relation = heap_openr(TypeRelationName);
  228. tup = SearchSysCacheTuple(TYPNAME,
  229.   PointerGetDatum(typeName),
  230.   0, 0, 0);
  231. if (!HeapTupleIsValid(tup))
  232. {
  233. heap_close(relation);
  234. elog(ERROR, "RemoveType: type '%s' does not exist", typeName);
  235. }
  236. relation = heap_openr(TypeRelationName);
  237. typeOid = tup->t_data->t_oid;
  238. heap_delete(relation, &tup->t_self, NULL);
  239. /* Now, Delete the "array of" that type */
  240. shadow_type = makeArrayTypeName(typeName);
  241. tup = SearchSysCacheTuple(TYPNAME,
  242.   PointerGetDatum(shadow_type),
  243.   0, 0, 0);
  244. if (!HeapTupleIsValid(tup))
  245. {
  246. heap_close(relation);
  247. elog(ERROR, "RemoveType: type '%s' does not exist", typeName);
  248. }
  249. typeOid = tup->t_data->t_oid;
  250. heap_delete(relation, &tup->t_self, NULL);
  251. heap_close(relation);
  252. }
  253. /*
  254.  * RemoveFunction
  255.  * Deletes a function.
  256.  *
  257.  * Exceptions:
  258.  * BadArg if name is invalid.
  259.  * "WARN" if function nonexistent.
  260.  * ...
  261.  */
  262. void
  263. RemoveFunction(char *functionName, /* function name to be removed */
  264.    int nargs,
  265.    List *argNameList /* list of TypeNames */ )
  266. {
  267. Relation relation;
  268. HeapTuple tup;
  269. Oid argList[8];
  270. char    *userName;
  271. char    *typename;
  272. int i;
  273. MemSet(argList, 0, 8 * sizeof(Oid));
  274. for (i = 0; i < nargs; i++)
  275. {
  276. typename = strVal(lfirst(argNameList));
  277. argNameList = lnext(argNameList);
  278. if (strcmp(typename, "opaque") == 0)
  279. argList[i] = 0;
  280. else
  281. {
  282. tup = SearchSysCacheTuple(TYPNAME,
  283.   PointerGetDatum(typename),
  284.   0, 0, 0);
  285. if (!HeapTupleIsValid(tup))
  286. elog(ERROR, "RemoveFunction: type '%s' not found", typename);
  287. argList[i] = tup->t_data->t_oid;
  288. }
  289. }
  290. #ifndef NO_SECURITY
  291. userName = GetPgUserName();
  292. if (!pg_func_ownercheck(userName, functionName, nargs, argList))
  293. {
  294. elog(ERROR, "RemoveFunction: function '%s': permission denied",
  295.  functionName);
  296. }
  297. #endif
  298. relation = heap_openr(ProcedureRelationName);
  299. tup = SearchSysCacheTuple(PRONAME,
  300.   PointerGetDatum(functionName),
  301.   Int32GetDatum(nargs),
  302.   PointerGetDatum(argList),
  303.   0);
  304. if (!HeapTupleIsValid(tup))
  305. {
  306. heap_close(relation);
  307. func_error("RemoveFunction", functionName, nargs, argList, NULL);
  308. }
  309. if ((((Form_pg_proc) GETSTRUCT(tup))->prolang) == INTERNALlanguageId)
  310. {
  311. heap_close(relation);
  312. elog(ERROR, "RemoveFunction: function "%s" is built-in", functionName);
  313. }
  314. heap_delete(relation, &tup->t_self, NULL);
  315. heap_close(relation);
  316. }
  317. void
  318. RemoveAggregate(char *aggName, char *aggType)
  319. {
  320. Relation relation;
  321. HeapTuple tup;
  322. char    *userName;
  323. Oid basetypeID = InvalidOid;
  324. bool defined;
  325. /*
  326.  * if a basetype is passed in, then attempt to find an aggregate for
  327.  * that specific type.
  328.  *
  329.  * else if the basetype is blank, then attempt to find an aggregate with
  330.  * a basetype of zero. This is valid. It means that the aggregate is
  331.  * to apply to all basetypes.  ie, a counter of some sort.
  332.  *
  333.  */
  334. if (aggType)
  335. {
  336. basetypeID = TypeGet(aggType, &defined);
  337. if (!OidIsValid(basetypeID))
  338. elog(ERROR, "RemoveAggregate: type '%s' does not exist", aggType);
  339. }
  340. else
  341. basetypeID = 0;
  342. #ifndef NO_SECURITY
  343. userName = GetPgUserName();
  344. if (!pg_aggr_ownercheck(userName, aggName, basetypeID))
  345. {
  346. if (aggType)
  347. {
  348. elog(ERROR, "RemoveAggregate: aggregate '%s' on type '%s': permission denied",
  349.  aggName, aggType);
  350. }
  351. else
  352. {
  353. elog(ERROR, "RemoveAggregate: aggregate '%s': permission denied",
  354.  aggName);
  355. }
  356. }
  357. #endif
  358. relation = heap_openr(AggregateRelationName);
  359. tup = SearchSysCacheTuple(AGGNAME,
  360.   PointerGetDatum(aggName),
  361.   ObjectIdGetDatum(basetypeID),
  362.   0, 0);
  363. if (!HeapTupleIsValid(tup))
  364. {
  365. heap_close(relation);
  366. if (aggType)
  367. {
  368. elog(ERROR, "RemoveAggregate: aggregate '%s' for '%s' does not exist",
  369.  aggName, aggType);
  370. }
  371. else
  372. {
  373. elog(ERROR, "RemoveAggregate: aggregate '%s' for all types does not exist",
  374.  aggName);
  375. }
  376. }
  377. heap_delete(relation, &tup->t_self, NULL);
  378. heap_close(relation);
  379. }