allow_dup_relfilenodeid_PoC.txt
text/plain
Filename: allow_dup_relfilenodeid_PoC.txt
Type: text/plain
Part: 1
diff --git a/src/backend/utils/cache/relfilenodemap.c b/src/backend/utils/cache/relfilenodemap.c
index 70c323c720..5d0b39a243 100644
--- a/src/backend/utils/cache/relfilenodemap.c
+++ b/src/backend/utils/cache/relfilenodemap.c
@@ -130,7 +130,8 @@ InitializeRelfilenodeMap(void)
/*
* Map a relation's (tablespace, filenode) to a relation's oid and cache the
- * result.
+ * result. If both non-temprary and temprary reltations are found, persistent
+ * one is choosed.
*
* Returns InvalidOid if no relation matching the criteria could be found.
*/
@@ -183,6 +184,8 @@ RelidByRelfilenode(Oid reltablespace, Oid relfilenode)
}
else
{
+ bool is_temp = false;
+
/*
* Not a shared table, could either be a plain relation or a
* non-shared, nailed one, like e.g. pg_class.
@@ -212,14 +215,25 @@ RelidByRelfilenode(Oid reltablespace, Oid relfilenode)
Form_pg_class classform = (Form_pg_class) GETSTRUCT(ntp);
if (found)
- elog(ERROR,
- "unexpected duplicate for tablespace %u, relfilenode %u",
- reltablespace, relfilenode);
+ {
+ /* check if the same entry for the same persistency exists */
+ if (is_temp ?
+ classform->relpersistence == RELPERSISTENCE_TEMP :
+ classform->relpersistence != RELPERSISTENCE_TEMP)
+ elog(ERROR,
+ "unexpected duplicate for tablespace %u, relfilenode %u",
+ reltablespace, relfilenode);
+
+ /* prioritize non-temporary if both are found */
+ if (!is_temp)
+ continue;
+ }
found = true;
Assert(classform->reltablespace == reltablespace);
Assert(classform->relfilenode == relfilenode);
relid = classform->oid;
+ is_temp = (classform->relpersistence == RELPERSISTENCE_TEMP);
}
systable_endscan(scandesc);