24#include "utils/fmgroids.h"
32#define SizeOfHeader (3 * sizeof(uint32))
35#define SizeOfItem(natts) \
36 (sizeof(double) + sizeof(AttrNumber) * (1 + (natts)))
39#define MinSizeOfItem SizeOfItem(2)
42#define MinSizeOfItems(ndeps) \
43 (SizeOfHeader + (ndeps) * MinSizeOfItem)
143 state->ndependencies++;
171 Assert((n >= k) && (k > 0));
177 state->ndependencies = 0;
225 int n_violations = 0;
228 int n_supporting_rows = 0;
241 for (
i = 0;
i < k;
i++)
242 attnums_dep[
i] =
data->attnums[dependency[
i]];
265 elog(
ERROR,
"cache lookup failed for ordering operator for type %u",
306 if (n_violations == 0)
307 n_supporting_rows += group_size;
322 return (n_supporting_rows * 1.0 /
data->numrows);
355 "dependency_degree cxt",
364 for (k = 2; k <=
data->nattnums; k++)
399 for (
i = 0;
i < k;
i++)
403 if (dependencies == NULL)
409 dependencies->
ndeps = 0;
412 dependencies->
ndeps++;
417 dependencies->
deps[dependencies->
ndeps - 1] = d;
448 for (
i = 0;
i < dependencies->
ndeps;
i++)
459 memcpy(tmp, &dependencies->
type,
sizeof(
uint32));
465 for (
i = 0;
i < dependencies->
ndeps;
i++)
469 memcpy(tmp, &d->
degree,
sizeof(
double));
470 tmp +=
sizeof(double);
495 Size min_expected_size;
503 elog(
ERROR,
"invalid MVDependencies size %zu (expected at least %zu)",
515 memcpy(&dependencies->
type, tmp,
sizeof(
uint32));
521 elog(
ERROR,
"invalid dependency magic %d (expected %d)",
525 elog(
ERROR,
"invalid dependency type %d (expected %d)",
528 if (dependencies->
ndeps == 0)
529 elog(
ERROR,
"invalid zero-length item array in MVDependencies");
535 elog(
ERROR,
"invalid dependencies size %zu (expected at least %zu)",
542 for (
i = 0;
i < dependencies->
ndeps;
i++)
549 memcpy(°ree, tmp,
sizeof(
double));
550 tmp +=
sizeof(double);
570 dependencies->
deps[
i] = d;
623 elog(
ERROR,
"cache lookup failed for statistics object %u", mvoid);
626 Anum_pg_statistic_ext_data_stxddependencies, &isnull);
629 "requested statistics kind \"%c\" is not yet built for statistics object %u",
630 STATS_EXT_DEPENDENCIES, mvoid);
659 if (rinfo->pseudoconstant)
750 foreach(lc, bool_expr->
args)
759 relid, &clause_attnum))
766 if (*
attnum != clause_attnum)
787 clause_expr = clause;
798 if (!
IsA(clause_expr,
Var))
802 var = (
Var *) clause_expr;
805 if (var->
varno != relid)
852 for (
i = 0;
i < ndependencies;
i++)
854 for (
j = 0;
j < dependencies[
i]->
ndeps;
j++)
883 strongest = dependency;
946 for (
i = 0;
i < ndependencies;
i++)
976 if (list_attnums[listidx] ==
i)
978 attr_clauses =
lappend(attr_clauses, clause);
984 jointype, sjinfo,
false);
985 attr_sel[attidx++] = simple_sel;
1012 for (
i = ndependencies - 1;
i >= 0;
i--)
1025 s1 *= attr_sel[attidx];
1031 s2 = attr_sel[attidx];
1045 attr_sel[attidx] = f + (1 - f) *
s2;
1047 attr_sel[attidx] = f *
s2 /
s1 + (1 - f) *
s2;
1056 for (
i = 0;
i < nattrs;
i++)
1087 if (rinfo->pseudoconstant)
1177 foreach(lc, bool_expr->
args)
1179 Node *or_expr = NULL;
1186 statlist, &or_expr))
1193 if (!
equal(or_expr, *expr))
1214 clause_expr = clause;
1227 foreach(lc, statlist)
1232 if (info->
kind != STATS_EXT_DEPENDENCIES)
1235 foreach(lc2, info->
exprs)
1239 if (
equal(clause_expr, stat_expr))
1292 int nfunc_dependencies;
1301 Node **unique_exprs;
1302 int unique_exprs_cnt;
1317 unique_exprs_cnt = 0;
1354 list_attnums[listidx] =
attnum;
1366 for (
i = 0;
i < unique_exprs_cnt;
i++)
1368 if (
equal(unique_exprs[
i], expr))
1379 unique_exprs[unique_exprs_cnt++] = expr;
1382 attnum = (-unique_exprs_cnt);
1386 list_attnums[listidx] =
attnum;
1400 if (unique_exprs_cnt > 0)
1401 attnum_offset = (unique_exprs_cnt + 1);
1418 Assert(list_attnums[
i] >= (-unique_exprs_cnt));
1422 attnum = list_attnums[
i] + attnum_offset;
1454 pfree(list_attnums);
1470 nfunc_dependencies = 0;
1482 if (
stat->kind != STATS_EXT_DEPENDENCIES)
1486 if (
stat->inherit != rte->
inh)
1514 for (
i = 0;
i < unique_exprs_cnt;
i++)
1518 foreach(lc,
stat->exprs)
1523 if (
equal(stat_expr, unique_exprs[
i]))
1532 if (nmatched + nexprs < 2)
1563 if (unique_exprs_cnt > 0 ||
stat->exprs !=
NIL)
1624 for (
int m = 0; m < unique_exprs_cnt; m++)
1630 if (
equal(unique_exprs[m], expr))
1632 unique_attnum = -(m + 1) + attnum_offset;
1663 deps->
ndeps = ndeps;
1670 if (deps->
ndeps > 0)
1672 func_dependencies[nfunc_dependencies] = deps;
1673 total_ndeps += deps->
ndeps;
1674 nfunc_dependencies++;
1679 if (nfunc_dependencies == 0)
1681 pfree(func_dependencies);
1683 pfree(list_attnums);
1684 pfree(unique_exprs);
1707 dependencies[ndependencies++] = dependency;
1718 if (ndependencies != 0)
1720 sjinfo, dependencies, ndependencies,
1721 list_attnums, estimatedclauses);
1724 for (
i = 0;
i < nfunc_dependencies;
i++)
1725 pfree(func_dependencies[
i]);
1727 pfree(dependencies);
1728 pfree(func_dependencies);
1730 pfree(list_attnums);
1731 pfree(unique_exprs);
Datum idx(PG_FUNCTION_ARGS)
#define AttributeNumberIsValid(attributeNumber)
#define AttrNumberIsForUserDefinedAttr(attributeNumber)
#define InvalidAttrNumber
int bms_next_member(const Bitmapset *a, int prevbit)
Bitmapset * bms_del_member(Bitmapset *a, int x)
void bms_free(Bitmapset *a)
int bms_num_members(const Bitmapset *a)
bool bms_is_member(int x, const Bitmapset *a)
Bitmapset * bms_add_member(Bitmapset *a, int x)
BMS_Membership bms_membership(const Bitmapset *a)
int bms_member_index(Bitmapset *a, int x)
bool is_pseudo_constant_clause(Node *clause)
Selectivity clauselist_selectivity_ext(PlannerInfo *root, List *clauses, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo, bool use_extended_stats)
static void generate_dependencies(DependencyGenerator state)
MVDependencies * statext_dependencies_deserialize(bytea *data)
MVDependencies * statext_dependencies_load(Oid mvoid, bool inh)
static bool dependency_is_compatible_expression(Node *clause, Index relid, List *statlist, Node **expr)
static AttrNumber * DependencyGenerator_next(DependencyGenerator state)
MVDependencies * statext_dependencies_build(StatsBuildData *data)
static bool dependency_is_compatible_clause(Node *clause, Index relid, AttrNumber *attnum)
static bool dependency_is_fully_matched(MVDependency *dependency, Bitmapset *attnums)
bytea * statext_dependencies_serialize(MVDependencies *dependencies)
static void DependencyGenerator_free(DependencyGenerator state)
struct DependencyGeneratorData DependencyGeneratorData
static Selectivity clauselist_apply_dependencies(PlannerInfo *root, List *clauses, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo, MVDependency **dependencies, int ndependencies, AttrNumber *list_attnums, Bitmapset **estimatedclauses)
static DependencyGenerator DependencyGenerator_init(int n, int k)
#define SizeOfItem(natts)
Selectivity dependencies_clauselist_selectivity(PlannerInfo *root, List *clauses, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo, RelOptInfo *rel, Bitmapset **estimatedclauses)
static double dependency_degree(StatsBuildData *data, int k, AttrNumber *dependency)
static void generate_dependencies_recurse(DependencyGenerator state, int index, AttrNumber start, AttrNumber *current)
DependencyGeneratorData * DependencyGenerator
static MVDependency * find_strongest_dependency(MVDependencies **dependencies, int ndependencies, Bitmapset *attnums)
bool equal(const void *a, const void *b)
bool has_stats_of_kind(List *stats, char requiredkind)
int multi_sort_compare_dims(int start, int end, const SortItem *a, const SortItem *b, MultiSortSupport mss)
int multi_sort_compare_dim(int dim, const SortItem *a, const SortItem *b, MultiSortSupport mss)
SortItem * build_sorted_items(StatsBuildData *data, int *nitems, MultiSortSupport mss, int numattrs, AttrNumber *attnums)
MultiSortSupport multi_sort_init(int ndims)
void multi_sort_add_dimension(MultiSortSupport mss, int sortdim, Oid oper, Oid collation)
#define palloc_array(type, count)
#define palloc0_array(type, count)
#define palloc0_object(type)
#define DatumGetByteaPP(X)
Assert(PointerIsAligned(start, uint64))
#define HeapTupleIsValid(tuple)
#define MaxHeapAttributeNumber
if(TABLE==NULL||TABLE_index==NULL)
List * lappend(List *list, void *datum)
RegProcedure get_oprrest(Oid opno)
void MemoryContextReset(MemoryContext context)
void * repalloc(void *pointer, Size size)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
void MemoryContextDelete(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
static bool is_orclause(const void *clause)
static bool is_opclause(const void *clause)
static bool is_notclause(const void *clause)
static Expr * get_notclausearg(const void *notclause)
#define IsA(nodeptr, _type_)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
#define planner_rt_fetch(rti, root)
static const struct exclude_list_item skip[]
static int list_length(const List *l)
static void * list_nth(const List *list, int n)
static Datum BoolGetDatum(bool X)
static Datum ObjectIdGetDatum(Oid X)
#define CLAMP_PROBABILITY(p)
#define STATS_MAX_DIMENSIONS
#define STATS_DEPS_TYPE_BASIC
AttrNumber * dependencies
MVDependency * deps[FLEXIBLE_ARRAY_MEMBER]
AttrNumber attributes[FLEXIBLE_ARRAY_MEMBER]
void ReleaseSysCache(HeapTuple tuple)
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
static Size VARSIZE_ANY(const void *PTR)
static Size VARSIZE_ANY_EXHDR(const void *PTR)
static char * VARDATA(const void *PTR)
static char * VARDATA_ANY(const void *PTR)
static void SET_VARSIZE(void *PTR, Size len)