36 int k,
int *combination);
42#define SizeOfHeader (3 * sizeof(uint32))
45#define SizeOfItem(natts) \
46 (sizeof(double) + sizeof(int) + (natts) * sizeof(AttrNumber))
49#define MinSizeOfItem SizeOfItem(2)
52#define MinSizeOfItems(nitems) \
53 (SizeOfHeader + (nitems) * MinSizeOfItem)
90 int numattrs =
data->nattnums;
100 for (k = 2; k <= numattrs; k++)
117 for (
j = 0;
j < k;
j++)
155 elog(
ERROR,
"cache lookup failed for statistics object %u", mvoid);
158 Anum_pg_statistic_ext_data_stxdndistinct, &isnull);
161 "requested statistics kind \"%c\" is not yet built for statistics object %u",
162 STATS_EXT_NDISTINCT, mvoid);
211 memcpy(tmp, &ndistinct->
type,
sizeof(
uint32));
224 memcpy(tmp, &item.
ndistinct,
sizeof(
double));
225 tmp +=
sizeof(double);
226 memcpy(tmp, &nmembers,
sizeof(
int));
260 elog(
ERROR,
"invalid MVNDistinct size %zu (expected at least %zu)",
275 elog(
ERROR,
"invalid ndistinct magic %08x (expected %08x)",
278 elog(
ERROR,
"invalid ndistinct type %d (expected %d)",
281 elog(
ERROR,
"invalid zero-length item array in MVNDistinct");
286 elog(
ERROR,
"invalid MVNDistinct size %zu (expected at least %zu)",
304 memcpy(&item->
ndistinct, tmp,
sizeof(
double));
305 tmp +=
sizeof(double);
341 int k,
int *combination)
352 int numrows =
data->numrows;
364 isnull = (
bool *)
palloc0(
sizeof(
bool) * numrows * k);
366 for (
i = 0;
i < numrows;
i++)
369 items[
i].isnull = &isnull[
i * k];
379 for (
i = 0;
i < k;
i++)
391 elog(
ERROR,
"cache lookup failed for ordering operator for type %u",
398 for (
j = 0;
j < numrows;
j++)
414 for (
i = 1;
i < numrows;
i++)
442 numer = (double) numrows * (
double) d;
444 denom = (double) (numrows -
f1) +
445 (double)
f1 * (
double) numrows / totalrows;
447 ndistinct = numer / denom;
450 if (ndistinct < (
double) d)
451 ndistinct = (
double) d;
453 if (ndistinct > totalrows)
454 ndistinct = totalrows;
456 return floor(ndistinct + 0.5);
470 Assert((k > 0) && (n >= k));
476 for (d = 1; d <= k; ++d)
492 return (1 << n) - (n + 1);
508 Assert((n >= k) && (k > 0));
516 state->combinations = (
int *)
palloc(
sizeof(
int) * k *
state->ncombinations);
597 current,
state->k *
sizeof(
int));
#define AttributeNumberIsValid(attributeNumber)
static Datum values[MAXATTR]
int multi_sort_compare(const void *a, const void *b, void *arg)
MultiSortSupport multi_sort_init(int ndims)
void multi_sort_add_dimension(MultiSortSupport mss, int sortdim, Oid oper, Oid collation)
#define DatumGetByteaPP(X)
Assert(PointerIsAligned(start, uint64))
#define HeapTupleIsValid(tuple)
void pfree(void *pointer)
void * palloc0(Size size)
static int n_choose_k(int n, int k)
struct CombinationGenerator CombinationGenerator
static double estimate_ndistinct(double totalrows, int numrows, int d, int f1)
static void generate_combinations_recurse(CombinationGenerator *state, int index, int start, int *current)
MVNDistinct * statext_ndistinct_deserialize(bytea *data)
static double ndistinct_for_combination(double totalrows, StatsBuildData *data, int k, int *combination)
bytea * statext_ndistinct_serialize(MVNDistinct *ndistinct)
static void generate_combinations(CombinationGenerator *state)
MVNDistinct * statext_ndistinct_load(Oid mvoid, bool inh)
static int num_combinations(int n)
MVNDistinct * statext_ndistinct_build(double totalrows, StatsBuildData *data)
#define SizeOfItem(natts)
static void generator_free(CombinationGenerator *state)
static CombinationGenerator * generator_init(int n, int k)
#define MinSizeOfItems(nitems)
static int * generator_next(CombinationGenerator *state)
void qsort_interruptible(void *base, size_t nel, size_t elsize, qsort_arg_comparator cmp, void *arg)
static Datum BoolGetDatum(bool X)
static Datum ObjectIdGetDatum(Oid X)
#define STATS_NDISTINCT_MAGIC
#define STATS_NDISTINCT_TYPE_BASIC
#define STATS_MAX_DIMENSIONS
MVNDistinctItem items[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)