]> granicus.if.org Git - postgresql/commitdiff
Fix REASSIGN OWNED for text search objects
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Tue, 15 Jul 2014 17:24:07 +0000 (13:24 -0400)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Tue, 15 Jul 2014 17:24:07 +0000 (13:24 -0400)
Trying to reassign objects owned by a user that had text search
dictionaries or configurations used to fail with:
ERROR:  unexpected classid 3600
or
ERROR:  unexpected classid 3602

Fix by adding cases for those object types in a switch in pg_shdepend.c.

Both REASSIGN OWNED and text search objects go back all the way to 8.1,
so backpatch to all supported branches.  In 9.3 the alter-owner code was
made generic, so the required change in recent branches is pretty
simple; however, for 9.2 and older ones we need some additional
reshuffling to enable specifying objects by OID rather than name.

Text search templates and parsers are not owned objects, so there's no
change required for them.

Per bug #9749 reported by Michal Novotný

src/backend/catalog/pg_shdepend.c
src/backend/commands/tsearchcmds.c
src/include/commands/defrem.h

index f77f8e3b8b31a2b8b68c71bb9c4f027b99bb1c09..b6afd5cf4f7e565684f80647e06e0a1a59e613d9 100644 (file)
@@ -35,6 +35,8 @@
 #include "catalog/pg_proc.h"
 #include "catalog/pg_shdepend.h"
 #include "catalog/pg_tablespace.h"
+#include "catalog/pg_ts_config.h"
+#include "catalog/pg_ts_dict.h"
 #include "catalog/pg_type.h"
 #include "commands/dbcommands.h"
 #include "commands/conversioncmds.h"
@@ -1393,6 +1395,14 @@ shdepReassignOwned(List *roleids, Oid newrole)
                                        AlterForeignDataWrapperOwner_oid(sdepForm->objid, newrole);
                                        break;
 
+                               case TSConfigRelationId:
+                                       AlterTSConfigurationOwner_oid(sdepForm->objid, newrole);
+                                       break;
+
+                               case TSDictionaryRelationId:
+                                       AlterTSDictionaryOwner_oid(sdepForm->objid, newrole);
+                                       break;
+
                                default:
                                        elog(ERROR, "unexpected classid %u", sdepForm->classid);
                                        break;
index 522ea6e2f58fd002baeb9d18687ff7e15361767e..e5ed1858fc12978a07c3031355e3db3e186c08e6 100644 (file)
@@ -827,22 +827,16 @@ AlterTSDictionary(AlterTSDictionaryStmt *stmt)
 }
 
 /*
- * ALTER TEXT SEARCH DICTIONARY OWNER
+ * Internal routine for changing the owner of a text search dictionary
  */
-void
-AlterTSDictionaryOwner(List *name, Oid newOwnerId)
+static void
+AlterTSDictionaryOwner_internal(Relation rel, Oid dictId, Oid newOwnerId)
 {
        HeapTuple       tup;
-       Relation        rel;
-       Oid                     dictId;
        Oid                     namespaceOid;
        AclResult       aclresult;
        Form_pg_ts_dict form;
 
-       rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
-
-       dictId = TSDictionaryGetDictid(name, false);
-
        tup = SearchSysCacheCopy1(TSDICTOID, ObjectIdGetDatum(dictId));
 
        if (!HeapTupleIsValid(tup)) /* should not happen */
@@ -860,7 +854,7 @@ AlterTSDictionaryOwner(List *name, Oid newOwnerId)
                        /* must be owner */
                        if (!pg_ts_dict_ownercheck(dictId, GetUserId()))
                                aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSDICTIONARY,
-                                                          NameListToString(name));
+                                                          NameStr(form->dictname));
 
                        /* Must be able to become new owner */
                        check_is_member_of_role(GetUserId(), newOwnerId);
@@ -882,10 +876,41 @@ AlterTSDictionaryOwner(List *name, Oid newOwnerId)
                                                                newOwnerId);
        }
 
-       heap_close(rel, NoLock);
        heap_freetuple(tup);
 }
 
