Commit ea4e1c0e authored by Tomas Vondra's avatar Tomas Vondra

Additional fixes of memory alignment in pg_mcv_list code

Commit d85e0f36 tried to fix memory alignment issues in serialization
and deserialization of pg_mcv_list values, but it was a few bricks shy.
The arrays of uint16 indexes in serialized items was not aligned, and
the both the values and isnull flags were using the same pointer.

Per investigation by Tom Lane on gaur.
parent 7ad6498f
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
* ndim * (sizeof(uint16) + sizeof(bool)) + 2 * sizeof(double) * ndim * (sizeof(uint16) + sizeof(bool)) + 2 * sizeof(double)
*/ */
#define ITEM_SIZE(ndims) \ #define ITEM_SIZE(ndims) \
((ndims) * (sizeof(uint16) + sizeof(bool)) + 2 * sizeof(double)) MAXALIGN((ndims) * (sizeof(uint16) + sizeof(bool)) + 2 * sizeof(double))
/* /*
* Macros for convenient access to parts of a serialized MCV item. * Macros for convenient access to parts of a serialized MCV item.
...@@ -929,8 +929,8 @@ statext_mcv_deserialize(bytea *data) ...@@ -929,8 +929,8 @@ statext_mcv_deserialize(bytea *data)
mcvlen = MAXALIGN(offsetof(MCVList, items) + (sizeof(MCVItem) * nitems)); mcvlen = MAXALIGN(offsetof(MCVList, items) + (sizeof(MCVItem) * nitems));
/* arrays of values and isnull flags for all MCV items */ /* arrays of values and isnull flags for all MCV items */
mcvlen += MAXALIGN(sizeof(Datum) * ndims * nitems); mcvlen += nitems * MAXALIGN(sizeof(Datum) * ndims);
mcvlen += MAXALIGN(sizeof(bool) * ndims * nitems); mcvlen += nitems * MAXALIGN(sizeof(bool) * ndims);
/* we don't quite need to align this, but it makes some assers easier */ /* we don't quite need to align this, but it makes some assers easier */
mcvlen += MAXALIGN(datalen); mcvlen += MAXALIGN(datalen);
...@@ -942,9 +942,9 @@ statext_mcv_deserialize(bytea *data) ...@@ -942,9 +942,9 @@ statext_mcv_deserialize(bytea *data)
valuesptr = (char *) mcvlist valuesptr = (char *) mcvlist
+ MAXALIGN(offsetof(MCVList, items) + (sizeof(MCVItem) * nitems)); + MAXALIGN(offsetof(MCVList, items) + (sizeof(MCVItem) * nitems));
isnullptr = valuesptr + (MAXALIGN(sizeof(Datum) * ndims * nitems)); isnullptr = valuesptr + (nitems * MAXALIGN(sizeof(Datum) * ndims));
dataptr = isnullptr + (MAXALIGN(sizeof(bool) * ndims * nitems)); dataptr = isnullptr + (nitems * MAXALIGN(sizeof(bool) * ndims));
/* /*
* Build mapping (index => value) for translating the serialized data into * Build mapping (index => value) for translating the serialized data into
...@@ -1043,10 +1043,11 @@ statext_mcv_deserialize(bytea *data) ...@@ -1043,10 +1043,11 @@ statext_mcv_deserialize(bytea *data)
MCVItem *item = &mcvlist->items[i]; MCVItem *item = &mcvlist->items[i];
item->values = (Datum *) valuesptr; item->values = (Datum *) valuesptr;
valuesptr += (sizeof(Datum) * ndims); valuesptr += MAXALIGN(sizeof(Datum) * ndims);
item->isnull = (bool *) isnullptr;
isnullptr += MAXALIGN(sizeof(bool) * ndims);
item->isnull = (bool *) valuesptr;
valuesptr += (sizeof(bool) * ndims);
/* just point to the right place */ /* just point to the right place */
indexes = ITEM_INDEXES(ptr); indexes = ITEM_INDEXES(ptr);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment