]> granicus.if.org Git - postgresql/commitdiff
Additional fixes of memory alignment in pg_mcv_list code
authorTomas Vondra <tomas.vondra@postgresql.org>
Sat, 30 Mar 2019 17:34:59 +0000 (18:34 +0100)
committerTomas Vondra <tomas.vondra@postgresql.org>
Sat, 30 Mar 2019 17:34:59 +0000 (18:34 +0100)
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.

src/backend/statistics/mcv.c

index e90a03fdf794cf05a7b99abc565088843d3c4863..c5288b42d6f134921bad01456d2128e782e4db0a 100644 (file)
@@ -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);