Hi,
While reviewing another patch[1] I saw that COMMENTS on tables are being
ignored in CREATE TABLE LIKE:
psql (18.1 (Debian 18.1-1.pgdg13+2))
Type "help" for help.
postgres=# \pset null '(null)'
Null display is "(null)".
postgres=# CREATE TABLE t1 (id int, name text);
COMMENT ON TABLE t1 IS 'table comment';
CREATE TABLE t2 (LIKE t1 INCLUDING ALL);
CREATE TABLE t3 (LIKE t1 INCLUDING COMMENTS);
SELECT
obj_description('t1'::regclass, 'pg_class') AS t1_comment,
obj_description('t2'::regclass, 'pg_class') AS t2_comment,
obj_description('t3'::regclass, 'pg_class') AS t3_comment;
CREATE TABLE
COMMENT
CREATE TABLE
CREATE TABLE
t1_comment | t2_comment | t3_comment
---------------+------------+------------
table comment | (null) | (null)
(1 row)
v1 attached attempts to fix it by expanding expandTableLikeClause() to
retrieve and copy the table-level comment when the INCLUDING COMMENTS
[ALL] option is specified:
psql (19devel)
Type "help" for help.
postgres=# CREATE TABLE t1 (id int, name text);
COMMENT ON TABLE t1 IS 'table comment';
CREATE TABLE t2 (LIKE t1 INCLUDING ALL);
CREATE TABLE t3 (LIKE t1 INCLUDING COMMENTS);
SELECT
obj_description('t1'::regclass, 'pg_class') AS t1_comment,
obj_description('t2'::regclass, 'pg_class') AS t2_comment,
obj_description('t3'::regclass, 'pg_class') AS t3_comment;
CREATE TABLE
COMMENT
CREATE TABLE
CREATE TABLE
t1_comment | t2_comment | t3_comment
---------------+---------------+---------------
table comment | table comment | table comment
(1 row)
Thoughts?
Best, Jim
1 -
https://www.postgresql.org/message-id/flat/DG7Y34A6VBEG.76L7K1OML5DI%40gmail.comFrom 5afdb72e13092a94d01d40dcdc78a96c2632b423 Mon Sep 17 00:00:00 2001
From: Jim Jones <[email protected]>
Date: Thu, 12 Feb 2026 10:39:25 +0100
Subject: [PATCH v1] Fix missing table-level comment copying in CREATE TABLE
LIKE
When using CREATE TABLE ... LIKE ... INCLUDING COMMENTS (or INCLUDING
ALL), table-level comments were not being copied to the new table, even
though column comments, constraint comments, index comments, and
statistics comments were properly copied.
---
src/backend/parser/parse_utilcmd.c | 36 +++++++++++++++----
.../regress/expected/create_table_like.out | 7 ++++
src/test/regress/sql/create_table_like.sql | 2 ++
3 files changed, 39 insertions(+), 6 deletions(-)
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index b5f4c72459..bc6c9175a3 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -1307,17 +1307,18 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
}
/*
- * We cannot yet deal with defaults, CHECK constraints, indexes, or
- * statistics, since we don't yet know what column numbers the copied
- * columns will have in the finished table. If any of those options are
- * specified, add the LIKE clause to cxt->likeclauses so that
- * expandTableLikeClause will be called after we do know that.
+ * We cannot yet deal with defaults, CHECK constraints, indexes,
+ * statistics, or table comments, since we don't yet know what column
+ * numbers the copied columns will have in the finished table. If any of
+ * those options are specified, add the LIKE clause to cxt->likeclauses
+ * so that expandTableLikeClause will be called after we do know that.
*
* In order for this to work, we remember the relation OID so that
* expandTableLikeClause is certain to open the same table.
*/
if (table_like_clause->options &
- (CREATE_TABLE_LIKE_DEFAULTS |
+ (CREATE_TABLE_LIKE_COMMENTS |
+ CREATE_TABLE_LIKE_DEFAULTS |
CREATE_TABLE_LIKE_GENERATED |
CREATE_TABLE_LIKE_CONSTRAINTS |
CREATE_TABLE_LIKE_INDEXES |
@@ -1625,6 +1626,29 @@ expandTableLikeClause(RangeVar *heapRel, TableLikeClause *table_like_clause)
list_free(parent_extstats);
}
+ /*
+ * Copy comment on the relation itself, if requested.
+ */
+ if (table_like_clause->options & CREATE_TABLE_LIKE_COMMENTS)
+ {
+ comment = GetComment(RelationGetRelid(relation), RelationRelationId, 0);
+
+ if (comment != NULL)
+ {
+ CommentStmt *stmt = makeNode(CommentStmt);
+
+ stmt->objtype = OBJECT_TABLE;
+ if (heapRel->schemaname)
+ stmt->object = (Node *)list_make2(makeString(heapRel->schemaname),
+ makeString(heapRel->relname));
+ else
+ stmt->object = (Node *)list_make1(makeString(heapRel->relname));
+ stmt->comment = comment;
+
+ result = lappend(result, stmt);
+ }
+ }
+
/* Done with child rel */
table_close(childrel, NoLock);
diff --git a/src/test/regress/expected/create_table_like.out b/src/test/regress/expected/create_table_like.out
index d3c35c1484..765155912f 100644
--- a/src/test/regress/expected/create_table_like.out
+++ b/src/test/regress/expected/create_table_like.out
@@ -341,6 +341,7 @@ CREATE TABLE ctlt3 (a text CHECK (length(a) < 5), c text CHECK (length(c) < 7));
ALTER TABLE ctlt3 ALTER COLUMN c SET STORAGE EXTERNAL;
ALTER TABLE ctlt3 ALTER COLUMN a SET STORAGE MAIN;
CREATE INDEX ctlt3_fnidx ON ctlt3 ((a || c));
+COMMENT ON TABLE ctlt3 IS 'ctlt3 table comment';
COMMENT ON COLUMN ctlt3.a IS 'A3';
COMMENT ON COLUMN ctlt3.c IS 'C';
COMMENT ON CONSTRAINT ctlt3_a_check ON ctlt3 IS 't3_a_check';
@@ -449,6 +450,12 @@ SELECT description FROM pg_description, pg_constraint c WHERE classoid = 'pg_con
t3_a_check
(1 row)
+SELECT obj_description('ctlt13_like'::regclass, 'pg_class') AS table_comment;
+ table_comment
+---------------------
+ ctlt3 table comment
+(1 row)
+
CREATE TABLE ctlt_all (LIKE ctlt1 INCLUDING ALL);
\d+ ctlt_all
Table "public.ctlt_all"
diff --git a/src/test/regress/sql/create_table_like.sql b/src/test/regress/sql/create_table_like.sql
index 93389b57db..0390834186 100644
--- a/src/test/regress/sql/create_table_like.sql
+++ b/src/test/regress/sql/create_table_like.sql
@@ -153,6 +153,7 @@ CREATE TABLE ctlt3 (a text CHECK (length(a) < 5), c text CHECK (length(c) < 7));
ALTER TABLE ctlt3 ALTER COLUMN c SET STORAGE EXTERNAL;
ALTER TABLE ctlt3 ALTER COLUMN a SET STORAGE MAIN;
CREATE INDEX ctlt3_fnidx ON ctlt3 ((a || c));
+COMMENT ON TABLE ctlt3 IS 'ctlt3 table comment';
COMMENT ON COLUMN ctlt3.a IS 'A3';
COMMENT ON COLUMN ctlt3.c IS 'C';
COMMENT ON CONSTRAINT ctlt3_a_check ON ctlt3 IS 't3_a_check';
@@ -173,6 +174,7 @@ CREATE TABLE ctlt13_inh () INHERITS (ctlt1, ctlt3);
CREATE TABLE ctlt13_like (LIKE ctlt3 INCLUDING CONSTRAINTS INCLUDING INDEXES INCLUDING COMMENTS INCLUDING STORAGE) INHERITS (ctlt1);
\d+ ctlt13_like
SELECT description FROM pg_description, pg_constraint c WHERE classoid = 'pg_constraint'::regclass AND objoid = c.oid AND c.conrelid = 'ctlt13_like'::regclass;
+SELECT obj_description('ctlt13_like'::regclass, 'pg_class') AS table_comment;
CREATE TABLE ctlt_all (LIKE ctlt1 INCLUDING ALL);
\d+ ctlt_all
--
2.43.0