Re: CREATE TABLE LIKE INCLUDING TRIGGERS - Mailing list pgsql-hackers

From Henson Choi
Subject Re: CREATE TABLE LIKE INCLUDING TRIGGERS
Date
Msg-id CAAAe_zAHAjTVGE9fAuTZ9df7Y7n7Zctn8WtEkUfytAu+VKQE7w@mail.gmail.com
Whole thread
In response to Re: CREATE TABLE LIKE INCLUDING TRIGGERS  (Henson Choi <assam258@gmail.com>)
List pgsql-hackers
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

pgsql-hackers by date:

Previous
From: jian he
Date:
Subject: Re: FOR PORTION OF does not recompute GENERATED STORED columns that depend on the range column
Next
From: Michael Paquier
Date:
Subject: Re: Fix DROP PROPERTY GRAPH "unsupported object class" error