CREATE TABLE LIKE INCLUDING PRIVILEGES

First seen: 2026-06-03 07:32:00+00:00 · Messages: 2 · Participants: 2

Latest Update

2026-06-04 · claude-opus-4-6

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:

  1. New LIKE option: INCLUDING PRIVILEGES — When specified, the ACLs from the source table are copied to the target table during CREATE TABLE ... LIKE.
  2. 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.
  3. Scope — Both pg_class.relacl (table-level privileges like SELECT, INSERT, UPDATE, DELETE, etc.) and pg_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:

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:

  1. Adding a new CREATE_TABLE_LIKE_PRIVILEGES flag
  2. Extending the parser grammar in src/backend/parser/gram.y
  3. Implementing the ACL copy logic in table creation
  4. Updating INCLUDING ALL to include the new flag
  5. 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.