1 /*-------------------------------------------------------------------------
4 * POSTGRES remove (function | type | operator ) utilty code.
6 * Copyright (c) 1994, Regents of the University of California
10 * $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.41 1999/12/10 03:55:49 momjian Exp $
12 *-------------------------------------------------------------------------
16 #include "access/heapam.h"
17 #include "catalog/catname.h"
18 #include "catalog/pg_language.h"
19 #include "catalog/pg_proc.h"
20 #include "catalog/pg_type.h"
21 #include "commands/comment.h"
22 #include "commands/defrem.h"
23 #include "miscadmin.h"
24 #include "parser/parse_func.h"
25 #include "utils/acl.h"
26 #include "utils/syscache.h"
31 * Deletes an operator.
34 * BadArg if name is invalid.
35 * BadArg if type1 is invalid.
36 * "WARN" if operator nonexistent.
40 RemoveOperator(char *operatorName, /* operator name */
41 char *typeName1, /* first type name */
42 char *typeName2) /* optional second type name */
46 Oid typeId1 = InvalidOid;
47 Oid typeId2 = InvalidOid;
54 typeId1 = TypeGet(typeName1, &defined);
55 if (!OidIsValid(typeId1))
57 elog(ERROR, "RemoveOperator: type '%s' does not exist", typeName1);
64 typeId2 = TypeGet(typeName2, &defined);
65 if (!OidIsValid(typeId2))
67 elog(ERROR, "RemoveOperator: type '%s' does not exist", typeName2);
72 if (OidIsValid(typeId1) && OidIsValid(typeId2))
74 else if (OidIsValid(typeId1))
79 relation = heap_openr(OperatorRelationName, RowExclusiveLock);
81 tup = SearchSysCacheTupleCopy(OPERNAME,
82 PointerGetDatum(operatorName),
83 ObjectIdGetDatum(typeId1),
84 ObjectIdGetDatum(typeId2),
85 CharGetDatum(oprtype));
87 if (HeapTupleIsValid(tup))
90 userName = GetPgUserName();
91 if (!pg_ownercheck(userName,
92 (char *) ObjectIdGetDatum(tup->t_data->t_oid),
94 elog(ERROR, "RemoveOperator: operator '%s': permission denied",
99 /*** Delete any comments associated with this operator ***/
101 DeleteComments(tup->t_data->t_oid);
103 heap_delete(relation, &tup->t_self, NULL);
108 if (OidIsValid(typeId1) && OidIsValid(typeId2))
110 elog(ERROR, "RemoveOperator: binary operator '%s' taking '%s' and '%s' does not exist",
115 else if (OidIsValid(typeId1))
117 elog(ERROR, "RemoveOperator: right unary operator '%s' taking '%s' does not exist",
123 elog(ERROR, "RemoveOperator: left unary operator '%s' taking '%s' does not exist",
129 heap_close(relation, RowExclusiveLock);
134 * this stuff is to support removing all reference to a type
135 * don't use it - pma 2/1/94
138 * SingleOpOperatorRemove
139 * Removes all operators that have operands or a result of type 'typeOid'.
142 SingleOpOperatorRemove(Oid typeOid)
148 static attnums[3] = {7, 8, 9}; /* left, right, return */
151 ScanKeyEntryInitialize(&key[0],
152 0, 0, F_OIDEQ, (Datum) typeOid);
153 rel = heap_openr(OperatorRelationName, RowExclusiveLock);
154 for (i = 0; i < 3; ++i)
156 key[0].sk_attno = attnums[i];
157 scan = heap_beginscan(rel, 0, SnapshotNow, 1, key);
158 while (HeapTupleIsValid(tup = heap_getnext(scan, 0))) {
160 /*** This is apparently a routine not in use, but remove ***/
161 /*** any comments anyways ***/
163 DeleteComments(tup->t_data->t_oid);
165 heap_delete(rel, &tup->t_self, NULL);
171 heap_close(rel, RowExclusiveLock);
175 * AttributeAndRelationRemove
176 * Removes all entries in the attribute and relation relations
177 * that contain entries of type 'typeOid'.
178 * Currently nothing calls this code, it is untested.
181 AttributeAndRelationRemove(Oid typeOid)
186 struct oidlist *next;
188 struct oidlist *oidptr,
196 * Get the oid's of the relations to be removed by scanning the entire
197 * attribute relation. We don't need to remove the attributes here,
198 * because amdestroy will remove all attributes of the relation. XXX
199 * should check for duplicate relations
202 ScanKeyEntryInitialize(&key[0],
203 0, 3, F_OIDEQ, (Datum) typeOid);
205 oidptr = (struct oidlist *) palloc(sizeof(*oidptr));
208 rel = heap_openr(AttributeRelationName, AccessShareLock);
209 scan = heap_beginscan(rel, 0, SnapshotNow, 1, key);
210 while (HeapTupleIsValid(tup = heap_getnext(scan, 0)))
212 optr->reloid = ((Form_pg_attribute) GETSTRUCT(tup))->attrelid;
213 optr->next = (struct oidlist *) palloc(sizeof(*oidptr));
218 heap_close(rel, AccessShareLock);
222 ScanKeyEntryInitialize(&key[0], 0,
223 ObjectIdAttributeNumber,
225 /* get RowExclusiveLock because heap_destroy will need it */
226 rel = heap_openr(RelationRelationName, RowExclusiveLock);
227 while (PointerIsValid((char *) optr->next))
229 key[0].sk_argument = (Datum) (optr++)->reloid;
230 scan = heap_beginscan(rel, 0, SnapshotNow, 1, key);
231 tup = heap_getnext(scan, 0);
232 if (HeapTupleIsValid(tup))
236 name = NameStr(((Form_pg_class) GETSTRUCT(tup))->relname);
237 heap_drop_with_catalog(name);
241 heap_close(rel, RowExclusiveLock);
248 * Removes the type 'typeName' and all attributes and relations that
252 RemoveType(char *typeName) /* type name to be removed */
261 userName = GetPgUserName();
262 if (!pg_ownercheck(userName, typeName, TYPENAME))
263 elog(ERROR, "RemoveType: type '%s': permission denied",
267 relation = heap_openr(TypeRelationName, RowExclusiveLock);
269 tup = SearchSysCacheTuple(TYPENAME,
270 PointerGetDatum(typeName),
272 if (!HeapTupleIsValid(tup))
274 heap_close(relation, RowExclusiveLock);
275 elog(ERROR, "RemoveType: type '%s' does not exist", typeName);
278 typeOid = tup->t_data->t_oid;
280 /*** Delete any comments associated with this type ***/
282 DeleteComments(typeOid);
284 heap_delete(relation, &tup->t_self, NULL);
286 /* Now, Delete the "array of" that type */
287 shadow_type = makeArrayTypeName(typeName);
288 tup = SearchSysCacheTuple(TYPENAME,
289 PointerGetDatum(shadow_type),
291 if (!HeapTupleIsValid(tup))
293 heap_close(relation, RowExclusiveLock);
294 elog(ERROR, "RemoveType: type '%s' does not exist", shadow_type);
297 heap_delete(relation, &tup->t_self, NULL);
299 heap_close(relation, RowExclusiveLock);
304 * Deletes a function.
307 * BadArg if name is invalid.
308 * "WARN" if function nonexistent.
312 RemoveFunction(char *functionName, /* function name to be removed */
314 List *argNameList /* list of TypeNames */ )
324 MemSet(argList, 0, 8 * sizeof(Oid));
325 for (i = 0; i < nargs; i++)
327 typename = strVal(lfirst(argNameList));
328 argNameList = lnext(argNameList);
330 if (strcmp(typename, "opaque") == 0)
334 tup = SearchSysCacheTuple(TYPENAME,
335 PointerGetDatum(typename),
338 if (!HeapTupleIsValid(tup))
339 elog(ERROR, "RemoveFunction: type '%s' not found", typename);
340 argList[i] = tup->t_data->t_oid;
345 userName = GetPgUserName();
346 if (!pg_func_ownercheck(userName, functionName, nargs, argList))
348 elog(ERROR, "RemoveFunction: function '%s': permission denied",
353 relation = heap_openr(ProcedureRelationName, RowExclusiveLock);
354 tup = SearchSysCacheTuple(PROCNAME,
355 PointerGetDatum(functionName),
356 Int32GetDatum(nargs),
357 PointerGetDatum(argList),
360 if (!HeapTupleIsValid(tup))
362 heap_close(relation, RowExclusiveLock);
363 func_error("RemoveFunction", functionName, nargs, argList, NULL);
366 if ((((Form_pg_proc) GETSTRUCT(tup))->prolang) == INTERNALlanguageId)
368 heap_close(relation, RowExclusiveLock);
369 elog(ERROR, "RemoveFunction: function \"%s\" is built-in", functionName);
372 /*** Delete any comments associated with this function ***/
374 DeleteComments(tup->t_data->t_oid);
376 heap_delete(relation, &tup->t_self, NULL);
378 heap_close(relation, RowExclusiveLock);
382 RemoveAggregate(char *aggName, char *aggType)
387 Oid basetypeID = InvalidOid;
392 * if a basetype is passed in, then attempt to find an aggregate for
393 * that specific type.
395 * else if the basetype is blank, then attempt to find an aggregate with
396 * a basetype of zero. This is valid. It means that the aggregate is
397 * to apply to all basetypes. ie, a counter of some sort.
403 basetypeID = TypeGet(aggType, &defined);
404 if (!OidIsValid(basetypeID))
405 elog(ERROR, "RemoveAggregate: type '%s' does not exist", aggType);
411 userName = GetPgUserName();
412 if (!pg_aggr_ownercheck(userName, aggName, basetypeID))
416 elog(ERROR, "RemoveAggregate: aggregate '%s' on type '%s': permission denied",
421 elog(ERROR, "RemoveAggregate: aggregate '%s': permission denied",
427 relation = heap_openr(AggregateRelationName, RowExclusiveLock);
428 tup = SearchSysCacheTuple(AGGNAME,
429 PointerGetDatum(aggName),
430 ObjectIdGetDatum(basetypeID),
433 if (!HeapTupleIsValid(tup))
435 heap_close(relation, RowExclusiveLock);
438 elog(ERROR, "RemoveAggregate: aggregate '%s' for '%s' does not exist",
443 elog(ERROR, "RemoveAggregate: aggregate '%s' for all types does not exist",
448 /*** Remove any comments related to this aggregate ***/
450 DeleteComments(tup->t_data->t_oid);
452 heap_delete(relation, &tup->t_self, NULL);
454 heap_close(relation, RowExclusiveLock);