diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 11371326a29..3cd4e7fcbcb 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -25637,7 +25637,8 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); pg_relation_filepath. For a relation in the database's default tablespace, the tablespace can be specified as zero. Returns NULL if no relation in the current database - is associated with the given values. + is associated with the given values, or if dealing with a temporary + relation. diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c index c0783ba1233..53af7f2e863 100644 --- a/src/backend/utils/adt/dbsize.c +++ b/src/backend/utils/adt/dbsize.c @@ -917,6 +917,9 @@ pg_relation_filenode(PG_FUNCTION_ARGS) * * We don't fail but return NULL if we cannot find a mapping. * + * Temporary relations are not detected, returning NULL (see + * RelidByRelfilenumber() for the reasons). + * * InvalidOid can be passed instead of the current database's default * tablespace. */ diff --git a/src/backend/utils/cache/relfilenodemap.c b/src/backend/utils/cache/relfilenodemap.c index 68b01ca68fe..f49bcc793b7 100644 --- a/src/backend/utils/cache/relfilenodemap.c +++ b/src/backend/utils/cache/relfilenodemap.c @@ -135,6 +135,11 @@ InitializeRelfilenodeMap(void) * Map a relation's (tablespace, filenode) to a relation's oid and cache the * result. * + * A temporary relation may share its relfilenumber with a permanent relation + * or temporary relations created in other backends. Being able to uniquely + * identify a temporary relation would require a backend's proc number, which + * we do not know about. Hence, this function ignores this case. + * * Returns InvalidOid if no relation matching the criteria could be found. */ Oid @@ -214,6 +219,9 @@ RelidByRelfilenode(Oid reltablespace, Oid relfilenode) { Form_pg_class classform = (Form_pg_class) GETSTRUCT(ntp); + if (classform->relpersistence == RELPERSISTENCE_TEMP) + continue; + if (found) elog(ERROR, "unexpected duplicate for tablespace %u, relfilenode %u", diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index a33ee26f293..d0095d0ebfa 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -3460,12 +3460,15 @@ SELECT conname as constraint, obj_description(oid, 'pg_constraint') as comment F -- filenode function call can return NULL for a relation dropped concurrently -- with the call's surrounding query, so ignore a NULL mapped_oid for -- relations that no longer exist after all calls finish. +-- Temporary relations are ignored, as not supported by pg_filenode_relation(). CREATE TEMP TABLE filenode_mapping AS SELECT oid, mapped_oid, reltablespace, relfilenode, relname FROM pg_class, pg_filenode_relation(reltablespace, pg_relation_filenode(oid)) AS mapped_oid -WHERE relkind IN ('r', 'i', 'S', 't', 'm') AND mapped_oid IS DISTINCT FROM oid; +WHERE relkind IN ('r', 'i', 'S', 't', 'm') + AND relpersistence != 't' + AND mapped_oid IS DISTINCT FROM oid; SELECT m.* FROM filenode_mapping m LEFT JOIN pg_class c ON c.oid = m.oid WHERE c.oid IS NOT NULL OR m.mapped_oid IS NOT NULL; oid | mapped_oid | reltablespace | relfilenode | relname diff --git a/src/test/regress/expected/create_table.out b/src/test/regress/expected/create_table.out index 86ca1381fc2..041cc3f28ab 100644 --- a/src/test/regress/expected/create_table.out +++ b/src/test/regress/expected/create_table.out @@ -297,6 +297,18 @@ ERROR: tables declared WITH OIDS are not supported -- but explicitly not adding oids is still supported CREATE TEMP TABLE withoutoid() WITHOUT OIDS; DROP TABLE withoutoid; CREATE TEMP TABLE withoutoid() WITH (oids = false); DROP TABLE withoutoid; +-- temporary tables are ignored by pg_filenode_relation(). +CREATE TEMP TABLE relation_filenode_check(c1 int); +SELECT relpersistence, + pg_filenode_relation (reltablespace, pg_relation_filenode(oid)) + FROM pg_class + WHERE relname = 'relation_filenode_check'; + relpersistence | pg_filenode_relation +----------------+---------------------- + t | +(1 row) + +DROP TABLE relation_filenode_check; -- check restriction with default expressions -- invalid use of column reference in default expressions CREATE TABLE default_expr_column (id int DEFAULT (id)); diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index e72f02fedeb..1ef803b9b8e 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -2180,13 +2180,15 @@ SELECT conname as constraint, obj_description(oid, 'pg_constraint') as comment F -- filenode function call can return NULL for a relation dropped concurrently -- with the call's surrounding query, so ignore a NULL mapped_oid for -- relations that no longer exist after all calls finish. +-- Temporary relations are ignored, as not supported by pg_filenode_relation(). CREATE TEMP TABLE filenode_mapping AS SELECT oid, mapped_oid, reltablespace, relfilenode, relname FROM pg_class, pg_filenode_relation(reltablespace, pg_relation_filenode(oid)) AS mapped_oid -WHERE relkind IN ('r', 'i', 'S', 't', 'm') AND mapped_oid IS DISTINCT FROM oid; - +WHERE relkind IN ('r', 'i', 'S', 't', 'm') + AND relpersistence != 't' + AND mapped_oid IS DISTINCT FROM oid; SELECT m.* FROM filenode_mapping m LEFT JOIN pg_class c ON c.oid = m.oid WHERE c.oid IS NOT NULL OR m.mapped_oid IS NOT NULL; diff --git a/src/test/regress/sql/create_table.sql b/src/test/regress/sql/create_table.sql index ad55a24a7bf..56184b15b49 100644 --- a/src/test/regress/sql/create_table.sql +++ b/src/test/regress/sql/create_table.sql @@ -304,6 +304,14 @@ CREATE TABLE withoid() WITH (oids = true); CREATE TEMP TABLE withoutoid() WITHOUT OIDS; DROP TABLE withoutoid; CREATE TEMP TABLE withoutoid() WITH (oids = false); DROP TABLE withoutoid; +-- temporary tables are ignored by pg_filenode_relation(). +CREATE TEMP TABLE relation_filenode_check(c1 int); +SELECT relpersistence, + pg_filenode_relation (reltablespace, pg_relation_filenode(oid)) + FROM pg_class + WHERE relname = 'relation_filenode_check'; +DROP TABLE relation_filenode_check; + -- check restriction with default expressions -- invalid use of column reference in default expressions CREATE TABLE default_expr_column (id int DEFAULT (id));