It seems odd that stats_ext uses double:

postgres=# SELECT attrelid::regclass, attname, atttypid::regtype, relkind FROM 
pg_attribute a JOIN pg_class c ON c.oid=a.attrelid WHERE 
attname='most_common_freqs';
      attrelid      |      attname      |      atttypid      | relkind 
--------------------+-------------------+--------------------+---------
 pg_stats           | most_common_freqs | real[]             | v
 pg_stats_ext       | most_common_freqs | double precision[] | v
 pg_stats_ext_exprs | most_common_freqs | real[]             | v

I'm not sure if that's deliberate ?

This patch changes extended stats to match.

-- 
Justin
>From cb75c69c8f787eca04f744afc3ffb6388ccf8bf4 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryz...@telsasoft.com>
Date: Tue, 14 Feb 2023 15:30:58 -0600
Subject: [PATCH] WIP: mcv.c: use float4 for mcv frequencies

---
 doc/src/sgml/func.sgml              |  4 ++--
 src/backend/statistics/mcv.c        | 34 ++++++++++++++---------------
 src/include/catalog/pg_proc.dat     |  2 +-
 src/include/statistics/statistics.h |  4 ++--
 4 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index ad0dfe3662d..3b0028b7987 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -28756,12 +28756,12 @@ CREATE EVENT TRIGGER test_table_rewrite_oid
        </row>
        <row>
         <entry><literal>frequency</literal></entry>
-        <entry><type>double precision</type></entry>
+        <entry><type>real</type></entry>
         <entry>frequency of this <acronym>MCV</acronym> item</entry>
        </row>
        <row>
         <entry><literal>base_frequency</literal></entry>
-        <entry><type>double precision</type></entry>
+        <entry><type>real</type></entry>
         <entry>base frequency of this <acronym>MCV</acronym> item</entry>
        </row>
       </tbody>
diff --git a/src/backend/statistics/mcv.c b/src/backend/statistics/mcv.c
index e21e0e87e41..b795cc7b210 100644
--- a/src/backend/statistics/mcv.c
+++ b/src/backend/statistics/mcv.c
@@ -46,16 +46,16 @@
  *
  * - indexes to values	  (ndim * sizeof(uint16))
  * - null flags			  (ndim * sizeof(bool))
- * - frequency			  (sizeof(double))
- * - base_frequency		  (sizeof(double))
+ * - frequency			  (sizeof(float))
+ * - base_frequency		  (sizeof(float))
  *
  * There is no alignment padding within an MCV item.
  * So in total each MCV item requires this many bytes:
  *
- *	 ndim * (sizeof(uint16) + sizeof(bool)) + 2 * sizeof(double)
+ *	 ndim * (sizeof(uint16) + sizeof(bool)) + 2 * sizeof(float)
  */
 #define ITEM_SIZE(ndims)	\
-	((ndims) * (sizeof(uint16) + sizeof(bool)) + 2 * sizeof(double))
+	((ndims) * (sizeof(uint16) + sizeof(bool)) + 2 * sizeof(float))
 
 /*
  * Used to compute size of serialized MCV list representation.
@@ -329,7 +329,7 @@ statext_mcv_build(StatsBuildData *data, double totalrows, int stattarget)
 												sizeof(SortItem),
 												multi_sort_compare, tmp);
 
-				item->base_frequency *= ((double) freq->count) / numrows;
+				item->base_frequency *= ((float) freq->count) / numrows;
 			}
 		}
 
@@ -942,11 +942,11 @@ statext_mcv_serialize(MCVList *mcvlist, VacAttrStats **stats)
 		memcpy(ptr, mcvitem->isnull, sizeof(bool) * ndims);
 		ptr += sizeof(bool) * ndims;
 
-		memcpy(ptr, &mcvitem->frequency, sizeof(double));
-		ptr += sizeof(double);
+		memcpy(ptr, &mcvitem->frequency, sizeof(float));
+		ptr += sizeof(float);
 
-		memcpy(ptr, &mcvitem->base_frequency, sizeof(double));
-		ptr += sizeof(double);
+		memcpy(ptr, &mcvitem->base_frequency, sizeof(float));
+		ptr += sizeof(float);
 
 		/* store the indexes last */
 		for (dim = 0; dim < ndims; dim++)
@@ -1290,11 +1290,11 @@ statext_mcv_deserialize(bytea *data)
 		memcpy(item->isnull, ptr, sizeof(bool) * ndims);
 		ptr += sizeof(bool) * ndims;
 
-		memcpy(&item->frequency, ptr, sizeof(double));
-		ptr += sizeof(double);
+		memcpy(&item->frequency, ptr, sizeof(float));
+		ptr += sizeof(float);
 
-		memcpy(&item->base_frequency, ptr, sizeof(double));
-		ptr += sizeof(double);
+		memcpy(&item->base_frequency, ptr, sizeof(float));
+		ptr += sizeof(float);
 
 		/* finally translate the indexes (for non-NULL only) */
 		for (dim = 0; dim < ndims; dim++)
@@ -1332,8 +1332,8 @@ statext_mcv_deserialize(bytea *data)
  * - item ID (0...nitems)
  * - values (string array)
  * - nulls only (boolean array)
- * - frequency (double precision)
- * - base_frequency (double precision)
+ * - frequency (float precision)
+ * - base_frequency (float precision)
  *
  * The input is the OID of the statistics, and there are no rows returned if
  * the statistics contains no histogram.
@@ -1446,8 +1446,8 @@ pg_stats_ext_mcvlist_items(PG_FUNCTION_ARGS)
 		values[0] = Int32GetDatum(funcctx->call_cntr);
 		values[1] = makeArrayResult(astate_values, CurrentMemoryContext);
 		values[2] = makeArrayResult(astate_nulls, CurrentMemoryContext);
-		values[3] = Float8GetDatum(item->frequency);
-		values[4] = Float8GetDatum(item->base_frequency);
+		values[3] = Float4GetDatum(item->frequency);
+		values[4] = Float4GetDatum(item->base_frequency);
 
 		/* no NULLs in the tuple */
 		memset(nulls, 0, sizeof(nulls));
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 5fec772214f..d35efd00a3f 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -5300,7 +5300,7 @@
 { oid => '3427', descr => 'details about MCV list items',
   proname => 'pg_mcv_list_items', prorows => '1000', proretset => 't',
   provolatile => 's', prorettype => 'record', proargtypes => 'pg_mcv_list',
-  proallargtypes => '{pg_mcv_list,int4,_text,_bool,float8,float8}',
+  proallargtypes => '{pg_mcv_list,int4,_text,_bool,float4,float4}',
   proargmodes => '{i,o,o,o,o,o}',
   proargnames => '{mcv_list,index,values,nulls,frequency,base_frequency}',
   prosrc => 'pg_stats_ext_mcvlist_items' },
diff --git a/src/include/statistics/statistics.h b/src/include/statistics/statistics.h
index 17e3e7f881d..8fc79956b37 100644
--- a/src/include/statistics/statistics.h
+++ b/src/include/statistics/statistics.h
@@ -77,8 +77,8 @@ typedef struct MVDependencies
  */
 typedef struct MCVItem
 {
-	double		frequency;		/* frequency of this combination */
-	double		base_frequency; /* frequency if independent */
+	float		frequency;		/* frequency of this combination */
+	float		base_frequency; /* frequency if independent */
 	bool	   *isnull;			/* NULL flags */
 	Datum	   *values;			/* item values */
 } MCVItem;
-- 
2.34.1

Reply via email to