diff options
author | Alexander Korotkov <akorotkov@postgresql.org> | 2024-03-23 23:00:06 +0200 |
---|---|---|
committer | Alexander Korotkov <akorotkov@postgresql.org> | 2024-03-24 00:08:13 +0200 |
commit | d603e674462d7c4df0e88b7a61d4ae14ae3ed191 (patch) | |
tree | 116f582aaa0a224fe83ca8b8ae94846383738b98 | |
parent | 50f8611d073e255c9d5b3792965595879c22c610 (diff) | |
download | postgresql-d603e674462d7c4df0e88b7a61d4ae14ae3ed191.tar.gz postgresql-d603e674462d7c4df0e88b7a61d4ae14ae3ed191.zip |
amcheck: Normalize index tuples containing uncompressed varlena
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
-rw-r--r-- | contrib/amcheck/expected/check_btree.out | 10 | ||||
-rw-r--r-- | contrib/amcheck/sql/check_btree.sql | 6 | ||||
-rw-r--r-- | contrib/amcheck/verify_nbtree.c | 13 |
3 files changed, 29 insertions, 0 deletions
diff --git a/contrib/amcheck/expected/check_btree.out b/contrib/amcheck/expected/check_btree.out index fecbeb05beb..5212af07225 100644 --- a/contrib/amcheck/expected/check_btree.out +++ b/contrib/amcheck/expected/check_btree.out @@ -202,6 +202,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 b65df121930..9871fc84023 100644 --- a/contrib/amcheck/sql/check_btree.sql +++ b/contrib/amcheck/sql/check_btree.sql @@ -140,6 +140,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 fa94c6c9b41..a8a6eb2bfda 100644 --- a/contrib/amcheck/verify_nbtree.c +++ b/contrib/amcheck/verify_nbtree.c @@ -28,6 +28,7 @@ #include "access/table.h" #include "access/tableam.h" #include "access/transam.h" +#include "access/tuptoaster.h" #include "access/xact.h" #include "catalog/index.h" #include "catalog/pg_am.h" @@ -2093,6 +2094,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 == 'x' || + att->attstorage == 'm')) + { + /* + * 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; |