Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit890192e

Browse files
committed
Support user mappings in get_object_address
Since commit72dd233 we were trying to obtain object addressinginformation in sql_drop event triggers, but that caused failures whenthe drops involved user mappings. This addition enables that to workagain. Naturally, pg_get_object_address can work with these objectsnow, too.I toyed with the idea of removing DropUserMappingStmt as a node andusing DropStmt instead in the DropUserMappingStmt grammar production,but that didn't go very well: for one thing the messages thrown by thespecific code are specialized (you get "server not found" if you specifythe wrong server, instead of a generic "user mapping for ... not found"which you'd get it we were to merge this with RemoveObjects --- unlesswe added even more special cases). For another thing, it would requireto pass RoleSpec nodes through the objname/objargs representation usedby RemoveObjects, which works in isolation, but gets messy whenpg_get_object_address is involved. So I dropped this part for now.Reviewed by Stephen Frost.
1 parent1ce7a57 commit890192e

File tree

7 files changed

+109
-13
lines changed

7 files changed

+109
-13
lines changed

‎src/backend/catalog/objectaddress.c

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@ ObjectTypeMap[] =
520520
/* OCLASS_FOREIGN_SERVER */
521521
{"server",OBJECT_FOREIGN_SERVER },
522522
/* OCLASS_USER_MAPPING */
523-
{"user mapping",-1 },/* unmapped */
523+
{"user mapping",OBJECT_USER_MAPPING },
524524
/* OCLASS_DEFACL */
525525
{"default acl",-1 },/* unmapped */
526526
/* OCLASS_EXTENSION */
@@ -555,6 +555,8 @@ static ObjectAddress get_object_address_type(ObjectType objtype,
555555
List*objname,boolmissing_ok);
556556
staticObjectAddressget_object_address_opcf(ObjectTypeobjtype,List*objname,
557557
List*objargs,boolmissing_ok);
558+
staticObjectAddressget_object_address_usermapping(List*objname,
559+
List*objargs,boolmissing_ok);
558560
staticconstObjectPropertyType*get_object_property_data(Oidclass_id);
559561

