mirror of
https://github.com/postgres/postgres.git
synced 2026-01-26 09:41:40 +03:00
Introduce routines to validate and free MVNDistinct and MVDependencies
These routines are useful to perform some basic validation checks on each object structure, working currently on attribute numbers for non-expression and expression attnums. These checks could be extended in the future. Note that this code is not used yet in the tree, and that these functions will become handy for an upcoming patch for the import of extended statistics data. However, they are worth their own independent change as they are actually useful by themselves, with at least the extension code argument in mind (or perhaps I am just feeling more pedantic today). Extracted from a larger patch by the same author, with many adjustments and fixes by me. Author: Corey Huinker <corey.huinker@gmail.com> Reviewed-by: Chao Li <li.evan.chao@gmail.com> Reviewed-by: Michael Paquier <michael@paquier.xyz> Discussion: https://postgr.es/m/CADkLM=dpz3KFnqP-dgJ-zvRvtjsa8UZv8wDAQdqho=qN3kX0Zg@mail.gmail.com
This commit is contained in:
@@ -579,6 +579,82 @@ statext_dependencies_deserialize(bytea *data)
|
||||
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
|
||||
|
||||
@@ -325,6 +325,82 @@ statext_ndistinct_deserialize(bytea *data)
|
||||
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.
|
||||
|
||||
@@ -72,10 +72,18 @@ typedef struct StatsBuildData
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user