| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /*------------------------------------------------------------------------- |
| * |
| * rel.h |
| * POSTGRES relation descriptor (a/k/a relcache entry) definitions. |
| * |
| * |
| * Portions Copyright (c) 2005-2009, Greenplum inc. |
| * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group |
| * Portions Copyright (c) 1994, Regents of the University of California |
| * |
| * $PostgreSQL: pgsql/src/include/utils/rel.h,v 1.92 2006/10/04 00:30:10 momjian Exp $ |
| * |
| *------------------------------------------------------------------------- |
| */ |
| #ifndef REL_H |
| #define REL_H |
| |
| #include "access/tupdesc.h" |
| #include "catalog/pg_am.h" |
| #include "catalog/pg_class.h" |
| #include "catalog/pg_index.h" |
| #include "fmgr.h" |
| #include "nodes/bitmapset.h" |
| #include "rewrite/prs2lock.h" |
| #include "storage/block.h" |
| #include "storage/relfilenode.h" |
| #include "utils/relcache.h" |
| #include "catalog/gp_persistent.h" |
| |
| |
| /* |
| * LockRelId and LockInfo really belong to lmgr.h, but it's more convenient |
| * to declare them here so we can have a LockInfoData field in a Relation. |
| */ |
| |
| typedef struct LockRelId |
| { |
| Oid relId; /* a relation identifier */ |
| Oid dbId; /* a database identifier */ |
| } LockRelId; |
| |
| typedef struct LockInfoData |
| { |
| LockRelId lockRelId; |
| } LockInfoData; |
| |
| typedef LockInfoData *LockInfo; |
| |
| /* |
| * Likewise, this struct really belongs to trigger.h, but for convenience |
| * we put it here. |
| */ |
| typedef struct Trigger |
| { |
| Oid tgoid; /* OID of trigger (pg_trigger row) */ |
| /* Remaining fields are copied from pg_trigger, see pg_trigger.h */ |
| char *tgname; |
| Oid tgfoid; |
| int16 tgtype; |
| bool tgenabled; |
| bool tgisconstraint; |
| Oid tgconstrrelid; |
| bool tgdeferrable; |
| bool tginitdeferred; |
| int16 tgnargs; |
| int16 tgnattr; |
| int16 *tgattr; |
| char **tgargs; |
| } Trigger; |
| |
| typedef struct TriggerDesc |
| { |
| /* |
| * Index data to identify which triggers are which. Since each trigger |
| * can appear in more than one class, for each class we provide a list of |
| * integer indexes into the triggers array. The class codes are defined |
| * by TRIGGER_EVENT_xxx macros in commands/trigger.h. |
| */ |
| #define TRIGGER_NUM_EVENT_CLASSES 4 |
| |
| uint16 n_before_statement[TRIGGER_NUM_EVENT_CLASSES]; |
| uint16 n_before_row[TRIGGER_NUM_EVENT_CLASSES]; |
| uint16 n_after_row[TRIGGER_NUM_EVENT_CLASSES]; |
| uint16 n_after_statement[TRIGGER_NUM_EVENT_CLASSES]; |
| int *tg_before_statement[TRIGGER_NUM_EVENT_CLASSES]; |
| int *tg_before_row[TRIGGER_NUM_EVENT_CLASSES]; |
| int *tg_after_row[TRIGGER_NUM_EVENT_CLASSES]; |
| int *tg_after_statement[TRIGGER_NUM_EVENT_CLASSES]; |
| |
| /* The actual array of triggers is here */ |
| Trigger *triggers; |
| int numtriggers; |
| } TriggerDesc; |
| |
| |
| /* |
| * Cached lookup information for the index access method functions defined |
| * by the pg_am row associated with an index relation. |
| */ |
| typedef struct RelationAmInfo |
| { |
| FmgrInfo aminsert; |
| FmgrInfo ambeginscan; |
| FmgrInfo amgettuple; |
| FmgrInfo amgetmulti; |
| FmgrInfo amrescan; |
| FmgrInfo amendscan; |
| FmgrInfo ammarkpos; |
| FmgrInfo amrestrpos; |
| FmgrInfo ambuild; |
| FmgrInfo ambulkdelete; |
| FmgrInfo amvacuumcleanup; |
| FmgrInfo amcostestimate; |
| FmgrInfo amoptions; |
| } RelationAmInfo; |
| |
| typedef struct RelationNodeInfo |
| { |
| bool isPresent; |
| |
| bool tidAllowedToBeZero; |
| // Persistent TID allowed to be zero for "Before Persistence" or Recovery. |
| |
| ItemPointerData persistentTid; |
| int64 persistentSerialNum; |
| } RelationNodeInfo; |
| |
| /* |
| * Here are the contents of a relation cache entry. |
| */ |
| |
| typedef struct RelationData |
| { |
| RelFileNode rd_node; /* relation physical identifier */ |
| /* use "struct" here to avoid needing to include smgr.h: */ |
| struct SMgrRelationData *rd_smgr; /* cached file handle, or NULL */ |
| BlockNumber rd_targblock; /* current insertion target block, or |
| * InvalidBlockNumber */ |
| int rd_refcnt; /* reference count */ |
| bool rd_istemp; /* CDB: true => skip locking, logging, fsync */ |
| bool rd_issyscat; /* GP: true => system catalog table (has "pg_" prefix) */ |
| bool rd_isnailed; /* rel is nailed in cache */ |
| bool rd_isvalid; /* relcache entry is valid */ |
| char rd_indexvalid; /* state of rd_indexlist: 0 = not valid, 1 = |
| * valid, 2 = temporarily forced */ |
| SubTransactionId rd_createSubid; /* rel was created in current xact */ |
| |
| /* |
| * Debugging information, Values from CREATE TABLE, if present. |
| */ |
| bool rd_haveCreateDebugInfo; |
| bool rd_createDebugIsZeroTid; |
| ItemPointerData rd_createDebugPersistentTid; |
| int64 rd_createDebugPersistentSerialNum; |
| |
| /* |
| * rd_createSubid is the ID of the highest subtransaction the rel has |
| * survived into; or zero if the rel was not created in the current top |
| * transaction. This should be relied on only for optimization purposes; |
| * it is possible for new-ness to be "forgotten" (eg, after CLUSTER). |
| */ |
| Form_pg_class rd_rel; /* RELATION tuple */ |
| TupleDesc rd_att; /* tuple descriptor */ |
| Oid rd_id; /* relation's object id */ |
| List *rd_indexlist; /* list of OIDs of indexes on relation */ |
| Oid rd_oidindex; /* OID of unique index on OID, if any */ |
| LockInfoData rd_lockInfo; /* lock mgr's info for locking relation */ |
| RuleLock *rd_rules; /* rewrite rules */ |
| MemoryContext rd_rulescxt; /* private memory cxt for rd_rules, if any */ |
| TriggerDesc *trigdesc; /* Trigger info, or NULL if rel has none */ |
| struct GpPolicy *rd_cdbpolicy; /* Partitioning info if distributed rel */ |
| bool rd_cdbDefaultStatsWarningIssued; |
| bool rd_isLocalBuf; /* CDB: true => rel uses the local buffer mgr */ |
| |
| /* |
| * rd_options is set whenever rd_rel is loaded into the relcache entry. |
| * Note that you can NOT look into rd_rel for this data. NULL means "use |
| * defaults". |
| */ |
| bytea *rd_options; /* parsed pg_class.reloptions */ |
| |
| /* These are non-NULL only for an index relation: */ |
| Form_pg_index rd_index; /* pg_index tuple describing this index */ |
| struct HeapTupleData *rd_indextuple; /* all of pg_index tuple */ |
| /* "struct HeapTupleData *" avoids need to include htup.h here */ |
| oidvector *rd_indclass; /* extracted pointer to rd_index field */ |
| Form_pg_am rd_am; /* pg_am tuple for index's AM */ |
| |
| /* |
| * index access support info (used only for an index relation) |
| * |
| * Note: only default operators and support procs for each opclass are |
| * cached, namely those with subtype zero. The arrays are indexed by |
| * strategy or support number, which is a sufficient identifier given that |
| * restriction. |
| * |
| * Note: rd_amcache is available for index AMs to cache private data about |
| * an index. This must be just a cache since it may get reset at any time |
| * (in particular, it will get reset by a relcache inval message for the |
| * index). If used, it must point to a single memory chunk palloc'd in |
| * rd_indexcxt. A relcache reset will include freeing that chunk and |
| * setting rd_amcache = NULL. |
| */ |
| MemoryContext rd_indexcxt; /* private memory cxt for this stuff */ |
| RelationAmInfo *rd_aminfo; /* lookup info for funcs found in pg_am */ |
| Oid *rd_operator; /* OIDs of index operators */ |
| RegProcedure *rd_support; /* OIDs of support procedures */ |
| FmgrInfo *rd_supportinfo; /* lookup info for support procedures */ |
| List *rd_indexprs; /* index expression trees, if any */ |
| List *rd_indpred; /* index predicate tree, if any */ |
| void *rd_amcache; /* available for use by index AM */ |
| |
| /* |
| * Physical file-system information. |
| */ |
| struct RelationNodeInfo rd_relationnodeinfo; |
| /* Values from gp_persistent_relation_node, if present */ |
| |
| /* use "struct" here to avoid needing to include pgstat.h: */ |
| struct PgStat_TableStatus *pgstat_info; /* statistics collection area */ |
| |
| /* |
| * in gpsql, master create all segfiles for segments, |
| * therefore we need an array. |
| * use this varaiable instead of rd_segfile0_relationnodeinfo, |
| * rd_segfile0_relationnodeinfo should be removed finally. |
| */ |
| /* |
| * in HAWQ 2.0, the number of segments is not fixed. |
| */ |
| /* |
| struct RelationNodeInfo * rd_segfile0_relationnodeinfos; |
| int32 rd_segfile0_count; |
| */ |
| |
| } RelationData; |
| |
| /* |
| * StdRdOptions |
| * Standard contents of rd_options for heaps and generic indexes. |
| * |
| * RelationGetFillFactor() and RelationGetTargetPageFreeSpace() can only |
| * be applied to relations that use this format or a superset for |
| * private options data. |
| */ |
| /* autovacuum-related reloptions. */ |
| typedef struct AutoVacOpts |
| { |
| bool enabled; |
| int vacuum_threshold; |
| int analyze_threshold; |
| int vacuum_cost_delay; |
| int vacuum_cost_limit; |
| int freeze_min_age; |
| int freeze_max_age; |
| int freeze_table_age; |
| float8 vacuum_scale_factor; |
| float8 analyze_scale_factor; |
| } AutoVacOpts; |
| |
| typedef struct StdRdOptions |
| { |
| int32 vl_len_; /* varlena header (do not touch directly!) */ |
| int fillfactor; /* page fill factor in percent (0..100) */ |
| AutoVacOpts autovacuum; /* autovacuum-related options */ |
| bool appendonly; /* is this an appendonly relation? */ |
| int blocksize; /* max varblock size (AO rels only) */ |
| int pagesize; /* page size(Parquet rels only) */ |
| int rowgroupsize; /* row group size (Parquet rels only)*/ |
| int compresslevel; /* compression level (AO rels only) */ |
| char* compresstype; /* compression type (AO rels only) */ |
| bool checksum; /* checksum (AO rels only) */ |
| char columnstore; /* columnstore (AO only, 'a' for ao, 'c' for co, 'p' for parquet) */ |
| bool forceHeap; /* specified appendonly=false */ |
| bool errorTable; /* skip GOH tablespace checking. */ |
| int bucket_num; /* default init segment num for random/hash/external table */ |
| } StdRdOptions; |
| |
| #define HEAP_MIN_FILLFACTOR 10 |
| #define HEAP_DEFAULT_FILLFACTOR 100 |
| |
| typedef struct TidycatOptions |
| { |
| /* |
| * Options only allowed during upgrade (tidycat option) |
| * Not all tidycat option are of interest to us: |
| * "shared" is not needed because it's derived from tablespace |
| */ |
| Oid relid; /* relid of the table in pg_class */ |
| Oid reltype_oid; /* static reltype in pg_type */ |
| Oid toast_oid; /* oid of the toast table */ |
| Oid toast_index; /* oid of the toast index */ |
| Oid toast_reltype; /* static reltype of the toast table in pg_type */ |
| Oid indexid; |
| } TidycatOptions; |
| |
| /* |
| * RelationGetFillFactor |
| * Returns the relation's fillfactor. Note multiple eval of argument! |
| */ |
| #define RelationGetFillFactor(relation, defaultff) \ |
| ((relation)->rd_options ? \ |
| ((StdRdOptions *) (relation)->rd_options)->fillfactor : (defaultff)) |
| |
| /* |
| * RelationGetTargetPageUsage |
| * Returns the relation's desired space usage per page in bytes. |
| */ |
| #define RelationGetTargetPageUsage(relation, defaultff) \ |
| (BLCKSZ * RelationGetFillFactor(relation, defaultff) / 100) |
| |
| /* |
| * RelationGetTargetPageFreeSpace |
| * Returns the relation's desired freespace per page in bytes. |
| */ |
| #define RelationGetTargetPageFreeSpace(relation, defaultff) \ |
| (BLCKSZ * (100 - RelationGetFillFactor(relation, defaultff)) / 100) |
| |
| /* |
| * RelationIsValid |
| * True iff relation descriptor is valid. |
| */ |
| #define RelationIsValid(relation) PointerIsValid(relation) |
| |
| #define InvalidRelation ((Relation) NULL) |
| |
| /* |
| * RelationIsHeap |
| * True iff relation has heap storage |
| */ |
| #define RelationIsHeap(relation) \ |
| ((bool)((relation)->rd_rel->relstorage == RELSTORAGE_HEAP)) |
| |
| /* |
| * RelationIsExternal |
| * True iff relation has external storage |
| */ |
| #define RelationIsExternal(relation) \ |
| ((bool)((relation)->rd_rel->relstorage == RELSTORAGE_EXTERNAL)) |
| |
| /* |
| * RelationIsAoRows |
| * True iff relation has append only storage with row orientation |
| */ |
| #define RelationIsAoRows(relation) \ |
| ((bool)(((relation)->rd_rel->relstorage == RELSTORAGE_AOROWS))) |
| |
| /* |
| * RelationIsParquet |
| * True iff relation has append only storage with parquet orientation |
| */ |
| #define RelationIsParquet(relation) \ |
| ((bool)(((relation)->rd_rel->relstorage == RELSTORAGE_PARQUET))) |
| |
| |
| /* |
| * RelationIsForeign |
| * True iff relation has foreign storage |
| */ |
| #define RelationIsForeign(relation) \ |
| ((bool)((relation)->rd_rel->relstorage == RELSTORAGE_FOREIGN)) |
| |
| /* |
| * RelationIsBitmapIndex |
| * True iff relation is a bitmap index |
| */ |
| #define RelationIsBitmapIndex(relation) \ |
| ((bool)((relation)->rd_rel->relam == BITMAP_AM_OID)) |
| |
| /* |
| * RelationHasReferenceCountZero |
| * True iff relation reference count is zero. |
| * |
| * Note: |
| * Assumes relation descriptor is valid. |
| */ |
| #define RelationHasReferenceCountZero(relation) \ |
| ((bool)((relation)->rd_refcnt == 0)) |
| |
| /* |
| * RelationGetForm |
| * Returns pg_class tuple for a relation. |
| * |
| * Note: |
| * Assumes relation descriptor is valid. |
| */ |
| #define RelationGetForm(relation) ((relation)->rd_rel) |
| |
| /* |
| * RelationGetRelid |
| * Returns the OID of the relation |
| */ |
| #define RelationGetRelid(relation) ((relation)->rd_id) |
| |
| /* |
| * RelationGetNumberOfAttributes |
| * Returns the number of attributes in a relation. |
| */ |
| #define RelationGetNumberOfAttributes(relation) ((relation)->rd_rel->relnatts) |
| |
| /* |
| * RelationGetDescr |
| * Returns tuple descriptor for a relation. |
| */ |
| #define RelationGetDescr(relation) ((relation)->rd_att) |
| |
| /* |
| * RelationGetRelationName |
| * Returns the rel's name. |
| * |
| * Note that the name is only unique within the containing namespace. |
| */ |
| #define RelationGetRelationName(relation) \ |
| (NameStr((relation)->rd_rel->relname)) |
| |
| /* |
| * RelationGetNamespace |
| * Returns the rel's namespace OID. |
| */ |
| #define RelationGetNamespace(relation) \ |
| ((relation)->rd_rel->relnamespace) |
| |
| /* |
| * RelationOpenSmgr |
| * Open the relation at the smgr level, if not already done. |
| */ |
| #define RelationOpenSmgr(relation) \ |
| do { \ |
| if ((relation)->rd_smgr == NULL) \ |
| smgrsetowner(&((relation)->rd_smgr), smgropen((relation)->rd_node)); \ |
| } while (0) |
| |
| /* |
| * RelationCloseSmgr |
| * Close the relation at the smgr level, if not already done. |
| * |
| * Note: smgrclose should unhook from owner pointer, hence the Assert. |
| */ |
| #define RelationCloseSmgr(relation) \ |
| do { \ |
| if ((relation)->rd_smgr != NULL) \ |
| { \ |
| smgrclose((relation)->rd_smgr); \ |
| Assert((relation)->rd_smgr == NULL); \ |
| } \ |
| } while (0) |
| |
| /* |
| * RELATION_IS_LOCAL |
| * If a rel is either temp or newly created in the current transaction, |
| * it can be assumed to be visible only to the current backend. |
| * |
| * Beware of multiple eval of argument |
| */ |
| #define RELATION_IS_LOCAL(relation) \ |
| ((relation)->rd_istemp || \ |
| (relation)->rd_createSubid != InvalidSubTransactionId) |
| |
| /* routines in utils/cache/relcache.c */ |
| extern void RelationIncrementReferenceCount(Relation rel); |
| extern void RelationDecrementReferenceCount(Relation rel); |
| |
| #endif /* REL_H */ |