30 #define CLS_LOWER_INF 1
31 #define CLS_UPPER_INF 2
32 #define CLS_CONTAIN_EMPTY 4
44 #define LIMIT_RATIO 0.3
47 #define INFINITE_BOUND_PENALTY 2.0
48 #define CONTAIN_EMPTY_PENALTY 1.0
49 #define DEFAULT_SUBTYPE_DIFF_PENALTY 1.0
113 #define PLACE_LEFT(range, off) \
115 if (v->spl_nleft > 0) \
116 left_range = range_super_union(typcache, left_range, range); \
118 left_range = (range); \
119 v->spl_left[v->spl_nleft++] = (off); \
122 #define PLACE_RIGHT(range, off) \
124 if (v->spl_nright > 0) \
125 right_range = range_super_union(typcache, right_range, range); \
127 right_range = (range); \
128 v->spl_right[v->spl_nright++] = (off); \
132 #define rangeCopy(r) \
133 ((RangeType *) DatumGetPointer(datumCopy(PointerGetDatum(r), \
154 bool use_upper_bound);
210 for (i = 1; i < entryvec->
n; i++)
263 bool has_subtype_diff;
371 if (!orig_empty && orig_lower.
infinite)
392 if (has_subtype_diff)
418 if (!orig_empty && orig_upper.
infinite)
439 if (has_subtype_diff)
482 if (has_subtype_diff)
491 if (has_subtype_diff)
523 int non_empty_classes_count = 0;
524 int biggest_class = -1;
525 int biggest_class_count = 0;
532 maxoff = entryvec->
n - 1;
540 memset(count_in_classes, 0,
sizeof(count_in_classes));
551 total_count = maxoff;
554 if (count_in_classes[j] > 0)
556 if (count_in_classes[j] > biggest_class_count)
558 biggest_class_count = count_in_classes[j];
561 non_empty_classes_count++;
565 Assert(non_empty_classes_count > 0);
567 if (non_empty_classes_count == 1)
601 memset(classes_groups, 0,
sizeof(classes_groups));
629 infCount = total_count - nonInfCount;
636 emptyCount = total_count - nonEmptyCount;
638 if (infCount > 0 && nonInfCount > 0 &&
639 (
Abs(infCount - nonInfCount) <=
640 Abs(emptyCount - nonEmptyCount)))
646 else if (emptyCount > 0 && nonEmptyCount > 0)
755 result_lower = &lower1;
757 result_lower = &lower2;
760 result_upper = &upper1;
762 result_upper = &upper2;
765 if (result_lower == &lower1 && result_upper == &upper1 &&
768 if (result_lower == &lower2 && result_upper == &upper2 &&
769 ((flags2 & RANGE_CONTAIN_EMPTY) || !(flags1 & RANGE_CONTAIN_EMPTY)))
772 result =
make_range(typcache, result_lower, result_upper,
false);
774 if ((flags1 & RANGE_CONTAIN_EMPTY) || (flags2 & RANGE_CONTAIN_EMPTY))
847 elog(
ERROR,
"unrecognized range strategy: %d", strategy);
890 elog(
ERROR,
"unrecognized range strategy: %d", strategy);
910 maxoff = entryvec->
n - 1;
948 maxoff = entryvec->
n - 1;
958 class = get_gist_range_class(range);
984 bool use_upper_bound)
993 maxoff = entryvec->
n - 1;
1007 sortItems[i - 1].
index =
i;
1009 if (use_upper_bound)
1011 &sortItems[i - 1].bound, &empty);
1021 split_idx = maxoff / 2;
1026 for (i = 0; i < maxoff; i++)
1079 *right_range =
NULL;
1080 int common_entries_count;
1094 maxoff = entryvec->
n - 1;
1096 context.
first =
true;
1109 &by_lower[i - FirstOffsetNumber].
lower,
1110 &by_lower[i - FirstOffsetNumber].
upper,
1119 memcpy(by_upper, by_lower, nentries *
sizeof(
NonEmptyRange));
1162 right_lower = &by_lower[i1].
lower;
1163 left_upper = &by_upper[i2].
lower;
1169 while (i1 < nentries &&
1171 &by_lower[i1].
lower) == 0)
1175 left_upper = &by_lower[i1].
upper;
1180 right_lower = &by_lower[i1].
lower;
1186 while (i2 < nentries &&
1203 right_lower = &by_lower[i1].
upper;
1204 left_upper = &by_upper[i2].
upper;
1212 &by_upper[i2].
upper) == 0)
1216 right_lower = &by_upper[i2].
lower;
1221 left_upper = &by_upper[i2].
upper;
1236 left_upper, i2 + 1);
1264 common_entries_count = 0;
1290 common_entries[common_entries_count].
index =
i;
1297 common_entries[common_entries_count].
delta =
1308 common_entries[common_entries_count].
delta = 0;
1310 common_entries_count++;
1334 if (common_entries_count > 0)
1346 for (i = 0; i < common_entries_count; i++)
1386 left_count = min_left_count;
1387 else if (max_left_count <= context->entries_count / 2)
1388 left_count = max_left_count;
1398 ratio = ((
float4)
Min(left_count, right_count)) /
1403 bool selectthis =
false;
1417 overlap = max_left_count - min_left_count;
1428 if (overlap < context->overlap ||
1429 (overlap == context->
overlap && ratio > context->
ratio))
1436 context->
first =
false;
1437 context->
ratio = ratio;
1441 context->
common_left = max_left_count - left_count;
1526 if (delta1 < delta2)
1528 else if (delta1 > delta2)
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
#define PG_RETURN_POINTER(x)
static bool range_gist_consistent_leaf(TypeCacheEntry *typcache, StrategyNumber strategy, RangeType *key, Datum query)
static struct cvec * range(struct vars *v, celt a, celt b, int cases)
static void range_gist_consider_split(ConsiderSplitContext *context, RangeBound *right_lower, int min_left_count, RangeBound *left_upper, int max_left_count)
#define RangeTypeGetDatum(X)
int range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1, RangeBound *b2)
#define RANGESTRAT_OVERRIGHT
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
#define RANGESTRAT_ADJACENT
#define RangeTypeGetOid(r)
Datum lower(PG_FUNCTION_ARGS)
bool range_eq_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
#define CONTAIN_EMPTY_PENALTY
bool range_before_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
bool range_overleft_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
#define PointerGetDatum(X)
#define PG_GETARG_DATUM(n)
#define INFINITE_BOUND_PENALTY
Datum range_gist_fetch(PG_FUNCTION_ARGS)
static void range_gist_class_split(TypeCacheEntry *typcache, GistEntryVector *entryvec, GIST_SPLITVEC *v, SplitLR *classes_groups)
bool range_overright_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
bool range_contained_by_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
#define DatumGetRangeType(X)
static float8 call_subtype_diff(TypeCacheEntry *typcache, Datum val1, Datum val2)
Datum idx(PG_FUNCTION_ARGS)
#define PG_GETARG_POINTER(n)
bool range_after_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Datum upper(PG_FUNCTION_ARGS)
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
#define OidIsValid(objectId)
void range_set_contain_empty(RangeType *range)
#define CLS_CONTAIN_EMPTY
float get_float4_infinity(void)
GISTENTRY vector[FLEXIBLE_ARRAY_MEMBER]
FmgrInfo rng_subdiff_finfo
#define PLACE_LEFT(range, off)
Datum range_gist_same(PG_FUNCTION_ARGS)
#define PG_GETARG_RANGE(n)
static int get_gist_range_class(RangeType *range)
#define RANGESTRAT_CONTAINS_ELEM
#define RANGESTRAT_BEFORE
#define FirstOffsetNumber
Datum range_gist_picksplit(PG_FUNCTION_ARGS)
void qsort_arg(void *base, size_t nel, size_t elsize, qsort_arg_comparator cmp, void *arg)
static RangeType * range_super_union(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Datum range_gist_decompress(PG_FUNCTION_ARGS)
Datum range_gist_consistent(PG_FUNCTION_ARGS)
Datum range_gist_compress(PG_FUNCTION_ARGS)
#define PLACE_RIGHT(range, off)
#define RANGESTRAT_CONTAINS
Datum range_gist_penalty(PG_FUNCTION_ARGS)
#define DatumGetFloat8(X)
#define PG_RETURN_BOOL(x)
bool range_adjacent_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
static void range_gist_fallback_split(TypeCacheEntry *typcache, GistEntryVector *entryvec, GIST_SPLITVEC *v)
#define RANGE_CONTAIN_EMPTY
#define PG_RETURN_RANGE(x)
#define Assert(condition)
static int single_bound_cmp(const void *a, const void *b, void *arg)
#define RANGESTRAT_CONTAINED_BY
#define RANGESTRAT_OVERLEFT
#define OffsetNumberNext(offsetNumber)
static bool range_gist_consistent_int(TypeCacheEntry *typcache, StrategyNumber strategy, RangeType *key, Datum query)
static void range_gist_double_sorting_split(TypeCacheEntry *typcache, GistEntryVector *entryvec, GIST_SPLITVEC *v)
#define DEFAULT_SUBTYPE_DIFF_PENALTY
#define PG_GETARG_UINT16(n)
#define RangeIsOrContainsEmpty(r)
char range_get_flags(RangeType *range)
#define RANGESTRAT_OVERLAPS
static void range_gist_single_sorting_split(TypeCacheEntry *typcache, GistEntryVector *entryvec, GIST_SPLITVEC *v, bool use_upper_bound)
#define qsort(a, b, c, d)
bool range_contains_elem_internal(TypeCacheEntry *typcache, RangeType *r, Datum val)
Datum range_gist_union(PG_FUNCTION_ARGS)
static int interval_cmp_lower(const void *a, const void *b, void *arg)
bool range_overlaps_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
TypeCacheEntry * typcache
bool range_contains_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
static int interval_cmp_upper(const void *a, const void *b, void *arg)
static int common_entry_cmp(const void *i1, const void *i2)