aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Vondra <tomas.vondra@postgresql.org>2019-03-30 18:34:59 +0100
committerTomas Vondra <tomas.vondra@postgresql.org>2019-03-30 18:34:59 +0100
commitea4e1c0e8f583f99c8caab5bcdfbbbaaed0685c0 (patch)
tree80a7d7d2146ff7a8ec3e56e17b8eab566870f201
parent7ad6498fd5a654de6e743814c36cf619a3b5ddb6 (diff)
downloadpostgresql-ea4e1c0e8f583f99c8caab5bcdfbbbaaed0685c0.tar.gz
postgresql-ea4e1c0e8f583f99c8caab5bcdfbbbaaed0685c0.zip
Additional fixes of memory alignment in pg_mcv_list code
Commit d85e0f366a 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.
-rw-r--r--src/backend/statistics/mcv.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/src/backend/statistics/mcv.c b/src/backend/statistics/mcv.c
index e90a03fdf79..c5288b42d6f 100644
--- a/src/backend/statistics/mcv.c
+++ b/src/backend/statistics/mcv.c
@@ -51,7 +51,7 @@
* ndim * (sizeof(uint16) + sizeof(bool)) + 2 * sizeof(double)
*/
#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.
@@ -929,8 +929,8 @@ statext_mcv_deserialize(bytea *data)
mcvlen = MAXALIGN(offsetof(MCVList, items) + (sizeof(MCVItem) * nitems));
/* arrays of values and isnull flags for all MCV items */
- mcvlen += MAXALIGN(sizeof(Datum) * ndims * nitems);
- mcvlen += MAXALIGN(sizeof(bool) * ndims * nitems);
+ mcvlen += nitems * MAXALIGN(sizeof(Datum) * ndims);
+ mcvlen += nitems * MAXALIGN(sizeof(bool) * ndims);
/* we don't quite need to align this, but it makes some assers easier */
mcvlen += MAXALIGN(datalen);
@@ -942,9 +942,9 @@ statext_mcv_deserialize(bytea *data)
valuesptr = (char *) mcvlist
+ 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
@@ -1043,10 +1043,11 @@ statext_mcv_deserialize(bytea *data)
MCVItem *item = &mcvlist->items[i];
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 */
indexes = ITEM_INDEXES(ptr);