Skip to content

Commit cc331e3

Browse files
Merge pull request #3 from Leafly-com/feat-add-column-level-management
fix: Use pg catalog tables for column grant info
2 parents 8eb45ae + ab2bb5e commit cc331e3

File tree

1 file changed

+18
-43
lines changed

1 file changed

+18
-43
lines changed

postgresql/resource_postgresql_grant.go

Lines changed: 18 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func resourcePostgreSQLGrant() *schema.Resource {
3939
Create: PGResourceFunc(resourcePostgreSQLGrantCreate),
4040
// Since all of this resource's arguments force a recreation
4141
// there's no need for an Update function
42-
//Update:
42+
// Update:
4343
Read: PGResourceFunc(resourcePostgreSQLGrantRead),
4444
Delete: PGResourceFunc(resourcePostgreSQLGrantDelete),
4545

@@ -325,52 +325,27 @@ func readColumnRolePrivileges(txn *sql.Tx, d *schema.ResourceData) error {
325325
missingColumns := d.Get("columns").(*schema.Set) // Getting columns from state.
326326
// If the query returns a column, it is a removed from the missingColumns.
327327

328-
roleOID, err := getRoleOID(txn, d.Get("role").(string))
329-
if err != nil {
330-
return err
331-
}
332-
333328
var rows *sql.Rows
334329

335-
// The following query is made up of 3 parts
336-
// The first one simply aggregates all privileges on one column in one table into one line.
337-
// The second part fetches all permissions on all columns for a given user & a given table in a give schema.
338-
// The third part fetches all table-level permissions for the aforementioned table.
339-
// Subtracting the third part from the second part allows us
340-
// to get column-level privileges without those created by table-level privileges.
330+
// The attacl column of pg_attribute contains information only about explicit column grants
341331
query := `
342-
SELECT table_name, column_name, array_agg(privilege_type) AS column_privileges
343-
FROM (
344-
SELECT table_name, column_name, privilege_type
345-
FROM information_schema.column_privileges
346-
WHERE
347-
grantee = $1
348-
AND
349-
table_schema = $2
350-
AND
351-
table_name = $3
352-
AND
353-
privilege_type = $6
354-
EXCEPT
355-
SELECT pg_class.relname, pg_attribute.attname, privilege_type AS table_grant
356-
FROM pg_class
357-
JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace
358-
LEFT JOIN (
359-
SELECT acls.*
360-
FROM
361-
(SELECT relname, relnamespace, relkind, (aclexplode(relacl)).* FROM pg_class c) as acls
362-
WHERE grantee=$4
363-
) privs
364-
USING (relname, relnamespace, relkind)
365-
LEFT JOIN pg_attribute ON pg_class.oid = pg_attribute.attrelid
366-
WHERE nspname = $2 AND relkind = $5
367-
)
368-
AS col_privs_without_table_privs
369-
GROUP BY col_privs_without_table_privs.table_name, col_privs_without_table_privs.column_name, col_privs_without_table_privs.privilege_type
370-
ORDER BY col_privs_without_table_privs.column_name
332+
SELECT relname AS table_name, attname AS column_name, array_agg(privilege_type) AS column_privileges
333+
FROM (SELECT relname, attname, (aclexplode(attacl)).*
334+
FROM pg_class
335+
JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid
336+
JOIN pg_attribute ON pg_class.oid = attrelid
337+
WHERE nspname = $2
338+
AND relname = $3
339+
AND relkind = $4)
340+
AS col_privs
341+
JOIN pg_roles ON pg_roles.oid = col_privs.grantee
342+
WHERE rolname = $1
343+
AND privilege_type = $5
344+
GROUP BY col_privs.relname, col_privs.attname, col_privs.privilege_type
345+
ORDER BY col_privs.attname
371346
;`
372-
rows, err = txn.Query(
373-
query, d.Get("role").(string), d.Get("schema"), objects.List()[0], roleOID, objectTypes["table"], d.Get("privileges").(*schema.Set).List()[0],
347+
rows, err := txn.Query(
348+
query, d.Get("role").(string), d.Get("schema"), objects.List()[0], objectTypes["table"], d.Get("privileges").(*schema.Set).List()[0],
374349
)
375350

376351
if err != nil {

0 commit comments

Comments
 (0)