return dependencies;
}
+/*
+ * Free allocations of a MVDependencies.
+ */
+void
+statext_dependencies_free(MVDependencies *dependencies)
+{
+ for (int i = 0; i < dependencies->ndeps; i++)
+ pfree(dependencies->deps[i]);
+ pfree(dependencies);
+}
+
+/*
+ * Validate a set of MVDependencies against the extended statistics object
+ * definition.
+ *
+ * Every MVDependencies 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 expression number, no attribute number
+ * can be below (0 - numexprs).
+ */
+bool
+statext_dependencies_validate(const MVDependencies *dependencies,
+ const int2vector *stxkeys,
+ int numexprs, int elevel)
+{
+ int attnum_expr_lowbound = 0 - numexprs;
+
+ /* Scan through each dependency entry */
+ for (int i = 0; i < dependencies->ndeps; i++)
+ {
+ const MVDependency *dep = dependencies->deps[i];
+
+ /*
+ * Cross-check each attribute in a dependency entry with the extended
+ * stats object definition.
+ */
+ for (int j = 0; j < dep->nattributes; j++)
+ {
+ AttrNumber attnum = dep->attributes[j];
+ bool ok = false;
+
+ if (attnum > 0)
+ {
+ /* attribute number in stxkeys */
+ for (int k = 0; k < stxkeys->dim1; k++)
+ {
+ if (attnum == stxkeys->values[k])
+ {
+ ok = true;
+ break;
+ }
+ }
+ }
+ else if ((attnum < 0) && (attnum >= attnum_expr_lowbound))
+ {
+ /* attribute number for an expression */
+ ok = true;
+ }
+
+ if (!ok)
+ {
+ ereport(elevel,
+ (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+ errmsg("could not validate \"%s\" object: invalid attribute number %d found",
+ "pg_dependencies", attnum)));
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
/*
* dependency_is_fully_matched
* checks that a functional dependency is fully matched given clauses on
return ndistinct;
}
+/*
+ * Free allocations of a MVNDistinct.
+ */
+void
+statext_ndistinct_free(MVNDistinct *ndistinct)
+{
+ for (int i = 0; i < ndistinct->nitems; i++)
+ pfree(ndistinct->items[i].attributes);
+ pfree(ndistinct);
+}
+
+/*
+ * Validate a set of MVNDistincts 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 expression number, no attribute
+ * number can be below (0 - numexprs).
+ */
+bool
+statext_ndistinct_validate(const MVNDistinct *ndistinct,
+ const int2vector *stxkeys,
+ int numexprs, int elevel)
+{
+ int attnum_expr_lowbound = 0 - numexprs;
+
+ /* Scan through each MVNDistinct entry */
+ for (int i = 0; i < ndistinct->nitems; i++)
+ {
+ MVNDistinctItem item = ndistinct->items[i];
+
+ /*
+ * Cross-check each attribute in a MVNDistinct entry with the extended
+ * stats object definition.
+ */
+ for (int j = 0; j < item.nattributes; j++)
+ {
+ AttrNumber attnum = item.attributes[j];
+ bool ok = false;
+
+ if (attnum > 0)
+ {
+ /* attribute number in stxkeys */
+ for (int k = 0; k < stxkeys->dim1; k++)
+ {
+ if (attnum == stxkeys->values[k])
+ {
+ ok = true;
+ break;
+ }
+ }
+ }
+ else if ((attnum < 0) && (attnum >= attnum_expr_lowbound))
+ {
+ /* attribute number for an expression */
+ ok = true;
+ }
+
+ if (!ok)
+ {
+ ereport(elevel,
+ (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+ errmsg("could not validate \"%s\" object: invalid attribute number %d found",
+ "pg_ndistinct", attnum)));
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
/*
* ndistinct_for_combination
* Estimates number of distinct values in a combination of columns.
extern MVNDistinct *statext_ndistinct_build(double totalrows, StatsBuildData *data);
extern bytea *statext_ndistinct_serialize(MVNDistinct *ndistinct);
extern MVNDistinct *statext_ndistinct_deserialize(bytea *data);
+extern bool statext_ndistinct_validate(const MVNDistinct *ndistinct,
+ const int2vector *stxkeys,
+ int numexprs, int elevel);
+extern void statext_ndistinct_free(MVNDistinct *ndistinct);
extern MVDependencies *statext_dependencies_build(StatsBuildData *data);
extern bytea *statext_dependencies_serialize(MVDependencies *dependencies);
extern MVDependencies *statext_dependencies_deserialize(bytea *data);
+extern bool statext_dependencies_validate(const MVDependencies *dependencies,
+ const int2vector *stxkeys,
+ int numexprs, int elevel);
+extern void statext_dependencies_free(MVDependencies *dependencies);
extern MCVList *statext_mcv_build(StatsBuildData *data,
double totalrows, int stattarget);