26 #include "utils/fmgrprotos.h"
50 int length_hist_nvalues,
double value,
bool equal);
52 int length_hist_nvalues,
double length1,
double length2,
bool equal);
55 const RangeBound *hist_lower,
int hist_nvalues,
56 Datum *length_hist_values,
int length_hist_nvalues);
59 const RangeBound *hist_lower,
int hist_nvalues,
60 Datum *length_hist_values,
int length_hist_nvalues);
71 case OID_RANGE_OVERLAP_OP:
74 case OID_RANGE_CONTAINS_OP:
75 case OID_RANGE_CONTAINED_OP:
78 case OID_RANGE_CONTAINS_ELEM_OP:
79 case OID_RANGE_ELEM_CONTAINED_OP:
87 case OID_RANGE_LESS_OP:
88 case OID_RANGE_LESS_EQUAL_OP:
89 case OID_RANGE_GREATER_OP:
90 case OID_RANGE_GREATER_EQUAL_OP:
91 case OID_RANGE_LEFT_OP:
92 case OID_RANGE_RIGHT_OP:
93 case OID_RANGE_OVERLAPS_LEFT_OP:
94 case OID_RANGE_OVERLAPS_RIGHT_OP:
126 &vardata, &other, &varonleft))
142 if (((
Const *) other)->constisnull)
175 if (
operator == OID_RANGE_CONTAINS_ELEM_OP)
184 lower.inclusive =
true;
186 lower.infinite =
false;
188 upper.inclusive =
true;
190 upper.infinite =
false;
195 else if (
operator == OID_RANGE_ELEM_CONTAINED_OP)
204 else if (((
Const *) other)->consttype == vardata.
vartype)
219 selec =
calc_rangesel(typcache, &vardata, constrange,
operator);
248 null_frac = stats->stanullfrac;
252 STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM,
257 elog(
ERROR,
"invalid empty fraction statistic");
288 case OID_RANGE_OVERLAP_OP:
289 case OID_RANGE_OVERLAPS_LEFT_OP:
290 case OID_RANGE_OVERLAPS_RIGHT_OP:
291 case OID_RANGE_LEFT_OP:
292 case OID_RANGE_RIGHT_OP:
294 case OID_RANGE_LESS_OP:
299 case OID_RANGE_CONTAINED_OP:
301 case OID_RANGE_LESS_EQUAL_OP:
306 case OID_RANGE_CONTAINS_OP:
308 case OID_RANGE_GREATER_EQUAL_OP:
313 case OID_RANGE_GREATER_OP:
314 selec = 1.0 - empty_frac;
318 case OID_RANGE_CONTAINS_ELEM_OP:
320 elog(
ERROR,
"unexpected operator %u",
operator);
337 if (hist_selec < 0.0)
345 if (
operator == OID_RANGE_CONTAINED_OP)
348 selec = (1.0 - empty_frac) * hist_selec + empty_frac;
353 selec = (1.0 - empty_frac) * hist_selec;
358 selec *= (1.0 - null_frac);
417 for (
i = 0;
i < nhist;
i++)
420 &hist_lower[
i], &hist_upper[
i], &empty);
423 elog(
ERROR,
"bounds histogram contains an empty range");
427 if (
operator == OID_RANGE_CONTAINS_OP ||
428 operator == OID_RANGE_CONTAINED_OP)
432 STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM,
449 memset(&lslot, 0,
sizeof(lslot));
461 case OID_RANGE_LESS_OP:
473 hist_lower, nhist,
false);
476 case OID_RANGE_LESS_EQUAL_OP:
479 hist_lower, nhist,
true);
482 case OID_RANGE_GREATER_OP:
485 hist_lower, nhist,
false);
488 case OID_RANGE_GREATER_EQUAL_OP:
491 hist_lower, nhist,
true);
494 case OID_RANGE_LEFT_OP:
498 hist_upper, nhist,
false);
501 case OID_RANGE_RIGHT_OP:
505 hist_lower, nhist,
true);
508 case OID_RANGE_OVERLAPS_RIGHT_OP:
512 hist_lower, nhist,
false);
515 case OID_RANGE_OVERLAPS_LEFT_OP:
519 hist_upper, nhist,
true);
522 case OID_RANGE_OVERLAP_OP:
523 case OID_RANGE_CONTAINS_ELEM_OP:
542 hist_selec = 1.0 - hist_selec;
545 case OID_RANGE_CONTAINS_OP:
548 &const_upper, hist_lower, nhist,
552 case OID_RANGE_CONTAINED_OP:
561 hist_upper, nhist,
true);
567 hist_lower, nhist,
false);
573 &const_upper, hist_lower, nhist,
579 elog(
ERROR,
"unknown range operator %u",
operator);
629 int hist_length,
bool equal)
632 upper = hist_length - 1,
661 upper = length_hist_nvalues - 1,
711 if (isnan(bin_width) || bin_width <= 0.0)
724 position =
Max(position, 0.0);
725 position =
Min(position, 1.0);
736 return ((
value->infinite &&
value->lower) ? 0.0 : 1.0);
741 return ((
value->infinite && !
value->lower) ? 1.0 : 0.0);
764 if (!isinf(hist1) && !isinf(hist2))
774 return 1.0 - (hist2 -
value) / (hist2 - hist1);
776 else if (isinf(hist1) && !isinf(hist2))
784 else if (isinf(hist1) && isinf(hist2))
826 if (isnan(
res) ||
res < 0.0)
856 double length1,
double length2,
bool equal)
867 Assert(length2 >= length1);
873 if (isinf(length2) &&
equal)
916 if (
i >= length_hist_nvalues - 1)
931 PB = (((double)
i) + pos) / (
double) (length_hist_nvalues - 1);
939 if (length2 == length1)
948 for (;
i < length_hist_nvalues - 1;
i++)
953 if (!(bin_upper < length2 || (
equal && bin_upper <= length2)))
961 PB = (double)
i / (
double) (length_hist_nvalues - 1);
969 if (PA > 0 || PB > 0)
970 area += 0.5 * (PB + PA) * (B - A);
978 if (
i >= length_hist_nvalues - 1)
987 PB = (((double)
i) + pos) / (
double) (length_hist_nvalues - 1);
989 if (PA > 0 || PB > 0)
990 area += 0.5 * (PB + PA) * (B - A);
1000 if (isinf(area) && isinf(length2))
1003 frac = area / (length2 - length1);
1020 const RangeBound *hist_lower,
int hist_nvalues,
1021 Datum *length_hist_values,
int length_hist_nvalues)
1027 double upper_bin_width;
1036 upper->lower =
true;
1044 if (upper_index < 0)
1055 upper_index =
Min(upper_index, hist_nvalues - 2);
1063 &hist_lower[upper_index],
1064 &hist_lower[upper_index + 1]);
1076 bin_width = upper_bin_width;
1079 for (
i = upper_index;
i >= 0;
i--)
1082 double length_hist_frac;
1083 bool final_bin =
false;
1100 &hist_lower[
i + 1]);
1101 if (bin_width < 0.0)
1113 length_hist_nvalues,
1114 prev_dist, dist,
true);
1120 sum_frac += length_hist_frac * bin_width / (double) (hist_nvalues - 1);
1141 const RangeBound *hist_lower,
int hist_nvalues,
1142 Datum *length_hist_values,
int length_hist_nvalues)
1159 if (lower_index < 0)
1170 lower_index =
Min(lower_index, hist_nvalues - 2);
1178 &hist_lower[lower_index + 1]);
1194 bin_width = lower_bin_width;
1195 for (
i = lower_index;
i >= 0;
i--)
1198 double length_hist_frac;
1213 length_hist_nvalues,
1214 prev_dist, dist,
false);
1216 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
#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)
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
RangeType * range_serialize(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty, struct Node *escontext)
static RangeType * DatumGetRangeTypeP(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 int length_hist_bsearch(Datum *length_hist_values, int length_hist_nvalues, double value, bool equal)
static double calc_hist_selectivity(TypeCacheEntry *typcache, VariableStatData *vardata, const RangeType *constval, Oid operator)
static int rbound_bsearch(TypeCacheEntry *typcache, const RangeBound *value, const RangeBound *hist, int hist_length, bool equal)
static double calc_rangesel(TypeCacheEntry *typcache, VariableStatData *vardata, const RangeType *constval, Oid operator)
static double default_range_selectivity(Oid operator)
static float8 get_len_position(double value, double hist1, double hist2)
Datum rangesel(PG_FUNCTION_ARGS)
static float8 get_distance(TypeCacheEntry *typcache, const RangeBound *bound1, const RangeBound *bound2)
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_RANGE_INEQ_SEL
FmgrInfo rng_cmp_proc_finfo
struct TypeCacheEntry * rngelemtype
FmgrInfo rng_subdiff_finfo