CREATE SCHEMA still resolves unqualified type names in pg_temp

From: Ayoub Kazar <ayoub(dot)kazar(at)data-bene(dot)io>
To: PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: CREATE SCHEMA still resolves unqualified type names in pg_temp
Date: 2026-11-13 13:10:12
Message-ID: 8d0b272d-1978-47a2-85a6-30679038765d@data-bene.io
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hello,

b6dae498dfa fixed the index/trigger cases by filling in the new schema's
name on the created objects' RangeVars.  But names that are looked up
inside the schema elements still go through the effective search_path,
where pg_temp is first.  For a column type, a temporary type can
therefore shadow a permanent one, and the column is dropped at session
end.

Reproducer: (see below too for FK case)

  -- session 1
  CREATE TYPE public.mytype AS (x text);
  CREATE TYPE pg_temp.mytype AS (y text);

  CREATE SCHEMA s CREATE TABLE t (a mytype);
  INSERT INTO s.t VALUES (ROW('test'));

  -- s.t.a is pg_temp.mytype, not public.mytype

  -- session 2, after session 1 exits
  \d s.t
  SELECT count(*) FROM s.t;

At session end the temp type is dropped, and the column's dependency on it
causes the column to be dropped.  In session 2, s.t has no columns but
still has the row we inserted.

The same thing happens to objects created in the new schema.  If pg_temp
has a table with the same name as a table created earlier in the same
CREATE SCHEMA, an unqualified FK reference in a later element resolves
to the temp table:

  CREATE TABLE pg_temp.parent (id int PRIMARY KEY);
  CREATE SCHEMA s
      CREATE TABLE parent (id int PRIMARY KEY)
      CREATE TABLE child (p_id int REFERENCES parent(id));

This fails with

  ERROR:  constraints on permanent tables may reference only permanent
tables

The same this affects LIKE, views, GRANT, etc.

The commit message for b6dae498dfa says names that will be looked up rather
than created should not resolve in pg_temp or pg_catalog, but only the
created objects' RangeVars are qualified.  The general search_path docs
say pg_temp is searched first for relation and type names, but CREATE
SCHEMA doesn't say anything about it.

The band-aid-like fix I have in mind is to append pg_temp to the temporary
search_path in CreateSchemaCommand:

  new_schema, old_path, pg_temp

finalNamespacePath() will produce

  pg_catalog, new_schema, old_path, pg_temp

when pg_catalog is not explicitly listed in old_path; an explicit
pg_temp or pg_catalog keeps its position.  That fixes the cases above,
but I'm not sure if it's the right answer, or this behavior is actually
the intended one... ; so maybe not a bug at all.

Attached is the fix, thoughts ?

Regards,
Ayoub Kazar

Attachment Content-Type Size
0001-Fix-CREATE-SCHEMA-lookup-names-resolving-in-pg_temp.patch text/x-patch 6.5 KB

Browse pgsql-hackers by date

  From Date Subject
Next Message Tender Wang 2026-11-13 13:13:01 Wrong varnullingrels for MERGE into a trigger-updatable view
Previous Message Rafia Sabih 2026-11-13 13:03:48 Semi-join related bug in postgres_fdw