| From: | Jim Jones <jim(dot)jones(at)uni-muenster(dot)de> |
|---|---|
| To: | PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org> |
| Subject: | CREATE TABLE .. LIKE copies comments to an unrelated table |
| Date: | 2026-10-01 14:35:15 |
| Message-ID: | 479d75af-1ab5-41f7-aa9b-e34d6581d7c0@uni-muenster.de |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
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?
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);
+ }
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
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Jelte Fennema-Nio | 2026-10-01 14:47:28 | Re: postgres_fdw: Fix costing of remote sorts without remote estimates |
| Previous Message | David Christensen | 2026-10-01 14:31:25 | Re: SSI: ON CONFLICT DO SELECT takes no predicate lock on the returned row |