Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit d898665

Browse files
committed
Extend pg_get_acl() to handle sub-object IDs
This patch modifies the pg_get_acl() function to accept a third argument called "objsubid", bringing it on par with similar functions in this area like pg_describe_object(). This enables the retrieval of ACLs for relation attributes when scanning dependencies. Bump catalog version. Author: Joel Jacobson Discussion: https://postgr.es/m/f2539bff-64be-47f0-9f0b-df85d3cc0432@app.fastmail.com
1 parent f7bd0a3 commit d898665

File tree

6 files changed

+73
-24
lines changed

6 files changed

+73
-24
lines changed

doc/src/sgml/func.sgml

+3-3
Original file line numberDiff line numberDiff line change
@@ -26661,12 +26661,12 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id'));
2666126661
<indexterm>
2666226662
<primary>pg_get_acl</primary>
2666326663
</indexterm>
26664-
<function>pg_get_acl</function> ( <parameter>classid</parameter> <type>oid</type>, <parameter>objid</parameter> <type>oid</type> )
26664+
<function>pg_get_acl</function> ( <parameter>classid</parameter> <type>oid</type>, <parameter>objid</parameter> <type>oid</type>, <parameter>objsubid</parameter> <type>integer</type> )
2666526665
<returnvalue>aclitem[]</returnvalue>
2666626666
</para>
2666726667
<para>
2666826668
Returns the <acronym>ACL</acronym> for a database object, specified
26669-
by catalog OID and object OID. This function returns
26669+
by catalog OID, object OID and sub-object ID. This function returns
2667026670
<literal>NULL</literal> values for undefined objects.
2667126671
</para></entry>
2667226672
</row>
@@ -26792,7 +26792,7 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id'));
2679226792
<programlisting>
2679326793
postgres=# SELECT
2679426794
(pg_identify_object(s.classid,s.objid,s.objsubid)).*,
26795-
pg_catalog.pg_get_acl(s.classid,s.objid) AS acl
26795+
pg_catalog.pg_get_acl(s.classid,s.objid,s.objsubid) AS acl
2679626796
FROM pg_catalog.pg_shdepend AS s
2679726797
JOIN pg_catalog.pg_database AS d
2679826798
ON d.datname = current_database() AND

src/backend/catalog/objectaddress.c

+32-11
Original file line numberDiff line numberDiff line change
@@ -4364,19 +4364,19 @@ pg_identify_object_as_address(PG_FUNCTION_ARGS)
43644364

