27 #include "utils/fmgrprotos.h"
46 int hist_nvalues,
bool equal);
55 int length_hist_nvalues,
double value,
58 int length_hist_nvalues,
double length1,
59 double length2,
bool equal);
65 Datum *length_hist_values,
66 int length_hist_nvalues);
72 Datum *length_hist_values,
73 int length_hist_nvalues);
84 case OID_MULTIRANGE_OVERLAPS_MULTIRANGE_OP:
85 case OID_MULTIRANGE_OVERLAPS_RANGE_OP:
86 case OID_RANGE_OVERLAPS_MULTIRANGE_OP:
89 case OID_RANGE_CONTAINS_MULTIRANGE_OP:
90 case OID_RANGE_MULTIRANGE_CONTAINED_OP:
91 case OID_MULTIRANGE_CONTAINS_RANGE_OP:
92 case OID_MULTIRANGE_CONTAINS_MULTIRANGE_OP:
93 case OID_MULTIRANGE_RANGE_CONTAINED_OP:
94 case OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP:
97 case OID_MULTIRANGE_CONTAINS_ELEM_OP:
98 case OID_MULTIRANGE_ELEM_CONTAINED_OP:
106 case OID_MULTIRANGE_LESS_OP:
107 case OID_MULTIRANGE_LESS_EQUAL_OP:
108 case OID_MULTIRANGE_GREATER_OP:
109 case OID_MULTIRANGE_GREATER_EQUAL_OP:
110 case OID_MULTIRANGE_LEFT_RANGE_OP:
111 case OID_MULTIRANGE_LEFT_MULTIRANGE_OP:
112 case OID_RANGE_LEFT_MULTIRANGE_OP:
113 case OID_MULTIRANGE_RIGHT_RANGE_OP:
114 case OID_MULTIRANGE_RIGHT_MULTIRANGE_OP:
115 case OID_RANGE_RIGHT_MULTIRANGE_OP:
116 case OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP:
117 case OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
118 case OID_MULTIRANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
119 case OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP:
120 case OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
121 case OID_MULTIRANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
158 &vardata, &other, &varonleft))
174 if (((
Const *) other)->constisnull)
207 if (
operator == OID_MULTIRANGE_CONTAINS_ELEM_OP)
216 lower.inclusive =
true;
218 lower.infinite =
false;
220 upper.inclusive =
true;
222 upper.infinite =
false;
230 else if (
operator == OID_RANGE_MULTIRANGE_CONTAINED_OP ||
231 operator == OID_MULTIRANGE_CONTAINS_RANGE_OP ||
232 operator == OID_MULTIRANGE_OVERLAPS_RANGE_OP ||
233 operator == OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP ||
234 operator == OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP ||
235 operator == OID_MULTIRANGE_LEFT_RANGE_OP ||
236 operator == OID_MULTIRANGE_RIGHT_RANGE_OP)
250 else if (
operator == OID_RANGE_OVERLAPS_MULTIRANGE_OP ||
251 operator == OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP ||
252 operator == OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP ||
253 operator == OID_RANGE_LEFT_MULTIRANGE_OP ||
254 operator == OID_RANGE_RIGHT_MULTIRANGE_OP ||
255 operator == OID_RANGE_CONTAINS_MULTIRANGE_OP ||
256 operator == OID_MULTIRANGE_ELEM_CONTAINED_OP ||
257 operator == OID_MULTIRANGE_RANGE_CONTAINED_OP)
266 else if (((
Const *) other)->consttype == vardata.
vartype)
311 null_frac = stats->stanullfrac;
315 STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM,
320 elog(
ERROR,
"invalid empty fraction statistic");
351 case OID_MULTIRANGE_OVERLAPS_RANGE_OP:
352 case OID_MULTIRANGE_OVERLAPS_MULTIRANGE_OP:
353 case OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP:
354 case OID_MULTIRANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
355 case OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP:
356 case OID_MULTIRANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
357 case OID_MULTIRANGE_LEFT_RANGE_OP:
358 case OID_MULTIRANGE_LEFT_MULTIRANGE_OP:
359 case OID_MULTIRANGE_RIGHT_RANGE_OP:
360 case OID_MULTIRANGE_RIGHT_MULTIRANGE_OP:
362 case OID_MULTIRANGE_LESS_OP:
370 case OID_RANGE_MULTIRANGE_CONTAINED_OP:
371 case OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP:
373 case OID_MULTIRANGE_LESS_EQUAL_OP:
378 case OID_MULTIRANGE_CONTAINS_RANGE_OP:
379 case OID_MULTIRANGE_CONTAINS_MULTIRANGE_OP:
381 case OID_MULTIRANGE_GREATER_EQUAL_OP:
386 case OID_MULTIRANGE_GREATER_OP:
387 selec = 1.0 - empty_frac;
391 case OID_MULTIRANGE_CONTAINS_ELEM_OP:
394 case OID_RANGE_OVERLAPS_MULTIRANGE_OP:
395 case OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
396 case OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
397 case OID_RANGE_LEFT_MULTIRANGE_OP:
398 case OID_RANGE_RIGHT_MULTIRANGE_OP:
399 case OID_RANGE_CONTAINS_MULTIRANGE_OP:
400 case OID_MULTIRANGE_ELEM_CONTAINED_OP:
401 case OID_MULTIRANGE_RANGE_CONTAINED_OP:
404 elog(
ERROR,
"unexpected operator %u",
operator);
421 if (hist_selec < 0.0)
429 if (
operator == OID_RANGE_MULTIRANGE_CONTAINED_OP ||
430 operator == OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP)
433 selec = (1.0 - empty_frac) * hist_selec + empty_frac;
438 selec = (1.0 - empty_frac) * hist_selec;
443 selec *= (1.0 - null_frac);
503 for (
i = 0;
i < nhist;
i++)
508 &hist_lower[
i], &hist_upper[
i], &empty);
511 elog(
ERROR,
"bounds histogram contains an empty range");
515 if (
operator == OID_MULTIRANGE_CONTAINS_RANGE_OP ||
516 operator == OID_MULTIRANGE_CONTAINS_MULTIRANGE_OP ||
517 operator == OID_MULTIRANGE_RANGE_CONTAINED_OP ||
518 operator == OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP)
522 STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM,
539 memset(&lslot, 0,
sizeof(lslot));
554 case OID_MULTIRANGE_LESS_OP:
566 hist_lower, nhist,
false);
569 case OID_MULTIRANGE_LESS_EQUAL_OP:
572 hist_lower, nhist,
true);
575 case OID_MULTIRANGE_GREATER_OP:
578 hist_lower, nhist,
false);
581 case OID_MULTIRANGE_GREATER_EQUAL_OP:
584 hist_lower, nhist,
true);
587 case OID_MULTIRANGE_LEFT_RANGE_OP:
588 case OID_MULTIRANGE_LEFT_MULTIRANGE_OP:
592 hist_upper, nhist,
false);
595 case OID_MULTIRANGE_RIGHT_RANGE_OP:
596 case OID_MULTIRANGE_RIGHT_MULTIRANGE_OP:
600 hist_lower, nhist,
true);
603 case OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP:
604 case OID_MULTIRANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
608 hist_lower, nhist,
false);
611 case OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP:
612 case OID_MULTIRANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
616 hist_upper, nhist,
true);
619 case OID_MULTIRANGE_OVERLAPS_RANGE_OP:
620 case OID_MULTIRANGE_OVERLAPS_MULTIRANGE_OP:
621 case OID_MULTIRANGE_CONTAINS_ELEM_OP:
637 &const_lower, hist_upper,
641 &const_upper, hist_lower,
643 hist_selec = 1.0 - hist_selec;
646 case OID_MULTIRANGE_CONTAINS_RANGE_OP:
647 case OID_MULTIRANGE_CONTAINS_MULTIRANGE_OP:
650 &const_upper, hist_lower, nhist,
654 case OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP:
655 case OID_RANGE_MULTIRANGE_CONTAINED_OP:
664 hist_upper, nhist,
true);
670 hist_lower, nhist,
false);
676 &const_upper, hist_lower, nhist,
682 case OID_RANGE_OVERLAPS_MULTIRANGE_OP:
683 case OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
684 case OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
685 case OID_RANGE_LEFT_MULTIRANGE_OP:
686 case OID_RANGE_RIGHT_MULTIRANGE_OP:
687 case OID_RANGE_CONTAINS_MULTIRANGE_OP:
688 case OID_MULTIRANGE_ELEM_CONTAINED_OP:
689 case OID_MULTIRANGE_RANGE_CONTAINED_OP:
692 elog(
ERROR,
"unknown multirange operator %u",
operator);
742 int hist_length,
bool equal)
745 upper = hist_length - 1,
774 upper = length_hist_nvalues - 1,
824 if (isnan(bin_width) || bin_width <= 0.0)
837 position =
Max(position, 0.0);
838 position =
Min(position, 1.0);
849 return ((
value->infinite &&
value->lower) ? 0.0 : 1.0);
854 return ((
value->infinite && !
value->lower) ? 1.0 : 0.0);
877 if (!isinf(hist1) && !isinf(hist2))
887 return 1.0 - (hist2 -
value) / (hist2 - hist1);
889 else if (isinf(hist1) && !isinf(hist2))
897 else if (isinf(hist1) && isinf(hist2))
939 if (isnan(
res) ||
res < 0.0)
969 double length1,
double length2,
bool equal)
980 Assert(length2 >= length1);
986 if (isinf(length2) &&
equal)
1029 if (
i >= length_hist_nvalues - 1)
1044 PB = (((double)
i) + pos) / (
double) (length_hist_nvalues - 1);
1052 if (length2 == length1)
1061 for (;
i < length_hist_nvalues - 1;
i++)
1066 if (!(bin_upper < length2 || (
equal && bin_upper <= length2)))
1074 PB = (double)
i / (
double) (length_hist_nvalues - 1);
1082 if (PA > 0 || PB > 0)
1083 area += 0.5 * (PB + PA) * (B - A);
1091 if (
i >= length_hist_nvalues - 1)
1102 PB = (((double)
i) + pos) / (
double) (length_hist_nvalues - 1);
1104 if (PA > 0 || PB > 0)
1105 area += 0.5 * (PB + PA) * (B - A);
1115 if (isinf(area) && isinf(length2))
1118 frac = area / (length2 - length1);
1135 const RangeBound *hist_lower,
int hist_nvalues,
1136 Datum *length_hist_values,
int length_hist_nvalues)
1142 double upper_bin_width;
1151 upper->lower =
true;
1159 if (upper_index < 0)
1170 upper_index =
Min(upper_index, hist_nvalues - 2);
1178 &hist_lower[upper_index],
1179 &hist_lower[upper_index + 1]);
1191 bin_width = upper_bin_width;
1194 for (
i = upper_index;
i >= 0;
i--)
1197 double length_hist_frac;
1198 bool final_bin =
false;
1215 &hist_lower[
i + 1]);
1216 if (bin_width < 0.0)
1228 length_hist_nvalues,
1229 prev_dist, dist,
true);
1235 sum_frac += length_hist_frac * bin_width / (double) (hist_nvalues - 1);
1256 const RangeBound *hist_lower,
int hist_nvalues,
1257 Datum *length_hist_values,
int length_hist_nvalues)
1274 if (lower_index < 0)
1285 lower_index =
Min(lower_index, hist_nvalues - 2);
1293 &hist_lower[lower_index + 1]);
1309 bin_width = lower_bin_width;
1310 for (
i = lower_index;
i >= 0;
i--)
1313 double length_hist_frac;
1328 length_hist_nvalues,
1329 prev_dist, dist,
false);
1331 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