Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitab65dfb

Browse files
committed
amcheck: Support for different header sizes of short varlena datum
In the heap, tuples may contain short varlena datum with both 1B header and 4Bheaders. But the corresponding index tuple should always have such varlena'swith 1B headers. So, for fingerprinting, we need to convert.Backpatch to all supported versions.Discussion:https://postgr.es/m/flat/7bdbe559-d61a-4ae4-a6e1-48abdf3024cc%40postgrespro.ruAuthor: Michael ZhilinReviewed-by: Alexander Lakhin, Andrey Borodin, Jian He, Alexander KorotkovBackpatch-through: 12
1 parent697f8d2 commitab65dfb

File tree

3 files changed

+55
-5
lines changed

3 files changed

+55
-5
lines changed

‎contrib/amcheck/expected/check_btree.out

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,18 @@ SELECT bt_index_check('bttest_unique_nulls_b_c_idx', heapallindexed => true, che
240240

241241
(1 row)
242242

243+
-- Check support of both 1B and 4B header sizes of short varlena datum
244+
CREATE TABLE varlena_bug (v text);
245+
ALTER TABLE varlena_bug ALTER column v SET storage plain;
246+
INSERT INTO varlena_bug VALUES ('x');
247+
COPY varlena_bug from stdin;
248+
CREATE INDEX varlena_bug_idx on varlena_bug(v);
249+
SELECT bt_index_check('varlena_bug_idx', true);
250+
bt_index_check
251+
----------------
252+
253+
(1 row)
254+
243255
-- cleanup
244256
DROP TABLE bttest_a;
245257
DROP TABLE bttest_b;
@@ -250,3 +262,4 @@ DROP FUNCTION ifun(int8);
250262
DROP TABLE bttest_unique_nulls;
251263
DROP OWNED BY regress_bttest_role; -- permissions
252264
DROP ROLE regress_bttest_role;
265+
DROP TABLE varlena_bug;

‎contrib/amcheck/sql/check_btree.sql

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,16 @@ SELECT bt_index_check('bttest_unique_nulls_c_key', heapallindexed => true, check
148148
CREATEINDEXon bttest_unique_nulls (b,c);
149149
SELECT bt_index_check('bttest_unique_nulls_b_c_idx', heapallindexed=> true, checkunique=> true);
150150

151+
-- Check support of both 1B and 4B header sizes of short varlena datum
152+
CREATETABLEvarlena_bug (vtext);
153+
ALTERTABLE varlena_bug ALTER column vSET storage plain;
154+
INSERT INTO varlena_bugVALUES ('x');
155+
COPY varlena_bugfrom stdin;
156+
x
157+
\.
158+
CREATEINDEXvarlena_bug_idxon varlena_bug(v);
159+
SELECT bt_index_check('varlena_bug_idx', true);
160+
151161
-- cleanup
152162
DROPTABLE bttest_a;
153163
DROPTABLE bttest_b;
@@ -158,3 +168,4 @@ DROP FUNCTION ifun(int8);
158168
DROPTABLE bttest_unique_nulls;
159169
DROP OWNED BY regress_bttest_role;-- permissions
160170
DROP ROLE regress_bttest_role;
171+
DROPTABLE varlena_bug;

‎contrib/amcheck/verify_nbtree.c

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2943,7 +2943,7 @@ bt_normalize_tuple(BtreeCheckState *state, IndexTuple itup)
29432943
TupleDesctupleDescriptor=RelationGetDescr(state->rel);
29442944
Datumnormalized[INDEX_MAX_KEYS];
29452945
boolisnull[INDEX_MAX_KEYS];
2946-
booltoast_free[INDEX_MAX_KEYS];
2946+
boolneed_free[INDEX_MAX_KEYS];
29472947
boolformnewtup= false;
29482948
IndexTuplereformed;
29492949
inti;
@@ -2962,7 +2962,7 @@ bt_normalize_tuple(BtreeCheckState *state, IndexTuple itup)
29622962
att=TupleDescAttr(tupleDescriptor,i);
29632963

29642964
/* Assume untoasted/already normalized datum initially */
2965-
toast_free[i]= false;
2965+
need_free[i]= false;
29662966
normalized[i]=index_getattr(itup,att->attnum,
29672967
tupleDescriptor,
29682968
&isnull[i]);
@@ -2985,11 +2985,32 @@ bt_normalize_tuple(BtreeCheckState *state, IndexTuple itup)
29852985
{
29862986
formnewtup= true;
29872987
normalized[i]=PointerGetDatum(PG_DETOAST_DATUM(normalized[i]));
2988-
toast_free[i]= true;
2988+
need_free[i]= true;
2989+
}
2990+
2991+
/*
2992+
* Short tuples may have 1B or 4B header. Convert 4B header of short
2993+
* tuples to 1B
2994+
*/
2995+
elseif (VARATT_CAN_MAKE_SHORT(DatumGetPointer(normalized[i])))
2996+
{
2997+
/* convert to short varlena */
2998+
Sizelen=VARATT_CONVERTED_SHORT_SIZE(DatumGetPointer(normalized[i]));
2999+
char*data=palloc(len);
3000+
3001+
SET_VARSIZE_SHORT(data,len);
3002+
memcpy(data+1,VARDATA(DatumGetPointer(normalized[i])),len-1);
3003+
3004+
formnewtup= true;
3005+
normalized[i]=PointerGetDatum(data);
3006+
need_free[i]= true;
29893007
}
29903008
}
29913009

2992-
/* Easier case: Tuple has varlena datums, none of which are compressed */
3010+
/*
3011+
* Easier case: Tuple has varlena datums, none of which are compressed or
3012+
* short with 4B header
3013+
*/
29933014
if (!formnewtup)
29943015
returnitup;
29953016

@@ -2999,6 +3020,11 @@ bt_normalize_tuple(BtreeCheckState *state, IndexTuple itup)
29993020
* (normalized input datums). This is rather naive, but shouldn't be
30003021
* necessary too often.
30013022
*
3023+
* In the heap, tuples may contain short varlena datums with both 1B
3024+
* header and 4B headers. But the corresponding index tuple should always
3025+
* have such varlena's with 1B headers. So, if there is a short varlena
3026+
* with 4B header, we need to convert it for for fingerprinting.
3027+
*
30023028
* Note that we rely on deterministic index_form_tuple() TOAST compression
30033029
* of normalized input.
30043030
*/
@@ -3007,7 +3033,7 @@ bt_normalize_tuple(BtreeCheckState *state, IndexTuple itup)
30073033

30083034
/* Cannot leak memory here */
30093035
for (i=0;i<tupleDescriptor->natts;i++)
3010-
if (toast_free[i])
3036+
if (need_free[i])
30113037
pfree(DatumGetPointer(normalized[i]));
30123038

30133039
returnreformed;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp