v3-0006-Create-create_stat_ext_entry-from-fetch_statentri.patch
text/x-patch
Filename: v3-0006-Create-create_stat_ext_entry-from-fetch_statentri.patch
Type: text/x-patch
Part: 5
Message:
Re: Statistics Import and Export
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v3-0006
Subject: Create create_stat_ext_entry() from fetch_statentries_for_relation().
| File | + | − |
|---|---|---|
| src/backend/statistics/extended_stats.c | 78 | 68 |
From 0797a698495c21baaef3b633e78425bcd7b16821 Mon Sep 17 00:00:00 2001
From: Corey Huinker <corey.huinker@gmail.com>
Date: Mon, 11 Dec 2023 03:23:28 -0500
Subject: [PATCH v3 6/9] Create create_stat_ext_entry() from
fetch_statentries_for_relation().
Refactor fetch_statentries_for_relation() to use create_stat_ext_entry() in
its inner loop.
Later commits will make use of create_stat_ext_entry().
This was made its own commit for code clarity.
---
src/backend/statistics/extended_stats.c | 146 +++++++++++++-----------
1 file changed, 78 insertions(+), 68 deletions(-)
diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c
index 7f014a0cbb..718826ecf1 100644
--- a/src/backend/statistics/extended_stats.c
+++ b/src/backend/statistics/extended_stats.c
@@ -418,6 +418,83 @@ statext_is_kind_built(HeapTuple htup, char type)
return !heap_attisnull(htup, attnum, NULL);
}
+/*
+ * Create a single StatExtEntry from a fetched heap tuple
+ */
+static StatExtEntry *
+create_stat_ext_entry(HeapTuple htup)
+{
+ StatExtEntry *entry;
+ Datum datum;
+ bool isnull;
+ int i;
+ ArrayType *arr;
+ char *enabled;
+ Form_pg_statistic_ext staForm;
+ List *exprs = NIL;
+
+ entry = palloc0(sizeof(StatExtEntry));
+ staForm = (Form_pg_statistic_ext) GETSTRUCT(htup);
+ entry->statOid = staForm->oid;
+ entry->schema = get_namespace_name(staForm->stxnamespace);
+ entry->name = pstrdup(NameStr(staForm->stxname));
+ entry->stattarget = staForm->stxstattarget;
+ for (i = 0; i < staForm->stxkeys.dim1; i++)
+ {
+ entry->columns = bms_add_member(entry->columns,
+ staForm->stxkeys.values[i]);
+ }
+
+ /* decode the stxkind char array into a list of chars */
+ datum = SysCacheGetAttrNotNull(STATEXTOID, htup,
+ Anum_pg_statistic_ext_stxkind);
+ arr = DatumGetArrayTypeP(datum);
+ if (ARR_NDIM(arr) != 1 ||
+ ARR_HASNULL(arr) ||
+ ARR_ELEMTYPE(arr) != CHAROID)
+ elog(ERROR, "stxkind is not a 1-D char array");
+ enabled = (char *) ARR_DATA_PTR(arr);
+ for (i = 0; i < ARR_DIMS(arr)[0]; i++)
+ {
+ Assert((enabled[i] == STATS_EXT_NDISTINCT) ||
+ (enabled[i] == STATS_EXT_DEPENDENCIES) ||
+ (enabled[i] == STATS_EXT_MCV) ||
+ (enabled[i] == STATS_EXT_EXPRESSIONS));
+ entry->types = lappend_int(entry->types, (int) enabled[i]);
+ }
+
+ /* decode expression (if any) */
+ datum = SysCacheGetAttr(STATEXTOID, htup,
+ Anum_pg_statistic_ext_stxexprs, &isnull);
+
+ if (!isnull)
+ {
+ char *exprsString;
+
+ exprsString = TextDatumGetCString(datum);
+ exprs = (List *) stringToNode(exprsString);
+
+ pfree(exprsString);
+
+ /*
+ * Run the expressions through eval_const_expressions. This is not
+ * just an optimization, but is necessary, because the planner
+ * will be comparing them to similarly-processed qual clauses, and
+ * may fail to detect valid matches without this. We must not use
+ * canonicalize_qual, however, since these aren't qual
+ * expressions.
+ */
+ exprs = (List *) eval_const_expressions(NULL, (Node *) exprs);
+
+ /* May as well fix opfuncids too */
+ fix_opfuncids((Node *) exprs);
+ }
+
+ entry->exprs = exprs;
+
+ return entry;
+}
+
/*
* Return a list (of StatExtEntry) of statistics objects for the given relation.
*/
@@ -443,74 +520,7 @@ fetch_statentries_for_relation(Relation pg_statext, Oid relid)
while (HeapTupleIsValid(htup = systable_getnext(scan)))
{
- StatExtEntry *entry;
- Datum datum;
- bool isnull;
- int i;
- ArrayType *arr;
- char *enabled;
- Form_pg_statistic_ext staForm;
- List *exprs = NIL;
-
- entry = palloc0(sizeof(StatExtEntry));
- staForm = (Form_pg_statistic_ext) GETSTRUCT(htup);
- entry->statOid = staForm->oid;
- entry->schema = get_namespace_name(staForm->stxnamespace);
- entry->name = pstrdup(NameStr(staForm->stxname));
- entry->stattarget = staForm->stxstattarget;
- for (i = 0; i < staForm->stxkeys.dim1; i++)
- {
- entry->columns = bms_add_member(entry->columns,
- staForm->stxkeys.values[i]);
- }
-
- /* decode the stxkind char array into a list of chars */
- datum = SysCacheGetAttrNotNull(STATEXTOID, htup,
- Anum_pg_statistic_ext_stxkind);
- arr = DatumGetArrayTypeP(datum);
- if (ARR_NDIM(arr) != 1 ||
- ARR_HASNULL(arr) ||
- ARR_ELEMTYPE(arr) != CHAROID)
- elog(ERROR, "stxkind is not a 1-D char array");
- enabled = (char *) ARR_DATA_PTR(arr);
- for (i = 0; i < ARR_DIMS(arr)[0]; i++)
- {
- Assert((enabled[i] == STATS_EXT_NDISTINCT) ||
- (enabled[i] == STATS_EXT_DEPENDENCIES) ||
- (enabled[i] == STATS_EXT_MCV) ||
- (enabled[i] == STATS_EXT_EXPRESSIONS));
- entry->types = lappend_int(entry->types, (int) enabled[i]);
- }
-
- /* decode expression (if any) */
- datum = SysCacheGetAttr(STATEXTOID, htup,
- Anum_pg_statistic_ext_stxexprs, &isnull);
-
- if (!isnull)
- {
- char *exprsString;
-
- exprsString = TextDatumGetCString(datum);
- exprs = (List *) stringToNode(exprsString);
-
- pfree(exprsString);
-
- /*
- * Run the expressions through eval_const_expressions. This is not
- * just an optimization, but is necessary, because the planner
- * will be comparing them to similarly-processed qual clauses, and
- * may fail to detect valid matches without this. We must not use
- * canonicalize_qual, however, since these aren't qual
- * expressions.
- */
- exprs = (List *) eval_const_expressions(NULL, (Node *) exprs);
-
- /* May as well fix opfuncids too */
- fix_opfuncids((Node *) exprs);
- }
-
- entry->exprs = exprs;
-
+ StatExtEntry *entry = create_stat_ext_entry(htup);
result = lappend(result, entry);
}
--
2.43.0