Skip to content

Commit a41dc73

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 8ebf5f7 commit a41dc73

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
@@ -942,22 +942,16 @@ AlterTSDictionary(AlterTSDictionaryStmt *stmt)
942942
}
943943

944944
/*
945-
* ALTER TEXT SEARCH DICTIONARY OWNER
945+
* Internal routine for changing the owner of a text search dictionary
946946
*/
947-
void
948-
AlterTSDictionaryOwner(List *name, Oid newOwnerId)
947+
static void
948+
AlterTSDictionaryOwner_internal(Relation rel, Oid dictId, Oid newOwnerId)
949949
{
950950
HeapTuple tup;
951-
Relation rel;
952-
Oid dictId;
953951
Oid namespaceOid;
954952
AclResult aclresult;
955953
Form_pg_ts_dict form;
956954

957-
rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
958-
959-
dictId = get_ts_dict_oid(name, false);
960-
961955
tup = SearchSysCacheCopy1(TSDICTOID, ObjectIdGetDatum(dictId));
962956

963957
if (!HeapTupleIsValid(tup)) /* should not happen */
@@ -975,7 +969,7 @@ AlterTSDictionaryOwner(List *name, Oid newOwnerId)
975969
/* must be owner */
976970
if (!pg_ts_dict_ownercheck(dictId, GetUserId()))
977971
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSDICTIONARY,
978-
NameListToString(name));
972+
NameStr(form->dictname));
979973

980974
/* Must be able to become new owner */
981975
check_is_member_of_role(GetUserId(), newOwnerId);
@@ -997,10 +991,41 @@ AlterTSDictionaryOwner(List *name, Oid newOwnerId)
997991
newOwnerId);
998992
}
999993

1000-
heap_close(rel, NoLock);
1001994
heap_freetuple(tup);
1002995
}
1003996

997+
/*
998+
* ALTER TEXT SEARCH DICTIONARY OWNER
999+
*/
1000+
void
1001+
AlterTSDictionaryOwner(List *name, Oid newOwnerId)
1002+
{
1003+
Relation rel;
1004+
Oid dictId;
1005+
1006+
rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
1007+
dictId = get_ts_dict_oid(name, false);
1008+
1009+
AlterTSDictionaryOwner_internal(rel, dictId, newOwnerId);
1010+
1011+
heap_close(rel, NoLock);
1012+
}
1013+
1014+
/*
1015+
* Change text search dictionary owner, by OID
1016+
*/
1017+
void
1018+
AlterTSDictionaryOwner_oid(Oid dictId, Oid newOwnerId)
1019+
{
1020+
Relation rel;
1021+
1022+
rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
1023+
1024+
AlterTSDictionaryOwner_internal(rel, dictId, newOwnerId);
1025+
1026+
heap_close(rel, NoLock);
1027+
}
1028+
10041029
/* ---------------------- TS Template commands -----------------------*/
10051030

10061031
/*
@@ -1833,22 +1858,16 @@ RemoveTSConfigurationById(Oid cfgId)
18331858
}
18341859

18351860
/*
1836-
* ALTER TEXT SEARCH CONFIGURATION OWNER
1861+
* Internal routine for changing the owner of a text search configuration
18371862
*/
1838-
void
1839-
AlterTSConfigurationOwner(List *name, Oid newOwnerId)
1863+
static void
1864+
AlterTSConfigurationOwner_internal(Relation rel, Oid cfgId, Oid newOwnerId)
18401865
{
18411866
HeapTuple tup;
1842-
Relation rel;
1843-
Oid cfgId;
18441867
AclResult aclresult;
18451868
Oid namespaceOid;
18461869
Form_pg_ts_config form;
18471870

1848-
rel = heap_open(TSConfigRelationId, RowExclusiveLock);
1849-
1850-
cfgId = get_ts_config_oid(name, false);
1851-
18521871
tup = SearchSysCacheCopy1(TSCONFIGOID, ObjectIdGetDatum(cfgId));
18531872

18541873
if (!HeapTupleIsValid(tup)) /* should not happen */
@@ -1866,7 +1885,7 @@ AlterTSConfigurationOwner(List *name, Oid newOwnerId)
18661885
/* must be owner */
18671886
if (!pg_ts_config_ownercheck(cfgId, GetUserId()))
18681887
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSCONFIGURATION,
1869-
NameListToString(name));
1888+
NameStr(form->cfgname));
18701889

18711890
/* Must be able to become new owner */
18721891
check_is_member_of_role(GetUserId(), newOwnerId);
@@ -1888,10 +1907,39 @@ AlterTSConfigurationOwner(List *name, Oid newOwnerId)
18881907
newOwnerId);
18891908
}
18901909

1891-
heap_close(rel, NoLock);
18921910
heap_freetuple(tup);
18931911
}
18941912

1913+
/*
1914+
* ALTER TEXT SEARCH CONFIGURATION OWNER
1915+
*/
1916+
void
1917+
AlterTSConfigurationOwner(List *name, Oid newOwnerId)
1918+
{
1919+
Relation rel;
1920+
Oid cfgId;
1921+
1922+
rel = heap_open(TSConfigRelationId, RowExclusiveLock);
1923+
cfgId = get_ts_config_oid(name, false);
1924+
1925+
AlterTSConfigurationOwner_internal(rel, cfgId, newOwnerId);
1926+
1927+
heap_close(rel, NoLock);
1928+
}
1929+
1930+
void
1931+
AlterTSConfigurationOwner_oid(Oid cfgId, Oid newOwnerId)
1932+
{
1933+
Relation rel;
1934+
1935+
rel = heap_open(TSConfigRelationId, RowExclusiveLock);
1936+
1937+
AlterTSConfigurationOwner_internal(rel, cfgId, newOwnerId);
1938+
1939+
heap_close(rel, NoLock);
1940+
}
1941+
1942+
18951943
/*
18961944
* ALTER TEXT SEARCH CONFIGURATION - main entry point
18971945
*/

src/include/commands/defrem.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ extern void RemoveTSDictionaries(DropStmt *drop);
125125
extern void RemoveTSDictionaryById(Oid dictId);
126126
extern void AlterTSDictionary(AlterTSDictionaryStmt *stmt);
127127
extern void AlterTSDictionaryOwner(List *name, Oid newOwnerId);
128+
extern void AlterTSDictionaryOwner_oid(Oid dictId, Oid newOwnerId);
128129
extern void AlterTSDictionaryNamespace(List *name, const char *newschema);
129130
extern Oid AlterTSDictionaryNamespace_oid(Oid dictId, Oid newNspOid);
130131

@@ -141,6 +142,7 @@ extern void RemoveTSConfigurations(DropStmt *stmt);
141142
extern void RemoveTSConfigurationById(Oid cfgId);
142143
extern void AlterTSConfiguration(AlterTSConfigurationStmt *stmt);
143144
extern void AlterTSConfigurationOwner(List *name, Oid newOwnerId);
145+
extern void AlterTSConfigurationOwner_oid(Oid cfgId, Oid newOwnerId);
144146
extern void AlterTSConfigurationNamespace(List *name, const char *newschema);
145147
extern Oid AlterTSConfigurationNamespace_oid(Oid cfgId, Oid newNspOid);
146148

0 commit comments

Comments
 (0)