RelidByRelfilenumber_prefer_perm_rels_15-16.patch
text/x-patch
Filename: RelidByRelfilenumber_prefer_perm_rels_15-16.patch
Type: text/x-patch
Part: 1
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/backend/utils/cache/relfilenumbermap.c | 26 | 4 |
diff --git a/src/backend/utils/cache/relfilenumbermap.c b/src/backend/utils/cache/relfilenumbermap.c
index 220f33d43f..d188f53eda 100644
--- a/src/backend/utils/cache/relfilenumbermap.c
+++ b/src/backend/utils/cache/relfilenumbermap.c
@@ -130,7 +130,12 @@ InitializeRelfilenumberMap(void)
/*
* Map a relation's (tablespace, relfilenumber) to a relation's oid and cache
- * the result.
+ * the result. If both permanent and temporary relations are found, persistent
+ * one is chosen.
+ *
+ * XXXX: This behavior is valid for most use cases, except for the SQL function
+ * pg_lation_filenode(), which can handle temporary relations. In all other
+ * cases, this function is intended fo ruse with permanent relations only.
*
* Returns InvalidOid if no relation matching the criteria could be found.
*/
@@ -183,6 +188,8 @@ RelidByRelfilenumber(Oid reltablespace, RelFileNumber relfilenumber)
}
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,19 +219,34 @@ RelidByRelfilenumber(Oid reltablespace, RelFileNumber relfilenumber)
Form_pg_class classform = (Form_pg_class) GETSTRUCT(ntp);
if (found)
- elog(ERROR,
- "unexpected duplicate for tablespace %u, relfilenumber %u",
- reltablespace, relfilenumber);
+ {
+ /* 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, relfilenumber %u",
+ reltablespace, relfilenumber);
+
+ /* prioritize non-temporary if both are found */
+ if (!is_temp)
+ continue;
+ }
found = true;
Assert(classform->reltablespace == reltablespace);
Assert(classform->relfilenode == relfilenumber);
relid = classform->oid;
+ is_temp = (classform->relpersistence == RELPERSISTENCE_TEMP);
}
systable_endscan(scandesc);
table_close(relation, AccessShareLock);
+ /* don't cache the relid if it is a temp relation */
+ if (is_temp && found)
+ return relid;
+
/* check for tables that are mapped but not shared */
if (!found)
relid = RelationMapFilenumberToOid(relfilenumber, false);