diff --git a/contrib/amcheck/expected/check_btree.out b/contrib/amcheck/expected/check_btree.out index d87e717886..cf8284fe12 100644 --- a/contrib/amcheck/expected/check_btree.out +++ b/contrib/amcheck/expected/check_btree.out @@ -252,6 +252,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; diff --git a/contrib/amcheck/sql/check_btree.sql b/contrib/amcheck/sql/check_btree.sql index b37fff0507..68bd71b064 100644 --- a/contrib/amcheck/sql/check_btree.sql +++ b/contrib/amcheck/sql/check_btree.sql @@ -158,6 +158,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; diff --git a/contrib/amcheck/verify_nbtree.c b/contrib/amcheck/verify_nbtree.c index e0dffd9bcc..f71f1854e0 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,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;