* Don't allow reindex on temp tables of other backends ... their local
* buffer manager is not going to cope.
*/
- if (isOtherTempNamespace(RelationGetNamespace(iRel)))
+ if (RELATION_IS_OTHER_TEMP(iRel))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot reindex temporary tables of other sessions")));
/*
* isOtherTempNamespace - is the given namespace some other backend's
* temporary-table namespace (including temporary-toast-table namespaces)?
+ *
+ * Note: for most purposes in the C code, this function is obsolete. Use
+ * RELATION_IS_OTHER_TEMP() instead to detect non-local temp relations.
*/
bool
isOtherTempNamespace(Oid namespaceId)
* Toast tables for regular relations go in pg_toast; those for temp
* relations go into the per-backend temp-toast-table namespace.
*/
- if (rel->rd_istemp)
+ if (rel->rd_islocaltemp)
namespaceid = GetTempToastNamespace();
else
namespaceid = PG_TOAST_NAMESPACE;
* probably not up-to-date on disk. (We don't throw a warning here; it
* would just lead to chatter during a database-wide ANALYZE.)
*/
- if (isOtherTempNamespace(RelationGetNamespace(onerel)))
+ if (RELATION_IS_OTHER_TEMP(onerel))
{
relation_close(onerel, ShareUpdateExclusiveLock);
return;
* Reject clustering a remote temp table ... their local buffer
* manager is not going to cope.
*/
- if (isOtherTempNamespace(RelationGetNamespace(rel)))
+ if (RELATION_IS_OTHER_TEMP(rel))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot cluster temporary tables of other sessions")));
* check_index_is_clusterable which is redundant, but we leave it for
* extra safety.
*/
- if (isOtherTempNamespace(RelationGetNamespace(OldHeap)))
+ if (RELATION_IS_OTHER_TEMP(OldHeap))
{
relation_close(OldHeap, AccessExclusiveLock);
return;
* Don't allow cluster on temp tables of other backends ... their local
* buffer manager is not going to cope.
*/
- if (isOtherTempNamespace(RelationGetNamespace(OldHeap)))
+ if (RELATION_IS_OTHER_TEMP(OldHeap))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot cluster temporary tables of other sessions")));
}
/* check read-only transaction */
- if (XactReadOnly && is_from &&
- !isTempNamespace(RelationGetNamespace(cstate->rel)))
+ if (XactReadOnly && is_from && !cstate->rel->rd_islocaltemp)
ereport(ERROR,
(errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
errmsg("transaction is read-only")));
/*
* Don't try to CREATE INDEX on temp tables of other backends.
*/
- if (isOtherTempNamespace(namespaceId))
+ if (RELATION_IS_OTHER_TEMP(rel))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot create indexes on temporary tables of other sessions")));
continue;
/* Skip temp tables of other backends; we can't reindex them at all */
- if (isOtherTempNamespace(classtuple->relnamespace))
+ if (classtuple->relistemp &&
+ !isTempNamespace(classtuple->relnamespace))
continue;
/* Check user/system classification, and optionally skip */
* Don't allow truncate on temp tables of other backends ... their local
* buffer manager is not going to cope.
*/
- if (isOtherTempNamespace(RelationGetNamespace(rel)))
+ if (RELATION_IS_OTHER_TEMP(rel))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot truncate temporary tables of other sessions")));
errmsg("inherited relation \"%s\" is not a table",
parent->relname)));
/* Permanent rels cannot inherit from temporary ones */
- if (!istemp && isTempNamespace(RelationGetNamespace(relation)))
+ if (!istemp && relation->rd_istemp)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("cannot inherit from temporary relation \"%s\"",
* Don't allow rewrite on temp tables of other backends ... their
* local buffer manager is not going to cope.
*/
- if (isOtherTempNamespace(RelationGetNamespace(OldHeap)))
+ if (RELATION_IS_OTHER_TEMP(OldHeap))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot rewrite temporary tables of other sessions")));
* backend has created in the temp table, because non-shared buffers are
* used for temp tables.)
*/
- if (isTempNamespace(RelationGetNamespace(pkrel)))
+ if (pkrel->rd_istemp)
{
- if (!isTempNamespace(RelationGetNamespace(rel)))
+ if (!rel->rd_istemp)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
errmsg("cannot reference temporary table from permanent table constraint")));
}
else
{
- if (isTempNamespace(RelationGetNamespace(rel)))
+ if (rel->rd_istemp)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
errmsg("cannot reference permanent table from temporary table constraint")));
* Don't allow moving temp tables of other backends ... their local buffer
* manager is not going to cope.
*/
- if (isOtherTempNamespace(RelationGetNamespace(rel)))
+ if (RELATION_IS_OTHER_TEMP(rel))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot move temporary tables of other sessions")));
ATSimplePermissions(parent_rel, false);
/* Permanent rels cannot inherit from temporary ones */
- if (!isTempNamespace(RelationGetNamespace(child_rel)) &&
- isTempNamespace(RelationGetNamespace(parent_rel)))
+ if (parent_rel->rd_istemp && !child_rel->rd_istemp)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("cannot inherit from temporary relation \"%s\"",
* warning here; it would just lead to chatter during a database-wide
* VACUUM.)
*/
- if (isOtherTempNamespace(RelationGetNamespace(onerel)))
+ if (RELATION_IS_OTHER_TEMP(onerel))
{
relation_close(onerel, lmode);
PopActiveSnapshot();
Index childRTindex;
AppendRelInfo *appinfo;
+ /* Open rel, acquire the appropriate lock type */
+ if (childOID != parentOID)
+ newrelation = heap_open(childOID, lockmode);
+ else
+ newrelation = oldrelation;
+
/*
* It is possible that the parent table has children that are temp
* tables of other backends. We cannot safely access such tables
* (because of buffering issues), and the best thing to do seems to be
* to silently ignore them.
*/
- if (childOID != parentOID &&
- isOtherTempNamespace(get_rel_namespace(childOID)))
+ if (childOID != parentOID && RELATION_IS_OTHER_TEMP(newrelation))
+ {
+ heap_close(newrelation, lockmode);
continue;
-
- /* Open rel, acquire the appropriate lock type */
- if (childOID != parentOID)
- newrelation = heap_open(childOID, lockmode);
- else
- newrelation = oldrelation;
+ }
/*
* Build an RTE for the child, and attach to query's rangetable list.
bool dovacuum;
bool doanalyze;
bool wraparound;
- int backendID;
relid = HeapTupleGetOid(tuple);
* Check if it is a temp table (presumably, of some other backend's).
* We cannot safely process other backends' temp tables.
*/
- backendID = GetTempNamespaceBackendId(classForm->relnamespace);
-
- if (backendID > 0)
+ if (classForm->relistemp)
{
+ int backendID;
+
+ backendID = GetTempNamespaceBackendId(classForm->relnamespace);
+
/* We just ignore it if the owning backend is still active */
if (backendID == MyBackendId || !BackendIdIsActive(backendID))
{
bool wraparound;
/*
- * Skip temp tables (i.e. those in temp namespaces). We cannot safely
- * process other backends' temp tables.
+ * We cannot safely process other backends' temp tables, so skip 'em.
*/
- if (isAnyTempNamespace(classForm->relnamespace))
+ if (classForm->relistemp)
continue;
relid = HeapTupleGetOid(tuple);
if (reln->rd_istemp)
{
+ /* see comments in ReadBufferExtended */
+ if (RELATION_IS_OTHER_TEMP(reln))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot access temporary tables of other sessions")));
+
/* pass it off to localbuf.c */
LocalPrefetchBuffer(reln->rd_smgr, forkNum, blockNum);
}
/* Open it at the smgr level if not already done */
RelationOpenSmgr(reln);
+ /*
+ * Reject attempts to read non-local temporary relations; we would
+ * be likely to get wrong data since we have no visibility into the
+ * owning session's local buffers.
+ */
+ if (RELATION_IS_OTHER_TEMP(reln))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot access temporary tables of other sessions")));
+
/*
* Read the buffer, and update pgstat counters to reflect a cache
* hit or miss.
/*
* ReadBufferWithoutRelcache -- like ReadBufferExtended, but doesn't require
* a relcache entry for the relation.
+ *
+ * NB: caller is assumed to know what it's doing if isTemp is true.
*/
Buffer
ReadBufferWithoutRelcache(RelFileNode rnode, bool isTemp,
relation->rd_isnailed = false;
relation->rd_createSubid = InvalidSubTransactionId;
relation->rd_newRelfilenodeSubid = InvalidSubTransactionId;
- relation->rd_istemp = isTempOrToastNamespace(relation->rd_rel->relnamespace);
+ relation->rd_istemp = relation->rd_rel->relistemp;
+ if (relation->rd_istemp)
+ relation->rd_islocaltemp = isTempOrToastNamespace(relation->rd_rel->relnamespace);
+ else
+ relation->rd_islocaltemp = false;
/*
* initialize the tuple descriptor (relation->rd_att).
relation->rd_createSubid = InvalidSubTransactionId;
relation->rd_newRelfilenodeSubid = InvalidSubTransactionId;
relation->rd_istemp = false;
+ relation->rd_islocaltemp = false;
/*
* initialize relation tuple form
/* must flag that we have rels created in this transaction */
need_eoxact_work = true;
- /* is it a temporary relation? */
+ /* it is temporary if and only if it is in my temp-table namespace */
rel->rd_istemp = isTempOrToastNamespace(relnamespace);
+ rel->rd_islocaltemp = rel->rd_istemp;
/*
* create a new tuple descriptor from the one passed in. We do this
* as the logical ID (OID).
*/
rel->rd_rel->relisshared = shared_relation;
-
- /* it is temporary if and only if it is in my temp-table namespace */
- rel->rd_rel->relistemp = isTempOrToastNamespace(relnamespace);
+ rel->rd_rel->relistemp = rel->rd_istemp;
RelationGetRelid(rel) = relid;
BlockNumber rd_targblock; /* current insertion target block, or
* InvalidBlockNumber */
int rd_refcnt; /* reference count */
- bool rd_istemp; /* rel uses the local buffer mgr */
+ bool rd_istemp; /* rel is a temporary relation */
+ bool rd_islocaltemp; /* rel is a temp rel of this session */
bool rd_isnailed; /* rel is nailed in cache */
bool rd_isvalid; /* relcache entry is valid */
char rd_indexvalid; /* state of rd_indexlist: 0 = not valid, 1 =
* Beware of multiple eval of argument
*/
#define RELATION_IS_LOCAL(relation) \
- ((relation)->rd_istemp || \
+ ((relation)->rd_islocaltemp || \
(relation)->rd_createSubid != InvalidSubTransactionId)
+/*
+ * RELATION_IS_OTHER_TEMP
+ * Test for a temporary relation that belongs to some other session.
+ *
+ * Beware of multiple eval of argument
+ */
+#define RELATION_IS_OTHER_TEMP(relation) \
+ ((relation)->rd_istemp && !(relation)->rd_islocaltemp)
+
/* routines in utils/cache/relcache.c */
extern void RelationIncrementReferenceCount(Relation rel);
extern void RelationDecrementReferenceCount(Relation rel);