summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlvaro Herrera2014-07-15 17:24:07 +0000
committerAlvaro Herrera2014-07-15 17:24:07 +0000
commita41dc73211c9ab579bb2cd87ad7d0a6ecf0806fe (patch)
tree60dbe7a4ec2b617f3841748d8af4e0049b01b0f2
parent8ebf5f7206e0e4c5d4113cf67d3db8f2a90d7e0f (diff)
Fix REASSIGN OWNED for text search objects
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ý
-rw-r--r--src/backend/catalog/pg_shdepend.c10
-rw-r--r--src/backend/commands/tsearchcmds.c92
-rw-r--r--src/include/commands/defrem.h2
3 files changed, 82 insertions, 22 deletions
diff --git a/src/backend/catalog/pg_shdepend.c b/src/backend/catalog/pg_shdepend.c
index 77e038d267e..2df46fa89f8 100644
--- a/src/backend/catalog/pg_shdepend.c
+++ b/src/backend/catalog/pg_shdepend.c
@@ -37,6 +37,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/collationcmds.h"
@@ -1405,6 +1407,14 @@ shdepReassignOwned(List *roleids, Oid newrole)
AlterExtensionOwner_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;
diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c
index deac1062ef9..7d91e026c7a 100644
--- a/src/backend/commands/tsearchcmds.c
+++ b/src/backend/commands/tsearchcmds.c
@@ -942,22 +942,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 = get_ts_dict_oid(name, false);
-
tup = SearchSysCacheCopy1(TSDICTOID, ObjectIdGetDatum(dictId));
if (!HeapTupleIsValid(tup)) /* should not happen */
@@ -975,7 +969,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);
@@ -997,10 +991,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 = get_ts_dict_oid(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 -----------------------*/
/*
@@ -1833,22 +1858,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 = get_ts_config_oid(name, false);
-
tup = SearchSysCacheCopy1(TSCONFIGOID, ObjectIdGetDatum(cfgId));
if (!HeapTupleIsValid(tup)) /* should not happen */
@@ -1866,7 +1885,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);
@@ -1888,11 +1907,40 @@ 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 = get_ts_config_oid(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
*/
void
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index 65121b944cf..379eaad695c 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -125,6 +125,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 AlterTSDictionaryNamespace(List *name, const char *newschema);
extern Oid AlterTSDictionaryNamespace_oid(Oid dictId, Oid newNspOid);
@@ -141,6 +142,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 void AlterTSConfigurationNamespace(List *name, const char *newschema);
extern Oid AlterTSConfigurationNamespace_oid(Oid cfgId, Oid newNspOid);