43654365
/*
43664366
* SQL-level callable function to obtain the ACL of a specified object, given
4367-
* its catalog OID and object OID.
4367+
* its catalog OID, object OID and sub-object ID.
43684368
*/
43694369
Datum
43704370
pg_get_acl(PG_FUNCTION_ARGS)
43714371
{
43724372
Oid classId = PG_GETARG_OID(0);
43734373
Oid objectId = PG_GETARG_OID(1);
4374+
int32 objsubid = PG_GETARG_INT32(2);
43744375
Oid catalogId;
43754376
AttrNumber Anum_acl;
4376-
Relation rel;
4377-
HeapTuple tup;
43784377
Datum datum;
43794378
bool isnull;
4379+
HeapTuple tup;
43804380

43814381
/* for "pinned" items in pg_depend, return null */
43824382
if (!OidIsValid(classId) && !OidIsValid(objectId))
@@ -4391,19 +4391,40 @@ pg_get_acl(PG_FUNCTION_ARGS)
43914391
if (Anum_acl == InvalidAttrNumber)
43924392
PG_RETURN_NULL();
43934393

4394-
rel = table_open(catalogId, AccessShareLock);
4394+
/*
4395+
* If dealing with a relation's attribute (objsubid is set), the ACL is
4396+
* retrieved from pg_attribute.
4397+
*/
4398+
if (classId == RelationRelationId && objsubid != 0)
4399+
{
4400+
AttrNumber attnum = (AttrNumber) objsubid;
43954401

4396-
tup = get_catalog_object_by_oid(rel, get_object_attnum_oid(catalogId),
4397-
objectId);
4398-
if (!HeapTupleIsValid(tup))
4402+
tup = SearchSysCacheCopyAttNum(objectId, attnum);
4403+
4404+
if (!HeapTupleIsValid(tup))
4405+
PG_RETURN_NULL();
4406+
4407+
datum = SysCacheGetAttr(ATTNUM, tup, Anum_pg_attribute_attacl,
4408+
&isnull);
4409+
}
4410+
else
43994411
{
4412+
Relation rel;
4413+
4414+
rel = table_open(catalogId, AccessShareLock);
4415+
4416+
tup = get_catalog_object_by_oid(rel, get_object_attnum_oid(catalogId),
4417+
objectId);
4418+
if (!HeapTupleIsValid(tup))
4419+
{
4420+
table_close(rel, AccessShareLock);
4421+
PG_RETURN_NULL();
4422+
}
4423+
4424+
datum = heap_getattr(tup, Anum_acl, RelationGetDescr(rel), &isnull);
44004425
table_close(rel, AccessShareLock);
4401-
PG_RETURN_NULL();
44024426
}
44034427

4404-
datum = heap_getattr(tup, Anum_acl, RelationGetDescr(rel), &isnull);
4405-
table_close(rel, AccessShareLock);
4406-
44074428
if (isnull)
44084429
PG_RETURN_NULL();
44094430

src/include/catalog/catversion.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,6 @@
5757
*/
5858

5959
/* yyyymmddN */
60-
#define CATALOG_VERSION_NO 202407091
60+
#define CATALOG_VERSION_NO 202407101
6161

6262
#endif

src/include/catalog/pg_proc.dat

+1-1
Original file line numberDiff line numberDiff line change
@@ -6364,7 +6364,7 @@
63646364

63656365
{ oid => '8730', descr => 'get ACL for SQL object',
63666366
proname => 'pg_get_acl', provolatile => 's', prorettype => '_aclitem',
6367-
proargtypes => 'oid oid', proargnames => '{classid,objid}',
6367+
proargtypes => 'oid oid int4', proargnames => '{classid,objid,objsubid}',
63686368
prosrc => 'pg_get_acl' },
63696369

63706370
{ oid => '3839',

src/test/regress/expected/privileges.out

+28-4
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ SELECT * FROM atest1;
213213
(0 rows)
214214

215215
CREATE TABLE atest2 (col1 varchar(10), col2 boolean);
216-
SELECT pg_get_acl('pg_class'::regclass, 'atest2'::regclass::oid);
216+
SELECT pg_get_acl('pg_class'::regclass, 'atest2'::regclass::oid, 0);
217217
pg_get_acl
218218
------------
219219

@@ -223,7 +223,7 @@ GRANT SELECT ON atest2 TO regress_priv_user2;
223223
GRANT UPDATE ON atest2 TO regress_priv_user3;
224224
GRANT INSERT ON atest2 TO regress_priv_user4 GRANTED BY CURRENT_USER;
225225
GRANT TRUNCATE ON atest2 TO regress_priv_user5 GRANTED BY CURRENT_ROLE;
226-
SELECT unnest(pg_get_acl('pg_class'::regclass, 'atest2'::regclass::oid));
226+
SELECT unnest(pg_get_acl('pg_class'::regclass, 'atest2'::regclass::oid, 0));
227227
unnest
228228
------------------------------------------------
229229
regress_priv_user1=arwdDxtm/regress_priv_user1
@@ -234,13 +234,13 @@ SELECT unnest(pg_get_acl('pg_class'::regclass, 'atest2'::regclass::oid));
234234
(5 rows)
235235

236236
-- Invalid inputs
237-
SELECT pg_get_acl('pg_class'::regclass, 0); -- null
237+
SELECT pg_get_acl('pg_class'::regclass, 0, 0); -- null
238238
pg_get_acl
239239
------------
240240

241241
(1 row)
242242

243-
SELECT pg_get_acl(0, 0); -- null
243+
SELECT pg_get_acl(0, 0, 0); -- null
244244
pg_get_acl
245245
------------
246246

@@ -653,6 +653,30 @@ CREATE TABLE atest5 (one int, two int unique, three int, four int unique);
653653
CREATE TABLE atest6 (one int, two int, blue int);
654654
GRANT SELECT (one), INSERT (two), UPDATE (three) ON atest5 TO regress_priv_user4;
655655
GRANT ALL (one) ON atest5 TO regress_priv_user3;
656+
SELECT unnest(pg_get_acl('pg_class'::regclass, 'atest5'::regclass::oid, 1));
657+
unnest
658+
--------------------------------------------
659+
regress_priv_user4=r/regress_priv_user1
660+
regress_priv_user3=arwx/regress_priv_user1
661+
(2 rows)
662+
663+
SELECT unnest(pg_get_acl('pg_class'::regclass, 'atest5'::regclass::oid, 2));
664+
unnest
665+
-----------------------------------------
666+
regress_priv_user4=a/regress_priv_user1
667+
(1 row)
668+
669+
SELECT unnest(pg_get_acl('pg_class'::regclass, 'atest5'::regclass::oid, 3));
670+
unnest
671+
-----------------------------------------
672+
regress_priv_user4=w/regress_priv_user1
673+
(1 row)
674+
675+
SELECT unnest(pg_get_acl('pg_class'::regclass, 'atest5'::regclass::oid, 4));
676+
unnest
677+
--------
678+
(0 rows)
679+
656680
INSERT INTO atest5 VALUES (1,2,3);
657681
SET SESSION AUTHORIZATION regress_priv_user4;
658682
SELECT * FROM atest5; -- fail

src/test/regress/sql/privileges.sql

+8-4
Original file line numberDiff line numberDiff line change
@@ -183,16 +183,16 @@ GRANT SELECT ON atest1 TO regress_priv_user3, regress_priv_user4;
183183
SELECT * FROM atest1;
184184

185185
CREATE TABLE atest2 (col1 varchar(10), col2 boolean);
186-
SELECT pg_get_acl('pg_class'::regclass, 'atest2'::regclass::oid);
186+
SELECT pg_get_acl('pg_class'::regclass, 'atest2'::regclass::oid, 0);
187187
GRANT SELECT ON atest2 TO regress_priv_user2;
188188
GRANT UPDATE ON atest2 TO regress_priv_user3;
189189
GRANT INSERT ON atest2 TO regress_priv_user4 GRANTED BY CURRENT_USER;
190190
GRANT TRUNCATE ON atest2 TO regress_priv_user5 GRANTED BY CURRENT_ROLE;
191-
SELECT unnest(pg_get_acl('pg_class'::regclass, 'atest2'::regclass::oid));
191+
SELECT unnest(pg_get_acl('pg_class'::regclass, 'atest2'::regclass::oid, 0));
192192

193193
-- Invalid inputs
194-
SELECT pg_get_acl('pg_class'::regclass, 0); -- null
195-
SELECT pg_get_acl(0, 0); -- null
194+
SELECT pg_get_acl('pg_class'::regclass, 0, 0); -- null
195+
SELECT pg_get_acl(0, 0, 0); -- null
196196

197197
GRANT TRUNCATE ON atest2 TO regress_priv_user4 GRANTED BY regress_priv_user5; -- error
198198

@@ -439,6 +439,10 @@ CREATE TABLE atest5 (one int, two int unique, three int, four int unique);
439439
CREATE TABLE atest6 (one int, two int, blue int);
440440
GRANT SELECT (one), INSERT (two), UPDATE (three) ON atest5 TO regress_priv_user4;
441441
GRANT ALL (one) ON atest5 TO regress_priv_user3;
442+
SELECT unnest(pg_get_acl('pg_class'::regclass, 'atest5'::regclass::oid, 1));
443+
SELECT unnest(pg_get_acl('pg_class'::regclass, 'atest5'::regclass::oid, 2));
444+
SELECT unnest(pg_get_acl('pg_class'::regclass, 'atest5'::regclass::oid, 3));
445+
SELECT unnest(pg_get_acl('pg_class'::regclass, 'atest5'::regclass::oid, 4));
442446

443447
INSERT INTO atest5 VALUES (1,2,3);
444448

0 commit comments

Comments
 (0)