Re: CREATE TABLE .. LIKE copies comments to an unrelated table

From: Junwang Zhao <zhjwpku(at)gmail(dot)com>
To: Jim Jones <jim(dot)jones(at)uni-muenster(dot)de>
Cc: PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: CREATE TABLE .. LIKE copies comments to an unrelated table
Date: 2026-10-01 15:31:57
Message-ID: CAEG8a3+sB2Egsse90eiTFZ7vodZ1ph_VkHt3=rbfjN1jes4XZQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Thu, Oct 1, 2026 at 10:35 PM Jim Jones <jim(dot)jones(at)uni-muenster(dot)de> wrote:
>
> Hi
>
> While working on another patch I found that CREATE TABLE ... LIKE
> INCLUDING COMMENTS copies the comments to the wrong table when the
> target is a temp table and a table with the same name exists in a schema
> listed before pg_temp in search_path.
>
> Example:
>
> psql (18.3 (Debian 18.3-1.pgdg13+1))
> Type "help" for help.
>
> db=> CREATE TABLE src (a int);
> CREATE TABLE
> db=> COMMENT ON COLUMN src.a IS 'col comment';
> COMMENT
> db=> CREATE TABLE foo (a int); -- unrelated table
> CREATE TABLE
> db=> COMMENT ON COLUMN foo.a IS 'important comment';
> COMMENT
> db=> SET search_path = public, pg_temp;
> SET
> db=> CREATE TEMP TABLE foo (LIKE src INCLUDING COMMENTS);
> CREATE TABLE
> db=> SELECT n.nspname, relname, col_description(c.oid, 1) AS colcomment
> FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace
> WHERE c.relname = 'foo';
> nspname | relname | colcomment
> ------------+---------+-------------
> public | foo | col comment
> pg_temp_24 | foo |
> (2 rows)
>
> The unrelated public.foo got the column comment and the created
> temporary table got none -- public.foo.a comment was overwritten. Is
> this the expected behaviour?

I think this is a bug, and I can reproduce it on master.

>
> Setting the schema to pg_temp in case of RELPERSISTENCE_TEMP in
> transformCreateStmt seems to do the trick (but I didn't dive too deep in
> the code just yet):
>
> - if (stmt->relation->schemaname == NULL
> - && stmt->relation->relpersistence != RELPERSISTENCE_TEMP)
> - stmt->relation->schemaname =
> get_namespace_name(namespaceid);
> + if (stmt->relation->schemaname == NULL)
> + {
> + if (stmt->relation->relpersistence == RELPERSISTENCE_TEMP)
> + stmt->relation->schemaname = pstrdup("pg_temp");
> + else
> + stmt->relation->schemaname =
> get_namespace_name(namespaceid);
> + }

The preceding RangeVarGetAndCheckCreationNamespace has already
initialized the temporary namespace and returned its OID, so simplified it
to:

if (stmt->relation->schemaname == NULL)
stmt->relation->schemaname = get_namespace_name(namespaceid);

should work, I did a quick test to verify this.

>
> With my changes in HEAD:
>
> db=> CREATE TABLE src (a int);
> CREATE TABLE
> db=> COMMENT ON COLUMN src.a IS 'col comment';
> COMMENT
> db=> CREATE TABLE foo (a int); -- unrelated table
> CREATE TABLE
> db=> COMMENT ON COLUMN foo.a IS 'important comment';
> COMMENT
> db=> SET search_path = public, pg_temp;
> SET
> db=> CREATE TEMP TABLE foo (LIKE src INCLUDING COMMENTS);
> CREATE TABLE
> db=> SELECT n.nspname, relname, col_description(c.oid, 1) AS colcomment
> FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace
> WHERE c.relname = 'foo';
> nspname | relname | colcomment
> ------------+---------+-------------------
> public | foo | important comment
> pg_temp_92 | foo | col comment
> (2 rows)
>
>
> WDYT?
>
> Best, Jim
>
>
>

--
Regards
Junwang Zhao

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Jim Jones 2026-10-01 16:02:22 Re: CREATE TABLE .. LIKE copies comments to an unrelated table
Previous Message David Christensen 2026-10-01 15:30:52 Re: SSI: ON CONFLICT DO SELECT takes no predicate lock on the returned row