21 #include "utils/fmgrprotos.h"
31 #define CLS_LOWER_INF 1
32 #define CLS_UPPER_INF 2
33 #define CLS_CONTAIN_EMPTY 4
45 #define LIMIT_RATIO 0.3
48 #define INFINITE_BOUND_PENALTY 2.0
49 #define CONTAIN_EMPTY_PENALTY 1.0
50 #define DEFAULT_SUBTYPE_DIFF_PENALTY 1.0
74 bool has_subtype_diff;
114 #define PLACE_LEFT(range, off) \
116 if (v->spl_nleft > 0) \
117 left_range = range_super_union(typcache, left_range, range); \
119 left_range = (range); \
120 v->spl_left[v->spl_nleft++] = (off); \
123 #define PLACE_RIGHT(range, off) \
125 if (v->spl_nright > 0) \
126 right_range = range_super_union(typcache, right_range, range); \
128 right_range = (range); \
129 v->spl_right[v->spl_nright++] = (off); \
133 #define rangeCopy(r) \
134 ((RangeType *) DatumGetPointer(datumCopy(PointerGetDatum(r), \
173 bool use_upper_bound);
215 if (!
OidIsValid(subtype) || subtype == ANYRANGEOID)
218 else if (subtype == ANYMULTIRANGEOID)
227 if (!
OidIsValid(subtype) || subtype == ANYRANGEOID)
230 else if (subtype == ANYMULTIRANGEOID)
297 if (!
OidIsValid(subtype) || subtype == ANYMULTIRANGEOID)
300 else if (subtype == ANYRANGEOID)
309 if (!
OidIsValid(subtype) || subtype == ANYMULTIRANGEOID)
312 else if (subtype == ANYRANGEOID)
336 for (
i = 1;
i < entryvec->
n;
i++)
370 bool has_subtype_diff;
478 if (!orig_empty && orig_lower.
infinite)
499 if (has_subtype_diff)
525 if (!orig_empty && orig_upper.
infinite)
546 if (has_subtype_diff)
589 if (has_subtype_diff)
598 if (has_subtype_diff)
630 int non_empty_classes_count = 0;
631 int biggest_class = -1;
632 int biggest_class_count = 0;
639 maxoff = entryvec->
n - 1;
647 memset(count_in_classes, 0,
sizeof(count_in_classes));
658 total_count = maxoff;
661 if (count_in_classes[
j] > 0)
663 if (count_in_classes[
j] > biggest_class_count)
665 biggest_class_count = count_in_classes[
j];
668 non_empty_classes_count++;
672 Assert(non_empty_classes_count > 0);
674 if (non_empty_classes_count == 1)
708 memset(classes_groups, 0,
sizeof(classes_groups));
736 infCount = total_count - nonInfCount;
743 emptyCount = total_count - nonEmptyCount;
745 if (infCount > 0 && nonInfCount > 0 &&
746 (abs(infCount - nonInfCount) <=
747 abs(emptyCount - nonEmptyCount)))
753 else if (emptyCount > 0 && nonEmptyCount > 0)
862 result_lower = &lower1;
864 result_lower = &lower2;
867 result_upper = &upper1;
869 result_upper = &upper2;
872 if (result_lower == &lower1 && result_upper == &upper1 &&
875 if (result_lower == &lower2 && result_upper == &upper2 &&
879 result =
make_range(typcache, result_lower, result_upper,
false, NULL);
968 elog(
ERROR,
"unrecognized range strategy: %d", strategy);
1030 elog(
ERROR,
"unrecognized range strategy: %d", strategy);
1049 elog(
ERROR,
"unrecognized range strategy: %d", strategy);
1084 elog(
ERROR,
"unrecognized range strategy: %d", strategy);
1119 elog(
ERROR,
"unrecognized range strategy: %d", strategy);
1138 elog(
ERROR,
"unrecognized range strategy: %d", strategy);
1158 maxoff = entryvec->
n - 1;
1196 maxoff = entryvec->
n - 1;
1206 class = get_gist_range_class(range);
1232 bool use_upper_bound)
1241 maxoff = entryvec->
n - 1;
1257 if (use_upper_bound)
1259 &sortItems[
i - 1].bound, &empty);
1269 split_idx = maxoff / 2;
1274 for (
i = 0;
i < maxoff;
i++)
1326 *right_range = NULL;
1327 int common_entries_count;
1341 maxoff = entryvec->
n - 1;
1366 memcpy(by_upper, by_lower, nentries *
sizeof(
NonEmptyRange));
1409 right_lower = &by_lower[i1].
lower;
1410 left_upper = &by_upper[i2].
lower;
1416 while (i1 < nentries &&
1418 &by_lower[i1].
lower) == 0)
1422 left_upper = &by_lower[i1].
upper;
1427 right_lower = &by_lower[i1].
lower;
1433 while (i2 < nentries &&
1450 right_lower = &by_lower[i1].
upper;
1451 left_upper = &by_upper[i2].
upper;
1459 &by_upper[i2].
upper) == 0)
1463 right_lower = &by_upper[i2].
lower;
1468 left_upper = &by_upper[i2].
upper;
1483 left_upper, i2 + 1);
1511 common_entries_count = 0;
1538 common_entries[common_entries_count].
index =
i;
1545 common_entries[common_entries_count].
delta =
1556 common_entries[common_entries_count].
delta = 0;
1558 common_entries_count++;
1582 if (common_entries_count > 0)
1594 for (
i = 0;
i < common_entries_count;
i++)
1634 if (min_left_count >= (
context->entries_count + 1) / 2)
1635 left_count = min_left_count;
1636 else if (max_left_count <= context->entries_count / 2)
1637 left_count = max_left_count;
1639 left_count =
context->entries_count / 2;
1640 right_count =
context->entries_count - left_count;
1647 ratio = ((
float4)
Min(left_count, right_count)) /
1652 bool selectthis =
false;
1661 if (
context->has_subtype_diff)
1666 overlap = max_left_count - min_left_count;
1677 if (overlap < context->overlap ||
1688 context->right_lower = right_lower;
1689 context->left_upper = left_upper;
1690 context->common_left = max_left_count - left_count;
1691 context->common_right = left_count - min_left_count;
1775 if (delta1 < delta2)
1777 else if (delta1 > delta2)
Datum idx(PG_FUNCTION_ARGS)
#define Assert(condition)
#define OidIsValid(objectId)
static float4 get_float4_infinity(void)
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
#define PG_GETARG_POINTER(n)
#define PG_GETARG_DATUM(n)
#define PG_GETARG_UINT16(n)
#define PG_RETURN_POINTER(x)
#define PG_RETURN_BOOL(x)
#define gistentryinit(e, k, r, pg, o, l)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
bool range_adjacent_multirange_internal(TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
bool range_after_multirange_internal(TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
bool multirange_contains_range_internal(TypeCacheEntry *rangetyp, const MultirangeType *mr, const RangeType *r)
RangeType * multirange_get_union_range(TypeCacheEntry *rangetyp, const MultirangeType *mr)
bool range_before_multirange_internal(TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
bool range_overright_multirange_internal(TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
bool range_contains_multirange_internal(TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
bool range_overlaps_multirange_internal(TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
bool range_overleft_multirange_internal(TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
#define MultirangeIsEmpty(mr)
#define MultirangeTypeGetOid(mr)
static MultirangeType * DatumGetMultirangeTypeP(Datum X)
#define OffsetNumberNext(offsetNumber)
#define FirstOffsetNumber
Datum lower(PG_FUNCTION_ARGS)
Datum upper(PG_FUNCTION_ARGS)
void qsort_arg(void *base, size_t nel, size_t elsize, qsort_arg_comparator cmp, void *arg)
#define qsort(a, b, c, d)
static Datum PointerGetDatum(const void *X)
static float8 DatumGetFloat8(Datum X)
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
bool range_contained_by_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
bool range_contains_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
bool range_after_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
bool range_overlaps_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
bool range_before_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
bool range_overright_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
bool range_contains_elem_internal(TypeCacheEntry *typcache, const RangeType *r, Datum val)
RangeType * make_range(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)
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
bool range_eq_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
bool range_adjacent_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
void range_set_contain_empty(RangeType *range)
char range_get_flags(const RangeType *range)
bool range_overleft_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
#define RANGESTRAT_OVERLAPS
#define RANGESTRAT_BEFORE
#define RANGESTRAT_OVERRIGHT
#define RANGE_CONTAIN_EMPTY
#define RangeIsOrContainsEmpty(r)
#define RANGESTRAT_OVERLEFT
#define RANGESTRAT_CONTAINED_BY
static Datum RangeTypePGetDatum(const RangeType *X)
#define PG_RETURN_RANGE_P(x)
#define RANGESTRAT_ADJACENT
static RangeType * DatumGetRangeTypeP(Datum X)
#define PG_GETARG_RANGE_P(n)
#define RANGESTRAT_CONTAINS_ELEM
#define RANGESTRAT_CONTAINS
#define RangeTypeGetOid(r)
static int interval_cmp_lower(const void *a, const void *b, void *arg)
static void range_gist_consider_split(ConsiderSplitContext *context, RangeBound *right_lower, int min_left_count, RangeBound *left_upper, int max_left_count)
#define CLS_CONTAIN_EMPTY
static bool range_gist_consistent_int_element(TypeCacheEntry *typcache, StrategyNumber strategy, const RangeType *key, Datum query)
#define DEFAULT_SUBTYPE_DIFF_PENALTY
static bool multirange_union_range_equal(TypeCacheEntry *typcache, const RangeType *r, const MultirangeType *mr)
Datum multirange_gist_compress(PG_FUNCTION_ARGS)
static int single_bound_cmp(const void *a, const void *b, void *arg)
Datum range_gist_union(PG_FUNCTION_ARGS)
static bool range_gist_consistent_leaf_multirange(TypeCacheEntry *typcache, StrategyNumber strategy, const RangeType *key, const MultirangeType *query)
#define PLACE_RIGHT(range, off)
Datum range_gist_same(PG_FUNCTION_ARGS)
static bool range_gist_consistent_leaf_range(TypeCacheEntry *typcache, StrategyNumber strategy, const RangeType *key, const RangeType *query)
static void range_gist_fallback_split(TypeCacheEntry *typcache, GistEntryVector *entryvec, GIST_SPLITVEC *v)
static bool range_gist_consistent_leaf_element(TypeCacheEntry *typcache, StrategyNumber strategy, const RangeType *key, Datum query)
static void range_gist_double_sorting_split(TypeCacheEntry *typcache, GistEntryVector *entryvec, GIST_SPLITVEC *v)
Datum range_gist_picksplit(PG_FUNCTION_ARGS)
static void range_gist_class_split(TypeCacheEntry *typcache, GistEntryVector *entryvec, GIST_SPLITVEC *v, SplitLR *classes_groups)
#define CONTAIN_EMPTY_PENALTY
#define PLACE_LEFT(range, off)
static int get_gist_range_class(RangeType *range)
static float8 call_subtype_diff(TypeCacheEntry *typcache, Datum val1, Datum val2)
static int common_entry_cmp(const void *i1, const void *i2)
static int interval_cmp_upper(const void *a, const void *b, void *arg)
Datum multirange_gist_consistent(PG_FUNCTION_ARGS)
Datum range_gist_consistent(PG_FUNCTION_ARGS)
static bool range_gist_consistent_int_range(TypeCacheEntry *typcache, StrategyNumber strategy, const RangeType *key, const RangeType *query)
static void range_gist_single_sorting_split(TypeCacheEntry *typcache, GistEntryVector *entryvec, GIST_SPLITVEC *v, bool use_upper_bound)
static RangeType * range_super_union(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
static bool range_gist_consistent_int_multirange(TypeCacheEntry *typcache, StrategyNumber strategy, const RangeType *key, const MultirangeType *query)
#define INFINITE_BOUND_PENALTY
Datum range_gist_penalty(PG_FUNCTION_ARGS)
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
GISTENTRY vector[FLEXIBLE_ARRAY_MEMBER]
struct TypeCacheEntry * rngtype
FmgrInfo rng_subdiff_finfo