Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * rel.h
4 : * POSTGRES relation descriptor (a/k/a relcache entry) definitions.
5 : *
6 : *
7 : * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
8 : * Portions Copyright (c) 1994, Regents of the University of California
9 : *
10 : * src/include/utils/rel.h
11 : *
12 : *-------------------------------------------------------------------------
13 : */
14 : #ifndef REL_H
15 : #define REL_H
16 :
17 : #include "access/tupdesc.h"
18 : #include "access/xlog.h"
19 : #include "catalog/catalog.h"
20 : #include "catalog/pg_class.h"
21 : #include "catalog/pg_index.h"
22 : #include "catalog/pg_publication.h"
23 : #include "nodes/bitmapset.h"
24 : #include "partitioning/partdefs.h"
25 : #include "rewrite/prs2lock.h"
26 : #include "storage/block.h"
27 : #include "storage/relfilelocator.h"
28 : #include "storage/smgr.h"
29 : #include "utils/relcache.h"
30 : #include "utils/reltrigger.h"
31 :
32 :
33 : /*
34 : * LockRelId and LockInfo really belong to lmgr.h, but it's more convenient
35 : * to declare them here so we can have a LockInfoData field in a Relation.
36 : */
37 :
38 : typedef struct LockRelId
39 : {
40 : Oid relId; /* a relation identifier */
41 : Oid dbId; /* a database identifier */
42 : } LockRelId;
43 :
44 : typedef struct LockInfoData
45 : {
46 : LockRelId lockRelId;
47 : } LockInfoData;
48 :
49 : typedef LockInfoData *LockInfo;
50 :
51 : /*
52 : * Here are the contents of a relation cache entry.
53 : */
54 :
55 : typedef struct RelationData
56 : {
57 : RelFileLocator rd_locator; /* relation physical identifier */
58 : SMgrRelation rd_smgr; /* cached file handle, or NULL */
59 : int rd_refcnt; /* reference count */
60 : ProcNumber rd_backend; /* owning backend's proc number, if temp rel */
61 : bool rd_islocaltemp; /* rel is a temp rel of this session */
62 : bool rd_isnailed; /* rel is nailed in cache */
63 : bool rd_isvalid; /* relcache entry is valid */
64 : bool rd_indexvalid; /* is rd_indexlist valid? (also rd_pkindex and
65 : * rd_replidindex) */
66 : bool rd_statvalid; /* is rd_statlist valid? */
67 :
68 : /*----------
69 : * rd_createSubid is the ID of the highest subtransaction the rel has
70 : * survived into or zero if the rel or its storage was created before the
71 : * current top transaction. (IndexStmt.oldNumber leads to the case of a new
72 : * rel with an old rd_locator.) rd_firstRelfilelocatorSubid is the ID of the
73 : * highest subtransaction an rd_locator change has survived into or zero if
74 : * rd_locator matches the value it had at the start of the current top
75 : * transaction. (Rolling back the subtransaction that
76 : * rd_firstRelfilelocatorSubid denotes would restore rd_locator to the value it
77 : * had at the start of the current top transaction. Rolling back any
78 : * lower subtransaction would not.) Their accuracy is critical to
79 : * RelationNeedsWAL().
80 : *
81 : * rd_newRelfilelocatorSubid is the ID of the highest subtransaction the
82 : * most-recent relfilenumber change has survived into or zero if not changed
83 : * in the current transaction (or we have forgotten changing it). This
84 : * field is accurate when non-zero, but it can be zero when a relation has
85 : * multiple new relfilenumbers within a single transaction, with one of them
86 : * occurring in a subsequently aborted subtransaction, e.g.
87 : * BEGIN;
88 : * TRUNCATE t;
89 : * SAVEPOINT save;
90 : * TRUNCATE t;
91 : * ROLLBACK TO save;
92 : * -- rd_newRelfilelocatorSubid is now forgotten
93 : *
94 : * If every rd_*Subid field is zero, they are read-only outside
95 : * relcache.c. Files that trigger rd_locator changes by updating
96 : * pg_class.reltablespace and/or pg_class.relfilenode call
97 : * RelationAssumeNewRelfilelocator() to update rd_*Subid.
98 : *
99 : * rd_droppedSubid is the ID of the highest subtransaction that a drop of
100 : * the rel has survived into. In entries visible outside relcache.c, this
101 : * is always zero.
102 : */
103 : SubTransactionId rd_createSubid; /* rel was created in current xact */
104 : SubTransactionId rd_newRelfilelocatorSubid; /* highest subxact changing
105 : * rd_locator to current value */
106 : SubTransactionId rd_firstRelfilelocatorSubid; /* highest subxact
107 : * changing rd_locator to
108 : * any value */
109 : SubTransactionId rd_droppedSubid; /* dropped with another Subid set */
110 :
111 : Form_pg_class rd_rel; /* RELATION tuple */
112 : TupleDesc rd_att; /* tuple descriptor */
113 : Oid rd_id; /* relation's object id */
114 : LockInfoData rd_lockInfo; /* lock mgr's info for locking relation */
115 : RuleLock *rd_rules; /* rewrite rules */
116 : MemoryContext rd_rulescxt; /* private memory cxt for rd_rules, if any */
117 : TriggerDesc *trigdesc; /* Trigger info, or NULL if rel has none */
118 : /* use "struct" here to avoid needing to include rowsecurity.h: */
119 : struct RowSecurityDesc *rd_rsdesc; /* row security policies, or NULL */
120 :
121 : /* data managed by RelationGetFKeyList: */
122 : List *rd_fkeylist; /* list of ForeignKeyCacheInfo (see below) */
123 : bool rd_fkeyvalid; /* true if list has been computed */
124 :
125 : /* data managed by RelationGetPartitionKey: */
126 : PartitionKey rd_partkey; /* partition key, or NULL */
127 : MemoryContext rd_partkeycxt; /* private context for rd_partkey, if any */
128 :
129 : /* data managed by RelationGetPartitionDesc: */
130 : PartitionDesc rd_partdesc; /* partition descriptor, or NULL */
131 : MemoryContext rd_pdcxt; /* private context for rd_partdesc, if any */
132 :
133 : /* Same as above, for partdescs that omit detached partitions */
134 : PartitionDesc rd_partdesc_nodetached; /* partdesc w/o detached parts */
135 : MemoryContext rd_pddcxt; /* for rd_partdesc_nodetached, if any */
136 :
137 : /*
138 : * pg_inherits.xmin of the partition that was excluded in
139 : * rd_partdesc_nodetached. This informs a future user of that partdesc:
140 : * if this value is not in progress for the active snapshot, then the
141 : * partdesc can be used, otherwise they have to build a new one. (This
142 : * matches what find_inheritance_children_extended would do).
143 : */
144 : TransactionId rd_partdesc_nodetached_xmin;
145 :
146 : /* data managed by RelationGetPartitionQual: */
147 : List *rd_partcheck; /* partition CHECK quals */
148 : bool rd_partcheckvalid; /* true if list has been computed */
149 : MemoryContext rd_partcheckcxt; /* private cxt for rd_partcheck, if any */
150 :
151 : /* data managed by RelationGetIndexList: */
152 : List *rd_indexlist; /* list of OIDs of indexes on relation */
153 : Oid rd_pkindex; /* OID of (deferrable?) primary key, if any */
154 : bool rd_ispkdeferrable; /* is rd_pkindex a deferrable PK? */
155 : Oid rd_replidindex; /* OID of replica identity index, if any */
156 :
157 : /* data managed by RelationGetStatExtList: */
158 : List *rd_statlist; /* list of OIDs of extended stats */
159 :
160 : /* data managed by RelationGetIndexAttrBitmap: */
161 : bool rd_attrsvalid; /* are bitmaps of attrs valid? */
162 : Bitmapset *rd_keyattr; /* cols that can be ref'd by foreign keys */
163 : Bitmapset *rd_pkattr; /* cols included in primary key */
164 : Bitmapset *rd_idattr; /* included in replica identity index */
165 : Bitmapset *rd_hotblockingattr; /* cols blocking HOT update */
166 : Bitmapset *rd_summarizedattr; /* cols indexed by summarizing indexes */
167 :
168 : PublicationDesc *rd_pubdesc; /* publication descriptor, or NULL */
169 :
170 : /*
171 : * rd_options is set whenever rd_rel is loaded into the relcache entry.
172 : * Note that you can NOT look into rd_rel for this data. NULL means "use
173 : * defaults".
174 : */
175 : bytea *rd_options; /* parsed pg_class.reloptions */
176 :
177 : /*
178 : * Oid of the handler for this relation. For an index this is a function
179 : * returning IndexAmRoutine, for table like relations a function returning
180 : * TableAmRoutine. This is stored separately from rd_indam, rd_tableam as
181 : * its lookup requires syscache access, but during relcache bootstrap we
182 : * need to be able to initialize rd_tableam without syscache lookups.
183 : */
184 : Oid rd_amhandler; /* OID of index AM's handler function */
185 :
186 : /*
187 : * Table access method.
188 : */
189 : const struct TableAmRoutine *rd_tableam;
190 :
191 : /* These are non-NULL only for an index relation: */
192 : Form_pg_index rd_index; /* pg_index tuple describing this index */
193 : /* use "struct" here to avoid needing to include htup.h: */
194 : struct HeapTupleData *rd_indextuple; /* all of pg_index tuple */
195 :
196 : /*
197 : * index access support info (used only for an index relation)
198 : *
199 : * Note: only default support procs for each opclass are cached, namely
200 : * those with lefttype and righttype equal to the opclass's opcintype. The
201 : * arrays are indexed by support function number, which is a sufficient
202 : * identifier given that restriction.
203 : */
204 : MemoryContext rd_indexcxt; /* private memory cxt for this stuff */
205 : /* use "struct" here to avoid needing to include amapi.h: */
206 : struct IndexAmRoutine *rd_indam; /* index AM's API struct */
207 : Oid *rd_opfamily; /* OIDs of op families for each index col */
208 : Oid *rd_opcintype; /* OIDs of opclass declared input data types */
209 : RegProcedure *rd_support; /* OIDs of support procedures */
210 : struct FmgrInfo *rd_supportinfo; /* lookup info for support procedures */
211 : int16 *rd_indoption; /* per-column AM-specific flags */
212 : List *rd_indexprs; /* index expression trees, if any */
213 : List *rd_indpred; /* index predicate tree, if any */
214 : Oid *rd_exclops; /* OIDs of exclusion operators, if any */
215 : Oid *rd_exclprocs; /* OIDs of exclusion ops' procs, if any */
216 : uint16 *rd_exclstrats; /* exclusion ops' strategy numbers, if any */
217 : Oid *rd_indcollation; /* OIDs of index collations */
218 : bytea **rd_opcoptions; /* parsed opclass-specific options */
219 :
220 : /*
221 : * rd_amcache is available for index and table AMs to cache private data
222 : * about the relation. This must be just a cache since it may get reset
223 : * at any time (in particular, it will get reset by a relcache inval
224 : * message for the relation). If used, it must point to a single memory
225 : * chunk palloc'd in CacheMemoryContext, or in rd_indexcxt for an index
226 : * relation. A relcache reset will include freeing that chunk and setting
227 : * rd_amcache = NULL.
228 : */
229 : void *rd_amcache; /* available for use by index/table AM */
230 :
231 : /*
232 : * foreign-table support
233 : *
234 : * rd_fdwroutine must point to a single memory chunk palloc'd in
235 : * CacheMemoryContext. It will be freed and reset to NULL on a relcache
236 : * reset.
237 : */
238 :
239 : /* use "struct" here to avoid needing to include fdwapi.h: */
240 : struct FdwRoutine *rd_fdwroutine; /* cached function pointers, or NULL */
241 :
242 : /*
243 : * Hack for CLUSTER, rewriting ALTER TABLE, etc: when writing a new
244 : * version of a table, we need to make any toast pointers inserted into it
245 : * have the existing toast table's OID, not the OID of the transient toast
246 : * table. If rd_toastoid isn't InvalidOid, it is the OID to place in
247 : * toast pointers inserted into this rel. (Note it's set on the new
248 : * version of the main heap, not the toast table itself.) This also
249 : * causes toast_save_datum() to try to preserve toast value OIDs.
250 : */
251 : Oid rd_toastoid; /* Real TOAST table's OID, or InvalidOid */
252 :
253 : bool pgstat_enabled; /* should relation stats be counted */
254 : /* use "struct" here to avoid needing to include pgstat.h: */
255 : struct PgStat_TableStatus *pgstat_info; /* statistics collection area */
256 : } RelationData;
257 :
258 :
259 : /*
260 : * ForeignKeyCacheInfo
261 : * Information the relcache can cache about foreign key constraints
262 : *
263 : * This is basically just an image of relevant columns from pg_constraint.
264 : * We make it a subclass of Node so that copyObject() can be used on a list
265 : * of these, but we also ensure it is a "flat" object without substructure,
266 : * so that list_free_deep() is sufficient to free such a list.
267 : * The per-FK-column arrays can be fixed-size because we allow at most
268 : * INDEX_MAX_KEYS columns in a foreign key constraint.
269 : *
270 : * Currently, we mostly cache fields of interest to the planner, but the set
271 : * of fields has already grown the constraint OID for other uses.
272 : */
273 : typedef struct ForeignKeyCacheInfo
274 : {
275 : pg_node_attr(no_equal, no_read, no_query_jumble)
276 :
277 : NodeTag type;
278 : /* oid of the constraint itself */
279 : Oid conoid;
280 : /* relation constrained by the foreign key */
281 : Oid conrelid;
282 : /* relation referenced by the foreign key */
283 : Oid confrelid;
284 : /* number of columns in the foreign key */
285 : int nkeys;
286 :
287 : /* Is enforced ? */
288 : bool conenforced;
289 :
290 : /*
291 : * these arrays each have nkeys valid entries:
292 : */
293 : /* cols in referencing table */
294 : AttrNumber conkey[INDEX_MAX_KEYS] pg_node_attr(array_size(nkeys));
295 : /* cols in referenced table */
296 : AttrNumber confkey[INDEX_MAX_KEYS] pg_node_attr(array_size(nkeys));
297 : /* PK = FK operator OIDs */
298 : Oid conpfeqop[INDEX_MAX_KEYS] pg_node_attr(array_size(nkeys));
299 : } ForeignKeyCacheInfo;
300 :
301 :
302 : /*
303 : * StdRdOptions
304 : * Standard contents of rd_options for heaps.
305 : *
306 : * RelationGetFillFactor() and RelationGetTargetPageFreeSpace() can only
307 : * be applied to relations that use this format or a superset for
308 : * private options data.
309 : */
310 : /* autovacuum-related reloptions. */
311 : typedef struct AutoVacOpts
312 : {
313 : bool enabled;
314 : int vacuum_threshold;
315 : int vacuum_max_threshold;
316 : int vacuum_ins_threshold;
317 : int analyze_threshold;
318 : int vacuum_cost_limit;
319 : int freeze_min_age;
320 : int freeze_max_age;
321 : int freeze_table_age;
322 : int multixact_freeze_min_age;
323 : int multixact_freeze_max_age;
324 : int multixact_freeze_table_age;
325 : int log_vacuum_min_duration;
326 : int log_analyze_min_duration;
327 : float8 vacuum_cost_delay;
328 : float8 vacuum_scale_factor;
329 : float8 vacuum_ins_scale_factor;
330 : float8 analyze_scale_factor;
331 : } AutoVacOpts;
332 :
333 : /* StdRdOptions->vacuum_index_cleanup values */
334 : typedef enum StdRdOptIndexCleanup
335 : {
336 : STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO = 0,
337 : STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF,
338 : STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON,
339 : } StdRdOptIndexCleanup;
340 :
341 : typedef struct StdRdOptions
342 : {
343 : int32 vl_len_; /* varlena header (do not touch directly!) */
344 : int fillfactor; /* page fill factor in percent (0..100) */
345 : int toast_tuple_target; /* target for tuple toasting */
346 : AutoVacOpts autovacuum; /* autovacuum-related options */
347 : bool user_catalog_table; /* use as an additional catalog relation */
348 : int parallel_workers; /* max number of parallel workers */
349 : StdRdOptIndexCleanup vacuum_index_cleanup; /* controls index vacuuming */
350 : bool vacuum_truncate; /* enables vacuum to truncate a relation */
351 : bool vacuum_truncate_set; /* whether vacuum_truncate is set */
352 :
353 : /*
354 : * Fraction of pages in a relation that vacuum can eagerly scan and fail
355 : * to freeze. 0 if disabled, -1 if unspecified.
356 : */
357 : double vacuum_max_eager_freeze_failure_rate;
358 : } StdRdOptions;
359 :
360 : #define HEAP_MIN_FILLFACTOR 10
361 : #define HEAP_DEFAULT_FILLFACTOR 100
362 :
363 : /*
364 : * RelationGetToastTupleTarget
365 : * Returns the relation's toast_tuple_target. Note multiple eval of argument!
366 : */
367 : #define RelationGetToastTupleTarget(relation, defaulttarg) \
368 : ((relation)->rd_options ? \
369 : ((StdRdOptions *) (relation)->rd_options)->toast_tuple_target : (defaulttarg))
370 :
371 : /*
372 : * RelationGetFillFactor
373 : * Returns the relation's fillfactor. Note multiple eval of argument!
374 : */
375 : #define RelationGetFillFactor(relation, defaultff) \
376 : ((relation)->rd_options ? \
377 : ((StdRdOptions *) (relation)->rd_options)->fillfactor : (defaultff))
378 :
379 : /*
380 : * RelationGetTargetPageUsage
381 : * Returns the relation's desired space usage per page in bytes.
382 : */
383 : #define RelationGetTargetPageUsage(relation, defaultff) \
384 : (BLCKSZ * RelationGetFillFactor(relation, defaultff) / 100)
385 :
386 : /*
387 : * RelationGetTargetPageFreeSpace
388 : * Returns the relation's desired freespace per page in bytes.
389 : */
390 : #define RelationGetTargetPageFreeSpace(relation, defaultff) \
391 : (BLCKSZ * (100 - RelationGetFillFactor(relation, defaultff)) / 100)
392 :
393 : /*
394 : * RelationIsUsedAsCatalogTable
395 : * Returns whether the relation should be treated as a catalog table
396 : * from the pov of logical decoding. Note multiple eval of argument!
397 : */
398 : #define RelationIsUsedAsCatalogTable(relation) \
399 : ((relation)->rd_options && \
400 : ((relation)->rd_rel->relkind == RELKIND_RELATION || \
401 : (relation)->rd_rel->relkind == RELKIND_MATVIEW) ? \
402 : ((StdRdOptions *) (relation)->rd_options)->user_catalog_table : false)
403 :
404 : /*
405 : * RelationGetParallelWorkers
406 : * Returns the relation's parallel_workers reloption setting.
407 : * Note multiple eval of argument!
408 : */
409 : #define RelationGetParallelWorkers(relation, defaultpw) \
410 : ((relation)->rd_options ? \
411 : ((StdRdOptions *) (relation)->rd_options)->parallel_workers : (defaultpw))
412 :
413 : /* ViewOptions->check_option values */
414 : typedef enum ViewOptCheckOption
415 : {
416 : VIEW_OPTION_CHECK_OPTION_NOT_SET,
417 : VIEW_OPTION_CHECK_OPTION_LOCAL,
418 : VIEW_OPTION_CHECK_OPTION_CASCADED,
419 : } ViewOptCheckOption;
420 :
421 : /*
422 : * ViewOptions
423 : * Contents of rd_options for views
424 : */
425 : typedef struct ViewOptions
426 : {
427 : int32 vl_len_; /* varlena header (do not touch directly!) */
428 : bool security_barrier;
429 : bool security_invoker;
430 : ViewOptCheckOption check_option;
431 : } ViewOptions;
432 :
433 : /*
434 : * RelationIsSecurityView
435 : * Returns whether the relation is security view, or not. Note multiple
436 : * eval of argument!
437 : */
438 : #define RelationIsSecurityView(relation) \
439 : (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW), \
440 : (relation)->rd_options ? \
441 : ((ViewOptions *) (relation)->rd_options)->security_barrier : false)
442 :
443 : /*
444 : * RelationHasSecurityInvoker
445 : * Returns true if the relation has the security_invoker property set.
446 : * Note multiple eval of argument!
447 : */
448 : #define RelationHasSecurityInvoker(relation) \
449 : (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW), \
450 : (relation)->rd_options ? \
451 : ((ViewOptions *) (relation)->rd_options)->security_invoker : false)
452 :
453 : /*
454 : * RelationHasCheckOption
455 : * Returns true if the relation is a view defined with either the local
456 : * or the cascaded check option. Note multiple eval of argument!
457 : */
458 : #define RelationHasCheckOption(relation) \
459 : (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW), \
460 : (relation)->rd_options && \
461 : ((ViewOptions *) (relation)->rd_options)->check_option != \
462 : VIEW_OPTION_CHECK_OPTION_NOT_SET)
463 :
464 : /*
465 : * RelationHasLocalCheckOption
466 : * Returns true if the relation is a view defined with the local check
467 : * option. Note multiple eval of argument!
468 : */
469 : #define RelationHasLocalCheckOption(relation) \
470 : (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW), \
471 : (relation)->rd_options && \
472 : ((ViewOptions *) (relation)->rd_options)->check_option == \
473 : VIEW_OPTION_CHECK_OPTION_LOCAL)
474 :
475 : /*
476 : * RelationHasCascadedCheckOption
477 : * Returns true if the relation is a view defined with the cascaded check
478 : * option. Note multiple eval of argument!
479 : */
480 : #define RelationHasCascadedCheckOption(relation) \
481 : (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW), \
482 : (relation)->rd_options && \
483 : ((ViewOptions *) (relation)->rd_options)->check_option == \
484 : VIEW_OPTION_CHECK_OPTION_CASCADED)
485 :
486 : /*
487 : * RelationIsValid
488 : * True iff relation descriptor is valid.
489 : */
490 : #define RelationIsValid(relation) ((relation) != NULL)
491 :
492 : /*
493 : * RelationHasReferenceCountZero
494 : * True iff relation reference count is zero.
495 : *
496 : * Note:
497 : * Assumes relation descriptor is valid.
498 : */
499 : #define RelationHasReferenceCountZero(relation) \
500 : ((bool)((relation)->rd_refcnt == 0))
501 :
502 : /*
503 : * RelationGetForm
504 : * Returns pg_class tuple for a relation.
505 : *
506 : * Note:
507 : * Assumes relation descriptor is valid.
508 : */
509 : #define RelationGetForm(relation) ((relation)->rd_rel)
510 :
511 : /*
512 : * RelationGetRelid
513 : * Returns the OID of the relation
514 : */
515 : #define RelationGetRelid(relation) ((relation)->rd_id)
516 :
517 : /*
518 : * RelationGetNumberOfAttributes
519 : * Returns the total number of attributes in a relation.
520 : */
521 : #define RelationGetNumberOfAttributes(relation) ((relation)->rd_rel->relnatts)
522 :
523 : /*
524 : * IndexRelationGetNumberOfAttributes
525 : * Returns the number of attributes in an index.
526 : */
527 : #define IndexRelationGetNumberOfAttributes(relation) \
528 : ((relation)->rd_index->indnatts)
529 :
530 : /*
531 : * IndexRelationGetNumberOfKeyAttributes
532 : * Returns the number of key attributes in an index.
533 : */
534 : #define IndexRelationGetNumberOfKeyAttributes(relation) \
535 : ((relation)->rd_index->indnkeyatts)
536 :
537 : /*
538 : * RelationGetDescr
539 : * Returns tuple descriptor for a relation.
540 : */
541 : #define RelationGetDescr(relation) ((relation)->rd_att)
542 :
543 : /*
544 : * RelationGetRelationName
545 : * Returns the rel's name.
546 : *
547 : * Note that the name is only unique within the containing namespace.
548 : */
549 : #define RelationGetRelationName(relation) \
550 : (NameStr((relation)->rd_rel->relname))
551 :
552 : /*
553 : * RelationGetNamespace
554 : * Returns the rel's namespace OID.
555 : */
556 : #define RelationGetNamespace(relation) \
557 : ((relation)->rd_rel->relnamespace)
558 :
559 : /*
560 : * RelationIsMapped
561 : * True if the relation uses the relfilenumber map. Note multiple eval
562 : * of argument!
563 : */
564 : #define RelationIsMapped(relation) \
565 : (RELKIND_HAS_STORAGE((relation)->rd_rel->relkind) && \
566 : ((relation)->rd_rel->relfilenode == InvalidRelFileNumber))
567 :
568 : #ifndef FRONTEND
569 : /*
570 : * RelationGetSmgr
571 : * Returns smgr file handle for a relation, opening it if needed.
572 : *
573 : * Very little code is authorized to touch rel->rd_smgr directly. Instead
574 : * use this function to fetch its value.
575 : */
576 : static inline SMgrRelation
577 133263208 : RelationGetSmgr(Relation rel)
578 : {
579 133263208 : if (unlikely(rel->rd_smgr == NULL))
580 : {
581 2136832 : rel->rd_smgr = smgropen(rel->rd_locator, rel->rd_backend);
582 2136832 : smgrpin(rel->rd_smgr);
583 : }
584 133263208 : return rel->rd_smgr;
585 : }
586 :
587 : /*
588 : * RelationCloseSmgr
589 : * Close the relation at the smgr level, if not already done.
590 : */
591 : static inline void
592 3031498 : RelationCloseSmgr(Relation relation)
593 : {
594 3031498 : if (relation->rd_smgr != NULL)
595 : {
596 445304 : smgrunpin(relation->rd_smgr);
597 445304 : smgrclose(relation->rd_smgr);
598 445304 : relation->rd_smgr = NULL;
599 : }
600 3031498 : }
601 : #endif /* !FRONTEND */
602 :
603 : /*
604 : * RelationGetTargetBlock
605 : * Fetch relation's current insertion target block.
606 : *
607 : * Returns InvalidBlockNumber if there is no current target block. Note
608 : * that the target block status is discarded on any smgr-level invalidation,
609 : * so there's no need to re-open the smgr handle if it's not currently open.
610 : */
611 : #define RelationGetTargetBlock(relation) \
612 : ( (relation)->rd_smgr != NULL ? (relation)->rd_smgr->smgr_targblock : InvalidBlockNumber )
613 :
614 : /*
615 : * RelationSetTargetBlock
616 : * Set relation's current insertion target block.
617 : */
618 : #define RelationSetTargetBlock(relation, targblock) \
619 : do { \
620 : RelationGetSmgr(relation)->smgr_targblock = (targblock); \
621 : } while (0)
622 :
623 : /*
624 : * RelationIsPermanent
625 : * True if relation is permanent.
626 : */
627 : #define RelationIsPermanent(relation) \
628 : ((relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
629 :
630 : /*
631 : * RelationNeedsWAL
632 : * True if relation needs WAL.
633 : *
634 : * Returns false if wal_level = minimal and this relation is created or
635 : * truncated in the current transaction. See "Skipping WAL for New
636 : * RelFileLocator" in src/backend/access/transam/README.
637 : */
638 : #define RelationNeedsWAL(relation) \
639 : (RelationIsPermanent(relation) && (XLogIsNeeded() || \
640 : (relation->rd_createSubid == InvalidSubTransactionId && \
641 : relation->rd_firstRelfilelocatorSubid == InvalidSubTransactionId)))
642 :
643 : /*
644 : * RelationUsesLocalBuffers
645 : * True if relation's pages are stored in local buffers.
646 : */
647 : #define RelationUsesLocalBuffers(relation) \
648 : ((relation)->rd_rel->relpersistence == RELPERSISTENCE_TEMP)
649 :
650 : /*
651 : * RELATION_IS_LOCAL
652 : * If a rel is either temp or newly created in the current transaction,
653 : * it can be assumed to be accessible only to the current backend.
654 : * This is typically used to decide that we can skip acquiring locks.
655 : *
656 : * Beware of multiple eval of argument
657 : */
658 : #define RELATION_IS_LOCAL(relation) \
659 : ((relation)->rd_islocaltemp || \
660 : (relation)->rd_createSubid != InvalidSubTransactionId)
661 :
662 : /*
663 : * RELATION_IS_OTHER_TEMP
664 : * Test for a temporary relation that belongs to some other session.
665 : *
666 : * Beware of multiple eval of argument
667 : */
668 : #define RELATION_IS_OTHER_TEMP(relation) \
669 : ((relation)->rd_rel->relpersistence == RELPERSISTENCE_TEMP && \
670 : !(relation)->rd_islocaltemp)
671 :
672 :
673 : /*
674 : * RelationIsScannable
675 : * Currently can only be false for a materialized view which has not been
676 : * populated by its query. This is likely to get more complicated later,
677 : * so use a macro which looks like a function.
678 : */
679 : #define RelationIsScannable(relation) ((relation)->rd_rel->relispopulated)
680 :
681 : /*
682 : * RelationIsPopulated
683 : * Currently, we don't physically distinguish the "populated" and
684 : * "scannable" properties of matviews, but that may change later.
685 : * Hence, use the appropriate one of these macros in code tests.
686 : */
687 : #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
688 :
689 : /*
690 : * RelationIsAccessibleInLogicalDecoding
691 : * True if we need to log enough information to have access via
692 : * decoding snapshot.
693 : */
694 : #define RelationIsAccessibleInLogicalDecoding(relation) \
695 : (XLogLogicalInfoActive() && \
696 : RelationNeedsWAL(relation) && \
697 : (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation)))
698 :
699 : /*
700 : * RelationIsLogicallyLogged
701 : * True if we need to log enough information to extract the data from the
702 : * WAL stream.
703 : *
704 : * We don't log information for unlogged tables (since they don't WAL log
705 : * anyway), for foreign tables (since they don't WAL log, either),
706 : * and for system tables (their content is hard to make sense of, and
707 : * it would complicate decoding slightly for little gain). Note that we *do*
708 : * log information for user defined catalog tables since they presumably are
709 : * interesting to the user...
710 : */
711 : #define RelationIsLogicallyLogged(relation) \
712 : (XLogLogicalInfoActive() && \
713 : RelationNeedsWAL(relation) && \
714 : (relation)->rd_rel->relkind != RELKIND_FOREIGN_TABLE && \
715 : !IsCatalogRelation(relation))
716 :
717 : /* routines in utils/cache/relcache.c */
718 : extern void RelationIncrementReferenceCount(Relation rel);
719 : extern void RelationDecrementReferenceCount(Relation rel);
720 :
721 : #endif /* REL_H */
|