00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "postgres.h"
00017
00018 #include "access/heapam.h"
00019 #include "access/htup_details.h"
00020 #include "catalog/dependency.h"
00021 #include "catalog/namespace.h"
00022 #include "catalog/objectaddress.h"
00023 #include "catalog/pg_class.h"
00024 #include "catalog/pg_proc.h"
00025 #include "commands/defrem.h"
00026 #include "miscadmin.h"
00027 #include "nodes/makefuncs.h"
00028 #include "parser/parse_type.h"
00029 #include "utils/builtins.h"
00030 #include "utils/syscache.h"
00031
00032 static void does_not_exist_skipping(ObjectType objtype,
00033 List *objname, List *objargs);
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 void
00047 RemoveObjects(DropStmt *stmt)
00048 {
00049 ObjectAddresses *objects;
00050 ListCell *cell1;
00051 ListCell *cell2 = NULL;
00052
00053 objects = new_object_addresses();
00054
00055 foreach(cell1, stmt->objects)
00056 {
00057 ObjectAddress address;
00058 List *objname = lfirst(cell1);
00059 List *objargs = NIL;
00060 Relation relation = NULL;
00061 Oid namespaceId;
00062
00063 if (stmt->arguments)
00064 {
00065 cell2 = (!cell2 ? list_head(stmt->arguments) : lnext(cell2));
00066 objargs = lfirst(cell2);
00067 }
00068
00069
00070 address = get_object_address(stmt->removeType,
00071 objname, objargs,
00072 &relation,
00073 AccessExclusiveLock,
00074 stmt->missing_ok);
00075
00076
00077 if (!OidIsValid(address.objectId))
00078 {
00079 does_not_exist_skipping(stmt->removeType, objname, objargs);
00080 continue;
00081 }
00082
00083
00084
00085
00086
00087
00088 if (stmt->removeType == OBJECT_FUNCTION)
00089 {
00090 Oid funcOid = address.objectId;
00091 HeapTuple tup;
00092
00093 tup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcOid));
00094 if (!HeapTupleIsValid(tup))
00095 elog(ERROR, "cache lookup failed for function %u", funcOid);
00096
00097 if (((Form_pg_proc) GETSTRUCT(tup))->proisagg)
00098 ereport(ERROR,
00099 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
00100 errmsg("\"%s\" is an aggregate function",
00101 NameListToString(objname)),
00102 errhint("Use DROP AGGREGATE to drop aggregate functions.")));
00103
00104 ReleaseSysCache(tup);
00105 }
00106
00107
00108 namespaceId = get_object_namespace(&address);
00109 if (!OidIsValid(namespaceId) ||
00110 !pg_namespace_ownercheck(namespaceId, GetUserId()))
00111 check_object_ownership(GetUserId(), stmt->removeType, address,
00112 objname, objargs, relation);
00113
00114
00115 if (relation)
00116 heap_close(relation, NoLock);
00117
00118 add_exact_object_address(&address, objects);
00119 }
00120
00121
00122 performMultipleDeletions(objects, stmt->behavior, 0);
00123
00124 free_object_addresses(objects);
00125 }
00126
00127
00128
00129
00130
00131
00132 static void
00133 does_not_exist_skipping(ObjectType objtype, List *objname, List *objargs)
00134 {
00135 const char *msg = NULL;
00136 char *name = NULL;
00137 char *args = NULL;
00138
00139 switch (objtype)
00140 {
00141 case OBJECT_TYPE:
00142 case OBJECT_DOMAIN:
00143 msg = gettext_noop("type \"%s\" does not exist, skipping");
00144 name = TypeNameToString(makeTypeNameFromNameList(objname));
00145 break;
00146 case OBJECT_COLLATION:
00147 msg = gettext_noop("collation \"%s\" does not exist, skipping");
00148 name = NameListToString(objname);
00149 break;
00150 case OBJECT_CONVERSION:
00151 msg = gettext_noop("conversion \"%s\" does not exist, skipping");
00152 name = NameListToString(objname);
00153 break;
00154 case OBJECT_SCHEMA:
00155 msg = gettext_noop("schema \"%s\" does not exist, skipping");
00156 name = NameListToString(objname);
00157 break;
00158 case OBJECT_TSPARSER:
00159 msg = gettext_noop("text search parser \"%s\" does not exist, skipping");
00160 name = NameListToString(objname);
00161 break;
00162 case OBJECT_TSDICTIONARY:
00163 msg = gettext_noop("text search dictionary \"%s\" does not exist, skipping");
00164 name = NameListToString(objname);
00165 break;
00166 case OBJECT_TSTEMPLATE:
00167 msg = gettext_noop("text search template \"%s\" does not exist, skipping");
00168 name = NameListToString(objname);
00169 break;
00170 case OBJECT_TSCONFIGURATION:
00171 msg = gettext_noop("text search configuration \"%s\" does not exist, skipping");
00172 name = NameListToString(objname);
00173 break;
00174 case OBJECT_EXTENSION:
00175 msg = gettext_noop("extension \"%s\" does not exist, skipping");
00176 name = NameListToString(objname);
00177 break;
00178 case OBJECT_FUNCTION:
00179 msg = gettext_noop("function %s(%s) does not exist, skipping");
00180 name = NameListToString(objname);
00181 args = TypeNameListToString(objargs);
00182 break;
00183 case OBJECT_AGGREGATE:
00184 msg = gettext_noop("aggregate %s(%s) does not exist, skipping");
00185 name = NameListToString(objname);
00186 args = TypeNameListToString(objargs);
00187 break;
00188 case OBJECT_OPERATOR:
00189 msg = gettext_noop("operator %s does not exist, skipping");
00190 name = NameListToString(objname);
00191 break;
00192 case OBJECT_LANGUAGE:
00193 msg = gettext_noop("language \"%s\" does not exist, skipping");
00194 name = NameListToString(objname);
00195 break;
00196 case OBJECT_CAST:
00197 msg = gettext_noop("cast from type %s to type %s does not exist, skipping");
00198 name = format_type_be(typenameTypeId(NULL,
00199 (TypeName *) linitial(objname)));
00200 args = format_type_be(typenameTypeId(NULL,
00201 (TypeName *) linitial(objargs)));
00202 break;
00203 case OBJECT_TRIGGER:
00204 msg = gettext_noop("trigger \"%s\" for table \"%s\" does not exist, skipping");
00205 name = strVal(llast(objname));
00206 args = NameListToString(list_truncate(list_copy(objname),
00207 list_length(objname) - 1));
00208 break;
00209 case OBJECT_EVENT_TRIGGER:
00210 msg = gettext_noop("event trigger \"%s\" does not exist, skipping");
00211 name = NameListToString(objname);
00212 break;
00213 case OBJECT_RULE:
00214 msg = gettext_noop("rule \"%s\" for relation \"%s\" does not exist, skipping");
00215 name = strVal(llast(objname));
00216 args = NameListToString(list_truncate(list_copy(objname),
00217 list_length(objname) - 1));
00218 break;
00219 case OBJECT_FDW:
00220 msg = gettext_noop("foreign-data wrapper \"%s\" does not exist, skipping");
00221 name = NameListToString(objname);
00222 break;
00223 case OBJECT_FOREIGN_SERVER:
00224 msg = gettext_noop("server \"%s\" does not exist, skipping");
00225 name = NameListToString(objname);
00226 break;
00227 case OBJECT_OPCLASS:
00228 msg = gettext_noop("operator class \"%s\" does not exist for access method \"%s\", skipping");
00229 name = NameListToString(objname);
00230 args = strVal(linitial(objargs));
00231 break;
00232 case OBJECT_OPFAMILY:
00233 msg = gettext_noop("operator family \"%s\" does not exist for access method \"%s\", skipping");
00234 name = NameListToString(objname);
00235 args = strVal(linitial(objargs));
00236 break;
00237 default:
00238 elog(ERROR, "unexpected object type (%d)", (int) objtype);
00239 break;
00240 }
00241
00242 if (!args)
00243 ereport(NOTICE, (errmsg(msg, name)));
00244 else
00245 ereport(NOTICE, (errmsg(msg, name, args)));
00246 }