raw_flags
  • HEAP_HASVARWIDTH 0x0002: some attribute is variable-width
  • HEAP_XMIN_COMMITTED 0x0100: hint: xmin is known to have committed
  • HEAP_XMAX_INVALID 0x0800: hint: xmax is invalid or aborted, so no delete, update or lock holds
combined_flags
none
Attributes
3t_infomask2 & 0x07FF: how many the tuple stores

Worked out as heap_tuple_infomask_flags() works it out in PostgreSQL 18.3, and tested against what it prints. With JavaScript off, this is the example the build worked out.

How it is worked out

raw_flags      = every bit set, t_infomask first, then t_infomask2
combined_flags = each two-bit state with both bits set
natts          = t_infomask2 & 0x07FF

Every tuple header carries two 16-bit fields. t_infomask says what the tuple holds (nulls, variable-width values, values stored out of line) and what is known about its xmin and xmax; t_infomask2 has three flags in its top bits and the number of attributes in its low 11.

The hint bits (HEAP_XMIN_COMMITTED and the other three) are set by whoever first looks up a transaction in pg_xact, often a plain SELECT. The same row can show a different t_infomask before and after it is read.

HEAP_MOVED_OFF and HEAP_MOVED_IN date from VACUUM FULL before 9.0. Nothing sets them now; they are still read, for clusters upgraded with pg_upgrade.

pageinspect prints the two fields as integers, heap_page_items() included; the names come from heap_tuple_infomask_flags(), which this follows flag for flag.

The same answer from a server:

SELECT * FROM heap_tuple_infomask_flags(2306, 3);

For an agent in the browser, where it has WebMCP, this page offers the tool as decode_infomask. Every pocket tool.

↑↓ move · ↵ open · esc close