Rework order of checks in ALTER / SET SCHEMA
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Tue, 15 Jan 2013 16:23:43 +0000 (13:23 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Tue, 15 Jan 2013 16:23:43 +0000 (13:23 -0300)
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.

src/backend/commands/alter.c
src/backend/commands/collationcmds.c
src/backend/commands/functioncmds.c
src/include/commands/alter.h
src/include/commands/collationcmds.h
src/include/commands/defrem.h
src/test/regress/expected/alter_generic.out

index 73138f940aed032f256925e1c6caa14f33ec84c7..b565e9b2c333e4e8c7f2abc2fb4edeb72ec3dc2d 100644 (file)
 #include "catalog/dependency.h"
 #include "catalog/indexing.h"
 #include "catalog/namespace.h"
+#include "catalog/pg_collation.h"
+#include "catalog/pg_conversion.h"
 #include "catalog/pg_largeobject.h"
 #include "catalog/pg_largeobject_metadata.h"
 #include "catalog/pg_namespace.h"
+#include "catalog/pg_proc.h"
+#include "catalog/pg_ts_config.h"
+#include "catalog/pg_ts_dict.h"
+#include "catalog/pg_ts_parser.h"
+#include "catalog/pg_ts_template.h"
 #include "commands/alter.h"
 #include "commands/collationcmds.h"
 #include "commands/conversioncmds.h"
@@ -46,6 +53,8 @@
 #include "utils/tqual.h"
 
 
+static Oid AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid);
+
 /*
  * Executes an ALTER OBJECT / RENAME TO statement. Based on the object
  * type, the function appropriate to that type is executed.
@@ -146,40 +155,32 @@ ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt)
 {
    switch (stmt->objectType)
    {
-       case OBJECT_AGGREGATE:
-           return AlterFunctionNamespace(stmt->object, stmt->objarg, true,
-                                         stmt->newschema);
-
-       case OBJECT_COLLATION:
-           return AlterCollationNamespace(stmt->object, stmt->newschema);
-
        case OBJECT_EXTENSION:
            return AlterExtensionNamespace(stmt->object, stmt->newschema);
 
-       case OBJECT_FUNCTION:
-           return AlterFunctionNamespace(stmt->object, stmt->objarg, false,
-                                         stmt->newschema);
-
+       case OBJECT_FOREIGN_TABLE:
        case OBJECT_SEQUENCE:
        case OBJECT_TABLE:
        case OBJECT_VIEW:
-       case OBJECT_FOREIGN_TABLE:
            return AlterTableNamespace(stmt);
 
-       case OBJECT_TYPE:
        case OBJECT_DOMAIN:
+       case OBJECT_TYPE:
            return AlterTypeNamespace(stmt->object, stmt->newschema,
                                      stmt->objectType);
 
            /* generic code path */
+       case OBJECT_AGGREGATE:
+       case OBJECT_COLLATION:
        case OBJECT_CONVERSION:
+       case OBJECT_FUNCTION:
        case OBJECT_OPERATOR:
        case OBJECT_OPCLASS:
        case OBJECT_OPFAMILY:
-       case OBJECT_TSPARSER:
+       case OBJECT_TSCONFIGURATION:
        case OBJECT_TSDICTIONARY:
+       case OBJECT_TSPARSER:
        case OBJECT_TSTEMPLATE:
-       case OBJECT_TSCONFIGURATION:
            {
                Relation    catalog;
                Relation    relation;
@@ -253,22 +254,16 @@ AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid,
                break;
            }
 
-       case OCLASS_PROC:
-           oldNspOid = AlterFunctionNamespace_oid(objid, nspOid);
-           break;
-
        case OCLASS_TYPE:
            oldNspOid = AlterTypeNamespace_oid(objid, nspOid, objsMoved);
            break;
 
        case OCLASS_COLLATION:
-           oldNspOid = AlterCollationNamespace_oid(objid, nspOid);
-           break;
-
        case OCLASS_CONVERSION:
        case OCLASS_OPERATOR:
        case OCLASS_OPCLASS:
        case OCLASS_OPFAMILY:
+       case OCLASS_PROC:
        case OCLASS_TSPARSER:
        case OCLASS_TSDICT:
        case OCLASS_TSTEMPLATE:
