Age Owner Branch data TLA 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-2026, 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 : : const 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 : : /*
254 : : * Type OID of the "chunk_id" column of this relation's TOAST table, i.e.
255 : : * OIDOID or OID8OID.
256 : : *
257 : : * This data is filled on demand by RelationGetToastChunkIdType(), not at
258 : : * relcache build time, so as to save on syscache lookups.
259 : : */
260 : : Oid rd_toastchunkidtype;
261 : :
262 : : bool pgstat_enabled; /* should relation stats be counted */
263 : : /* use "struct" here to avoid needing to include pgstat.h: */
264 : : struct PgStat_RelationStatus *pgstat_info; /* statistics collection area */
265 : : } RelationData;
266 : :
267 : :
268 : : /*
269 : : * ForeignKeyCacheInfo
270 : : * Information the relcache can cache about foreign key constraints
271 : : *
272 : : * This is basically just an image of relevant columns from pg_constraint.
273 : : * We make it a subclass of Node so that copyObject() can be used on a list
274 : : * of these, but we also ensure it is a "flat" object without substructure,
275 : : * so that list_free_deep() is sufficient to free such a list.
276 : : * The per-FK-column arrays can be fixed-size because we allow at most
277 : : * INDEX_MAX_KEYS columns in a foreign key constraint.
278 : : *
279 : : * Currently, we mostly cache fields of interest to the planner, but the set
280 : : * of fields has already grown the constraint OID for other uses.
281 : : */
282 : : typedef struct ForeignKeyCacheInfo
283 : : {
284 : : pg_node_attr(no_equal, no_read, no_query_jumble)
285 : :
286 : : NodeTag type;
287 : : /* oid of the constraint itself */
288 : : Oid conoid;
289 : : /* relation constrained by the foreign key */
290 : : Oid conrelid;
291 : : /* relation referenced by the foreign key */
292 : : Oid confrelid;
293 : : /* number of columns in the foreign key */
294 : : int nkeys;
295 : :
296 : : /* Is enforced ? */
297 : : bool conenforced;
298 : :
299 : : /*
300 : : * these arrays each have nkeys valid entries:
301 : : */
302 : : /* cols in referencing table */
303 : : AttrNumber conkey[INDEX_MAX_KEYS] pg_node_attr(array_size(nkeys));
304 : : /* cols in referenced table */
305 : : AttrNumber confkey[INDEX_MAX_KEYS] pg_node_attr(array_size(nkeys));
306 : : /* PK = FK operator OIDs */
307 : : Oid conpfeqop[INDEX_MAX_KEYS] pg_node_attr(array_size(nkeys));
308 : : } ForeignKeyCacheInfo;
309 : :
310 : :
311 : : /*
312 : : * StdRdOptions
313 : : * Standard contents of rd_options for heaps.
314 : : *
315 : : * RelationGetFillFactor() and RelationGetTargetPageFreeSpace() can only
316 : : * be applied to relations that use this format or a superset for
317 : : * private options data.
318 : : */
319 : : /* autovacuum-related reloptions. */
320 : : typedef struct AutoVacOpts
321 : : {
322 : : pg_ternary enabled;
323 : :
324 : : int autovacuum_parallel_workers;
325 : : int vacuum_threshold;
326 : : int vacuum_max_threshold;
327 : : int vacuum_ins_threshold;
328 : : int analyze_threshold;
329 : : int vacuum_cost_limit;
330 : : int freeze_min_age;
331 : : int freeze_max_age;
332 : : int freeze_table_age;
333 : : int multixact_freeze_min_age;
334 : : int multixact_freeze_max_age;
335 : : int multixact_freeze_table_age;
336 : : int log_vacuum_min_duration;
337 : : int log_analyze_min_duration;
338 : : float8 vacuum_cost_delay;
339 : : float8 vacuum_scale_factor;
340 : : float8 vacuum_ins_scale_factor;
341 : : float8 analyze_scale_factor;
342 : : } AutoVacOpts;
343 : :
344 : : /* StdRdOptions->vacuum_index_cleanup values */
345 : : typedef enum StdRdOptIndexCleanup
346 : : {
347 : : STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO = 0,
348 : : STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF,
349 : : STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON,
350 : : STDRD_OPTION_VACUUM_INDEX_CLEANUP_NOT_SET,
351 : : } StdRdOptIndexCleanup;
352 : :
353 : : /* StdRdOptions->toast_value_type values */
354 : : typedef enum StdRdOptToastValueType
355 : : {
356 : : STDRD_OPTION_TOAST_VALUE_TYPE_INVALID = 0,
357 : : STDRD_OPTION_TOAST_VALUE_TYPE_OID,
358 : : STDRD_OPTION_TOAST_VALUE_TYPE_OID8,
359 : : } StdRdOptToastValueType;
360 : :
361 : : typedef struct StdRdOptions
362 : : {
363 : : int32 vl_len_; /* varlena header (do not touch directly!) */
364 : : int fillfactor; /* page fill factor in percent (0..100) */
365 : : int toast_tuple_target; /* target for tuple toasting */
366 : : StdRdOptToastValueType toast_value_type; /* type assigned to chunk_id
367 : : * at toast table creation */
368 : : AutoVacOpts autovacuum; /* autovacuum-related options */
369 : : bool user_catalog_table; /* use as an additional catalog relation */
370 : : int parallel_workers; /* max number of parallel workers */
371 : : StdRdOptIndexCleanup vacuum_index_cleanup; /* controls index vacuuming */
372 : : pg_ternary vacuum_truncate; /* enables vacuum to truncate a relation */
373 : :
374 : : /*
375 : : * Fraction of pages in a relation that vacuum can eagerly scan and fail
376 : : * to freeze. 0 if disabled, -1 if unspecified.
377 : : */
378 : : double vacuum_max_eager_freeze_failure_rate;
379 : : } StdRdOptions;
380 : :
381 : : #define HEAP_MIN_FILLFACTOR 10
382 : : #define HEAP_DEFAULT_FILLFACTOR 100
383 : :
384 : : /*
385 : : * RelationGetToastTupleTarget
386 : : * Returns the relation's toast_tuple_target. Note multiple eval of argument!
387 : : */
388 : : #define RelationGetToastTupleTarget(relation, defaulttarg) \
389 : : ((relation)->rd_options ? \
390 : : ((StdRdOptions *) (relation)->rd_options)->toast_tuple_target : (defaulttarg))
391 : :
392 : : /*
393 : : * RelationGetToastValueType
394 : : * Returns the relation's toast_value_type. Note multiple eval of argument!
395 : : */
396 : : #define RelationGetToastValueType(relation, defaulttarg) \
397 : : ((relation)->rd_options ? \
398 : : ((StdRdOptions *) (relation)->rd_options)->toast_value_type : (defaulttarg))
399 : :
400 : : /*
401 : : * RelationGetFillFactor
402 : : * Returns the relation's fillfactor. Note multiple eval of argument!
403 : : */
404 : : #define RelationGetFillFactor(relation, defaultff) \
405 : : ((relation)->rd_options ? \
406 : : ((StdRdOptions *) (relation)->rd_options)->fillfactor : (defaultff))
407 : :
408 : : /*
409 : : * RelationGetTargetPageUsage
410 : : * Returns the relation's desired space usage per page in bytes.
411 : : */
412 : : #define RelationGetTargetPageUsage(relation, defaultff) \
413 : : (BLCKSZ * RelationGetFillFactor(relation, defaultff) / 100)
414 : :
415 : : /*
416 : : * RelationGetTargetPageFreeSpace
417 : : * Returns the relation's desired freespace per page in bytes.
418 : : */
419 : : #define RelationGetTargetPageFreeSpace(relation, defaultff) \
420 : : (BLCKSZ * (100 - RelationGetFillFactor(relation, defaultff)) / 100)
421 : :
422 : : /*
423 : : * RelationIsUsedAsCatalogTable
424 : : * Returns whether the relation should be treated as a catalog table
425 : : * from the pov of logical decoding. Note multiple eval of argument!
426 : : */
427 : : #define RelationIsUsedAsCatalogTable(relation) \
428 : : ((relation)->rd_options && \
429 : : ((relation)->rd_rel->relkind == RELKIND_RELATION || \
430 : : (relation)->rd_rel->relkind == RELKIND_MATVIEW) ? \
431 : : ((StdRdOptions *) (relation)->rd_options)->user_catalog_table : false)
432 : :
433 : : /*
434 : : * RelationGetParallelWorkers
435 : : * Returns the relation's parallel_workers reloption setting.
436 : : * Note multiple eval of argument!
437 : : */
438 : : #define RelationGetParallelWorkers(relation, defaultpw) \
439 : : ((relation)->rd_options ? \
440 : : ((StdRdOptions *) (relation)->rd_options)->parallel_workers : (defaultpw))
441 : :
442 : : /* ViewOptions->check_option values */
443 : : typedef enum ViewOptCheckOption
444 : : {
445 : : VIEW_OPTION_CHECK_OPTION_NOT_SET,
446 : : VIEW_OPTION_CHECK_OPTION_LOCAL,
447 : : VIEW_OPTION_CHECK_OPTION_CASCADED,
448 : : } ViewOptCheckOption;
449 : :
450 : : /*
451 : : * ViewOptions
452 : : * Contents of rd_options for views
453 : : */
454 : : typedef struct ViewOptions
455 : : {
456 : : int32 vl_len_; /* varlena header (do not touch directly!) */
457 : : bool security_barrier;
458 : : bool security_invoker;
459 : : ViewOptCheckOption check_option;
460 : : } ViewOptions;
461 : :
462 : : /*
463 : : * RelationIsSecurityView
464 : : * Returns whether the relation is security view, or not. Note multiple
465 : : * eval of argument!
466 : : */
467 : : #define RelationIsSecurityView(relation) \
468 : : (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW), \
469 : : (relation)->rd_options ? \
470 : : ((ViewOptions *) (relation)->rd_options)->security_barrier : false)
471 : :
472 : : /*
473 : : * RelationHasSecurityInvoker
474 : : * Returns true if the relation has the security_invoker property set.
475 : : * Note multiple eval of argument!
476 : : */
477 : : #define RelationHasSecurityInvoker(relation) \
478 : : (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW), \
479 : : (relation)->rd_options ? \
480 : : ((ViewOptions *) (relation)->rd_options)->security_invoker : false)
481 : :
482 : : /*
483 : : * RelationHasCheckOption
484 : : * Returns true if the relation is a view defined with either the local
485 : : * or the cascaded check option. Note multiple eval of argument!
486 : : */
487 : : #define RelationHasCheckOption(relation) \
488 : : (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW), \
489 : : (relation)->rd_options && \
490 : : ((ViewOptions *) (relation)->rd_options)->check_option != \
491 : : VIEW_OPTION_CHECK_OPTION_NOT_SET)
492 : :
493 : : /*
494 : : * RelationHasLocalCheckOption
495 : : * Returns true if the relation is a view defined with the local check
496 : : * option. Note multiple eval of argument!
497 : : */
498 : : #define RelationHasLocalCheckOption(relation) \
499 : : (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW), \
500 : : (relation)->rd_options && \
501 : : ((ViewOptions *) (relation)->rd_options)->check_option == \
502 : : VIEW_OPTION_CHECK_OPTION_LOCAL)
503 : :
504 : : /*
505 : : * RelationHasCascadedCheckOption
506 : : * Returns true if the relation is a view defined with the cascaded check
507 : : * option. Note multiple eval of argument!
508 : : */
509 : : #define RelationHasCascadedCheckOption(relation) \
510 : : (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW), \
511 : : (relation)->rd_options && \
512 : : ((ViewOptions *) (relation)->rd_options)->check_option == \
513 : : VIEW_OPTION_CHECK_OPTION_CASCADED)
514 : :
515 : : /*
516 : : * RelationIsValid
517 : : * True iff relation descriptor is valid.
518 : : */
519 : : #define RelationIsValid(relation) ((relation) != NULL)
520 : :
521 : : /*
522 : : * RelationHasReferenceCountZero
523 : : * True iff relation reference count is zero.
524 : : *
525 : : * Note:
526 : : * Assumes relation descriptor is valid.
527 : : */
528 : : #define RelationHasReferenceCountZero(relation) \
529 : : ((bool)((relation)->rd_refcnt == 0))
530 : :
531 : : /*
532 : : * RelationGetForm
533 : : * Returns pg_class tuple for a relation.
534 : : *
535 : : * Note:
536 : : * Assumes relation descriptor is valid.
537 : : */
538 : : #define RelationGetForm(relation) ((relation)->rd_rel)
539 : :
540 : : /*
541 : : * RelationGetRelid
542 : : * Returns the OID of the relation
543 : : */
544 : : #define RelationGetRelid(relation) ((relation)->rd_id)
545 : :
546 : : /*
547 : : * RelationGetNumberOfAttributes
548 : : * Returns the total number of attributes in a relation.
549 : : */
550 : : #define RelationGetNumberOfAttributes(relation) ((relation)->rd_rel->relnatts)
551 : :
552 : : /*
553 : : * IndexRelationGetNumberOfAttributes
554 : : * Returns the number of attributes in an index.
555 : : */
556 : : #define IndexRelationGetNumberOfAttributes(relation) \
557 : : ((relation)->rd_index->indnatts)
558 : :
559 : : /*
560 : : * IndexRelationGetNumberOfKeyAttributes
561 : : * Returns the number of key attributes in an index.
562 : : */
563 : : #define IndexRelationGetNumberOfKeyAttributes(relation) \
564 : : ((relation)->rd_index->indnkeyatts)
565 : :
566 : : /*
567 : : * RelationGetDescr
568 : : * Returns tuple descriptor for a relation.
569 : : */
570 : : #define RelationGetDescr(relation) ((relation)->rd_att)
571 : :
572 : : /*
573 : : * RelationGetRelationName
574 : : * Returns the rel's name.
575 : : *
576 : : * Note that the name is only unique within the containing namespace.
577 : : */
578 : : #define RelationGetRelationName(relation) \
579 : : (NameStr((relation)->rd_rel->relname))
580 : :
581 : : /*
582 : : * RelationGetNamespace
583 : : * Returns the rel's namespace OID.
584 : : */
585 : : #define RelationGetNamespace(relation) \
586 : : ((relation)->rd_rel->relnamespace)
587 : :
588 : : /*
589 : : * RelationIsMapped
590 : : * True if the relation uses the relfilenumber map. Note multiple eval
591 : : * of argument!
592 : : */
593 : : #define RelationIsMapped(relation) \
594 : : (RELKIND_HAS_STORAGE((relation)->rd_rel->relkind) && \
595 : : ((relation)->rd_rel->relfilenode == InvalidRelFileNumber))
596 : :
597 : : #ifndef FRONTEND
598 : : /*
599 : : * RelationGetSmgr
600 : : * Returns smgr file handle for a relation, opening it if needed.
601 : : *
602 : : * Very little code is authorized to touch rel->rd_smgr directly. Instead
603 : : * use this function to fetch its value.
604 : : */
605 : : static inline SMgrRelation
1896 tgl@sss.pgh.pa.us 606 :CBC 91771058 : RelationGetSmgr(Relation rel)
607 : : {
608 [ + + ]: 91771058 : if (unlikely(rel->rd_smgr == NULL))
609 : : {
963 heikki.linnakangas@i 610 : 987751 : rel->rd_smgr = smgropen(rel->rd_locator, rel->rd_backend);
611 : 987751 : smgrpin(rel->rd_smgr);
612 : : }
1896 tgl@sss.pgh.pa.us 613 : 91771058 : return rel->rd_smgr;
614 : : }
615 : :
616 : : /*
617 : : * RelationCloseSmgr
618 : : * Close the relation at the smgr level, if not already done.
619 : : */
620 : : static inline void
1444 peter@eisentraut.org 621 : 1923996 : RelationCloseSmgr(Relation relation)
622 : : {
623 [ + + ]: 1923996 : if (relation->rd_smgr != NULL)
624 : : {
963 heikki.linnakangas@i 625 : 258478 : smgrunpin(relation->rd_smgr);
1444 peter@eisentraut.org 626 : 258478 : smgrclose(relation->rd_smgr);
963 heikki.linnakangas@i 627 : 258478 : relation->rd_smgr = NULL;
628 : : }
1444 peter@eisentraut.org 629 : 1923996 : }
630 : : #endif /* !FRONTEND */
631 : :
632 : : /*
633 : : * RelationGetTargetBlock
634 : : * Fetch relation's current insertion target block.
635 : : *
636 : : * Returns InvalidBlockNumber if there is no current target block. Note
637 : : * that the target block status is discarded on any smgr-level invalidation,
638 : : * so there's no need to re-open the smgr handle if it's not currently open.
639 : : */
640 : : #define RelationGetTargetBlock(relation) \
641 : : ( (relation)->rd_smgr != NULL ? (relation)->rd_smgr->smgr_targblock : InvalidBlockNumber )
642 : :
643 : : /*
644 : : * RelationSetTargetBlock
645 : : * Set relation's current insertion target block.
646 : : */
647 : : #define RelationSetTargetBlock(relation, targblock) \
648 : : do { \
649 : : RelationGetSmgr(relation)->smgr_targblock = (targblock); \
650 : : } while (0)
651 : :
652 : : /*
653 : : * RelationIsPermanent
654 : : * True if relation is permanent.
655 : : */
656 : : #define RelationIsPermanent(relation) \
657 : : ((relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT)
658 : :
659 : : /*
660 : : * RelationNeedsWAL
661 : : * True if relation needs WAL.
662 : : *
663 : : * Returns false if wal_level = minimal and this relation is created or
664 : : * truncated in the current transaction. See "Skipping WAL for New
665 : : * RelFileLocator" in src/backend/access/transam/README.
666 : : */
667 : : #define RelationNeedsWAL(relation) \
668 : : (RelationIsPermanent(relation) && (XLogIsNeeded() || \
669 : : (relation->rd_createSubid == InvalidSubTransactionId && \
670 : : relation->rd_firstRelfilelocatorSubid == InvalidSubTransactionId)))
671 : :
672 : : /*
673 : : * RelationUsesLocalBuffers
674 : : * True if relation's pages are stored in local buffers.
675 : : */
676 : : #define RelationUsesLocalBuffers(relation) \
677 : : ((relation)->rd_rel->relpersistence == RELPERSISTENCE_TEMP)
678 : :
679 : : /*
680 : : * RELATION_IS_LOCAL
681 : : * If a rel is either temp or newly created in the current transaction,
682 : : * it can be assumed to be accessible only to the current backend.
683 : : * This is typically used to decide that we can skip acquiring locks.
684 : : *
685 : : * Beware of multiple eval of argument
686 : : */
687 : : #define RELATION_IS_LOCAL(relation) \
688 : : ((relation)->rd_islocaltemp || \
689 : : (relation)->rd_createSubid != InvalidSubTransactionId)
690 : :
691 : : /*
692 : : * RELATION_IS_OTHER_TEMP
693 : : * Test for a temporary relation that belongs to some other session.
694 : : *
695 : : * Reading another session's temp-table data through never works right:
696 : : * the owning session keeps the data in its private local buffer pool,
697 : : * which we cannot access. Existing buffer-manager entry points
698 : : * (ReadBuffer_common(), StartReadBuffersImpl(), read_stream_begin_impl(),
699 : : * PrefetchBuffer() and ExtendBufferedRelCommon()) already enforce this; any
700 : : * new buffer-access entry points must do the same. Command-level code
701 : : * (TRUNCATE, ALTER TABLE, VACUUM, CLUSTER, REINDEX, ...) additionally uses
702 : : * this macro for command-specific error messages.
703 : : *
704 : : * Beware of multiple eval of argument
705 : : */
706 : : #define RELATION_IS_OTHER_TEMP(relation) \
707 : : ((relation)->rd_rel->relpersistence == RELPERSISTENCE_TEMP && \
708 : : !(relation)->rd_islocaltemp)
709 : :
710 : :
711 : : /*
712 : : * RelationIsScannable
713 : : * Currently can only be false for a materialized view which has not been
714 : : * populated by its query. This is likely to get more complicated later,
715 : : * so use a macro which looks like a function.
716 : : */
717 : : #define RelationIsScannable(relation) ((relation)->rd_rel->relispopulated)
718 : :
719 : : /*
720 : : * RelationIsPopulated
721 : : * Currently, we don't physically distinguish the "populated" and
722 : : * "scannable" properties of matviews, but that may change later.
723 : : * Hence, use the appropriate one of these macros in code tests.
724 : : */
725 : : #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated)
726 : :
727 : : /*
728 : : * RelationIsAccessibleInLogicalDecoding
729 : : * True if we need to log enough information to have access via
730 : : * decoding snapshot.
731 : : */
732 : : #define RelationIsAccessibleInLogicalDecoding(relation) \
733 : : (XLogLogicalInfoActive() && \
734 : : RelationNeedsWAL(relation) && \
735 : : (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation)))
736 : :
737 : : /*
738 : : * RelationIsLogicallyLogged
739 : : * True if we need to log enough information to extract the data from the
740 : : * WAL stream.
741 : : *
742 : : * We don't log information for unlogged tables (since they don't WAL log
743 : : * anyway), for foreign tables (since they don't WAL log, either),
744 : : * and for system tables (their content is hard to make sense of, and
745 : : * it would complicate decoding slightly for little gain). Note that we *do*
746 : : * log information for user defined catalog tables since they presumably are
747 : : * interesting to the user...
748 : : */
749 : : #define RelationIsLogicallyLogged(relation) \
750 : : (XLogLogicalInfoActive() && \
751 : : RelationNeedsWAL(relation) && \
752 : : (relation)->rd_rel->relkind != RELKIND_FOREIGN_TABLE && \
753 : : !IsCatalogRelation(relation))
754 : :
755 : : /* routines in utils/cache/relcache.c */
756 : : extern void RelationIncrementReferenceCount(Relation rel);
757 : : extern void RelationDecrementReferenceCount(Relation rel);
758 : :
759 : : #endif /* REL_H */
|