From 212d916166223777fa7c1ee8ea9f5d2f86e325f5 Mon Sep 17 00:00:00 2001 From: Tomas Vondra Date: Fri, 17 Feb 2023 02:45:14 +0100 Subject: [PATCH 7/9] Support SK_SEARCHARRAY in BRIN minmax-multi Similar approach to minmax, but the issues with deconstructing the array over and over are even more serious. --- src/backend/access/brin/brin_minmax_multi.c | 502 +++++++++-- src/include/catalog/pg_amproc.dat | 57 ++ src/include/catalog/pg_proc.dat | 4 + src/test/regress/expected/brin_multi.out | 926 ++++++++++++++++++++ src/test/regress/sql/brin_multi.sql | 301 +++++++ 5 files changed, 1725 insertions(+), 65 deletions(-) diff --git a/src/backend/access/brin/brin_minmax_multi.c b/src/backend/access/brin/brin_minmax_multi.c index 859e0022fb4..dd22b3e3c02 100644 --- a/src/backend/access/brin/brin_minmax_multi.c +++ b/src/backend/access/brin/brin_minmax_multi.c @@ -109,6 +109,14 @@ #define MINMAX_BUFFER_MAX 8192 #define MINMAX_BUFFER_LOAD_FACTOR 0.5 +/* + * We use some private sk_flags bits in preprocessed scan keys. We're allowed + * to use bits 16-31 (see skey.h). The uppermost bits are copied from the + * index's indoption[] array entry for the index attribute. + */ +#define SK_BRIN_SORTED 0x00010000 /* deconstructed and sorted array */ + + typedef struct MinmaxMultiOpaque { FmgrInfo extra_procinfos[MINMAX_MAX_PROCNUMS]; @@ -2562,6 +2570,157 @@ brin_minmax_multi_add_value(PG_FUNCTION_ARGS) PG_RETURN_BOOL(modified); } + +static int +compare_array_values(const void *a, const void *b, void *arg) +{ + Datum da = * (Datum *) a; + Datum db = * (Datum *) b; + SortSupport ssup = (SortSupport) arg; + + return ApplySortComparator(da, false, db, false, ssup); +} + +/* + * lower_boundary + * Determine lowest index so that (values[index] >= minvalue). + * + * The array of values is expected to be sorted, so this is the first value + * that may fall into the [minvalue, maxvalue] range, as it exceeds minval. + * It's not guaranteed, though, as it might exceed maxvalue too. + */ +static int +lower_boundary(Datum *values, int nvalues, Datum minvalue, SortSupport ssup) +{ + int start = 0, + end = (nvalues - 1); + + /* everything exceeds minval and might match */ + if (compare_array_values(&minvalue, &values[start], ssup) <= 0) + return 0; + + /* nothing could match */ + if (compare_array_values(&minvalue, &values[end], ssup) > 0) + return nvalues; + + while ((end - start) > 0) + { + int midpoint; + int r; + + midpoint = start + (end - start) / 2; + + r = compare_array_values(&minvalue, &values[midpoint], ssup); + + if (r > 0) + start = Max(midpoint, start + 1); + else + end = midpoint; + } + + /* the value should meet the (v >=minvalue) requirement */ + Assert(compare_array_values(&values[start], &minvalue, ssup) >= 0); + + /* we know start can't be 0, so it's legal to subtract 1 */ + Assert(compare_array_values(&values[start-1], &minvalue, ssup) < 0); + + return start; +} + +typedef struct ScanKeyArray { + Oid typeid; + int nelements; + Datum *elements; +} ScanKeyArray; + +Datum +brin_minmax_multi_preprocess(PG_FUNCTION_ARGS) +{ + // BrinDesc *bdesc = (BrinDesc *) PG_GETARG_POINTER(0); + ScanKey key = (ScanKey) PG_GETARG_POINTER(1); + ScanKey newkey; + ScanKeyArray *scanarray; + + ArrayType *arrayval; + int16 elmlen; + bool elmbyval; + char elmalign; + int num_elems; + Datum *elem_values; + bool *elem_nulls; + TypeCacheEntry *type; + SortSupportData ssup; + + /* number of non-null elements in the array */ + int num_nonnulls; + + /* + * ignore scalar keys + * + * XXX Maybe we should preprocess scalar keys too. It'd make the consistent + * function simpler by removing the branching. + */ + if (!(key->sk_flags & SK_SEARCHARRAY)) + PG_RETURN_POINTER(key); + + arrayval = DatumGetArrayTypeP(key->sk_argument); + + get_typlenbyvalalign(ARR_ELEMTYPE(arrayval), + &elmlen, &elmbyval, &elmalign); + + deconstruct_array(arrayval, + ARR_ELEMTYPE(arrayval), + elmlen, elmbyval, elmalign, + &elem_values, &elem_nulls, &num_elems); + + /* eliminate NULL elements */ + num_nonnulls = 0; + for (int i = 0; i < num_elems; i++) + { + /* skip NULL elements */ + if (elem_nulls[i]) + continue; + + /* if needed, move the non-NULL ones */ + if (num_nonnulls != i) + elem_values[num_nonnulls] = elem_values[i]; + + num_nonnulls++; + } + + num_elems = num_nonnulls; + + type = lookup_type_cache(ARR_ELEMTYPE(arrayval), TYPECACHE_LT_OPR); + + memset(&ssup, 0, sizeof(SortSupportData)); + + ssup.ssup_collation = key->sk_collation; + ssup.ssup_cxt = CurrentMemoryContext; + + PrepareSortSupportFromOrderingOp(type->lt_opr, &ssup); + + qsort_interruptible(elem_values, num_elems, sizeof(Datum), + compare_array_values, &ssup); + + scanarray = palloc0(sizeof(ScanKeyArray)); + scanarray->typeid = ARR_ELEMTYPE(arrayval); + scanarray->nelements = num_elems; + scanarray->elements = elem_values; + + newkey = palloc0(sizeof(ScanKeyData)); + + ScanKeyEntryInitializeWithInfo(newkey, + (key->sk_flags | SK_BRIN_SORTED), + key->sk_attno, + key->sk_strategy, + key->sk_subtype, + key->sk_collation, + &key->sk_func, + PointerGetDatum(scanarray)); + + PG_RETURN_POINTER(newkey); +} + /* * Given an index tuple corresponding to a certain page range and a scan key, * return whether the scan key is consistent with the index tuple's min/max @@ -2591,6 +2750,15 @@ brin_minmax_multi_consistent(PG_FUNCTION_ARGS) serialized = (SerializedRanges *) PG_DETOAST_DATUM(column->bv_values[0]); ranges = brin_range_deserialize(serialized->maxvalues, serialized); + /* + * XXX Would it make sense to have a quick initial check on the whole + * summary? We know most page ranges are not expected to match, and we + * know the ranges/values are sorted so we could check global min/max + * (essentially what regular minmax is doing) and bail if no match is + * possible. That should be cheap and might save a lot on inspecting + * the individual ranges/values. + */ + /* inspect the ranges, and for each one evaluate the scan keys */ for (rangeno = 0; rangeno < ranges->nranges; rangeno++) { @@ -2611,67 +2779,183 @@ brin_minmax_multi_consistent(PG_FUNCTION_ARGS) attno = key->sk_attno; subtype = key->sk_subtype; value = key->sk_argument; - switch (key->sk_strategy) + + if (likely(!(key->sk_flags & SK_BRIN_SORTED))) { - case BTLessStrategyNumber: - case BTLessEqualStrategyNumber: - finfo = minmax_multi_get_strategy_procinfo(bdesc, attno, subtype, - key->sk_strategy); - /* first value from the array */ - matches = FunctionCall2Coll(finfo, colloid, minval, value); - break; + switch (key->sk_strategy) + { + case BTLessStrategyNumber: + case BTLessEqualStrategyNumber: + finfo = minmax_multi_get_strategy_procinfo(bdesc, attno, subtype, + key->sk_strategy); + /* first value from the array */ + matches = FunctionCall2Coll(finfo, colloid, minval, value); + break; - case BTEqualStrategyNumber: - { - Datum compar; - FmgrInfo *cmpFn; + case BTEqualStrategyNumber: + { + Datum compar; + FmgrInfo *cmpFn; + + /* by default this range does not match */ + matches = BoolGetDatum(false); + + /* + * Otherwise, need to compare the new value with + * boundaries of all the ranges. First check if it's + * less than the absolute minimum, which is the first + * value in the array. + */ + cmpFn = minmax_multi_get_strategy_procinfo(bdesc, attno, subtype, + BTGreaterStrategyNumber); + compar = FunctionCall2Coll(cmpFn, colloid, minval, value); + + /* smaller than the smallest value in this range */ + if (DatumGetBool(compar)) + break; + + cmpFn = minmax_multi_get_strategy_procinfo(bdesc, attno, subtype, + BTLessStrategyNumber); + compar = FunctionCall2Coll(cmpFn, colloid, maxval, value); + + /* larger than the largest value in this range */ + if (DatumGetBool(compar)) + break; + + /* + * We haven't managed to eliminate this range, so + * consider it matching. + */ + matches = BoolGetDatum(true); - /* by default this range does not match */ - matches = BoolGetDatum(false); + break; + } + case BTGreaterEqualStrategyNumber: + case BTGreaterStrategyNumber: + finfo = minmax_multi_get_strategy_procinfo(bdesc, attno, subtype, + key->sk_strategy); + /* last value from the array */ + matches = FunctionCall2Coll(finfo, colloid, maxval, value); + break; - /* - * Otherwise, need to compare the new value with - * boundaries of all the ranges. First check if it's - * less than the absolute minimum, which is the first - * value in the array. - */ - cmpFn = minmax_multi_get_strategy_procinfo(bdesc, attno, subtype, - BTGreaterStrategyNumber); - compar = FunctionCall2Coll(cmpFn, colloid, minval, value); + default: + /* shouldn't happen */ + elog(ERROR, "invalid strategy number %d", key->sk_strategy); + matches = BoolGetDatum(false); + break; + } + } + else + { + ScanKeyArray *array = (ScanKeyArray *) value; - /* smaller than the smallest value in this range */ - if (DatumGetBool(compar)) - break; + /* can happen if the IN list contained just NULLs */ + if (array->nelements == 0) + PG_RETURN_BOOL(false); - cmpFn = minmax_multi_get_strategy_procinfo(bdesc, attno, subtype, - BTLessStrategyNumber); - compar = FunctionCall2Coll(cmpFn, colloid, maxval, value); + switch (key->sk_strategy) + { + case BTLessStrategyNumber: + case BTLessEqualStrategyNumber: + finfo = minmax_multi_get_strategy_procinfo(bdesc, attno, subtype, + key->sk_strategy); + /* first value from the array */ + matches = FunctionCall2Coll(finfo, colloid, minval, + array->elements[array->nelements-1]); + break; - /* larger than the largest value in this range */ - if (DatumGetBool(compar)) - break; + case BTEqualStrategyNumber: /* - * We haven't managed to eliminate this range, so - * consider it matching. + * See brin_minmax.c for description of what this is doing. */ - matches = BoolGetDatum(true); - + { + Datum val; + SortSupportData ssup; + int lower; + TypeCacheEntry *type; + + /* Is the first (smallest) value after the BRIN range? */ + val = array->elements[0]; + + finfo = minmax_multi_get_strategy_procinfo(bdesc, attno, subtype, + BTLessEqualStrategyNumber); + matches = FunctionCall2Coll(finfo, colloid, val, maxval); + + /* minval > max(range values) */ + if (!DatumGetBool(matches)) + break; + + /* Is the last (largest) value before the BRIN range? */ + val = array->elements[array->nelements-1]; + + finfo = minmax_multi_get_strategy_procinfo(bdesc, attno, subtype, + BTGreaterEqualStrategyNumber); + matches = FunctionCall2Coll(finfo, colloid, val, minval); + + /* maxval < min(range values) */ + if (!DatumGetBool(matches)) + break; + + /* + * OK, there might be some values matching the range. We have + * to search them one by one, or perhaps try binsearch. + */ + type = lookup_type_cache(array->typeid, TYPECACHE_LT_OPR); + + memset(&ssup, 0, sizeof(SortSupportData)); + + ssup.ssup_collation = key->sk_collation; + ssup.ssup_cxt = CurrentMemoryContext; + + PrepareSortSupportFromOrderingOp(type->lt_opr, &ssup); + + lower = lower_boundary(array->elements, array->nelements, minval, &ssup); + + /* no elements can possibly match */ + if (lower == array->nelements) + { + matches = BoolGetDatum(false); + break; + } + + /* + * OK, the first element must match the upper boundary too + * (if it does not, no following elements can). + */ + val = array->elements[lower]; + + /* + * In the equality case (WHERE col = someval), we want to return + * the current page range if the minimum value in the range <= + * scan key, and the maximum value >= scan key. + */ + finfo = minmax_multi_get_strategy_procinfo(bdesc, attno, subtype, + BTLessEqualStrategyNumber); + matches = FunctionCall2Coll(finfo, colloid, minval, val); + if (!DatumGetBool(matches)) + break; + /* max() >= scankey */ + finfo = minmax_multi_get_strategy_procinfo(bdesc, attno, subtype, + BTGreaterEqualStrategyNumber); + matches = FunctionCall2Coll(finfo, colloid, maxval, val); + break; + } + case BTGreaterEqualStrategyNumber: + case BTGreaterStrategyNumber: + finfo = minmax_multi_get_strategy_procinfo(bdesc, attno, subtype, + key->sk_strategy); + /* last value from the array */ + matches = FunctionCall2Coll(finfo, colloid, maxval, + array->elements[0]); break; - } - case BTGreaterEqualStrategyNumber: - case BTGreaterStrategyNumber: - finfo = minmax_multi_get_strategy_procinfo(bdesc, attno, subtype, - key->sk_strategy); - /* last value from the array */ - matches = FunctionCall2Coll(finfo, colloid, maxval, value); - break; - default: - /* shouldn't happen */ - elog(ERROR, "invalid strategy number %d", key->sk_strategy); - matches = BoolGetDatum(false); - break; + default: + /* shouldn't happen */ + elog(ERROR, "invalid strategy number %d", key->sk_strategy); + matches = BoolGetDatum(false); + break; + } } /* the range has to match all the scan keys */ @@ -2713,24 +2997,112 @@ brin_minmax_multi_consistent(PG_FUNCTION_ARGS) attno = key->sk_attno; subtype = key->sk_subtype; value = key->sk_argument; - switch (key->sk_strategy) + if (likely(!(key->sk_flags & SK_SEARCHARRAY))) { - case BTLessStrategyNumber: - case BTLessEqualStrategyNumber: - case BTEqualStrategyNumber: - case BTGreaterEqualStrategyNumber: - case BTGreaterStrategyNumber: - - finfo = minmax_multi_get_strategy_procinfo(bdesc, attno, subtype, - key->sk_strategy); - matches = FunctionCall2Coll(finfo, colloid, val, value); - break; + switch (key->sk_strategy) + { + case BTLessStrategyNumber: + case BTLessEqualStrategyNumber: + case BTEqualStrategyNumber: + case BTGreaterEqualStrategyNumber: + case BTGreaterStrategyNumber: + + finfo = minmax_multi_get_strategy_procinfo(bdesc, attno, subtype, + key->sk_strategy); + matches = FunctionCall2Coll(finfo, colloid, val, value); + break; - default: - /* shouldn't happen */ - elog(ERROR, "invalid strategy number %d", key->sk_strategy); - matches = BoolGetDatum(false); - break; + default: + /* shouldn't happen */ + elog(ERROR, "invalid strategy number %d", key->sk_strategy); + matches = BoolGetDatum(false); + break; + } + } + else + { + ScanKeyArray *array = (ScanKeyArray *) value; + + /* can happen if the IN list contained just NULLs */ + if (array->nelements == 0) + PG_RETURN_BOOL(false); + + /* + * XXX We should be able to be smarter for the scalar values, as + * we keep them sorted too. So we should be able to quickly check + * if any of the values can match the sorted key values. + */ + switch (key->sk_strategy) + { + case BTLessStrategyNumber: + case BTLessEqualStrategyNumber: + finfo = minmax_multi_get_strategy_procinfo(bdesc, attno, subtype, + key->sk_strategy); + /* first value from the array */ + matches = FunctionCall2Coll(finfo, colloid, val, + array->elements[array->nelements-1]); + break; + + case BTEqualStrategyNumber: + + /* + * See brin_minmax.c for description of what this is doing. + */ + { + SortSupportData ssup; + int lower; + TypeCacheEntry *type; + + /* + * OK, there might be some values matching the range. We have + * to search them one by one, or perhaps try binsearch. + */ + type = lookup_type_cache(array->typeid, TYPECACHE_LT_OPR); + + memset(&ssup, 0, sizeof(SortSupportData)); + + ssup.ssup_collation = key->sk_collation; + ssup.ssup_cxt = CurrentMemoryContext; + + PrepareSortSupportFromOrderingOp(type->lt_opr, &ssup); + + lower = lower_boundary(array->elements, array->nelements, val, &ssup); + + /* no elements can possibly match */ + if (lower == array->nelements) + { + matches = BoolGetDatum(false); + break; + } + + /* + * OK, check the first element must match the upper boundary too + * (if it does not, no following elements can). + * + * In the equality case (WHERE col = someval), we want to return + * the current page range if the minimum value in the range <= + * scan key, and the maximum value >= scan key. + */ + finfo = minmax_multi_get_strategy_procinfo(bdesc, attno, subtype, + BTEqualStrategyNumber); + matches = FunctionCall2Coll(finfo, colloid, val, array->elements[lower]); + break; + } + case BTGreaterEqualStrategyNumber: + case BTGreaterStrategyNumber: + finfo = minmax_multi_get_strategy_procinfo(bdesc, attno, subtype, + key->sk_strategy); + /* last value from the array */ + matches = FunctionCall2Coll(finfo, colloid, val, + array->elements[0]); + break; + + default: + /* shouldn't happen */ + elog(ERROR, "invalid strategy number %d", key->sk_strategy); + matches = BoolGetDatum(false); + break; + } } /* the range has to match all the scan keys */ diff --git a/src/include/catalog/pg_amproc.dat b/src/include/catalog/pg_amproc.dat index 166681c31ef..4f17f0d58c1 100644 --- a/src/include/catalog/pg_amproc.dat +++ b/src/include/catalog/pg_amproc.dat @@ -946,6 +946,9 @@ { amprocfamily => 'brin/integer_minmax_multi_ops', amproclefttype => 'int2', amprocrighttype => 'int2', amprocnum => '5', amproc => 'brin_minmax_multi_options' }, +{ amprocfamily => 'brin/integer_minmax_multi_ops', amproclefttype => 'int2', + amprocrighttype => 'int2', amprocnum => '6', + amproc => 'brin_minmax_multi_preprocess' }, { amprocfamily => 'brin/integer_minmax_multi_ops', amproclefttype => 'int2', amprocrighttype => 'int2', amprocnum => '11', amproc => 'brin_minmax_multi_distance_int2' }, @@ -965,6 +968,9 @@ { amprocfamily => 'brin/integer_minmax_multi_ops', amproclefttype => 'int4', amprocrighttype => 'int4', amprocnum => '5', amproc => 'brin_minmax_multi_options' }, +{ amprocfamily => 'brin/integer_minmax_multi_ops', amproclefttype => 'int4', + amprocrighttype => 'int4', amprocnum => '6', + amproc => 'brin_minmax_multi_preprocess' }, { amprocfamily => 'brin/integer_minmax_multi_ops', amproclefttype => 'int4', amprocrighttype => 'int4', amprocnum => '11', amproc => 'brin_minmax_multi_distance_int4' }, @@ -984,6 +990,9 @@ { amprocfamily => 'brin/integer_minmax_multi_ops', amproclefttype => 'int8', amprocrighttype => 'int8', amprocnum => '5', amproc => 'brin_minmax_multi_options' }, +{ amprocfamily => 'brin/integer_minmax_multi_ops', amproclefttype => 'int8', + amprocrighttype => 'int8', amprocnum => '6', + amproc => 'brin_minmax_multi_preprocess' }, { amprocfamily => 'brin/integer_minmax_multi_ops', amproclefttype => 'int8', amprocrighttype => 'int8', amprocnum => '11', amproc => 'brin_minmax_multi_distance_int8' }, @@ -1095,6 +1104,9 @@ { amprocfamily => 'brin/oid_minmax_multi_ops', amproclefttype => 'oid', amprocrighttype => 'oid', amprocnum => '5', amproc => 'brin_minmax_multi_options' }, +{ amprocfamily => 'brin/oid_minmax_multi_ops', amproclefttype => 'oid', + amprocrighttype => 'oid', amprocnum => '6', + amproc => 'brin_minmax_multi_preprocess' }, { amprocfamily => 'brin/oid_minmax_multi_ops', amproclefttype => 'oid', amprocrighttype => 'oid', amprocnum => '11', amproc => 'brin_minmax_multi_distance_int4' }, @@ -1161,6 +1173,9 @@ { amprocfamily => 'brin/tid_minmax_multi_ops', amproclefttype => 'tid', amprocrighttype => 'tid', amprocnum => '5', amproc => 'brin_minmax_multi_options' }, +{ amprocfamily => 'brin/tid_minmax_multi_ops', amproclefttype => 'tid', + amprocrighttype => 'tid', amprocnum => '6', + amproc => 'brin_minmax_multi_preprocess' }, { amprocfamily => 'brin/tid_minmax_multi_ops', amproclefttype => 'tid', amprocrighttype => 'tid', amprocnum => '11', amproc => 'brin_minmax_multi_distance_tid' }, @@ -1214,6 +1229,9 @@ { amprocfamily => 'brin/float_minmax_multi_ops', amproclefttype => 'float4', amprocrighttype => 'float4', amprocnum => '5', amproc => 'brin_minmax_multi_options' }, +{ amprocfamily => 'brin/float_minmax_multi_ops', amproclefttype => 'float4', + amprocrighttype => 'float4', amprocnum => '6', + amproc => 'brin_minmax_multi_preprocess' }, { amprocfamily => 'brin/float_minmax_multi_ops', amproclefttype => 'float4', amprocrighttype => 'float4', amprocnum => '11', amproc => 'brin_minmax_multi_distance_float4' }, @@ -1233,6 +1251,9 @@ { amprocfamily => 'brin/float_minmax_multi_ops', amproclefttype => 'float8', amprocrighttype => 'float8', amprocnum => '5', amproc => 'brin_minmax_multi_options' }, +{ amprocfamily => 'brin/float_minmax_multi_ops', amproclefttype => 'float8', + amprocrighttype => 'float8', amprocnum => '6', + amproc => 'brin_minmax_multi_preprocess' }, { amprocfamily => 'brin/float_minmax_multi_ops', amproclefttype => 'float8', amprocrighttype => 'float8', amprocnum => '11', amproc => 'brin_minmax_multi_distance_float8' }, @@ -1305,6 +1326,9 @@ { amprocfamily => 'brin/macaddr_minmax_multi_ops', amproclefttype => 'macaddr', amprocrighttype => 'macaddr', amprocnum => '5', amproc => 'brin_minmax_multi_options' }, +{ amprocfamily => 'brin/macaddr_minmax_multi_ops', amproclefttype => 'macaddr', + amprocrighttype => 'macaddr', amprocnum => '6', + amproc => 'brin_minmax_multi_preprocess' }, { amprocfamily => 'brin/macaddr_minmax_multi_ops', amproclefttype => 'macaddr', amprocrighttype => 'macaddr', amprocnum => '11', amproc => 'brin_minmax_multi_distance_macaddr' }, @@ -1361,6 +1385,9 @@ { amprocfamily => 'brin/macaddr8_minmax_multi_ops', amproclefttype => 'macaddr8', amprocrighttype => 'macaddr8', amprocnum => '5', amproc => 'brin_minmax_multi_options' }, +{ amprocfamily => 'brin/macaddr8_minmax_multi_ops', + amproclefttype => 'macaddr8', amprocrighttype => 'macaddr8', amprocnum => '6', + amproc => 'brin_minmax_multi_preprocess' }, { amprocfamily => 'brin/macaddr8_minmax_multi_ops', amproclefttype => 'macaddr8', amprocrighttype => 'macaddr8', amprocnum => '11', amproc => 'brin_minmax_multi_distance_macaddr8' }, @@ -1415,6 +1442,9 @@ { amprocfamily => 'brin/network_minmax_multi_ops', amproclefttype => 'inet', amprocrighttype => 'inet', amprocnum => '5', amproc => 'brin_minmax_multi_options' }, +{ amprocfamily => 'brin/network_minmax_multi_ops', amproclefttype => 'inet', + amprocrighttype => 'inet', amprocnum => '6', + amproc => 'brin_minmax_multi_preprocess' }, { amprocfamily => 'brin/network_minmax_multi_ops', amproclefttype => 'inet', amprocrighttype => 'inet', amprocnum => '11', amproc => 'brin_minmax_multi_distance_inet' }, @@ -1521,6 +1551,9 @@ { amprocfamily => 'brin/time_minmax_multi_ops', amproclefttype => 'time', amprocrighttype => 'time', amprocnum => '5', amproc => 'brin_minmax_multi_options' }, +{ amprocfamily => 'brin/time_minmax_multi_ops', amproclefttype => 'time', + amprocrighttype => 'time', amprocnum => '6', + amproc => 'brin_minmax_multi_preprocess' }, { amprocfamily => 'brin/time_minmax_multi_ops', amproclefttype => 'time', amprocrighttype => 'time', amprocnum => '11', amproc => 'brin_minmax_multi_distance_time' }, @@ -1604,6 +1637,9 @@ { amprocfamily => 'brin/datetime_minmax_multi_ops', amproclefttype => 'timestamp', amprocrighttype => 'timestamp', amprocnum => '5', amproc => 'brin_minmax_multi_options' }, +{ amprocfamily => 'brin/datetime_minmax_multi_ops', + amproclefttype => 'timestamp', amprocrighttype => 'timestamp', + amprocnum => '6', amproc => 'brin_minmax_multi_preprocess' }, { amprocfamily => 'brin/datetime_minmax_multi_ops', amproclefttype => 'timestamp', amprocrighttype => 'timestamp', amprocnum => '11', amproc => 'brin_minmax_multi_distance_timestamp' }, @@ -1623,6 +1659,9 @@ { amprocfamily => 'brin/datetime_minmax_multi_ops', amproclefttype => 'timestamptz', amprocrighttype => 'timestamptz', amprocnum => '5', amproc => 'brin_minmax_multi_options' }, +{ amprocfamily => 'brin/datetime_minmax_multi_ops', + amproclefttype => 'timestamptz', amprocrighttype => 'timestamptz', + amprocnum => '6', amproc => 'brin_minmax_multi_preprocess' }, { amprocfamily => 'brin/datetime_minmax_multi_ops', amproclefttype => 'timestamptz', amprocrighttype => 'timestamptz', amprocnum => '11', amproc => 'brin_minmax_multi_distance_timestamp' }, @@ -1642,6 +1681,9 @@ { amprocfamily => 'brin/datetime_minmax_multi_ops', amproclefttype => 'date', amprocrighttype => 'date', amprocnum => '5', amproc => 'brin_minmax_multi_options' }, +{ amprocfamily => 'brin/datetime_minmax_multi_ops', amproclefttype => 'date', + amprocrighttype => 'date', amprocnum => '6', + amproc => 'brin_minmax_multi_preprocess' }, { amprocfamily => 'brin/datetime_minmax_multi_ops', amproclefttype => 'date', amprocrighttype => 'date', amprocnum => '11', amproc => 'brin_minmax_multi_distance_date' }, @@ -1733,6 +1775,9 @@ { amprocfamily => 'brin/interval_minmax_multi_ops', amproclefttype => 'interval', amprocrighttype => 'interval', amprocnum => '5', amproc => 'brin_minmax_multi_options' }, +{ amprocfamily => 'brin/interval_minmax_multi_ops', + amproclefttype => 'interval', amprocrighttype => 'interval', amprocnum => '6', + amproc => 'brin_minmax_multi_preprocess' }, { amprocfamily => 'brin/interval_minmax_multi_ops', amproclefttype => 'interval', amprocrighttype => 'interval', amprocnum => '11', amproc => 'brin_minmax_multi_distance_interval' }, @@ -1789,6 +1834,9 @@ { amprocfamily => 'brin/timetz_minmax_multi_ops', amproclefttype => 'timetz', amprocrighttype => 'timetz', amprocnum => '5', amproc => 'brin_minmax_multi_options' }, +{ amprocfamily => 'brin/timetz_minmax_multi_ops', amproclefttype => 'timetz', + amprocrighttype => 'timetz', amprocnum => '6', + amproc => 'brin_minmax_multi_preprocess' }, { amprocfamily => 'brin/timetz_minmax_multi_ops', amproclefttype => 'timetz', amprocrighttype => 'timetz', amprocnum => '11', amproc => 'brin_minmax_multi_distance_timetz' }, @@ -1875,6 +1923,9 @@ { amprocfamily => 'brin/numeric_minmax_multi_ops', amproclefttype => 'numeric', amprocrighttype => 'numeric', amprocnum => '5', amproc => 'brin_minmax_multi_options' }, +{ amprocfamily => 'brin/numeric_minmax_multi_ops', amproclefttype => 'numeric', + amprocrighttype => 'numeric', amprocnum => '6', + amproc => 'brin_minmax_multi_preprocess' }, { amprocfamily => 'brin/numeric_minmax_multi_ops', amproclefttype => 'numeric', amprocrighttype => 'numeric', amprocnum => '11', amproc => 'brin_minmax_multi_distance_numeric' }, @@ -1929,6 +1980,9 @@ { amprocfamily => 'brin/uuid_minmax_multi_ops', amproclefttype => 'uuid', amprocrighttype => 'uuid', amprocnum => '5', amproc => 'brin_minmax_multi_options' }, +{ amprocfamily => 'brin/uuid_minmax_multi_ops', amproclefttype => 'uuid', + amprocrighttype => 'uuid', amprocnum => '6', + amproc => 'brin_minmax_multi_preprocess' }, { amprocfamily => 'brin/uuid_minmax_multi_ops', amproclefttype => 'uuid', amprocrighttype => 'uuid', amprocnum => '11', amproc => 'brin_minmax_multi_distance_uuid' }, @@ -2005,6 +2059,9 @@ { amprocfamily => 'brin/pg_lsn_minmax_multi_ops', amproclefttype => 'pg_lsn', amprocrighttype => 'pg_lsn', amprocnum => '5', amproc => 'brin_minmax_multi_options' }, +{ amprocfamily => 'brin/pg_lsn_minmax_multi_ops', amproclefttype => 'pg_lsn', + amprocrighttype => 'pg_lsn', amprocnum => '6', + amproc => 'brin_minmax_multi_preprocess' }, { amprocfamily => 'brin/pg_lsn_minmax_multi_ops', amproclefttype => 'pg_lsn', amprocrighttype => 'pg_lsn', amprocnum => '11', amproc => 'brin_minmax_multi_distance_pg_lsn' }, diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 6638552bd05..4e8d6668648 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -8520,6 +8520,10 @@ proname => 'brin_minmax_multi_options', proisstrict => 'f', prorettype => 'void', proargtypes => 'internal', prosrc => 'brin_minmax_multi_options' }, +{ oid => '9326', descr => 'BRIN multi minmax support', + proname => 'brin_minmax_multi_preprocess', proisstrict => 'f', + prorettype => 'internal', proargtypes => 'internal internal', + prosrc => 'brin_minmax_multi_preprocess' }, { oid => '4621', descr => 'BRIN multi minmax int2 distance', proname => 'brin_minmax_multi_distance_int2', prorettype => 'float8', diff --git a/src/test/regress/expected/brin_multi.out b/src/test/regress/expected/brin_multi.out index 98e1cdaa361..15355b699d7 100644 --- a/src/test/regress/expected/brin_multi.out +++ b/src/test/regress/expected/brin_multi.out @@ -823,3 +823,929 @@ SELECT COUNT(*) FROM brin_test_multi_2 WHERE a >= 'c51ce410-c124-a10e-0db5-e4b97 DROP TABLE brin_test_multi_2; RESET enable_seqscan; +-- do some tests on IN clauses for simple data types +CREATE TABLE brin_in_test_multi_1 (a INT, b BIGINT) WITH (fillfactor=10); +INSERT INTO brin_in_test_multi_1 +SELECT i/5 + mod(991 * i + 617, 20), + i/10 + mod(853 * i + 491, 30) + FROM generate_series(1,1000) s(i); +CREATE INDEX brin_in_test_multi_1_idx_1 ON brin_in_test_multi_1 USING brin (a int4_minmax_multi_ops) WITH (pages_per_range=1); +CREATE INDEX brin_in_test_multi_1_idx_2 ON brin_in_test_multi_1 USING brin (b int8_minmax_multi_ops) WITH (pages_per_range=1); +SET enable_seqscan=off; +-- int: equality +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (113); + QUERY PLAN +------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (a = 113) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_1 + Index Cond: (a = 113) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (113); + count +------- + 8 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (113, NULL); + QUERY PLAN +--------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (a = ANY ('{113,NULL}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_1 + Index Cond: (a = ANY ('{113,NULL}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (113, NULL); + count +------- + 8 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (NULL, NULL); + QUERY PLAN +---------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (a = ANY ('{NULL,NULL}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_1 + Index Cond: (a = ANY ('{NULL,NULL}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (NULL, NULL); + count +------- + 0 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (113, 177); + QUERY PLAN +-------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (a = ANY ('{113,177}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_1 + Index Cond: (a = ANY ('{113,177}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (113, 177); + count +------- + 16 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (-113, -177); + QUERY PLAN +---------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (a = ANY ('{-113,-177}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_1 + Index Cond: (a = ANY ('{-113,-177}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (-113, -177); + count +------- + 0 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (313, 377); + QUERY PLAN +-------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (a = ANY ('{313,377}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_1 + Index Cond: (a = ANY ('{313,377}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (313, 377); + count +------- + 0 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (113, 177, NULL); + QUERY PLAN +------------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (a = ANY ('{113,177,NULL}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_1 + Index Cond: (a = ANY ('{113,177,NULL}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (113, 177, NULL); + count +------- + 16 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (113, 177, 25); + QUERY PLAN +----------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (a = ANY ('{113,177,25}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_1 + Index Cond: (a = ANY ('{113,177,25}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (113, 177, 25); + count +------- + 24 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (NULL, 113, 177, 25); + QUERY PLAN +---------------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (a = ANY ('{NULL,113,177,25}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_1 + Index Cond: (a = ANY ('{NULL,113,177,25}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (NULL, 113, 177, 25); + count +------- + 24 +(1 row) + +-- int: less than +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a < ANY(ARRAY[113]); + QUERY PLAN +------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (a < ANY ('{113}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_1 + Index Cond: (a < ANY ('{113}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a < ANY(ARRAY[113]); + count +------- + 515 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a < ANY(ARRAY[113, NULL]); + QUERY PLAN +--------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (a < ANY ('{113,NULL}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_1 + Index Cond: (a < ANY ('{113,NULL}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a < ANY(ARRAY[113, NULL]); + count +------- + 515 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a < ANY(ARRAY[NULL, NULL]::int[]); + QUERY PLAN +---------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (a < ANY ('{NULL,NULL}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_1 + Index Cond: (a < ANY ('{NULL,NULL}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a < ANY(ARRAY[NULL, NULL]::int[]); + count +------- + 0 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a <= ANY(ARRAY[113, 177]); + QUERY PLAN +--------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (a <= ANY ('{113,177}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_1 + Index Cond: (a <= ANY ('{113,177}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a <= ANY(ARRAY[113, 177]); + count +------- + 843 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a < ANY(ARRAY[113, 177, NULL]); + QUERY PLAN +------------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (a < ANY ('{113,177,NULL}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_1 + Index Cond: (a < ANY ('{113,177,NULL}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a < ANY(ARRAY[113, 177, NULL]); + count +------- + 835 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a <= ANY(ARRAY[113, 177, 25]); + QUERY PLAN +------------------------------------------------------------------ + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (a <= ANY ('{113,177,25}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_1 + Index Cond: (a <= ANY ('{113,177,25}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a <= ANY(ARRAY[113, 177, 25]); + count +------- + 843 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a < ANY(ARRAY[NULL, 113, 177, 25]); + QUERY PLAN +---------------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (a < ANY ('{NULL,113,177,25}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_1 + Index Cond: (a < ANY ('{NULL,113,177,25}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a < ANY(ARRAY[NULL, 113, 177, 25]); + count +------- + 835 +(1 row) + +-- int: greater than +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a > ANY(ARRAY[113]); + QUERY PLAN +------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (a > ANY ('{113}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_1 + Index Cond: (a > ANY ('{113}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a > ANY(ARRAY[113]); + count +------- + 477 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a > ANY(ARRAY[113, NULL]); + QUERY PLAN +--------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (a > ANY ('{113,NULL}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_1 + Index Cond: (a > ANY ('{113,NULL}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a > ANY(ARRAY[113, NULL]); + count +------- + 477 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a > ANY(ARRAY[NULL, NULL]::int[]); + QUERY PLAN +---------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (a > ANY ('{NULL,NULL}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_1 + Index Cond: (a > ANY ('{NULL,NULL}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a > ANY(ARRAY[NULL, NULL]::int[]); + count +------- + 0 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a >= ANY(ARRAY[113, 177]); + QUERY PLAN +--------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (a >= ANY ('{113,177}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_1 + Index Cond: (a >= ANY ('{113,177}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a >= ANY(ARRAY[113, 177]); + count +------- + 485 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a > ANY(ARRAY[113, 177, NULL]); + QUERY PLAN +------------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (a > ANY ('{113,177,NULL}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_1 + Index Cond: (a > ANY ('{113,177,NULL}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a > ANY(ARRAY[113, 177, NULL]); + count +------- + 477 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a > ANY(ARRAY[113, 177, 25]); + QUERY PLAN +----------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (a > ANY ('{113,177,25}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_1 + Index Cond: (a > ANY ('{113,177,25}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a > ANY(ARRAY[113, 177, 25]); + count +------- + 917 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a >= ANY(ARRAY[NULL, 113, 177, 25]); + QUERY PLAN +----------------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (a >= ANY ('{NULL,113,177,25}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_1 + Index Cond: (a >= ANY ('{NULL,113,177,25}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a >= ANY(ARRAY[NULL, 113, 177, 25]); + count +------- + 925 +(1 row) + +-- bigint: equality +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (82); + QUERY PLAN +------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (b = 82) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_2 + Index Cond: (b = 82) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (82); + count +------- + 10 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (82, NULL); + QUERY PLAN +------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (b = ANY ('{82,NULL}'::bigint[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_2 + Index Cond: (b = ANY ('{82,NULL}'::bigint[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (82, NULL); + count +------- + 10 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (NULL, NULL); + QUERY PLAN +--------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (b = ANY ('{NULL,NULL}'::bigint[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_2 + Index Cond: (b = ANY ('{NULL,NULL}'::bigint[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (NULL, NULL); + count +------- + 0 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (82, 41); + QUERY PLAN +------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (b = ANY ('{82,41}'::bigint[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_2 + Index Cond: (b = ANY ('{82,41}'::bigint[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (82, 41); + count +------- + 20 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (-82, -141); + QUERY PLAN +-------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (b = ANY ('{-82,-141}'::bigint[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_2 + Index Cond: (b = ANY ('{-82,-141}'::bigint[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (-82, -141); + count +------- + 0 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (382, 441); + QUERY PLAN +------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (b = ANY ('{382,441}'::bigint[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_2 + Index Cond: (b = ANY ('{382,441}'::bigint[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (382, 441); + count +------- + 0 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (82, 41, NULL); + QUERY PLAN +---------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (b = ANY ('{82,41,NULL}'::bigint[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_2 + Index Cond: (b = ANY ('{82,41,NULL}'::bigint[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (82, 41, NULL); + count +------- + 20 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (82, 41, 15); + QUERY PLAN +-------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (b = ANY ('{82,41,15}'::bigint[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_2 + Index Cond: (b = ANY ('{82,41,15}'::bigint[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (82, 41, 15); + count +------- + 25 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (NULL, 82, 41, 15); + QUERY PLAN +------------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (b = ANY ('{NULL,82,41,15}'::bigint[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_2 + Index Cond: (b = ANY ('{NULL,82,41,15}'::bigint[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (NULL, 82, 41, 15); + count +------- + 25 +(1 row) + +-- bigint: less than +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b < ANY(ARRAY[82]); + QUERY PLAN +------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (b < ANY ('{82}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_2 + Index Cond: (b < ANY ('{82}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b < ANY(ARRAY[82]); + count +------- + 674 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b < ANY(ARRAY[82, NULL]); + QUERY PLAN +-------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (b < ANY ('{82,NULL}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_2 + Index Cond: (b < ANY ('{82,NULL}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b < ANY(ARRAY[82, NULL]); + count +------- + 674 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b < ANY(ARRAY[NULL, NULL]::bigint[]); + QUERY PLAN +--------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (b < ANY ('{NULL,NULL}'::bigint[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_2 + Index Cond: (b < ANY ('{NULL,NULL}'::bigint[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b < ANY(ARRAY[NULL, NULL]::bigint[]); + count +------- + 0 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b <= ANY(ARRAY[82, 41]); + QUERY PLAN +------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (b <= ANY ('{82,41}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_2 + Index Cond: (b <= ANY ('{82,41}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b <= ANY(ARRAY[82, 41]); + count +------- + 684 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b < ANY(ARRAY[82, 41, NULL]); + QUERY PLAN +----------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (b < ANY ('{82,41,NULL}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_2 + Index Cond: (b < ANY ('{82,41,NULL}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b < ANY(ARRAY[82, 41, NULL]); + count +------- + 674 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b <= ANY(ARRAY[82, 41, 15]); + QUERY PLAN +---------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (b <= ANY ('{82,41,15}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_2 + Index Cond: (b <= ANY ('{82,41,15}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b <= ANY(ARRAY[82, 41, 15]); + count +------- + 684 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b < ANY(ARRAY[NULL, 82, 41, 15]); + QUERY PLAN +-------------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (b < ANY ('{NULL,82,41,15}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_2 + Index Cond: (b < ANY ('{NULL,82,41,15}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b < ANY(ARRAY[NULL, 82, 41, 15]); + count +------- + 674 +(1 row) + +-- bigint: greater than +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b > ANY(ARRAY[82]); + QUERY PLAN +------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (b > ANY ('{82}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_2 + Index Cond: (b > ANY ('{82}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b > ANY(ARRAY[82]); + count +------- + 316 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b > ANY(ARRAY[82, NULL]); + QUERY PLAN +-------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (b > ANY ('{82,NULL}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_2 + Index Cond: (b > ANY ('{82,NULL}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b > ANY(ARRAY[82, NULL]); + count +------- + 316 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b > ANY(ARRAY[NULL, NULL]::bigint[]); + QUERY PLAN +--------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (b > ANY ('{NULL,NULL}'::bigint[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_2 + Index Cond: (b > ANY ('{NULL,NULL}'::bigint[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b > ANY(ARRAY[NULL, NULL]::bigint[]); + count +------- + 0 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b > ANY(ARRAY[82, 41]); + QUERY PLAN +------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (b > ANY ('{82,41}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_2 + Index Cond: (b > ANY ('{82,41}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b > ANY(ARRAY[82, 41]); + count +------- + 726 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b >= ANY(ARRAY[82, 41, NULL]); + QUERY PLAN +------------------------------------------------------------------ + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (b >= ANY ('{82,41,NULL}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_2 + Index Cond: (b >= ANY ('{82,41,NULL}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b >= ANY(ARRAY[82, 41, NULL]); + count +------- + 736 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b >= ANY(ARRAY[82, 41, 15]); + QUERY PLAN +---------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (b >= ANY ('{82,41,15}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_2 + Index Cond: (b >= ANY ('{82,41,15}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b >= ANY(ARRAY[82, 41, 15]); + count +------- + 961 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b > ANY(ARRAY[NULL, 82, 41, 15]); + QUERY PLAN +-------------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_1 + Recheck Cond: (b > ANY ('{NULL,82,41,15}'::integer[])) + -> Bitmap Index Scan on brin_in_test_multi_1_idx_2 + Index Cond: (b > ANY ('{NULL,82,41,15}'::integer[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b > ANY(ARRAY[NULL, 82, 41, 15]); + count +------- + 956 +(1 row) + +DROP TABLE brin_in_test_multi_1; +RESET enable_seqscan; +-- do some tests on IN clauses for varlena data types +CREATE TABLE brin_in_test_multi_2 (a UUID) WITH (fillfactor=10); +INSERT INTO brin_in_test_multi_2 +SELECT v::uuid FROM (SELECT row_number() OVER (ORDER BY v) c, v FROM (SELECT md5((i/13)::text) AS v FROM generate_series(1,1000) s(i)) foo) bar ORDER BY c + 25 * random(); +CREATE INDEX brin_in_test_multi_2_idx ON brin_in_test_multi_2 USING brin (a uuid_minmax_multi_ops) WITH (pages_per_range=1); +SET enable_seqscan=off; +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN ('33e75ff0-9dd6-01bb-e69f-351039152189'); + QUERY PLAN +------------------------------------------------------------------------------ + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_2 + Recheck Cond: (a = '33e75ff0-9dd6-01bb-e69f-351039152189'::uuid) + -> Bitmap Index Scan on brin_in_test_multi_2_idx + Index Cond: (a = '33e75ff0-9dd6-01bb-e69f-351039152189'::uuid) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN ('33e75ff0-9dd6-01bb-e69f-351039152189'); + count +------- + 13 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN ('33e75ff0-9dd6-01bb-e69f-351039152189', NULL); + QUERY PLAN +--------------------------------------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_2 + Recheck Cond: (a = ANY ('{33e75ff0-9dd6-01bb-e69f-351039152189,NULL}'::uuid[])) + -> Bitmap Index Scan on brin_in_test_multi_2_idx + Index Cond: (a = ANY ('{33e75ff0-9dd6-01bb-e69f-351039152189,NULL}'::uuid[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN ('33e75ff0-9dd6-01bb-e69f-351039152189', NULL); + count +------- + 13 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN (NULL, NULL); + QUERY PLAN +------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_2 + Recheck Cond: (a = ANY ('{NULL,NULL}'::uuid[])) + -> Bitmap Index Scan on brin_in_test_multi_2_idx + Index Cond: (a = ANY ('{NULL,NULL}'::uuid[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN (NULL, NULL); + count +------- + 0 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN ('33e75ff0-9dd6-01bb-e69f-351039152189', 'f457c545-a9de-d88f-18ec-ee47145a72c0'); + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_2 + Recheck Cond: (a = ANY ('{33e75ff0-9dd6-01bb-e69f-351039152189,f457c545-a9de-d88f-18ec-ee47145a72c0}'::uuid[])) + -> Bitmap Index Scan on brin_in_test_multi_2_idx + Index Cond: (a = ANY ('{33e75ff0-9dd6-01bb-e69f-351039152189,f457c545-a9de-d88f-18ec-ee47145a72c0}'::uuid[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN ('33e75ff0-9dd6-01bb-e69f-351039152189', 'f457c545-a9de-d88f-18ec-ee47145a72c0'); + count +------- + 26 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN ('33e75ff0-9dd6-01bb-e69f-351039152189', 'f457c545-a9de-d88f-18ec-ee47145a72c0', NULL); + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_2 + Recheck Cond: (a = ANY ('{33e75ff0-9dd6-01bb-e69f-351039152189,f457c545-a9de-d88f-18ec-ee47145a72c0,NULL}'::uuid[])) + -> Bitmap Index Scan on brin_in_test_multi_2_idx + Index Cond: (a = ANY ('{33e75ff0-9dd6-01bb-e69f-351039152189,f457c545-a9de-d88f-18ec-ee47145a72c0,NULL}'::uuid[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN ('33e75ff0-9dd6-01bb-e69f-351039152189', 'f457c545-a9de-d88f-18ec-ee47145a72c0', NULL); + count +------- + 26 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN ('33e75ff0-9dd6-01bb-e69f-351039152189', 'f457c545-a9de-d88f-18ec-ee47145a72c0', 'c51ce410-c124-a10e-0db5-e4b97fc2af39'); + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_2 + Recheck Cond: (a = ANY ('{33e75ff0-9dd6-01bb-e69f-351039152189,f457c545-a9de-d88f-18ec-ee47145a72c0,c51ce410-c124-a10e-0db5-e4b97fc2af39}'::uuid[])) + -> Bitmap Index Scan on brin_in_test_multi_2_idx + Index Cond: (a = ANY ('{33e75ff0-9dd6-01bb-e69f-351039152189,f457c545-a9de-d88f-18ec-ee47145a72c0,c51ce410-c124-a10e-0db5-e4b97fc2af39}'::uuid[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN ('33e75ff0-9dd6-01bb-e69f-351039152189', 'f457c545-a9de-d88f-18ec-ee47145a72c0', 'c51ce410-c124-a10e-0db5-e4b97fc2af39'); + count +------- + 39 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN (NULL, '33e75ff0-9dd6-01bb-e69f-351039152189', 'f457c545-a9de-d88f-18ec-ee47145a72c0', 'c51ce410-c124-a10e-0db5-e4b97fc2af39'); + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on brin_in_test_multi_2 + Recheck Cond: (a = ANY ('{NULL,33e75ff0-9dd6-01bb-e69f-351039152189,f457c545-a9de-d88f-18ec-ee47145a72c0,c51ce410-c124-a10e-0db5-e4b97fc2af39}'::uuid[])) + -> Bitmap Index Scan on brin_in_test_multi_2_idx + Index Cond: (a = ANY ('{NULL,33e75ff0-9dd6-01bb-e69f-351039152189,f457c545-a9de-d88f-18ec-ee47145a72c0,c51ce410-c124-a10e-0db5-e4b97fc2af39}'::uuid[])) +(5 rows) + +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN (NULL, '33e75ff0-9dd6-01bb-e69f-351039152189', 'f457c545-a9de-d88f-18ec-ee47145a72c0', 'c51ce410-c124-a10e-0db5-e4b97fc2af39'); + count +------- + 39 +(1 row) + +DROP TABLE brin_in_test_multi_2; +RESET enable_seqscan; diff --git a/src/test/regress/sql/brin_multi.sql b/src/test/regress/sql/brin_multi.sql index a59e182bc25..fa1d5f7dfef 100644 --- a/src/test/regress/sql/brin_multi.sql +++ b/src/test/regress/sql/brin_multi.sql @@ -550,3 +550,304 @@ SELECT COUNT(*) FROM brin_test_multi_2 WHERE a >= 'c51ce410-c124-a10e-0db5-e4b97 DROP TABLE brin_test_multi_2; RESET enable_seqscan; + + +-- do some tests on IN clauses for simple data types +CREATE TABLE brin_in_test_multi_1 (a INT, b BIGINT) WITH (fillfactor=10); +INSERT INTO brin_in_test_multi_1 +SELECT i/5 + mod(991 * i + 617, 20), + i/10 + mod(853 * i + 491, 30) + FROM generate_series(1,1000) s(i); + +CREATE INDEX brin_in_test_multi_1_idx_1 ON brin_in_test_multi_1 USING brin (a int4_minmax_multi_ops) WITH (pages_per_range=1); +CREATE INDEX brin_in_test_multi_1_idx_2 ON brin_in_test_multi_1 USING brin (b int8_minmax_multi_ops) WITH (pages_per_range=1); + +SET enable_seqscan=off; + +-- int: equality +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (113); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (113); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (113, NULL); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (113, NULL); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (NULL, NULL); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (NULL, NULL); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (113, 177); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (113, 177); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (-113, -177); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (-113, -177); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (313, 377); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (313, 377); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (113, 177, NULL); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (113, 177, NULL); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (113, 177, 25); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (113, 177, 25); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (NULL, 113, 177, 25); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a IN (NULL, 113, 177, 25); + +-- int: less than +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a < ANY(ARRAY[113]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a < ANY(ARRAY[113]); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a < ANY(ARRAY[113, NULL]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a < ANY(ARRAY[113, NULL]); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a < ANY(ARRAY[NULL, NULL]::int[]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a < ANY(ARRAY[NULL, NULL]::int[]); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a <= ANY(ARRAY[113, 177]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a <= ANY(ARRAY[113, 177]); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a < ANY(ARRAY[113, 177, NULL]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a < ANY(ARRAY[113, 177, NULL]); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a <= ANY(ARRAY[113, 177, 25]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a <= ANY(ARRAY[113, 177, 25]); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a < ANY(ARRAY[NULL, 113, 177, 25]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a < ANY(ARRAY[NULL, 113, 177, 25]); + +-- int: greater than +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a > ANY(ARRAY[113]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a > ANY(ARRAY[113]); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a > ANY(ARRAY[113, NULL]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a > ANY(ARRAY[113, NULL]); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a > ANY(ARRAY[NULL, NULL]::int[]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a > ANY(ARRAY[NULL, NULL]::int[]); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a >= ANY(ARRAY[113, 177]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a >= ANY(ARRAY[113, 177]); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a > ANY(ARRAY[113, 177, NULL]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a > ANY(ARRAY[113, 177, NULL]); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a > ANY(ARRAY[113, 177, 25]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a > ANY(ARRAY[113, 177, 25]); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a >= ANY(ARRAY[NULL, 113, 177, 25]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE a >= ANY(ARRAY[NULL, 113, 177, 25]); + +-- bigint: equality +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (82); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (82); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (82, NULL); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (82, NULL); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (NULL, NULL); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (NULL, NULL); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (82, 41); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (82, 41); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (-82, -141); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (-82, -141); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (382, 441); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (382, 441); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (82, 41, NULL); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (82, 41, NULL); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (82, 41, 15); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (82, 41, 15); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (NULL, 82, 41, 15); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b IN (NULL, 82, 41, 15); + +-- bigint: less than +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b < ANY(ARRAY[82]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b < ANY(ARRAY[82]); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b < ANY(ARRAY[82, NULL]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b < ANY(ARRAY[82, NULL]); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b < ANY(ARRAY[NULL, NULL]::bigint[]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b < ANY(ARRAY[NULL, NULL]::bigint[]); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b <= ANY(ARRAY[82, 41]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b <= ANY(ARRAY[82, 41]); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b < ANY(ARRAY[82, 41, NULL]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b < ANY(ARRAY[82, 41, NULL]); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b <= ANY(ARRAY[82, 41, 15]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b <= ANY(ARRAY[82, 41, 15]); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b < ANY(ARRAY[NULL, 82, 41, 15]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b < ANY(ARRAY[NULL, 82, 41, 15]); + +-- bigint: greater than +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b > ANY(ARRAY[82]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b > ANY(ARRAY[82]); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b > ANY(ARRAY[82, NULL]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b > ANY(ARRAY[82, NULL]); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b > ANY(ARRAY[NULL, NULL]::bigint[]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b > ANY(ARRAY[NULL, NULL]::bigint[]); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b > ANY(ARRAY[82, 41]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b > ANY(ARRAY[82, 41]); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b >= ANY(ARRAY[82, 41, NULL]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b >= ANY(ARRAY[82, 41, NULL]); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b >= ANY(ARRAY[82, 41, 15]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b >= ANY(ARRAY[82, 41, 15]); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b > ANY(ARRAY[NULL, 82, 41, 15]); + +SELECT COUNT(*) FROM brin_in_test_multi_1 WHERE b > ANY(ARRAY[NULL, 82, 41, 15]); + + +DROP TABLE brin_in_test_multi_1; +RESET enable_seqscan; + + +-- do some tests on IN clauses for varlena data types +CREATE TABLE brin_in_test_multi_2 (a UUID) WITH (fillfactor=10); +INSERT INTO brin_in_test_multi_2 +SELECT v::uuid FROM (SELECT row_number() OVER (ORDER BY v) c, v FROM (SELECT md5((i/13)::text) AS v FROM generate_series(1,1000) s(i)) foo) bar ORDER BY c + 25 * random(); + +CREATE INDEX brin_in_test_multi_2_idx ON brin_in_test_multi_2 USING brin (a uuid_minmax_multi_ops) WITH (pages_per_range=1); + +SET enable_seqscan=off; + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN ('33e75ff0-9dd6-01bb-e69f-351039152189'); + +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN ('33e75ff0-9dd6-01bb-e69f-351039152189'); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN ('33e75ff0-9dd6-01bb-e69f-351039152189', NULL); + +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN ('33e75ff0-9dd6-01bb-e69f-351039152189', NULL); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN (NULL, NULL); + +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN (NULL, NULL); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN ('33e75ff0-9dd6-01bb-e69f-351039152189', 'f457c545-a9de-d88f-18ec-ee47145a72c0'); + +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN ('33e75ff0-9dd6-01bb-e69f-351039152189', 'f457c545-a9de-d88f-18ec-ee47145a72c0'); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN ('33e75ff0-9dd6-01bb-e69f-351039152189', 'f457c545-a9de-d88f-18ec-ee47145a72c0', NULL); + +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN ('33e75ff0-9dd6-01bb-e69f-351039152189', 'f457c545-a9de-d88f-18ec-ee47145a72c0', NULL); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN ('33e75ff0-9dd6-01bb-e69f-351039152189', 'f457c545-a9de-d88f-18ec-ee47145a72c0', 'c51ce410-c124-a10e-0db5-e4b97fc2af39'); + +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN ('33e75ff0-9dd6-01bb-e69f-351039152189', 'f457c545-a9de-d88f-18ec-ee47145a72c0', 'c51ce410-c124-a10e-0db5-e4b97fc2af39'); + +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN (NULL, '33e75ff0-9dd6-01bb-e69f-351039152189', 'f457c545-a9de-d88f-18ec-ee47145a72c0', 'c51ce410-c124-a10e-0db5-e4b97fc2af39'); + +SELECT COUNT(*) FROM brin_in_test_multi_2 WHERE a IN (NULL, '33e75ff0-9dd6-01bb-e69f-351039152189', 'f457c545-a9de-d88f-18ec-ee47145a72c0', 'c51ce410-c124-a10e-0db5-e4b97fc2af39'); + +DROP TABLE brin_in_test_multi_2; +RESET enable_seqscan; -- 2.39.1