@@ -292,6 +287,43 @@ AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid,
    return oldNspOid;
 }
 
+/*
+ * Raise an error to the effect that an object of the given name is already
+ * present in the given namespace.
+ */
+static void
+report_namespace_conflict(Oid classId, const char *name, Oid nspOid)
+{
+   char   *msgfmt;
+
+   Assert(OidIsValid(nspOid));
+   switch (classId)
+   {
+       case ConversionRelationId:
+           msgfmt = gettext_noop("conversion \"%s\" already exists in schema \"%s\"");
+           break;
+       case TSParserRelationId:
+           msgfmt = gettext_noop("text search parser \"%s\" already exists in schema \"%s\"");
+           break;
+       case TSDictionaryRelationId:
+           msgfmt = gettext_noop("text search dictionary \"%s\" already exists in schema \"%s\"");
+           break;
+       case TSTemplateRelationId:
+           msgfmt = gettext_noop("text search template \"%s\" already exists in schema \"%s\"");
+           break;
+       case TSConfigRelationId:
+           msgfmt = gettext_noop("text search configuration \"%s\" already exists in schema \"%s\"");
+           break;
+       default:
+           elog(ERROR, "unsupported object class %u", classId);
+           break;
+   }
+
+   ereport(ERROR,
+           (errcode(ERRCODE_DUPLICATE_OBJECT),
+            errmsg(msgfmt, name, get_namespace_name(nspOid))));
+}
+
 /*
  * Generic function to change the namespace of a given object, for simple
  * cases (won't work for tables, nor other cases where we need to do more
@@ -303,7 +335,7 @@ AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid,
  *
  * Returns the OID of the object's previous namespace.
  */
-Oid
+static Oid
 AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid)
 {
    Oid         classId = RelationGetRelid(rel);
@@ -373,13 +405,36 @@ AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid)
     * Since this is just a friendliness check, we can just skip it in cases
     * where there isn't a suitable syscache available.
     */
-   if (nameCacheId >= 0 &&
-       SearchSysCacheExists2(nameCacheId, name, ObjectIdGetDatum(nspOid)))
-       ereport(ERROR,
-               (errcode(ERRCODE_DUPLICATE_OBJECT),
-                errmsg("%s already exists in schema \"%s\"",
-                       getObjectDescriptionOids(classId, objid),
-                       get_namespace_name(nspOid))));
+   if (classId == ProcedureRelationId)
+   {
+       HeapTuple   tup;
+       Form_pg_proc proc;
+
+       tup = SearchSysCacheCopy1(PROCOID, ObjectIdGetDatum(objid));
+       if (!HeapTupleIsValid(tup))
+           elog(ERROR, "cache lookup failed for function %u", objid);
+       proc = (Form_pg_proc) GETSTRUCT(tup);
+
+       IsThereFunctionInNamespace(NameStr(proc->proname), proc->pronargs,
+                                  proc->proargtypes, nspOid);
+       heap_freetuple(tup);
+   }
+   else if (classId == CollationRelationId)
+   {
+       char *collname;
+
+       collname = get_collation_name(objid);
+       if (!collname)
+           elog(ERROR, "cache lookup failed for collation %u", objid);
+       IsThereCollationInNamespace(collname, nspOid);
+       pfree(collname);
+   }
+   else if (nameCacheId >= 0 &&
+            SearchSysCacheExists2(nameCacheId, name,
+                                  ObjectIdGetDatum(nspOid)))
+       report_namespace_conflict(classId,
+                                 NameStr(*(DatumGetName(name))),
+                                 nspOid);
 
    /* Build modified tuple */
    values = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(Datum));
@@ -406,7 +461,6 @@ AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid)
    return oldNspOid;
 }
 
-
 /*
  * Executes an ALTER OBJECT / OWNER TO statement.  Based on the object
  * type, the function appropriate to that type is executed.
index b763f15b30dff40e1e8f1b270ba67bc7b71ae6bd..67200f87ba543ad95b519bfa27ce6effc4cb6cae 100644 (file)
@@ -167,27 +167,7 @@ RenameCollation(List *name, const char *newname)
    namespaceOid = ((Form_pg_collation) GETSTRUCT(tup))->collnamespace;
 
    /* make sure the new name doesn't exist */
