Home Explore Blog CI



postgresql

14th chunk of `doc/src/sgml/storage.sgml`
a34c8f8dfdfa1cd2b096695f3cdd97eb8dcb9bca872a08020000000100000e0c
 the user data. The header is
  detailed
  in <xref linkend="heaptupleheaderdata-table"/>.  The actual user data
  (columns of the row) begins at the offset indicated by
  <structfield>t_hoff</structfield>, which must always be a multiple of the MAXALIGN
  distance for the platform.
  The null bitmap is
  only present if the <firstterm>HEAP_HASNULL</firstterm> bit is set in
  <structfield>t_infomask</structfield>. If it is present it begins just after
  the fixed header and occupies enough bytes to have one bit per data column
  (that is, the number of bits that equals the attribute count in
  <structfield>t_infomask2</structfield>). In this list of bits, a
  1 bit indicates not-null, a 0 bit is a null.  When the bitmap is not
  present, all columns are assumed not-null.
  The object ID is only present if the <firstterm>HEAP_HASOID_OLD</firstterm> bit
  is set in <structfield>t_infomask</structfield>.  If present, it appears just
  before the <structfield>t_hoff</structfield> boundary.  Any padding needed to make
  <structfield>t_hoff</structfield> a MAXALIGN multiple will appear between the null
  bitmap and the object ID.  (This in turn ensures that the object ID is
  suitably aligned.)

 </para>

 <table tocentry="1" id="heaptupleheaderdata-table">
 <title>HeapTupleHeaderData Layout</title>
 <titleabbrev>HeapTupleHeaderData Layout</titleabbrev>
 <tgroup cols="4">
 <thead>
  <row>
   <entry>Field</entry>
   <entry>Type</entry>
   <entry>Length</entry>
   <entry>Description</entry>
  </row>
 </thead>
 <tbody>
  <row>
   <entry>t_xmin</entry>
   <entry>TransactionId</entry>
   <entry>4 bytes</entry>
   <entry>insert XID stamp</entry>
  </row>
  <row>
   <entry>t_xmax</entry>
   <entry>TransactionId</entry>
   <entry>4 bytes</entry>
   <entry>delete XID stamp</entry>
  </row>
  <row>
   <entry>t_cid</entry>
   <entry>CommandId</entry>
   <entry>4 bytes</entry>
   <entry>insert and/or delete CID stamp (overlays with t_xvac)</entry>
  </row>
  <row>
   <entry>t_xvac</entry>
   <entry>TransactionId</entry>
   <entry>4 bytes</entry>
   <entry>XID for VACUUM operation moving a row version</entry>
  </row>
  <row>
   <entry>t_ctid</entry>
   <entry>ItemPointerData</entry>
   <entry>6 bytes</entry>
   <entry>current TID of this or newer row version</entry>
  </row>
  <row>
   <entry>t_infomask2</entry>
   <entry>uint16</entry>
   <entry>2 bytes</entry>
   <entry>number of attributes, plus various flag bits</entry>
  </row>
  <row>
   <entry>t_infomask</entry>
   <entry>uint16</entry>
   <entry>2 bytes</entry>
   <entry>various flag bits</entry>
  </row>
  <row>
   <entry>t_hoff</entry>
   <entry>uint8</entry>
   <entry>1 byte</entry>
   <entry>offset to user data</entry>
  </row>
 </tbody>
 </tgroup>
 </table>

 <para>
   All the details can be found in
   <filename>src/include/access/htup_details.h</filename>.
 </para>

 <para>

  Interpreting the actual data can only be done with information obtained
  from other tables, mostly <structname>pg_attribute</structname>. The
  key values needed to identify field locations are
  <structfield>attlen</structfield> and <structfield>attalign</structfield>.
  There is no way to directly get a
  particular attribute, except when there are only fixed width fields and no
  null values. All this trickery is wrapped up in the functions
  <firstterm>heap_getattr</firstterm>, <firstterm>fastgetattr</firstterm>
  and <firstterm>heap_getsysattr</firstterm>.

 </para>
 <para>

  To read the data you need to examine each attribute in turn. First check
  whether the field is NULL according to the null bitmap.

Title: HeapTupleHeaderData Layout and Attribute Access
Summary
This section details the layout of the HeapTupleHeaderData, including fields like t_xmin, t_xmax, t_cid, t_ctid, t_infomask2, t_infomask, and t_hoff. It explains how the presence of the null bitmap and object ID is determined by bits in t_infomask, and how padding ensures proper alignment. Accessing the actual data requires information from tables like pg_attribute, using attlen and attalign. Functions like heap_getattr, fastgetattr, and heap_getsysattr are used to access attributes, and the null bitmap is checked to determine if a field is NULL.