From e46c9322d58fd8d9d3f68f379202d7cc4f134e43 Mon Sep 17 00:00:00 2001
From: Jim Jones <jim.jones@uni-muenster.de>
Date: Thu, 1 Oct 2026 18:24:22 +0200
Subject: [PATCH v1] Fix copied comments landing on wrong table in CREATE TEMP
 TABLE LIKE

transformCreateStmt() schema-qualifies the target name so that the
commands generated after the table is created cannot find a different
table of the same name earlier in search_path.  Temp tables were
exempted, on the theory that the RangeVar's relpersistence is enough.
But the CommentStmts generated by LIKE ... INCLUDING COMMENTS identify
the table by a name list, which loses relpersistence.  So with pg_temp
listed explicitly after another schema containing a table of the same
name, the copied column and constraint comments were applied to that
other table, or the command failed if it had no matching constraint.

Fix by qualifying temp table names too, using the actual temp schema
name.
---
 src/backend/parser/parse_utilcmd.c             | 10 ++++++----
 .../regress/expected/create_table_like.out     | 18 ++++++++++++++++++
 src/test/regress/sql/create_table_like.sql     | 13 +++++++++++++
 3 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index f0c7755b8fb..6532afd8329 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -222,11 +222,13 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
 	 * If the target relation name isn't schema-qualified, make it so.  This
 	 * prevents some corner cases in which added-on rewritten commands might
 	 * think they should apply to other relations that have the same name and
-	 * are earlier in the search path.  But a local temp table is effectively
-	 * specified to be in pg_temp, so no need for anything extra in that case.
+	 * are earlier in the search path.  This applies to temp tables too: the
+	 * RangeVar's relpersistence suffices for commands that look the table up
+	 * via the RangeVar itself, but not for those that identify it by a name
+	 * list, such as the COMMENT commands generated for LIKE ... INCLUDING
+	 * COMMENTS.
 	 */
-	if (stmt->relation->schemaname == NULL
-		&& stmt->relation->relpersistence != RELPERSISTENCE_TEMP)
+	if (stmt->relation->schemaname == NULL)
 		stmt->relation->schemaname = get_namespace_name(namespaceid);
 
 	/* Set up CreateStmtContext */
diff --git a/src/test/regress/expected/create_table_like.out b/src/test/regress/expected/create_table_like.out
index a23735b5fb4..3386c028a31 100644
--- a/src/test/regress/expected/create_table_like.out
+++ b/src/test/regress/expected/create_table_like.out
@@ -544,6 +544,24 @@ Statistics objects:
 Not-null constraints:
     "ctlt1_a_not_null" NOT NULL "a"
 
+ROLLBACK;
+-- Check that copied comments go to a new temp table, not to a same-named
+-- permanent table that precedes pg_temp in the search path
+BEGIN;
+SET LOCAL search_path = public, pg_temp;
+CREATE TABLE ctlt_src (a int);
+COMMENT ON COLUMN ctlt_src.a IS 'src column';
+CREATE TABLE ctlt_temp (a int);
+COMMENT ON COLUMN ctlt_temp.a IS 'unrelated column';
+CREATE TEMP TABLE ctlt_temp (LIKE ctlt_src INCLUDING COMMENTS);
+SELECT relpersistence, col_description(oid, 1) AS column_comment
+FROM pg_class WHERE relname = 'ctlt_temp' ORDER BY 1;
+ relpersistence |  column_comment  
+----------------+------------------
+ p              | unrelated column
+ t              | src column
+(2 rows)
+
 ROLLBACK;
 DROP TABLE ctlt1, ctlt2, ctlt3, ctlt4, ctlt12_storage, ctlt12_comments, ctlt1_inh, ctlt13_inh, ctlt13_like, ctlt_all, ctla, ctlb CASCADE;
 NOTICE:  drop cascades to table inhe
diff --git a/src/test/regress/sql/create_table_like.sql b/src/test/regress/sql/create_table_like.sql
index d52a93ef131..9ffd3178302 100644
--- a/src/test/regress/sql/create_table_like.sql
+++ b/src/test/regress/sql/create_table_like.sql
@@ -195,6 +195,19 @@ CREATE TABLE ctlt1 (LIKE ctlt1 INCLUDING ALL);
 \d+ ctlt1
 ROLLBACK;
 
+-- Check that copied comments go to a new temp table, not to a same-named
+-- permanent table that precedes pg_temp in the search path
+BEGIN;
+SET LOCAL search_path = public, pg_temp;
+CREATE TABLE ctlt_src (a int);
+COMMENT ON COLUMN ctlt_src.a IS 'src column';
+CREATE TABLE ctlt_temp (a int);
+COMMENT ON COLUMN ctlt_temp.a IS 'unrelated column';
+CREATE TEMP TABLE ctlt_temp (LIKE ctlt_src INCLUDING COMMENTS);
+SELECT relpersistence, col_description(oid, 1) AS column_comment
+FROM pg_class WHERE relname = 'ctlt_temp' ORDER BY 1;
+ROLLBACK;
+
 DROP TABLE ctlt1, ctlt2, ctlt3, ctlt4, ctlt12_storage, ctlt12_comments, ctlt1_inh, ctlt13_inh, ctlt13_like, ctlt_all, ctla, ctlb CASCADE;
 
 -- LIKE must respect NO INHERIT property of constraints
-- 
2.55.0