-   if (SearchSysCacheExists3(COLLNAMEENCNSP,
-                             CStringGetDatum(newname),
-                             Int32GetDatum(GetDatabaseEncoding()),
-                             ObjectIdGetDatum(namespaceOid)))
-       ereport(ERROR,
-               (errcode(ERRCODE_DUPLICATE_OBJECT),
-                errmsg("collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"",
-                       newname,
-                       GetDatabaseEncodingName(),
-                       get_namespace_name(namespaceOid))));
-
-   /* mustn't match an any-encoding entry, either */
-   if (SearchSysCacheExists3(COLLNAMEENCNSP,
-                             CStringGetDatum(newname),
-                             Int32GetDatum(-1),
-                             ObjectIdGetDatum(namespaceOid)))
-       ereport(ERROR,
-               (errcode(ERRCODE_DUPLICATE_OBJECT),
-                errmsg("collation \"%s\" already exists in schema \"%s\"",
-                       newname,
-                       get_namespace_name(namespaceOid))));
+   IsThereCollationInNamespace(newname, namespaceOid);
 
    /* must be owner */
    if (!pg_collation_ownercheck(collationOid, GetUserId()))
@@ -213,71 +193,32 @@ RenameCollation(List *name, const char *newname)
 }
 
 /*
- * Execute ALTER COLLATION SET SCHEMA
- */
-Oid
-AlterCollationNamespace(List *name, const char *newschema)
-{
-   Oid         collOid,
-               nspOid;
-
-   collOid = get_collation_oid(name, false);
-
-   nspOid = LookupCreationNamespace(newschema);
-
-   AlterCollationNamespace_oid(collOid, nspOid);
-
-   return collOid;
-}
-
-/*
- * Change collation schema, by oid
+ * Subroutine for ALTER COLLATION SET SCHEMA and RENAME
+ *
+ * Is there a collation with the same name of the given collation already in
+ * the given namespace?  If so, raise an appropriate error message.
  */
-Oid
-AlterCollationNamespace_oid(Oid collOid, Oid newNspOid)
+void
+IsThereCollationInNamespace(const char *collname, Oid nspOid)
 {
-   Oid         oldNspOid;
-   Relation    rel;
-   char       *collation_name;
-
-   rel = heap_open(CollationRelationId, RowExclusiveLock);
-
-   /*
-    * We have to check for name collision ourselves, because
-    * AlterObjectNamespace_internal doesn't know how to deal with the encoding
-    * considerations.
-    */
-   collation_name = get_collation_name(collOid);
-   if (!collation_name)
-       elog(ERROR, "cache lookup failed for collation %u", collOid);
-
    /* make sure the name doesn't already exist in new schema */
    if (SearchSysCacheExists3(COLLNAMEENCNSP,
-                             CStringGetDatum(collation_name),
+                             CStringGetDatum(collname),
                              Int32GetDatum(GetDatabaseEncoding()),
-                             ObjectIdGetDatum(newNspOid)))
+                             ObjectIdGetDatum(nspOid)))
        ereport(ERROR,
                (errcode(ERRCODE_DUPLICATE_OBJECT),
                 errmsg("collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"",
-                       collation_name,
-                       GetDatabaseEncodingName(),
-                       get_namespace_name(newNspOid))));
+                       collname, GetDatabaseEncodingName(),
+                       get_namespace_name(nspOid))));
 
    /* mustn't match an any-encoding entry, either */
    if (SearchSysCacheExists3(COLLNAMEENCNSP,
-                             CStringGetDatum(collation_name),
+                             CStringGetDatum(collname),
                              Int32GetDatum(-1),
-                             ObjectIdGetDatum(newNspOid)))
+                             ObjectIdGetDatum(nspOid)))
        ereport(ERROR,
                (errcode(ERRCODE_DUPLICATE_OBJECT),
                 errmsg("collation \"%s\" already exists in schema \"%s\"",
-                       collation_name,
-                       get_namespace_name(newNspOid))));
-
-   /* OK, do the work */
-   oldNspOid = AlterObjectNamespace_internal(rel, collOid, newNspOid);
-
-   heap_close(rel, RowExclusiveLock);
-
-   return oldNspOid;
+                       collname, get_namespace_name(nspOid))));
 }
