aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTomas Vondra <tomas.vondra@postgresql.org>2023-07-02 10:33:34 +0200
committerTomas Vondra <tomas.vondra@postgresql.org>2023-07-02 10:33:38 +0200
commit0457109344b46f481f9bf09b85674695ba57c8e4 (patch)
treeaefc8772d87064ed99da8778ea17a21a495fbf0b /src
parent2b8b2852bbc54f02e26131a966e62c432144dc93 (diff)
downloadpostgresql-0457109344b46f481f9bf09b85674695ba57c8e4.tar.gz
postgresql-0457109344b46f481f9bf09b85674695ba57c8e4.zip
Improve BRIN minmax-multi opclass test coverage
Per the code coverage report, the existing regression tests did not exercice some a couple important BRIN minmax-multi code paths. - The tests focused on testing planning with a range of scan key strategies, but not the execution. Fixed by adding queries that actually test query execution for both equality and inequality. - All tests created indexes after inserting data, but this only exercises the CREATE INDEX strategy that sees all values at once, not incremental summary updates. The new tests flip the order and create the index before adding data. - The assert check(s) validating correctness of expanded ranges were present only in the "union" code path, which is not covered by regression tests at all (as it requires concurrency etc.). Fixed by adding the asserts to a couple more places. Reviewed-by: Heikki Linnakangas Discussion: https://postgr.es/m/57020b2e-d9c9-9bc7-4892-b36d9bb07563%40enterprisedb.com
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/brin/brin_minmax_multi.c9
-rw-r--r--src/test/regress/expected/brin_multi.out357
-rw-r--r--src/test/regress/sql/brin_multi.sql165
3 files changed, 531 insertions, 0 deletions
diff --git a/src/backend/access/brin/brin_minmax_multi.c b/src/backend/access/brin/brin_minmax_multi.c
index e9ce0f2a1be..f8b2a3f9bc6 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 861a06ef8ca..9f46934c9be 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 070455257c0..d50dbdee682 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;