On Mon, Nov 16, 2020 at 06:24:41PM +0100, Tomas Vondra wrote:
> On 1/15/20 12:44 AM, Tom Lane wrote:
> > Tomas Vondra <tomas.von...@2ndquadrant.com> writes:
> >> On Tue, Jan 14, 2020 at 05:37:53PM -0500, Tom Lane wrote:
> >>> I wonder just how messy it would be to add a column to pg_statistic_ext
> >>> whose type is the composite type "pg_statistic", and drop the required
> >>> data into that.  We've not yet used any composite types in the system
> >>> catalogs, AFAIR, but since pg_statistic_ext isn't a bootstrap catalog
> >>> it seems like we might be able to get away with it.
> > 
> > [ I meant pg_statistic_ext_data, obviously ]
> > 
> >> I don't know, but feels a bit awkward to store this type of stats into
> >> pg_statistic_ext, which was meant for multi-column stats. Maybe it'd
> >> work fine, not sure.
> 
> I've started looking at statistics on expressions too, mostly because it
> seems the extended stats improvements (as discussed in [1]) need that.
> 
> The "stash pg_statistic records into pg_statistics_ext_data" approach
> seems simple, but it's not clear to me how to make it work, so I'd
> appreciate some guidance.
> 
> 
> 1) Considering we don't have any composite types in any catalog yet, and
> naive attempts to just use something like
> 
>     pg_statistic stxdexprs[1];
> 
> did not work. So I suppose this will require changes to genbki.pl, but
> honestly, my Perl-fu is non-existent :-(

In the attached, I didn't need to mess with perl.

> 2) Won't it be an issue that pg_statistic contains pseudo-types? That
> is, this does not work, for example:
> 
>     test=# create table t (a pg_statistic[]);
>     ERROR:  column "stavalues1" has pseudo-type anyarray

It works during initdb for the reasons that it's allowed for pg_statistic.

-- 
Justin
>From b9dabd3b773b077e55bb5ea23b89eb3d650029ee Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryz...@telsasoft.com>
Date: Tue, 17 Nov 2020 09:28:33 -0600
Subject: [PATCH 1/2] Allow composite types in bootstrap

---
 src/backend/bootstrap/bootstrap.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index a7ed93fdc1..ed6b3906ee 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -937,6 +937,21 @@ gettype(char *type)
 				return (*app)->am_oid;
 			}
 		}
+
+		/* The type wasn't known; check again to handle composite
+		 * types, added since first populating the array. */
+		Typ = NULL;
+		populate_typ_array();
+
+		/* Need to avoid infinite recursion... */
+		for (app = Typ; *app != NULL; app++)
+		{
+			if (strncmp(NameStr((*app)->am_typ.typname), type, NAMEDATALEN) == 0)
+			{
+				Ap = *app;
+				return (*app)->am_oid;
+			}
+		}
 	}
 	else
 	{
-- 
2.17.0

>From d7246706640d9a7e40805f1861d269cccb3f05ef Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryz...@telsasoft.com>
Date: Tue, 17 Nov 2020 09:47:32 -0600
Subject: [PATCH 2/2] Add pg_statistic_ext_data.stxdexpr

---
 src/backend/catalog/Makefile                | 8 ++++----
 src/backend/commands/statscmds.c            | 2 ++
 src/include/catalog/pg_statistic_ext_data.h | 1 +
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/src/backend/catalog/Makefile b/src/backend/catalog/Makefile
index 2519771210..91db93f64d 100644
--- a/src/backend/catalog/Makefile
+++ b/src/backend/catalog/Makefile
@@ -49,15 +49,15 @@ include $(top_srcdir)/src/backend/common.mk
 
 # Note: the order of this list determines the order in which the catalog
 # header files are assembled into postgres.bki.  BKI_BOOTSTRAP catalogs
-# must appear first, and there are reputedly other, undocumented ordering
-# dependencies.
+# must appear first, and pg_statistic before pg_statistic_ext_data, and there
+# are reputedly other, undocumented ordering dependencies.
 CATALOG_HEADERS := \
 	pg_proc.h pg_type.h pg_attribute.h pg_class.h \
 	pg_attrdef.h pg_constraint.h pg_inherits.h pg_index.h pg_operator.h \
 	pg_opfamily.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \
 	pg_language.h pg_largeobject_metadata.h pg_largeobject.h pg_aggregate.h \
-	pg_statistic_ext.h pg_statistic_ext_data.h \
-	pg_statistic.h pg_rewrite.h pg_trigger.h pg_event_trigger.h pg_description.h \
+	pg_statistic.h pg_statistic_ext.h pg_statistic_ext_data.h \
+	pg_rewrite.h pg_trigger.h pg_event_trigger.h pg_description.h \
 	pg_cast.h pg_enum.h pg_namespace.h pg_conversion.h pg_depend.h \
 	pg_database.h pg_db_role_setting.h pg_tablespace.h \
 	pg_authid.h pg_auth_members.h pg_shdepend.h pg_shdescription.h \
diff --git a/src/backend/commands/statscmds.c b/src/backend/commands/statscmds.c
index 3057d89d50..476a6314a6 100644
--- a/src/backend/commands/statscmds.c
+++ b/src/backend/commands/statscmds.c
@@ -366,6 +366,7 @@ CreateStatistics(CreateStatsStmt *stmt)
 	datanulls[Anum_pg_statistic_ext_data_stxdndistinct - 1] = true;
 	datanulls[Anum_pg_statistic_ext_data_stxddependencies - 1] = true;
 	datanulls[Anum_pg_statistic_ext_data_stxdmcv - 1] = true;
+	datanulls[Anum_pg_statistic_ext_data_stxdexpr - 1] = true;
 
 	/* insert it into pg_statistic_ext_data */
 	htup = heap_form_tuple(datarel->rd_att, datavalues, datanulls);
@@ -638,6 +639,7 @@ UpdateStatisticsForTypeChange(Oid statsOid, Oid relationOid, int attnum,
 
 	replaces[Anum_pg_statistic_ext_data_stxdmcv - 1] = true;
 	nulls[Anum_pg_statistic_ext_data_stxdmcv - 1] = true;
+	nulls[Anum_pg_statistic_ext_data_stxdexpr - 1] = true;
 
 	rel = table_open(StatisticExtDataRelationId, RowExclusiveLock);
 
diff --git a/src/include/catalog/pg_statistic_ext_data.h b/src/include/catalog/pg_statistic_ext_data.h
index c9515df117..c494d159a0 100644
--- a/src/include/catalog/pg_statistic_ext_data.h
+++ b/src/include/catalog/pg_statistic_ext_data.h
@@ -37,6 +37,7 @@ CATALOG(pg_statistic_ext_data,3429,StatisticExtDataRelationId)
 	pg_ndistinct stxdndistinct; /* ndistinct coefficients (serialized) */
 	pg_dependencies stxddependencies;	/* dependencies (serialized) */
 	pg_mcv_list stxdmcv;		/* MCV (serialized) */
+	pg_statistic stxdexpr;		/* expressions */
 
 #endif
 
-- 
2.17.0

Reply via email to