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 <[email protected]>
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