Thread
-
Re: CREATE TABLE LIKE INCLUDING TRIGGERS
Henson Choi <assam258@gmail.com> — 2026-05-07T01:38:35Z
Hi Jian, This is the line-by-line code review I promised earlier. The overall conclusion is that the patch is in good shape. I have some minor items below, none of which are blockers. WHAT LOOKS GOOD --------------- The keyword placement is correct. TRIGGERS is classified as UNRESERVED_KEYWORD and also listed in bare_label_keyword, so existing SQL that uses "triggers" as an identifier continues to work without quoting. No compatibility concern here. generateClonedTriggerStmt() is well-structured. The WHEN-clause remapping via map_variable_attnos() and the transformed flag to prevent re-transformation in CreateTriggerFiringOn() are correct. pg_dump needs no changes. LIKE-copied triggers are stored as independent pg_trigger rows, so the existing dump logic picks them up automatically. MINOR ISSUES ------------ 1. Test: cross-file dependency on trigger_func (create_table_like.sql) create_table_like.sql references trigger_func without creating it, relying on triggers.sql having run first. The dependency is noted in a comment, and parallel_schedule guarantees the correct order for a full "make check" run. However, "make check TESTS=create_table_like" will fail because trigger_func does not exist. PostgreSQL convention is that each test file creates and drops the objects it needs. Please add a local definition of trigger_func in create_table_like.sql (and drop it at the end of the new block). 2. Test: EXCLUDING TRIGGERS not exercised The grammar now accepts EXCLUDING TRIGGERS, but no test uses it. The default (no option) is equivalent, but a one-line smoke test would confirm the keyword is accepted and has the expected effect: CREATE TABLE t_excl (LIKE source_table EXCLUDING TRIGGERS); 3. Documentation: create_table.sgml wording inconsistent with create_foreign_table.sgml create_foreign_table.sgml already reads: "All non-internal triggers are copied to the new table." create_table.sgml reads: "All non-internal triggers on the original table will be created on the new table." Two problems with the latter: a) "on the original table" is redundant; no other INCLUDING option includes this phrase (compare INCLUDING STATISTICS: "Extended statistics are copied to the new table."). b) "will be created" misrepresents the action; the correct verb is "are copied", matching the pattern used elsewhere. Recommended wording for create_table.sgml: "All non-internal triggers are copied to the new table." 4. Code comment: capitalisation in generateClonedTriggerStmt() (trigger.c) /* Reconstruct trigger function String list */ "String" should be lowercase "string". 5. Code comment: overly verbose in expandTableLikeClause() (parse_utilcmd.c) /* We make use of CreateTrigStmt's trigcomment option */ The code is self-explanatory. I would recommend removing it or replacing it with something like: /* pass comment through to CreateTrigger */ 6. Commit message grammar (commit e73f551) Several sentences contain grammatical errors: a) "This will copy all source table's trigger to the new table." -> "...triggers..." b) "Internal trigger (such as foreign key associated trigger) won't being copied to new table." -> "Internal triggers (such as foreign-key-associated triggers) won't be copied to the new table." c) "However this command will fail if the source table's trigger contain whole-row reference." -> "However, this command will fail if the source table's triggers contain a whole-row reference." 7. Whole-row reference restriction: implementation gap or deliberate? Triggers whose WHEN clause contains a whole-row reference (OLD.*, NEW.*) are rejected. Is this a deliberate decision, or a known gap left for a follow-up? If the latter, a XXX comment at the rejection site would help future contributors: /* * XXX: whole-row Vars could in principle be handled by passing the * target table's composite type OID as to_rowtype, but * generateClonedTriggerStmt() currently has no access to it. */ SUMMARY OF ITEMS TO ADDRESS ---------------------------- [1] create_table_like.sql: define and drop trigger_func locally so the file can be run in isolation. [2] Add a test for EXCLUDING TRIGGERS. [3] create_table.sgml: align the INCLUDING TRIGGERS description with create_foreign_table.sgml, which already reads correctly: "All non-internal triggers are copied to the new table." [4] trigger.c generateClonedTriggerStmt(): lowercase "string" in comment "/* Reconstruct trigger function String list */". [5] parse_utilcmd.c expandTableLikeClause(): simplify or remove the comment "/* We make use of CreateTrigStmt's trigcomment option */". [6] Commit message: fix grammar in items (a), (b), (c) listed above. Items [3]-[6] are purely cosmetic. [1] and [2] are worth considering before commit, but none of these are blockers. Thanks for the patch. Best regards, Henson Choi