From 330ad2f0fa34e6f2dffe19afa340cd3da2261920 Mon Sep 17 00:00:00 2001 From: reshke kirill Date: Mon, 16 Dec 2024 10:49:43 +0000 Subject: [PATCH v36 5/8] Fix for gin_index_check. Never explicitly check high key on rightmost page is entry tree. Its value is not stored explicitly and is equal to infitity. --- contrib/amcheck/verify_gin.c | 43 ++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/contrib/amcheck/verify_gin.c b/contrib/amcheck/verify_gin.c index 2dc5fbba619..74783af54d4 100644 --- a/contrib/amcheck/verify_gin.c +++ b/contrib/amcheck/verify_gin.c @@ -163,6 +163,7 @@ gin_check_posting_tree_parent_keys_consistency(Relation rel, BlockNumber posting Page page; OffsetNumber i, maxoff; + BlockNumber rightlink; CHECK_FOR_INTERRUPTS(); @@ -170,6 +171,7 @@ gin_check_posting_tree_parent_keys_consistency(Relation rel, BlockNumber posting RBM_NORMAL, strategy); LockBuffer(buffer, GIN_SHARE); page = (Page) BufferGetPage(buffer); + Assert(GinPageIsData(page)); /* Check that the tree has the same height in all branches */ @@ -234,8 +236,8 @@ gin_check_posting_tree_parent_keys_consistency(Relation rel, BlockNumber posting * Check that tuples in each page are properly ordered and * consistent with parent high key */ - Assert(GinPageIsData(page)); maxoff = GinPageGetOpaque(page)->maxoff; + rightlink = GinPageGetOpaque(page)->rightlink; elog(DEBUG1, "page blk: %u, type data, maxoff %d", stack->blkno, maxoff); @@ -273,7 +275,12 @@ gin_check_posting_tree_parent_keys_consistency(Relation rel, BlockNumber posting */ bound = *GinDataPageGetRightBound(page); - if (stack->parentblk != InvalidBlockNumber && + /* + * Gin page right bound has sane value if only not a highkey on + * rightmost page on level. + */ + if (ItemPointerIsValid(&stack->parentkey) && + rightlink != InvalidBlockNumber && !ItemPointerEquals(&stack->parentkey, &bound)) ereport(ERROR, (errcode(ERRCODE_INDEX_CORRUPTED), @@ -287,11 +294,12 @@ gin_check_posting_tree_parent_keys_consistency(Relation rel, BlockNumber posting for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) { + GinPostingTreeScanItem *ptr; PostingItem *posting_item = GinDataPageGetPostingItem(page, i); /* ItemPointerGetOffsetNumber expects a valid pointer */ if (!(i == maxoff && - GinPageGetOpaque(page)->rightlink == InvalidBlockNumber)) + rightlink == InvalidBlockNumber)) elog(DEBUG3, "key (%u, %u) -> %u", ItemPointerGetBlockNumber(&posting_item->key), ItemPointerGetOffsetNumber(&posting_item->key), @@ -300,8 +308,7 @@ gin_check_posting_tree_parent_keys_consistency(Relation rel, BlockNumber posting elog(DEBUG3, "key (%u, %u) -> %u", 0, 0, BlockIdGetBlockNumber(&posting_item->child_blkno)); - if (i == maxoff && - GinPageGetOpaque(page)->rightlink == InvalidBlockNumber) + if (i == maxoff && rightlink == InvalidBlockNumber) { /* * The rightmost item in the tree level has (0, 0) as the @@ -340,19 +347,23 @@ gin_check_posting_tree_parent_keys_consistency(Relation rel, BlockNumber posting RelationGetRelationName(rel), stack->blkno, i))); - /* If this is an internal page, recurse into the child */ - if (!GinPageIsLeaf(page)) - { - GinPostingTreeScanItem *ptr; + /* This is an internal page, recurse into the child */ + ptr = (GinPostingTreeScanItem *) palloc(sizeof(GinPostingTreeScanItem)); + ptr->depth = stack->depth + 1; - ptr = (GinPostingTreeScanItem *) palloc(sizeof(GinPostingTreeScanItem)); - ptr->depth = stack->depth + 1; + /* + * Set rightmost parent key to invalid iterm pointer. Its + * value is 'Infinity' and not explicitly stored. + */ + if (rightlink == InvalidBlockNumber) + ItemPointerSetInvalid(&ptr->parentkey); + else ptr->parentkey = posting_item->key; - ptr->parentblk = stack->blkno; - ptr->blkno = BlockIdGetBlockNumber(&posting_item->child_blkno); - ptr->next = stack->next; - stack->next = ptr; - } + + ptr->parentblk = stack->blkno; + ptr->blkno = BlockIdGetBlockNumber(&posting_item->child_blkno); + ptr->next = stack->next; + stack->next = ptr; } } LockBuffer(buffer, GIN_UNLOCK); -- 2.39.3 (Apple Git-145)