1 /*------------------------------------------------------------------------- 2 * 3 * rel.h 4 * POSTGRES relation descriptor (a/k/a relcache entry) definitions. 5 * 6 * 7 * Portions Copyright (c) 1996-2020, 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 /* data managed by RelationGetPartitionQual: */ 132 List *rd_partcheck; /* partition CHECK quals */ 133 bool rd_partcheckvalid; /* true if list has been computed */ 134 MemoryContext rd_partcheckcxt; /* private cxt for rd_partcheck, if any */ 135 136 /* data managed by RelationGetIndexList: */ 137 List *rd_indexlist; /* list of OIDs of indexes on relation */ 138 Oid rd_pkindex; /* OID of primary key, if any */ 139 Oid rd_replidindex; /* OID of replica identity index, if any */ 140 141 /* data managed by RelationGetStatExtList: */ 142 List *rd_statlist; /* list of OIDs of extended stats */ 143 144 /* data managed by RelationGetIndexAttrBitmap: */ 145 Bitmapset *rd_indexattr; /* identifies columns used in indexes */ 146 Bitmapset *rd_keyattr; /* cols that can be ref'd by foreign keys */ 147 Bitmapset *rd_pkattr; /* cols included in primary key */ 148 Bitmapset *rd_idattr; /* included in replica identity index */ 149 150 PublicationActions *rd_pubactions; /* publication actions */ 151 152 /* 153 * rd_options is set whenever rd_rel is loaded into the relcache entry. 154 * Note that you can NOT look into rd_rel for this data. NULL means "use 155 * defaults". 156 */ 157 bytea *rd_options; /* parsed pg_class.reloptions */ 158 159 /* 160 * Oid of the handler for this relation. For an index this is a function 161 * returning IndexAmRoutine, for table like relations a function returning 162 * TableAmRoutine. This is stored separately from rd_indam, rd_tableam as 163 * its lookup requires syscache access, but during relcache bootstrap we 164 * need to be able to initialize rd_tableam without syscache lookups. 165 */ 166 Oid rd_amhandler; /* OID of index AM's handler function */ 167 168 /* 169 * Table access method. 170 */ 171 const struct TableAmRoutine *rd_tableam; 172 173 /* These are non-NULL only for an index relation: */ 174 Form_pg_index rd_index; /* pg_index tuple describing this index */ 175 /* use "struct" here to avoid needing to include htup.h: */ 176 struct HeapTupleData *rd_indextuple; /* all of pg_index tuple */ 177 178 /* 179 * index access support info (used only for an index relation) 180 * 181 * Note: only default support procs for each opclass are cached, namely 182 * those with lefttype and righttype equal to the opclass's opcintype. The 183 * arrays are indexed by support function number, which is a sufficient 184 * identifier given that restriction. 185 */ 186 MemoryContext rd_indexcxt; /* private memory cxt for this stuff */ 187 /* use "struct" here to avoid needing to include amapi.h: */ 188 struct IndexAmRoutine *rd_indam; /* index AM's API struct */ 189 Oid *rd_opfamily; /* OIDs of op families for each index col */ 190 Oid *rd_opcintype; /* OIDs of opclass declared input data types */ 191 RegProcedure *rd_support; /* OIDs of support procedures */ 192 struct FmgrInfo *rd_supportinfo; /* lookup info for support procedures */ 193 int16 *rd_indoption; /* per-column AM-specific flags */ 194 List *rd_indexprs; /* index expression trees, if any */ 195 List *rd_indpred; /* index predicate tree, if any */ 196 Oid *rd_exclops; /* OIDs of exclusion operators, if any */ 197 Oid *rd_exclprocs; /* OIDs of exclusion ops' procs, if any */ 198 uint16 *rd_exclstrats; /* exclusion ops' strategy numbers, if any */ 199 Oid *rd_indcollation; /* OIDs of index collations */ 200 bytea **rd_opcoptions; /* parsed opclass-specific options */ 201 202 /* 203 * rd_amcache is available for index and table AMs to cache private data 204 * about the relation. This must be just a cache since it may get reset 205 * at any time (in particular, it will get reset by a relcache inval 206 * message for the relation). If used, it must point to a single memory 207 * chunk palloc'd in CacheMemoryContext, or in rd_indexcxt for an index 208 * relation. A relcache reset will include freeing that chunk and setting 209 * rd_amcache = NULL. 210 */ 211 void *rd_amcache; /* available for use by index/table AM */ 212 213 /* 214 * foreign-table support 215 * 216 * rd_fdwroutine must point to a single memory chunk palloc'd in 217 * CacheMemoryContext. It will be freed and reset to NULL on a relcache 218 * reset. 219 */ 220 221 /* use "struct" here to avoid needing to include fdwapi.h: */ 222 struct FdwRoutine *rd_fdwroutine; /* cached function pointers, or NULL */ 223 224 /* 225 * Hack for CLUSTER, rewriting ALTER TABLE, etc: when writing a new 226 * version of a table, we need to make any toast pointers inserted into it 227 * have the existing toast table's OID, not the OID of the transient toast 228 * table. If rd_toastoid isn't InvalidOid, it is the OID to place in 229 * toast pointers inserted into this rel. (Note it's set on the new 230 * version of the main heap, not the toast table itself.) This also 231 * causes toast_save_datum() to try to preserve toast value OIDs. 232 */ 233 Oid rd_toastoid; /* Real TOAST table's OID, or InvalidOid */ 234 235 /* use "struct" here to avoid needing to include pgstat.h: */ 236 struct PgStat_TableStatus *pgstat_info; /* statistics collection area */ 237 } RelationData; 238 239 240 /* 241 * ForeignKeyCacheInfo 242 * Information the relcache can cache about foreign key constraints 243 * 244 * This is basically just an image of relevant columns from pg_constraint. 245 * We make it a subclass of Node so that copyObject() can be used on a list 246 * of these, but we also ensure it is a "flat" object without substructure, 247 * so that list_free_deep() is sufficient to free such a list. 248 * The per-FK-column arrays can be fixed-size because we allow at most 249 * INDEX_MAX_KEYS columns in a foreign key constraint. 250 * 251 * Currently, we mostly cache fields of interest to the planner, but the set 252 * of fields has already grown the constraint OID for other uses. 253 */ 254 typedef struct ForeignKeyCacheInfo 255 { 256 NodeTag type; 257 Oid conoid; /* oid of the constraint itself */ 258 Oid conrelid; /* relation constrained by the foreign key */ 259 Oid confrelid; /* relation referenced by the foreign key */ 260 int nkeys; /* number of columns in the foreign key */ 261 /* these arrays each have nkeys valid entries: */ 262 AttrNumber conkey[INDEX_MAX_KEYS]; /* cols in referencing table */ 263 AttrNumber confkey[INDEX_MAX_KEYS]; /* cols in referenced table */ 264 Oid conpfeqop[INDEX_MAX_KEYS]; /* PK = FK operator OIDs */ 265 } ForeignKeyCacheInfo; 266 267 268 /* 269 * StdRdOptions 270 * Standard contents of rd_options for heaps. 271 * 272 * RelationGetFillFactor() and RelationGetTargetPageFreeSpace() can only 273 * be applied to relations that use this format or a superset for 274 * private options data. 275 */ 276 /* autovacuum-related reloptions. */ 277 typedef struct AutoVacOpts 278 { 279 bool enabled; 280 int vacuum_threshold; 281 int vacuum_ins_threshold; 282 int analyze_threshold; 283 int vacuum_cost_limit; 284 int freeze_min_age; 285 int freeze_max_age; 286 int freeze_table_age; 287 int multixact_freeze_min_age; 288 int multixact_freeze_max_age; 289 int multixact_freeze_table_age; 290 int log_min_duration; 291 float8 vacuum_cost_delay; 292 float8 vacuum_scale_factor; 293 float8 vacuum_ins_scale_factor; 294 float8 analyze_scale_factor; 295 } AutoVacOpts; 296 297 typedef struct StdRdOptions 298 { 299 int32 vl_len_; /* varlena header (do not touch directly!) */ 300 int fillfactor; /* page fill factor in percent (0..100) */ 301 /* fraction of newly inserted tuples prior to trigger index cleanup */ 302 int toast_tuple_target; /* target for tuple toasting */ 303 AutoVacOpts autovacuum; /* autovacuum-related options */ 304 bool user_catalog_table; /* use as an additional catalog relation */ 305 int parallel_workers; /* max number of parallel workers */ 306 bool vacuum_index_cleanup; /* enables index vacuuming and cleanup */ 307 bool vacuum_truncate; /* enables vacuum to truncate a relation */ 308 } StdRdOptions; 309 310 #define HEAP_MIN_FILLFACTOR 10 311 #define HEAP_DEFAULT_FILLFACTOR 100 312 313 /* 314 * RelationGetToastTupleTarget 315 * Returns the relation's toast_tuple_target. Note multiple eval of argument! 316 */ 317 #define RelationGetToastTupleTarget(relation, defaulttarg) \ 318 ((relation)->rd_options ? \ 319 ((StdRdOptions *) (relation)->rd_options)->toast_tuple_target : (defaulttarg)) 320 321 /* 322 * RelationGetFillFactor 323 * Returns the relation's fillfactor. Note multiple eval of argument! 324 */ 325 #define RelationGetFillFactor(relation, defaultff) \ 326 ((relation)->rd_options ? \ 327 ((StdRdOptions *) (relation)->rd_options)->fillfactor : (defaultff)) 328 329 /* 330 * RelationGetTargetPageUsage 331 * Returns the relation's desired space usage per page in bytes. 332 */ 333 #define RelationGetTargetPageUsage(relation, defaultff) \ 334 (BLCKSZ * RelationGetFillFactor(relation, defaultff) / 100) 335 336 /* 337 * RelationGetTargetPageFreeSpace 338 * Returns the relation's desired freespace per page in bytes. 339 */ 340 #define RelationGetTargetPageFreeSpace(relation, defaultff) \ 341 (BLCKSZ * (100 - RelationGetFillFactor(relation, defaultff)) / 100) 342 343 /* 344 * RelationIsUsedAsCatalogTable 345 * Returns whether the relation should be treated as a catalog table 346 * from the pov of logical decoding. Note multiple eval of argument! 347 */ 348 #define RelationIsUsedAsCatalogTable(relation) \ 349 ((relation)->rd_options && \ 350 ((relation)->rd_rel->relkind == RELKIND_RELATION || \ 351 (relation)->rd_rel->relkind == RELKIND_MATVIEW) ? \ 352 ((StdRdOptions *) (relation)->rd_options)->user_catalog_table : false) 353 354 /* 355 * RelationGetParallelWorkers 356 * Returns the relation's parallel_workers reloption setting. 357 * Note multiple eval of argument! 358 */ 359 #define RelationGetParallelWorkers(relation, defaultpw) \ 360 ((relation)->rd_options ? \ 361 ((StdRdOptions *) (relation)->rd_options)->parallel_workers : (defaultpw)) 362 363 /* ViewOptions->check_option values */ 364 typedef enum ViewOptCheckOption 365 { 366 VIEW_OPTION_CHECK_OPTION_NOT_SET, 367 VIEW_OPTION_CHECK_OPTION_LOCAL, 368 VIEW_OPTION_CHECK_OPTION_CASCADED 369 } ViewOptCheckOption; 370 371 /* 372 * ViewOptions 373 * Contents of rd_options for views 374 */ 375 typedef struct ViewOptions 376 { 377 int32 vl_len_; /* varlena header (do not touch directly!) */ 378 bool security_barrier; 379 ViewOptCheckOption check_option; 380 } ViewOptions; 381 382 /* 383 * RelationIsSecurityView 384 * Returns whether the relation is security view, or not. Note multiple 385 * eval of argument! 386 */ 387 #define RelationIsSecurityView(relation) \ 388 (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW), \ 389 (relation)->rd_options ? \ 390 ((ViewOptions *) (relation)->rd_options)->security_barrier : false) 391 392 /* 393 * RelationHasCheckOption 394 * Returns true if the relation is a view defined with either the local 395 * or the cascaded check option. Note multiple eval of argument! 396 */ 397 #define RelationHasCheckOption(relation) \ 398 (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW), \ 399 (relation)->rd_options && \ 400 ((ViewOptions *) (relation)->rd_options)->check_option != \ 401 VIEW_OPTION_CHECK_OPTION_NOT_SET) 402 403 /* 404 * RelationHasLocalCheckOption 405 * Returns true if the relation is a view defined with the local check 406 * option. Note multiple eval of argument! 407 */ 408 #define RelationHasLocalCheckOption(relation) \ 409 (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW), \ 410 (relation)->rd_options && \ 411 ((ViewOptions *) (relation)->rd_options)->check_option == \ 412 VIEW_OPTION_CHECK_OPTION_LOCAL) 413 414 /* 415 * RelationHasCascadedCheckOption 416 * Returns true if the relation is a view defined with the cascaded check 417 * option. Note multiple eval of argument! 418 */ 419 #define RelationHasCascadedCheckOption(relation) \ 420 (AssertMacro(relation->rd_rel->relkind == RELKIND_VIEW), \ 421 (relation)->rd_options && \ 422 ((ViewOptions *) (relation)->rd_options)->check_option == \ 423 VIEW_OPTION_CHECK_OPTION_CASCADED) 424 425 /* 426 * RelationIsValid 427 * True iff relation descriptor is valid. 428 */ 429 #define RelationIsValid(relation) PointerIsValid(relation) 430 431 #define InvalidRelation ((Relation) NULL) 432 433 /* 434 * RelationHasReferenceCountZero 435 * True iff relation reference count is zero. 436 * 437 * Note: 438 * Assumes relation descriptor is valid. 439 */ 440 #define RelationHasReferenceCountZero(relation) \ 441 ((bool)((relation)->rd_refcnt == 0)) 442 443 /* 444 * RelationGetForm 445 * Returns pg_class tuple for a relation. 446 * 447 * Note: 448 * Assumes relation descriptor is valid. 449 */ 450 #define RelationGetForm(relation) ((relation)->rd_rel) 451 452 /* 453 * RelationGetRelid 454 * Returns the OID of the relation 455 */ 456 #define RelationGetRelid(relation) ((relation)->rd_id) 457 458 /* 459 * RelationGetNumberOfAttributes 460 * Returns the total number of attributes in a relation. 461 */ 462 #define RelationGetNumberOfAttributes(relation) ((relation)->rd_rel->relnatts) 463 464 /* 465 * IndexRelationGetNumberOfAttributes 466 * Returns the number of attributes in an index. 467 */ 468 #define IndexRelationGetNumberOfAttributes(relation) \ 469 ((relation)->rd_index->indnatts) 470 471 /* 472 * IndexRelationGetNumberOfKeyAttributes 473 * Returns the number of key attributes in an index. 474 */ 475 #define IndexRelationGetNumberOfKeyAttributes(relation) \ 476 ((relation)->rd_index->indnkeyatts) 477 478 /* 479 * RelationGetDescr 480 * Returns tuple descriptor for a relation. 481 */ 482 #define RelationGetDescr(relation) ((relation)->rd_att) 483 484 /* 485 * RelationGetRelationName 486 * Returns the rel's name. 487 * 488 * Note that the name is only unique within the containing namespace. 489 */ 490 #define RelationGetRelationName(relation) \ 491 (NameStr((relation)->rd_rel->relname)) 492 493 /* 494 * RelationGetNamespace 495 * Returns the rel's namespace OID. 496 */ 497 #define RelationGetNamespace(relation) \ 498 ((relation)->rd_rel->relnamespace) 499 500 /* 501 * RelationIsMapped 502 * True if the relation uses the relfilenode map. Note multiple eval 503 * of argument! 504 */ 505 #define RelationIsMapped(relation) \ 506 (RELKIND_HAS_STORAGE((relation)->rd_rel->relkind) && \ 507 ((relation)->rd_rel->relfilenode == InvalidOid)) 508 509 /* 510 * RelationOpenSmgr 511 * Open the relation at the smgr level, if not already done. 512 */ 513 #define RelationOpenSmgr(relation) \ 514 do { \ 515 if ((relation)->rd_smgr == NULL) \ 516 smgrsetowner(&((relation)->rd_smgr), smgropen((relation)->rd_node, (relation)->rd_backend)); \ 517 } while (0) 518 519 /* 520 * RelationCloseSmgr 521 * Close the relation at the smgr level, if not already done. 522 * 523 * Note: smgrclose should unhook from owner pointer, hence the Assert. 524 */ 525 #define RelationCloseSmgr(relation) \ 526 do { \ 527 if ((relation)->rd_smgr != NULL) \ 528 { \ 529 smgrclose((relation)->rd_smgr); \ 530 Assert((relation)->rd_smgr == NULL); \ 531 } \ 532 } while (0) 533 534 /* 535 * RelationGetTargetBlock 536 * Fetch relation's current insertion target block. 537 * 538 * Returns InvalidBlockNumber if there is no current target block. Note 539 * that the target block status is discarded on any smgr-level invalidation. 540 */ 541 #define RelationGetTargetBlock(relation) \ 542 ( (relation)->rd_smgr != NULL ? (relation)->rd_smgr->smgr_targblock : InvalidBlockNumber ) 543 544 /* 545 * RelationSetTargetBlock 546 * Set relation's current insertion target block. 547 */ 548 #define RelationSetTargetBlock(relation, targblock) \ 549 do { \ 550 RelationOpenSmgr(relation); \ 551 (relation)->rd_smgr->smgr_targblock = (targblock); \ 552 } while (0) 553 554 /* 555 * RelationNeedsWAL 556 * True if relation needs WAL. 557 * 558 * Returns false if wal_level = minimal and this relation is created or 559 * truncated in the current transaction. See "Skipping WAL for New 560 * RelFileNode" in src/backend/access/transam/README. 561 */ 562 #define RelationNeedsWAL(relation) \ 563 ((relation)->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT && \ 564 (XLogIsNeeded() || \ 565 (relation->rd_createSubid == InvalidSubTransactionId && \ 566 relation->rd_firstRelfilenodeSubid == InvalidSubTransactionId))) 567 568 /* 569 * RelationUsesLocalBuffers 570 * True if relation's pages are stored in local buffers. 571 */ 572 #define RelationUsesLocalBuffers(relation) \ 573 ((relation)->rd_rel->relpersistence == RELPERSISTENCE_TEMP) 574 575 /* 576 * RELATION_IS_LOCAL 577 * If a rel is either temp or newly created in the current transaction, 578 * it can be assumed to be accessible only to the current backend. 579 * This is typically used to decide that we can skip acquiring locks. 580 * 581 * Beware of multiple eval of argument 582 */ 583 #define RELATION_IS_LOCAL(relation) \ 584 ((relation)->rd_islocaltemp || \ 585 (relation)->rd_createSubid != InvalidSubTransactionId) 586 587 /* 588 * RELATION_IS_OTHER_TEMP 589 * Test for a temporary relation that belongs to some other session. 590 * 591 * Beware of multiple eval of argument 592 */ 593 #define RELATION_IS_OTHER_TEMP(relation) \ 594 ((relation)->rd_rel->relpersistence == RELPERSISTENCE_TEMP && \ 595 !(relation)->rd_islocaltemp) 596 597 598 /* 599 * RelationIsScannable 600 * Currently can only be false for a materialized view which has not been 601 * populated by its query. This is likely to get more complicated later, 602 * so use a macro which looks like a function. 603 */ 604 #define RelationIsScannable(relation) ((relation)->rd_rel->relispopulated) 605 606 /* 607 * RelationIsPopulated 608 * Currently, we don't physically distinguish the "populated" and 609 * "scannable" properties of matviews, but that may change later. 610 * Hence, use the appropriate one of these macros in code tests. 611 */ 612 #define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated) 613 614 /* 615 * RelationIsAccessibleInLogicalDecoding 616 * True if we need to log enough information to have access via 617 * decoding snapshot. 618 */ 619 #define RelationIsAccessibleInLogicalDecoding(relation) \ 620 (XLogLogicalInfoActive() && \ 621 RelationNeedsWAL(relation) && \ 622 (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation))) 623 624 /* 625 * RelationIsLogicallyLogged 626 * True if we need to log enough information to extract the data from the 627 * WAL stream. 628 * 629 * We don't log information for unlogged tables (since they don't WAL log 630 * anyway) and for system tables (their content is hard to make sense of, and 631 * it would complicate decoding slightly for little gain). Note that we *do* 632 * log information for user defined catalog tables since they presumably are 633 * interesting to the user... 634 */ 635 #define RelationIsLogicallyLogged(relation) \ 636 (XLogLogicalInfoActive() && \ 637 RelationNeedsWAL(relation) && \ 638 !IsCatalogRelation(relation)) 639 640 /* routines in utils/cache/relcache.c */ 641 extern void RelationIncrementReferenceCount(Relation rel); 642 extern void RelationDecrementReferenceCount(Relation rel); 643 644 #endif /* REL_H */ 645