31 #define DEFAULT_CONTAIN_SEL 0.005
34 #define DEFAULT_OVERLAP_SEL 0.01
37 #define DEFAULT_SEL(operator) \
38 ((operator) == OID_ARRAY_OVERLAP_OP ? \
39 DEFAULT_OVERLAP_SEL : DEFAULT_CONTAIN_SEL)
42 Oid elemtype,
Oid operator);
45 Datum *mcelem,
int nmcelem,
46 float4 *numbers,
int nnumbers,
50 float4 *numbers,
int nnumbers,
51 Datum *array_data,
int nitems,
54 float4 *numbers,
int nnumbers,
55 Datum *array_data,
int nitems,
59 static float *
calc_distr(
const float *p,
int n,
int m,
float rest);
84 Oid elemtype,
bool isEquality,
bool useOr,
111 if (((
Const *) leftop)->constisnull)
117 constval = ((
Const *) leftop)->constvalue;
153 &numbers, &nnumbers))
212 selec *= (1.0 - stats->stanullfrac);
267 &vardata, &other, &varonleft))
283 if (((
Const *) other)->constisnull)
312 element_typeid,
operator);
347 Oid elemtype,
Oid operator)
384 &numbers, &nnumbers))
424 selec *= (1.0 - stats->stanullfrac);
451 Datum *mcelem,
int nmcelem,
452 float4 *numbers,
int nnumbers,
473 &elem_values, &elem_nulls, &num_elems);
477 null_present =
false;
478 for (i = 0; i < num_elems; i++)
483 elem_values[nonnull_nitems++] = elem_values[
i];
505 elem_values, nonnull_nitems,
510 elem_values, nonnull_nitems,
515 elog(
ERROR,
"arraycontsel called for unrecognized operator %u",
544 float4 *numbers,
int nnumbers,
545 Datum *array_data,
int nitems,
561 if (nnumbers != nmcelem + 3)
570 minfreq = numbers[nmcelem];
603 for (i = 0; i < nitems; i++)
616 &mcelem_index, cmpfunc);
620 while (mcelem_index < nmcelem)
637 if (match && numbers)
640 elem_selec = numbers[mcelem_index];
659 selec = selec + elem_selec - selec * elem_selec;
719 float4 *numbers,
int nnumbers,
720 Datum *array_data,
int nitems,
744 if (numbers ==
NULL || nnumbers != nmcelem + 3)
748 if (hist ==
NULL || nhist < 3)
756 minfreq = numbers[nmcelem];
757 nullelem_freq = numbers[nmcelem + 2];
758 avg_count = hist[nhist - 1];
778 elem_selec = (
float *)
palloc(
sizeof(
float) * nitems);
782 for (i = 0; i < nitems; i++)
796 while (mcelem_index < nmcelem)
804 mult *= (1.0f - numbers[mcelem_index]);
805 rest -= numbers[mcelem_index];
819 elem_selec[unique_nitems] = numbers[mcelem_index];
821 rest -= numbers[mcelem_index];
841 while (mcelem_index < nmcelem)
843 mult *= (1.0f - numbers[mcelem_index]);
844 rest -= numbers[mcelem_index];
877 if ((nmcelem + unique_nitems) > 0 &&
878 unique_nitems >
EFFORT * nmcelem / (nmcelem + unique_nitems))
884 double b = (double) nmcelem;
887 n = (int) ((sqrt(b * b + 4 *
EFFORT * b) - b) / 2);
890 qsort(elem_selec, unique_nitems,
sizeof(
float),
900 dist =
calc_distr(elem_selec, unique_nitems, unique_nitems, 0.0f);
901 mcelem_dist =
calc_distr(numbers, nmcelem, unique_nitems, rest);
904 hist_part =
calc_hist(hist, nhist - 1, unique_nitems);
907 for (i = 0; i <= unique_nitems; i++)
914 if (mcelem_dist[i] > 0)
915 selec += hist_part[
i] * mult * dist[
i] / mcelem_dist[
i];
924 selec *= (1.0f - nullelem_freq);
948 float prev_interval = 0,
952 hist_part = (
float *)
palloc((n + 1) *
sizeof(float));
959 frac = 1.0f / ((float) (nhist - 1));
961 for (k = 0; k <= n; k++)
971 while (i < nhist && hist[i] <= k)
984 next_interval = hist[
i] - hist[i - 1];
993 val = (float) (count - 1);
994 if (next_interval > 0)
995 val += 0.5f / next_interval;
996 if (prev_interval > 0)
997 val += 0.5f / prev_interval;
998 hist_part[k] = frac *
val;
1000 prev_interval = next_interval;
1005 if (prev_interval > 0)
1006 hist_part[k] = frac / prev_interval;
1008 hist_part[k] = 0.0f;
1044 row = (
float *)
palloc((m + 1) *
sizeof(float));
1045 prev_row = (
float *)
palloc((m + 1) *
sizeof(float));
1049 for (i = 1; i <= n; i++)
1059 for (j = 0; j <= i && j <= m; j++)
1064 val += prev_row[j] * (1.0f - t);
1066 val += prev_row[j - 1] * t;
1085 for (i = 0; i <= m; i++)
1095 for (i = 0; i <= m; i++)
1097 for (j = 0; j <= m -
i; j++)
1098 row[j + i] += prev_row[j] * t;
1101 t *= rest / (float) (i + 1);
1204 float d1 = *((
const float *) key1);
1205 float d2 = *((
const float *) key2);
#define PG_GETARG_INT32(n)
#define IsA(nodeptr, _type_)
static int element_compare(const void *key1, const void *key2, void *arg)
#define PointerGetDatum(X)
bool get_restriction_variable(PlannerInfo *root, List *args, int varRelid, VariableStatData *vardata, Node **other, bool *varonleft)
#define DEFAULT_CONTAIN_SEL
#define PG_RETURN_FLOAT8(x)
static float * calc_hist(const float4 *hist, int nhist, int n)
#define PG_GETARG_POINTER(n)
bool get_attstatsslot(HeapTuple statstuple, Oid atttype, int32 atttypmod, int reqkind, Oid reqop, Oid *actualop, Datum **values, int *nvalues, float4 **numbers, int *nnumbers)
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
FormData_pg_statistic * Form_pg_statistic
#define OidIsValid(objectId)
Datum arraycontsel(PG_FUNCTION_ARGS)
#define CLAMP_PROBABILITY(p)
#define OID_ARRAY_CONTAINS_OP
void pfree(void *pointer)
#define STATISTIC_KIND_DECHIST
#define OID_ARRAY_OVERLAP_OP
#define DEFAULT_COLLATION_OID
static float * calc_distr(const float *p, int n, int m, float rest)
static Selectivity mcelem_array_selec(ArrayType *array, TypeCacheEntry *typentry, Datum *mcelem, int nmcelem, float4 *numbers, int nnumbers, float4 *hist, int nhist, Oid operator, FmgrInfo *cmpfunc)
void qsort_arg(void *base, size_t nel, size_t elsize, qsort_arg_comparator cmp, void *arg)
#define OID_ARRAY_CONTAINED_OP
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
static bool find_next_mcelem(Datum *mcelem, int nmcelem, Datum value, int *index, FmgrInfo *cmpfunc)
#define HeapTupleIsValid(tuple)
void examine_variable(PlannerInfo *root, Node *node, int varRelid, VariableStatData *vardata)
Selectivity scalararraysel_containment(PlannerInfo *root, Node *leftop, Node *rightop, Oid elemtype, bool isEquality, bool useOr, int varRelid)
static int floor_log2(uint32 n)
static Selectivity calc_arraycontsel(VariableStatData *vardata, Datum constval, Oid elemtype, Oid operator)
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, FmgrInfo *cmpfunc)
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
static Datum values[MAXATTR]
Oid get_base_element_type(Oid typid)
#define DEFAULT_SEL(operator)
#define ReleaseVariableStats(vardata)
#define STATISTIC_KIND_MCELEM
#define TYPECACHE_CMP_PROC_FINFO
#define qsort(a, b, c, d)
void free_attstatsslot(Oid atttype, Datum *values, int nvalues, float4 *numbers, int nnumbers)
Datum arraycontjoinsel(PG_FUNCTION_ARGS)
static int cmp(const chr *x, const chr *y, size_t len)
static int float_compare_desc(const void *key1, const void *key2)
static Selectivity mcelem_array_contain_overlap_selec(Datum *mcelem, int nmcelem, float4 *numbers, int nnumbers, Datum *array_data, int nitems, Oid operator, FmgrInfo *cmpfunc)
#define DatumGetArrayTypeP(X)