Gregory Stark stark at enterprisedb.com
Wed May 9 08:13:29 PDT 2007
The coding below from a recent commit to xxid.c is unfortunately unsafe.
Packed varlenas are unaligned (even if the datum itself is aligned the data
within will be unaligned since it follows a 1-byte header). That means
snap->nxip which is an integer and should be 4-byte aligned on most
architectures will land on random alignments.

In fact since the struct itself will require 4-byte alignment the compiler may
not be happy with accessing even single bytes from it if it's in a packed
varlena and stored unaligned.

In short, it's sad but you can't use PG_DETOAST_DATUM_PACKED unless you really
don't care about the alignment of the data which means basically it's only
useful for data like text and bytea which contain just unaligned bytes. Or
perhaps for functions that are just going to memcpy or memcmp the data without
accessing fields within it.

The alternative is to mark the data type as typstorage 'p' which disables
packed storage altogether. That might make sense if you store relatively few
such data and process them frequently so the cpu costs of copying them is
actually greater than the i/o costs of storing padding bytes. int2vector and
oidvector are set like that in part for reasons like that (plus others).

typedef struct
{
	TransactionId xmin;
	TransactionId xmax;
	int			nxip;
	TransactionId xip[1];
}	xxid_snapshot;

...

Datum
_Slony_I_xxid_snapshot_out(PG_FUNCTION_ARGS)
{
	xxid_snapshot *snap = (xxid_snapshot *) VARDATA_ANY(PG_DETOAST_DATUM_PACKED((PG_GETARG_DATUM(0))));

	char	   *str = palloc(28 + snap->nxip * 13);
...


-- 
  Gregory Stark
  EnterpriseDB          http://www.enterprisedb.com



More information about the Slony1-hackers mailing list