CREATE TABLE LIKE INCLUDING PRIVILEGES — Technical Analysis
Core Problem
The CREATE TABLE ... LIKE statement in PostgreSQL allows copying a table's structure (columns, constraints, indexes, etc.) but currently does not copy access control lists (ACLs). This means that when a table is duplicated using LIKE, all privilege grants must be manually re-applied. The proposal adds a new INCLUDING PRIVILEGES option that would copy both table-level ACLs (pg_class.relacl) and column-level ACLs (pg_attribute.attacl) from the source table to the newly created table.
The inspiration comes from a message by Tom Lane (referenced as [1]), though as the subsequent discussion reveals, the interpretation of that message's intent is contested.
Proposed Solution
The patch introduces:
- New LIKE option:
INCLUDING PRIVILEGES— When specified, the ACLs from the source table are copied to the target table duringCREATE TABLE ... LIKE. - Ownership restriction — The feature only works if the current user is the owner of the source table. This is a security guardrail to prevent users from creating tables with privilege grants they shouldn't be able to issue.
- Scope — Both
pg_class.relacl(table-level privileges like SELECT, INSERT, UPDATE, DELETE, etc.) andpg_attribute.attacl(column-level privileges) are copied.
Critical Design Issues Identified
1. INCLUDING ALL Backward Compatibility Break
This is the most architecturally significant concern raised. PostgreSQL's INCLUDING ALL is a shorthand that includes all available LIKE options. If INCLUDING PRIVILEGES is added to the set, then INCLUDING ALL would now require table ownership to succeed — a breaking change for any existing code or workflow that uses INCLUDING ALL on tables not owned by the current user.
The reviewer identifies a trilemma with no clean resolution:
| Option | Problem |
|---|---|
INCLUDING ALL includes INCLUDING PRIVILEGES |
Breaks backward compat — requires ownership |
INCLUDING ALL excludes INCLUDING PRIVILEGES |
Violates the semantic contract of "ALL" |
INCLUDING ALL silently skips if not owner |
Confusing, non-deterministic behavior |
INCLUDING ALL ignores ownership check |
Security vulnerability |
This is a fundamental design tension between the extensibility of the LIKE mechanism and the security constraints unique to privilege copying.
2. Privilege Escalation Bug
The reviewer identifies a concrete security vulnerability in the current patch: GRANT OPTION is being propagated incorrectly. The patch appears to grant WITH GRANT OPTION on all copied privileges if any of the source privileges have GRANT OPTION.
Looking at the demo output: bob=a*/alice — the * indicates GRANT OPTION on the a (INSERT) privilege for bob, which correctly mirrors the source. However, the reviewer's concern suggests that in edge cases or in the implementation logic, the GRANT OPTION flag is being applied too broadly. This could allow a user to escalate privileges by creating a LIKE copy and then using the incorrectly-granted GRANT OPTION to further delegate access they shouldn't be able to delegate.
3. Semantic Questions About ACL Copying
When ACLs are copied, the grantor recorded in the ACL entries remains the original grantor (in the demo, alice). This is semantically correct if the creator IS the original owner/grantor, but raises questions about what happens in more complex scenarios:
- What if the source table has grants from multiple grantors?
- What if the source table has grants issued by roles the current user doesn't have membership in?
- Should copied ACLs be "re-granted" (with the current user as grantor) or literally byte-copied?
Architectural Context
The CREATE TABLE ... LIKE infrastructure lives in src/backend/commands/tablecmds.c (specifically in the transformTableLikeClause function area). LIKE options are bitmask flags defined in src/include/nodes/parsenodes.h. Adding a new option requires:
- Adding a new
CREATE_TABLE_LIKE_PRIVILEGESflag - Extending the parser grammar in
src/backend/parser/gram.y - Implementing the ACL copy logic in table creation
- Updating
INCLUDING ALLto include the new flag - Adding appropriate permission checks
The ACL system itself is defined in src/backend/utils/adt/acl.c with the Acl type being an array of AclItem structures, each encoding grantee, grantor, and a privilege bitmask with grant option bits.
Assessment
The proposal addresses a real usability gap, but the implementation faces significant design challenges that may not have clean solutions. The INCLUDING ALL compatibility issue in particular suggests this feature may need a different approach — perhaps a separate command or a different integration point than the LIKE mechanism. The privilege escalation bug indicates the patch needs more careful handling of per-privilege grant option flags rather than treating them as a single boolean.