mirror of
https://github.com/postgres/postgres.git
synced 2025-10-22 14:32:25 +03:00
Clean up manipulations of hash indexes' hasho_flag field.
Standardize on testing a hash index page's type by doing (opaque->hasho_flag & LH_PAGE_TYPE) == LH_xxx_PAGE Various places were taking shortcuts like opaque->hasho_flag & LH_BUCKET_PAGE which while not actually wrong, is still bad practice because it encourages use of opaque->hasho_flag & LH_UNUSED_PAGE which *is* wrong (LH_UNUSED_PAGE == 0, so the above is constant false). hash_xlog.c's hash_mask() contained such an incorrect test. This also ensures that we mask out the additional flag bits that hasho_flag has accreted since 9.6. pgstattuple's pgstat_hash_page(), for one, was failing to do that and was thus actively broken. Also fix assorted comments that hadn't been updated to reflect the extended usage of hasho_flag, and fix some macros that were testing just "(hasho_flag & bit)" to use the less dangerous, project-approved form "((hasho_flag & bit) != 0)". Coverity found the bug in hash_mask(); I noted the one in pgstat_hash_page() through code reading.
This commit is contained in:
@@ -41,13 +41,13 @@ typedef uint32 Bucket;
|
||||
/*
|
||||
* Special space for hash index pages.
|
||||
*
|
||||
* hasho_flag tells us which type of page we're looking at. For
|
||||
* example, knowing overflow pages from bucket pages is necessary
|
||||
* information when you're deleting tuples from a page. If all the
|
||||
* tuples are deleted from an overflow page, the overflow is made
|
||||
* available to other buckets by calling _hash_freeovflpage(). If all
|
||||
* the tuples are deleted from a bucket page, no additional action is
|
||||
* necessary.
|
||||
* hasho_flag's LH_PAGE_TYPE bits tell us which type of page we're looking at.
|
||||
* Additional bits in the flag word are used for more transient purposes.
|
||||
*
|
||||
* To test a page's type, do (hasho_flag & LH_PAGE_TYPE) == LH_xxx_PAGE.
|
||||
* However, we ensure that each used page type has a distinct bit so that
|
||||
* we can OR together page types for uses such as the allowable-page-types
|
||||
* argument of _hash_checkpage().
|
||||
*/
|
||||
#define LH_UNUSED_PAGE (0)
|
||||
#define LH_OVERFLOW_PAGE (1 << 0)
|
||||
@@ -60,7 +60,7 @@ typedef uint32 Bucket;
|
||||
#define LH_PAGE_HAS_DEAD_TUPLES (1 << 7)
|
||||
|
||||
#define LH_PAGE_TYPE \
|
||||
(LH_OVERFLOW_PAGE|LH_BUCKET_PAGE|LH_BITMAP_PAGE|LH_META_PAGE)
|
||||
(LH_OVERFLOW_PAGE | LH_BUCKET_PAGE | LH_BITMAP_PAGE | LH_META_PAGE)
|
||||
|
||||
/*
|
||||
* In an overflow page, hasho_prevblkno stores the block number of the previous
|
||||
@@ -78,16 +78,16 @@ typedef struct HashPageOpaqueData
|
||||
BlockNumber hasho_prevblkno; /* see above */
|
||||
BlockNumber hasho_nextblkno; /* see above */
|
||||
Bucket hasho_bucket; /* bucket number this pg belongs to */
|
||||
uint16 hasho_flag; /* page type code, see above */
|
||||
uint16 hasho_flag; /* page type code + flag bits, see above */
|
||||
uint16 hasho_page_id; /* for identification of hash indexes */
|
||||
} HashPageOpaqueData;
|
||||
|
||||
typedef HashPageOpaqueData *HashPageOpaque;
|
||||
|
||||
#define H_NEEDS_SPLIT_CLEANUP(opaque) ((opaque)->hasho_flag & LH_BUCKET_NEEDS_SPLIT_CLEANUP)
|
||||
#define H_BUCKET_BEING_SPLIT(opaque) ((opaque)->hasho_flag & LH_BUCKET_BEING_SPLIT)
|
||||
#define H_BUCKET_BEING_POPULATED(opaque) ((opaque)->hasho_flag & LH_BUCKET_BEING_POPULATED)
|
||||
#define H_HAS_DEAD_TUPLES(opaque) ((opaque)->hasho_flag & LH_PAGE_HAS_DEAD_TUPLES)
|
||||
#define H_NEEDS_SPLIT_CLEANUP(opaque) (((opaque)->hasho_flag & LH_BUCKET_NEEDS_SPLIT_CLEANUP) != 0)
|
||||
#define H_BUCKET_BEING_SPLIT(opaque) (((opaque)->hasho_flag & LH_BUCKET_BEING_SPLIT) != 0)
|
||||
#define H_BUCKET_BEING_POPULATED(opaque) (((opaque)->hasho_flag & LH_BUCKET_BEING_POPULATED) != 0)
|
||||
#define H_HAS_DEAD_TUPLES(opaque) (((opaque)->hasho_flag & LH_PAGE_HAS_DEAD_TUPLES) != 0)
|
||||
|
||||
/*
|
||||
* The page ID is for the convenience of pg_filedump and similar utilities,
|
||||
|
Reference in New Issue
Block a user