v2-0005-Add-attnum-bounds-checking-routines-to-pg_ndistin.patch
text/x-patch
Filename: v2-0005-Add-attnum-bounds-checking-routines-to-pg_ndistin.patch
Type: text/x-patch
Part: 0
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 v2-0005
Subject: Add attnum bounds checking routines to pg_ndistinct
| File | + | − |
|---|---|---|
| src/backend/statistics/mvdistinct.c | 62 | 0 |
| src/include/statistics/extended_stats_internal.h | 3 | 0 |
From 878672ff4456a6df6955a207811beb3fe60f226e Mon Sep 17 00:00:00 2001
From: Corey Huinker <corey.huinker@gmail.com>
Date: Thu, 23 Jan 2025 23:36:54 -0500
Subject: [PATCH v2 5/6] Add attnum bounds checking routines to pg_ndistinct
---
.../statistics/extended_stats_internal.h | 3 +
src/backend/statistics/mvdistinct.c | 62 +++++++++++++++++++
2 files changed, 65 insertions(+)
diff --git a/src/include/statistics/extended_stats_internal.h b/src/include/statistics/extended_stats_internal.h
index df1a5308f4..d5d4cddad5 100644
--- a/src/include/statistics/extended_stats_internal.h
+++ b/src/include/statistics/extended_stats_internal.h
@@ -130,5 +130,8 @@ extern Datum import_mcvlist(HeapTuple tup, int elevel, int numattrs,
Oid *atttypids, int32 *atttypmods, Oid *atttypcolls,
int nitems, Datum *mcv_elems, bool *mcv_nulls,
bool *mcv_elem_nulls, float8 *freqs, float8 *base_freqs);
+extern bool pg_ndistinct_validate_items(MVNDistinct *ndistinct, int2vector *stxkeys,
+ int numexprs, int elevel);
+extern void free_pg_ndistinct(MVNDistinct *ndistinct);
#endif /* EXTENDED_STATS_INTERNAL_H */
diff --git a/src/backend/statistics/mvdistinct.c b/src/backend/statistics/mvdistinct.c
index e2a3acaf78..e9c02aaa63 100644
--- a/src/backend/statistics/mvdistinct.c
+++ b/src/backend/statistics/mvdistinct.c
@@ -630,6 +630,68 @@ pg_ndistinct_in(PG_FUNCTION_ARGS)
PG_RETURN_NULL();
}
+/*
+ * Free allocations of an MVNDistinct
+ */
+void
+free_pg_ndistinct(MVNDistinct *ndistinct)
+{
+ for (int i = 0; i < ndistinct->nitems; i++)
+ pfree(ndistinct->items[i].attributes);
+
+ pfree(ndistinct);
+}
+
+/*
+ * Validate an MVNDistinct against the extended statistics object definition.
+ *
+ * Every MVNDistinctItem must be checked to ensure that the attnums in the
+ * attributes list correspond to attnums/expressions defined by the
+ * extended statistics object.
+ *
+ * Positive attnums are attributes which must be found in the stxkeys,
+ * while negative attnums correspond to an expr number, so the attnum
+ * can't be below (0 - numexprs).
+ */
+bool
+pg_ndistinct_validate_items(MVNDistinct *ndistinct, int2vector *stxkeys, int numexprs, int elevel)
+{
+ int attnum_expr_lowbound = 0 - numexprs;
+
+ for (int i = 0; i < ndistinct->nitems; i++)
+ {
+ MVNDistinctItem item = ndistinct->items[i];
+
+ for (int j = 0; j < item.nattributes; j++)
+ {
+ AttrNumber attnum = item.attributes[j];
+ bool ok = false;
+
+ if (attnum > 0)
+ {
+ for (int k = 0; k < stxkeys->dim1; k++)
+ if (attnum == stxkeys->values[k])
+ {
+ ok = true;
+ break;
+ }
+ }
+ else if ((attnum < 0) && (attnum >= attnum_expr_lowbound))
+ ok = true;
+
+ if (!ok)
+ {
+ ereport(elevel,
+ (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+ errmsg("pg_ndistinct: invalid attnum for this statistics object: %d", attnum)));
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+
/*
* pg_ndistinct
* output routine for type pg_ndistinct
--
2.48.1