Header And Logo

PostgreSQL
| The world's most advanced open source database.

Functions

dropcmds.c File Reference

#include "postgres.h"
#include "access/heapam.h"
#include "access/htup_details.h"
#include "catalog/dependency.h"
#include "catalog/namespace.h"
#include "catalog/objectaddress.h"
#include "catalog/pg_class.h"
#include "catalog/pg_proc.h"
#include "commands/defrem.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "parser/parse_type.h"
#include "utils/builtins.h"
#include "utils/syscache.h"
Include dependency graph for dropcmds.c:

Go to the source code of this file.

Functions

static void does_not_exist_skipping (ObjectType objtype, List *objname, List *objargs)
void RemoveObjects (DropStmt *stmt)

Function Documentation

static void does_not_exist_skipping ( ObjectType  objtype,
List objname,
List objargs 
) [static]

Definition at line 133 of file dropcmds.c.

References elog, ereport, errmsg(), ERROR, format_type_be(), gettext_noop, linitial, list_copy(), list_length(), list_truncate(), llast, makeTypeNameFromNameList(), name, NameListToString(), NOTICE, NULL, OBJECT_AGGREGATE, OBJECT_CAST, OBJECT_COLLATION, OBJECT_CONVERSION, OBJECT_DOMAIN, OBJECT_EVENT_TRIGGER, OBJECT_EXTENSION, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FUNCTION, OBJECT_LANGUAGE, OBJECT_OPCLASS, OBJECT_OPERATOR, OBJECT_OPFAMILY, OBJECT_RULE, OBJECT_SCHEMA, OBJECT_TRIGGER, OBJECT_TSCONFIGURATION, OBJECT_TSDICTIONARY, OBJECT_TSPARSER, OBJECT_TSTEMPLATE, OBJECT_TYPE, strVal, TypeNameListToString(), TypeNameToString(), and typenameTypeId().

Referenced by RemoveObjects().

{
    const char *msg = NULL;
    char       *name = NULL;
    char       *args = NULL;

    switch (objtype)
    {
        case OBJECT_TYPE:
        case OBJECT_DOMAIN:
            msg = gettext_noop("type \"%s\" does not exist, skipping");
            name = TypeNameToString(makeTypeNameFromNameList(objname));
            break;
        case OBJECT_COLLATION:
            msg = gettext_noop("collation \"%s\" does not exist, skipping");
            name = NameListToString(objname);
            break;
        case OBJECT_CONVERSION:
            msg = gettext_noop("conversion \"%s\" does not exist, skipping");
            name = NameListToString(objname);
            break;
        case OBJECT_SCHEMA:
            msg = gettext_noop("schema \"%s\" does not exist, skipping");
            name = NameListToString(objname);
            break;
        case OBJECT_TSPARSER:
            msg = gettext_noop("text search parser \"%s\" does not exist, skipping");
            name = NameListToString(objname);
            break;
        case OBJECT_TSDICTIONARY:
            msg = gettext_noop("text search dictionary \"%s\" does not exist, skipping");
            name = NameListToString(objname);
            break;
        case OBJECT_TSTEMPLATE:
            msg = gettext_noop("text search template \"%s\" does not exist, skipping");
            name = NameListToString(objname);
            break;
        case OBJECT_TSCONFIGURATION:
            msg = gettext_noop("text search configuration \"%s\" does not exist, skipping");
            name = NameListToString(objname);
            break;
        case OBJECT_EXTENSION:
            msg = gettext_noop("extension \"%s\" does not exist, skipping");
            name = NameListToString(objname);
            break;
        case OBJECT_FUNCTION:
            msg = gettext_noop("function %s(%s) does not exist, skipping");
            name = NameListToString(objname);
            args = TypeNameListToString(objargs);
            break;
        case OBJECT_AGGREGATE:
            msg = gettext_noop("aggregate %s(%s) does not exist, skipping");
            name = NameListToString(objname);
            args = TypeNameListToString(objargs);
            break;
        case OBJECT_OPERATOR:
            msg = gettext_noop("operator %s does not exist, skipping");
            name = NameListToString(objname);
            break;
        case OBJECT_LANGUAGE:
            msg = gettext_noop("language \"%s\" does not exist, skipping");
            name = NameListToString(objname);
            break;
        case OBJECT_CAST:
            msg = gettext_noop("cast from type %s to type %s does not exist, skipping");
            name = format_type_be(typenameTypeId(NULL,
                                            (TypeName *) linitial(objname)));
            args = format_type_be(typenameTypeId(NULL,
                                            (TypeName *) linitial(objargs)));
            break;
        case OBJECT_TRIGGER:
            msg = gettext_noop("trigger \"%s\" for table \"%s\" does not exist, skipping");
            name = strVal(llast(objname));
            args = NameListToString(list_truncate(list_copy(objname),
                                                  list_length(objname) - 1));
            break;
        case OBJECT_EVENT_TRIGGER:
            msg = gettext_noop("event trigger \"%s\" does not exist, skipping");
            name = NameListToString(objname);
            break;
        case OBJECT_RULE:
            msg = gettext_noop("rule \"%s\" for relation \"%s\" does not exist, skipping");
            name = strVal(llast(objname));
            args = NameListToString(list_truncate(list_copy(objname),
                                                  list_length(objname) - 1));
            break;
        case OBJECT_FDW:
            msg = gettext_noop("foreign-data wrapper \"%s\" does not exist, skipping");
            name = NameListToString(objname);
            break;
        case OBJECT_FOREIGN_SERVER:
            msg = gettext_noop("server \"%s\" does not exist, skipping");
            name = NameListToString(objname);
            break;
        case OBJECT_OPCLASS:
            msg = gettext_noop("operator class \"%s\" does not exist for access method \"%s\", skipping");
            name = NameListToString(objname);
            args = strVal(linitial(objargs));
            break;
        case OBJECT_OPFAMILY:
            msg = gettext_noop("operator family \"%s\" does not exist for access method \"%s\", skipping");
            name = NameListToString(objname);
            args = strVal(linitial(objargs));
            break;
        default:
            elog(ERROR, "unexpected object type (%d)", (int) objtype);
            break;
    }

    if (!args)
        ereport(NOTICE, (errmsg(msg, name)));
    else
        ereport(NOTICE, (errmsg(msg, name, args)));
}

