Assert(ndistinct->type == STATS_NDISTINCT_TYPE_BASIC);
 
        /*
-        * Base size is base struct size, plus one base struct for each items,
-        * including number of items for each.
+        * Base size is size of scalar fields in the struct, plus one base struct
+        * for each item, including number of items for each.
         */
-       len = VARHDRSZ + offsetof(MVNDistinct, items) +
+       len = VARHDRSZ + SizeOfMVNDistinct +
                ndistinct->nitems * (offsetof(MVNDistinctItem, attrs) + sizeof(int));
 
        /* and also include space for the actual attribute numbers */
 
        tmp = VARDATA(output);
 
-       /* Store the base struct values */
-       memcpy(tmp, ndistinct, offsetof(MVNDistinct, items));
-       tmp += offsetof(MVNDistinct, items);
+       /* Store the base struct values (magic, type, nitems) */
+       memcpy(tmp, &ndistinct->magic, sizeof(uint32));
+       tmp += sizeof(uint32);
+       memcpy(tmp, &ndistinct->type, sizeof(uint32));
+       tmp += sizeof(uint32);
+       memcpy(tmp, &ndistinct->nitems, sizeof(uint32));
+       tmp += sizeof(uint32);
 
        /*
         * store number of attributes and attribute numbers for each ndistinct
 statext_ndistinct_deserialize(bytea *data)
 {
        int                     i;
-       Size            expected_size;
+       Size            minimum_size;
+       MVNDistinct     ndist;
        MVNDistinct *ndistinct;
        char       *tmp;
 
        if (data == NULL)
                return NULL;
 
-       if (VARSIZE_ANY_EXHDR(data) < offsetof(MVNDistinct, items))
+       /* we expect at least the basic fields of MVNDistinct struct */
+       if (VARSIZE_ANY_EXHDR(data) < SizeOfMVNDistinct)
                elog(ERROR, "invalid MVNDistinct size %ld (expected at least %ld)",
-                        VARSIZE_ANY_EXHDR(data), offsetof(MVNDistinct, items));
-
-       /* read the MVNDistinct header */
-       ndistinct = (MVNDistinct *) palloc(sizeof(MVNDistinct));
+                        VARSIZE_ANY_EXHDR(data), SizeOfMVNDistinct);
 
        /* initialize pointer to the data part (skip the varlena header) */
        tmp = VARDATA_ANY(data);
 
-       /* get the header and perform basic sanity checks */
-       memcpy(ndistinct, tmp, offsetof(MVNDistinct, items));
-       tmp += offsetof(MVNDistinct, items);
-
-       if (ndistinct->magic != STATS_NDISTINCT_MAGIC)
-               elog(ERROR, "invalid ndistinct magic %d (expected %d)",
-                        ndistinct->magic, STATS_NDISTINCT_MAGIC);
-
-       if (ndistinct->type != STATS_NDISTINCT_TYPE_BASIC)
-               elog(ERROR, "invalid ndistinct type %d (expected %d)",
-                        ndistinct->type, STATS_NDISTINCT_TYPE_BASIC);
-
-       Assert(ndistinct->nitems > 0);
+       /* read the header fields and perform basic sanity checks */
+       memcpy(&ndist.magic, tmp, sizeof(uint32));
+       tmp += sizeof(uint32);
+       memcpy(&ndist.type, tmp, sizeof(uint32));
+       tmp += sizeof(uint32);
+       memcpy(&ndist.nitems, tmp, sizeof(uint32));
+       tmp += sizeof(uint32);
+
+       if (ndist.magic != STATS_NDISTINCT_MAGIC)
+               ereport(ERROR,
+                               (errcode(ERRCODE_DATA_CORRUPTED),
+                                errmsg("invalid ndistinct magic %08x (expected %08x)",
+                                               ndist.magic, STATS_NDISTINCT_MAGIC)));
+       if (ndist.type != STATS_NDISTINCT_TYPE_BASIC)
+               ereport(ERROR,
+                               (errcode(ERRCODE_DATA_CORRUPTED),
+                                errmsg("invalid ndistinct type %d (expected %d)",
+                                               ndist.type, STATS_NDISTINCT_TYPE_BASIC)));
+       if (ndist.nitems == 0)
+               ereport(ERROR,
+                               (errcode(ERRCODE_DATA_CORRUPTED),
+                                errmsg("invalid zero-length item array in MVNDistinct")));
 
        /* what minimum bytea size do we expect for those parameters */
-       expected_size = offsetof(MVNDistinct, items) +
-               ndistinct->nitems * (offsetof(MVNDistinctItem, attrs) +
-                                                        sizeof(AttrNumber) * 2);
+       minimum_size = (SizeOfMVNDistinct +
+                                       ndist.nitems * (SizeOfMVNDistinctItem +
+                                                                       sizeof(AttrNumber) * 2));
+       if (VARSIZE_ANY_EXHDR(data) < minimum_size)
+               ereport(ERROR,
+                               (errcode(ERRCODE_DATA_CORRUPTED),
+                                errmsg("invalid MVNDistinct size %ld (expected at least %ld)",
+                                               VARSIZE_ANY_EXHDR(data), minimum_size)));
 
-       if (VARSIZE_ANY_EXHDR(data) < expected_size)
-               elog(ERROR, "invalid dependencies size %ld (expected at least %ld)",
-                        VARSIZE_ANY_EXHDR(data), expected_size);
-
-       /* allocate space for the ndistinct items */
-       ndistinct = repalloc(ndistinct, offsetof(MVNDistinct, items) +
-                                                (ndistinct->nitems * sizeof(MVNDistinctItem)));
+       /*
+        * Allocate space for the ndistinct items (no space for each item's attnos:
+        * those live in bitmapsets allocated separately)
+        */
+       ndistinct = palloc0(MAXALIGN(SizeOfMVNDistinct) +
+                                               (ndist.nitems * sizeof(MVNDistinctItem)));
+       ndistinct->magic = ndist.magic;
+       ndistinct->type = ndist.type;
+       ndistinct->nitems = ndist.nitems;
 
        for (i = 0; i < ndistinct->nitems; i++)
        {