27 #include "utils/fmgrprotos.h"
45 int hist_nvalues,
bool equal);
54 int length_hist_nvalues,
double value,
57 int length_hist_nvalues,
double length1,
58 double length2,
bool equal);
64 Datum *length_hist_values,
65 int length_hist_nvalues);
71 Datum *length_hist_values,
72 int length_hist_nvalues);
83 case OID_MULTIRANGE_OVERLAPS_MULTIRANGE_OP:
84 case OID_MULTIRANGE_OVERLAPS_RANGE_OP:
85 case OID_RANGE_OVERLAPS_MULTIRANGE_OP:
88 case OID_RANGE_CONTAINS_MULTIRANGE_OP:
89 case OID_RANGE_MULTIRANGE_CONTAINED_OP:
90 case OID_MULTIRANGE_CONTAINS_RANGE_OP:
91 case OID_MULTIRANGE_CONTAINS_MULTIRANGE_OP:
92 case OID_MULTIRANGE_RANGE_CONTAINED_OP:
93 case OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP:
96 case OID_MULTIRANGE_CONTAINS_ELEM_OP:
97 case OID_MULTIRANGE_ELEM_CONTAINED_OP:
105 case OID_MULTIRANGE_LESS_OP:
106 case OID_MULTIRANGE_LESS_EQUAL_OP:
107 case OID_MULTIRANGE_GREATER_OP:
108 case OID_MULTIRANGE_GREATER_EQUAL_OP:
109 case OID_MULTIRANGE_LEFT_RANGE_OP:
110 case OID_MULTIRANGE_LEFT_MULTIRANGE_OP:
111 case OID_RANGE_LEFT_MULTIRANGE_OP:
112 case OID_MULTIRANGE_RIGHT_RANGE_OP:
113 case OID_MULTIRANGE_RIGHT_MULTIRANGE_OP:
114 case OID_RANGE_RIGHT_MULTIRANGE_OP:
115 case OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP:
116 case OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
117 case OID_MULTIRANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
118 case OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP:
119 case OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
120 case OID_MULTIRANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
157 &vardata, &other, &varonleft))
173 if (((
Const *) other)->constisnull)
206 if (
operator == OID_MULTIRANGE_CONTAINS_ELEM_OP)
215 lower.inclusive =
true;
217 lower.infinite =
false;
219 upper.inclusive =
true;
221 upper.infinite =
false;
229 else if (
operator == OID_RANGE_MULTIRANGE_CONTAINED_OP ||
230 operator == OID_MULTIRANGE_CONTAINS_RANGE_OP ||
231 operator == OID_MULTIRANGE_OVERLAPS_RANGE_OP ||
232 operator == OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP ||
233 operator == OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP ||
234 operator == OID_MULTIRANGE_LEFT_RANGE_OP ||
235 operator == OID_MULTIRANGE_RIGHT_RANGE_OP)
249 else if (
operator == OID_RANGE_OVERLAPS_MULTIRANGE_OP ||
250 operator == OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP ||
251 operator == OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP ||
252 operator == OID_RANGE_LEFT_MULTIRANGE_OP ||
253 operator == OID_RANGE_RIGHT_MULTIRANGE_OP ||
254 operator == OID_RANGE_CONTAINS_MULTIRANGE_OP ||
255 operator == OID_MULTIRANGE_ELEM_CONTAINED_OP ||
256 operator == OID_MULTIRANGE_RANGE_CONTAINED_OP)
265 else if (((
Const *) other)->consttype == vardata.
vartype)
310 null_frac = stats->stanullfrac;
314 STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM,
319 elog(
ERROR,
"invalid empty fraction statistic");
350 case OID_MULTIRANGE_OVERLAPS_RANGE_OP:
351 case OID_MULTIRANGE_OVERLAPS_MULTIRANGE_OP:
352 case OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP:
353 case OID_MULTIRANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
354 case OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP:
355 case OID_MULTIRANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
356 case OID_MULTIRANGE_LEFT_RANGE_OP:
357 case OID_MULTIRANGE_LEFT_MULTIRANGE_OP:
358 case OID_MULTIRANGE_RIGHT_RANGE_OP:
359 case OID_MULTIRANGE_RIGHT_MULTIRANGE_OP:
361 case OID_MULTIRANGE_LESS_OP:
369 case OID_RANGE_MULTIRANGE_CONTAINED_OP:
370 case OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP:
372 case OID_MULTIRANGE_LESS_EQUAL_OP:
377 case OID_MULTIRANGE_CONTAINS_RANGE_OP:
378 case OID_MULTIRANGE_CONTAINS_MULTIRANGE_OP:
380 case OID_MULTIRANGE_GREATER_EQUAL_OP:
385 case OID_MULTIRANGE_GREATER_OP:
386 selec = 1.0 - empty_frac;
390 case OID_MULTIRANGE_CONTAINS_ELEM_OP:
393 case OID_RANGE_OVERLAPS_MULTIRANGE_OP:
394 case OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
395 case OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
396 case OID_RANGE_LEFT_MULTIRANGE_OP:
397 case OID_RANGE_RIGHT_MULTIRANGE_OP:
398 case OID_RANGE_CONTAINS_MULTIRANGE_OP:
399 case OID_MULTIRANGE_ELEM_CONTAINED_OP:
400 case OID_MULTIRANGE_RANGE_CONTAINED_OP:
403 elog(
ERROR,
"unexpected operator %u",
operator);
420 if (hist_selec < 0.0)
428 if (
operator == OID_RANGE_MULTIRANGE_CONTAINED_OP ||
429 operator == OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP)
432 selec = (1.0 - empty_frac) * hist_selec + empty_frac;
437 selec = (1.0 - empty_frac) * hist_selec;
442 selec *= (1.0 - null_frac);
502 for (
i = 0;
i < nhist;
i++)
507 &hist_lower[
i], &hist_upper[
i], &empty);
510 elog(
ERROR,
"bounds histogram contains an empty range");
514 if (
operator == OID_MULTIRANGE_CONTAINS_RANGE_OP ||
515 operator == OID_MULTIRANGE_CONTAINS_MULTIRANGE_OP ||
516 operator == OID_MULTIRANGE_RANGE_CONTAINED_OP ||
517 operator == OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP)
521 STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM,
538 memset(&lslot, 0,
sizeof(lslot));
553 case OID_MULTIRANGE_LESS_OP:
565 hist_lower, nhist,
false);
568 case OID_MULTIRANGE_LESS_EQUAL_OP:
571 hist_lower, nhist,
true);
574 case OID_MULTIRANGE_GREATER_OP:
577 hist_lower, nhist,
false);
580 case OID_MULTIRANGE_GREATER_EQUAL_OP:
583 hist_lower, nhist,
true);
586 case OID_MULTIRANGE_LEFT_RANGE_OP:
587 case OID_MULTIRANGE_LEFT_MULTIRANGE_OP:
591 hist_upper, nhist,
false);
594 case OID_MULTIRANGE_RIGHT_RANGE_OP:
595 case OID_MULTIRANGE_RIGHT_MULTIRANGE_OP:
599 hist_lower, nhist,
true);
602 case OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP:
603 case OID_MULTIRANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
607 hist_lower, nhist,
false);
610 case OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP:
611 case OID_MULTIRANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
615 hist_upper, nhist,
true);
618 case OID_MULTIRANGE_OVERLAPS_RANGE_OP:
619 case OID_MULTIRANGE_OVERLAPS_MULTIRANGE_OP:
620 case OID_MULTIRANGE_CONTAINS_ELEM_OP:
636 &const_lower, hist_upper,
640 &const_upper, hist_lower,
642 hist_selec = 1.0 - hist_selec;
645 case OID_MULTIRANGE_CONTAINS_RANGE_OP:
646 case OID_MULTIRANGE_CONTAINS_MULTIRANGE_OP:
649 &const_upper, hist_lower, nhist,
653 case OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP:
654 case OID_RANGE_MULTIRANGE_CONTAINED_OP:
663 hist_upper, nhist,
true);
669 hist_lower, nhist,
false);
675 &const_upper, hist_lower, nhist,
681 case OID_RANGE_OVERLAPS_MULTIRANGE_OP:
682 case OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
683 case OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
684 case OID_RANGE_LEFT_MULTIRANGE_OP:
685 case OID_RANGE_RIGHT_MULTIRANGE_OP:
686 case OID_RANGE_CONTAINS_MULTIRANGE_OP:
687 case OID_MULTIRANGE_ELEM_CONTAINED_OP:
688 case OID_MULTIRANGE_RANGE_CONTAINED_OP:
691 elog(
ERROR,
"unknown multirange operator %u",
operator);
741 int hist_length,
bool equal)
744 upper = hist_length - 1,
773 upper = length_hist_nvalues - 1,
823 if (isnan(bin_width) || bin_width <= 0.0)
836 position =
Max(position, 0.0);
837 position =
Min(position, 1.0);
848 return ((
value->infinite &&
value->lower) ? 0.0 : 1.0);
853 return ((
value->infinite && !
value->lower) ? 1.0 : 0.0);
876 if (!isinf(hist1) && !isinf(hist2))
886 return 1.0 - (hist2 -
value) / (hist2 - hist1);
888 else if (isinf(hist1) && !isinf(hist2))
896 else if (isinf(hist1) && isinf(hist2))
938 if (isnan(
res) ||
res < 0.0)
968 double length1,
double length2,
bool equal)
979 Assert(length2 >= length1);
985 if (isinf(length2) &&
equal)
1028 if (
i >= length_hist_nvalues - 1)
1043 PB = (((double)
i) + pos) / (
double) (length_hist_nvalues - 1);
1051 if (length2 == length1)
1060 for (;
i < length_hist_nvalues - 1;
i++)
1065 if (!(bin_upper < length2 || (
equal && bin_upper <= length2)))
1073 PB = (double)
i / (
double) (length_hist_nvalues - 1);
1081 if (PA > 0 || PB > 0)
1082 area += 0.5 * (PB + PA) * (B - A);
1090 if (
i >= length_hist_nvalues - 1)
1101 PB = (((double)
i) + pos) / (
double) (length_hist_nvalues - 1);
1103 if (PA > 0 || PB > 0)
1104 area += 0.5 * (PB + PA) * (B - A);
1114 if (isinf(area) && isinf(length2))
1117 frac = area / (length2 - length1);
1134 const RangeBound *hist_lower,
int hist_nvalues,
1135 Datum *length_hist_values,
int length_hist_nvalues)
1141 double upper_bin_width;
1150 upper->lower =
true;
1158 if (upper_index < 0)
1169 upper_index =
Min(upper_index, hist_nvalues - 2);
1177 &hist_lower[upper_index],
1178 &hist_lower[upper_index + 1]);
1190 bin_width = upper_bin_width;
1193 for (
i = upper_index;
i >= 0;
i--)
1196 double length_hist_frac;
1197 bool final_bin =
false;
1214 &hist_lower[
i + 1]);
1215 if (bin_width < 0.0)
1227 length_hist_nvalues,
1228 prev_dist, dist,
true);
1234 sum_frac += length_hist_frac * bin_width / (double) (hist_nvalues - 1);
1255 const RangeBound *hist_lower,
int hist_nvalues,
1256 Datum *length_hist_values,
int length_hist_nvalues)
1273 if (lower_index < 0)
1284 lower_index =
Min(lower_index, hist_nvalues - 2);
1292 &hist_lower[lower_index + 1]);
1308 bin_width = lower_bin_width;
1309 for (
i = lower_index;
i >= 0;
i--)
1312 double length_hist_frac;
1327 length_hist_nvalues,
1328 prev_dist, dist,
false);
1330 sum_frac += length_hist_frac * bin_width / (double) (hist_nvalues - 1);
#define OidIsValid(objectId)
static void PGresult * res
elog(ERROR, "%s: %s", p2, msg)
bool equal(const void *a, const void *b)
static float8 get_float8_infinity(void)
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)
Assert(fmt[strlen(fmt) - 1] !='\n')
void free_attstatsslot(AttStatsSlot *sslot)
bool get_attstatsslot(AttStatsSlot *sslot, HeapTuple statstuple, int reqkind, Oid reqop, int flags)
Oid get_commutator(Oid opno)
#define ATTSTATSSLOT_NUMBERS
#define ATTSTATSSLOT_VALUES
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
MultirangeType * make_multirange(Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
#define MultirangeIsEmpty(mr)
static MultirangeType * DatumGetMultirangeTypeP(Datum X)
static double calc_length_hist_frac(Datum *length_hist_values, int length_hist_nvalues, double length1, double length2, bool equal)
static double calc_hist_selectivity_contained(TypeCacheEntry *typcache, const RangeBound *lower, RangeBound *upper, const RangeBound *hist_lower, int hist_nvalues, Datum *length_hist_values, int length_hist_nvalues)
static float8 get_position(TypeCacheEntry *typcache, const RangeBound *value, const RangeBound *hist1, const RangeBound *hist2)
static double calc_hist_selectivity_scalar(TypeCacheEntry *typcache, const RangeBound *constbound, const RangeBound *hist, int hist_nvalues, bool equal)
static double calc_hist_selectivity_contains(TypeCacheEntry *typcache, const RangeBound *lower, const RangeBound *upper, const RangeBound *hist_lower, int hist_nvalues, Datum *length_hist_values, int length_hist_nvalues)
static double calc_multirangesel(TypeCacheEntry *typcache, VariableStatData *vardata, const MultirangeType *constval, Oid operator)
static int length_hist_bsearch(Datum *length_hist_values, int length_hist_nvalues, double value, bool equal)
static int rbound_bsearch(TypeCacheEntry *typcache, const RangeBound *value, const RangeBound *hist, int hist_length, bool equal)
static double calc_hist_selectivity(TypeCacheEntry *typcache, VariableStatData *vardata, const MultirangeType *constval, Oid operator)
static double default_multirange_selectivity(Oid operator)
static float8 get_len_position(double value, double hist1, double hist2)
Datum multirangesel(PG_FUNCTION_ARGS)
static float8 get_distance(TypeCacheEntry *typcache, const RangeBound *bound1, const RangeBound *bound2)
#define IsA(nodeptr, _type_)
Datum lower(PG_FUNCTION_ARGS)
Datum upper(PG_FUNCTION_ARGS)
FormData_pg_statistic * Form_pg_statistic
static float8 DatumGetFloat8(Datum X)
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
RangeType * range_serialize(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty, struct Node *escontext)
static RangeType * DatumGetRangeTypeP(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)
bool statistic_proc_security_check(VariableStatData *vardata, Oid func_oid)
#define ReleaseVariableStats(vardata)
#define CLAMP_PROBABILITY(p)
#define DEFAULT_MULTIRANGE_INEQ_SEL
FmgrInfo rng_cmp_proc_finfo
struct TypeCacheEntry * rngelemtype
struct TypeCacheEntry * rngtype
FmgrInfo rng_subdiff_finfo