Skip to content

Commit b42f09f

Browse files
committed
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ý
1 parent 2dde11a commit b42f09f

File tree

3 files changed

+82
-22
lines changed

3 files changed

+82
-22
lines changed

src/backend/catalog/pg_shdepend.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
#include "catalog/pg_proc.h"
3838
#include "catalog/pg_shdepend.h"
3939
#include "catalog/pg_tablespace.h"
40+
#include "catalog/pg_ts_config.h"
41+
#include "catalog/pg_ts_dict.h"
4042
#include "catalog/pg_type.h"
4143
#include "commands/dbcommands.h"
4244
#include "commands/collationcmds.h"
@@ -1405,6 +1407,14 @@ shdepReassignOwned(List *roleids, Oid newrole)
14051407
AlterExtensionOwner_oid(sdepForm->objid, newrole);
14061408
break;
14071409

1410+
case TSConfigRelationId:
1411+
AlterTSConfigurationOwner_oid(sdepForm->objid, newrole);
1412+
break;
1413+
1414+
case TSDictionaryRelationId:
1415+
AlterTSDictionaryOwner_oid(sdepForm->objid, newrole);
1416+
break;
1417+
14081418
default:
14091419
elog(ERROR, "unexpected classid %u", sdepForm->classid);
14101420
break;

src/backend/commands/tsearchcmds.c

Lines changed: 70 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -810,22 +810,16 @@ AlterTSDictionary(AlterTSDictionaryStmt *stmt)
810810
}
811811

812812
/*
813-
* ALTER TEXT SEARCH DICTIONARY OWNER
813+
* Internal routine for changing the owner of a text search dictionary
814814
*/
815-
void
816-
AlterTSDictionaryOwner(List *name, Oid newOwnerId)
815+
static void
816+
AlterTSDictionaryOwner_internal(Relation rel, Oid dictId, Oid newOwnerId)
817817
{
818818
HeapTuple tup;
819-
Relation rel;
820-
Oid dictId;
821819
Oid namespaceOid;
822820
AclResult aclresult;
823821
Form_pg_ts_dict form;
824822

825-
rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
826-
827-
dictId = get_ts_dict_oid(name, false);
828-
829823
tup = SearchSysCacheCopy1(TSDICTOID, ObjectIdGetDatum(dictId));
830824

831825
if (!HeapTupleIsValid(tup)) /* should not happen */
@@ -843,7 +837,7 @@ AlterTSDictionaryOwner(List *name, Oid newOwnerId)
843837
/* must be owner */
844838
if (!pg_ts_dict_ownercheck(dictId, GetUserId()))
845839
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSDICTIONARY,
846-
NameListToString(name));
840+
NameStr(form->dictname));
847841

848842
/* Must be able to become new owner */
849843
check_is_member_of_role(GetUserId(), newOwnerId);
@@ -865,10 +859,41 @@ AlterTSDictionaryOwner(List *name, Oid newOwnerId)
865859
newOwnerId);
866860
}
867861

868-
heap_close(rel, NoLock);
869862
heap_freetuple(tup);
870863
}
871864

865+
/*
866+
* ALTER TEXT SEARCH DICTIONARY OWNER
867+
*/
868+
void
869+
AlterTSDictionaryOwner(List *name, Oid newOwnerId)
870+
{
871+
Relation rel;
872+
Oid dictId;
873+
874+
rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
875+
dictId = get_ts_dict_oid(name, false);
876+
877+
AlterTSDictionaryOwner_internal(rel, dictId, newOwnerId);
878+
879+
heap_close(rel, NoLock);
880+
}
881+
882+
/*
883+
* Change text search dictionary owner, by OID
884+
*/
885+
void
886+
AlterTSDictionaryOwner_oid(Oid dictId, Oid newOwnerId)
887+
{
888+
Relation rel;
889+
890+
rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
891+
892+
AlterTSDictionaryOwner_internal(rel, dictId, newOwnerId);
893+
894+
heap_close(rel, NoLock);
895+
}
896+
872897
/* ---------------------- TS Template commands -----------------------*/
873898

