2026-06-01 · claude-opus-4-6
CREATE TABLE LIKE: INCLUDING PARAMETERS and INCLUDING TRIGGERS — May 2026 Summary
Overview
This thread advances two patches extending CREATE TABLE ... (LIKE source INCLUDING ...) to cover two previously unsupported attribute categories: table-level storage parameters (reloptions like fillfactor, autovacuum_*, toast.*) and triggers. Both patches reached near-commit-readiness by month's end, with architectural debates settled and only polish items remaining.
Key Developments
INCLUDING PARAMETERS — Syntax and Semantics Settled
The syntax for copying table-level reloptions was finalized as INCLUDING PARAMETERS (not INCLUDING STORAGE PARAMETER), after David G. Johnston argued the qualifier "STORAGE" was too narrow for what might eventually include planner-related options. PARAMETERS was added as an unreserved bare-label keyword with no backward-compatibility risk.
Semantic boundaries were established:
- Foreign tables: silently ignored (no traditional reloptions)
- Views: rejected — view reloptions (
check_option, security_barrier) have a disjoint namespace
- Column-level attribute options (e.g.,
n_distinct): explicitly excluded — these are data-derived planner hints inappropriate for empty clone tables
Implementation reuses the existing untransformRelOptions() function for catalog decompilation, per Euler Taveira's review.
INCLUDING TRIGGERS — Architecture Debate Resolved
The most significant architectural discussion concerned whether to inject Oid fields into CreateTrigStmt for efficient cloning (avoiding name re-resolution). Robert Haas settled the debate decisively: maintain consistency with the existing catalog round-trip pattern (OID → name → parse node → re-execute), even though it's "incredibly ugly," because fragmenting the pattern makes future system-wide cleanup impossible.
Trigger cloning semantics were refined:
- Internal triggers (FK-associated): skipped — they're owned by constraints
- INSTEAD OF triggers: rejected on non-view targets
- Whole-row
WHEN clause references: rejected (rowtype safety)
tgenabled state: preserved (matching constraint precedent)
- Trigger comments: copied only when
INCLUDING COMMENTS specified
- Partition triggers: not recursively cloned
A transformed boolean flag on CreateTrigStmt signals that the whenClause is already a transformed expression tree (from pg_trigger.tgqual), preventing redundant and incorrect re-parse-analysis.
Final Review Round — Converging on Commit
Henson Choi's detailed review confirmed the patch is "in good shape" with no blockers, but identified:
- A test isolation bug:
create_table_like.sql depends on trigger_func from triggers.sql — breaks standalone test runs
- Missing
EXCLUDING TRIGGERS test coverage
- The whole-row
WHEN restriction may be liftable in future via composite-type OID remapping (suggests XXX comment)
- Minor documentation wording inconsistencies and commit message grammar
No new architectural objections were raised. The RangeVar-vs-Oid debate, INCLUDING PARAMETERS naming, and map_variable_attnos() approach were all endorsed by the reviewer.
Current Status
Both patches appear commit-ready pending minor polish (test self-containment fix, documentation alignment, cosmetic cleanups). The thread has converged on all design decisions.
2026-06-01 · claude-opus-4-6
New in this round: Zsolt Parragi's late review and Lakshmi's status update
Two new messages since the last analysis.
Lakshmi's message (2026-05-27)
From the email address (lakshmigcdac@gmail.com), this appears to be a brief status/acknowledgment message. No substantive technical content is visible beyond the metadata.
Zsolt Parragi's review (2026-05-27) — Two substantive findings
Zsolt Parragi returns after missing several patch iterations and raises two concrete issues:
1. INSTEAD OF triggers not properly skipped (bug report)
Zsolt provides a complete reproducer: creating an INSTEAD OF trigger on a view, then doing CREATE TABLE t_all (LIKE v_instead INCLUDING ALL) causes an error:
ERROR: "t_all" is a table
DETAIL: Tables cannot have INSTEAD OF triggers.
This was already identified in prior analysis as a design decision (INSTEAD OF triggers on views should be rejected when cloning onto a plain table), but Zsolt's point is that the error should be silently skipped rather than producing a hard failure. The distinction is important: INCLUDING ALL should not blow up when the source is a view that happens to have view-specific triggers. The user's intent with INCLUDING ALL is "copy everything that makes sense for the target relkind," not "fail if anything is incompatible." This mirrors how INCLUDING PARAMETERS is silently ignored for foreign tables.
2. Unnecessary stmt->transformed = true assignment (code simplification)
Zsolt identifies dead code in the CreateTrigger refactoring. When the else branch executes (i.e., the statement was NOT already transformed), it sets stmt->transformed = true at the end — but this assignment is pointless because:
- The statement is not reused after this point
- The flag is never checked again downstream
- The transformation operates on a copy anyway
Zsolt confirms "everything seems to work fine if I remove this assignment" and notes that removing it eliminates the need for const-related function signature changes that were introduced solely to support this flag mutation. This is a genuine simplification opportunity that reduces the patch's footprint.
Technical significance
The INSTEAD OF trigger issue refines the earlier design discussion — it's not about whether to reject them (that was settled), but about the UX of how (silent skip vs. hard error, especially under INCLUDING ALL). The stmt->transformed observation is a clean code-reduction that simplifies the patch without behavioral change.