in src/backend/access/common/memtuple.c [201:415]
static void create_col_bind(MemTupleBindingCols *colbind, bool islarge, TupleDesc tupdesc, int col_align)
{
int i = 0;
int physical_col = 0;
int pass = 0;
uint32 cur_offset = (col_align == 8) ? 8 : 4;
uint32 null_save_entries = compute_null_save_entries(tupdesc->natts);
/* alloc null save entries. Zero it */
colbind->null_saves = (short *) palloc0(sizeof(short) * null_save_entries);
colbind->null_saves_aligned = (short *) palloc0(sizeof(short) * null_save_entries);
colbind->has_null_saves_alignment_mismatch = false;
colbind->has_dropped_attr_alignment_mismatch = false;
/* alloc bindings, no need to zero because we will fill them out */
colbind->bindings = (MemTupleAttrBinding *) palloc(sizeof(MemTupleAttrBinding) * tupdesc->natts);
/*
* The length of each binding is determined according to the alignment
* of the physically following binding. Use this pointer to keep track
* of the previously processed binding.
*/
MemTupleAttrBinding *previous_bind = NULL;
/*
* First pass, do 8 bytes aligned, native type.
* Sencond pass, do 4 bytes aligned, native type.
* Third pass, do 2 bytes aligned, native type.
* Finall, do 1 bytes aligned native type.
*
* depends on islarge, varlena types are either handled in the
* second pass (is large, varoffset using 4 bytes), or in the
* third pass (not large, varoffset using 2 bytes).
*/
for(pass =0; pass < 4; ++pass)
{
for(i=0; i<tupdesc->natts; ++i)
{
Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
MemTupleAttrBinding *bind = &colbind->bindings[i];
if(pass == 0 && attr->attlen > 0 && attr->attalign == 'd')
{
bind->offset = att_align_nominal(cur_offset, attr->attalign);
bind->len = attr->attlen;
add_null_save(colbind->null_saves, physical_col, attr->attlen);
if (physical_col)
{
/* Set the aligned length of the previous binding according to current alignment. */
if (add_null_save_aligned(previous_bind, colbind->null_saves_aligned, physical_col - 1, 'd'))
{
colbind->has_null_saves_alignment_mismatch = true;
if (attr->attisdropped)
{
colbind->has_dropped_attr_alignment_mismatch = true;
}
}
}
bind->flag = attr->attbyval ? MTB_ByVal_Native : MTB_ByVal_Ptr;
bind->null_byte = physical_col >> 3;
bind->null_mask = 1 << (physical_col-(bind->null_byte << 3));
physical_col += 1;
cur_offset = bind->offset + bind->len;
previous_bind = bind;
}
else if (pass == 1 &&( (attr->attlen > 0 && attr->attalign == 'i')
|| ( islarge && att_bind_as_varoffset(attr))
)
)
{
bind->offset = att_align_nominal(cur_offset, 'i');
bind->len = attr->attlen > 0 ? attr->attlen : 4;
add_null_save(colbind->null_saves, physical_col, bind->len);
if (physical_col)
{
/* Set the aligned length of the previous binding according to current alignment. */
if (add_null_save_aligned(previous_bind, colbind->null_saves_aligned, physical_col - 1, 'i'))
{
colbind->has_null_saves_alignment_mismatch = true;
if (attr->attisdropped)
{
colbind->has_dropped_attr_alignment_mismatch = true;
}
}
}
if(attr->attlen > 0)
bind->flag = attr->attbyval ? MTB_ByVal_Native : MTB_ByVal_Ptr;
else if(attr->attlen == -1)
bind->flag = MTB_ByRef;
else
{
Assert(attr->attlen == -2);
bind->flag = MTB_ByRef_CStr;
}
bind->null_byte = physical_col >> 3;
bind->null_mask = 1 << (physical_col-(bind->null_byte << 3));
physical_col += 1;
cur_offset = bind->offset + bind->len;
previous_bind = bind;
}
else if (pass == 2 && ( (attr->attlen > 0 && attr->attalign == 's')
|| ( !islarge && att_bind_as_varoffset(attr))
)
)
{
bind->offset = att_align_nominal(cur_offset, 's');
bind->len = attr->attlen > 0 ? attr->attlen : 2;
add_null_save(colbind->null_saves, physical_col, bind->len);
if (physical_col)
{
/* Set the aligned length of the previous binding according to current alignment. */
if (add_null_save_aligned(previous_bind, colbind->null_saves_aligned, physical_col - 1, 's'))
{
colbind->has_null_saves_alignment_mismatch = true;
if (attr->attisdropped)
{
colbind->has_dropped_attr_alignment_mismatch = true;
}
}
}
if(attr->attlen > 0)
bind->flag = attr->attbyval ? MTB_ByVal_Native : MTB_ByVal_Ptr;
else if(attr->attlen == -1)
bind->flag = MTB_ByRef;
else
{
Assert(attr->attlen == -2);
bind->flag = MTB_ByRef_CStr;
}
bind->null_byte = physical_col >> 3;
bind->null_mask = 1 << (physical_col-(bind->null_byte << 3));
physical_col += 1;
cur_offset = bind->offset + bind->len;
previous_bind = bind;
}
else if (pass == 3 && (
(attr->attlen > 0 && attr->attalign == 'c')
|| (attr->attlen < 0 && !att_bind_as_varoffset(attr))
)
)
{
bind->offset = att_align_nominal(cur_offset, 'c');
#ifdef MEMTUPLE_INLINE_CHARTYPE
/* Inline CHAR(N) disabled. See att_bind_as_varoffset */
bind->len = attr->attlen > 0 ? attr->attlen : (attr->atttypmod - 3);
#else
bind->len = attr->attlen;
#endif
add_null_save(colbind->null_saves, physical_col, 1);
if (physical_col)
{
/* Set the aligned length of the previous binding according to current alignment. */
if (add_null_save_aligned(previous_bind, colbind->null_saves_aligned, physical_col - 1, 'c'))
{
colbind->has_null_saves_alignment_mismatch = true;
if (attr->attisdropped)
{
colbind->has_dropped_attr_alignment_mismatch = true;
}
}
}
if(attr->attlen > 0 && attr->attbyval)
bind->flag = MTB_ByVal_Native;
else
bind->flag = MTB_ByVal_Ptr;
bind->null_byte = physical_col >> 3;
bind->null_mask = 1 << (physical_col-(bind->null_byte << 3));
physical_col += 1;
cur_offset = bind->offset + bind->len;
previous_bind = bind;
}
}
}
if (physical_col)
{
/* No extra alignment required for the last binding */
add_null_save_aligned(previous_bind, colbind->null_saves_aligned, physical_col - 1, 'c');
}
if (!colbind->has_null_saves_alignment_mismatch)
{
pfree(colbind->null_saves);
colbind->null_saves = NULL;
}
#ifdef USE_DEBUG_ASSERT
for(i=0; i<tupdesc->natts; ++i)
{
MemTupleAttrBinding *bind = &colbind->bindings[i];
Assert(bind->offset[i] != 0);
}
#endif
if(tupdesc->natts != 0)
colbind->var_start = cur_offset;
else
colbind->var_start = 8;
Assert(tupdesc->natts == physical_col);
}