23#include "utils/fmgrprotos.h"
30#define DEFAULT_CONTAIN_SEL 0.005
33#define DEFAULT_OVERLAP_SEL 0.01
36#define DEFAULT_SEL(operator) \
37 ((operator) == OID_ARRAY_OVERLAP_OP ? \
38 DEFAULT_OVERLAP_SEL : DEFAULT_CONTAIN_SEL)
41 Oid elemtype,
Oid operator);
44 Datum *mcelem,
int nmcelem,
45 float4 *numbers,
int nnumbers,
49 float4 *numbers,
int nnumbers,
53 float4 *numbers,
int nnumbers,
58static float *
calc_distr(
const float *p,
int n,
int m,
float rest);
83 Oid elemtype,
bool isEquality,
bool useOr,
110 if (((
Const *) leftop)->constisnull)
116 constval = ((
Const *) leftop)->constvalue;
153 memset(&hslot, 0,
sizeof(hslot));
166 OID_ARRAY_CONTAINS_OP,
176 OID_ARRAY_CONTAINED_OP,
189 OID_ARRAY_CONTAINS_OP,
196 OID_ARRAY_CONTAINED_OP,
203 selec *= (1.0 - stats->stanullfrac);
212 OID_ARRAY_CONTAINS_OP,
219 OID_ARRAY_CONTAINED_OP,
258 &vardata, &other, &varonleft))
274 if (((
Const *) other)->constisnull)
286 if (
operator == OID_ARRAY_CONTAINS_OP)
287 operator = OID_ARRAY_CONTAINED_OP;
288 else if (
operator == OID_ARRAY_CONTAINED_OP)
289 operator = OID_ARRAY_CONTAINS_OP;
303 element_typeid,
operator);
338 Oid elemtype,
Oid operator)
375 if (
operator != OID_ARRAY_CONTAINED_OP ||
379 memset(&hslot, 0,
sizeof(hslot));
395 NULL, 0, NULL, 0, NULL, 0,
402 selec *= (1.0 - stats->stanullfrac);
408 NULL, 0, NULL, 0, NULL, 0,
429 Datum *mcelem,
int nmcelem,
430 float4 *numbers,
int nnumbers,
451 &elem_values, &elem_nulls, &num_elems);
455 null_present =
false;
456 for (
i = 0;
i < num_elems;
i++)
461 elem_values[nonnull_nitems++] = elem_values[
i];
468 if (null_present &&
operator == OID_ARRAY_CONTAINS_OP)
480 if (
operator == OID_ARRAY_CONTAINS_OP ||
operator == OID_ARRAY_OVERLAP_OP)
483 elem_values, nonnull_nitems,
485 else if (
operator == OID_ARRAY_CONTAINED_OP)
488 elem_values, nonnull_nitems,
493 elog(
ERROR,
"arraycontsel called for unrecognized operator %u",
522 float4 *numbers,
int nnumbers,
539 if (nnumbers != nmcelem + 3)
548 minfreq = numbers[nmcelem];
562 if (
operator == OID_ARRAY_CONTAINS_OP)
594 &mcelem_index, typentry);
598 while (mcelem_index < nmcelem)
615 if (match && numbers)
618 elem_selec = numbers[mcelem_index];
634 if (
operator == OID_ARRAY_CONTAINS_OP)
637 selec = selec + elem_selec - selec * elem_selec;
697 float4 *numbers,
int nnumbers,
722 if (numbers == NULL || nnumbers != nmcelem + 3)
726 if (hist == NULL || nhist < 3)
734 minfreq = numbers[nmcelem];
735 nullelem_freq = numbers[nmcelem + 2];
736 avg_count = hist[nhist - 1];
774 while (mcelem_index < nmcelem)
782 mult *= (1.0f - numbers[mcelem_index]);
783 rest -= numbers[mcelem_index];
797 elem_selec[unique_nitems] = numbers[mcelem_index];
799 rest -= numbers[mcelem_index];
819 while (mcelem_index < nmcelem)
821 mult *= (1.0f - numbers[mcelem_index]);
822 rest -= numbers[mcelem_index];
855 if ((nmcelem + unique_nitems) > 0 &&
856 unique_nitems >
EFFORT * nmcelem / (nmcelem + unique_nitems))
862 double b = (double) nmcelem;
865 n = (int) ((sqrt(
b *
b + 4 *
EFFORT *
b) -
b) / 2);
868 qsort(elem_selec, unique_nitems,
sizeof(
float),
878 dist =
calc_distr(elem_selec, unique_nitems, unique_nitems, 0.0f);
879 mcelem_dist =
calc_distr(numbers, nmcelem, unique_nitems, rest);
882 hist_part =
calc_hist(hist, nhist - 1, unique_nitems);
885 for (
i = 0;
i <= unique_nitems;
i++)
892 if (mcelem_dist[
i] > 0)
893 selec += hist_part[
i] * mult * dist[
i] / mcelem_dist[
i];
902 selec *= (1.0f - nullelem_freq);
926 float prev_interval = 0,
930 hist_part = (
float *)
palloc((n + 1) *
sizeof(float));
937 frac = 1.0f / ((float) (nhist - 1));
939 for (k = 0; k <= n; k++)
949 while (
i < nhist && hist[
i] <= k)
962 next_interval = hist[
i] - hist[
i - 1];
971 val = (float) (count - 1);
972 if (next_interval > 0)
973 val += 0.5f / next_interval;
974 if (prev_interval > 0)
975 val += 0.5f / prev_interval;
976 hist_part[k] = frac *
val;
978 prev_interval = next_interval;
983 if (prev_interval > 0)
984 hist_part[k] = frac / prev_interval;
1022 row = (
float *)
palloc((m + 1) *
sizeof(float));
1023 prev_row = (
float *)
palloc((m + 1) *
sizeof(float));
1027 for (
i = 1;
i <= n;
i++)
1037 for (
j = 0;
j <=
i &&
j <= m;
j++)
1042 val += prev_row[
j] * (1.0f - t);
1044 val += prev_row[
j - 1] * t;
1063 for (
i = 0;
i <= m;
i++)
1073 for (
i = 0;
i <= m;
i++)
1075 for (
j = 0;
j <= m -
i;
j++)
1076 row[
j +
i] += prev_row[
j] * t;
1079 t *= rest / (float) (
i + 1);
1183 float d1 = *((
const float *) key1);
1184 float d2 = *((
const float *) key2);
#define DatumGetArrayTypeP(X)
Selectivity scalararraysel_containment(PlannerInfo *root, Node *leftop, Node *rightop, Oid elemtype, bool isEquality, bool useOr, int varRelid)
static int float_compare_desc(const void *key1, const void *key2)
static Selectivity mcelem_array_contained_selec(Datum *mcelem, int nmcelem, float4 *numbers, int nnumbers, Datum *array_data, int nitems, float4 *hist, int nhist, Oid operator, TypeCacheEntry *typentry)
#define DEFAULT_CONTAIN_SEL
static Selectivity calc_arraycontsel(VariableStatData *vardata, Datum constval, Oid elemtype, Oid operator)
static int floor_log2(uint32 n)
static float * calc_hist(const float4 *hist, int nhist, int n)
static int element_compare(const void *key1, const void *key2, void *arg)
static float * calc_distr(const float *p, int n, int m, float rest)
Datum arraycontsel(PG_FUNCTION_ARGS)
static Selectivity mcelem_array_selec(ArrayType *array, TypeCacheEntry *typentry, Datum *mcelem, int nmcelem, float4 *numbers, int nnumbers, float4 *hist, int nhist, Oid operator)
static Selectivity mcelem_array_contain_overlap_selec(Datum *mcelem, int nmcelem, float4 *numbers, int nnumbers, Datum *array_data, int nitems, Oid operator, TypeCacheEntry *typentry)
Datum arraycontjoinsel(PG_FUNCTION_ARGS)
#define DEFAULT_SEL(operator)
static bool find_next_mcelem(Datum *mcelem, int nmcelem, Datum value, int *index, TypeCacheEntry *typentry)
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
#define OidIsValid(objectId)
static void PGresult * res
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
#define PG_RETURN_FLOAT8(x)
#define PG_GETARG_POINTER(n)
#define PG_GETARG_INT32(n)
#define HeapTupleIsValid(tuple)
void free_attstatsslot(AttStatsSlot *sslot)
Oid get_base_element_type(Oid typid)
bool get_attstatsslot(AttStatsSlot *sslot, HeapTuple statstuple, int reqkind, Oid reqop, int flags)
#define ATTSTATSSLOT_NUMBERS
#define ATTSTATSSLOT_VALUES
void pfree(void *pointer)
#define IsA(nodeptr, _type_)
FormData_pg_statistic * Form_pg_statistic
void qsort_arg(void *base, size_t nel, size_t elsize, qsort_arg_comparator cmp, void *arg)
#define qsort(a, b, c, d)
static Datum PointerGetDatum(const void *X)
static int32 DatumGetInt32(Datum X)
static int cmp(const chr *x, const chr *y, size_t len)
bool get_restriction_variable(PlannerInfo *root, List *args, int varRelid, VariableStatData *vardata, Node **other, bool *varonleft)
void examine_variable(PlannerInfo *root, Node *node, int varRelid, VariableStatData *vardata)
bool statistic_proc_security_check(VariableStatData *vardata, Oid func_oid)
#define ReleaseVariableStats(vardata)
#define CLAMP_PROBABILITY(p)
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
#define TYPECACHE_CMP_PROC_FINFO