]> granicus.if.org Git - postgresql/blob - src/backend/commands/remove.c
This patch changes quite a few instances of references of Oid's
[postgresql] / src / backend / commands / remove.c
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: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.7 1996/11/30 18:06:10 momjian Exp $
11  *
12  *-------------------------------------------------------------------------
13  */
14 #include <postgres.h>
15
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>
29 #include <fmgr.h>
30 #ifndef HAVE_MEMMOVE
31 # include <regex/utils.h>
32 #else
33 # include <string.h>
34 #endif
35
36 /*
37  * RemoveOperator --
38  *      Deletes an operator.
39  *
40  * Exceptions:
41  *      BadArg if name is invalid.
42  *      BadArg if type1 is invalid.
43  *      "WARN" if operator nonexistent.
44  *      ...
45  */
46 void
47 RemoveOperator(char *operatorName, /* operator name */
48                char *typeName1, /* first type name */
49                char *typeName2) /* optional second type name */
50 {
51     Relation    relation;
52     HeapScanDesc scan;
53     HeapTuple   tup;
54     Oid         typeId1 = InvalidOid;
55     Oid         typeId2 = InvalidOid;
56     bool        defined;
57     ItemPointerData     itemPointerData;
58     Buffer      buffer;
59     ScanKeyData operatorKey[3];
60     char *userName;
61     
62      if (typeName1) {
63         typeId1 = TypeGet(typeName1, &defined);
64         if (!OidIsValid(typeId1)) {
65             elog(WARN, "RemoveOperator: type '%s' does not exist", typeName1);
66             return;
67         }
68     }
69     
70     if (typeName2) {
71         typeId2 = TypeGet(typeName2, &defined);
72         if (!OidIsValid(typeId2)) {
73             elog(WARN, "RemoveOperator: type '%s' does not exist", typeName2);
74             return;
75         }
76     }
77     
78     ScanKeyEntryInitialize(&operatorKey[0], 0x0,
79                            Anum_pg_operator_oprname,
80                            NameEqualRegProcedure,
81                            PointerGetDatum(operatorName));
82     
83     ScanKeyEntryInitialize(&operatorKey[1], 0x0,
84                            Anum_pg_operator_oprleft,
85                            ObjectIdEqualRegProcedure,
86                            ObjectIdGetDatum(typeId1));
87     
88     ScanKeyEntryInitialize(&operatorKey[2], 0x0,
89                            Anum_pg_operator_oprright,
90                            ObjectIdEqualRegProcedure,
91                            ObjectIdGetDatum(typeId2));
92     
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)) {
97 #ifndef NO_SECURITY
98         userName = GetPgUserName();
99         if (!pg_ownercheck(userName,
100                            (char *) ObjectIdGetDatum(tup->t_oid),
101                            OPROID))
102             elog(WARN, "RemoveOperator: operator '%s': permission denied",
103                  operatorName);
104 #endif
105         ItemPointerCopy(&tup->t_ctid, &itemPointerData);
106         heap_delete(relation, &itemPointerData);
107     } else {
108         if (OidIsValid(typeId1) && OidIsValid(typeId2)) {
109             elog(WARN, "RemoveOperator: binary operator '%s' taking '%s' and '%s' does not exist",
110                  operatorName,
111                  typeName1,
112                  typeName2);
113         } else if (OidIsValid(typeId1)) {
114             elog(WARN, "RemoveOperator: right unary operator '%s' taking '%s' does not exist",
115                  operatorName,
116                  typeName1);
117         } else {
118             elog(WARN, "RemoveOperator: left unary operator '%s' taking '%s' does not exist",
119                  operatorName,
120                  typeName2);
121         }
122     }
123     heap_endscan(scan);
124     heap_close(relation);
125 }
126
127 #ifdef NOTYET
128 /*
129  * this stuff is to support removing all reference to a type
130  * don't use it  - pma 2/1/94
131  */
132 /*
133  *  SingleOpOperatorRemove
134  *      Removes all operators that have operands or a result of type 'typeOid'.
135  */
136 static void
137 SingleOpOperatorRemove(Oid typeOid)
138 {
139     Relation    rdesc;
140     ScanKeyData         key[3];
141     HeapScanDesc        sdesc;
142     HeapTuple   tup;
143     ItemPointerData itemPointerData;
144     Buffer              buffer;
145     static              attnums[3] = { 7, 8, 9 }; /* left, right, return */
146     register    i;
147     
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);
158         }
159         heap_endscan(sdesc);
160     }
161     heap_close(rdesc);
162 }
163
164 /*
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.
169  */
170 static void
171 AttributeAndRelationRemove(Oid typeOid)
172 {
173     struct oidlist {
174         Oid             reloid;
175         struct oidlist  *next;
176     };
177     struct oidlist      *oidptr, *optr;
178     Relation            rdesc;
179     ScanKeyData         key[1];
180     HeapScanDesc        sdesc;
181     HeapTuple           tup;
182     ItemPointerData     itemPointerData;
183     Buffer              buffer;
184     
185     /*
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
191      */
192     
193     ScanKeyEntryInitialize(&key[0],
194                            0, 3, ObjectIdEqualRegProcedure, (Datum)typeOid);
195     
196     oidptr = (struct oidlist *) palloc(sizeof(*oidptr));
197     oidptr->next = NULL;
198     optr = 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));     
205         optr = optr->next;
206     }
207     optr->next = NULL;
208     heap_endscan(sdesc);
209     heap_close(rdesc);
210     
211     
212     ScanKeyEntryInitialize(&key[0], 0,
213                            ObjectIdAttributeNumber,
214                            ObjectIdEqualRegProcedure, (Datum)0);
215     optr = oidptr;
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)) {
222             char *name;
223             
224             name = (((Form_pg_class)GETSTRUCT(tup))->relname).data;
225             heap_destroy(name);
226         }
227     }
228     heap_endscan(sdesc);
229     heap_close(rdesc);
230 }
231 #endif /* NOTYET */
232
233 /*
234  *  TypeRemove
235  *      Removes the type 'typeName' and all attributes and relations that
236  *      use it.
237  */
238 void
239 RemoveType(char *typeName)    /* type name to be removed */
240 {
241     Relation    relation;  
242     HeapScanDesc        scan;      
243     HeapTuple   tup;
244     Oid typeOid;
245     ItemPointerData     itemPointerData;
246     static ScanKeyData typeKey[1] = {
247         { 0, Anum_pg_type_typname, NameEqualRegProcedure }
248     };
249     char *shadow_type;
250     char *userName;
251     
252 #ifndef NO_SECURITY
253     userName = GetPgUserName();
254     if (!pg_ownercheck(userName, typeName, TYPNAME))
255         elog(WARN, "RemoveType: type '%s': permission denied",
256              typeName);
257 #endif
258     
259     relation = heap_openr(TypeRelationName);
260     fmgr_info(typeKey[0].sk_procedure, &typeKey[0].sk_func,
261               &typeKey[0].sk_nargs);
262     
263     /* Delete the primary type */
264     
265     typeKey[0].sk_argument = PointerGetDatum(typeName);
266     
267     scan = heap_beginscan(relation, 0, NowTimeQual, 1, typeKey);
268     tup = heap_getnext(scan, 0, (Buffer *) 0);
269     if (!HeapTupleIsValid(tup)) {
270         heap_endscan(scan);
271         heap_close(relation);
272         elog(WARN, "RemoveType: type '%s' does not exist",
273              typeName);
274     }
275     typeOid = tup->t_oid;
276     ItemPointerCopy(&tup->t_ctid, &itemPointerData);
277     heap_delete(relation, &itemPointerData);
278     heap_endscan(scan);
279     
280     /* Now, Delete the "array of" that type */
281     shadow_type = makeArrayTypeName(typeName);
282     typeKey[0].sk_argument = NameGetDatum(shadow_type);
283     
284     scan = heap_beginscan(relation, 0, NowTimeQual,
285                           1, (ScanKey) typeKey);
286     tup = heap_getnext(scan, 0,  (Buffer *) 0);
287     
288     if (!HeapTupleIsValid(tup))
289         {
290             elog(WARN, "RemoveType: type '%s': array stub not found",
291                  typeName);
292         }
293     typeOid = tup->t_oid;
294     ItemPointerCopy(&tup->t_ctid, &itemPointerData);
295     heap_delete(relation, &itemPointerData);
296     heap_endscan(scan);
297     
298     heap_close(relation);
299 }
300
301 /*
302  * RemoveFunction --
303  *      Deletes a function.
304  *
305  * Exceptions:
306  *      BadArg if name is invalid.
307  *      "WARN" if function nonexistent.
308  *      ...
309  */
310 void
311 RemoveFunction(char *functionName, /* function name to be removed */
312                int nargs,
313                List *argNameList /* list of TypeNames */)
314 {
315     Relation         relation;
316     HeapScanDesc         scan;
317     HeapTuple        tup;
318     Buffer           buffer = InvalidBuffer;
319     bool                 bufferUsed = FALSE;
320     Oid  argList[8];
321     Form_pg_proc         the_proc = NULL;
322     ItemPointerData  itemPointerData;
323     static ScanKeyData key[3] = {
324         { 0, Anum_pg_proc_proname, NameEqualRegProcedure }
325     };
326     char *userName;
327     char *typename;
328     int                 i;
329     
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);
335         
336         if (strcmp(typename, "opaque") == 0)
337             argList[i] = 0;
338         else {
339             tup = SearchSysCacheTuple(TYPNAME, PointerGetDatum(typename),
340                                       0,0,0);
341             
342             if (!HeapTupleIsValid(tup)) {
343                 elog(WARN, "RemoveFunction: type '%s' not found",typename);
344             }
345             argList[i] = tup->t_oid;
346         }
347     }
348     
349     tup = SearchSysCacheTuple(PRONAME, PointerGetDatum(functionName),
350                               Int32GetDatum(nargs),
351                               PointerGetDatum(argList),0);
352     if (!HeapTupleIsValid(tup))
353         func_error("RemoveFunction", functionName, nargs, argList);
354     
355 #ifndef NO_SECURITY
356     userName = GetPgUserName();
357     if (!pg_func_ownercheck(userName, functionName, nargs, argList)) {
358         elog(WARN, "RemoveFunction: function '%s': permission denied",
359              functionName);
360     }
361 #endif
362     
363     key[0].sk_argument = PointerGetDatum(functionName);
364     
365     fmgr_info(key[0].sk_procedure, &key[0].sk_func, &key[0].sk_nargs);
366     
367     relation = heap_openr(ProcedureRelationName);
368     scan = heap_beginscan(relation, 0, NowTimeQual, 1, key);
369     
370     do { /* hope this is ok because it's indexed */
371         if (bufferUsed) {
372             ReleaseBuffer(buffer);
373             bufferUsed = FALSE;
374         }
375         tup = heap_getnext(scan,  0, (Buffer *) &buffer);
376         if (!HeapTupleIsValid(tup))
377             break;
378         bufferUsed = TRUE;
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])));
383     
384     
385     if (!HeapTupleIsValid(tup) || namestrcmp(&(the_proc->proname), 
386                                              functionName) != 0)
387         {       
388             heap_endscan(scan);
389             heap_close(relation);
390             func_error("RemoveFunction", functionName,nargs, argList);
391         }
392     
393     /* ok, function has been found */
394     
395     if (the_proc->prolang == INTERNALlanguageId)
396         elog(WARN, "RemoveFunction: function \"%-.*s\" is built-in",
397              NAMEDATALEN, functionName);
398     
399     ItemPointerCopy(&tup->t_ctid, &itemPointerData);
400     heap_delete(relation, &itemPointerData);
401     heap_endscan(scan);
402     heap_close(relation);
403 }
404
405 void
406 RemoveAggregate(char *aggName)
407 {
408     Relation    relation;
409     HeapScanDesc        scan;
410     HeapTuple   tup;
411     ItemPointerData       itemPointerData;
412     static ScanKeyData key[3] = {
413         { 0, Anum_pg_aggregate_aggname, NameEqualRegProcedure }
414     };
415     
416     key[0].sk_argument = PointerGetDatum(aggName);
417     
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)) {
423         heap_endscan(scan);
424         heap_close(relation);
425         elog(WARN, "RemoveAggregate: aggregate '%s' does not exist",
426              aggName);
427     }
428     ItemPointerCopy(&tup->t_ctid, &itemPointerData);
429     heap_delete(relation, &itemPointerData);
430     heap_endscan(scan);
431     heap_close(relation);
432 }