void RemoveObjects ( DropStmt stmt  ) 

Definition at line 47 of file dropcmds.c.

References AccessExclusiveLock, add_exact_object_address(), DropStmt::arguments, DropStmt::behavior, check_object_ownership(), does_not_exist_skipping(), elog, ereport, errcode(), errhint(), errmsg(), ERROR, free_object_addresses(), get_object_address(), get_object_namespace(), GETSTRUCT, GetUserId(), heap_close, HeapTupleIsValid, lfirst, list_head(), lnext, DropStmt::missing_ok, NameListToString(), new_object_addresses(), NoLock, OBJECT_FUNCTION, ObjectAddress::objectId, ObjectIdGetDatum, DropStmt::objects, OidIsValid, performMultipleDeletions(), pg_namespace_ownercheck(), PROCOID, ReleaseSysCache(), DropStmt::removeType, and SearchSysCache1.

Referenced by ExecDropStmt().

{
    ObjectAddresses *objects;
    ListCell   *cell1;
    ListCell   *cell2 = NULL;

    objects = new_object_addresses();

    foreach(cell1, stmt->objects)
    {
        ObjectAddress address;
        List       *objname = lfirst(cell1);
        List       *objargs = NIL;
        Relation    relation = NULL;
        Oid         namespaceId;

        if (stmt->arguments)
        {
            cell2 = (!cell2 ? list_head(stmt->arguments) : lnext(cell2));
            objargs = lfirst(cell2);
        }

        /* Get an ObjectAddress for the object. */
        address = get_object_address(stmt->removeType,
                                     objname, objargs,
                                     &relation,
                                     AccessExclusiveLock,
                                     stmt->missing_ok);

        /* Issue NOTICE if supplied object was not found. */
        if (!OidIsValid(address.objectId))
        {
            does_not_exist_skipping(stmt->removeType, objname, objargs);
            continue;
        }

        /*
         * Although COMMENT ON FUNCTION, SECURITY LABEL ON FUNCTION, etc. are
         * happy to operate on an aggregate as on any other function, we have
         * historically not allowed this for DROP FUNCTION.
         */
        if (stmt->removeType == OBJECT_FUNCTION)
        {
            Oid         funcOid = address.objectId;
            HeapTuple   tup;

            tup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcOid));
            if (!HeapTupleIsValid(tup)) /* should not happen */
                elog(ERROR, "cache lookup failed for function %u", funcOid);

            if (((Form_pg_proc) GETSTRUCT(tup))->proisagg)
                ereport(ERROR,
                        (errcode(ERRCODE_WRONG_OBJECT_TYPE),
                         errmsg("\"%s\" is an aggregate function",
                                NameListToString(objname)),
                errhint("Use DROP AGGREGATE to drop aggregate functions.")));

            ReleaseSysCache(tup);
        }

        /* Check permissions. */
        namespaceId = get_object_namespace(&address);
        if (!OidIsValid(namespaceId) ||
            !pg_namespace_ownercheck(namespaceId, GetUserId()))
            check_object_ownership(GetUserId(), stmt->removeType, address,
                                   objname, objargs, relation);

        /* Release any relcache reference count, but keep lock until commit. */
        if (relation)
            heap_close(relation, NoLock);

        add_exact_object_address(&address, objects);
    }

    /* Here we really delete them. */
    performMultipleDeletions(objects, stmt->behavior, 0);

    free_object_addresses(objects);
}