index c858511c1d9b2c602dd27b118440a30622aaceff..4f8e82a8e6978f3656e87acc626c932fd71651eb 100644 (file)
@@ -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
index 37e095efa562316190ccfeafafbbcb6c0053162c..b9400a98128a789ce35ca59e0d6d27fef18fc4f2 100644 (file)
@@ -21,9 +21,8 @@
 extern Oid ExecRenameStmt(RenameStmt *stmt);
 
 extern Oid ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt);
-extern Oid AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid,
+extern Oid AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid,
                         ObjectAddresses *objsMoved);
-extern Oid AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid);
 
 extern Oid ExecAlterOwnerStmt(AlterOwnerStmt *stmt);
 extern void AlterObjectOwner_internal(Relation catalog, Oid objectId,
index c7b536a6358989d201f70f8b49bed192ed8bd4f9..5aaa1781726e977761cff17eb3666ff8b788b543 100644 (file)
@@ -19,7 +19,6 @@
 
 extern Oid DefineCollation(List *names, List *parameters);
 extern Oid RenameCollation(List *name, const char *newname);
-extern Oid AlterCollationNamespace(List *name, const char *newschema);
-extern Oid AlterCollationNamespace_oid(Oid collOid, Oid newNspOid);
+extern void IsThereCollationInNamespace(const char *collname, Oid newNspOid);
 
 #endif   /* COLLATIONCMDS_H */
index c327136a36db6dc92f9eb78ee891e2c7a6262aeb..7de6d5de9792727c05d29e9659f870228c6c564a 100644 (file)
@@ -50,9 +50,8 @@ extern Oid RenameFunction(List *name, List *argtypes, const char *newname);
 extern Oid AlterFunction(AlterFunctionStmt *stmt);
 extern Oid CreateCast(CreateCastStmt *stmt);
 extern void DropCastById(Oid castOid);
-extern Oid AlterFunctionNamespace(List *name, List *argtypes, bool isagg,
-                                 const char *newschema);
-extern Oid AlterFunctionNamespace_oid(Oid procOid, Oid nspOid);
+extern void IsThereFunctionInNamespace(const char *proname, int pronargs,
+                          oidvector proargtypes, Oid nspOid);
 extern void ExecuteDoStmt(DoStmt *stmt);
 extern Oid get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok);
 
index 3beddd783e38e6e93ca90da8a4849bfff1837f7d..f27d21787e302f389e15af9ad62c07ac9a8f562a 100644 (file)
@@ -69,7 +69,7 @@ ERROR:  must be member of role "regtest_alter_user3"
 ALTER FUNCTION alt_func3(int) SET SCHEMA alt_nsp2;      -- failed (not owner)
 ERROR:  must be owner of function alt_func3
 ALTER FUNCTION alt_func2(int) SET SCHEMA alt_nsp2; -- failed (name conflicts)
-ERROR:  function "alt_func2" already exists in schema "alt_nsp2"
+ERROR:  function alt_func2(integer) already exists in schema "alt_nsp2"
 ALTER AGGREGATE alt_agg3(int) RENAME TO alt_agg4;   -- failed (not owner)
 ERROR:  must be owner of function alt_agg3
 ALTER AGGREGATE alt_agg1(int) RENAME TO alt_agg4;   -- OK
@@ -80,7 +80,7 @@ ERROR:  must be member of role "regtest_alter_user3"
 ALTER AGGREGATE alt_agg3(int) SET SCHEMA alt_nsp2;  -- failed (not owner)
 ERROR:  must be owner of function alt_agg3
 ALTER AGGREGATE alt_agg2(int) SET SCHEMA alt_nsp2;  -- failed (name conflict)
-ERROR:  function "alt_agg2" already exists in schema "alt_nsp2"
+ERROR:  function alt_agg2(integer) already exists in schema "alt_nsp2"
 RESET SESSION AUTHORIZATION;
 SELECT n.nspname, proname, prorettype::regtype, proisagg, a.rolname
   FROM pg_proc p, pg_namespace n, pg_authid a