874899
/*
@@ -1578,22 +1603,16 @@ RemoveTSConfigurationById(Oid cfgId)
15781603
}
15791604

15801605
/*
1581-
* ALTER TEXT SEARCH CONFIGURATION OWNER
1606+
* Internal routine for changing the owner of a text search configuration
15821607
*/
1583-
void
1584-
AlterTSConfigurationOwner(List *name, Oid newOwnerId)
1608+
static void
1609+
AlterTSConfigurationOwner_internal(Relation rel, Oid cfgId, Oid newOwnerId)
15851610
{
15861611
HeapTuple tup;
1587-
Relation rel;
1588-
Oid cfgId;
15891612
AclResult aclresult;
15901613
Oid namespaceOid;
15911614
Form_pg_ts_config form;
15921615

1593-
rel = heap_open(TSConfigRelationId, RowExclusiveLock);
1594-
1595-
cfgId = get_ts_config_oid(name, false);
1596-
15971616
tup = SearchSysCacheCopy1(TSCONFIGOID, ObjectIdGetDatum(cfgId));
15981617

15991618
if (!HeapTupleIsValid(tup)) /* should not happen */
@@ -1611,7 +1630,7 @@ AlterTSConfigurationOwner(List *name, Oid newOwnerId)
16111630
/* must be owner */
16121631
if (!pg_ts_config_ownercheck(cfgId, GetUserId()))
16131632
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSCONFIGURATION,
1614-
NameListToString(name));
1633+
NameStr(form->cfgname));
16151634

16161635
/* Must be able to become new owner */
16171636
check_is_member_of_role(GetUserId(), newOwnerId);
@@ -1633,10 +1652,39 @@ AlterTSConfigurationOwner(List *name, Oid newOwnerId)
16331652
newOwnerId);
16341653
}
16351654

1636-
heap_close(rel, NoLock);
16371655
heap_freetuple(tup);
16381656
}
16391657

1658+
/*
1659+
* ALTER TEXT SEARCH CONFIGURATION OWNER
1660+
*/
1661+
void
1662+
AlterTSConfigurationOwner(List *name, Oid newOwnerId)
1663+
{
1664+
Relation rel;
1665+
Oid cfgId;
1666+
1667+
rel = heap_open(TSConfigRelationId, RowExclusiveLock);
1668+
cfgId = get_ts_config_oid(name, false);
1669+
1670+
AlterTSConfigurationOwner_internal(rel, cfgId, newOwnerId);
1671+
1672+
heap_close(rel, NoLock);
1673+
}
1674+
1675+
void
1676+
AlterTSConfigurationOwner_oid(Oid cfgId, Oid newOwnerId)
1677+
{
1678+
Relation rel;
1679+
1680+
rel = heap_open(TSConfigRelationId, RowExclusiveLock);
1681+
1682+
AlterTSConfigurationOwner_internal(rel, cfgId, newOwnerId);
1683+
1684+
heap_close(rel, NoLock);
1685+
}
1686+
1687+
16401688
/*
16411689
* ALTER TEXT SEARCH CONFIGURATION - main entry point
16421690
*/

src/include/commands/defrem.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ extern void RenameTSDictionary(List *oldname, const char *newname);
107107
extern void RemoveTSDictionaryById(Oid dictId);
108108
extern void AlterTSDictionary(AlterTSDictionaryStmt *stmt);
109109
extern void AlterTSDictionaryOwner(List *name, Oid newOwnerId);
110+
extern void AlterTSDictionaryOwner_oid(Oid dictId, Oid newOwnerId);
110111
extern void AlterTSDictionaryNamespace(List *name, const char *newschema);
111112
extern Oid AlterTSDictionaryNamespace_oid(Oid dictId, Oid newNspOid);
112113

@@ -121,6 +122,7 @@ extern void RenameTSConfiguration(List *oldname, const char *newname);
121122
extern void RemoveTSConfigurationById(Oid cfgId);
122123
extern void AlterTSConfiguration(AlterTSConfigurationStmt *stmt);
123124
extern void AlterTSConfigurationOwner(List *name, Oid newOwnerId);
125+
extern void AlterTSConfigurationOwner_oid(Oid cfgId, Oid newOwnerId);
124126
extern void AlterTSConfigurationNamespace(List *name, const char *newschema);
125127
extern Oid AlterTSConfigurationNamespace_oid(Oid cfgId, Oid newNspOid);
126128

0 commit comments

Comments
 (0)