mcv-serialization-fix.patch
text/plain
Filename: mcv-serialization-fix.patch
Type: text/plain
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/statistics/mcv.c | 13 | 9 |
diff --git a/src/backend/statistics/mcv.c b/src/backend/statistics/mcv.c
index 5fe61ea0a4..01ea05b486 100644
--- a/src/backend/statistics/mcv.c
+++ b/src/backend/statistics/mcv.c
@@ -57,10 +57,10 @@
/*
* Macros for convenient access to parts of a serialized MCV item.
*/
-#define ITEM_INDEXES(item) ((uint16 *) (item))
-#define ITEM_NULLS(item,ndims) ((bool *) (ITEM_INDEXES(item) + (ndims)))
-#define ITEM_FREQUENCY(item,ndims) ((double *) (ITEM_NULLS(item, ndims) + (ndims)))
-#define ITEM_BASE_FREQUENCY(item,ndims) ((double *) (ITEM_FREQUENCY(item, ndims) + 1))
+#define ITEM_INDEXES(item) ((char *) item)
+#define ITEM_NULLS(item,ndims) (ITEM_INDEXES(item) + (ndims) * sizeof(uint16))
+#define ITEM_FREQUENCY(item,ndims) (ITEM_NULLS(item, ndims) + (ndims) * sizeof(bool))
+#define ITEM_BASE_FREQUENCY(item,ndims) (ITEM_FREQUENCY(item, ndims) + sizeof(double))
/*
* Used to compute size of serialized MCV list representation.
@@ -751,6 +751,7 @@ statext_mcv_serialize(MCVList *mcvlist, VacAttrStats **stats)
for (i = 0; i < mcvlist->nitems; i++)
{
MCVItem *mcvitem = &mcvlist->items[i];
+ uint16 *indexes = (uint16 *) ITEM_INDEXES(item);
/* don't write beyond the allocated space */
Assert(ptr <= raw + total_length - itemsize);
@@ -773,10 +774,10 @@ statext_mcv_serialize(MCVList *mcvlist, VacAttrStats **stats)
Assert(value != NULL); /* serialization or deduplication error */
/* compute index within the array */
- ITEM_INDEXES(item)[dim] = (uint16) (value - values[dim]);
+ indexes[dim] = (uint16) (value - values[dim]);
/* check the index is within expected bounds */
- Assert(ITEM_INDEXES(item)[dim] < info[dim].nvalues);
+ Assert(indexes[dim] < info[dim].nvalues);
}
/* copy NULL and frequency flags into the item */
@@ -1087,10 +1088,13 @@ statext_mcv_deserialize(bytea *data)
item->isnull = (bool *) isnullptr;
isnullptr += MAXALIGN(sizeof(bool) * ndims);
+ /*
+ * To access indexes, we can just point to the right place (we can
+ * do this, because we ensure alignment during serialization).
+ */
+ indexes = (uint16 *) ITEM_INDEXES(ptr);
- /* just point to the right place */
- indexes = ITEM_INDEXES(ptr);
-
+ /* The remaining fields may not be aligned, though. */
memcpy(item->isnull, ITEM_NULLS(ptr, ndims), sizeof(bool) * ndims);
memcpy(&item->frequency, ITEM_FREQUENCY(ptr, ndims), sizeof(double));
memcpy(&item->base_frequency, ITEM_BASE_FREQUENCY(ptr, ndims), sizeof(double));