26#include "utils/fmgrprotos.h"
44 int hist_nvalues,
bool equal);
53 int length_hist_nvalues,
double value,
56 int length_hist_nvalues,
double length1,
57 double length2,
bool equal);
63 Datum *length_hist_values,
64 int length_hist_nvalues);
70 Datum *length_hist_values,
71 int length_hist_nvalues);
82 case OID_MULTIRANGE_OVERLAPS_MULTIRANGE_OP:
83 case OID_MULTIRANGE_OVERLAPS_RANGE_OP:
84 case OID_RANGE_OVERLAPS_MULTIRANGE_OP:
87 case OID_RANGE_CONTAINS_MULTIRANGE_OP:
88 case OID_RANGE_MULTIRANGE_CONTAINED_OP:
89 case OID_MULTIRANGE_CONTAINS_RANGE_OP:
90 case OID_MULTIRANGE_CONTAINS_MULTIRANGE_OP:
91 case OID_MULTIRANGE_RANGE_CONTAINED_OP:
92 case OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP:
95 case OID_MULTIRANGE_CONTAINS_ELEM_OP:
96 case OID_MULTIRANGE_ELEM_CONTAINED_OP:
104 case OID_MULTIRANGE_LESS_OP:
105 case OID_MULTIRANGE_LESS_EQUAL_OP:
106 case OID_MULTIRANGE_GREATER_OP:
107 case OID_MULTIRANGE_GREATER_EQUAL_OP:
108 case OID_MULTIRANGE_LEFT_RANGE_OP:
109 case OID_MULTIRANGE_LEFT_MULTIRANGE_OP:
110 case OID_RANGE_LEFT_MULTIRANGE_OP:
111 case OID_MULTIRANGE_RIGHT_RANGE_OP:
112 case OID_MULTIRANGE_RIGHT_MULTIRANGE_OP:
113 case OID_RANGE_RIGHT_MULTIRANGE_OP:
114 case OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP:
115 case OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
116 case OID_MULTIRANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
117 case OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP:
118 case OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
119 case OID_MULTIRANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
156 &vardata, &other, &varonleft))
172 if (((
Const *) other)->constisnull)
205 if (
operator == OID_MULTIRANGE_CONTAINS_ELEM_OP)
214 lower.inclusive =
true;
216 lower.infinite =
false;
218 upper.inclusive =
true;
220 upper.infinite =
false;
228 else if (
operator == OID_RANGE_MULTIRANGE_CONTAINED_OP ||
229 operator == OID_MULTIRANGE_CONTAINS_RANGE_OP ||
230 operator == OID_MULTIRANGE_OVERLAPS_RANGE_OP ||
231 operator == OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP ||
232 operator == OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP ||
233 operator == OID_MULTIRANGE_LEFT_RANGE_OP ||
234 operator == OID_MULTIRANGE_RIGHT_RANGE_OP)
248 else if (
operator == OID_RANGE_OVERLAPS_MULTIRANGE_OP ||
249 operator == OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP ||
250 operator == OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP ||
251 operator == OID_RANGE_LEFT_MULTIRANGE_OP ||
252 operator == OID_RANGE_RIGHT_MULTIRANGE_OP ||
253 operator == OID_RANGE_CONTAINS_MULTIRANGE_OP ||
254 operator == OID_MULTIRANGE_ELEM_CONTAINED_OP ||
255 operator == OID_MULTIRANGE_RANGE_CONTAINED_OP)
264 else if (((
Const *) other)->consttype == vardata.
vartype)
309 null_frac = stats->stanullfrac;
313 STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM,
318 elog(
ERROR,
"invalid empty fraction statistic");
349 case OID_MULTIRANGE_OVERLAPS_RANGE_OP:
350 case OID_MULTIRANGE_OVERLAPS_MULTIRANGE_OP:
351 case OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP:
352 case OID_MULTIRANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
353 case OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP:
354 case OID_MULTIRANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
355 case OID_MULTIRANGE_LEFT_RANGE_OP:
356 case OID_MULTIRANGE_LEFT_MULTIRANGE_OP:
357 case OID_MULTIRANGE_RIGHT_RANGE_OP:
358 case OID_MULTIRANGE_RIGHT_MULTIRANGE_OP:
360 case OID_MULTIRANGE_LESS_OP:
368 case OID_RANGE_MULTIRANGE_CONTAINED_OP:
369 case OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP:
371 case OID_MULTIRANGE_LESS_EQUAL_OP:
376 case OID_MULTIRANGE_CONTAINS_RANGE_OP:
377 case OID_MULTIRANGE_CONTAINS_MULTIRANGE_OP:
379 case OID_MULTIRANGE_GREATER_EQUAL_OP:
384 case OID_MULTIRANGE_GREATER_OP:
385 selec = 1.0 - empty_frac;
389 case OID_MULTIRANGE_CONTAINS_ELEM_OP:
392 case OID_RANGE_OVERLAPS_MULTIRANGE_OP:
393 case OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
394 case OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
395 case OID_RANGE_LEFT_MULTIRANGE_OP:
396 case OID_RANGE_RIGHT_MULTIRANGE_OP:
397 case OID_RANGE_CONTAINS_MULTIRANGE_OP:
398 case OID_MULTIRANGE_ELEM_CONTAINED_OP:
399 case OID_MULTIRANGE_RANGE_CONTAINED_OP:
402 elog(
ERROR,
"unexpected operator %u",
operator);
419 if (hist_selec < 0.0)
427 if (
operator == OID_RANGE_MULTIRANGE_CONTAINED_OP ||
428 operator == OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP)
431 selec = (1.0 - empty_frac) * hist_selec + empty_frac;
436 selec = (1.0 - empty_frac) * hist_selec;
441 selec *= (1.0 - null_frac);
501 for (
i = 0;
i < nhist;
i++)
506 &hist_lower[
i], &hist_upper[
i], &empty);
509 elog(
ERROR,
"bounds histogram contains an empty range");
513 if (
operator == OID_MULTIRANGE_CONTAINS_RANGE_OP ||
514 operator == OID_MULTIRANGE_CONTAINS_MULTIRANGE_OP ||
515 operator == OID_MULTIRANGE_RANGE_CONTAINED_OP ||
516 operator == OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP)
520 STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM,
537 memset(&lslot, 0,
sizeof(lslot));
552 case OID_MULTIRANGE_LESS_OP:
564 hist_lower, nhist,
false);
567 case OID_MULTIRANGE_LESS_EQUAL_OP:
570 hist_lower, nhist,
true);
573 case OID_MULTIRANGE_GREATER_OP:
576 hist_lower, nhist,
false);
579 case OID_MULTIRANGE_GREATER_EQUAL_OP:
582 hist_lower, nhist,
true);
585 case OID_MULTIRANGE_LEFT_RANGE_OP:
586 case OID_MULTIRANGE_LEFT_MULTIRANGE_OP:
590 hist_upper, nhist,
false);
593 case OID_MULTIRANGE_RIGHT_RANGE_OP:
594 case OID_MULTIRANGE_RIGHT_MULTIRANGE_OP:
598 hist_lower, nhist,
true);
601 case OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP:
602 case OID_MULTIRANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
606 hist_lower, nhist,
false);
609 case OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP:
610 case OID_MULTIRANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
614 hist_upper, nhist,
true);
617 case OID_MULTIRANGE_OVERLAPS_RANGE_OP:
618 case OID_MULTIRANGE_OVERLAPS_MULTIRANGE_OP:
619 case OID_MULTIRANGE_CONTAINS_ELEM_OP:
635 &const_lower, hist_upper,
639 &const_upper, hist_lower,
641 hist_selec = 1.0 - hist_selec;
644 case OID_MULTIRANGE_CONTAINS_RANGE_OP:
645 case OID_MULTIRANGE_CONTAINS_MULTIRANGE_OP:
648 &const_upper, hist_lower, nhist,
652 case OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP:
653 case OID_RANGE_MULTIRANGE_CONTAINED_OP:
662 hist_upper, nhist,
true);
668 hist_lower, nhist,
false);
674 &const_upper, hist_lower, nhist,
680 case OID_RANGE_OVERLAPS_MULTIRANGE_OP:
681 case OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
682 case OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
683 case OID_RANGE_LEFT_MULTIRANGE_OP:
684 case OID_RANGE_RIGHT_MULTIRANGE_OP:
685 case OID_RANGE_CONTAINS_MULTIRANGE_OP:
686 case OID_MULTIRANGE_ELEM_CONTAINED_OP:
687 case OID_MULTIRANGE_RANGE_CONTAINED_OP:
690 elog(
ERROR,
"unknown multirange operator %u",
operator);
740 int hist_length,
bool equal)
743 upper = hist_length - 1,
772 upper = length_hist_nvalues - 1,
822 if (isnan(bin_width) || bin_width <= 0.0)
835 position =
Max(position, 0.0);
836 position =
Min(position, 1.0);
847 return ((
value->infinite &&
value->lower) ? 0.0 : 1.0);
852 return ((
value->infinite && !
value->lower) ? 1.0 : 0.0);
875 if (!isinf(hist1) && !isinf(hist2))
885 return 1.0 - (hist2 -
value) / (hist2 - hist1);
887 else if (isinf(hist1) && !isinf(hist2))
895 else if (isinf(hist1) && isinf(hist2))
937 if (isnan(
res) ||
res < 0.0)
967 double length1,
double length2,
bool equal)
978 Assert(length2 >= length1);
984 if (isinf(length2) &&
equal)
1027 if (
i >= length_hist_nvalues - 1)
1042 PB = (((double)
i) + pos) / (
double) (length_hist_nvalues - 1);
1050 if (length2 == length1)
1059 for (;
i < length_hist_nvalues - 1;
i++)
1064 if (!(bin_upper < length2 || (
equal && bin_upper <= length2)))
1072 PB = (double)
i / (
double) (length_hist_nvalues - 1);
1080 if (PA > 0 || PB > 0)
1081 area += 0.5 * (PB + PA) * (B - A);
1089 if (
i >= length_hist_nvalues - 1)
1100 PB = (((double)
i) + pos) / (
double) (length_hist_nvalues - 1);
1102 if (PA > 0 || PB > 0)
1103 area += 0.5 * (PB + PA) * (B - A);
1113 if (isinf(area) && isinf(length2))
1116 frac = area / (length2 - length1);
1133 const RangeBound *hist_lower,
int hist_nvalues,
1134 Datum *length_hist_values,
int length_hist_nvalues)
1140 double upper_bin_width;
1149 upper->lower =
true;
1157 if (upper_index < 0)
1168 upper_index =
Min(upper_index, hist_nvalues - 2);
1176 &hist_lower[upper_index],
1177 &hist_lower[upper_index + 1]);
1189 bin_width = upper_bin_width;
1192 for (
i = upper_index;
i >= 0;
i--)
1195 double length_hist_frac;
1196 bool final_bin =
false;
1213 &hist_lower[
i + 1]);
1214 if (bin_width < 0.0)
1226 length_hist_nvalues,
1227 prev_dist, dist,
true);
1233 sum_frac += length_hist_frac * bin_width / (double) (hist_nvalues - 1);
1254 const RangeBound *hist_lower,
int hist_nvalues,
1255 Datum *length_hist_values,
int length_hist_nvalues)
1272 if (lower_index < 0)
1283 lower_index =
Min(lower_index, hist_nvalues - 2);
1291 &hist_lower[lower_index + 1]);
1307 bin_width = lower_bin_width;
1308 for (
i = lower_index;
i >= 0;
i--)
1311 double length_hist_frac;
1326 length_hist_nvalues,
1327 prev_dist, dist,
false);
1329 sum_frac += length_hist_frac * bin_width / (double) (hist_nvalues - 1);
#define Assert(condition)
#define OidIsValid(objectId)
static void PGresult * res
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)
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
MultirangeType * make_multirange(Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
#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)
RangeType * range_serialize(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty, struct Node *escontext)
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
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