diff --git a/src/backend/access/gin/ginbtree.c b/src/backend/access/gin/ginbtree.c index 070cd9209e..9d857a0310 100644 --- a/src/backend/access/gin/ginbtree.c +++ b/src/backend/access/gin/ginbtree.c @@ -304,7 +304,7 @@ ginInsertValue(GinBtree btree, GinBtreeStack *stack, GinStatsData *buildStats) MarkBufferDirty(stack->buffer); - if (!btree->index->rd_istemp) + if (RelationNeedsWAL(btree->index)) { XLogRecPtr recptr; @@ -373,7 +373,7 @@ ginInsertValue(GinBtree btree, GinBtreeStack *stack, GinStatsData *buildStats) MarkBufferDirty(lbuffer); MarkBufferDirty(stack->buffer); - if (!btree->index->rd_istemp) + if (RelationNeedsWAL(btree->index)) { XLogRecPtr recptr; @@ -422,7 +422,7 @@ ginInsertValue(GinBtree btree, GinBtreeStack *stack, GinStatsData *buildStats) MarkBufferDirty(rbuffer); MarkBufferDirty(stack->buffer); - if (!btree->index->rd_istemp) + if (RelationNeedsWAL(btree->index)) { XLogRecPtr recptr; diff --git a/src/backend/access/gin/ginfast.c b/src/backend/access/gin/ginfast.c index 525f79cea7..74339c9eea 100644 --- a/src/backend/access/gin/ginfast.c +++ b/src/backend/access/gin/ginfast.c @@ -103,7 +103,7 @@ writeListPage(Relation index, Buffer buffer, MarkBufferDirty(buffer); - if (!index->rd_istemp) + if (RelationNeedsWAL(index)) { XLogRecData rdata[2]; ginxlogInsertListPage data; @@ -384,7 +384,7 @@ ginHeapTupleFastInsert(Relation index, GinState *ginstate, */ MarkBufferDirty(metabuffer); - if (!index->rd_istemp) + if (RelationNeedsWAL(index)) { XLogRecPtr recptr; @@ -564,7 +564,7 @@ shiftList(Relation index, Buffer metabuffer, BlockNumber newHead, MarkBufferDirty(buffers[i]); } - if (!index->rd_istemp) + if (RelationNeedsWAL(index)) { XLogRecPtr recptr; diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c index fa70e4fa55..8681edefe6 100644 --- a/src/backend/access/gin/gininsert.c +++ b/src/backend/access/gin/gininsert.c @@ -55,7 +55,7 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems) MarkBufferDirty(buffer); - if (!index->rd_istemp) + if (RelationNeedsWAL(index)) { XLogRecPtr recptr; XLogRecData rdata[2]; @@ -325,7 +325,7 @@ ginbuild(PG_FUNCTION_ARGS) GinInitBuffer(RootBuffer, GIN_LEAF); MarkBufferDirty(RootBuffer); - if (!index->rd_istemp) + if (RelationNeedsWAL(index)) { XLogRecPtr recptr; XLogRecData rdata; diff --git a/src/backend/access/gin/ginutil.c b/src/backend/access/gin/ginutil.c index 27326acec9..5f20ac9349 100644 --- a/src/backend/access/gin/ginutil.c +++ b/src/backend/access/gin/ginutil.c @@ -410,7 +410,7 @@ ginUpdateStats(Relation index, const GinStatsData *stats) MarkBufferDirty(metabuffer); - if (!index->rd_istemp) + if (RelationNeedsWAL(index)) { XLogRecPtr recptr; ginxlogUpdateMeta data; diff --git a/src/backend/access/gin/ginvacuum.c b/src/backend/access/gin/ginvacuum.c index 7dfecffc87..4b35acb983 100644 --- a/src/backend/access/gin/ginvacuum.c +++ b/src/backend/access/gin/ginvacuum.c @@ -93,7 +93,7 @@ xlogVacuumPage(Relation index, Buffer buffer) Assert(GinPageIsLeaf(page)); - if (index->rd_istemp) + if (!RelationNeedsWAL(index)) return; data.node = index->rd_node; @@ -308,7 +308,7 @@ ginDeletePage(GinVacuumState *gvs, BlockNumber deleteBlkno, BlockNumber leftBlkn MarkBufferDirty(lBuffer); MarkBufferDirty(dBuffer); - if (!gvs->index->rd_istemp) + if (RelationNeedsWAL(gvs->index)) { XLogRecPtr recptr; XLogRecData rdata[4]; diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c index d6aaea2162..b34830bb42 100644 --- a/src/backend/access/gist/gist.c +++ b/src/backend/access/gist/gist.c @@ -115,7 +115,7 @@ gistbuild(PG_FUNCTION_ARGS) MarkBufferDirty(buffer); - if (!index->rd_istemp) + if (RelationNeedsWAL(index)) { XLogRecPtr recptr; XLogRecData rdata; @@ -401,7 +401,7 @@ gistplacetopage(GISTInsertState *state, GISTSTATE *giststate) dist->page = BufferGetPage(dist->buffer); } - if (!state->r->rd_istemp) + if (RelationNeedsWAL(state->r)) { XLogRecPtr recptr; XLogRecData *rdata; @@ -465,7 +465,7 @@ gistplacetopage(GISTInsertState *state, GISTSTATE *giststate) MarkBufferDirty(state->stack->buffer); - if (!state->r->rd_istemp) + if (RelationNeedsWAL(state->r)) { OffsetNumber noffs = 0, offs[1]; @@ -550,7 +550,7 @@ gistfindleaf(GISTInsertState *state, GISTSTATE *giststate) 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)) @@ -911,7 +911,7 @@ gistmakedeal(GISTInsertState *state, GISTSTATE *giststate) } /* 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); } @@ -1011,7 +1011,7 @@ gistnewroot(Relation r, Buffer buffer, IndexTuple *itup, int len, ItemPointer ke MarkBufferDirty(buffer); - if (!r->rd_istemp) + if (RelationNeedsWAL(r)) { XLogRecPtr recptr; XLogRecData *rdata; diff --git a/src/backend/access/gist/gistvacuum.c b/src/backend/access/gist/gistvacuum.c index dbe9406ceb..e02e72d431 100644 --- a/src/backend/access/gist/gistvacuum.c +++ b/src/backend/access/gist/gistvacuum.c @@ -248,7 +248,7 @@ gistbulkdelete(PG_FUNCTION_ARGS) PageIndexTupleDelete(page, todelete[i]); GistMarkTuplesDeleted(page); - if (!rel->rd_istemp) + if (RelationNeedsWAL(rel)) { XLogRecData *rdata; XLogRecPtr recptr; diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 4fe3a73910..4020906b34 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -124,7 +124,7 @@ initscan(HeapScanDesc scan, ScanKey key, bool is_rescan) * * 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; @@ -905,7 +905,7 @@ relation_open(Oid relationId, LOCKMODE lockmode) 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); @@ -951,7 +951,7 @@ try_relation_open(Oid relationId, LOCKMODE lockmode) 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); @@ -1917,7 +1917,7 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid, 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; @@ -2227,7 +2227,7 @@ l1: MarkBufferDirty(buffer); /* XLOG stuff */ - if (!relation->rd_istemp) + if (RelationNeedsWAL(relation)) { xl_heap_delete xlrec; XLogRecPtr recptr; @@ -2780,7 +2780,7 @@ l2: MarkBufferDirty(buffer); /* XLOG stuff */ - if (!relation->rd_istemp) + if (RelationNeedsWAL(relation)) { XLogRecPtr recptr = log_heap_update(relation, buffer, oldtup.t_self, newbuf, heaptup, @@ -3403,7 +3403,7 @@ l3: * (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; @@ -3505,7 +3505,7 @@ heap_inplace_update(Relation relation, HeapTuple tuple) MarkBufferDirty(buffer); /* XLOG stuff */ - if (!relation->rd_istemp) + if (RelationNeedsWAL(relation)) { xl_heap_inplace xlrec; XLogRecPtr recptr; @@ -3867,8 +3867,8 @@ log_heap_clean(Relation reln, Buffer buffer, 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); @@ -3950,8 +3950,8 @@ log_heap_freeze(Relation reln, Buffer 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); @@ -3996,8 +3996,8 @@ log_heap_update(Relation reln, Buffer oldbuf, ItemPointerData from, 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; @@ -4997,7 +4997,7 @@ heap2_desc(StringInfo buf, uint8 xl_info, char *rec) * 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. * @@ -5010,8 +5010,8 @@ heap2_desc(StringInfo buf, uint8 xl_info, char *rec) 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 */ diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c index ee5f38fccd..d1b08b3a8b 100644 --- a/src/backend/access/heap/pruneheap.c +++ b/src/backend/access/heap/pruneheap.c @@ -233,7 +233,7 @@ heap_page_prune(Relation relation, Buffer buffer, TransactionId OldestXmin, /* * Emit a WAL HEAP_CLEAN record showing what we did */ - if (!relation->rd_istemp) + if (RelationNeedsWAL(relation)) { XLogRecPtr recptr; diff --git a/src/backend/access/heap/rewriteheap.c b/src/backend/access/heap/rewriteheap.c index 19ca302ebb..eb2dbffb9d 100644 --- a/src/backend/access/heap/rewriteheap.c +++ b/src/backend/access/heap/rewriteheap.c @@ -277,8 +277,8 @@ end_heap_rewrite(RewriteState state) } /* - * 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 @@ -287,7 +287,7 @@ end_heap_rewrite(RewriteState state) * 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 */ diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c index eaad8122b1..ee0f04cdb5 100644 --- a/src/backend/access/nbtree/nbtinsert.c +++ b/src/backend/access/nbtree/nbtinsert.c @@ -766,7 +766,7 @@ _bt_insertonpg(Relation rel, } /* XLOG stuff */ - if (!rel->rd_istemp) + if (RelationNeedsWAL(rel)) { xl_btree_insert xlrec; BlockNumber xldownlink; @@ -1165,7 +1165,7 @@ _bt_split(Relation rel, Buffer buf, OffsetNumber firstright, } /* XLOG stuff */ - if (!rel->rd_istemp) + if (RelationNeedsWAL(rel)) { xl_btree_split xlrec; uint8 xlinfo; @@ -1914,7 +1914,7 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf) MarkBufferDirty(metabuf); /* XLOG stuff */ - if (!rel->rd_istemp) + if (RelationNeedsWAL(rel)) { xl_btree_newroot xlrec; XLogRecPtr recptr; diff --git a/src/backend/access/nbtree/nbtpage.c b/src/backend/access/nbtree/nbtpage.c index e0c0f21f4e..2b4478089d 100644 --- a/src/backend/access/nbtree/nbtpage.c +++ b/src/backend/access/nbtree/nbtpage.c @@ -224,7 +224,7 @@ _bt_getroot(Relation rel, int access) MarkBufferDirty(metabuf); /* XLOG stuff */ - if (!rel->rd_istemp) + if (RelationNeedsWAL(rel)) { xl_btree_newroot xlrec; XLogRecPtr recptr; @@ -452,7 +452,7 @@ _bt_checkpage(Relation rel, Buffer buf) 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 */ @@ -751,7 +751,7 @@ _bt_delitems_vacuum(Relation rel, Buffer buf, MarkBufferDirty(buf); /* XLOG stuff */ - if (!rel->rd_istemp) + if (RelationNeedsWAL(rel)) { XLogRecPtr recptr; XLogRecData rdata[2]; @@ -829,7 +829,7 @@ _bt_delitems_delete(Relation rel, Buffer buf, MarkBufferDirty(buf); /* XLOG stuff */ - if (!rel->rd_istemp) + if (RelationNeedsWAL(rel)) { XLogRecPtr recptr; XLogRecData rdata[3]; @@ -1365,7 +1365,7 @@ _bt_pagedel(Relation rel, Buffer buf, BTStack stack) MarkBufferDirty(lbuf); /* XLOG stuff */ - if (!rel->rd_istemp) + if (RelationNeedsWAL(rel)) { xl_btree_delete_page xlrec; xl_btree_metadata xlmeta; diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c index a1d3aef353..3fb43a2e58 100644 --- a/src/backend/access/nbtree/nbtsort.c +++ b/src/backend/access/nbtree/nbtsort.c @@ -211,9 +211,9 @@ _bt_leafbuild(BTSpool *btspool, BTSpool *btspool2) /* * 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; @@ -797,9 +797,9 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2) _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 @@ -811,7 +811,7 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2) * 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); diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y index e475403b9e..73ef114d9c 100644 --- a/src/backend/bootstrap/bootparse.y +++ b/src/backend/bootstrap/bootparse.y @@ -219,6 +219,7 @@ Boot_CreateStmt: $3, tupdesc, RELKIND_RELATION, + RELPERSISTENCE_PERMANENT, shared_relation, mapped_relation, true); @@ -238,6 +239,7 @@ Boot_CreateStmt: tupdesc, NIL, RELKIND_RELATION, + RELPERSISTENCE_PERMANENT, shared_relation, mapped_relation, true, diff --git a/src/backend/catalog/catalog.c b/src/backend/catalog/catalog.c index 63225127f7..88b5c2a215 100644 --- a/src/backend/catalog/catalog.c +++ b/src/backend/catalog/catalog.c @@ -524,12 +524,26 @@ GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn) * 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; diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 9b7668c133..bcf6caa2ee 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -238,6 +238,7 @@ heap_create(const char *relname, Oid relid, TupleDesc tupDesc, char relkind, + char relpersistence, bool shared_relation, bool mapped_relation, bool allow_system_table_mods) @@ -311,7 +312,8 @@ heap_create(const char *relname, relid, reltablespace, shared_relation, - mapped_relation); + mapped_relation, + relpersistence); /* * Have the storage manager create the relation's disk file, if needed. @@ -322,7 +324,7 @@ heap_create(const char *relname, if (create_storage) { RelationOpenSmgr(rel); - RelationCreateStorage(rel->rd_node, rel->rd_istemp); + RelationCreateStorage(rel->rd_node, relpersistence); } return rel; @@ -693,7 +695,7 @@ InsertPgClassTuple(Relation pg_class_desc, 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); @@ -898,6 +900,7 @@ heap_create_with_catalog(const char *relname, TupleDesc tupdesc, List *cooked_constraints, char relkind, + char relpersistence, bool shared_relation, bool mapped_relation, bool oidislocal, @@ -997,8 +1000,7 @@ heap_create_with_catalog(const char *relname, } else relid = GetNewRelFileNode(reltablespace, pg_class_desc, - isTempOrToastNamespace(relnamespace) ? - MyBackendId : InvalidBackendId); + relpersistence); } /* @@ -1036,6 +1038,7 @@ heap_create_with_catalog(const char *relname, relid, tupdesc, relkind, + relpersistence, shared_relation, mapped_relation, allow_system_table_mods); diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index b437c9976a..8fbe8ebc91 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -545,6 +545,7 @@ index_create(Oid heapRelationId, bool is_exclusion; Oid namespaceId; int i; + char relpersistence; is_exclusion = (indexInfo->ii_ExclusionOps != NULL); @@ -561,11 +562,13 @@ index_create(Oid heapRelationId, /* * 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 @@ -646,9 +649,7 @@ index_create(Oid heapRelationId, else { indexRelationId = - GetNewRelFileNode(tableSpaceId, pg_class, - heapRelation->rd_istemp ? - MyBackendId : InvalidBackendId); + GetNewRelFileNode(tableSpaceId, pg_class, relpersistence); } } @@ -663,6 +664,7 @@ index_create(Oid heapRelationId, indexRelationId, indexTupDesc, RELKIND_INDEX, + relpersistence, shared_relation, mapped_relation, allow_system_table_mods); diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index 653c9ada11..84cbfeb0a7 100644 --- a/src/backend/catalog/namespace.c +++ b/src/backend/catalog/namespace.c @@ -235,14 +235,14 @@ RangeVarGetRelid(const RangeVar *relation, bool failOK) } /* - * 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, @@ -308,7 +308,7 @@ RangeVarGetCreationNamespace(const RangeVar *newRelation) newRelation->relname))); } - if (newRelation->istemp) + if (newRelation->relpersistence == RELPERSISTENCE_TEMP) { /* TEMP tables are created in our backend-local temp namespace */ if (newRelation->schemaname) diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c index 0ce2051b6b..671aaff133 100644 --- a/src/backend/catalog/storage.c +++ b/src/backend/catalog/storage.c @@ -95,19 +95,35 @@ typedef struct xl_smgr_truncate * 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. @@ -253,7 +269,7 @@ RelationTruncate(Relation rel, BlockNumber nblocks) * 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. diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 7bf64e22ee..d1f6c9f368 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -195,7 +195,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, Datum reloptio * 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; @@ -216,6 +216,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, Datum reloptio tupdesc, NIL, RELKIND_TOASTVALUE, + rel->rd_rel->relpersistence, shared_relation, mapped_relation, true, diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c index e1dbd6d985..249067f1e2 100644 --- a/src/backend/commands/cluster.c +++ b/src/backend/commands/cluster.c @@ -675,6 +675,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace) tupdesc, NIL, OldHeap->rd_rel->relkind, + OldHeap->rd_rel->relpersistence, false, RelationIsMapped(OldHeap), true, @@ -789,9 +790,9 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, /* * 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); diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 9407d0f02d..0940893135 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -222,7 +222,7 @@ DefineIndex(RangeVar *heapRelation, } else { - tablespaceId = GetDefaultTablespace(rel->rd_istemp); + tablespaceId = GetDefaultTablespace(rel->rd_rel->relpersistence); /* note InvalidOid is OK in this case */ } @@ -1706,7 +1706,7 @@ ReindexDatabase(const char *databaseName, bool do_system, bool do_user) 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; diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index bb8ebce25a..e1df5fb13c 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -366,7 +366,7 @@ fill_seq_with_data(Relation rel, HeapTuple tuple) MarkBufferDirty(buf); /* XLOG stuff */ - if (!rel->rd_istemp) + if (RelationNeedsWAL(rel)) { xl_seq_rec xlrec; XLogRecPtr recptr; @@ -448,7 +448,7 @@ AlterSequence(AlterSeqStmt *stmt) MarkBufferDirty(buf); /* XLOG stuff */ - if (!seqrel->rd_istemp) + if (RelationNeedsWAL(seqrel)) { xl_seq_rec xlrec; XLogRecPtr recptr; @@ -678,7 +678,7 @@ nextval_internal(Oid relid) MarkBufferDirty(buf); /* XLOG stuff */ - if (logit && !seqrel->rd_istemp) + if (logit && RelationNeedsWAL(seqrel)) { xl_seq_rec xlrec; XLogRecPtr recptr; @@ -855,7 +855,7 @@ do_setval(Oid relid, int64 next, bool iscalled) MarkBufferDirty(buf); /* XLOG stuff */ - if (!seqrel->rd_istemp) + if (RelationNeedsWAL(seqrel)) { xl_seq_rec xlrec; XLogRecPtr recptr; diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 937992ba58..6729d8336f 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -224,7 +224,7 @@ static const struct dropmsgstrings dropmsgstringarray[] = { 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); @@ -339,7 +339,7 @@ static void ATPrepAddInherit(Relation child_rel); 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); @@ -391,7 +391,8 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId) /* * 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"))); @@ -401,7 +402,8 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId) * 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"))); @@ -434,7 +436,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId) } else { - tablespaceId = GetDefaultTablespace(stmt->relation->istemp); + tablespaceId = GetDefaultTablespace(stmt->relation->relpersistence); /* note InvalidOid is OK in this case */ } @@ -478,7 +480,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId) * inherited attributes. */ schema = MergeAttributes(schema, stmt->inhRelations, - stmt->relation->istemp, + stmt->relation->relpersistence, &inheritOids, &old_constraints, &parentOidCount); /* @@ -557,6 +559,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId) list_concat(cookedDefaults, old_constraints), relkind, + stmt->relation->relpersistence, false, false, localHasOids, @@ -1208,7 +1211,7 @@ storage_name(char c) *---------- */ static List * -MergeAttributes(List *schema, List *supers, bool istemp, +MergeAttributes(List *schema, List *supers, char relpersistence, List **supOids, List **supconstr, int *supOidCount) { ListCell *entry; @@ -1316,7 +1319,8 @@ MergeAttributes(List *schema, List *supers, bool istemp, 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\"", @@ -5124,26 +5128,27 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, 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; } /* @@ -7347,7 +7352,8 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode) * 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; @@ -7364,10 +7370,11 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode) * 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++) @@ -7375,7 +7382,8 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode) 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); } } @@ -7410,7 +7418,7 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode) */ static void copy_relation_data(SMgrRelation src, SMgrRelation dst, - ForkNumber forkNum, bool istemp) + ForkNumber forkNum, char relpersistence) { char *buf; Page page; @@ -7429,9 +7437,9 @@ copy_relation_data(SMgrRelation src, SMgrRelation dst, /* * 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); @@ -7470,7 +7478,7 @@ copy_relation_data(SMgrRelation src, SMgrRelation dst, * 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); } @@ -7538,7 +7546,8 @@ ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode) 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\"", diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index cd80c811a9..5ad0831404 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -1050,8 +1050,8 @@ assign_default_tablespace(const char *newval, bool doit, GucSource source) /* * 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". * @@ -1062,12 +1062,12 @@ assign_default_tablespace(const char *newval, bool doit, GucSource source) * 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(); diff --git a/src/backend/commands/vacuumlazy.c b/src/backend/commands/vacuumlazy.c index 0ac993f957..cbdf97de91 100644 --- a/src/backend/commands/vacuumlazy.c +++ b/src/backend/commands/vacuumlazy.c @@ -268,10 +268,10 @@ static void 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; /* @@ -664,8 +664,7 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats, if (nfrozen > 0) { MarkBufferDirty(buf); - /* no XLOG for temp tables, though */ - if (!onerel->rd_istemp) + if (RelationNeedsWAL(onerel)) { XLogRecPtr recptr; @@ -895,7 +894,7 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer, MarkBufferDirty(buffer); /* XLOG stuff */ - if (!onerel->rd_istemp) + if (RelationNeedsWAL(onerel)) { XLogRecPtr recptr; diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c index 09ab24b011..2b2b908500 100644 --- a/src/backend/commands/view.c +++ b/src/backend/commands/view.c @@ -68,10 +68,10 @@ isViewOnTempTable_walker(Node *node, void *context) 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; } } @@ -173,9 +173,9 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace) /* * 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 @@ -454,10 +454,11 @@ DefineView(ViewStmt *stmt, const char *queryString) * 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))); diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 69f3a28d41..c4719f33b9 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -2131,7 +2131,8 @@ OpenIntoRel(QueryDesc *queryDesc) /* * 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"))); @@ -2141,7 +2142,8 @@ OpenIntoRel(QueryDesc *queryDesc) * 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"))); @@ -2168,7 +2170,7 @@ OpenIntoRel(QueryDesc *queryDesc) } else { - tablespaceId = GetDefaultTablespace(into->rel->istemp); + tablespaceId = GetDefaultTablespace(into->rel->relpersistence); /* note InvalidOid is OK in this case */ } @@ -2208,6 +2210,7 @@ OpenIntoRel(QueryDesc *queryDesc) tupdesc, NIL, RELKIND_RELATION, + into->rel->relpersistence, false, false, true, diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 735322ee3f..4e1f221af1 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -958,7 +958,7 @@ _copyRangeVar(RangeVar *from) 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); diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 2d2b8c7763..85cded0f74 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -104,7 +104,7 @@ _equalRangeVar(RangeVar *a, RangeVar *b) 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); diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c index 4b268f3c6b..f06f73bd6a 100644 --- a/src/backend/nodes/makefuncs.c +++ b/src/backend/nodes/makefuncs.c @@ -15,6 +15,7 @@ */ #include "postgres.h" +#include "catalog/pg_class.h" #include "catalog/pg_type.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" @@ -378,7 +379,7 @@ makeRangeVar(char *schemaname, char *relname, int location) r->schemaname = schemaname; r->relname = relname; r->inhOpt = INH_DEFAULT; - r->istemp = false; + r->relpersistence = RELPERSISTENCE_PERMANENT; r->alias = NULL; r->location = location; diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 5d09e16477..7d77d84a37 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -841,7 +841,7 @@ _outRangeVar(StringInfo str, RangeVar *node) 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); } diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index 2166a5d1e0..933d58ada5 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -373,7 +373,7 @@ _readRangeVar(void) 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); diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 9ec75f776c..8fc79b6337 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -311,7 +311,8 @@ static RangeVar *makeRangeVarFromAnyName(List *names, int position, core_yyscan_ %type arg_class %type func_return func_type -%type OptTemp opt_trusted opt_restart_seqs +%type opt_trusted opt_restart_seqs +%type OptTemp %type OnCommitOption %type for_locking_item @@ -2280,7 +2281,7 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' OptInherit OptWith OnCommitOption OptTableSpace { CreateStmt *n = makeNode(CreateStmt); - $4->istemp = $2; + $4->relpersistence = $2; n->relation = $4; n->tableElts = $6; n->inhRelations = $8; @@ -2296,7 +2297,7 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' OptTableSpace { CreateStmt *n = makeNode(CreateStmt); - $7->istemp = $2; + $7->relpersistence = $2; n->relation = $7; n->tableElts = $9; n->inhRelations = $11; @@ -2311,7 +2312,7 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' OptTypedTableElementList OptWith OnCommitOption OptTableSpace { CreateStmt *n = makeNode(CreateStmt); - $4->istemp = $2; + $4->relpersistence = $2; n->relation = $4; n->tableElts = $7; n->ofTypename = makeTypeNameFromNameList($6); @@ -2327,7 +2328,7 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' OptTypedTableElementList OptWith OnCommitOption OptTableSpace { CreateStmt *n = makeNode(CreateStmt); - $7->istemp = $2; + $7->relpersistence = $2; n->relation = $7; n->tableElts = $10; n->ofTypename = makeTypeNameFromNameList($9); @@ -2348,13 +2349,13 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' * 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: @@ -2834,7 +2835,7 @@ CreateAsStmt: (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) @@ -2900,7 +2901,7 @@ CreateSeqStmt: 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; @@ -6621,7 +6622,7 @@ ViewStmt: CREATE OptTemp VIEW qualified_name opt_column_list { ViewStmt *n = makeNode(ViewStmt); n->view = $4; - n->view->istemp = $2; + n->view->relpersistence = $2; n->aliases = $5; n->query = $7; n->replace = false; @@ -6632,7 +6633,7 @@ ViewStmt: CREATE OptTemp VIEW qualified_name opt_column_list { ViewStmt *n = makeNode(ViewStmt); n->view = $6; - n->view->istemp = $4; + n->view->relpersistence = $4; n->aliases = $7; n->query = $9; n->replace = true; @@ -7328,7 +7329,7 @@ ExecuteStmt: EXECUTE name execute_param_clause 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, @@ -7889,42 +7890,42 @@ OptTempTableName: 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; } ; @@ -10916,16 +10917,12 @@ qualified_name_list: 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: @@ -10946,7 +10943,6 @@ qualified_name: parser_errposition(@1))); break; } - $$->location = @1; } ; @@ -12163,6 +12159,7 @@ makeRangeVarFromAnyName(List *names, int position, core_yyscan_t yyscanner) break; } + r->relpersistence = RELPERSISTENCE_PERMANENT; r->location = position; return r; diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index a8aee204c7..aa7c144c94 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -158,10 +158,11 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString) * 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); diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index c7d704dc8c..89b2540871 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -1975,7 +1975,7 @@ do_autovacuum(void) * 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; @@ -2072,7 +2072,7 @@ do_autovacuum(void) /* * We cannot safely process other backends' temp tables, so skip 'em. */ - if (classForm->relistemp) + if (classForm->relpersistence == RELPERSISTENCE_TEMP) continue; relid = HeapTupleGetOid(tuple); diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index edc497788d..860e736ff0 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -123,7 +123,7 @@ PrefetchBuffer(Relation reln, ForkNumber forkNum, BlockNumber blockNum) /* 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)) @@ -2071,7 +2071,7 @@ FlushRelationBuffers(Relation rel) /* 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++) { diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c index f5250a263c..e352cdafb3 100644 --- a/src/backend/utils/adt/dbsize.c +++ b/src/backend/utils/adt/dbsize.c @@ -612,16 +612,26 @@ pg_relation_filepath(PG_FUNCTION_ARGS) 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); diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 8df12a1424..1509686079 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -849,20 +849,30 @@ RelationBuildDesc(Oid targetRelId, bool insertIt) 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; } /* @@ -1358,7 +1368,6 @@ formrdesc(const char *relationName, Oid relationReltype, relation->rd_isnailed = true; relation->rd_createSubid = InvalidSubTransactionId; relation->rd_newRelfilenodeSubid = InvalidSubTransactionId; - relation->rd_istemp = false; relation->rd_backend = InvalidBackendId; /* @@ -1384,11 +1393,8 @@ formrdesc(const char *relationName, Oid relationReltype, 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; @@ -2366,7 +2372,8 @@ RelationBuildLocalRelation(const char *relname, Oid relid, Oid reltablespace, bool shared_relation, - bool mapped_relation) + bool mapped_relation, + char relpersistence) { Relation rel; MemoryContext oldcxt; @@ -2440,10 +2447,6 @@ RelationBuildLocalRelation(const char *relname, /* 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 @@ -2483,6 +2486,21 @@ RelationBuildLocalRelation(const char *relname, /* 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 @@ -2491,7 +2509,6 @@ RelationBuildLocalRelation(const char *relname, * map. */ rel->rd_rel->relisshared = shared_relation; - rel->rd_rel->relistemp = rel->rd_istemp; RelationGetRelid(rel) = relid; @@ -2569,7 +2586,7 @@ RelationSetNewRelfilenode(Relation relation, TransactionId freezeXid) /* 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. @@ -2592,7 +2609,7 @@ RelationSetNewRelfilenode(Relation relation, TransactionId freezeXid) 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); /* diff --git a/src/include/catalog/catalog.h b/src/include/catalog/catalog.h index 97c808bc50..56dcdd53fe 100644 --- a/src/include/catalog/catalog.h +++ b/src/include/catalog/catalog.h @@ -56,6 +56,6 @@ extern Oid GetNewOid(Relation relation); extern Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn); extern Oid GetNewRelFileNode(Oid reltablespace, Relation pg_class, - BackendId backend); + char relpersistence); #endif /* CATALOG_H */ diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 6c12f7cbf8..1c3d14951c 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 201012031 +#define CATALOG_VERSION_NO 201012131 #endif diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h index 7795bda323..646ab9c8f1 100644 --- a/src/include/catalog/heap.h +++ b/src/include/catalog/heap.h @@ -40,6 +40,7 @@ extern Relation heap_create(const char *relname, Oid relid, TupleDesc tupDesc, char relkind, + char relpersistence, bool shared_relation, bool mapped_relation, bool allow_system_table_mods); @@ -54,6 +55,7 @@ extern Oid heap_create_with_catalog(const char *relname, TupleDesc tupdesc, List *cooked_constraints, char relkind, + char relpersistence, bool shared_relation, bool mapped_relation, bool oidislocal, diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h index f50cf9d55b..1edbfe378b 100644 --- a/src/include/catalog/pg_class.h +++ b/src/include/catalog/pg_class.h @@ -49,7 +49,7 @@ CATALOG(pg_class,1259) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83) BKI_SCHEMA_MACRO 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 */ @@ -108,7 +108,7 @@ typedef FormData_pg_class *Form_pg_class; #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 @@ -132,13 +132,13 @@ typedef FormData_pg_class *Form_pg_class; */ /* 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 */ @@ -149,4 +149,7 @@ DESCR(""); #define RELKIND_VIEW 'v' /* view */ #define RELKIND_COMPOSITE_TYPE 'c' /* composite type */ +#define RELPERSISTENCE_PERMANENT 'p' +#define RELPERSISTENCE_TEMP 't' + #endif /* PG_CLASS_H */ diff --git a/src/include/catalog/storage.h b/src/include/catalog/storage.h index d7b8731838..f086b1c33f 100644 --- a/src/include/catalog/storage.h +++ b/src/include/catalog/storage.h @@ -20,7 +20,7 @@ #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); diff --git a/src/include/commands/tablespace.h b/src/include/commands/tablespace.h index 327fbc6c4f..1e3f6ca0c6 100644 --- a/src/include/commands/tablespace.h +++ b/src/include/commands/tablespace.h @@ -47,7 +47,7 @@ extern void AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt); extern void TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo); -extern Oid GetDefaultTablespace(bool forTemp); +extern Oid GetDefaultTablespace(char relpersistence); extern void PrepareTempTablespaces(void); diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index b17adf2aa3..ba5ae371c0 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -74,7 +74,7 @@ typedef struct RangeVar 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; diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index 39e0365c0b..88a3168d13 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -132,7 +132,6 @@ typedef struct RelationData 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 = @@ -389,6 +388,27 @@ typedef struct StdRdOptions (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, @@ -407,7 +427,8 @@ typedef struct StdRdOptions * 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); diff --git a/src/include/utils/relcache.h b/src/include/utils/relcache.h index 10d82d4b41..35000500c1 100644 --- a/src/include/utils/relcache.h +++ b/src/include/utils/relcache.h @@ -69,7 +69,8 @@ extern Relation RelationBuildLocalRelation(const char *relname, 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