@@ -1179,15 +1179,17 @@ check_toast_tuple(HeapTuple toasttup, HeapCheckContext *ctx,
11791179 if (isnull )
11801180 {
11811181 report_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 ));
11831184 return ;
11841185 }
11851186 chunk = DatumGetPointer (fastgetattr (toasttup , 3 ,
11861187 ctx -> toast_rel -> rd_att , & isnull ));
11871188 if (isnull )
11881189 {
11891190 report_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 ));
11911193 return ;
11921194 }
11931195 if (!VARATT_IS_EXTENDED (chunk ))
@@ -1205,8 +1207,9 @@ check_toast_tuple(HeapTuple toasttup, HeapCheckContext *ctx,
12051207 uint32 header = ((varattrib_4b * ) chunk )-> va_4byte .va_header ;
12061208
12071209 report_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 ));
12101213 return ;
12111214 }
12121215
@@ -1216,15 +1219,17 @@ check_toast_tuple(HeapTuple toasttup, HeapCheckContext *ctx,
12161219 if (curchunk != chunkno )
12171220 {
12181221 report_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 ));
12211225 return ;
12221226 }
1223- if (curchunk > endchunk )
1227+ if (chunkno > endchunk )
12241228 {
12251229 report_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 ));
12281233 return ;
12291234 }
12301235
@@ -1233,8 +1238,9 @@ check_toast_tuple(HeapTuple toasttup, HeapCheckContext *ctx,
12331238
12341239 if (chunksize != expected_size )
12351240 report_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)
12651271 char * tp ; /* pointer to the tuple data */
12661272 uint16 infomask ;
12671273 Form_pg_attribute thisatt ;
1274+ struct varatt_external toast_pointer ;
12681275
12691276 infomask = ctx -> tuphdr -> t_infomask ;
12701277 thisatt = TupleDescAttr (RelationGetDescr (ctx -> rel ), ctx -> attnum );
@@ -1274,8 +1281,7 @@ check_tuple_attribute(HeapCheckContext *ctx)
12741281 if (ctx -> tuphdr -> t_hoff + ctx -> offset > ctx -> lp_len )
12751282 {
12761283 report_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" ,
12791285 thisatt -> attlen ,
12801286 ctx -> tuphdr -> t_hoff + ctx -> offset ,
12811287 ctx -> lp_len ));
@@ -1295,8 +1301,7 @@ check_tuple_attribute(HeapCheckContext *ctx)
12951301 if (ctx -> tuphdr -> t_hoff + ctx -> offset > ctx -> lp_len )
12961302 {
12971303 report_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" ,
13001305 thisatt -> attlen ,
13011306 ctx -> tuphdr -> t_hoff + ctx -> offset ,
13021307 ctx -> lp_len ));
@@ -1328,8 +1333,7 @@ check_tuple_attribute(HeapCheckContext *ctx)
13281333 if (va_tag != VARTAG_ONDISK )
13291334 {
13301335 report_corruption (ctx ,
1331- psprintf ("toasted attribute %u has unexpected TOAST tag %u" ,
1332- ctx -> attnum ,
1336+ psprintf ("toasted attribute has unexpected TOAST tag %u" ,
13331337 va_tag ));
13341338 /* We can't know where the next attribute begins */
13351339 return false;
@@ -1343,8 +1347,7 @@ check_tuple_attribute(HeapCheckContext *ctx)
13431347 if (ctx -> tuphdr -> t_hoff + ctx -> offset > ctx -> lp_len )
13441348 {
13451349 report_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" ,
13481351 thisatt -> attlen ,
13491352 ctx -> tuphdr -> t_hoff + ctx -> offset ,
13501353 ctx -> 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 */
13751383 if (!(infomask & HEAP_HASEXTERNAL ))
13761384 {
13771385 report_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 ));
13801388 return true;
13811389 }
13821390
13831391 /* The relation better have a toast table */
13841392 if (!ctx -> rel -> rd_rel -> reltoastrelid )
13851393 {
13861394 report_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 ));
13891397 return true;
13901398 }
13911399
@@ -1464,12 +1472,13 @@ check_toasted_attribute(HeapCheckContext *ctx, ToastedAttribute *ta)
14641472
14651473 if (!found_toasttup )
14661474 report_toast_corruption (ctx , ta ,
1467- psprintf ("toasted value for attribute %u missing from toast table" ,
1468- ta -> attnum ));
1475+ psprintf ("toast value %u not found in toast table" ,
1476+ ta -> toast_pointer . va_valueid ));
14691477 else if (chunkno != (endchunk + 1 ))
14701478 report_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/*
0 commit comments