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