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
128 #define MINMAX_MULTI_DEFAULT_VALUES_PER_PAGE 32
130 #define MinMaxMultiGetValuesPerRange(opts) \
131 ((opts) && (((MinMaxMultiOptions *) (opts))->valuesPerRange != 0) ? \
132 ((MinMaxMultiOptions *) (opts))->valuesPerRange : \
133 MINMAX_MULTI_DEFAULT_VALUES_PER_PAGE)
135 #define SAMESIGN(a,b) (((a) < 0) == ((b) < 0))
274 #ifdef USE_ASSERT_CHECKING
285 for (
i = 0;
i < (nvalues - 1);
i++)
299 #ifdef USE_ASSERT_CHECKING
315 AssertArrayOrder(cmpFn, colloid, ranges->
values, 2 * ranges->
nranges);
318 AssertArrayOrder(cmpFn, colloid, &ranges->
values[2 * ranges->
nranges],
360 int midpoint = (
start + end) / 2;
367 minvalue = ranges->
values[2 * midpoint];
368 maxvalue = ranges->
values[2 * midpoint + 1];
379 end = (midpoint - 1);
392 start = (midpoint + 1);
410 for (
i = ranges->
nsorted; i < ranges->nvalues;
i++)
431 #ifdef USE_ASSERT_CHECKING
446 for (
i = 0;
i < nranges;
i++)
452 if (ranges[
i].collapsed)
464 for (
i = 0;
i < nranges - 1;
i++)
548 for (
i = 1;
i <
range->nvalues;
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 (
int 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)
783 Size slen = strlen(ptr) + 1;
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);
940 minvalue = ranges->
values[0];
979 int midpoint = (
start + end) / 2;
986 minvalue = ranges->
values[2 * midpoint];
987 maxvalue = ranges->
values[2 * midpoint + 1];
998 end = (midpoint - 1);
1011 start = (midpoint + 1);
1052 Oid typid = attr->atttypid;
1093 for (
i = 2 * ranges->
nranges; i < 2 * ranges->nranges + ranges->
nsorted;
i++)
1206 for (
i = 1;
i < neranges;
i++)
1219 Assert((n > 0) && (n <= neranges));
1239 while (
idx < (neranges - 1))
1248 eranges[
idx].maxval,
1249 eranges[
idx + 1].minval);
1269 eranges[
idx].maxval,
1270 eranges[
idx + 1].maxval);
1287 memmove(&eranges[
idx + 1], &eranges[
idx + 2],
1343 ndistances = (neranges - 1);
1350 for (
i = 0;
i < ndistances;
i++)
1405 *nranges = neranges;
1410 #ifdef USE_ASSERT_CHECKING
1422 for (
i = 0;
i < ncranges;
i++)
1424 if (cranges[
i].collapsed)
1488 int ndistances = (neranges - 1);
1491 int keep = (max_values / 2 - 1);
1499 if (keep >= ndistances)
1515 for (
i = 0;
i < keep;
i++)
1526 Assert(nvalues <= max_values);
1530 Assert(nvalues % 2 == 0);
1540 for (
i = 0;
i < (nvalues / 2);
i++)
1551 return (nvalues / 2);
1566 for (
i = 0;
i < neranges;
i++)
1568 if (!eranges[
i].collapsed)
1578 for (
i = 0;
i < neranges;
i++)
1580 if (eranges[
i].collapsed)
1654 "minmax-multi context",
1708 bool modified =
false;
1733 attno, attr, ranges);
1827 "minmax-multi context",
1845 max_values, cmpFn, ranges->
colloid);
1847 Assert(count_values(eranges, neranges) <= max_values);
1890 if (isnan(
a1) && isnan(
a2))
1894 if (isnan(
a1) || isnan(
a2))
1916 if (isnan(
a1) && isnan(
a2))
1920 if (isnan(
a1) || isnan(
a2))
2068 delta += (int) u2->
data[
i] - (
int) u1->
data[
i];
2199 delta = (lsnb - lsna);
2303 unsigned char *addra,
2341 for (
i = 0;
i <
len;
i++)
2346 nbits =
Max(0, lena - (
i * 8));
2349 mask = (0xFF << (8 - nbits));
2350 addra[
i] = (addra[
i] & mask);
2353 nbits =
Max(0, lenb - (
i * 8));
2356 mask = (0xFF << (8 - nbits));
2357 addrb[
i] = (addrb[
i] & mask);
2363 for (
i =
len - 1;
i >= 0;
i--)
2365 unsigned char a = addra[
i];
2366 unsigned char b = addrb[
i];
2372 Assert((delta >= 0) && (delta <= 1));
2421 bool modified =
false;
2449 int target_maxvalues;
2466 maxvalues =
Max(maxvalues, target_maxvalues);
2474 ranges->
attno = attno;
2476 ranges->
typid = attr->atttypid;
2520 ranges->
attno = attno;
2522 ranges->
typid = attr->atttypid;
2574 for (rangeno = 0; rangeno < ranges->
nranges; rangeno++)
2580 bool matching =
true;
2582 for (keyno = 0; keyno < nkeys; keyno++)
2590 attno =
key->sk_attno;
2591 subtype =
key->sk_subtype;
2593 switch (
key->sk_strategy)
2651 elog(
ERROR,
"invalid strategy number %d",
key->sk_strategy);
2657 matching &= matches;
2681 bool matching =
true;
2683 for (keyno = 0; keyno < nkeys; keyno++)
2692 attno =
key->sk_attno;
2693 subtype =
key->sk_subtype;
2695 switch (
key->sk_strategy)
2710 elog(
ERROR,
"invalid strategy number %d",
key->sk_strategy);
2716 matching &= matches;
2770 Assert(ranges_a && ranges_b);
2783 "minmax-multi context",
2851 pfree(serialized_a);
2913 Assert(strategynum >= 1 &&
2946 elog(
ERROR,
"missing operator %d(%u,%u) in opfamily %u",
2947 strategynum, attr->atttypid, subtype, opfamily);
2950 Anum_pg_amop_amopopr));
2992 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2993 errmsg(
"cannot accept a value of type %s",
"brin_minmax_multi_summary")));
3012 Ranges *ranges_deserialized;
3042 for (
i = 0;
i < ranges_deserialized->
nranges;
i++)
3065 if (ranges_deserialized->
nranges > 0)
3082 astate_values = NULL;
3084 for (
i = 0;
i < ranges_deserialized->
nvalues;
i++)
3099 if (ranges_deserialized->
nvalues > 0)
3129 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3130 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 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 Ranges * brin_range_deserialize(int maxvalues, SerializedRanges *serialized)
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 PG_USED_FOR_ASSERTS_ONLY
#define Assert(condition)
#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 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 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)
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 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 char * DatumGetCString(Datum X)
static Oid DatumGetObjectId(Datum X)
static Datum Int16GetDatum(int16 X)
static float8 DatumGetFloat8(Datum X)
static Datum ObjectIdGetDatum(Oid X)
static Pointer DatumGetPointer(Datum X)
MemoryContextSwitchTo(old_ctx)
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 *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
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)
HeapTuple SearchSysCache4(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4)
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
#define TupleDescAttr(tupdesc, 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)