if (isnull)
{
report_toast_corruption(ctx, ta,
- pstrdup("toast chunk sequence number is null"));
+ psprintf("toast value %u has toast chunk with null sequence number",
+ ta->toast_pointer.va_valueid));
return;
}
chunk = DatumGetPointer(fastgetattr(toasttup, 3,
if (isnull)
{
report_toast_corruption(ctx, ta,
- pstrdup("toast chunk data is null"));
+ psprintf("toast value %u chunk %d has null data",
+ ta->toast_pointer.va_valueid, chunkno));
return;
}
if (!VARATT_IS_EXTENDED(chunk))
uint32 header = ((varattrib_4b *) chunk)->va_4byte.va_header;
report_toast_corruption(ctx, ta,
- psprintf("corrupt extended toast chunk has invalid varlena header: %0x (sequence number %d)",
- header, curchunk));
+ psprintf("toast value %u chunk %d has invalid varlena header %0x",
+ ta->toast_pointer.va_valueid,
+ chunkno, header));
return;
}
if (curchunk != chunkno)
{
report_toast_corruption(ctx, ta,
- psprintf("toast chunk sequence number %u does not match the expected sequence number %u",
- curchunk, chunkno));
+ psprintf("toast value %u chunk %d has sequence number %d, but expected sequence number %d",
+ ta->toast_pointer.va_valueid,
+ chunkno, curchunk, chunkno));
return;
}
- if (curchunk > endchunk)
+ if (chunkno > endchunk)
{
report_toast_corruption(ctx, ta,
- psprintf("toast chunk sequence number %u exceeds the end chunk sequence number %u",
- curchunk, endchunk));
+ psprintf("toast value %u chunk %d follows last expected chunk %d",
+ ta->toast_pointer.va_valueid,
+ chunkno, endchunk));
return;
}
if (chunksize != expected_size)
report_toast_corruption(ctx, ta,
- psprintf("toast chunk size %u differs from the expected size %u",
- chunksize, expected_size));
+ psprintf("toast value %u chunk %d has size %u, but expected size %u",
+ ta->toast_pointer.va_valueid,
+ chunkno, chunksize, expected_size));
}
/*
char *tp; /* pointer to the tuple data */
uint16 infomask;
Form_pg_attribute thisatt;
+ struct varatt_external toast_pointer;
infomask = ctx->tuphdr->t_infomask;
thisatt = TupleDescAttr(RelationGetDescr(ctx->rel), ctx->attnum);
if (ctx->tuphdr->t_hoff + ctx->offset > ctx->lp_len)
{
report_corruption(ctx,
- psprintf("attribute %u with length %u starts at offset %u beyond total tuple length %u",
- ctx->attnum,
+ psprintf("attribute with length %u starts at offset %u beyond total tuple length %u",
thisatt->attlen,
ctx->tuphdr->t_hoff + ctx->offset,
ctx->lp_len));
if (ctx->tuphdr->t_hoff + ctx->offset > ctx->lp_len)
{
report_corruption(ctx,
- psprintf("attribute %u with length %u ends at offset %u beyond total tuple length %u",
- ctx->attnum,
+ psprintf("attribute with length %u ends at offset %u beyond total tuple length %u",
thisatt->attlen,
ctx->tuphdr->t_hoff + ctx->offset,
ctx->lp_len));
if (va_tag != VARTAG_ONDISK)
{
report_corruption(ctx,
- psprintf("toasted attribute %u has unexpected TOAST tag %u",
- ctx->attnum,
+ psprintf("toasted attribute has unexpected TOAST tag %u",
va_tag));
/* We can't know where the next attribute begins */
return false;
if (ctx->tuphdr->t_hoff + ctx->offset > ctx->lp_len)
{
report_corruption(ctx,
- psprintf("attribute %u with length %u ends at offset %u beyond total tuple length %u",
- ctx->attnum,
+ psprintf("attribute with length %u ends at offset %u beyond total tuple length %u",
thisatt->attlen,
ctx->tuphdr->t_hoff + ctx->offset,
ctx->lp_len));
/* It is external, and we're looking at a page on disk */
+ /*
+ * Must copy attr into toast_pointer for alignment considerations
+ */
+ VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr);
+
/* The tuple header better claim to contain toasted values */
if (!(infomask & HEAP_HASEXTERNAL))
{
report_corruption(ctx,
- psprintf("attribute %u is external but tuple header flag HEAP_HASEXTERNAL not set",
- ctx->attnum));
+ psprintf("toast value %u is external but tuple header flag HEAP_HASEXTERNAL not set",
+ toast_pointer.va_valueid));
return true;
}
if (!ctx->rel->rd_rel->reltoastrelid)
{
report_corruption(ctx,
- psprintf("attribute %u is external but relation has no toast relation",
- ctx->attnum));
+ psprintf("toast value %u is external but relation has no toast relation",
+ toast_pointer.va_valueid));
return true;
}
if (!found_toasttup)
report_toast_corruption(ctx, ta,
- psprintf("toasted value for attribute %u missing from toast table",
- ta->attnum));
+ psprintf("toast value %u not found in toast table",
+ ta->toast_pointer.va_valueid));
else if (chunkno != (endchunk + 1))
report_toast_corruption(ctx, ta,
- psprintf("final toast chunk number %u differs from expected value %u",
- chunkno, (endchunk + 1)));
+ psprintf("toast value %u was expected to end at chunk %u, but ended at chunk %u",
+ ta->toast_pointer.va_valueid,
+ (endchunk + 1), chunkno));
}
/*