+/*
+ * ALTER TEXT SEARCH DICTIONARY OWNER
+ */
+void
+AlterTSDictionaryOwner(List *name, Oid newOwnerId)
+{
+       Relation        rel;
+       Oid                     dictId;
+
+       rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
+       dictId = TSDictionaryGetDictid(name, false);
+
+       AlterTSDictionaryOwner_internal(rel, dictId, newOwnerId);
+
+       heap_close(rel, NoLock);
+}
+
+/*
+ * Change text search dictionary owner, by OID
+ */
+void
+AlterTSDictionaryOwner_oid(Oid dictId, Oid newOwnerId)
+{
+       Relation        rel;
+
+       rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
+
+       AlterTSDictionaryOwner_internal(rel, dictId, newOwnerId);
+
+       heap_close(rel, NoLock);
+}
+
 /* ---------------------- TS Template commands -----------------------*/
 
 /*
@@ -1612,22 +1637,16 @@ RemoveTSConfigurationById(Oid cfgId)
 }
 
 /*
- * ALTER TEXT SEARCH CONFIGURATION OWNER
+ * Internal routine for changing the owner of a text search configuration
  */
-void
-AlterTSConfigurationOwner(List *name, Oid newOwnerId)
+static void
+AlterTSConfigurationOwner_internal(Relation rel, Oid cfgId, Oid newOwnerId)
 {
        HeapTuple       tup;
-       Relation        rel;
-       Oid                     cfgId;
        AclResult       aclresult;
        Oid                     namespaceOid;
        Form_pg_ts_config form;
 
-       rel = heap_open(TSConfigRelationId, RowExclusiveLock);
-
-       cfgId = TSConfigGetCfgid(name, false);
-
        tup = SearchSysCacheCopy1(TSCONFIGOID, ObjectIdGetDatum(cfgId));
 
        if (!HeapTupleIsValid(tup)) /* should not happen */
@@ -1645,7 +1664,7 @@ AlterTSConfigurationOwner(List *name, Oid newOwnerId)
                        /* must be owner */
                        if (!pg_ts_config_ownercheck(cfgId, GetUserId()))
                                aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSCONFIGURATION,
-                                                          NameListToString(name));
+                                                          NameStr(form->cfgname));
 
                        /* Must be able to become new owner */
                        check_is_member_of_role(GetUserId(), newOwnerId);
@@ -1667,10 +1686,39 @@ AlterTSConfigurationOwner(List *name, Oid newOwnerId)
                                                                newOwnerId);
        }
 
-       heap_close(rel, NoLock);
        heap_freetuple(tup);
 }
 
+/*
+ * ALTER TEXT SEARCH CONFIGURATION OWNER
+ */
+void
+AlterTSConfigurationOwner(List *name, Oid newOwnerId)
+{
+       Relation        rel;
+       Oid                     cfgId;
+
+       rel = heap_open(TSConfigRelationId, RowExclusiveLock);
+       cfgId = TSConfigGetCfgid(name, false);
+
+       AlterTSConfigurationOwner_internal(rel, cfgId, newOwnerId);
+
+       heap_close(rel, NoLock);
+}
+
+void
+AlterTSConfigurationOwner_oid(Oid cfgId, Oid newOwnerId)
+{
+       Relation        rel;
+
+       rel = heap_open(TSConfigRelationId, RowExclusiveLock);
+
+       AlterTSConfigurationOwner_internal(rel, cfgId, newOwnerId);
+
+       heap_close(rel, NoLock);
+}
+
+
 /*
  * ALTER TEXT SEARCH CONFIGURATION - main entry point
  */
index deebecc8dde8c6a07b2ad9b8a2bc55a02bb4c232..3d61bab51279cd11982e4cfa382afc6f62d06885 100644 (file)
@@ -112,6 +112,7 @@ extern void RemoveTSDictionaries(DropStmt *drop);
 extern void RemoveTSDictionaryById(Oid dictId);
 extern void AlterTSDictionary(AlterTSDictionaryStmt *stmt);
 extern void AlterTSDictionaryOwner(List *name, Oid newOwnerId);
+extern void AlterTSDictionaryOwner_oid(Oid dictId, Oid newOwnerId);
 
 extern void DefineTSTemplate(List *names, List *parameters);
 extern void RenameTSTemplate(List *oldname, const char *newname);
@@ -124,6 +125,7 @@ extern void RemoveTSConfigurations(DropStmt *stmt);
 extern void RemoveTSConfigurationById(Oid cfgId);
 extern void AlterTSConfiguration(AlterTSConfigurationStmt *stmt);
 extern void AlterTSConfigurationOwner(List *name, Oid newOwnerId);
+extern void AlterTSConfigurationOwner_oid(Oid cfgId, Oid newOwnerId);
 
 extern text *serialize_deflist(List *deflist);
 extern List *deserialize_deflist(Datum txt);