MarkBufferDirty(stack->buffer);
- if (!btree->index->rd_istemp)
+ if (RelationNeedsWAL(btree->index))
{
XLogRecPtr recptr;
MarkBufferDirty(lbuffer);
MarkBufferDirty(stack->buffer);
- if (!btree->index->rd_istemp)
+ if (RelationNeedsWAL(btree->index))
{
XLogRecPtr recptr;
MarkBufferDirty(rbuffer);
MarkBufferDirty(stack->buffer);
- if (!btree->index->rd_istemp)
+ if (RelationNeedsWAL(btree->index))
{
XLogRecPtr recptr;
MarkBufferDirty(buffer);
- if (!index->rd_istemp)
+ if (RelationNeedsWAL(index))
{
XLogRecData rdata[2];
ginxlogInsertListPage data;
*/
MarkBufferDirty(metabuffer);
- if (!index->rd_istemp)
+ if (RelationNeedsWAL(index))
{
XLogRecPtr recptr;
MarkBufferDirty(buffers[i]);
}
- if (!index->rd_istemp)
+ if (RelationNeedsWAL(index))
{
XLogRecPtr recptr;
MarkBufferDirty(buffer);
- if (!index->rd_istemp)
+ if (RelationNeedsWAL(index))
{
XLogRecPtr recptr;
XLogRecData rdata[2];
GinInitBuffer(RootBuffer, GIN_LEAF);
MarkBufferDirty(RootBuffer);
- if (!index->rd_istemp)
+ if (RelationNeedsWAL(index))
{
XLogRecPtr recptr;
XLogRecData rdata;
MarkBufferDirty(metabuffer);
- if (!index->rd_istemp)
+ if (RelationNeedsWAL(index))
{
XLogRecPtr recptr;
ginxlogUpdateMeta data;
Assert(GinPageIsLeaf(page));
- if (index->rd_istemp)
+ if (!RelationNeedsWAL(index))
return;
data.node = index->rd_node;
MarkBufferDirty(lBuffer);
MarkBufferDirty(dBuffer);
- if (!gvs->index->rd_istemp)
+ if (RelationNeedsWAL(gvs->index))
{
XLogRecPtr recptr;
XLogRecData rdata[4];
MarkBufferDirty(buffer);
- if (!index->rd_istemp)
+ if (RelationNeedsWAL(index))
{
XLogRecPtr recptr;
XLogRecData rdata;
dist->page = BufferGetPage(dist->buffer);
}
- if (!state->r->rd_istemp)
+ if (RelationNeedsWAL(state->r))
{
XLogRecPtr recptr;
XLogRecData *rdata;
MarkBufferDirty(state->stack->buffer);
- if (!state->r->rd_istemp)
+ if (RelationNeedsWAL(state->r))
{
OffsetNumber noffs = 0,
offs[1];
opaque = GistPageGetOpaque(state->stack->page);
state->stack->lsn = PageGetLSN(state->stack->page);
- Assert(state->r->rd_istemp || !XLogRecPtrIsInvalid(state->stack->lsn));
+ Assert(!RelationNeedsWAL(state->r) || !XLogRecPtrIsInvalid(state->stack->lsn));
if (state->stack->blkno != GIST_ROOT_BLKNO &&
XLByteLT(state->stack->parent->lsn, opaque->nsn))
}
/* say to xlog that insert is completed */
- if (state->needInsertComplete && !state->r->rd_istemp)
+ if (state->needInsertComplete && RelationNeedsWAL(state->r))
gistxlogInsertCompletion(state->r->rd_node, &(state->key), 1);
}
MarkBufferDirty(buffer);
- if (!r->rd_istemp)
+ if (RelationNeedsWAL(r))
{
XLogRecPtr recptr;
XLogRecData *rdata;
PageIndexTupleDelete(page, todelete[i]);
GistMarkTuplesDeleted(page);
- if (!rel->rd_istemp)
+ if (RelationNeedsWAL(rel))
{
XLogRecData *rdata;
XLogRecPtr recptr;
*
* During a rescan, don't make a new strategy object if we don't have to.
*/
- if (!scan->rs_rd->rd_istemp &&
+ if (!RelationUsesLocalBuffers(scan->rs_rd) &&
scan->rs_nblocks > NBuffers / 4)
{
allow_strat = scan->rs_allow_strat;
elog(ERROR, "could not open relation with OID %u", relationId);
/* Make note that we've accessed a temporary relation */
- if (r->rd_istemp)
+ if (RelationUsesLocalBuffers(r))
MyXactAccessedTempRel = true;
pgstat_initstats(r);
elog(ERROR, "could not open relation with OID %u", relationId);
/* Make note that we've accessed a temporary relation */
- if (r->rd_istemp)
+ if (RelationUsesLocalBuffers(r))
MyXactAccessedTempRel = true;
pgstat_initstats(r);
MarkBufferDirty(buffer);
/* XLOG stuff */
- if (!(options & HEAP_INSERT_SKIP_WAL) && !relation->rd_istemp)
+ if (!(options & HEAP_INSERT_SKIP_WAL) && RelationNeedsWAL(relation))
{
xl_heap_insert xlrec;
xl_heap_header xlhdr;
MarkBufferDirty(buffer);
/* XLOG stuff */
- if (!relation->rd_istemp)
+ if (RelationNeedsWAL(relation))
{
xl_heap_delete xlrec;
XLogRecPtr recptr;
MarkBufferDirty(buffer);
/* XLOG stuff */
- if (!relation->rd_istemp)
+ if (RelationNeedsWAL(relation))
{
XLogRecPtr recptr = log_heap_update(relation, buffer, oldtup.t_self,
newbuf, heaptup,
* (Also, in a PITR log-shipping or 2PC environment, we have to have XLOG
* entries for everything anyway.)
*/
- if (!relation->rd_istemp)
+ if (RelationNeedsWAL(relation))
{
xl_heap_lock xlrec;
XLogRecPtr recptr;
MarkBufferDirty(buffer);
/* XLOG stuff */
- if (!relation->rd_istemp)
+ if (RelationNeedsWAL(relation))
{
xl_heap_inplace xlrec;
XLogRecPtr recptr;
XLogRecPtr recptr;
XLogRecData rdata[4];
- /* Caller should not call me on a temp relation */
- Assert(!reln->rd_istemp);
+ /* Caller should not call me on a non-WAL-logged relation */
+ Assert(RelationNeedsWAL(reln));
xlrec.node = reln->rd_node;
xlrec.block = BufferGetBlockNumber(buffer);
XLogRecPtr recptr;
XLogRecData rdata[2];
- /* Caller should not call me on a temp relation */
- Assert(!reln->rd_istemp);
+ /* Caller should not call me on a non-WAL-logged relation */
+ Assert(RelationNeedsWAL(reln));
/* nor when there are no tuples to freeze */
Assert(offcnt > 0);
XLogRecData rdata[4];
Page page = BufferGetPage(newbuf);
- /* Caller should not call me on a temp relation */
- Assert(!reln->rd_istemp);
+ /* Caller should not call me on a non-WAL-logged relation */
+ Assert(RelationNeedsWAL(reln));
if (HeapTupleIsHeapOnly(newtup))
info = XLOG_HEAP_HOT_UPDATE;
* heap_sync - sync a heap, for use when no WAL has been written
*
* This forces the heap contents (including TOAST heap if any) down to disk.
- * If we skipped using WAL, and it's not a temp relation, we must force the
+ * If we skipped using WAL, and WAL is otherwise needed, we must force the
* relation down to disk before it's safe to commit the transaction. This
* requires writing out any dirty buffers and then doing a forced fsync.
*
void
heap_sync(Relation rel)
{
- /* temp tables never need fsync */
- if (rel->rd_istemp)
+ /* non-WAL-logged tables never need fsync */
+ if (!RelationNeedsWAL(rel))
return;
/* main heap */
/*
* Emit a WAL HEAP_CLEAN record showing what we did
*/
- if (!relation->rd_istemp)
+ if (RelationNeedsWAL(relation))
{
XLogRecPtr recptr;
}
/*
- * If the rel isn't temp, must fsync before commit. We use heap_sync to
- * ensure that the toast table gets fsync'd too.
+ * If the rel is WAL-logged, must fsync before commit. We use heap_sync
+ * to ensure that the toast table gets fsync'd too.
*
* It's obvious that we must do this when not WAL-logging. It's less
* obvious that we have to do it even if we did WAL-log the pages. The
* occurring during the rewriteheap operation won't have fsync'd data we
* wrote before the checkpoint.
*/
- if (!state->rs_new_rel->rd_istemp)
+ if (RelationNeedsWAL(state->rs_new_rel))
heap_sync(state->rs_new_rel);
/* Deleting the context frees everything */
}
/* XLOG stuff */
- if (!rel->rd_istemp)
+ if (RelationNeedsWAL(rel))
{
xl_btree_insert xlrec;
BlockNumber xldownlink;
}
/* XLOG stuff */
- if (!rel->rd_istemp)
+ if (RelationNeedsWAL(rel))
{
xl_btree_split xlrec;
uint8 xlinfo;
MarkBufferDirty(metabuf);
/* XLOG stuff */
- if (!rel->rd_istemp)
+ if (RelationNeedsWAL(rel))
{
xl_btree_newroot xlrec;
XLogRecPtr recptr;
MarkBufferDirty(metabuf);
/* XLOG stuff */
- if (!rel->rd_istemp)
+ if (RelationNeedsWAL(rel))
{
xl_btree_newroot xlrec;
XLogRecPtr recptr;
static void
_bt_log_reuse_page(Relation rel, BlockNumber blkno, TransactionId latestRemovedXid)
{
- if (rel->rd_istemp)
+ if (!RelationNeedsWAL(rel))
return;
/* No ereport(ERROR) until changes are logged */
MarkBufferDirty(buf);
/* XLOG stuff */
- if (!rel->rd_istemp)
+ if (RelationNeedsWAL(rel))
{
XLogRecPtr recptr;
XLogRecData rdata[2];
MarkBufferDirty(buf);
/* XLOG stuff */
- if (!rel->rd_istemp)
+ if (RelationNeedsWAL(rel))
{
XLogRecPtr recptr;
XLogRecData rdata[3];
MarkBufferDirty(lbuf);
/* XLOG stuff */
- if (!rel->rd_istemp)
+ if (RelationNeedsWAL(rel))
{
xl_btree_delete_page xlrec;
xl_btree_metadata xlmeta;
/*
* We need to log index creation in WAL iff WAL archiving/streaming is
- * enabled AND it's not a temp index.
+ * enabled UNLESS the index isn't WAL-logged anyway.
*/
- wstate.btws_use_wal = XLogIsNeeded() && !wstate.index->rd_istemp;
+ wstate.btws_use_wal = XLogIsNeeded() && RelationNeedsWAL(wstate.index);
/* reserve the metapage */
wstate.btws_pages_alloced = BTREE_METAPAGE + 1;
_bt_uppershutdown(wstate, state);
/*
- * If the index isn't temp, we must fsync it down to disk before it's safe
- * to commit the transaction. (For a temp index we don't care since the
- * index will be uninteresting after a crash anyway.)
+ * If the index is WAL-logged, we must fsync it down to disk before it's
+ * safe to commit the transaction. (For a non-WAL-logged index we don't
+ * care since the index will be uninteresting after a crash anyway.)
*
* It's obvious that we must do this when not WAL-logging the build. It's
* less obvious that we have to do it even if we did WAL-log the index
* fsync those pages here, they might still not be on disk when the crash
* occurs.
*/
- if (!wstate->index->rd_istemp)
+ if (RelationNeedsWAL(wstate->index))
{
RelationOpenSmgr(wstate->index);
smgrimmedsync(wstate->index->rd_smgr, MAIN_FORKNUM);
$3,
tupdesc,
RELKIND_RELATION,
+ RELPERSISTENCE_PERMANENT,
shared_relation,
mapped_relation,
true);
tupdesc,
NIL,
RELKIND_RELATION,
+ RELPERSISTENCE_PERMANENT,
shared_relation,
mapped_relation,
true,
* created by bootstrap have preassigned OIDs, so there's no need.
*/
Oid
-GetNewRelFileNode(Oid reltablespace, Relation pg_class, BackendId backend)
+GetNewRelFileNode(Oid reltablespace, Relation pg_class, char relpersistence)
{
RelFileNodeBackend rnode;
char *rpath;
int fd;
bool collides;
+ BackendId backend;
+
+ switch (relpersistence)
+ {
+ case RELPERSISTENCE_TEMP:
+ backend = MyBackendId;
+ break;
+ case RELPERSISTENCE_PERMANENT:
+ backend = InvalidBackendId;
+ break;
+ default:
+ elog(ERROR, "invalid relpersistence: %c", relpersistence);
+ return InvalidOid; /* placate compiler */
+ }
/* This logic should match RelationInitPhysicalAddr */
rnode.node.spcNode = reltablespace ? reltablespace : MyDatabaseTableSpace;
Oid relid,
TupleDesc tupDesc,
char relkind,
+ char relpersistence,
bool shared_relation,
bool mapped_relation,
bool allow_system_table_mods)
relid,
reltablespace,
shared_relation,
- mapped_relation);
+ mapped_relation,
+ relpersistence);
/*
* Have the storage manager create the relation's disk file, if needed.
if (create_storage)
{
RelationOpenSmgr(rel);
- RelationCreateStorage(rel->rd_node, rel->rd_istemp);
+ RelationCreateStorage(rel->rd_node, relpersistence);
}
return rel;
values[Anum_pg_class_reltoastidxid - 1] = ObjectIdGetDatum(rd_rel->reltoastidxid);
values[Anum_pg_class_relhasindex - 1] = BoolGetDatum(rd_rel->relhasindex);
values[Anum_pg_class_relisshared - 1] = BoolGetDatum(rd_rel->relisshared);
- values[Anum_pg_class_relistemp - 1] = BoolGetDatum(rd_rel->relistemp);
+ values[Anum_pg_class_relpersistence - 1] = CharGetDatum(rd_rel->relpersistence);
values[Anum_pg_class_relkind - 1] = CharGetDatum(rd_rel->relkind);
values[Anum_pg_class_relnatts - 1] = Int16GetDatum(rd_rel->relnatts);
values[Anum_pg_class_relchecks - 1] = Int16GetDatum(rd_rel->relchecks);
TupleDesc tupdesc,
List *cooked_constraints,
char relkind,
+ char relpersistence,
bool shared_relation,
bool mapped_relation,
bool oidislocal,
}
else
relid = GetNewRelFileNode(reltablespace, pg_class_desc,
- isTempOrToastNamespace(relnamespace) ?
- MyBackendId : InvalidBackendId);
+ relpersistence);
}
/*
relid,
tupdesc,
relkind,
+ relpersistence,
shared_relation,
mapped_relation,
allow_system_table_mods);
bool is_exclusion;
Oid namespaceId;
int i;
+ char relpersistence;
is_exclusion = (indexInfo->ii_ExclusionOps != NULL);
/*
* The index will be in the same namespace as its parent table, and is
* shared across databases if and only if the parent is. Likewise, it
- * will use the relfilenode map if and only if the parent does.
+ * will use the relfilenode map if and only if the parent does; and it
+ * inherits the parent's relpersistence.
*/
namespaceId = RelationGetNamespace(heapRelation);
shared_relation = heapRelation->rd_rel->relisshared;
mapped_relation = RelationIsMapped(heapRelation);
+ relpersistence = heapRelation->rd_rel->relpersistence;
/*
* check parameters
else
{
indexRelationId =
- GetNewRelFileNode(tableSpaceId, pg_class,
- heapRelation->rd_istemp ?
- MyBackendId : InvalidBackendId);
+ GetNewRelFileNode(tableSpaceId, pg_class, relpersistence);
}
}
indexRelationId,
indexTupDesc,
RELKIND_INDEX,
+ relpersistence,
shared_relation,
mapped_relation,
allow_system_table_mods);
}
/*
- * If istemp is set, this is a reference to a temp relation. The parser
- * never generates such a RangeVar in simple DML, but it can happen in
- * contexts such as "CREATE TEMP TABLE foo (f1 int PRIMARY KEY)". Such a
- * command will generate an added CREATE INDEX operation, which must be
+ * Some non-default relpersistence value may have been specified. The
+ * parser never generates such a RangeVar in simple DML, but it can happen
+ * in contexts such as "CREATE TEMP TABLE foo (f1 int PRIMARY KEY)". Such
+ * a command will generate an added CREATE INDEX operation, which must be
* careful to find the temp table, even when pg_temp is not first in the
* search path.
*/
- if (relation->istemp)
+ if (relation->relpersistence == RELPERSISTENCE_TEMP)
{
if (relation->schemaname)
ereport(ERROR,
newRelation->relname)));
}
- if (newRelation->istemp)
+ if (newRelation->relpersistence == RELPERSISTENCE_TEMP)
{
/* TEMP tables are created in our backend-local temp namespace */
if (newRelation->schemaname)
* transaction aborts later on, the storage will be destroyed.
*/
void
-RelationCreateStorage(RelFileNode rnode, bool istemp)
+RelationCreateStorage(RelFileNode rnode, char relpersistence)
{
PendingRelDelete *pending;
XLogRecPtr lsn;
XLogRecData rdata;
xl_smgr_create xlrec;
SMgrRelation srel;
- BackendId backend = istemp ? MyBackendId : InvalidBackendId;
+ BackendId backend;
+ bool needs_wal;
+
+ switch (relpersistence)
+ {
+ case RELPERSISTENCE_TEMP:
+ backend = MyBackendId;
+ needs_wal = false;
+ break;
+ case RELPERSISTENCE_PERMANENT:
+ backend = InvalidBackendId;
+ needs_wal = true;
+ break;
+ default:
+ elog(ERROR, "invalid relpersistence: %c", relpersistence);
+ return; /* placate compiler */
+ }
srel = smgropen(rnode, backend);
smgrcreate(srel, MAIN_FORKNUM, false);
- if (!istemp)
+ if (needs_wal)
{
/*
* Make an XLOG entry reporting the file creation.
* failure to truncate, that might spell trouble at WAL replay, into a
* certain PANIC.
*/
- if (!rel->rd_istemp)
+ if (RelationNeedsWAL(rel))
{
/*
* Make an XLOG entry reporting the file truncation.
* 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_backend == MyBackendId)
+ if (RelationUsesTempNamespace(rel))
namespaceid = GetTempToastNamespace();
else
namespaceid = PG_TOAST_NAMESPACE;
tupdesc,
NIL,
RELKIND_TOASTVALUE,
+ rel->rd_rel->relpersistence,
shared_relation,
mapped_relation,
true,
tupdesc,
NIL,
OldHeap->rd_rel->relkind,
+ OldHeap->rd_rel->relpersistence,
false,
RelationIsMapped(OldHeap),
true,
/*
* We need to log the copied data in WAL iff WAL archiving/streaming is
- * enabled AND it's not a temp rel.
+ * enabled AND it's not a WAL-logged rel.
*/
- use_wal = XLogIsNeeded() && !NewHeap->rd_istemp;
+ use_wal = XLogIsNeeded() && RelationNeedsWAL(NewHeap);
/* use_wal off requires smgr_targblock be initially invalid */
Assert(RelationGetTargetBlock(NewHeap) == InvalidBlockNumber);
}
else
{
- tablespaceId = GetDefaultTablespace(rel->rd_istemp);
+ tablespaceId = GetDefaultTablespace(rel->rd_rel->relpersistence);
/* note InvalidOid is OK in this case */
}
continue;
/* Skip temp tables of other backends; we can't reindex them at all */
- if (classtuple->relistemp &&
+ if (classtuple->relpersistence == RELPERSISTENCE_TEMP &&
!isTempNamespace(classtuple->relnamespace))
continue;
MarkBufferDirty(buf);
/* XLOG stuff */
- if (!rel->rd_istemp)
+ if (RelationNeedsWAL(rel))
{
xl_seq_rec xlrec;
XLogRecPtr recptr;
MarkBufferDirty(buf);
/* XLOG stuff */
- if (!seqrel->rd_istemp)
+ if (RelationNeedsWAL(seqrel))
{
xl_seq_rec xlrec;
XLogRecPtr recptr;
MarkBufferDirty(buf);
/* XLOG stuff */
- if (logit && !seqrel->rd_istemp)
+ if (logit && RelationNeedsWAL(seqrel))
{
xl_seq_rec xlrec;
XLogRecPtr recptr;
MarkBufferDirty(buf);
/* XLOG stuff */
- if (!seqrel->rd_istemp)
+ if (RelationNeedsWAL(seqrel))
{
xl_seq_rec xlrec;
XLogRecPtr recptr;
static void truncate_check_rel(Relation rel);
-static List *MergeAttributes(List *schema, List *supers, bool istemp,
+static List *MergeAttributes(List *schema, List *supers, char relpersistence,
List **supOids, List **supconstr, int *supOidCount);
static bool MergeCheckConstraint(List *constraints, char *name, Node *expr);
static bool change_varattnos_walker(Node *node, const AttrNumber *newattno);
static void ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode);
static void ATExecDropInherit(Relation rel, RangeVar *parent, LOCKMODE lockmode);
static void copy_relation_data(SMgrRelation rel, SMgrRelation dst,
- ForkNumber forkNum, bool istemp);
+ ForkNumber forkNum, char relpersistence);
static const char *storage_name(char c);
/*
* Check consistency of arguments
*/
- if (stmt->oncommit != ONCOMMIT_NOOP && !stmt->relation->istemp)
+ if (stmt->oncommit != ONCOMMIT_NOOP
+ && stmt->relation->relpersistence != RELPERSISTENCE_TEMP)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
errmsg("ON COMMIT can only be used on temporary tables")));
* code. This is needed because calling code might not expect untrusted
* tables to appear in pg_temp at the front of its search path.
*/
- if (stmt->relation->istemp && InSecurityRestrictedOperation())
+ if (stmt->relation->relpersistence == RELPERSISTENCE_TEMP
+ && InSecurityRestrictedOperation())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("cannot create temporary table within security-restricted operation")));
}
else
{
- tablespaceId = GetDefaultTablespace(stmt->relation->istemp);
+ tablespaceId = GetDefaultTablespace(stmt->relation->relpersistence);
/* note InvalidOid is OK in this case */
}
* inherited attributes.
*/
schema = MergeAttributes(schema, stmt->inhRelations,
- stmt->relation->istemp,
+ stmt->relation->relpersistence,
&inheritOids, &old_constraints, &parentOidCount);
/*
list_concat(cookedDefaults,
old_constraints),
relkind,
+ stmt->relation->relpersistence,
false,
false,
localHasOids,
*----------
*/
static List *
-MergeAttributes(List *schema, List *supers, bool istemp,
+MergeAttributes(List *schema, List *supers, char relpersistence,
List **supOids, List **supconstr, int *supOidCount)
{
ListCell *entry;
errmsg("inherited relation \"%s\" is not a table",
parent->relname)));
/* Permanent rels cannot inherit from temporary ones */
- if (!istemp && relation->rd_istemp)
+ if (relpersistence != RELPERSISTENCE_TEMP
+ && RelationUsesTempNamespace(relation))
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("cannot inherit from temporary relation \"%s\"",
RelationGetRelationName(pkrel))));
/*
- * Disallow reference from permanent table to temp table or vice versa.
- * (The ban on perm->temp is for fairly obvious reasons. The ban on
- * temp->perm is because other backends might need to run the RI triggers
- * on the perm table, but they can't reliably see tuples the owning
- * backend has created in the temp table, because non-shared buffers are
- * used for temp tables.)
+ * References from permanent tables to temp tables are disallowed because
+ * the contents of the temp table disappear at the end of each session.
+ * References from temp tables to permanent tables are also disallowed,
+ * because other backends might need to run the RI triggers on the perm
+ * table, but they can't reliably see tuples in the local buffers of other
+ * backends.
*/
- if (pkrel->rd_istemp)
+ switch (rel->rd_rel->relpersistence)
{
- if (!rel->rd_istemp)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
- errmsg("cannot reference temporary table from permanent table constraint")));
- }
- else
- {
- if (rel->rd_istemp)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
- errmsg("cannot reference permanent table from temporary table constraint")));
+ case RELPERSISTENCE_PERMANENT:
+ if (pkrel->rd_rel->relpersistence != RELPERSISTENCE_PERMANENT)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
+ errmsg("constraints on permanent tables may reference only permanent tables")));
+ break;
+ case RELPERSISTENCE_TEMP:
+ if (pkrel->rd_rel->relpersistence != RELPERSISTENCE_TEMP)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
+ errmsg("constraints on temporary tables may reference only temporary tables")));
+ break;
}
/*
* Relfilenodes are not unique across tablespaces, so we need to allocate
* a new one in the new tablespace.
*/
- newrelfilenode = GetNewRelFileNode(newTableSpace, NULL, rel->rd_backend);
+ newrelfilenode = GetNewRelFileNode(newTableSpace, NULL,
+ rel->rd_rel->relpersistence);
/* Open old and new relation */
newrnode = rel->rd_node;
* NOTE: any conflict in relfilenode value will be caught in
* RelationCreateStorage().
*/
- RelationCreateStorage(newrnode, rel->rd_istemp);
+ RelationCreateStorage(newrnode, rel->rd_rel->relpersistence);
/* copy main fork */
- copy_relation_data(rel->rd_smgr, dstrel, MAIN_FORKNUM, rel->rd_istemp);
+ copy_relation_data(rel->rd_smgr, dstrel, MAIN_FORKNUM,
+ rel->rd_rel->relpersistence);
/* copy those extra forks that exist */
for (forkNum = MAIN_FORKNUM + 1; forkNum <= MAX_FORKNUM; forkNum++)
if (smgrexists(rel->rd_smgr, forkNum))
{
smgrcreate(dstrel, forkNum, false);
- copy_relation_data(rel->rd_smgr, dstrel, forkNum, rel->rd_istemp);
+ copy_relation_data(rel->rd_smgr, dstrel, forkNum,
+ rel->rd_rel->relpersistence);
}
}
*/
static void
copy_relation_data(SMgrRelation src, SMgrRelation dst,
- ForkNumber forkNum, bool istemp)
+ ForkNumber forkNum, char relpersistence)
{
char *buf;
Page page;
/*
* We need to log the copied data in WAL iff WAL archiving/streaming is
- * enabled AND it's not a temp rel.
+ * enabled AND it's a permanent relation.
*/
- use_wal = XLogIsNeeded() && !istemp;
+ use_wal = XLogIsNeeded() && relpersistence == RELPERSISTENCE_PERMANENT;
nblocks = smgrnblocks(src, forkNum);
* wouldn't replay our earlier WAL entries. If we do not fsync those pages
* here, they might still not be on disk when the crash occurs.
*/
- if (!istemp)
+ if (relpersistence == RELPERSISTENCE_PERMANENT)
smgrimmedsync(dst, forkNum);
}
ATSimplePermissions(parent_rel, false, false);
/* Permanent rels cannot inherit from temporary ones */
- if (parent_rel->rd_istemp && !child_rel->rd_istemp)
+ if (RelationUsesTempNamespace(parent_rel)
+ && !RelationUsesTempNamespace(child_rel))
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("cannot inherit from temporary relation \"%s\"",
/*
* GetDefaultTablespace -- get the OID of the current default tablespace
*
- * Regular objects and temporary objects have different default tablespaces,
- * hence the forTemp parameter must be specified.
+ * Temporary objects have different default tablespaces, hence the
+ * relpersistence parameter must be specified.
*
* May return InvalidOid to indicate "use the database's default tablespace".
*
* default_tablespace GUC variable.
*/
Oid
-GetDefaultTablespace(bool forTemp)
+GetDefaultTablespace(char relpersistence)
{
Oid result;
/* The temp-table case is handled elsewhere */
- if (forTemp)
+ if (relpersistence == RELPERSISTENCE_TEMP)
{
PrepareTempTablespaces();
return GetNextTempTableSpace();
vacuum_log_cleanup_info(Relation rel, LVRelStats *vacrelstats)
{
/*
- * No need to log changes for temp tables, they do not contain data
- * visible on the standby server.
+ * Skip this for relations for which no WAL is to be written, or if we're
+ * not trying to support archive recovery.
*/
- if (rel->rd_istemp || !XLogIsNeeded())
+ if (!RelationNeedsWAL(rel) || !XLogIsNeeded())
return;
/*
if (nfrozen > 0)
{
MarkBufferDirty(buf);
- /* no XLOG for temp tables, though */
- if (!onerel->rd_istemp)
+ if (RelationNeedsWAL(onerel))
{
XLogRecPtr recptr;
MarkBufferDirty(buffer);
/* XLOG stuff */
- if (!onerel->rd_istemp)
+ if (RelationNeedsWAL(onerel))
{
XLogRecPtr recptr;
if (rte->rtekind == RTE_RELATION)
{
Relation rel = heap_open(rte->relid, AccessShareLock);
- bool istemp = rel->rd_istemp;
+ char relpersistence = rel->rd_rel->relpersistence;
heap_close(rel, AccessShareLock);
- if (istemp)
+ if (relpersistence == RELPERSISTENCE_TEMP)
return true;
}
}
/*
* Due to the namespace visibility rules for temporary objects, we
* should only end up replacing a temporary view with another
- * temporary view, and vice versa.
+ * temporary view, and similarly for permanent views.
*/
- Assert(relation->istemp == rel->rd_istemp);
+ Assert(relation->relpersistence == rel->rd_rel->relpersistence);
/*
* Create a tuple descriptor to compare against the existing view, and
* schema name.
*/
view = stmt->view;
- if (!view->istemp && isViewOnTempTable(viewParse))
+ if (view->relpersistence == RELPERSISTENCE_PERMANENT
+ && isViewOnTempTable(viewParse))
{
view = copyObject(view); /* don't corrupt original command */
- view->istemp = true;
+ view->relpersistence = RELPERSISTENCE_TEMP;
ereport(NOTICE,
(errmsg("view \"%s\" will be a temporary view",
view->relname)));
/*
* Check consistency of arguments
*/
- if (into->onCommit != ONCOMMIT_NOOP && !into->rel->istemp)
+ if (into->onCommit != ONCOMMIT_NOOP
+ && into->rel->relpersistence != RELPERSISTENCE_TEMP)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
errmsg("ON COMMIT can only be used on temporary tables")));
* code. This is needed because calling code might not expect untrusted
* tables to appear in pg_temp at the front of its search path.
*/
- if (into->rel->istemp && InSecurityRestrictedOperation())
+ if (into->rel->relpersistence == RELPERSISTENCE_TEMP
+ && InSecurityRestrictedOperation())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("cannot create temporary table within security-restricted operation")));
}
else
{
- tablespaceId = GetDefaultTablespace(into->rel->istemp);
+ tablespaceId = GetDefaultTablespace(into->rel->relpersistence);
/* note InvalidOid is OK in this case */
}
tupdesc,
NIL,
RELKIND_RELATION,
+ into->rel->relpersistence,
false,
false,
true,
COPY_STRING_FIELD(schemaname);
COPY_STRING_FIELD(relname);
COPY_SCALAR_FIELD(inhOpt);
- COPY_SCALAR_FIELD(istemp);
+ COPY_SCALAR_FIELD(relpersistence);
COPY_NODE_FIELD(alias);
COPY_LOCATION_FIELD(location);
COMPARE_STRING_FIELD(schemaname);
COMPARE_STRING_FIELD(relname);
COMPARE_SCALAR_FIELD(inhOpt);
- COMPARE_SCALAR_FIELD(istemp);
+ COMPARE_SCALAR_FIELD(relpersistence);
COMPARE_NODE_FIELD(alias);
COMPARE_LOCATION_FIELD(location);
*/
#include "postgres.h"
+#include "catalog/pg_class.h"
#include "catalog/pg_type.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
r->schemaname = schemaname;
r->relname = relname;
r->inhOpt = INH_DEFAULT;
- r->istemp = false;
+ r->relpersistence = RELPERSISTENCE_PERMANENT;
r->alias = NULL;
r->location = location;
WRITE_STRING_FIELD(schemaname);
WRITE_STRING_FIELD(relname);
WRITE_ENUM_FIELD(inhOpt, InhOption);
- WRITE_BOOL_FIELD(istemp);
+ WRITE_CHAR_FIELD(relpersistence);
WRITE_NODE_FIELD(alias);
WRITE_LOCATION_FIELD(location);
}
READ_STRING_FIELD(schemaname);
READ_STRING_FIELD(relname);
READ_ENUM_FIELD(inhOpt, InhOption);
- READ_BOOL_FIELD(istemp);
+ READ_CHAR_FIELD(relpersistence);
READ_NODE_FIELD(alias);
READ_LOCATION_FIELD(location);
%type <fun_param_mode> arg_class
%type <typnam> func_return func_type
-%type <boolean> OptTemp opt_trusted opt_restart_seqs
+%type <boolean> opt_trusted opt_restart_seqs
+%type <ival> OptTemp
%type <oncommit> OnCommitOption
%type <node> for_locking_item
OptInherit OptWith OnCommitOption OptTableSpace
{
CreateStmt *n = makeNode(CreateStmt);
- $4->istemp = $2;
+ $4->relpersistence = $2;
n->relation = $4;
n->tableElts = $6;
n->inhRelations = $8;
OptTableSpace
{
CreateStmt *n = makeNode(CreateStmt);
- $7->istemp = $2;
+ $7->relpersistence = $2;
n->relation = $7;
n->tableElts = $9;
n->inhRelations = $11;
OptTypedTableElementList OptWith OnCommitOption OptTableSpace
{
CreateStmt *n = makeNode(CreateStmt);
- $4->istemp = $2;
+ $4->relpersistence = $2;
n->relation = $4;
n->tableElts = $7;
n->ofTypename = makeTypeNameFromNameList($6);
OptTypedTableElementList OptWith OnCommitOption OptTableSpace
{
CreateStmt *n = makeNode(CreateStmt);
- $7->istemp = $2;
+ $7->relpersistence = $2;
n->relation = $7;
n->tableElts = $10;
n->ofTypename = makeTypeNameFromNameList($9);
* NOTE: we accept both GLOBAL and LOCAL options; since we have no modules
* the LOCAL keyword is really meaningless.
*/
-OptTemp: TEMPORARY { $$ = TRUE; }
- | TEMP { $$ = TRUE; }
- | LOCAL TEMPORARY { $$ = TRUE; }
- | LOCAL TEMP { $$ = TRUE; }
- | GLOBAL TEMPORARY { $$ = TRUE; }
- | GLOBAL TEMP { $$ = TRUE; }
- | /*EMPTY*/ { $$ = FALSE; }
+OptTemp: TEMPORARY { $$ = RELPERSISTENCE_TEMP; }
+ | TEMP { $$ = RELPERSISTENCE_TEMP; }
+ | LOCAL TEMPORARY { $$ = RELPERSISTENCE_TEMP; }
+ | LOCAL TEMP { $$ = RELPERSISTENCE_TEMP; }
+ | GLOBAL TEMPORARY { $$ = RELPERSISTENCE_TEMP; }
+ | GLOBAL TEMP { $$ = RELPERSISTENCE_TEMP; }
+ | /*EMPTY*/ { $$ = RELPERSISTENCE_PERMANENT; }
;
OptTableElementList:
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("CREATE TABLE AS cannot specify INTO"),
parser_errposition(exprLocation((Node *) n->intoClause))));
- $4->rel->istemp = $2;
+ $4->rel->relpersistence = $2;
n->intoClause = $4;
/* Implement WITH NO DATA by forcing top-level LIMIT 0 */
if (!$7)
CREATE OptTemp SEQUENCE qualified_name OptSeqOptList
{
CreateSeqStmt *n = makeNode(CreateSeqStmt);
- $4->istemp = $2;
+ $4->relpersistence = $2;
n->sequence = $4;
n->options = $5;
n->ownerId = InvalidOid;
{
ViewStmt *n = makeNode(ViewStmt);
n->view = $4;
- n->view->istemp = $2;
+ n->view->relpersistence = $2;
n->aliases = $5;
n->query = $7;
n->replace = false;
{
ViewStmt *n = makeNode(ViewStmt);
n->view = $6;
- n->view->istemp = $4;
+ n->view->relpersistence = $4;
n->aliases = $7;
n->query = $9;
n->replace = true;
ExecuteStmt *n = makeNode(ExecuteStmt);
n->name = $7;
n->params = $8;
- $4->rel->istemp = $2;
+ $4->rel->relpersistence = $2;
n->into = $4;
if ($4->colNames)
ereport(ERROR,
TEMPORARY opt_table qualified_name
{
$$ = $3;
- $$->istemp = true;
+ $$->relpersistence = RELPERSISTENCE_TEMP;
}
| TEMP opt_table qualified_name
{
$$ = $3;
- $$->istemp = true;
+ $$->relpersistence = RELPERSISTENCE_TEMP;
}
| LOCAL TEMPORARY opt_table qualified_name
{
$$ = $4;
- $$->istemp = true;
+ $$->relpersistence = RELPERSISTENCE_TEMP;
}
| LOCAL TEMP opt_table qualified_name
{
$$ = $4;
- $$->istemp = true;
+ $$->relpersistence = RELPERSISTENCE_TEMP;
}
| GLOBAL TEMPORARY opt_table qualified_name
{
$$ = $4;
- $$->istemp = true;
+ $$->relpersistence = RELPERSISTENCE_TEMP;
}
| GLOBAL TEMP opt_table qualified_name
{
$$ = $4;
- $$->istemp = true;
+ $$->relpersistence = RELPERSISTENCE_TEMP;
}
| TABLE qualified_name
{
$$ = $2;
- $$->istemp = false;
+ $$->relpersistence = RELPERSISTENCE_PERMANENT;
}
| qualified_name
{
$$ = $1;
- $$->istemp = false;
+ $$->relpersistence = RELPERSISTENCE_PERMANENT;
}
;
qualified_name:
ColId
{
- $$ = makeNode(RangeVar);
- $$->catalogname = NULL;
- $$->schemaname = NULL;
- $$->relname = $1;
- $$->location = @1;
+ $$ = makeRangeVar(NULL, $1, @1);
}
| ColId indirection
{
check_qualified_name($2, yyscanner);
- $$ = makeNode(RangeVar);
+ $$ = makeRangeVar(NULL, NULL, @1);
switch (list_length($2))
{
case 1:
parser_errposition(@1)));
break;
}
- $$->location = @1;
}
;
break;
}
+ r->relpersistence = RELPERSISTENCE_PERMANENT;
r->location = position;
return r;
* If the target relation name isn't schema-qualified, make it so. This
* prevents some corner cases in which added-on rewritten commands might
* think they should apply to other relations that have the same name and
- * are earlier in the search path. "istemp" is equivalent to a
- * specification of pg_temp, so no need for anything extra in that case.
+ * are earlier in the search path. But a local temp table is effectively
+ * specified to be in pg_temp, so no need for anything extra in that case.
*/
- if (stmt->relation->schemaname == NULL && !stmt->relation->istemp)
+ if (stmt->relation->schemaname == NULL
+ && stmt->relation->relpersistence != RELPERSISTENCE_TEMP)
{
Oid namespaceid = RangeVarGetCreationNamespace(stmt->relation);
* Check if it is a temp table (presumably, of some other backend's).
* We cannot safely process other backends' temp tables.
*/
- if (classForm->relistemp)
+ if (classForm->relpersistence == RELPERSISTENCE_TEMP)
{
int backendID;
/*
* We cannot safely process other backends' temp tables, so skip 'em.
*/
- if (classForm->relistemp)
+ if (classForm->relpersistence == RELPERSISTENCE_TEMP)
continue;
relid = HeapTupleGetOid(tuple);
/* Open it at the smgr level if not already done */
RelationOpenSmgr(reln);
- if (reln->rd_istemp)
+ if (RelationUsesLocalBuffers(reln))
{
/* see comments in ReadBufferExtended */
if (RELATION_IS_OTHER_TEMP(reln))
/* Open rel at the smgr level if not already done */
RelationOpenSmgr(rel);
- if (rel->rd_istemp)
+ if (RelationUsesLocalBuffers(rel))
{
for (i = 0; i < NLocBuffer; i++)
{
PG_RETURN_NULL();
}
- /* If temporary, determine owning backend. */
- if (!relform->relistemp)
- backend = InvalidBackendId;
- else if (isTempOrToastNamespace(relform->relnamespace))
- backend = MyBackendId;
- else
+ /* Determine owning backend. */
+ switch (relform->relpersistence)
{
- /* Do it the hard way. */
- backend = GetTempNamespaceBackendId(relform->relnamespace);
- Assert(backend != InvalidBackendId);
+ case RELPERSISTENCE_PERMANENT:
+ backend = InvalidBackendId;
+ break;
+ case RELPERSISTENCE_TEMP:
+ if (isTempOrToastNamespace(relform->relnamespace))
+ backend = MyBackendId;
+ else
+ {
+ /* Do it the hard way. */
+ backend = GetTempNamespaceBackendId(relform->relnamespace);
+ Assert(backend != InvalidBackendId);
+ }
+ break;
+ default:
+ elog(ERROR, "invalid relpersistence: %c", relform->relpersistence);
+ backend = InvalidBackendId; /* placate compiler */
+ break;
}
ReleaseSysCache(tuple);
relation->rd_isnailed = false;
relation->rd_createSubid = InvalidSubTransactionId;
relation->rd_newRelfilenodeSubid = InvalidSubTransactionId;
- relation->rd_istemp = relation->rd_rel->relistemp;
- if (!relation->rd_istemp)
- relation->rd_backend = InvalidBackendId;
- else if (isTempOrToastNamespace(relation->rd_rel->relnamespace))
- relation->rd_backend = MyBackendId;
- else
+ switch (relation->rd_rel->relpersistence)
{
- /*
- * If it's a temporary table, but not one of ours, we have to use
- * the slow, grotty method to figure out the owning backend.
- */
- relation->rd_backend =
- GetTempNamespaceBackendId(relation->rd_rel->relnamespace);
- Assert(relation->rd_backend != InvalidBackendId);
+ case RELPERSISTENCE_PERMANENT:
+ relation->rd_backend = InvalidBackendId;
+ break;
+ case RELPERSISTENCE_TEMP:
+ if (isTempOrToastNamespace(relation->rd_rel->relnamespace))
+ relation->rd_backend = MyBackendId;
+ 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.
+ */
+ relation->rd_backend =
+ GetTempNamespaceBackendId(relation->rd_rel->relnamespace);
+ Assert(relation->rd_backend != InvalidBackendId);
+ }
+ break;
+ default:
+ elog(ERROR, "invalid relpersistence: %c",
+ relation->rd_rel->relpersistence);
+ break;
}
/*
relation->rd_isnailed = true;
relation->rd_createSubid = InvalidSubTransactionId;
relation->rd_newRelfilenodeSubid = InvalidSubTransactionId;
- relation->rd_istemp = false;
relation->rd_backend = InvalidBackendId;
/*
if (isshared)
relation->rd_rel->reltablespace = GLOBALTABLESPACE_OID;
- /*
- * Likewise, we must know if a relation is temp ... but formrdesc is not
- * used for any temp relations.
- */
- relation->rd_rel->relistemp = false;
+ /* formrdesc is used only for permanent relations */
+ relation->rd_rel->relpersistence = RELPERSISTENCE_PERMANENT;
relation->rd_rel->relpages = 1;
relation->rd_rel->reltuples = 1;
Oid relid,
Oid reltablespace,
bool shared_relation,
- bool mapped_relation)
+ bool mapped_relation,
+ char relpersistence)
{
Relation rel;
MemoryContext oldcxt;
/* must flag that we have rels created in this transaction */
need_eoxact_work = true;
- /* it is temporary if and only if it is in my temp-table namespace */
- rel->rd_istemp = isTempOrToastNamespace(relnamespace);
- rel->rd_backend = rel->rd_istemp ? MyBackendId : InvalidBackendId;
-
/*
* create a new tuple descriptor from the one passed in. We do this
* partly to copy it into the cache context, and partly because the new
/* needed when bootstrapping: */
rel->rd_rel->relowner = BOOTSTRAP_SUPERUSERID;
+ /* set up persistence; rd_backend is a function of persistence type */
+ rel->rd_rel->relpersistence = relpersistence;
+ switch (relpersistence)
+ {
+ case RELPERSISTENCE_PERMANENT:
+ rel->rd_backend = InvalidBackendId;
+ break;
+ case RELPERSISTENCE_TEMP:
+ rel->rd_backend = MyBackendId;
+ break;
+ default:
+ elog(ERROR, "invalid relpersistence: %c", relpersistence);
+ break;
+ }
+
/*
* Insert relation physical and logical identifiers (OIDs) into the right
* places. Note that the physical ID (relfilenode) is initially the same
* map.
*/
rel->rd_rel->relisshared = shared_relation;
- rel->rd_rel->relistemp = rel->rd_istemp;
RelationGetRelid(rel) = relid;
/* Allocate a new relfilenode */
newrelfilenode = GetNewRelFileNode(relation->rd_rel->reltablespace, NULL,
- relation->rd_backend);
+ relation->rd_rel->relpersistence);
/*
* Get a writable copy of the pg_class tuple for the given relation.
newrnode.node = relation->rd_node;
newrnode.node.relNode = newrelfilenode;
newrnode.backend = relation->rd_backend;
- RelationCreateStorage(newrnode.node, relation->rd_istemp);
+ RelationCreateStorage(newrnode.node, relation->rd_rel->relpersistence);
smgrclosenode(newrnode);
/*
extern Oid GetNewOidWithIndex(Relation relation, Oid indexId,
AttrNumber oidcolumn);
extern Oid GetNewRelFileNode(Oid reltablespace, Relation pg_class,
- BackendId backend);
+ char relpersistence);
#endif /* CATALOG_H */
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 201012031
+#define CATALOG_VERSION_NO 201012131
#endif
Oid relid,
TupleDesc tupDesc,
char relkind,
+ char relpersistence,
bool shared_relation,
bool mapped_relation,
bool allow_system_table_mods);
TupleDesc tupdesc,
List *cooked_constraints,
char relkind,
+ char relpersistence,
bool shared_relation,
bool mapped_relation,
bool oidislocal,
Oid reltoastidxid; /* if toast table, OID of chunk_id index */
bool relhasindex; /* T if has (or has had) any indexes */
bool relisshared; /* T if shared across databases */
- bool relistemp; /* T if temporary relation */
+ char relpersistence; /* see RELPERSISTENCE_xxx constants */
char relkind; /* see RELKIND_xxx constants below */
int2 relnatts; /* number of user attributes */
#define Anum_pg_class_reltoastidxid 12
#define Anum_pg_class_relhasindex 13
#define Anum_pg_class_relisshared 14
-#define Anum_pg_class_relistemp 15
+#define Anum_pg_class_relpersistence 15
#define Anum_pg_class_relkind 16
#define Anum_pg_class_relnatts 17
#define Anum_pg_class_relchecks 18
*/
/* Note: "3" in the relfrozenxid column stands for FirstNormalTransactionId */
-DATA(insert OID = 1247 ( pg_type PGNSP 71 0 PGUID 0 0 0 0 0 0 0 f f f r 28 0 t f f f f f 3 _null_ _null_ ));
+DATA(insert OID = 1247 ( pg_type PGNSP 71 0 PGUID 0 0 0 0 0 0 0 f f p r 28 0 t f f f f f 3 _null_ _null_ ));
DESCR("");
-DATA(insert OID = 1249 ( pg_attribute PGNSP 75 0 PGUID 0 0 0 0 0 0 0 f f f r 19 0 f f f f f f 3 _null_ _null_ ));
+DATA(insert OID = 1249 ( pg_attribute PGNSP 75 0 PGUID 0 0 0 0 0 0 0 f f p r 19 0 f f f f f f 3 _null_ _null_ ));
DESCR("");
-DATA(insert OID = 1255 ( pg_proc PGNSP 81 0 PGUID 0 0 0 0 0 0 0 f f f r 25 0 t f f f f f 3 _null_ _null_ ));
+DATA(insert OID = 1255 ( pg_proc PGNSP 81 0 PGUID 0 0 0 0 0 0 0 f f p r 25 0 t f f f f f 3 _null_ _null_ ));
DESCR("");
-DATA(insert OID = 1259 ( pg_class PGNSP 83 0 PGUID 0 0 0 0 0 0 0 f f f r 27 0 t f f f f f 3 _null_ _null_ ));
+DATA(insert OID = 1259 ( pg_class PGNSP 83 0 PGUID 0 0 0 0 0 0 0 f f p r 27 0 t f f f f f 3 _null_ _null_ ));
DESCR("");
#define RELKIND_INDEX 'i' /* secondary index */
#define RELKIND_VIEW 'v' /* view */
#define RELKIND_COMPOSITE_TYPE 'c' /* composite type */
+#define RELPERSISTENCE_PERMANENT 'p'
+#define RELPERSISTENCE_TEMP 't'
+
#endif /* PG_CLASS_H */
#include "storage/relfilenode.h"
#include "utils/relcache.h"
-extern void RelationCreateStorage(RelFileNode rnode, bool istemp);
+extern void RelationCreateStorage(RelFileNode rnode, char relpersistence);
extern void RelationDropStorage(Relation rel);
extern void RelationPreserveStorage(RelFileNode rnode);
extern void RelationTruncate(Relation rel, BlockNumber nblocks);
extern void TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo);
-extern Oid GetDefaultTablespace(bool forTemp);
+extern Oid GetDefaultTablespace(char relpersistence);
extern void PrepareTempTablespaces(void);
char *relname; /* the relation/sequence name */
InhOption inhOpt; /* expand rel by inheritance? recursively act
* on children? */
- bool istemp; /* is this a temp relation/sequence? */
+ char relpersistence; /* see RELPERSISTENCE_* in pg_class.h */
Alias *alias; /* table alias & optional column aliases */
int location; /* token location, or -1 if unknown */
} RangeVar;
struct SMgrRelationData *rd_smgr; /* cached file handle, or NULL */
int rd_refcnt; /* reference count */
BackendId rd_backend; /* owning backend id, if temporary relation */
- bool rd_istemp; /* rel is a temporary relation */
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 =
(relation)->rd_smgr->smgr_targblock = (targblock); \
} while (0)
+/*
+ * RelationNeedsWAL
+ * True if relation needs WAL.
+ */
+#define RelationNeedsWAL(relation) \
+ ((relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
+
+/*
+ * RelationUsesLocalBuffers
+ * True if relation's pages are stored in local buffers.
+ */
+#define RelationUsesLocalBuffers(relation) \
+ ((relation)->rd_rel->relpersistence == RELPERSISTENCE_TEMP)
+
+/*
+ * RelationUsesTempNamespace
+ * True if relation's catalog entries live in a private namespace.
+ */
+#define RelationUsesTempNamespace(relation) \
+ ((relation)->rd_rel->relpersistence == RELPERSISTENCE_TEMP)
+
/*
* RELATION_IS_LOCAL
* If a rel is either temp or newly created in the current transaction,
* Beware of multiple eval of argument
*/
#define RELATION_IS_OTHER_TEMP(relation) \
- ((relation)->rd_istemp && (relation)->rd_backend != MyBackendId)
+ ((relation)->rd_rel->relpersistence == RELPERSISTENCE_TEMP \
+ && (relation)->rd_backend != MyBackendId)
/* routines in utils/cache/relcache.c */
extern void RelationIncrementReferenceCount(Relation rel);
Oid relid,
Oid reltablespace,
bool shared_relation,
- bool mapped_relation);
+ bool mapped_relation,
+ char relpersistence);
/*
* Routine to manage assignment of new relfilenode to a relation