diff options
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/access/tableam.h | 141 | ||||
-rw-r--r-- | src/include/catalog/index.h | 77 |
2 files changed, 191 insertions, 27 deletions
diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index 37890dc2f5c..2546d3005fb 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -28,6 +28,9 @@ extern bool synchronize_seqscans; struct BulkInsertStateData; +struct IndexInfo; +struct IndexBuildCallback; +struct ValidateIndexState; /* @@ -106,6 +109,14 @@ typedef struct TM_FailureData #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* Typedef for callback function for table_index_build_scan */ +typedef void (*IndexBuildCallback) (Relation index, + HeapTuple htup, + Datum *values, + bool *isnull, + bool tupleIsAlive, + void *state); + /* * API struct for a table AM. Note this must be allocated in a * server-lifetime manner, typically as a static const struct, which then gets @@ -361,6 +372,31 @@ typedef struct TableAmRoutine uint8 flags, TM_FailureData *tmfd); + + /* ------------------------------------------------------------------------ + * DDL related functionality. + * ------------------------------------------------------------------------ + */ + + /* see table_index_build_range_scan for reference about parameters */ + double (*index_build_range_scan) (Relation heap_rel, + Relation index_rel, + struct IndexInfo *index_nfo, + bool allow_sync, + bool anyvisible, + BlockNumber start_blockno, + BlockNumber end_blockno, + IndexBuildCallback callback, + void *callback_state, + TableScanDesc scan); + + /* see table_index_validate_scan for reference about parameters */ + void (*index_validate_scan) (Relation heap_rel, + Relation index_rel, + struct IndexInfo *index_info, + Snapshot snapshot, + struct ValidateIndexState *state); + } TableAmRoutine; @@ -920,6 +956,111 @@ table_lock_tuple(Relation rel, ItemPointer tid, Snapshot snapshot, } +/* ------------------------------------------------------------------------ + * DDL related functionality. + * ------------------------------------------------------------------------ + */ + +/* + * table_index_build_range_scan - scan the table to find tuples to be indexed + * + * This is called back from an access-method-specific index build procedure + * after the AM has done whatever setup it needs. The parent heap relation + * is scanned to find tuples that should be entered into the index. Each + * such tuple is passed to the AM's callback routine, which does the right + * things to add it to the new index. After we return, the AM's index + * build procedure does whatever cleanup it needs. + * + * The total count of live tuples is returned. This is for updating pg_class + * statistics. (It's annoying not to be able to do that here, but we want to + * merge that update with others; see index_update_stats.) Note that the + * index AM itself must keep track of the number of index tuples; we don't do + * so here because the AM might reject some of the tuples for its own reasons, + * such as being unable to store NULLs. + * + * + * A side effect is to set indexInfo->ii_BrokenHotChain to true if we detect + * any potentially broken HOT chains. Currently, we set this if there are any + * RECENTLY_DEAD or DELETE_IN_PROGRESS entries in a HOT chain, without trying + * very hard to detect whether they're really incompatible with the chain tip. + * This only really makes sense for heap AM, it might need to be generalized + * for other AMs later. + */ +static inline double +table_index_build_scan(Relation heap_rel, + Relation index_rel, + struct IndexInfo *index_nfo, + bool allow_sync, + IndexBuildCallback callback, + void *callback_state, + TableScanDesc scan) +{ + return heap_rel->rd_tableam->index_build_range_scan(heap_rel, + index_rel, + index_nfo, + allow_sync, + false, + 0, + InvalidBlockNumber, + callback, + callback_state, + scan); +} + +/* + * As table_index_build_scan(), except that instead of scanning the complete + * table, only the given number of blocks are scanned. Scan to end-of-rel can + * be signalled by passing InvalidBlockNumber as numblocks. Note that + * restricting the range to scan cannot be done when requesting syncscan. + * + * When "anyvisible" mode is requested, all tuples visible to any transaction + * are indexed and counted as live, including those inserted or deleted by + * transactions that are still in progress. + */ +static inline double +table_index_build_range_scan(Relation heap_rel, + Relation index_rel, + struct IndexInfo *index_nfo, + bool allow_sync, + bool anyvisible, + BlockNumber start_blockno, + BlockNumber numblocks, + IndexBuildCallback callback, + void *callback_state, + TableScanDesc scan) +{ + return heap_rel->rd_tableam->index_build_range_scan(heap_rel, + index_rel, + index_nfo, + allow_sync, + anyvisible, + start_blockno, + numblocks, + callback, + callback_state, + scan); +} + +/* + * table_index_validate_scan - second table scan for concurrent index build + * + * See validate_index() for an explanation. + */ +static inline void +table_index_validate_scan(Relation heap_rel, + Relation index_rel, + struct IndexInfo *index_info, + Snapshot snapshot, + struct ValidateIndexState *state) +{ + heap_rel->rd_tableam->index_validate_scan(heap_rel, + index_rel, + index_info, + snapshot, + state); +} + + /* ---------------------------------------------------------------------------- * Functions to make modifications a bit simpler. * ---------------------------------------------------------------------------- diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h index 29f7ed62379..55a3f446833 100644 --- a/src/include/catalog/index.h +++ b/src/include/catalog/index.h @@ -20,14 +20,6 @@ #define DEFAULT_INDEX_TYPE "btree" -/* Typedef for callback function for IndexBuildHeapScan */ -typedef void (*IndexBuildCallback) (Relation index, - HeapTuple htup, - Datum *values, - bool *isnull, - bool tupleIsAlive, - void *state); - /* Action code for index_set_state_flags */ typedef enum { @@ -37,6 +29,15 @@ typedef enum INDEX_DROP_SET_DEAD } IndexStateFlagsAction; +/* state info for validate_index bulkdelete callback */ +typedef struct ValidateIndexState +{ + Tuplesortstate *tuplesort; /* for sorting the index TIDs */ + /* statistics (for debug purposes only): */ + double htups, + itups, + tups_inserted; +} ValidateIndexState; extern void index_check_primary_key(Relation heapRel, IndexInfo *indexInfo, @@ -110,25 +111,6 @@ extern void index_build(Relation heapRelation, bool isreindex, bool parallel); -struct TableScanDescData; -extern double IndexBuildHeapScan(Relation heapRelation, - Relation indexRelation, - IndexInfo *indexInfo, - bool allow_sync, - IndexBuildCallback callback, - void *callback_state, - struct TableScanDescData *scan); -extern double IndexBuildHeapRangeScan(Relation heapRelation, - Relation indexRelation, - IndexInfo *indexInfo, - bool allow_sync, - bool anyvisible, - BlockNumber start_blockno, - BlockNumber end_blockno, - IndexBuildCallback callback, - void *callback_state, - struct TableScanDescData *scan); - extern void validate_index(Oid heapId, Oid indexId, Snapshot snapshot); extern void index_set_state_flags(Oid indexId, IndexStateFlagsAction action); @@ -155,4 +137,45 @@ extern void RestoreReindexState(void *reindexstate); extern void IndexSetParentIndex(Relation idx, Oid parentOid); + +/* + * itemptr_encode - Encode ItemPointer as int64/int8 + * + * This representation must produce values encoded as int64 that sort in the + * same order as their corresponding original TID values would (using the + * default int8 opclass to produce a result equivalent to the default TID + * opclass). + * + * As noted in validate_index(), this can be significantly faster. + */ +static inline int64 +itemptr_encode(ItemPointer itemptr) +{ + BlockNumber block = ItemPointerGetBlockNumber(itemptr); + OffsetNumber offset = ItemPointerGetOffsetNumber(itemptr); + int64 encoded; + + /* + * Use the 16 least significant bits for the offset. 32 adjacent bits are + * used for the block number. Since remaining bits are unused, there + * cannot be negative encoded values (We assume a two's complement + * representation). + */ + encoded = ((uint64) block << 16) | (uint16) offset; + + return encoded; +} + +/* + * itemptr_decode - Decode int64/int8 representation back to ItemPointer + */ +static inline void +itemptr_decode(ItemPointer itemptr, int64 encoded) +{ + BlockNumber block = (BlockNumber) (encoded >> 16); + OffsetNumber offset = (OffsetNumber) (encoded & 0xFFFF); + + ItemPointerSet(itemptr, block, offset); +} + #endif /* INDEX_H */ |