560562
staticvoidgetRelationDescription(StringInfobuffer,Oidrelid);
@@ -769,6 +771,10 @@ get_object_address(ObjectType objtype, List *objname, List *objargs,
769771
address.objectId=get_ts_config_oid(objname,missing_ok);
770772
address.objectSubId=0;
771773
break;
774+
caseOBJECT_USER_MAPPING:
775+
address=get_object_address_usermapping(objname,objargs,
776+
missing_ok);
777+
break;
772778
default:
773779
elog(ERROR,"unrecognized objtype: %d", (int)objtype);
774780
/* placate compiler, in case it thinks elog might return */
@@ -1372,6 +1378,75 @@ get_object_address_opcf(ObjectType objtype,
13721378
returnaddress;
13731379
}
13741380

1381+
/*
1382+
* Find the ObjectAddress for a user mapping.
1383+
*/
1384+
staticObjectAddress
1385+
get_object_address_usermapping(List*objname,List*objargs,boolmissing_ok)
1386+
{
1387+
ObjectAddressaddress;
1388+
Oiduserid;
1389+
char*username;
1390+
char*servername;
1391+
ForeignServer*server;
1392+
HeapTupletp;
1393+
1394+
ObjectAddressSet(address,UserMappingRelationId,InvalidOid);
1395+
1396+
/* fetch string names from input lists, for error messages */
1397+
username=strVal(linitial(objname));
1398+
servername=strVal(linitial(objargs));
1399+
1400+
/* look up pg_authid OID of mapped user; InvalidOid if PUBLIC */
1401+
if (strcmp(username,"public")==0)
1402+
userid=InvalidOid;
1403+
else
1404+
{
1405+
tp=SearchSysCache1(AUTHNAME,
1406+
CStringGetDatum(username));
1407+
if (!HeapTupleIsValid(tp))
1408+
{
1409+
if (!missing_ok)
1410+
ereport(ERROR,
1411+
(errcode(ERRCODE_UNDEFINED_OBJECT),
1412+
errmsg("user mapping for user \"%s\" in server \"%s\" does not exist",
1413+
username,servername)));
1414+
returnaddress;
1415+
}
1416+
userid=HeapTupleGetOid(tp);
1417+
ReleaseSysCache(tp);
1418+
}
1419+
1420+
/* Now look up the pg_user_mapping tuple */
1421+
server=GetForeignServerByName(servername, true);
1422+
if (!server)
1423+
{
1424+
if (!missing_ok)
1425+
ereport(ERROR,
1426+
(errcode(ERRCODE_UNDEFINED_OBJECT),
1427+
errmsg("server \"%s\" does not exist",servername)));
1428+
returnaddress;
1429+
}
1430+
tp=SearchSysCache2(USERMAPPINGUSERSERVER,
1431+
ObjectIdGetDatum(userid),
1432+
ObjectIdGetDatum(server->serverid));
1433+
if (!HeapTupleIsValid(tp))
1434+
{
1435+
if (!missing_ok)
1436+
ereport(ERROR,
1437+
(errcode(ERRCODE_UNDEFINED_OBJECT),
1438+
errmsg("user mapping for user \"%s\" in server \"%s\" does not exist",
1439+
username,servername)));
1440+
returnaddress;
1441+
}
1442+
1443+
address.objectId=HeapTupleGetOid(tp);
1444+
1445+
ReleaseSysCache(tp);
1446+
1447+
returnaddress;
1448+
}
1449+
13751450
/*
13761451
* Convert an array of TEXT into a List of string Values, as emitted by the
13771452
* parser, which is what get_object_address uses as input.
@@ -1523,6 +1598,7 @@ pg_get_object_address(PG_FUNCTION_ARGS)
15231598
caseOBJECT_OPCLASS:
15241599
caseOBJECT_OPFAMILY:
15251600
caseOBJECT_CAST:
1601+
caseOBJECT_USER_MAPPING:
15261602
if (list_length(args)!=1)
15271603
ereport(ERROR,
15281604
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),

‎src/backend/commands/event_trigger.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,6 +1092,7 @@ EventTriggerSupportsObjectType(ObjectType obtype)
10921092
caseOBJECT_TSPARSER:
10931093
caseOBJECT_TSTEMPLATE:
10941094
caseOBJECT_TYPE:
1095+
caseOBJECT_USER_MAPPING:
10951096
caseOBJECT_VIEW:
10961097
return true;
10971098
}

‎src/include/nodes/parsenodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,6 +1268,7 @@ typedef enum ObjectType
12681268
OBJECT_TSPARSER,
12691269
OBJECT_TSTEMPLATE,
12701270
OBJECT_TYPE,
1271+
OBJECT_USER_MAPPING,
12711272
OBJECT_VIEW
12721273
}ObjectType;
12731274

‎src/test/regress/expected/event_trigger.out

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,12 @@ revoke all on table event_trigger_fire1 from public;
110110
NOTICE: test_event_trigger: ddl_command_end REVOKE
111111
drop table event_trigger_fire1;
112112
NOTICE: test_event_trigger: ddl_command_end DROP TABLE
113+
create foreign data wrapper useless;
114+
NOTICE: test_event_trigger: ddl_command_end CREATE FOREIGN DATA WRAPPER
115+
create server useless_server foreign data wrapper useless;
116+
NOTICE: test_event_trigger: ddl_command_end CREATE SERVER
117+
create user mapping for regression_bob server useless_server;
118+
NOTICE: test_event_trigger: ddl_command_end CREATE USER MAPPING
113119
-- alter owner to non-superuser should fail
114120
alter event trigger regress_event_trigger owner to regression_bob;
115121
ERROR: permission denied to change owner of event trigger "regress_event_trigger"
@@ -125,10 +131,11 @@ alter event trigger regress_event_trigger rename to regress_event_trigger3;
125131
-- should fail, doesn't exist any more
126132
drop event trigger regress_event_trigger;
127133
ERROR: event trigger "regress_event_trigger" does not exist
128-
-- should fail, regression_bob ownsregress_event_trigger2/3
134+
-- should fail, regression_bob ownssome objects
129135
drop role regression_bob;
130136
ERROR: role "regression_bob" cannot be dropped because some objects depend on it
131137
DETAIL: owner of event trigger regress_event_trigger3
138+
owner of user mapping for regression_bob on server useless_server
132139
-- cleanup before next test
133140
-- these are all OK; the second one should emit a NOTICE
134141
drop event trigger if exists regress_event_trigger2;

‎src/test/regress/expected/object_address.out

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ CREATE DOMAIN addr_nsp.gendomain AS int4 CONSTRAINT domconstr CHECK (value > 0);
2828
CREATE FUNCTION addr_nsp.trig() RETURNS TRIGGER LANGUAGE plpgsql AS $$ BEGIN END; $$;
2929
CREATE TRIGGER t BEFORE INSERT ON addr_nsp.gentable FOR EACH ROW EXECUTE PROCEDURE addr_nsp.trig();
3030
CREATE POLICY genpol ON addr_nsp.gentable;
31+
CREATE SERVER "integer" FOREIGN DATA WRAPPER addr_fdw;
32+
CREATE USER MAPPING FOR regtest_addr_user SERVER "integer";
3133
-- test some error cases
3234
SELECT pg_get_object_address('stone', '{}', '{}');
3335
ERROR: unrecognized object type "stone"
@@ -42,8 +44,7 @@ DECLARE
4244
BEGIN
4345
FOR objtype IN VALUES ('toast table'), ('index column'), ('sequence column'),
4446
('toast table column'), ('view column'), ('materialized view column'),
45-
('operator of access method'), ('function of access method'),
46-
('user mapping')
47+
('operator of access method'), ('function of access method')
4748
LOOP
4849
BEGIN
4950
PERFORM pg_get_object_address(objtype, '{one}', '{}');
@@ -61,7 +62,6 @@ WARNING: error for view column: unsupported object type "view column"
6162
WARNING: error for materialized view column: unsupported object type "materialized view column"
6263
WARNING: error for operator of access method: unsupported object type "operator of access method"
6364
WARNING: error for function of access method: unsupported object type "function of access method"
64-
WARNING: error for user mapping: unsupported object type "user mapping"
6565
DO $$
6666
DECLARE
6767
objtype text;
@@ -77,7 +77,7 @@ BEGIN
7777
('operator'), ('operator class'), ('operator family'), ('rule'), ('trigger'),
7878
('text search parser'), ('text search dictionary'),
7979
('text search template'), ('text search configuration'),
80-
('policy')
80+
('policy'), ('user mapping')
8181
LOOP
8282
FOR names IN VALUES ('{eins}'), ('{addr_nsp, zwei}'), ('{eins, zwei, drei}')
8383
LOOP
@@ -249,6 +249,12 @@ WARNING: error for policy,{addr_nsp,zwei},{}: relation "addr_nsp" does not exis
249249
WARNING: error for policy,{addr_nsp,zwei},{integer}: relation "addr_nsp" does not exist
250250
WARNING: error for policy,{eins,zwei,drei},{}: schema "eins" does not exist
251251
WARNING: error for policy,{eins,zwei,drei},{integer}: schema "eins" does not exist
252+
WARNING: error for user mapping,{eins},{}: argument list length must be exactly 1
253+
WARNING: error for user mapping,{eins},{integer}: user mapping for user "eins" in server "integer" does not exist
254+
WARNING: error for user mapping,{addr_nsp,zwei},{}: argument list length must be exactly 1
255+
WARNING: error for user mapping,{addr_nsp,zwei},{integer}: user mapping for user "addr_nsp" in server "integer" does not exist
256+
WARNING: error for user mapping,{eins,zwei,drei},{}: argument list length must be exactly 1
257+
WARNING: error for user mapping,{eins,zwei,drei},{integer}: user mapping for user "eins" in server "integer" does not exist
252258
-- these object types cannot be qualified names
253259
SELECT pg_get_object_address('language', '{one}', '{}');
254260
ERROR: language "one" does not exist
@@ -334,7 +340,7 @@ WITH objects (type, name, args) AS (VALUES
334340
-- tablespace
335341
('foreign-data wrapper', '{addr_fdw}', '{}'),
336342
('server', '{addr_fserv}', '{}'),
337-
--user mapping
343+
('user mapping', '{regtest_addr_user}', '{integer}'),
338344
-- extension
339345
-- event trigger
340346
('policy', '{addr_nsp, gentable, genpol}', '{}')
@@ -365,6 +371,7 @@ SELECT (pg_identify_object(addr1.classid, addr1.objid, addr1.subobjid)).*,
365371
foreign table | addr_nsp | genftable | addr_nsp.genftable | t
366372
role | | regtest_addr_user | regtest_addr_user | t
367373
server | | addr_fserv | addr_fserv | t
374+
user mapping | | | regtest_addr_user on server integer | t
368375
foreign-data wrapper | | addr_fdw | addr_fdw | t
369376
default value | | | for addr_nsp.gentable.b | t
370377
cast | | | (bigint AS integer) | t
@@ -384,7 +391,7 @@ SELECT (pg_identify_object(addr1.classid, addr1.objid, addr1.subobjid)).*,
384391
text search parser | addr_nsp | addr_ts_prs | addr_nsp.addr_ts_prs | t
385392
text search configuration | addr_nsp | addr_ts_conf | addr_nsp.addr_ts_conf | t
386393
text search template | addr_nsp | addr_ts_temp | addr_nsp.addr_ts_temp | t
387-
(35 rows)
394+
(36 rows)
388395

389396
---
390397
--- Cleanup resources

‎src/test/regress/sql/event_trigger.sql

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ grant all on table event_trigger_fire1 to public;
107107
comment on table event_trigger_fire1 is'here is a comment';
108108
revoke allon table event_trigger_fire1from public;
109109
droptable event_trigger_fire1;
110+
create foreign data wrapper useless;
111+
create server useless_server foreign data wrapper useless;
112+
createusermapping for regression_bob server useless_server;
110113

111114
-- alter owner to non-superuser should fail
112115
alter event trigger regress_event_trigger owner to regression_bob;
@@ -124,7 +127,7 @@ alter event trigger regress_event_trigger rename to regress_event_trigger3;
124127
-- should fail, doesn't exist any more
125128
drop event trigger regress_event_trigger;
126129

127-
-- should fail, regression_bob ownsregress_event_trigger2/3
130+
-- should fail, regression_bob ownssome objects
128131
drop role regression_bob;
129132

130133
-- cleanup before next test

‎src/test/regress/sql/object_address.sql

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ CREATE DOMAIN addr_nsp.gendomain AS int4 CONSTRAINT domconstr CHECK (value > 0);
3232
CREATEFUNCTIONaddr_nsp.trig() RETURNS TRIGGER LANGUAGE plpgsqlAS $$BEGIN END; $$;
3333
CREATETRIGGERt BEFORE INSERTONaddr_nsp.gentable FOR EACH ROW EXECUTE PROCEDUREaddr_nsp.trig();
3434
CREATE POLICY genpolONaddr_nsp.gentable;
35+
CREATE SERVER"integer" FOREIGN DATA WRAPPER addr_fdw;
36+
CREATEUSERMAPPING FOR regtest_addr_user SERVER"integer";
3537

3638
-- test some error cases
3739
SELECT pg_get_object_address('stone','{}','{}');
@@ -45,8 +47,7 @@ DECLARE
4547
BEGIN
4648
FOR objtypeINVALUES ('toast table'), ('index column'), ('sequence column'),
4749
('toast table column'), ('view column'), ('materialized view column'),
48-
('operator of access method'), ('function of access method'),
49-
('user mapping')
50+
('operator of access method'), ('function of access method')
5051
LOOP
5152
BEGIN
5253
PERFORM pg_get_object_address(objtype,'{one}','{}');
@@ -72,7 +73,7 @@ BEGIN
7273
('operator'), ('operator class'), ('operator family'), ('rule'), ('trigger'),
7374
('text search parser'), ('text search dictionary'),
7475
('text search template'), ('text search configuration'),
75-
('policy')
76+
('policy'), ('user mapping')
7677
LOOP
7778
FOR namesINVALUES ('{eins}'), ('{addr_nsp, zwei}'), ('{eins, zwei, drei}')
7879
LOOP
@@ -154,7 +155,7 @@ WITH objects (type, name, args) AS (VALUES
154155
-- tablespace
155156
('foreign-data wrapper','{addr_fdw}','{}'),
156157
('server','{addr_fserv}','{}'),
157-
--user mapping
158+
('user mapping','{regtest_addr_user}','{integer}'),
158159
-- extension
159160
-- event trigger
160161
('policy','{addr_nsp, gentable, genpol}','{}')

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp