v3-0002-amcheck-prevent-false-positives-from-extended-dat.patch

application/octet-stream

Filename: v3-0002-amcheck-prevent-false-positives-from-extended-dat.patch
Type: application/octet-stream
Part: 2
Message: Re: [BUG] false positive in bt_index_check in case of short 4B varlena datum

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: format-patch
Series: patch v3-0002
Subject: amcheck: prevent false positives from extended datums
File+
contrib/amcheck/expected/check_btree.out 12 0
contrib/amcheck/sql/check_btree.sql 9 0
contrib/amcheck/verify_nbtree.c 12 0
From e2ab4c0d3ad9777f70fccb21dd446e248cd5f52a Mon Sep 17 00:00:00 2001
From: "Andrey M. Borodin" <x4mmm@night.local>
Date: Tue, 23 Jan 2024 21:57:02 +0500
Subject: [PATCH v3 2/3] amcheck: prevent false positives from extended datums

Reported-by: Alexander Lakhin
---
 contrib/amcheck/expected/check_btree.out | 12 ++++++++++++
 contrib/amcheck/sql/check_btree.sql      |  9 +++++++++
 contrib/amcheck/verify_nbtree.c          | 12 ++++++++++++
 3 files changed, 33 insertions(+)

diff --git a/contrib/amcheck/expected/check_btree.out b/contrib/amcheck/expected/check_btree.out
index e37901c402..36b1ebe34c 100644
--- a/contrib/amcheck/expected/check_btree.out
+++ b/contrib/amcheck/expected/check_btree.out
@@ -258,6 +258,18 @@ SELECT bt_index_check('varlena_bug_idx', true);
  
 (1 row)
 
+-- Check extended varlena
+CREATE TABLE tbl(t text);
+ALTER TABLE tbl ALTER COLUMN t SET STORAGE plain;
+CREATE INDEX tbl_idx ON tbl (t);
+INSERT INTO tbl VALUES (repeat('Test', 250));
+ALTER TABLE tbl ALTER COLUMN t SET STORAGE extended;
+SELECT bt_index_check('tbl_idx', true);
+ bt_index_check 
+----------------
+ 
+(1 row)
+
 -- cleanup
 DROP TABLE bttest_a;
 DROP TABLE bttest_b;
diff --git a/contrib/amcheck/sql/check_btree.sql b/contrib/amcheck/sql/check_btree.sql
index e67eb6352f..0a827edd1a 100644
--- a/contrib/amcheck/sql/check_btree.sql
+++ b/contrib/amcheck/sql/check_btree.sql
@@ -164,6 +164,15 @@ COPY varlena_bug FROM :'filename';
 CREATE INDEX varlena_bug_idx on varlena_bug(v);
 SELECT bt_index_check('varlena_bug_idx', true);
 
+-- Check extended varlena
+CREATE TABLE tbl(t text);
+ALTER TABLE tbl ALTER COLUMN t SET STORAGE plain;
+CREATE INDEX tbl_idx ON tbl (t);
+INSERT INTO tbl VALUES (repeat('Test', 250));
+ALTER TABLE tbl ALTER COLUMN t SET STORAGE extended;
+
+SELECT bt_index_check('tbl_idx', true);
+
 -- cleanup
 DROP TABLE bttest_a;
 DROP TABLE bttest_b;
diff --git a/contrib/amcheck/verify_nbtree.c b/contrib/amcheck/verify_nbtree.c
index e7f01c2add..6654b5afe7 100644
--- a/contrib/amcheck/verify_nbtree.c
+++ b/contrib/amcheck/verify_nbtree.c
@@ -23,6 +23,7 @@
  */
 #include "postgres.h"
 
+#include "access/heaptoast.h"
 #include "access/htup_details.h"
 #include "access/nbtree.h"
 #include "access/table.h"
@@ -2981,6 +2982,17 @@ bt_normalize_tuple(BtreeCheckState *state, IndexTuple itup)
 							ItemPointerGetBlockNumber(&(itup->t_tid)),
 							ItemPointerGetOffsetNumber(&(itup->t_tid)),
 							RelationGetRelationName(state->rel))));
+		else if (!VARATT_IS_EXTENDED(DatumGetPointer(normalized[i])) &&
+			VARSIZE(DatumGetPointer(normalized[i])) > TOAST_INDEX_TARGET &&
+			(att->attstorage == TYPSTORAGE_EXTENDED ||
+			 att->attstorage == TYPSTORAGE_MAIN))
+		{
+			/*
+			 * this attribute will be compressed by index_form_tuple(),
+			 * this might be already done in heap, so force forming.
+			 */
+			formnewtup = true;
+		}
 		else if (VARATT_IS_COMPRESSED(DatumGetPointer(normalized[i])))
 		{
 			formnewtup = true;
-- 
2.37.1 (Apple Git-137.1)