92#define MINMAX_MAX_PROCNUMS 1
93#define PROCNUM_DISTANCE 11
99#define PROCNUM_BASE 11
106#define MINMAX_BUFFER_FACTOR 10
107#define MINMAX_BUFFER_MIN 256
108#define MINMAX_BUFFER_MAX 8192
109#define MINMAX_BUFFER_LOAD_FACTOR 0.5
127#define MINMAX_MULTI_DEFAULT_VALUES_PER_PAGE 32
129#define MinMaxMultiGetValuesPerRange(opts) \
130 ((opts) && (((MinMaxMultiOptions *) (opts))->valuesPerRange != 0) ? \
131 ((MinMaxMultiOptions *) (opts))->valuesPerRange : \
132 MINMAX_MULTI_DEFAULT_VALUES_PER_PAGE)
134#define SAMESIGN(a,b) (((a) < 0) == ((b) < 0))
273#ifdef USE_ASSERT_CHECKING
284 for (
i = 0;
i < (nvalues - 1);
i++)
298#ifdef USE_ASSERT_CHECKING
314 AssertArrayOrder(cmpFn, colloid, ranges->
values, 2 * ranges->
nranges);
317 AssertArrayOrder(cmpFn, colloid, &ranges->
values[2 * ranges->
nranges],
359 int midpoint = (
start + end) / 2;
366 minvalue = ranges->
values[2 * midpoint];
367 maxvalue = ranges->
values[2 * midpoint + 1];
378 end = (midpoint - 1);
391 start = (midpoint + 1);
409 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++)
608 typid =
range->typid;
625 for (
i = 0;
i < nvalues;
i++)
630 else if (typlen == -2)
634 for (
i = 0;
i < nvalues;
i++)
643 len += nvalues * typlen;
653 serialized->
typid = typid;
662 ptr = serialized->
data;
664 for (
int i = 0;
i < nvalues;
i++)
680 memcpy(ptr, &tmp, typlen);
688 else if (typlen == -1)
695 else if (typlen == -2)
704 Assert(ptr <= ((
char *) serialized +
len));
708 Assert(ptr == ((
char *) serialized +
len));
739 Assert(nvalues <= serialized->maxvalues);
748 range->maxvalues = maxvalues;
761 ptr = serialized->
data;
771 for (
i = 0; (
i < nvalues) && (!typbyval);
i++)
775 else if (typlen == -1)
780 else if (typlen == -2)
782 Size slen = strlen(ptr) + 1;
790 dataptr =
palloc(datalen);
796 ptr = serialized->
data;
798 for (
i = 0;
i < nvalues;
i++)
804 memcpy(&v, ptr, typlen);
813 memcpy(dataptr, ptr, typlen);
818 else if (typlen == -1)
826 else if (typlen == -2)
828 Size slen = strlen(ptr) + 1;
832 memcpy(dataptr, ptr, slen);
939 minvalue = ranges->
values[0];
978 int midpoint = (
start + end) / 2;
985 minvalue = ranges->
values[2 * midpoint];
986 maxvalue = ranges->
values[2 * midpoint + 1];
997 end = (midpoint - 1);
1010 start = (midpoint + 1);
1051 Oid typid = attr->atttypid;
1092 for (
i = 2 * ranges->
nranges; i < 2 * ranges->nranges + ranges->
nsorted;
i++)
1205 for (
i = 1;
i < neranges;
i++)
1218 Assert((n > 0) && (n <= neranges));
1238 while (
idx < (neranges - 1))
1247 eranges[
idx].maxval,
1248 eranges[
idx + 1].minval);
1268 eranges[
idx].maxval,
1269 eranges[
idx + 1].maxval);
1286 memmove(&eranges[
idx + 1], &eranges[
idx + 2],
1342 ndistances = (neranges - 1);
1349 for (
i = 0;
i < ndistances;
i++)
1404 *nranges = neranges;
1409#ifdef USE_ASSERT_CHECKING
1421 for (
i = 0;
i < ncranges;
i++)
1423 if (cranges[
i].collapsed)
1487 int ndistances = (neranges - 1);
1490 int keep = (max_values / 2 - 1);
1498 if (keep >= ndistances)
1514 for (
i = 0;
i < keep;
i++)
1525 Assert(nvalues <= max_values);
1529 Assert(nvalues % 2 == 0);
1539 for (
i = 0;
i < (nvalues / 2);
i++)
1550 return (nvalues / 2);
1565 for (
i = 0;
i < neranges;
i++)
1567 if (!eranges[
i].collapsed)
1577 for (
i = 0;
i < neranges;
i++)
1579 if (eranges[
i].collapsed)
1653 "minmax-multi context",
1707 bool modified =
false;
1732 attno, attr, ranges);
1826 "minmax-multi context",
1844 max_values, cmpFn, ranges->
colloid);
1846 Assert(count_values(eranges, neranges) <= max_values);
1889 if (isnan(
a1) && isnan(
a2))
1893 if (isnan(
a1) || isnan(
a2))
1915 if (isnan(
a1) && isnan(
a2))
1919 if (isnan(
a1) || isnan(
a2))
2067 delta += (int) u2->
data[
i] - (
int) u1->
data[
i];
2198 delta = (lsnb - lsna);
2302 unsigned char *addra,
2340 for (
i = 0;
i <
len;
i++)
2345 nbits =
Max(0, lena - (
i * 8));
2348 mask = (0xFF << (8 - nbits));
2349 addra[
i] = (addra[
i] & mask);
2352 nbits =
Max(0, lenb - (
i * 8));
2355 mask = (0xFF << (8 - nbits));
2356 addrb[
i] = (addrb[
i] & mask);
2362 for (
i =
len - 1;
i >= 0;
i--)
2364 unsigned char a = addra[
i];
2365 unsigned char b = addrb[
i];
2371 Assert((delta >= 0) && (delta <= 1));
2420 bool modified =
false;
2448 int target_maxvalues;
2465 maxvalues =
Max(maxvalues, target_maxvalues);
2473 ranges->
attno = attno;
2475 ranges->
typid = attr->atttypid;
2519 ranges->
attno = attno;
2521 ranges->
typid = attr->atttypid;
2573 for (rangeno = 0; rangeno < ranges->
nranges; rangeno++)
2579 bool matching =
true;
2581 for (keyno = 0; keyno < nkeys; keyno++)
2589 attno =
key->sk_attno;
2590 subtype =
key->sk_subtype;
2592 switch (
key->sk_strategy)
2650 elog(
ERROR,
"invalid strategy number %d",
key->sk_strategy);
2656 matching &= matches;
2680 bool matching =
true;
2682 for (keyno = 0; keyno < nkeys; keyno++)
2691 attno =
key->sk_attno;
2692 subtype =
key->sk_subtype;
2694 switch (
key->sk_strategy)
2709 elog(
ERROR,
"invalid strategy number %d",
key->sk_strategy);
2715 matching &= matches;
2769 Assert(ranges_a && ranges_b);
2782 "minmax-multi context",
2850 pfree(serialized_a);
2883 errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2885 errdetail_internal(
"The operator class is missing support function %d for column %d.",
2904 Assert(strategynum >= 1 &&
2937 elog(
ERROR,
"missing operator %d(%u,%u) in opfamily %u",
2938 strategynum, attr->atttypid, subtype, opfamily);
2941 Anum_pg_amop_amopopr));
2983 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2984 errmsg(
"cannot accept a value of type %s",
"brin_minmax_multi_summary")));
3003 Ranges *ranges_deserialized;
3033 for (
i = 0;
i < ranges_deserialized->
nranges;
i++)
3056 if (ranges_deserialized->
nranges > 0)
3073 astate_values = NULL;
3075 for (
i = 0;
i < ranges_deserialized->
nvalues;
i++)
3090 if (ranges_deserialized->
nvalues > 0)
3120 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3121 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)
static ExpandedRange * build_expanded_ranges(FmgrInfo *cmp, Oid colloid, Ranges *ranges, int *nranges)
#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)
static DistanceValue * build_distances(FmgrInfo *distanceFn, Oid colloid, ExpandedRange *eranges, int neranges)
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 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)
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 Ranges * brin_range_deserialize(int maxvalues, SerializedRanges *serialized)
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)
static Ranges * minmax_multi_init(int maxvalues)
#define MINMAX_BUFFER_MIN
#define RegProcedureIsValid(p)
#define PG_USED_FOR_ASSERTS_ONLY
#define FLEXIBLE_ARRAY_MEMBER
#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 errmsg_internal(const char *fmt,...)
int errdetail_internal(const char *fmt,...)
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)
char * OidOutputFunctionCall(Oid functionId, Datum val)
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, MemoryContext destcxt)
#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_GETARG_FLOAT4(n)
#define PG_RETURN_POINTER(x)
#define PG_GET_COLLATION()
#define PG_RETURN_BOOL(x)
#define PG_GETARG_INT16(n)
Assert(PointerIsAligned(start, uint64))
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)
if(TABLE==NULL||TABLE_index==NULL)
int32 ItemPointerCompare(ItemPointer arg1, ItemPointer arg2)
static OffsetNumber ItemPointerGetOffsetNumberNoCheck(const ItemPointerData *pointer)
static BlockNumber ItemPointerGetBlockNumberNoCheck(const ItemPointerData *pointer)
ItemPointerData * ItemPointer
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 *base0, 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)
#define qsort(a, b, c, d)
static bool DatumGetBool(Datum X)
static Datum PointerGetDatum(const void *X)
static Oid DatumGetObjectId(Datum X)
static Datum Int16GetDatum(int16 X)
static float8 DatumGetFloat8(Datum X)
static Datum ObjectIdGetDatum(Oid X)
static char * DatumGetCString(Datum X)
static Pointer DatumGetPointer(Datum X)
static int cmp(const chr *x, const chr *y, size_t len)
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
void init_local_reloptions(local_relopts *relopts, 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 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
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)
HeapTuple SearchSysCache4(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
static Datum fetch_att(const void *T, bool attbyval, int attlen)
static void store_att_byval(void *T, Datum newdatum, int 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)
static pg_uuid_t * DatumGetUUIDP(Datum X)
#define SET_VARSIZE(PTR, len)
text * cstring_to_text_with_len(const char *s, int len)
text * cstring_to_text(const char *s)
Datum byteasend(PG_FUNCTION_ARGS)