diff --git a/src/backend/access/brin/brin_minmax_multi.c b/src/backend/access/brin/brin_minmax_multi.c index e9ce0f2a1b..f8b2a3f9bc 100644 --- a/src/backend/access/brin/brin_minmax_multi.c +++ b/src/backend/access/brin/brin_minmax_multi.c @@ -1660,6 +1660,9 @@ ensure_free_space_in_buffer(BrinDesc *bdesc, Oid colloid, /* build the expanded ranges */ eranges = build_expanded_ranges(cmpFn, colloid, range, &neranges); + /* Is the expanded representation of ranges correct? */ + AssertCheckExpandedRanges(bdesc, colloid, attno, attr, eranges, neranges); + /* and we'll also need the 'distance' procedure */ distanceFn = minmax_multi_get_procinfo(bdesc, attno, PROCNUM_DISTANCE); @@ -1675,6 +1678,9 @@ ensure_free_space_in_buffer(BrinDesc *bdesc, Oid colloid, range->maxvalues * MINMAX_BUFFER_LOAD_FACTOR, cmpFn, colloid); + /* Is the result of reducing expanded ranges correct? */ + AssertCheckExpandedRanges(bdesc, colloid, attno, attr, eranges, neranges); + /* Make sure we've sufficiently reduced the number of ranges. */ Assert(count_values(eranges, neranges) <= range->maxvalues * MINMAX_BUFFER_LOAD_FACTOR); @@ -2859,6 +2865,9 @@ brin_minmax_multi_union(PG_FUNCTION_ARGS) ranges_a->maxvalues, cmpFn, colloid); + /* Is the result of reducing expanded ranges correct? */ + AssertCheckExpandedRanges(bdesc, colloid, attno, attr, eranges, neranges); + /* update the first range summary */ store_expanded_ranges(ranges_a, eranges, neranges); diff --git a/src/test/regress/expected/brin_multi.out b/src/test/regress/expected/brin_multi.out index 861a06ef8c..9f46934c9b 100644 --- a/src/test/regress/expected/brin_multi.out +++ b/src/test/regress/expected/brin_multi.out @@ -466,3 +466,360 @@ EXPLAIN (COSTS OFF) SELECT * FROM brin_test_multi WHERE b = 1; Filter: (b = 1) (2 rows) +-- do some inequality tests +CREATE TABLE brin_test_multi_1 (a INT, b BIGINT) WITH (fillfactor=10); +INSERT INTO brin_test_multi_1 +SELECT i/5 + mod(911 * i + 483, 25), + i/10 + mod(751 * i + 221, 41) + FROM generate_series(1,1000) s(i); +CREATE INDEX brin_test_multi_1_idx_1 ON brin_test_multi_1 USING brin (a int4_minmax_multi_ops) WITH (pages_per_range=5); +CREATE INDEX brin_test_multi_1_idx_2 ON brin_test_multi_1 USING brin (b int8_minmax_multi_ops) WITH (pages_per_range=5); +SET enable_seqscan=off; +-- int: less than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a < 37; + count +------- + 124 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a < 113; + count +------- + 504 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a <= 177; + count +------- + 829 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a <= 25; + count +------- + 69 +(1 row) + +-- int: greater than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a > 120; + count +------- + 456 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a >= 180; + count +------- + 161 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a > 71; + count +------- + 701 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a >= 63; + count +------- + 746 +(1 row) + +-- int: equals +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a = 207; + count +------- + 3 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a = 177; + count +------- + 5 +(1 row) + +-- bigint: less than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b < 73; + count +------- + 529 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b <= 47; + count +------- + 279 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b < 199; + count +------- + 1000 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b <= 150; + count +------- + 1000 +(1 row) + +-- bigint: greater than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 93; + count +------- + 261 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 37; + count +------- + 821 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b >= 215; + count +------- + 0 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 201; + count +------- + 0 +(1 row) + +-- bigint: equals +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b = 88; + count +------- + 10 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b = 103; + count +------- + 9 +(1 row) + +-- now do the same, but insert the rows with the indexes already created +-- so that we don't use the "build callback" and instead use the regular +-- approach of adding rows into existing ranges +TRUNCATE brin_test_multi_1; +INSERT INTO brin_test_multi_1 +SELECT i/5 + mod(911 * i + 483, 25), + i/10 + mod(751 * i + 221, 41) + FROM generate_series(1,1000) s(i); +-- int: less than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a < 37; + count +------- + 124 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a < 113; + count +------- + 504 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a <= 177; + count +------- + 829 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a <= 25; + count +------- + 69 +(1 row) + +-- int: greater than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a > 120; + count +------- + 456 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a >= 180; + count +------- + 161 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a > 71; + count +------- + 701 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a >= 63; + count +------- + 746 +(1 row) + +-- int: equals +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a = 207; + count +------- + 3 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a = 177; + count +------- + 5 +(1 row) + +-- bigint: less than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b < 73; + count +------- + 529 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b <= 47; + count +------- + 279 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b < 199; + count +------- + 1000 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b <= 150; + count +------- + 1000 +(1 row) + +-- bigint: greater than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 93; + count +------- + 261 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 37; + count +------- + 821 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b >= 215; + count +------- + 0 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 201; + count +------- + 0 +(1 row) + +-- bigint: equals +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b = 88; + count +------- + 10 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b = 103; + count +------- + 9 +(1 row) + +DROP TABLE brin_test_multi_1; +RESET enable_seqscan; +-- do some inequality tests for varlena data types +CREATE TABLE brin_test_multi_2 (a UUID) WITH (fillfactor=10); +INSERT INTO brin_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_test_multi_2_idx ON brin_test_multi_2 USING brin (a uuid_minmax_multi_ops) WITH (pages_per_range=5); +SET enable_seqscan=off; +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a < '33e75ff0-9dd6-01bb-e69f-351039152189'; + count +------- + 195 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a > '33e75ff0-9dd6-01bb-e69f-351039152189'; + count +------- + 792 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a <= 'f457c545-a9de-d88f-18ec-ee47145a72c0'; + count +------- + 961 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a >= 'c51ce410-c124-a10e-0db5-e4b97fc2af39'; + count +------- + 272 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = 'cfcd2084-95d5-65ef-66e7-dff9f98764da'; + count +------- + 12 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = 'aab32389-22bc-c25a-6f60-6eb525ffdc56'; + count +------- + 13 +(1 row) + +-- now do the same, but insert the rows with the indexes already created +-- so that we don't use the "build callback" and instead use the regular +-- approach of adding rows into existing ranges +TRUNCATE brin_test_multi_2; +INSERT INTO brin_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(); +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a < '33e75ff0-9dd6-01bb-e69f-351039152189'; + count +------- + 195 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a > '33e75ff0-9dd6-01bb-e69f-351039152189'; + count +------- + 792 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a <= 'f457c545-a9de-d88f-18ec-ee47145a72c0'; + count +------- + 961 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a >= 'c51ce410-c124-a10e-0db5-e4b97fc2af39'; + count +------- + 272 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = 'cfcd2084-95d5-65ef-66e7-dff9f98764da'; + count +------- + 12 +(1 row) + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = 'aab32389-22bc-c25a-6f60-6eb525ffdc56'; + count +------- + 13 +(1 row) + +DROP TABLE brin_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 070455257c..d50dbdee68 100644 --- a/src/test/regress/sql/brin_multi.sql +++ b/src/test/regress/sql/brin_multi.sql @@ -421,3 +421,168 @@ VACUUM ANALYZE brin_test_multi; EXPLAIN (COSTS OFF) SELECT * FROM brin_test_multi WHERE a = 1; -- Ensure brin index is not used when values are not correlated EXPLAIN (COSTS OFF) SELECT * FROM brin_test_multi WHERE b = 1; + + +-- do some inequality tests +CREATE TABLE brin_test_multi_1 (a INT, b BIGINT) WITH (fillfactor=10); +INSERT INTO brin_test_multi_1 +SELECT i/5 + mod(911 * i + 483, 25), + i/10 + mod(751 * i + 221, 41) + FROM generate_series(1,1000) s(i); + +CREATE INDEX brin_test_multi_1_idx_1 ON brin_test_multi_1 USING brin (a int4_minmax_multi_ops) WITH (pages_per_range=5); +CREATE INDEX brin_test_multi_1_idx_2 ON brin_test_multi_1 USING brin (b int8_minmax_multi_ops) WITH (pages_per_range=5); + +SET enable_seqscan=off; + +-- int: less than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a < 37; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a < 113; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a <= 177; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a <= 25; + +-- int: greater than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a > 120; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a >= 180; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a > 71; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a >= 63; + +-- int: equals +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a = 207; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a = 177; + +-- bigint: less than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b < 73; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b <= 47; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b < 199; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b <= 150; + +-- bigint: greater than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 93; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 37; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b >= 215; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 201; + +-- bigint: equals +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b = 88; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b = 103; + +-- now do the same, but insert the rows with the indexes already created +-- so that we don't use the "build callback" and instead use the regular +-- approach of adding rows into existing ranges +TRUNCATE brin_test_multi_1; + +INSERT INTO brin_test_multi_1 +SELECT i/5 + mod(911 * i + 483, 25), + i/10 + mod(751 * i + 221, 41) + FROM generate_series(1,1000) s(i); + +-- int: less than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a < 37; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a < 113; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a <= 177; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a <= 25; + +-- int: greater than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a > 120; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a >= 180; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a > 71; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a >= 63; + +-- int: equals +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a = 207; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE a = 177; + +-- bigint: less than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b < 73; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b <= 47; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b < 199; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b <= 150; + +-- bigint: greater than +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 93; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 37; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b >= 215; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 201; + +-- bigint: equals +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b = 88; + +SELECT COUNT(*) FROM brin_test_multi_1 WHERE b = 103; + + +DROP TABLE brin_test_multi_1; +RESET enable_seqscan; + + +-- do some inequality tests for varlena data types +CREATE TABLE brin_test_multi_2 (a UUID) WITH (fillfactor=10); +INSERT INTO brin_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_test_multi_2_idx ON brin_test_multi_2 USING brin (a uuid_minmax_multi_ops) WITH (pages_per_range=5); + +SET enable_seqscan=off; + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a < '33e75ff0-9dd6-01bb-e69f-351039152189'; + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a > '33e75ff0-9dd6-01bb-e69f-351039152189'; + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a <= 'f457c545-a9de-d88f-18ec-ee47145a72c0'; + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a >= 'c51ce410-c124-a10e-0db5-e4b97fc2af39'; + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = 'cfcd2084-95d5-65ef-66e7-dff9f98764da'; + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = 'aab32389-22bc-c25a-6f60-6eb525ffdc56'; + + +-- now do the same, but insert the rows with the indexes already created +-- so that we don't use the "build callback" and instead use the regular +-- approach of adding rows into existing ranges + +TRUNCATE brin_test_multi_2; +INSERT INTO brin_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(); + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a < '33e75ff0-9dd6-01bb-e69f-351039152189'; + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a > '33e75ff0-9dd6-01bb-e69f-351039152189'; + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a <= 'f457c545-a9de-d88f-18ec-ee47145a72c0'; + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a >= 'c51ce410-c124-a10e-0db5-e4b97fc2af39'; + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = 'cfcd2084-95d5-65ef-66e7-dff9f98764da'; + +SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = 'aab32389-22bc-c25a-6f60-6eb525ffdc56'; + +DROP TABLE brin_test_multi_2; +RESET enable_seqscan;