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