aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils')
-rw-r--r--src/backend/utils/adt/dbsize.c5
-rw-r--r--src/backend/utils/cache/relcache.c25
2 files changed, 25 insertions, 5 deletions
diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c
index 2ccdc0cee6e..03975fcea44 100644
--- a/src/backend/utils/adt/dbsize.c
+++ b/src/backend/utils/adt/dbsize.c
@@ -259,6 +259,9 @@ pg_tablespace_size_name(PG_FUNCTION_ARGS)
/*
* calculate size of (one fork of) a relation
+ *
+ * Note: we can safely apply this to temp tables of other sessions, so there
+ * is no check here or at the call sites for that.
*/
static int64
calculate_relation_size(RelFileNode *rfn, BackendId backend, ForkNumber forknum)
@@ -313,7 +316,7 @@ pg_relation_size(PG_FUNCTION_ARGS)
* that makes queries like "SELECT pg_relation_size(oid) FROM pg_class"
* less robust, because while we scan pg_class with an MVCC snapshot,
* someone else might drop the table. It's better to return NULL for
- * alread-dropped tables than throw an error and abort the whole query.
+ * already-dropped tables than throw an error and abort the whole query.
*/
if (rel == NULL)
PG_RETURN_NULL();
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index a64d739cebc..bd7f567f1e9 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -852,20 +852,33 @@ RelationBuildDesc(Oid targetRelId, bool insertIt)
case RELPERSISTENCE_UNLOGGED:
case RELPERSISTENCE_PERMANENT:
relation->rd_backend = InvalidBackendId;
+ relation->rd_islocaltemp = false;
break;
case RELPERSISTENCE_TEMP:
if (isTempOrToastNamespace(relation->rd_rel->relnamespace))
+ {
relation->rd_backend = MyBackendId;
+ relation->rd_islocaltemp = true;
+ }
else
{
/*
- * If it's a local temp table, but not one of ours, we have to
- * use the slow, grotty method to figure out the owning
- * backend.
+ * If it's a temp table, but not one of ours, we have to use
+ * the slow, grotty method to figure out the owning backend.
+ *
+ * Note: it's possible that rd_backend gets set to MyBackendId
+ * here, in case we are looking at a pg_class entry left over
+ * from a crashed backend that coincidentally had the same
+ * BackendId we're using. We should *not* consider such a
+ * table to be "ours"; this is why we need the separate
+ * rd_islocaltemp flag. The pg_class entry will get flushed
+ * if/when we clean out the corresponding temp table namespace
+ * in preparation for using it.
*/
relation->rd_backend =
GetTempNamespaceBackendId(relation->rd_rel->relnamespace);
Assert(relation->rd_backend != InvalidBackendId);
+ relation->rd_islocaltemp = false;
}
break;
default:
@@ -1386,6 +1399,7 @@ formrdesc(const char *relationName, Oid relationReltype,
relation->rd_createSubid = InvalidSubTransactionId;
relation->rd_newRelfilenodeSubid = InvalidSubTransactionId;
relation->rd_backend = InvalidBackendId;
+ relation->rd_islocaltemp = false;
/*
* initialize relation tuple form
@@ -2535,16 +2549,19 @@ RelationBuildLocalRelation(const char *relname,
/* needed when bootstrapping: */
rel->rd_rel->relowner = BOOTSTRAP_SUPERUSERID;
- /* set up persistence; rd_backend is a function of persistence type */
+ /* set up persistence and relcache fields dependent on it */
rel->rd_rel->relpersistence = relpersistence;
switch (relpersistence)
{
case RELPERSISTENCE_UNLOGGED:
case RELPERSISTENCE_PERMANENT:
rel->rd_backend = InvalidBackendId;
+ rel->rd_islocaltemp = false;
break;
case RELPERSISTENCE_TEMP:
+ Assert(isTempOrToastNamespace(relnamespace));
rel->rd_backend = MyBackendId;
+ rel->rd_islocaltemp = true;
break;
default:
elog(ERROR, "invalid relpersistence: %c", relpersistence);