Skip to content

feat: support column privilege diffs - #310

Draft
dilame wants to merge 1 commit into
stripe:mainfrom
dilame:feat/column-privileges
Draft

dilame wants to merge 1 commit into
stripe:mainfrom
dilame:feat/column-privileges

Conversation

@dilame

@dilame dilame commented Sep 26, 2026

Copy link
Copy Markdown

What changed

Adds schema tracking and migration generation for column-level privileges.

  • Fetches per-column ACLs from pg_attribute.attacl through a new GetColumnPrivileges query.
  • Adds ColumnPrivilege and Table.ColumnPrivileges to the schema model.
  • Generates GRANT/REVOKE SELECT|INSERT|UPDATE|REFERENCES (column) ON table statements for column ACL drift.
  • Emits column grants after CREATE TABLE for new tables and after ADD COLUMN for new columns, ordered through SQL graph dependencies.
  • Drops privileges together with their column, so a column removed from the target schema does not produce a REVOKE.
  • Clears column privileges during plan validation, matching table privilege behavior, because privilege statements are skipped when temp DB roles do not exist.
  • Column privileges on individual partitions are not implemented, matching the existing table privilege limitation.

Why

PostgreSQL stores column grants in pg_attribute.attacl, separate from the table ACL in pg_class.relacl. Before this change, pg-schema-diff did not model column ACLs, so a plan could omit GRANT ... (column) statements for new tables and new columns, and it could miss drift when a column grant was revoked. Both cases had to be patched by hand.

Validation

Ran the full test suite with PostgreSQL 17 server utilities and PostgreSQL 18 pg_dump for --restrict-key support:

go test ./...

New acceptance cases cover a new table with column grants, granting and revoking a column privilege, granting on a new column (asserting ADD COLUMN is ordered before GRANT), a grant on multiple columns, GRANT OPTION recreation, a non-public schema, and the partition not-implemented paths.

Track per-column ACLs from pg_attribute.attacl so plans emit
GRANT/REVOKE SELECT/INSERT/UPDATE/REFERENCES (column) statements. Column
grants are emitted after CREATE TABLE for new tables and after ADD COLUMN
for new columns. A column that is dropped takes its privileges with it, so
no REVOKE is emitted for it.

Constraint: Column privileges are stored in pg_attribute.attacl, separate
from the table ACL in pg_class.relacl, so they need their own introspection
query and schema field.

Rejected: Folding column ACLs into the table privilege list | table and
column privileges live in different catalogs and their SQL statements carry
different column lists.

Directive: Keep column privilege validation aligned with table privilege
validation because privilege statements are skipped when roles are absent in
the temp DB.

Tested: go test ./... with PostgreSQL 17 server utilities and PostgreSQL 18
pg_dump for --restrict-key support
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant