@@ -1179,15 +1179,17 @@ check_toast_tuple(HeapTuple toasttup, HeapCheckContext *ctx,
11791179if (isnull )
11801180{
11811181report_toast_corruption (ctx ,ta ,
1182- pstrdup ("toast chunk sequence number is null" ));
1182+ psprintf ("toast value %u has toast chunk with null sequence number" ,
1183+ ta -> toast_pointer .va_valueid ));
11831184return ;
11841185}
11851186chunk = DatumGetPointer (fastgetattr (toasttup ,3 ,
11861187ctx -> toast_rel -> rd_att ,& isnull ));
11871188if (isnull )
11881189{
11891190report_toast_corruption (ctx ,ta ,
1190- pstrdup ("toast chunk data is null" ));
1191+ psprintf ("toast value %u chunk %d has null data" ,
1192+ ta -> toast_pointer .va_valueid ,chunkno ));
11911193return ;
11921194}
11931195if (!VARATT_IS_EXTENDED (chunk ))
@@ -1205,8 +1207,9 @@ check_toast_tuple(HeapTuple toasttup, HeapCheckContext *ctx,
12051207uint32 header = ((varattrib_4b * )chunk )-> va_4byte .va_header ;
12061208
12071209report_toast_corruption (ctx ,ta ,
1208- psprintf ("corrupt extended toast chunk has invalid varlena header: %0x (sequence number %d)" ,
1209- header ,curchunk ));
1210+ psprintf ("toast value %u chunk %d has invalid varlena header %0x" ,
1211+ ta -> toast_pointer .va_valueid ,
1212+ chunkno ,header ));
12101213return ;
12111214}
12121215
@@ -1216,15 +1219,17 @@ check_toast_tuple(HeapTuple toasttup, HeapCheckContext *ctx,
12161219if (curchunk != chunkno )
12171220{
12181221report_toast_corruption (ctx ,ta ,
1219- psprintf ("toast chunk sequence number %u does not match the expected sequence number %u" ,
1220- curchunk ,chunkno ));
1222+ psprintf ("toast value %u chunk %d has sequence number %d, but expected sequence number %d" ,
1223+ ta -> toast_pointer .va_valueid ,
1224+ chunkno ,curchunk ,chunkno ));
12211225return ;
12221226}
1223- if (curchunk > endchunk )
1227+ if (chunkno > endchunk )
12241228{
12251229report_toast_corruption (ctx ,ta ,
1226- psprintf ("toast chunk sequence number %u exceeds the end chunk sequence number %u" ,
1227- curchunk ,endchunk ));
1230+ psprintf ("toast value %u chunk %d follows last expected chunk %d" ,
1231+ ta -> toast_pointer .va_valueid ,
1232+ chunkno ,endchunk ));
12281233return ;
12291234}
12301235
@@ -1233,8 +1238,9 @@ check_toast_tuple(HeapTuple toasttup, HeapCheckContext *ctx,
12331238
12341239if (chunksize != expected_size )
12351240report_toast_corruption (ctx ,ta ,
1236- psprintf ("toast chunk size %u differs from the expected size %u" ,
1237- chunksize ,expected_size ));
1241+ psprintf ("toast value %u chunk %d has size %u, but expected size %u" ,
1242+ ta -> toast_pointer .va_valueid ,
1243+ chunkno ,chunksize ,expected_size ));
12381244}
12391245
12401246/*
@@ -1265,6 +1271,7 @@ check_tuple_attribute(HeapCheckContext *ctx)
12651271char * tp ;/* pointer to the tuple data */
12661272uint16 infomask ;
12671273Form_pg_attribute thisatt ;
1274+ struct varatt_external toast_pointer ;
12681275
12691276infomask = ctx -> tuphdr -> t_infomask ;
12701277thisatt = TupleDescAttr (RelationGetDescr (ctx -> rel ),ctx -> attnum );
@@ -1274,8 +1281,7 @@ check_tuple_attribute(HeapCheckContext *ctx)
12741281if (ctx -> tuphdr -> t_hoff + ctx -> offset > ctx -> lp_len )
12751282{
12761283report_corruption (ctx ,
1277- psprintf ("attribute %u with length %u starts at offset %u beyond total tuple length %u" ,
1278- ctx -> attnum ,
1284+ psprintf ("attribute with length %u starts at offset %u beyond total tuple length %u" ,
12791285thisatt -> attlen ,
12801286ctx -> tuphdr -> t_hoff + ctx -> offset ,
12811287ctx -> lp_len ));
@@ -1295,8 +1301,7 @@ check_tuple_attribute(HeapCheckContext *ctx)
12951301if (ctx -> tuphdr -> t_hoff + ctx -> offset > ctx -> lp_len )
12961302{
12971303report_corruption (ctx ,
1298- psprintf ("attribute %u with length %u ends at offset %u beyond total tuple length %u" ,
1299- ctx -> attnum ,
1304+ psprintf ("attribute with length %u ends at offset %u beyond total tuple length %u" ,
13001305thisatt -> attlen ,
13011306ctx -> tuphdr -> t_hoff + ctx -> offset ,
13021307ctx -> lp_len ));
@@ -1328,8 +1333,7 @@ check_tuple_attribute(HeapCheckContext *ctx)
13281333if (va_tag != VARTAG_ONDISK )
13291334{
13301335report_corruption (ctx ,
1331- psprintf ("toasted attribute %u has unexpected TOAST tag %u" ,
1332- ctx -> attnum ,
1336+ psprintf ("toasted attribute has unexpected TOAST tag %u" ,
13331337va_tag ));
13341338/* We can't know where the next attribute begins */
13351339return false;
@@ -1343,8 +1347,7 @@ check_tuple_attribute(HeapCheckContext *ctx)
13431347if (ctx -> tuphdr -> t_hoff + ctx -> offset > ctx -> lp_len )
13441348{
13451349report_corruption (ctx ,
1346- psprintf ("attribute %u with length %u ends at offset %u beyond total tuple length %u" ,
1347- ctx -> attnum ,
1350+ psprintf ("attribute with length %u ends at offset %u beyond total tuple length %u" ,
13481351thisatt -> attlen ,
13491352ctx -> tuphdr -> t_hoff + ctx -> offset ,
13501353ctx -> lp_len ));
@@ -1371,21 +1374,26 @@ check_tuple_attribute(HeapCheckContext *ctx)
13711374
13721375/* It is external, and we're looking at a page on disk */
13731376
1377+ /*
1378+ * Must copy attr into toast_pointer for alignment considerations
1379+ */
1380+ VARATT_EXTERNAL_GET_POINTER (toast_pointer ,attr );
1381+
13741382/* The tuple header better claim to contain toasted values */
13751383if (!(infomask & HEAP_HASEXTERNAL ))
13761384{
13771385report_corruption (ctx ,
1378- psprintf ("attribute %u is external but tuple header flag HEAP_HASEXTERNAL not set" ,
1379- ctx -> attnum ));
1386+ psprintf ("toast value %u is external but tuple header flag HEAP_HASEXTERNAL not set" ,
1387+ toast_pointer . va_valueid ));
13801388return true;
13811389}
13821390
13831391/* The relation better have a toast table */
13841392if (!ctx -> rel -> rd_rel -> reltoastrelid )
13851393{
13861394report_corruption (ctx ,
1387- psprintf ("attribute %u is external but relation has no toast relation" ,
1388- ctx -> attnum ));
1395+ psprintf ("toast value %u is external but relation has no toast relation" ,
1396+ toast_pointer . va_valueid ));
13891397return true;
13901398}
13911399
@@ -1464,12 +1472,13 @@ check_toasted_attribute(HeapCheckContext *ctx, ToastedAttribute *ta)
14641472
14651473if (!found_toasttup )
14661474report_toast_corruption (ctx ,ta ,
1467- psprintf ("toasted valuefor attribute %umissing from toast table" ,
1468- ta -> attnum ));
1475+ psprintf ("toast value %unot found in toast table" ,
1476+ ta -> toast_pointer . va_valueid ));
14691477else if (chunkno != (endchunk + 1 ))
14701478report_toast_corruption (ctx ,ta ,
1471- psprintf ("final toast chunk number %u differs from expected value %u" ,
1472- chunkno , (endchunk + 1 )));
1479+ psprintf ("toast value %u was expected to end at chunk %u, but ended at chunk %u" ,
1480+ ta -> toast_pointer .va_valueid ,
1481+ (endchunk + 1 ),chunkno ));
14731482}
14741483
14751484/*