aboutsummaryrefslogtreecommitdiff
path: root/src/include/utils/rel.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/utils/rel.h')
-rw-r--r--src/include/utils/rel.h37
1 files changed, 24 insertions, 13 deletions
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index 77d176a9348..b4faa1c1238 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -24,6 +24,7 @@
#include "rewrite/prs2lock.h"
#include "storage/block.h"
#include "storage/relfilenode.h"
+#include "storage/smgr.h"
#include "utils/relcache.h"
#include "utils/reltrigger.h"
@@ -53,8 +54,7 @@ typedef LockInfoData *LockInfo;
typedef struct RelationData
{
RelFileNode rd_node; /* relation physical identifier */
- /* use "struct" here to avoid needing to include smgr.h: */
- struct SMgrRelationData *rd_smgr; /* cached file handle, or NULL */
+ SMgrRelation rd_smgr; /* cached file handle, or NULL */
int rd_refcnt; /* reference count */
BackendId rd_backend; /* owning backend id, if temporary relation */
bool rd_islocaltemp; /* rel is a temp rel of this session */
@@ -528,14 +528,25 @@ typedef struct ViewOptions
((relation)->rd_rel->relfilenode == InvalidOid))
/*
- * RelationOpenSmgr
- * Open the relation at the smgr level, if not already done.
- */
-#define RelationOpenSmgr(relation) \
- do { \
- if ((relation)->rd_smgr == NULL) \
- smgrsetowner(&((relation)->rd_smgr), smgropen((relation)->rd_node, (relation)->rd_backend)); \
- } while (0)
+ * RelationGetSmgr
+ * Returns smgr file handle for a relation, opening it if needed.
+ *
+ * Very little code is authorized to touch rel->rd_smgr directly. Instead
+ * use this function to fetch its value.
+ *
+ * Note: since a relcache flush can cause the file handle to be closed again,
+ * it's unwise to hold onto the pointer returned by this function for any
+ * long period. Recommended practice is to just re-execute RelationGetSmgr
+ * each time you need to access the SMgrRelation. It's quite cheap in
+ * comparison to whatever an smgr function is going to do.
+ */
+static inline SMgrRelation
+RelationGetSmgr(Relation rel)
+{
+ if (unlikely(rel->rd_smgr == NULL))
+ smgrsetowner(&(rel->rd_smgr), smgropen(rel->rd_node, rel->rd_backend));
+ return rel->rd_smgr;
+}
/*
* RelationCloseSmgr
@@ -557,7 +568,8 @@ typedef struct ViewOptions
* Fetch relation's current insertion target block.
*
* Returns InvalidBlockNumber if there is no current target block. Note
- * that the target block status is discarded on any smgr-level invalidation.
+ * that the target block status is discarded on any smgr-level invalidation,
+ * so there's no need to re-open the smgr handle if it's not currently open.
*/
#define RelationGetTargetBlock(relation) \
( (relation)->rd_smgr != NULL ? (relation)->rd_smgr->smgr_targblock : InvalidBlockNumber )
@@ -568,8 +580,7 @@ typedef struct ViewOptions
*/
#define RelationSetTargetBlock(relation, targblock) \
do { \
- RelationOpenSmgr(relation); \
- (relation)->rd_smgr->smgr_targblock = (targblock); \
+ RelationGetSmgr(relation)->smgr_targblock = (targblock); \
} while (0)
/*