93 #define MINMAX_MAX_PROCNUMS 1
94 #define PROCNUM_DISTANCE 11
100 #define PROCNUM_BASE 11
107 #define MINMAX_BUFFER_FACTOR 10
108 #define MINMAX_BUFFER_MIN 256
109 #define MINMAX_BUFFER_MAX 8192
110 #define MINMAX_BUFFER_LOAD_FACTOR 0.5
129 #define MINMAX_MULTI_DEFAULT_VALUES_PER_PAGE 32
131 #define MinMaxMultiGetValuesPerRange(opts) \
132 ((opts) && (((MinMaxMultiOptions *) (opts))->valuesPerRange != 0) ? \
133 ((MinMaxMultiOptions *) (opts))->valuesPerRange : \
134 MINMAX_MULTI_DEFAULT_VALUES_PER_PAGE)
136 #define SAMESIGN(a,b) (((a) < 0) == ((b) < 0))
270 #ifdef USE_ASSERT_CHECKING
281 for (
i = 0;
i < (nvalues - 1);
i++)
295 #ifdef USE_ASSERT_CHECKING
311 AssertArrayOrder(cmpFn, colloid, ranges->
values, 2 * ranges->
nranges);
314 AssertArrayOrder(cmpFn, colloid, &ranges->
values[2 * ranges->
nranges],
334 minvalue = ranges->
values[0];
361 int midpoint = (start + end) / 2;
368 minvalue = ranges->
values[2 * midpoint];
369 maxvalue = ranges->
values[2 * midpoint + 1];
380 end = (midpoint - 1);
393 start = (midpoint + 1);
403 for (
i = ranges->
nsorted; i < ranges->nvalues;
i++)
430 #ifdef USE_ASSERT_CHECKING
445 for (
i = 0;
i < nranges;
i++)
451 if (ranges[
i].collapsed)
463 for (
i = 0;
i < nranges - 1;
i++)
547 for (
i = 1;
i <
range->nvalues;
i++)
551 &
range->values[start +
i],
555 range->values[start + n] =
range->values[start +
i];
609 typid =
range->typid;
626 for (
i = 0;
i < nvalues;
i++)
631 else if (typlen == -2)
635 for (
i = 0;
i < nvalues;
i++)
644 len += nvalues * typlen;
654 serialized->
typid = typid;
663 ptr = serialized->
data;
665 for (
i = 0;
i < nvalues;
i++)
681 memcpy(ptr, &tmp, typlen);
689 else if (typlen == -1)
696 else if (typlen == -2)
705 Assert(ptr <= ((
char *) serialized +
len));
709 Assert(ptr == ((
char *) serialized +
len));
740 Assert(nvalues <= serialized->maxvalues);
749 range->maxvalues = maxvalues;
762 ptr = serialized->
data;
772 for (
i = 0; (
i < nvalues) && (!typbyval);
i++)
776 else if (typlen == -1)
781 else if (typlen == -2)
791 dataptr =
palloc(datalen);
797 ptr = serialized->
data;
799 for (
i = 0;
i < nvalues;
i++)
805 memcpy(&v, ptr, typlen);
814 memcpy(dataptr, ptr, typlen);
819 else if (typlen == -1)
827 else if (typlen == -2)
829 Size slen = strlen(ptr) + 1;
833 memcpy(dataptr, ptr, slen);
976 int midpoint = (start + end) / 2;
983 minvalue = ranges->
values[2 * midpoint];
984 maxvalue = ranges->
values[2 * midpoint + 1];
995 end = (midpoint - 1);
1008 start = (midpoint + 1);
1049 Oid typid = attr->atttypid;
1090 for (
i = 2 * ranges->
nranges; i < 2 * ranges->nranges + ranges->
nsorted;
i++)
1203 for (
i = 1;
i < neranges;
i++)
1216 Assert((n > 0) && (n <= neranges));
1236 while (
idx < (neranges - 1))
1245 eranges[
idx].maxval,
1246 eranges[
idx + 1].minval);
1266 eranges[
idx].maxval,
1267 eranges[
idx + 1].maxval);
1284 memmove(&eranges[
idx + 1], &eranges[
idx + 2],
1336 ndistances = (neranges - 1);
1343 for (
i = 0;
i < ndistances;
i++)
1398 *nranges = neranges;
1403 #ifdef USE_ASSERT_CHECKING
1415 for (
i = 0;
i < ncranges;
i++)
1417 if (cranges[
i].collapsed)
1481 int ndistances = (neranges - 1);
1484 int keep = (max_values / 2 - 1);
1492 if (keep >= ndistances)
1508 for (
i = 0;
i < keep;
i++)
1519 Assert(nvalues <= max_values);
1523 Assert(nvalues % 2 == 0);
1533 for (
i = 0;
i < (nvalues / 2);
i++)
1544 return (nvalues / 2);
1559 for (
i = 0;
i < neranges;
i++)
1561 if (!eranges[
i].collapsed)
1571 for (
i = 0;
i < neranges;
i++)
1573 if (eranges[
i].collapsed)
1647 "minmax-multi context",
1695 bool modified =
false;
1720 attno, attr, ranges);
1814 "minmax-multi context",
1832 max_values, cmpFn, ranges->
colloid);
1834 Assert(count_values(eranges, neranges) <= max_values);
1877 if (isnan(
a1) && isnan(
a2))
1881 if (isnan(
a1) || isnan(
a2))
1903 if (isnan(
a1) && isnan(
a2))
1907 if (isnan(
a1) || isnan(
a2))
2055 delta += (int) u2->
data[
i] - (
int) u1->
data[
i];
2162 (
errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2163 errmsg(
"interval out of range")));
2169 (
errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2170 errmsg(
"interval out of range")));
2176 (
errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2177 errmsg(
"interval out of range")));
2212 delta = (lsnb - lsna);
2316 unsigned char *addra,
2354 for (
i = 0;
i <
len;
i++)
2359 nbits = lena - (
i * 8);
2362 mask = (0xFF << (8 - nbits));
2363 addra[
i] = (addra[
i] & mask);
2366 nbits = lenb - (
i * 8);
2369 mask = (0xFF << (8 - nbits));
2370 addrb[
i] = (addrb[
i] & mask);
2376 for (
i =
len - 1;
i >= 0;
i--)
2378 unsigned char a = addra[
i];
2379 unsigned char b = addrb[
i];
2385 Assert((delta >= 0) && (delta <= 1));
2434 bool modified =
false;
2462 int target_maxvalues;
2479 maxvalues =
Max(maxvalues, target_maxvalues);
2487 ranges->
attno = attno;
2489 ranges->
typid = attr->atttypid;
2533 ranges->
attno = attno;
2535 ranges->
typid = attr->atttypid;
2587 for (rangeno = 0; rangeno < ranges->
nranges; rangeno++)
2593 bool matching =
true;
2595 for (keyno = 0; keyno < nkeys; keyno++)
2603 attno =
key->sk_attno;
2604 subtype =
key->sk_subtype;
2606 switch (
key->sk_strategy)
2664 elog(
ERROR,
"invalid strategy number %d",
key->sk_strategy);
2694 bool matching =
true;
2696 for (keyno = 0; keyno < nkeys; keyno++)
2705 attno =
key->sk_attno;
2706 subtype =
key->sk_subtype;
2708 switch (
key->sk_strategy)
2723 elog(
ERROR,
"invalid strategy number %d",
key->sk_strategy);
2783 Assert(ranges_a && ranges_b);
2796 "minmax-multi context",
2861 pfree(serialized_a);
2923 Assert(strategynum >= 1 &&
2957 elog(
ERROR,
"missing operator %d(%u,%u) in opfamily %u",
2958 strategynum, attr->atttypid, subtype, opfamily);
2961 Anum_pg_amop_amopopr, &isNull));
3003 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3004 errmsg(
"cannot accept a value of type %s",
"brin_minmax_multi_summary")));
3023 Ranges *ranges_deserialized;
3053 for (
i = 0;
i < ranges_deserialized->
nranges;
i++)
3076 if (ranges_deserialized->
nranges > 0)
3093 astate_values = NULL;
3095 for (
i = 0;
i < ranges_deserialized->
nvalues;
i++)
3116 if (ranges_deserialized->
nvalues > 0)
3146 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3147 errmsg(
"cannot accept a value of type %s",
"brin_minmax_multi_summary")));
Datum idx(PG_FUNCTION_ARGS)
ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)
Datum makeArrayResult(ArrayBuildState *astate, MemoryContext rcontext)
Datum numeric_sub(PG_FUNCTION_ARGS)
Datum numeric_le(PG_FUNCTION_ARGS)
Datum numeric_float8(PG_FUNCTION_ARGS)
static Datum values[MAXATTR]
#define BrinGetPagesPerRange(relation)
#define SizeofBrinOpcInfo(ncols)
Datum brin_minmax_multi_distance_float8(PG_FUNCTION_ARGS)
Datum brin_minmax_multi_options(PG_FUNCTION_ARGS)
Datum brin_minmax_multi_union(PG_FUNCTION_ARGS)
Datum brin_minmax_multi_distance_float4(PG_FUNCTION_ARGS)
#define MinMaxMultiGetValuesPerRange(opts)
static void AssertCheckExpandedRanges(BrinDesc *bdesc, Oid colloid, AttrNumber attno, Form_pg_attribute attr, ExpandedRange *ranges, int nranges)
struct DistanceValue DistanceValue
Datum brin_minmax_multi_distance_int8(PG_FUNCTION_ARGS)
Datum brin_minmax_multi_summary_recv(PG_FUNCTION_ARGS)
Datum brin_minmax_multi_summary_out(PG_FUNCTION_ARGS)
Datum brin_minmax_multi_add_value(PG_FUNCTION_ARGS)
struct SerializedRanges SerializedRanges
Datum brin_minmax_multi_distance_uuid(PG_FUNCTION_ARGS)
Datum brin_minmax_multi_distance_inet(PG_FUNCTION_ARGS)
Datum brin_minmax_multi_consistent(PG_FUNCTION_ARGS)
static void AssertCheckRanges(Ranges *ranges, FmgrInfo *cmpFn, Oid colloid)
static int compare_expanded_ranges(const void *a, const void *b, void *arg)
Datum brin_minmax_multi_distance_time(PG_FUNCTION_ARGS)
Datum brin_minmax_multi_distance_timestamp(PG_FUNCTION_ARGS)
static bool range_add_value(BrinDesc *bdesc, Oid colloid, AttrNumber attno, Form_pg_attribute attr, Ranges *ranges, Datum newval)
static Ranges * minmax_multi_init(int maxvalues)
static bool ensure_free_space_in_buffer(BrinDesc *bdesc, Oid colloid, AttrNumber attno, Form_pg_attribute attr, Ranges *range)
static int reduce_expanded_ranges(ExpandedRange *eranges, int neranges, DistanceValue *distances, int max_values, FmgrInfo *cmp, Oid colloid)
struct MinMaxMultiOptions MinMaxMultiOptions
struct MinmaxMultiOpaque MinmaxMultiOpaque
static int compare_values(const void *a, const void *b, void *arg)
static void compactify_ranges(BrinDesc *bdesc, Ranges *ranges, int max_values)
#define MINMAX_BUFFER_MAX
Datum brin_minmax_multi_distance_numeric(PG_FUNCTION_ARGS)
#define MINMAX_BUFFER_LOAD_FACTOR
Datum brin_minmax_multi_summary_send(PG_FUNCTION_ARGS)
static Ranges * brin_range_deserialize(int maxvalues, SerializedRanges *range)
static ExpandedRange * build_expanded_ranges(FmgrInfo *cmp, Oid colloid, Ranges *ranges, int *nranges)
Datum brin_minmax_multi_distance_pg_lsn(PG_FUNCTION_ARGS)
static int brin_minmax_multi_get_values(BrinDesc *bdesc, MinMaxMultiOptions *opts)
struct compare_context compare_context
static FmgrInfo * minmax_multi_get_procinfo(BrinDesc *bdesc, uint16 attno, uint16 procnum)
struct ExpandedRange ExpandedRange
Datum brin_minmax_multi_distance_macaddr8(PG_FUNCTION_ARGS)
#define MINMAX_MAX_PROCNUMS
static int sort_expanded_ranges(FmgrInfo *cmp, Oid colloid, ExpandedRange *eranges, int neranges)
#define MINMAX_BUFFER_FACTOR
Datum brin_minmax_multi_distance_date(PG_FUNCTION_ARGS)
static void range_deduplicate_values(Ranges *range)
static void fill_expanded_ranges(ExpandedRange *eranges, int neranges, Ranges *ranges)
static int merge_overlapping_ranges(FmgrInfo *cmp, Oid colloid, ExpandedRange *eranges, int neranges)
Datum brin_minmax_multi_summary_in(PG_FUNCTION_ARGS)
static void store_expanded_ranges(Ranges *ranges, ExpandedRange *eranges, int neranges)
static bool has_matching_range(BrinDesc *bdesc, Oid colloid, Ranges *ranges, Datum newval, AttrNumber attno, Oid typid)
Datum brin_minmax_multi_distance_int2(PG_FUNCTION_ARGS)
static bool range_contains_value(BrinDesc *bdesc, Oid colloid, AttrNumber attno, Form_pg_attribute attr, Ranges *ranges, Datum newval, bool full)
Datum brin_minmax_multi_opcinfo(PG_FUNCTION_ARGS)
static int compare_distances(const void *a, const void *b)
Datum brin_minmax_multi_distance_interval(PG_FUNCTION_ARGS)
Datum brin_minmax_multi_distance_timetz(PG_FUNCTION_ARGS)
static void brin_minmax_multi_serialize(BrinDesc *bdesc, Datum src, Datum *dst)
static SerializedRanges * brin_range_serialize(Ranges *range)
Datum brin_minmax_multi_distance_tid(PG_FUNCTION_ARGS)
static DistanceValue * build_distances(FmgrInfo *distanceFn, Oid colloid, ExpandedRange *eranges, int neranges)
Datum brin_minmax_multi_distance_macaddr(PG_FUNCTION_ARGS)
static FmgrInfo * minmax_multi_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno, Oid subtype, uint16 strategynum)
#define MINMAX_MULTI_DEFAULT_VALUES_PER_PAGE
Datum brin_minmax_multi_distance_int4(PG_FUNCTION_ARGS)
#define MINMAX_BUFFER_MIN
#define RegProcedureIsValid(p)
#define offsetof(type, field)
#define FLEXIBLE_ARRAY_MEMBER
#define PG_USED_FOR_ASSERTS_ONLY
#define TIMESTAMP_NOT_FINITE(j)
#define DATE_NOT_FINITE(j)
#define PG_GETARG_TIMEADT(n)
#define PG_GETARG_TIMETZADT_P(n)
#define PG_GETARG_DATEADT(n)
Datum datumCopy(Datum value, bool typByVal, int typLen)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
static float8 get_float8_infinity(void)
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
void fmgr_info(Oid functionId, FmgrInfo *finfo)
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
char * OidOutputFunctionCall(Oid functionId, Datum val)
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, MemoryContext destcxt)
#define PG_GETARG_BYTEA_PP(n)
#define DirectFunctionCall2(func, arg1, arg2)
#define PG_GETARG_FLOAT8(n)
#define PG_RETURN_FLOAT8(x)
#define PG_GETARG_POINTER(n)
#define PG_RETURN_CSTRING(x)
#define DirectFunctionCall1(func, arg1)
#define PG_GETARG_DATUM(n)
#define PG_GETARG_INT64(n)
#define PG_GET_OPCLASS_OPTIONS()
#define PG_DETOAST_DATUM(datum)
#define FunctionCall1(flinfo, arg1)
#define PG_GETARG_INT32(n)
#define PG_RETURN_DATUM(x)
#define PG_GETARG_FLOAT4(n)
#define PG_RETURN_POINTER(x)
#define PG_GET_COLLATION()
#define PG_RETURN_BOOL(x)
#define PG_GETARG_INT16(n)
static const FormData_pg_attribute a1
static const FormData_pg_attribute a2
#define HeapTupleIsValid(tuple)
#define MaxHeapTuplesPerPage
FmgrInfo * index_getprocinfo(Relation irel, AttrNumber attnum, uint16 procnum)
RegProcedure index_getprocid(Relation irel, AttrNumber attnum, uint16 procnum)
int32 ItemPointerCompare(ItemPointer arg1, ItemPointer arg2)
#define ItemPointerGetBlockNumberNoCheck(pointer)
ItemPointerData * ItemPointer
#define ItemPointerGetOffsetNumberNoCheck(pointer)
Assert(fmt[strlen(fmt) - 1] !='\n')
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
RegProcedure get_opcode(Oid opno)
int16 get_typlen(Oid typid)
bool get_typbyval(Oid typid)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
void MemoryContextDelete(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
static AmcheckOptions opts
FormData_pg_attribute * Form_pg_attribute
void * bsearch_arg(const void *key, const void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *, void *), void *arg)
void qsort_arg(void *base, size_t nel, size_t elsize, qsort_arg_comparator cmp, void *arg)
void pg_qsort(void *base, size_t nel, size_t elsize, int(*cmp)(const void *, const void *))
#define DatumGetObjectId(X)
#define DatumGetPointer(X)
#define ObjectIdGetDatum(X)
#define DatumGetFloat8(X)
#define SET_VARSIZE(PTR, len)
#define DatumGetCString(X)
#define PointerGetDatum(X)
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
static int cmp(const chr *x, const chr *y, size_t len)
void init_local_reloptions(local_relopts *opts, Size relopt_struct_size)
void add_local_int_reloption(local_relopts *relopts, const char *name, const char *desc, int default_val, int min_val, int max_val, int offset)
#define BTGreaterStrategyNumber
#define BTMaxStrategyNumber
#define BTLessStrategyNumber
#define BTEqualStrategyNumber
#define BTLessEqualStrategyNumber
#define BTGreaterEqualStrategyNumber
void appendStringInfo(StringInfo str, const char *fmt,...)
void appendStringInfoString(StringInfo str, const char *s)
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
BrinOpcInfo * bd_info[FLEXIBLE_ARRAY_MEMBER]
TypeCacheEntry * oi_typcache[FLEXIBLE_ARRAY_MEMBER]
brin_serialize_callback_type bv_serialize
bool extra_proc_missing[MINMAX_MAX_PROCNUMS]
FmgrInfo extra_procinfos[MINMAX_MAX_PROCNUMS]
FmgrInfo strategy_procinfos[BTMaxStrategyNumber]
Datum values[FLEXIBLE_ARRAY_MEMBER]
char data[FLEXIBLE_ARRAY_MEMBER]
unsigned char data[UUID_LEN]
void ReleaseSysCache(HeapTuple tuple)
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
HeapTuple SearchSysCache4(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
#define TupleDescAttr(tupdesc, i)
#define store_att_byval(T, newdatum, attlen)
#define fetch_att(T, attbyval, attlen)
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
#define PG_GETARG_MACADDR_P(n)
#define PG_GETARG_MACADDR8_P(n)
#define PG_GETARG_INET_PP(n)
#define ip_family(inetptr)
#define ip_addrsize(inetptr)
#define PG_GETARG_TIMESTAMP(n)
#define PG_GETARG_INTERVAL_P(n)
Datum uuid_le(PG_FUNCTION_ARGS)
text * cstring_to_text(const char *s)
Datum byteasend(PG_FUNCTION_ARGS)