1/*-------------------------------------------------------------------------
4 * handle various "DROP" operations
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/backend/commands/dropcmds.c
13 *-------------------------------------------------------------------------
34 const char **msg,
char **
name);
36 const char **msg,
char **
name);
38 const char **msg,
char **
name);
42 * Drop one or more objects.
44 * We don't currently handle all object types here. Relations, for example,
45 * require special handling, because (for example) indexes have additional
46 * locking requirements.
48 * We look up all the objects first, and then delete them in a single
49 * performMultipleDeletions() call. This avoids unnecessary DROP RESTRICT
50 * errors if there are dependencies between them.
60 foreach(cell1,
stmt->objects)
67 /* Get an ObjectAddress for the object. */
75 * Issue NOTICE if supplied object was not found. Note this is only
76 * relevant in the missing_ok case, because otherwise
77 * get_object_address would have thrown an error.
87 * Although COMMENT ON FUNCTION, SECURITY LABEL ON FUNCTION, etc. are
88 * happy to operate on an aggregate as on any other function, we have
89 * historically not allowed this for DROP FUNCTION.
95 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
96 errmsg(
"\"%s\" is an aggregate function",
98 errhint(
"Use DROP AGGREGATE to drop aggregate functions.")));
101 /* Check permissions. */
109 * Make note if a temporary namespace has been accessed in this
115 /* Release any relcache reference count, but keep lock until commit. */
122 /* Here we really delete them. */
129 * owningrel_does_not_exist_skipping
130 * Subroutine for RemoveObjects
132 * After determining that a specification for a rule or trigger returns that
133 * the specified object does not exist, test whether its owning relation, and
134 * its schema, exist or not; if they do, return false --- the trigger or rule
135 * itself is missing instead. If the owning relation or its schema do not
136 * exist, fill the error message format string and name, and return true.
153 *msg =
gettext_noop(
"relation \"%s\" does not exist, skipping");
163 * schema_does_not_exist_skipping
164 * Subroutine for RemoveObjects
166 * After determining that a specification for a schema-qualifiable object
167 * refers to an object that does not exist, test whether the specified schema
168 * exists or not. If no schema was specified, or if the schema does exist,
169 * return false -- the object itself is missing instead. If the specified
170 * schema does not exist, fill the error message format string and the
171 * specified schema name, and return true.
183 *msg =
gettext_noop(
"schema \"%s\" does not exist, skipping");
193 * type_in_list_does_not_exist_skipping
194 * Subroutine for RemoveObjects
196 * After determining that a specification for a function, cast, aggregate or
197 * operator returns that the specified object does not exist, test whether the
198 * involved datatypes, and their schemas, exist or not; if they do, return
199 * false --- the original object itself is missing instead. If the datatypes
200 * or schemas do not exist, fill the error message format string and the
201 * missing name, and return true.
203 * First parameter is a list of TypeNames.
215 if (typeName != NULL)
219 /* type doesn't exist, try to find why */
223 *msg =
gettext_noop(
"type \"%s\" does not exist, skipping");
235 * does_not_exist_skipping
236 * Subroutine for RemoveObjects
238 * Generate a NOTICE stating that the named object was not found, and is
239 * being skipped. This is only relevant when "IF EXISTS" is used; otherwise,
240 * get_object_address() in RemoveObjects would have thrown an ERROR.
245 const char *msg = NULL;
252 msg =
gettext_noop(
"access method \"%s\" does not exist, skipping");
262 msg =
gettext_noop(
"type \"%s\" does not exist, skipping");
270 msg =
gettext_noop(
"collation \"%s\" does not exist, skipping");
277 msg =
gettext_noop(
"conversion \"%s\" does not exist, skipping");
282 msg =
gettext_noop(
"schema \"%s\" does not exist, skipping");
288 msg =
gettext_noop(
"statistics object \"%s\" does not exist, skipping");
295 msg =
gettext_noop(
"text search parser \"%s\" does not exist, skipping");
302 msg =
gettext_noop(
"text search dictionary \"%s\" does not exist, skipping");
309 msg =
gettext_noop(
"text search template \"%s\" does not exist, skipping");
316 msg =
gettext_noop(
"text search configuration \"%s\" does not exist, skipping");
321 msg =
gettext_noop(
"extension \"%s\" does not exist, skipping");
331 msg =
gettext_noop(
"function %s(%s) does not exist, skipping");
344 msg =
gettext_noop(
"procedure %s(%s) does not exist, skipping");
357 msg =
gettext_noop(
"routine %s(%s) does not exist, skipping");
370 msg =
gettext_noop(
"aggregate %s(%s) does not exist, skipping");
383 msg =
gettext_noop(
"operator %s does not exist, skipping");
389 msg =
gettext_noop(
"language \"%s\" does not exist, skipping");
397 /* XXX quote or no quote? */
398 msg =
gettext_noop(
"cast from type %s to type %s does not exist, skipping");
407 msg =
gettext_noop(
"transform for type %s language \"%s\" does not exist, skipping");
415 msg =
gettext_noop(
"trigger \"%s\" for relation \"%s\" does not exist, skipping");
424 msg =
gettext_noop(
"policy \"%s\" for relation \"%s\" does not exist, skipping");
431 msg =
gettext_noop(
"event trigger \"%s\" does not exist, skipping");
437 msg =
gettext_noop(
"rule \"%s\" for relation \"%s\" does not exist, skipping");
444 msg =
gettext_noop(
"foreign-data wrapper \"%s\" does not exist, skipping");
448 msg =
gettext_noop(
"server \"%s\" does not exist, skipping");
457 msg =
gettext_noop(
"operator class \"%s\" does not exist for access method \"%s\", skipping");
469 msg =
gettext_noop(
"operator family \"%s\" does not exist for access method \"%s\", skipping");
476 msg =
gettext_noop(
"publication \"%s\" does not exist, skipping");
493 * These are handled elsewhere, so if someone gets here the code
494 * is probably wrong or should be revisited.
496 elog(
ERROR,
"unsupported object type: %d", (
int) objtype);
511 /* These are currently not used or needed. */
512 elog(
ERROR,
"unsupported object type: %d", (
int) objtype);
515 /* no default, to let compiler warn about missing case */
518 elog(
ERROR,
"unrecognized object type: %d", (
int) objtype);
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
#define OidIsValid(objectId)
void performMultipleDeletions(const ObjectAddresses *objects, DropBehavior behavior, int flags)
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
ObjectAddresses * new_object_addresses(void)
void free_object_addresses(ObjectAddresses *addrs)
static bool type_in_list_does_not_exist_skipping(List *typenames, const char **msg, char **name)
void RemoveObjects(DropStmt *stmt)
static void does_not_exist_skipping(ObjectType objtype, Node *object)
static bool owningrel_does_not_exist_skipping(List *object, const char **msg, char **name)
static bool schema_does_not_exist_skipping(List *object, const char **msg, char **name)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
Assert(PointerIsAligned(start, uint64))
List * list_copy_tail(const List *oldlist, int nskip)
List * list_copy_head(const List *oldlist, int len)
#define AccessExclusiveLock
char get_func_prokind(Oid funcid)
char * NameListToString(const List *names)
bool isTempNamespace(Oid namespaceId)
RangeVar * makeRangeVarFromNameList(const List *names)
Oid LookupNamespaceNoError(const char *nspname)
#define RangeVarGetRelid(relation, lockmode, missing_ok)
#define castNode(_type_, nodeptr)
void check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address, Node *object, Relation relation)
ObjectAddress get_object_address(ObjectType objtype, Node *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
Oid get_object_namespace(const ObjectAddress *address)
char * TypeNameToString(const TypeName *typeName)
char * TypeNameListToString(List *typenames)
Oid LookupTypeNameOid(ParseState *pstate, const TypeName *typeName, bool missing_ok)
@ OBJECT_PUBLICATION_NAMESPACE
#define lfirst_node(type, lc)
static int list_length(const List *l)
#define linitial_node(type, l)
#define lsecond_node(type, l)
void table_close(Relation relation, LOCKMODE lockmode)
#define XACT_FLAGS_ACCESSEDTEMPNAMESPACE