mcv-serialization-fix.patch

text/plain

Filename: mcv-serialization-fix.patch
Type: text/plain
Part: 0
Message: Re: mcvstats serialization code is still shy of a load

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));