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.7 1996/11/30 18:06:10 momjian Exp $
12 *-------------------------------------------------------------------------
16 #include <utils/acl.h>
17 #include <access/heapam.h>
18 #include <utils/builtins.h>
19 #include <utils/syscache.h>
20 #include <catalog/catname.h>
21 #include <commands/defrem.h>
22 #include <miscadmin.h>
23 #include <catalog/pg_aggregate.h>
24 #include <catalog/pg_language.h>
25 #include <catalog/pg_operator.h>
26 #include <catalog/pg_proc.h>
27 #include <parser/catalog_utils.h>
28 #include <storage/bufmgr.h>
31 # include <regex/utils.h>
38 * Deletes an operator.
41 * BadArg if name is invalid.
42 * BadArg if type1 is invalid.
43 * "WARN" if operator nonexistent.
47 RemoveOperator(char *operatorName, /* operator name */
48 char *typeName1, /* first type name */
49 char *typeName2) /* optional second type name */
54 Oid typeId1 = InvalidOid;
55 Oid typeId2 = InvalidOid;
57 ItemPointerData itemPointerData;
59 ScanKeyData operatorKey[3];
63 typeId1 = TypeGet(typeName1, &defined);
64 if (!OidIsValid(typeId1)) {
65 elog(WARN, "RemoveOperator: type '%s' does not exist", typeName1);
71 typeId2 = TypeGet(typeName2, &defined);
72 if (!OidIsValid(typeId2)) {
73 elog(WARN, "RemoveOperator: type '%s' does not exist", typeName2);
78 ScanKeyEntryInitialize(&operatorKey[0], 0x0,
79 Anum_pg_operator_oprname,
80 NameEqualRegProcedure,
81 PointerGetDatum(operatorName));
83 ScanKeyEntryInitialize(&operatorKey[1], 0x0,
84 Anum_pg_operator_oprleft,
85 ObjectIdEqualRegProcedure,
86 ObjectIdGetDatum(typeId1));
88 ScanKeyEntryInitialize(&operatorKey[2], 0x0,
89 Anum_pg_operator_oprright,
90 ObjectIdEqualRegProcedure,
91 ObjectIdGetDatum(typeId2));
93 relation = heap_openr(OperatorRelationName);
94 scan = heap_beginscan(relation, 0, NowTimeQual, 3, operatorKey);
95 tup = heap_getnext(scan, 0, &buffer);
96 if (HeapTupleIsValid(tup)) {
98 userName = GetPgUserName();
99 if (!pg_ownercheck(userName,
100 (char *) ObjectIdGetDatum(tup->t_oid),
102 elog(WARN, "RemoveOperator: operator '%s': permission denied",
105 ItemPointerCopy(&tup->t_ctid, &itemPointerData);
106 heap_delete(relation, &itemPointerData);
108 if (OidIsValid(typeId1) && OidIsValid(typeId2)) {
109 elog(WARN, "RemoveOperator: binary operator '%s' taking '%s' and '%s' does not exist",
113 } else if (OidIsValid(typeId1)) {
114 elog(WARN, "RemoveOperator: right unary operator '%s' taking '%s' does not exist",
118 elog(WARN, "RemoveOperator: left unary operator '%s' taking '%s' does not exist",
124 heap_close(relation);
129 * this stuff is to support removing all reference to a type
130 * don't use it - pma 2/1/94
133 * SingleOpOperatorRemove
134 * Removes all operators that have operands or a result of type 'typeOid'.
137 SingleOpOperatorRemove(Oid typeOid)
143 ItemPointerData itemPointerData;
145 static attnums[3] = { 7, 8, 9 }; /* left, right, return */
148 ScanKeyEntryInitialize(&key[0],
149 0, 0, ObjectIdEqualRegProcedure, (Datum)typeOid);
150 rdesc = heap_openr(OperatorRelationName);
151 for (i = 0; i < 3; ++i) {
152 key[0].sk_attno = attnums[i];
153 sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 1, key);
154 while (PointerIsValid(tup = heap_getnext(sdesc, 0, &buffer))) {
155 ItemPointerCopy(&tup->t_ctid, &itemPointerData);
156 /* XXX LOCK not being passed */
157 heap_delete(rdesc, &itemPointerData);
165 * AttributeAndRelationRemove
166 * Removes all entries in the attribute and relation relations
167 * that contain entries of type 'typeOid'.
168 * Currently nothing calls this code, it is untested.
171 AttributeAndRelationRemove(Oid typeOid)
175 struct oidlist *next;
177 struct oidlist *oidptr, *optr;
182 ItemPointerData itemPointerData;
186 * Get the oid's of the relations to be removed by scanning the
187 * entire attribute relation.
188 * We don't need to remove the attributes here,
189 * because amdestroy will remove all attributes of the relation.
190 * XXX should check for duplicate relations
193 ScanKeyEntryInitialize(&key[0],
194 0, 3, ObjectIdEqualRegProcedure, (Datum)typeOid);
196 oidptr = (struct oidlist *) palloc(sizeof(*oidptr));
199 rdesc = heap_openr(AttributeRelationName);
200 sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 1, key);
201 while (PointerIsValid(tup = heap_getnext(sdesc, 0, &buffer))) {
202 ItemPointerCopy(&tup->t_ctid, &itemPointerData);
203 optr->reloid = ((AttributeTupleForm)GETSTRUCT(tup))->attrelid;
204 optr->next = (struct oidlist *) palloc(sizeof(*oidptr));
212 ScanKeyEntryInitialize(&key[0], 0,
213 ObjectIdAttributeNumber,
214 ObjectIdEqualRegProcedure, (Datum)0);
216 rdesc = heap_openr(RelationRelationName);
217 while (PointerIsValid((char *) optr->next)) {
218 key[0].sk_argument = (Datum) (optr++)->reloid;
219 sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 1, key);
220 tup = heap_getnext(sdesc, 0, &buffer);
221 if (PointerIsValid(tup)) {
224 name = (((Form_pg_class)GETSTRUCT(tup))->relname).data;
235 * Removes the type 'typeName' and all attributes and relations that
239 RemoveType(char *typeName) /* type name to be removed */
245 ItemPointerData itemPointerData;
246 static ScanKeyData typeKey[1] = {
247 { 0, Anum_pg_type_typname, NameEqualRegProcedure }
253 userName = GetPgUserName();
254 if (!pg_ownercheck(userName, typeName, TYPNAME))
255 elog(WARN, "RemoveType: type '%s': permission denied",
259 relation = heap_openr(TypeRelationName);
260 fmgr_info(typeKey[0].sk_procedure, &typeKey[0].sk_func,
261 &typeKey[0].sk_nargs);
263 /* Delete the primary type */
265 typeKey[0].sk_argument = PointerGetDatum(typeName);
267 scan = heap_beginscan(relation, 0, NowTimeQual, 1, typeKey);
268 tup = heap_getnext(scan, 0, (Buffer *) 0);
269 if (!HeapTupleIsValid(tup)) {
271 heap_close(relation);
272 elog(WARN, "RemoveType: type '%s' does not exist",
275 typeOid = tup->t_oid;
276 ItemPointerCopy(&tup->t_ctid, &itemPointerData);
277 heap_delete(relation, &itemPointerData);
280 /* Now, Delete the "array of" that type */
281 shadow_type = makeArrayTypeName(typeName);
282 typeKey[0].sk_argument = NameGetDatum(shadow_type);
284 scan = heap_beginscan(relation, 0, NowTimeQual,
285 1, (ScanKey) typeKey);
286 tup = heap_getnext(scan, 0, (Buffer *) 0);
288 if (!HeapTupleIsValid(tup))
290 elog(WARN, "RemoveType: type '%s': array stub not found",
293 typeOid = tup->t_oid;
294 ItemPointerCopy(&tup->t_ctid, &itemPointerData);
295 heap_delete(relation, &itemPointerData);
298 heap_close(relation);
303 * Deletes a function.
306 * BadArg if name is invalid.
307 * "WARN" if function nonexistent.
311 RemoveFunction(char *functionName, /* function name to be removed */
313 List *argNameList /* list of TypeNames */)
318 Buffer buffer = InvalidBuffer;
319 bool bufferUsed = FALSE;
321 Form_pg_proc the_proc = NULL;
322 ItemPointerData itemPointerData;
323 static ScanKeyData key[3] = {
324 { 0, Anum_pg_proc_proname, NameEqualRegProcedure }
330 memset(argList, 0, 8 * sizeof(Oid));
331 for (i=0; i<nargs; i++) {
332 /* typename = ((TypeName*)(lfirst(argNameList)))->name; */
333 typename = strVal(lfirst(argNameList));
334 argNameList = lnext(argNameList);
336 if (strcmp(typename, "opaque") == 0)
339 tup = SearchSysCacheTuple(TYPNAME, PointerGetDatum(typename),
342 if (!HeapTupleIsValid(tup)) {
343 elog(WARN, "RemoveFunction: type '%s' not found",typename);
345 argList[i] = tup->t_oid;
349 tup = SearchSysCacheTuple(PRONAME, PointerGetDatum(functionName),
350 Int32GetDatum(nargs),
351 PointerGetDatum(argList),0);
352 if (!HeapTupleIsValid(tup))
353 func_error("RemoveFunction", functionName, nargs, argList);
356 userName = GetPgUserName();
357 if (!pg_func_ownercheck(userName, functionName, nargs, argList)) {
358 elog(WARN, "RemoveFunction: function '%s': permission denied",
363 key[0].sk_argument = PointerGetDatum(functionName);
365 fmgr_info(key[0].sk_procedure, &key[0].sk_func, &key[0].sk_nargs);
367 relation = heap_openr(ProcedureRelationName);
368 scan = heap_beginscan(relation, 0, NowTimeQual, 1, key);
370 do { /* hope this is ok because it's indexed */
372 ReleaseBuffer(buffer);
375 tup = heap_getnext(scan, 0, (Buffer *) &buffer);
376 if (!HeapTupleIsValid(tup))
379 the_proc = (Form_pg_proc) GETSTRUCT(tup);
380 } while ( (namestrcmp(&(the_proc->proname), functionName) == 0) &&
381 (the_proc->pronargs != nargs ||
382 !oid8eq(&(the_proc->proargtypes[0]), &argList[0])));
385 if (!HeapTupleIsValid(tup) || namestrcmp(&(the_proc->proname),
389 heap_close(relation);
390 func_error("RemoveFunction", functionName,nargs, argList);
393 /* ok, function has been found */
395 if (the_proc->prolang == INTERNALlanguageId)
396 elog(WARN, "RemoveFunction: function \"%-.*s\" is built-in",
397 NAMEDATALEN, functionName);
399 ItemPointerCopy(&tup->t_ctid, &itemPointerData);
400 heap_delete(relation, &itemPointerData);
402 heap_close(relation);
406 RemoveAggregate(char *aggName)
411 ItemPointerData itemPointerData;
412 static ScanKeyData key[3] = {
413 { 0, Anum_pg_aggregate_aggname, NameEqualRegProcedure }
416 key[0].sk_argument = PointerGetDatum(aggName);
418 fmgr_info(key[0].sk_procedure, &key[0].sk_func, &key[0].sk_nargs);
419 relation = heap_openr(AggregateRelationName);
420 scan = heap_beginscan(relation, 0, NowTimeQual, 1, key);
421 tup = heap_getnext(scan, 0, (Buffer *) 0);
422 if (!HeapTupleIsValid(tup)) {
424 heap_close(relation);
425 elog(WARN, "RemoveAggregate: aggregate '%s' does not exist",
428 ItemPointerCopy(&tup->t_ctid, &itemPointerData);
429 heap_delete(relation, &itemPointerData);
431 heap_close(relation);