@@ -129,7 +129,7 @@ ERROR:  must be member of role "regtest_alter_user3"
 ALTER CONVERSION alt_conv3 SET SCHEMA alt_nsp2;  -- failed (not owner)
 ERROR:  must be owner of conversion alt_conv3
 ALTER CONVERSION alt_conv2 SET SCHEMA alt_nsp2;  -- failed (name conflict)
-ERROR:  conversion alt_conv2 already exists in schema "alt_nsp2"
+ERROR:  conversion "alt_conv2" already exists in schema "alt_nsp2"
 RESET SESSION AUTHORIZATION;
 SELECT n.nspname, c.conname, a.rolname
   FROM pg_conversion c, pg_namespace n, pg_authid a
@@ -346,7 +346,7 @@ ERROR:  must be member of role "regtest_alter_user3"
 ALTER TEXT SEARCH DICTIONARY alt_ts_dict3 SET SCHEMA alt_nsp2;  -- failed (not owner)
 ERROR:  must be owner of text search dictionary alt_ts_dict3
 ALTER TEXT SEARCH DICTIONARY alt_ts_dict2 SET SCHEMA alt_nsp2;  -- failed (name conflict)
-ERROR:  text search dictionary alt_ts_dict2 already exists in schema "alt_nsp2"
+ERROR:  text search dictionary "alt_ts_dict2" already exists in schema "alt_nsp2"
 RESET SESSION AUTHORIZATION;
 SELECT nspname, dictname, rolname
   FROM pg_ts_dict t, pg_namespace n, pg_authid a
@@ -387,7 +387,7 @@ ERROR:  must be member of role "regtest_alter_user3"
 ALTER TEXT SEARCH CONFIGURATION alt_ts_conf3 SET SCHEMA alt_nsp2;  -- failed (not owner)
 ERROR:  must be owner of text search configuration alt_ts_conf3
 ALTER TEXT SEARCH CONFIGURATION alt_ts_conf2 SET SCHEMA alt_nsp2;  -- failed (name conflict)
-ERROR:  text search configuration alt_ts_conf2 already exists in schema "alt_nsp2"
+ERROR:  text search configuration "alt_ts_conf2" already exists in schema "alt_nsp2"
 RESET SESSION AUTHORIZATION;
 SELECT nspname, cfgname, rolname
   FROM pg_ts_config t, pg_namespace n, pg_authid a
@@ -413,7 +413,7 @@ ALTER TEXT SEARCH TEMPLATE alt_ts_temp1 RENAME TO alt_ts_temp3; -- OK
 ALTER TEXT SEARCH TEMPLATE alt_ts_temp2 SET SCHEMA alt_nsp2;    -- OK
 CREATE TEXT SEARCH TEMPLATE alt_ts_temp2 (lexize=dsimple_lexize);
 ALTER TEXT SEARCH TEMPLATE alt_ts_temp2 SET SCHEMA alt_nsp2;    -- failed (name conflict)
-ERROR:  text search template alt_ts_temp2 already exists in schema "alt_nsp2"
+ERROR:  text search template "alt_ts_temp2" already exists in schema "alt_nsp2"
 SELECT nspname, tmplname
   FROM pg_ts_template t, pg_namespace n
   WHERE t.tmplnamespace = n.oid AND nspname like 'alt_nsp%'
@@ -439,7 +439,7 @@ ALTER TEXT SEARCH PARSER alt_ts_prs2 SET SCHEMA alt_nsp2;   -- OK
 CREATE TEXT SEARCH PARSER alt_ts_prs2
     (start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype);
 ALTER TEXT SEARCH PARSER alt_ts_prs2 SET SCHEMA alt_nsp2;   -- failed (name conflict)
-ERROR:  text search parser alt_ts_prs2 already exists in schema "alt_nsp2"
+ERROR:  text search parser "alt_ts_prs2" already exists in schema "alt_nsp2"
 SELECT nspname, prsname
   FROM pg_ts_parser t, pg_namespace n
   WHERE t.prsnamespace = n.oid AND nspname like 'alt_nsp%'