[go: up one dir, main page]

amcheck: Normalize index tuples containing uncompressed varlena
authorAlexander Korotkov <akorotkov@postgresql.org>
Sat, 23 Mar 2024 21:00:06 +0000 (23:00 +0200)
committerAlexander Korotkov <akorotkov@postgresql.org>
Sat, 23 Mar 2024 21:02:43 +0000 (23:02 +0200)
It might happen that the varlena value wasn't compressed by index_form_tuple()
due to current storage parameters.  If compression is currently enabled, we
need to compress such values to match index tuple coming from the heap.

Backpatch to all supported versions.

Discussion: https://postgr.es/m/flat/7bdbe559-d61a-4ae4-a6e1-48abdf3024cc%40postgrespro.ru
Author: Andrey Borodin
Reviewed-by: Alexander Lakhin, Michael Zhilin, Jian He, Alexander Korotkov
Backpatch-through: 12

contrib/amcheck/expected/check_btree.out
contrib/amcheck/sql/check_btree.sql
contrib/amcheck/verify_nbtree.c

index fe6bf2923f59b2be2a061f69d381d411b4e98596..2acbc98a70b2d139407889984c3308bfc10f81c9 100644 (file)
@@ -211,6 +211,16 @@ SELECT bt_index_check('varlena_bug_idx', true);
  
 (1 row)
 
+-- Also check that we compress varlena values, which were previously stored
+-- uncompressed in index.
+INSERT INTO varlena_bug VALUES (repeat('Test', 250));
+ALTER TABLE varlena_bug ALTER COLUMN v SET STORAGE extended;
+SELECT bt_index_check('varlena_bug_idx', true);
+ bt_index_check 
+----------------
+(1 row)
+
 -- cleanup
 DROP TABLE bttest_a;
 DROP TABLE bttest_b;
index 92a3b0f419c8dae033dab0006833caf31b796a8a..e2f47fcfbe10a7673edac5e69bb0b48207b3cd30 100644 (file)
@@ -145,6 +145,12 @@ x
 CREATE INDEX varlena_bug_idx on varlena_bug(v);
 SELECT bt_index_check('varlena_bug_idx', true);
 
+-- Also check that we compress varlena values, which were previously stored
+-- uncompressed in index.
+INSERT INTO varlena_bug VALUES (repeat('Test', 250));
+ALTER TABLE varlena_bug ALTER COLUMN v SET STORAGE extended;
+SELECT bt_index_check('varlena_bug_idx', true);
+
 -- cleanup
 DROP TABLE bttest_a;
 DROP TABLE bttest_b;
index 4aae32c9db85af7d715754ecc74aac2c73468490..c08f19fa89496d22f499c72db06d39f018c7e21c 100644 (file)
@@ -23,6 +23,7 @@
  */
 #include "postgres.h"
 
+#include "access/heaptoast.h"
 #include "access/htup_details.h"
 #include "access/nbtree.h"
 #include "access/table.h"
@@ -2679,6 +2680,18 @@ bt_normalize_tuple(BtreeCheckState *state, IndexTuple itup)
                            ItemPointerGetBlockNumber(&(itup->t_tid)),
                            ItemPointerGetOffsetNumber(&(itup->t_tid)),
                            RelationGetRelationName(state->rel))));
+       else if (!VARATT_IS_COMPRESSED(DatumGetPointer(normalized[i])) &&
+                VARSIZE(DatumGetPointer(normalized[i])) > TOAST_INDEX_TARGET &&
+                (att->attstorage == TYPSTORAGE_EXTENDED ||
+                 att->attstorage == TYPSTORAGE_MAIN))
+       {
+           /*
+            * This value will be compressed by index_form_tuple() with the
+            * current storage settings.  We may be here because this tuple
+            * was formed with different storage settings.  So, force forming.
+            */
+           formnewtup = true;
+       }
        else if (VARATT_IS_COMPRESSED(DatumGetPointer(normalized[i])))
        {
            formnewtup = true;