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))
275 #ifdef USE_ASSERT_CHECKING
286 for (
i = 0;
i < (nvalues - 1);
i++)
300 #ifdef USE_ASSERT_CHECKING
316 AssertArrayOrder(cmpFn, colloid, ranges->
values, 2 * ranges->
nranges);
319 AssertArrayOrder(cmpFn, colloid, &ranges->
values[2 * ranges->
nranges],
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);
411 for (
i = ranges->
nsorted; i < ranges->nvalues;
i++)
432 #ifdef USE_ASSERT_CHECKING
447 for (
i = 0;
i < nranges;
i++)
453 if (ranges[
i].collapsed)
465 for (
i = 0;
i < nranges - 1;
i++)
549 for (
i = 1;
i <
range->nvalues;
i++)
553 &
range->values[start +
i],
557 range->values[start + n] =
range->values[start +
i];
610 typid =
range->typid;
627 for (
i = 0;
i < nvalues;
i++)
632 else if (typlen == -2)
636 for (
i = 0;
i < nvalues;
i++)
645 len += nvalues * typlen;
655 serialized->
typid = typid;
664 ptr = serialized->
data;
666 for (
int i = 0;
i < nvalues;
i++)
682 memcpy(ptr, &tmp, typlen);
690 else if (typlen == -1)
697 else if (typlen == -2)
706 Assert(ptr <= ((
char *) serialized +
len));
710 Assert(ptr == ((
char *) serialized +
len));
741 Assert(nvalues <= serialized->maxvalues);
750 range->maxvalues = maxvalues;
763 ptr = serialized->
data;
773 for (
i = 0; (
i < nvalues) && (!typbyval);
i++)
777 else if (typlen == -1)
782 else if (typlen == -2)
784 Size slen = strlen(ptr) + 1;
792 dataptr =
palloc(datalen);
798 ptr = serialized->
data;
800 for (
i = 0;
i < nvalues;
i++)
806 memcpy(&v, ptr, typlen);
815 memcpy(dataptr, ptr, typlen);
820 else if (typlen == -1)
828 else if (typlen == -2)
830 Size slen = strlen(ptr) + 1;
834 memcpy(dataptr, ptr, slen);
941 minvalue = ranges->
values[0];
980 int midpoint = (start + end) / 2;
987 minvalue = ranges->
values[2 * midpoint];
988 maxvalue = ranges->
values[2 * midpoint + 1];
999 end = (midpoint - 1);
1012 start = (midpoint + 1);
1053 Oid typid = attr->atttypid;
1094 for (
i = 2 * ranges->
nranges; i < 2 * ranges->nranges + ranges->
nsorted;
i++)
1207 for (
i = 1;
i < neranges;
i++)
1220 Assert((n > 0) && (n <= neranges));
1240 while (
idx < (neranges - 1))
1249 eranges[
idx].maxval,
1250 eranges[
idx + 1].minval);
1270 eranges[
idx].maxval,
1271 eranges[
idx + 1].maxval);
1288 memmove(&eranges[
idx + 1], &eranges[
idx + 2],
1344 ndistances = (neranges - 1);
1351 for (
i = 0;
i < ndistances;
i++)
1406 *nranges = neranges;
1411 #ifdef USE_ASSERT_CHECKING
1423 for (
i = 0;
i < ncranges;
i++)
1425 if (cranges[
i].collapsed)
1489 int ndistances = (neranges - 1);
1492 int keep = (max_values / 2 - 1);
1500 if (keep >= ndistances)
1516 for (
i = 0;
i < keep;
i++)
1527 Assert(nvalues <= max_values);
1531 Assert(nvalues % 2 == 0);
1541 for (
i = 0;
i < (nvalues / 2);
i++)
1552 return (nvalues / 2);
1567 for (
i = 0;
i < neranges;
i++)
1569 if (!eranges[
i].collapsed)
1579 for (
i = 0;
i < neranges;
i++)
1581 if (eranges[
i].collapsed)
1655 "minmax-multi context",
1709 bool modified =
false;
1734 attno, attr, ranges);
1828 "minmax-multi context",
1846 max_values, cmpFn, ranges->
colloid);
1848 Assert(count_values(eranges, neranges) <= max_values);
1891 if (isnan(
a1) && isnan(
a2))
1895 if (isnan(
a1) || isnan(
a2))
1917 if (isnan(
a1) && isnan(
a2))
1921 if (isnan(
a1) || isnan(
a2))
2069 delta += (int) u2->
data[
i] - (
int) u1->
data[
i];
2176 (
errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2177 errmsg(
"interval out of range")));
2183 (
errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2184 errmsg(
"interval out of range")));
2190 (
errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2191 errmsg(
"interval out of range")));
2226 delta = (lsnb - lsna);
2330 unsigned char *addra,
2368 for (
i = 0;
i <
len;
i++)
2373 nbits =
Max(0, lena - (
i * 8));
2376 mask = (0xFF << (8 - nbits));
2377 addra[
i] = (addra[
i] & mask);
2380 nbits =
Max(0, lenb - (
i * 8));
2383 mask = (0xFF << (8 - nbits));
2384 addrb[
i] = (addrb[
i] & mask);
2390 for (
i =
len - 1;
i >= 0;
i--)
2392 unsigned char a = addra[
i];
2393 unsigned char b = addrb[
i];
2399 Assert((delta >= 0) && (delta <= 1));
2448 bool modified =
false;
2476 int target_maxvalues;
2493 maxvalues =
Max(maxvalues, target_maxvalues);
2501 ranges->
attno = attno;
2503 ranges->
typid = attr->atttypid;
2547 ranges->
attno = attno;
2549 ranges->
typid = attr->atttypid;
2601 for (rangeno = 0; rangeno < ranges->
nranges; rangeno++)
2607 bool matching =
true;
2609 for (keyno = 0; keyno < nkeys; keyno++)
2617 attno =
key->sk_attno;
2618 subtype =
key->sk_subtype;
2620 switch (
key->sk_strategy)
2678 elog(
ERROR,
"invalid strategy number %d",
key->sk_strategy);
2684 matching &= matches;
2708 bool matching =
true;
2710 for (keyno = 0; keyno < nkeys; keyno++)
2719 attno =
key->sk_attno;
2720 subtype =
key->sk_subtype;
2722 switch (
key->sk_strategy)
2737 elog(
ERROR,
"invalid strategy number %d",
key->sk_strategy);
2743 matching &= matches;
2797 Assert(ranges_a && ranges_b);
2810 "minmax-multi context",
2878 pfree(serialized_a);
2940 Assert(strategynum >= 1 &&
2973 elog(
ERROR,
"missing operator %d(%u,%u) in opfamily %u",
2974 strategynum, attr->atttypid, subtype, opfamily);
2977 Anum_pg_amop_amopopr));
3019 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3020 errmsg(
"cannot accept a value of type %s",
"brin_minmax_multi_summary")));
3039 Ranges *ranges_deserialized;
3069 for (
i = 0;
i < ranges_deserialized->
nranges;
i++)
3092 if (ranges_deserialized->
nranges > 0)
3109 astate_values = NULL;
3111 for (
i = 0;
i < ranges_deserialized->
nvalues;
i++)
3126 if (ranges_deserialized->
nvalues > 0)
3156 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3157 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 FLEXIBLE_ARRAY_MEMBER
#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)
elog(ERROR, "%s: %s", p2, msg)
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_DETOAST_DATUM_PACKED(datum)
#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
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 *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)
void pg_qsort(void *base, size_t nel, size_t elsize, int(*cmp)(const void *, const void *))
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)
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)