diff options
author | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2013-01-15 13:23:43 -0300 |
---|---|---|
committer | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2013-01-15 13:23:43 -0300 |
commit | 7ac5760fa283bc090c25e4ea495a0d2bb41db7b5 (patch) | |
tree | 023eec06b6465fd108a7dbfca628ab7de872c995 /src/backend/commands/functioncmds.c | |
parent | ffda05977a93f9b3f8a6b05657ba2f16decb6b23 (diff) | |
download | postgresql-7ac5760fa283bc090c25e4ea495a0d2bb41db7b5.tar.gz postgresql-7ac5760fa283bc090c25e4ea495a0d2bb41db7b5.zip |
Rework order of checks in ALTER / SET SCHEMA
When attempting to move an object into the schema in which it already
was, for most objects classes we were correctly complaining about
exactly that ("object is already in schema"); but for some other object
classes, such as functions, we were instead complaining of a name
collision ("object already exists in schema"). The latter is wrong and
misleading, per complaint from Robert Haas in
CA+TgmoZ0+gNf7RDKRc3u5rHXffP=QjqPZKGxb4BsPz65k7qnHQ@mail.gmail.com
To fix, refactor the way these checks are done. As a bonus, the
resulting code is smaller and can also share some code with Rename
cases.
While at it, remove use of getObjectDescriptionOids() in error messages.
These are normally disallowed because of translatability considerations,
but this one had slipped through since 9.1. (Not sure that this is
worth backpatching, though, as it would create some untranslated
messages in back branches.)
This is loosely based on a patch by KaiGai Kohei, heavily reworked by
me.
Diffstat (limited to 'src/backend/commands/functioncmds.c')
-rw-r--r-- | src/backend/commands/functioncmds.c | 82 |
1 files changed, 14 insertions, 68 deletions
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index c858511c1d9..4f8e82a8e69 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -1069,20 +1069,9 @@ RenameFunction(List *name, List *argtypes, const char *newname) namespaceOid = procForm->pronamespace; /* make sure the new name doesn't exist */ - if (SearchSysCacheExists3(PROCNAMEARGSNSP, - CStringGetDatum(newname), - PointerGetDatum(&procForm->proargtypes), - ObjectIdGetDatum(namespaceOid))) - { - ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_FUNCTION), - errmsg("function %s already exists in schema \"%s\"", - funcname_signature_string(newname, - procForm->pronargs, - NIL, - procForm->proargtypes.values), - get_namespace_name(namespaceOid)))); - } + IsThereFunctionInNamespace(newname, procForm->pronargs, + procForm->proargtypes, + namespaceOid); /* must be owner */ if (!pg_proc_ownercheck(procOid, GetUserId())) @@ -1688,71 +1677,28 @@ DropCastById(Oid castOid) } /* - * Execute ALTER FUNCTION/AGGREGATE SET SCHEMA + * Subroutine for ALTER FUNCTION/AGGREGATE SET SCHEMA * - * These commands are identical except for the lookup procedure, so share code. + * Is there a function with the given name and signature already in the given + * namespace? If so, raise an appropriate error message. */ -Oid -AlterFunctionNamespace(List *name, List *argtypes, bool isagg, - const char *newschema) -{ - Oid procOid; - Oid nspOid; - - /* get function OID */ - if (isagg) - procOid = LookupAggNameTypeNames(name, argtypes, false); - else - procOid = LookupFuncNameTypeNames(name, argtypes, false); - - /* get schema OID and check its permissions */ - nspOid = LookupCreationNamespace(newschema); - - AlterFunctionNamespace_oid(procOid, nspOid); - - return procOid; -} - -Oid -AlterFunctionNamespace_oid(Oid procOid, Oid nspOid) +void +IsThereFunctionInNamespace(const char *proname, int pronargs, + oidvector proargtypes, Oid nspOid) { - Oid oldNspOid; - HeapTuple tup; - Relation procRel; - Form_pg_proc proc; - - procRel = heap_open(ProcedureRelationId, RowExclusiveLock); - - /* - * We have to check for name collisions ourselves, because - * AlterObjectNamespace_internal doesn't know how to deal with the - * argument types. - */ - tup = SearchSysCacheCopy1(PROCOID, ObjectIdGetDatum(procOid)); - if (!HeapTupleIsValid(tup)) - elog(ERROR, "cache lookup failed for function %u", procOid); - proc = (Form_pg_proc) GETSTRUCT(tup); - /* check for duplicate name (more friendly than unique-index failure) */ if (SearchSysCacheExists3(PROCNAMEARGSNSP, - CStringGetDatum(NameStr(proc->proname)), - PointerGetDatum(&proc->proargtypes), + CStringGetDatum(proname), + PointerGetDatum(&proargtypes), ObjectIdGetDatum(nspOid))) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_FUNCTION), - errmsg("function \"%s\" already exists in schema \"%s\"", - NameStr(proc->proname), + errmsg("function %s already exists in schema \"%s\"", + funcname_signature_string(proname, pronargs, + NIL, proargtypes.values), get_namespace_name(nspOid)))); - - /* OK, do the work */ - oldNspOid = AlterObjectNamespace_internal(procRel, procOid, nspOid); - - heap_close(procRel, RowExclusiveLock); - - return oldNspOid; } - /* * ExecuteDoStmt * Execute inline procedural-language code |