summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2025-10-01 14:17:54 +0900
committerMichael Paquier <michael@paquier.xyz>2025-10-01 14:17:54 +0900
commit9952f6c05a40976063c3e2a4482873ec710f01a2 (patch)
treea52723f1637de7bf317193b59b3a1c87a1661cb2
parent8e2acda2b098bf53120721e16a7b1055c4e5b3a6 (diff)
test_bitmapset: Simplify code of the module
Two macros are added in this module, to cut duplicated patterns: - PG_ARG_GETBITMAPSET(), for input argument handling, with knowledge about NULL. - PG_RETURN_BITMAPSET_AS_TEXT(), that generates a text result from a Bitmapset. These changes limit the code so as the SQL functions are now mostly wrappers of the equivalent C function. Functions that use integer input arguments still need some NULL handling, like bms_make_singleton(). A NULL input is translated to "<>", which is what nodeToString() generates. Some of the tests are able to generate this result. Per discussion, the calls of bms_free() are removed. These may be justified if the functions are used in a rather long-lived memory context, but let's keep the code minimal for now. These calls used NULL checks, which were also not necessary as NULL is an input authorized by bms_free(). Some of the tests existed to cover behaviors related to the SQL functions for NULL inputs. Most of them are still relevant, as the routines of bitmapset.c are able to handle such cases. The coverage reports of bitmapset.c and test_bitmapset.c remain the same after these changes, with 300 lines of C code removed. Author: David Rowley <dgrowleyml@gmail.com> Co-authored-by: Greg Burd <greg@burd.me> Discussion: https://postgr.es/m/CAApHDvqghMnm_zgSNefto9oaEJ0S-3Cgb3gdsV7XvLC-hMS02Q@mail.gmail.com
-rw-r--r--src/test/modules/test_bitmapset/expected/test_bitmapset.out271
-rw-r--r--src/test/modules/test_bitmapset/sql/test_bitmapset.sql84
-rw-r--r--src/test/modules/test_bitmapset/test_bitmapset--1.0.sql2
-rw-r--r--src/test/modules/test_bitmapset/test_bitmapset.c615
4 files changed, 254 insertions, 718 deletions
diff --git a/src/test/modules/test_bitmapset/expected/test_bitmapset.out b/src/test/modules/test_bitmapset/expected/test_bitmapset.out
index be7b6399c82..3198614d6ad 100644
--- a/src/test/modules/test_bitmapset/expected/test_bitmapset.out
+++ b/src/test/modules/test_bitmapset/expected/test_bitmapset.out
@@ -76,7 +76,7 @@ SELECT test_bms_replace_members(NULL, '(b 1 2 3)') AS result;
SELECT test_bms_replace_members('(b 1 2 3)', NULL) AS result;
result
--------
-
+ <>
(1 row)
SELECT test_bms_replace_members('(b 1 2 3)', '(b 3 5 6)') AS result;
@@ -104,44 +104,19 @@ SELECT test_bms_replace_members('(b 1 2 3 4 5)', '(b 500 600)') AS result;
(b 500 600)
(1 row)
--- Test module checks
-SELECT test_bms_replace_members('(b 1 2 3)', NULL) AS result;
- result
---------
-
-(1 row)
-
-SELECT test_bms_replace_members('(b 5)', NULL) AS result;
- result
---------
-
-(1 row)
-
-SELECT test_bms_replace_members(NULL, '(b 5)') AS result;
- result
---------
- (b 5)
-(1 row)
-
-SELECT test_bms_replace_members(NULL, NULL) AS result;
- result
---------
-
-(1 row)
-
-- bms_del_member()
SELECT test_bms_del_member('(b)', -20); -- error
ERROR: negative bitmapset member not allowed
SELECT test_bms_del_member('(b)', 10) AS result;
result
--------
-
+ <>
(1 row)
SELECT test_bms_del_member('(b 10)', 10) AS result;
result
--------
-
+ <>
(1 row)
SELECT test_bms_del_member('(b 10)', 5) AS result;
@@ -190,12 +165,6 @@ SELECT test_bms_del_member('(b 1 50 100 200)', 100) AS result;
(1 row)
-- Test module checks
-SELECT test_bms_del_member('(b 42)', 42) AS result;
- result
---------
-
-(1 row)
-
SELECT test_bms_del_member('(b 5)', NULL) AS result;
result
--------
@@ -206,13 +175,13 @@ SELECT test_bms_del_member('(b 5)', NULL) AS result;
SELECT test_bms_del_members('(b)', '(b 10)') AS result;
result
--------
-
+ <>
(1 row)
SELECT test_bms_del_members('(b 10)', '(b 10)') AS result;
result
--------
-
+ <>
(1 row)
SELECT test_bms_del_members('(b 10)', '(b 5)') AS result;
@@ -252,7 +221,7 @@ SELECT test_bms_del_members('(b 1 2 100 200 300)', '(b 200 300)') AS result;
(b 1 2 100)
(1 row)
--- Test module checks
+-- NULL inputs
SELECT test_bms_del_members('(b 5)', NULL) AS result;
result
--------
@@ -262,7 +231,7 @@ SELECT test_bms_del_members('(b 5)', NULL) AS result;
SELECT test_bms_del_members(NULL, '(b 5)') AS result;
result
--------
-
+ <>
(1 row)
-- bms_join()
@@ -303,7 +272,7 @@ SELECT test_bms_join('(b 1 2)', '(b 100 200 300)') AS result;
(b 1 2 100 200 300)
(1 row)
--- Test module checks
+-- NULL inputs
SELECT test_bms_join('(b 5)', NULL) AS result;
result
--------
@@ -319,7 +288,7 @@ SELECT test_bms_join(NULL, '(b 5)') AS result;
SELECT test_bms_join(NULL, NULL) AS result;
result
--------
-
+ <>
(1 row)
-- bms_union()
@@ -341,7 +310,7 @@ SELECT test_bms_union('(b 1 3 5)', '(b)') AS result;
SELECT test_bms_union('(b)', '(b)') AS result;
result
--------
-
+ <>
(1 row)
-- Overlapping ranges
@@ -354,7 +323,7 @@ SELECT test_bms_union(
(b 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20)
(1 row)
--- Union with varrying word counts
+-- Union with varying word counts
SELECT test_bms_union('(b 1 2)', '(b 100 300)') AS result;
result
-----------------
@@ -367,7 +336,7 @@ SELECT test_bms_union('(b 100 300)', '(b 1 2)') AS result;
(b 1 2 100 300)
(1 row)
--- Test module checks
+-- NULL inputs
SELECT test_bms_union('(b 5)', NULL) AS result;
result
--------
@@ -383,7 +352,7 @@ SELECT test_bms_union(NULL, '(b 5)') AS result;
SELECT test_bms_union(NULL, NULL) AS result;
result
--------
-
+ <>
(1 row)
-- bms_intersect()
@@ -398,17 +367,17 @@ SELECT test_bms_intersect('(b 1 3 5)', '(b 3 5 7)') AS result;
SELECT test_bms_intersect('(b 1 3 5)', '(b 2 4 6)') AS result;
result
--------
-
+ <>
(1 row)
-- Intersect with empty
SELECT test_bms_intersect('(b 1 3 5)', '(b)') AS result;
result
--------
-
+ <>
(1 row)
--- Intersect with varrying word counts
+-- Intersect with varying word counts
SELECT test_bms_intersect('(b 1 300)', '(b 1 2 3 4 5)') AS result;
result
--------
@@ -421,29 +390,23 @@ SELECT test_bms_intersect('(b 1 2 3 4 5)', '(b 1 300)') AS result;
(b 1)
(1 row)
--- Test module checks
-SELECT test_bms_intersect('(b 1)', '(b 2)') AS result;
- result
---------
-
-(1 row)
-
+-- NULL inputs
SELECT test_bms_intersect('(b 5)', NULL) AS result;
result
--------
-
+ <>
(1 row)
SELECT test_bms_intersect(NULL, '(b 5)') AS result;
result
--------
-
+ <>
(1 row)
SELECT test_bms_intersect(NULL, NULL) AS result;
result
--------
-
+ <>
(1 row)
-- bms_int_members()
@@ -458,14 +421,14 @@ SELECT test_bms_int_members('(b 1 3 5)', '(b 3 5 7)') AS result;
SELECT test_bms_int_members('(b 1 3 5)', '(b 2 4 6)') AS result;
result
--------
-
+ <>
(1 row)
-- Intersect with empty
SELECT test_bms_int_members('(b 1 3 5)', '(b)') AS result;
result
--------
-
+ <>
(1 row)
-- Multiple members
@@ -475,29 +438,23 @@ SELECT test_bms_int_members('(b 0 31 32 63 64)', '(b 31 32 64 65)') AS result;
(b 31 32 64)
(1 row)
--- Test module checks
-SELECT test_bms_int_members('(b 1)', '(b 2)') AS result;
- result
---------
-
-(1 row)
-
+-- NULL inputs
SELECT test_bms_int_members('(b 5)', NULL) AS result;
result
--------
-
+ <>
(1 row)
SELECT test_bms_int_members(NULL, '(b 5)') AS result;
result
--------
-
+ <>
(1 row)
SELECT test_bms_int_members(NULL, NULL) AS result;
result
--------
-
+ <>
(1 row)
-- bms_difference()
@@ -519,14 +476,14 @@ SELECT test_bms_difference('(b 1 3 5)', '(b 2 4 6)') AS result;
SELECT test_bms_difference('(b 1 3 5)', '(b 1 3 5)') AS result;
result
--------
-
+ <>
(1 row)
-- Substraction to empty
SELECT test_bms_difference('(b 42)', '(b 42)') AS result;
result
--------
-
+ <>
(1 row)
-- Subtraction edge case
@@ -552,13 +509,7 @@ SELECT test_bms_difference('(b 1 2 100 200)', '(b 1 2)') AS result;
(b 100 200)
(1 row)
--- Test module checks
-SELECT test_bms_difference('(b 5)', '(b 5 10)') AS result;
- result
---------
-
-(1 row)
-
+-- NULL inputs
SELECT test_bms_difference('(b 5)', NULL) AS result;
result
--------
@@ -568,13 +519,13 @@ SELECT test_bms_difference('(b 5)', NULL) AS result;
SELECT test_bms_difference(NULL, '(b 5)') AS result;
result
--------
-
+ <>
(1 row)
SELECT test_bms_difference(NULL, NULL) AS result;
result
--------
-
+ <>
(1 row)
-- bms_is_member()
@@ -608,7 +559,7 @@ SELECT test_bms_is_member('(b)', 1) AS result;
SELECT test_bms_is_member('(b 5)', NULL) AS result;
result
--------
- f
+
(1 row)
-- bms_member_index()
@@ -655,17 +606,11 @@ SELECT test_bms_member_index('(b 1 50 100 200)', 200) AS result;
3
(1 row)
--- Test module checks
-SELECT test_bms_member_index('', 5) AS result;
- result
---------
- -1
-(1 row)
-
-SELECT test_bms_member_index(NULL, 5) AS result;
+-- Test module check
+SELECT test_bms_member_index('(b 1 3 5)', NULL) AS result;
result
--------
- -1
+
(1 row)
-- bms_num_members()
@@ -731,7 +676,7 @@ SELECT test_bms_equal('(b 5 10)', '(b 100 200 300)') AS result;
f
(1 row)
--- Test module checks
+-- NULL inputs
SELECT test_bms_equal('(b 5)', NULL) AS result;
result
--------
@@ -796,7 +741,7 @@ SELECT test_bms_compare(
-1
(1 row)
--- Test module checks
+-- NULL inputs
SELECT test_bms_compare('(b 5)', NULL) AS result;
result
--------
@@ -902,6 +847,7 @@ SELECT test_bms_add_range('(b 5)', NULL, NULL) AS result;
(1 row)
+-- NULL inputs
SELECT test_bms_add_range(NULL, 5, 10) AS result;
result
------------------
@@ -911,13 +857,7 @@ SELECT test_bms_add_range(NULL, 5, 10) AS result;
SELECT test_bms_add_range(NULL, 10, 5) AS result;
result
--------
-
-(1 row)
-
-SELECT test_bms_add_range(NULL, NULL, NULL) AS result;
- result
---------
-
+ <>
(1 row)
-- bms_membership()
@@ -939,7 +879,7 @@ SELECT test_bms_membership('(b 1 2)') AS result;
2
(1 row)
--- Test module check
+-- NULL input
SELECT test_bms_membership(NULL) AS result;
result
--------
@@ -965,13 +905,6 @@ SELECT test_bms_is_empty('(b 1)') AS result;
f
(1 row)
--- Test module check
-SELECT test_bms_is_empty(NULL) AS result;
- result
---------
- t
-(1 row)
-
-- bms_singleton_member()
SELECT test_bms_singleton_member('(b)'); -- error
ERROR: bitmapset is empty
@@ -983,7 +916,7 @@ SELECT test_bms_singleton_member('(b 42)') AS result;
42
(1 row)
--- Test module check
+-- NULL input
SELECT test_bms_singleton_member(NULL) AS result;
result
--------
@@ -991,37 +924,31 @@ SELECT test_bms_singleton_member(NULL) AS result;
(1 row)
-- bms_get_singleton_member()
-SELECT test_bms_get_singleton_member('(b)', 1000);
+SELECT test_bms_get_singleton_member('(b)');
test_bms_get_singleton_member
-------------------------------
- 1000
-(1 row)
-
--- Not a singleton, returns input default
-SELECT test_bms_get_singleton_member('(b 3 6)', 1000) AS result;
- result
---------
- 1000
+ -1
(1 row)
--- Singletone, returns sole member
-SELECT test_bms_get_singleton_member('(b 400)', 1000) AS result;
+-- Try with an empty set
+SELECT test_bms_get_singleton_member(NULL) AS result;
result
--------
- 400
+ -1
(1 row)
--- Test module checks
-SELECT test_bms_get_singleton_member('', 1000) AS result;
+-- Not a singleton, returns input default
+SELECT test_bms_get_singleton_member('(b 3 6)') AS result;
result
--------
- 1000
+ -1
(1 row)
-SELECT test_bms_get_singleton_member(NULL, -1) AS result;
+-- Singletone, returns sole member
+SELECT test_bms_get_singleton_member('(b 400)') AS result;
result
--------
- -1
+ 400
(1 row)
-- bms_next_member() and bms_prev_member()
@@ -1088,47 +1015,30 @@ SELECT test_bms_prev_member('(b 0 63 64 127)', -1) AS result;
127
(1 row)
--- Test module checks
-SELECT test_bms_next_member('', 5) AS result;
- result
---------
- -2
-(1 row)
-
-SELECT test_bms_next_member('(b 5)', NULL) AS result;
- result
---------
- -2
-(1 row)
-
+-- NULL inputs
SELECT test_bms_next_member(NULL, 5) AS result;
result
--------
-2
(1 row)
-SELECT test_bms_next_member(NULL, NULL) AS result;
- result
---------
- -2
-(1 row)
-
-SELECT test_bms_prev_member('', 5) AS result;
+SELECT test_bms_prev_member(NULL, 5) AS result;
result
--------
-2
(1 row)
-SELECT test_bms_prev_member('(b 5)', NULL) AS result;
+-- Test module check
+SELECT test_bms_next_member('(b 5 10)', NULL) AS result;
result
--------
- -2
+
(1 row)
-SELECT test_bms_prev_member(NULL, 5) AS result;
+SELECT test_bms_prev_member('(b 5 10)', NULL) AS result;
result
--------
- -2
+
(1 row)
-- bms_hash_value()
@@ -1150,7 +1060,7 @@ SELECT test_bms_hash_value('(b 1 3 5)') != test_bms_hash_value('(b 2 4 6)') AS r
t
(1 row)
--- Test module check
+-- NULL input
SELECT test_bms_hash_value(NULL) AS result;
result
--------
@@ -1176,7 +1086,7 @@ SELECT test_bms_overlap('(b)', '(b 1 3 5)') AS result;
f
(1 row)
--- Test module checks
+-- NULL inputs
SELECT test_bms_overlap('(b 5)', NULL) AS result;
result
--------
@@ -1240,7 +1150,7 @@ SELECT test_bms_is_subset('(b 1 2 50 100)', '(b 1 2)') AS result;
f
(1 row)
--- Test module checks
+-- NULL inputs
SELECT test_bms_is_subset('(b 5)', NULL) AS result;
result
--------
@@ -1398,30 +1308,11 @@ SELECT test_bms_subset_compare('(b 2 64 128)', '(b 1 65)') AS result;
3
(1 row)
--- Test module checks
-SELECT test_bms_subset_compare('(b 5)', NULL) AS result;
- result
---------
- 2
-(1 row)
-
-SELECT test_bms_subset_compare(NULL, '(b 5)') AS result;
- result
---------
- 1
-(1 row)
-
-SELECT test_bms_subset_compare(NULL, NULL) AS result;
- result
---------
- 0
-(1 row)
-
-- bms_copy()
SELECT test_bms_copy(NULL) AS result;
result
--------
-
+ <>
(1 row)
SELECT test_bms_copy('(b 1 3 5 7)') AS result;
@@ -1430,13 +1321,6 @@ SELECT test_bms_copy('(b 1 3 5 7)') AS result;
(b 1 3 5 7)
(1 row)
--- Test module check
-SELECT test_bms_copy(NULL) AS result;
- result
---------
-
-(1 row)
-
-- bms_add_members()
SELECT test_bms_add_members('(b 1 3)', '(b 5 7)') AS result;
result
@@ -1547,7 +1431,7 @@ SELECT (test_bitmap_match('(b)', '(b)') = 0) =
t
(1 row)
--- Test module checks
+-- NULL inputs
SELECT test_bitmap_match('(b 5)', NULL) AS result;
result
--------
@@ -1609,7 +1493,7 @@ SELECT test_bms_overlap_list('(b 5 10)', ARRAY[-1,5]) AS result; -- error
ERROR: negative bitmapset member not allowed
SELECT test_bms_overlap_list('(b 1 2 3)', ARRAY[-5,-1,0]) AS result; -- error
ERROR: negative bitmapset member not allowed
--- Test module checks
+-- NULL inputs
SELECT test_bms_overlap_list('(b 5)', NULL) AS result;
result
--------
@@ -1641,6 +1525,12 @@ SELECT test_bms_nonempty_difference('(b 1 3 5)', NULL) AS result;
t
(1 row)
+SELECT test_bms_nonempty_difference(NULL, NULL) AS result;
+ result
+--------
+ f
+(1 row)
+
SELECT test_bms_nonempty_difference('(b 1 3 5)', '(b 2 4 6)') AS result;
result
--------
@@ -1678,25 +1568,6 @@ SELECT test_bms_nonempty_difference('(b 1 2)', '(b 50 100)') AS result;
t
(1 row)
--- Test module checks
-SELECT test_bms_nonempty_difference('(b 5)', NULL) AS result;
- result
---------
- t
-(1 row)
-
-SELECT test_bms_nonempty_difference(NULL, '(b 5)') AS result;
- result
---------
- f
-(1 row)
-
-SELECT test_bms_nonempty_difference(NULL, NULL) AS result;
- result
---------
- f
-(1 row)
-
-- random operations
SELECT test_random_operations(-1, 10000, 81920, 0) > 0 AS result;
result
diff --git a/src/test/modules/test_bitmapset/sql/test_bitmapset.sql b/src/test/modules/test_bitmapset/sql/test_bitmapset.sql
index c6e6bce60a3..0a2fa151093 100644
--- a/src/test/modules/test_bitmapset/sql/test_bitmapset.sql
+++ b/src/test/modules/test_bitmapset/sql/test_bitmapset.sql
@@ -29,11 +29,6 @@ SELECT test_bms_replace_members('(b 1 2 3)', '(b 3 5)') AS result;
SELECT test_bms_replace_members('(b 1 2)', '(b 3 5 7)') AS result;
-- Force repalloc() with larger set
SELECT test_bms_replace_members('(b 1 2 3 4 5)', '(b 500 600)') AS result;
--- Test module checks
-SELECT test_bms_replace_members('(b 1 2 3)', NULL) AS result;
-SELECT test_bms_replace_members('(b 5)', NULL) AS result;
-SELECT test_bms_replace_members(NULL, '(b 5)') AS result;
-SELECT test_bms_replace_members(NULL, NULL) AS result;
-- bms_del_member()
SELECT test_bms_del_member('(b)', -20); -- error
@@ -50,7 +45,6 @@ SELECT test_bms_del_member('(b 1 200)', 200) AS result;
SELECT test_bms_del_member('(b 1 50 100 200)', 200) AS result;
SELECT test_bms_del_member('(b 1 50 100 200)', 100) AS result;
-- Test module checks
-SELECT test_bms_del_member('(b 42)', 42) AS result;
SELECT test_bms_del_member('(b 5)', NULL) AS result;
-- bms_del_members()
@@ -63,7 +57,7 @@ SELECT test_bms_del_members('(b 5 100 200)', '(b 200)') AS result;
-- Force word count changes
SELECT test_bms_del_members('(b 1 2 100 200 300)', '(b 1 2)') AS result;
SELECT test_bms_del_members('(b 1 2 100 200 300)', '(b 200 300)') AS result;
--- Test module checks
+-- NULL inputs
SELECT test_bms_del_members('(b 5)', NULL) AS result;
SELECT test_bms_del_members(NULL, '(b 5)') AS result;
@@ -75,7 +69,7 @@ SELECT test_bms_join('(b 1 3 5)', '(b 1 4 5)') AS result;
-- Force word count changes
SELECT test_bms_join('(b 5)', '(b 100)') AS result;
SELECT test_bms_join('(b 1 2)', '(b 100 200 300)') AS result;
--- Test module checks
+-- NULL inputs
SELECT test_bms_join('(b 5)', NULL) AS result;
SELECT test_bms_join(NULL, '(b 5)') AS result;
SELECT test_bms_join(NULL, NULL) AS result;
@@ -92,10 +86,10 @@ SELECT test_bms_union(
test_bms_add_range('(b)', 0, 15),
test_bms_add_range('(b)', 10, 20)
) AS result;
--- Union with varrying word counts
+-- Union with varying word counts
SELECT test_bms_union('(b 1 2)', '(b 100 300)') AS result;
SELECT test_bms_union('(b 100 300)', '(b 1 2)') AS result;
--- Test module checks
+-- NULL inputs
SELECT test_bms_union('(b 5)', NULL) AS result;
SELECT test_bms_union(NULL, '(b 5)') AS result;
SELECT test_bms_union(NULL, NULL) AS result;
@@ -107,11 +101,10 @@ SELECT test_bms_intersect('(b 1 3 5)', '(b 3 5 7)') AS result;
SELECT test_bms_intersect('(b 1 3 5)', '(b 2 4 6)') AS result;
-- Intersect with empty
SELECT test_bms_intersect('(b 1 3 5)', '(b)') AS result;
--- Intersect with varrying word counts
+-- Intersect with varying word counts
SELECT test_bms_intersect('(b 1 300)', '(b 1 2 3 4 5)') AS result;
SELECT test_bms_intersect('(b 1 2 3 4 5)', '(b 1 300)') AS result;
--- Test module checks
-SELECT test_bms_intersect('(b 1)', '(b 2)') AS result;
+-- NULL inputs
SELECT test_bms_intersect('(b 5)', NULL) AS result;
SELECT test_bms_intersect(NULL, '(b 5)') AS result;
SELECT test_bms_intersect(NULL, NULL) AS result;
@@ -125,8 +118,7 @@ SELECT test_bms_int_members('(b 1 3 5)', '(b 2 4 6)') AS result;
SELECT test_bms_int_members('(b 1 3 5)', '(b)') AS result;
-- Multiple members
SELECT test_bms_int_members('(b 0 31 32 63 64)', '(b 31 32 64 65)') AS result;
--- Test module checks
-SELECT test_bms_int_members('(b 1)', '(b 2)') AS result;
+-- NULL inputs
SELECT test_bms_int_members('(b 5)', NULL) AS result;
SELECT test_bms_int_members(NULL, '(b 5)') AS result;
SELECT test_bms_int_members(NULL, NULL) AS result;
@@ -148,8 +140,7 @@ SELECT test_bms_difference(
-- Difference with different word counts
SELECT test_bms_difference('(b 5 100)', '(b 5)') AS result;
SELECT test_bms_difference('(b 1 2 100 200)', '(b 1 2)') AS result;
--- Test module checks
-SELECT test_bms_difference('(b 5)', '(b 5 10)') AS result;
+-- NULL inputs
SELECT test_bms_difference('(b 5)', NULL) AS result;
SELECT test_bms_difference(NULL, '(b 5)') AS result;
SELECT test_bms_difference(NULL, NULL) AS result;
@@ -172,9 +163,8 @@ SELECT test_bms_member_index('(b 1 3 5)', 3) AS result;
SELECT test_bms_member_index('(b 100 200)', 100) AS result;
SELECT test_bms_member_index('(b 100 200)', 200) AS result;
SELECT test_bms_member_index('(b 1 50 100 200)', 200) AS result;
--- Test module checks
-SELECT test_bms_member_index('', 5) AS result;
-SELECT test_bms_member_index(NULL, 5) AS result;
+-- Test module check
+SELECT test_bms_member_index('(b 1 3 5)', NULL) AS result;
-- bms_num_members()
SELECT test_bms_num_members('(b)') AS result;
@@ -190,7 +180,7 @@ SELECT test_bms_equal('(b 1 3 5)', '(b 2 4 6)') AS result;
-- Equal with different word counts
SELECT test_bms_equal('(b 5)', '(b 100)') AS result;
SELECT test_bms_equal('(b 5 10)', '(b 100 200 300)') AS result;
--- Test module checks
+-- NULL inputs
SELECT test_bms_equal('(b 5)', NULL) AS result;
SELECT test_bms_equal(NULL, '(b 5)') AS result;
SELECT test_bms_equal(NULL, NULL) AS result;
@@ -206,7 +196,7 @@ SELECT test_bms_compare(
test_bms_add_range('(b)', 0, 63),
test_bms_add_range('(b)', 0, 64)
) AS result;
--- Test module checks
+-- NULL inputs
SELECT test_bms_compare('(b 5)', NULL) AS result;
SELECT test_bms_compare(NULL, '(b 5)') AS result;
SELECT test_bms_compare(NULL, NULL) AS result;
@@ -232,40 +222,37 @@ SELECT length(test_bms_add_range('(b 1 2)', 200, 250)) AS result;
SELECT test_bms_add_range('(b 5)', 5, NULL) AS result;
SELECT test_bms_add_range('(b 5)', NULL, 10) AS result;
SELECT test_bms_add_range('(b 5)', NULL, NULL) AS result;
+-- NULL inputs
SELECT test_bms_add_range(NULL, 5, 10) AS result;
SELECT test_bms_add_range(NULL, 10, 5) AS result;
-SELECT test_bms_add_range(NULL, NULL, NULL) AS result;
-- bms_membership()
SELECT test_bms_membership('(b)') AS result;
SELECT test_bms_membership('(b 42)') AS result;
SELECT test_bms_membership('(b 1 2)') AS result;
--- Test module check
+-- NULL input
SELECT test_bms_membership(NULL) AS result;
-- bms_is_empty()
SELECT test_bms_is_empty(NULL) AS result;
SELECT test_bms_is_empty('(b)') AS result;
SELECT test_bms_is_empty('(b 1)') AS result;
--- Test module check
-SELECT test_bms_is_empty(NULL) AS result;
-- bms_singleton_member()
SELECT test_bms_singleton_member('(b)'); -- error
SELECT test_bms_singleton_member('(b 1 2)'); -- error
SELECT test_bms_singleton_member('(b 42)') AS result;
--- Test module check
+-- NULL input
SELECT test_bms_singleton_member(NULL) AS result;
-- bms_get_singleton_member()
-SELECT test_bms_get_singleton_member('(b)', 1000);
+SELECT test_bms_get_singleton_member('(b)');
+-- Try with an empty set
+SELECT test_bms_get_singleton_member(NULL) AS result;
-- Not a singleton, returns input default
-SELECT test_bms_get_singleton_member('(b 3 6)', 1000) AS result;
+SELECT test_bms_get_singleton_member('(b 3 6)') AS result;
-- Singletone, returns sole member
-SELECT test_bms_get_singleton_member('(b 400)', 1000) AS result;
--- Test module checks
-SELECT test_bms_get_singleton_member('', 1000) AS result;
-SELECT test_bms_get_singleton_member(NULL, -1) AS result;
+SELECT test_bms_get_singleton_member('(b 400)') AS result;
-- bms_next_member() and bms_prev_member()
-- First member
@@ -286,27 +273,25 @@ SELECT test_bms_prev_member('(b 5 10 15 20)', 5) AS result;
SELECT test_bms_prev_member('(b)', 100) AS result;
-- Negative prevbit should result in highest possible bit in set
SELECT test_bms_prev_member('(b 0 63 64 127)', -1) AS result;
--- Test module checks
-SELECT test_bms_next_member('', 5) AS result;
-SELECT test_bms_next_member('(b 5)', NULL) AS result;
+-- NULL inputs
SELECT test_bms_next_member(NULL, 5) AS result;
-SELECT test_bms_next_member(NULL, NULL) AS result;
-SELECT test_bms_prev_member('', 5) AS result;
-SELECT test_bms_prev_member('(b 5)', NULL) AS result;
SELECT test_bms_prev_member(NULL, 5) AS result;
+-- Test module check
+SELECT test_bms_next_member('(b 5 10)', NULL) AS result;
+SELECT test_bms_prev_member('(b 5 10)', NULL) AS result;
-- bms_hash_value()
SELECT test_bms_hash_value('(b)') = 0 AS result;
SELECT test_bms_hash_value('(b 1 3 5)') = test_bms_hash_value('(b 1 3 5)') AS result;
SELECT test_bms_hash_value('(b 1 3 5)') != test_bms_hash_value('(b 2 4 6)') AS result;
--- Test module check
+-- NULL input
SELECT test_bms_hash_value(NULL) AS result;
-- bms_overlap()
SELECT test_bms_overlap('(b 1 3 5)', '(b 3 5 7)') AS result;
SELECT test_bms_overlap('(b 1 3 5)', '(b 2 4 6)') AS result;
SELECT test_bms_overlap('(b)', '(b 1 3 5)') AS result;
--- Test module checks
+-- NULL inputs
SELECT test_bms_overlap('(b 5)', NULL) AS result;
SELECT test_bms_overlap(NULL, '(b 5)') AS result;
SELECT test_bms_overlap(NULL, NULL) AS result;
@@ -321,7 +306,7 @@ SELECT test_bms_is_subset(test_bms_add_range(NULL, 0, 31),
-- Is subset with shorter word counts?
SELECT test_bms_is_subset('(b 5 100)', '(b 5)') AS result;
SELECT test_bms_is_subset('(b 1 2 50 100)', '(b 1 2)') AS result;
--- Test module checks
+-- NULL inputs
SELECT test_bms_is_subset('(b 5)', NULL) AS result;
SELECT test_bms_is_subset(NULL, '(b 5)') AS result;
SELECT test_bms_is_subset(NULL, NULL) AS result;
@@ -350,16 +335,10 @@ SELECT test_bms_subset_compare('(b 1 2)', '(b 1 2 64)') AS result;
SELECT test_bms_subset_compare('(b 64 200)', '(b 1 201)') AS result;
SELECT test_bms_subset_compare('(b 1 64 65)', '(b 1 2 64)') AS result;
SELECT test_bms_subset_compare('(b 2 64 128)', '(b 1 65)') AS result;
--- Test module checks
-SELECT test_bms_subset_compare('(b 5)', NULL) AS result;
-SELECT test_bms_subset_compare(NULL, '(b 5)') AS result;
-SELECT test_bms_subset_compare(NULL, NULL) AS result;
-- bms_copy()
SELECT test_bms_copy(NULL) AS result;
SELECT test_bms_copy('(b 1 3 5 7)') AS result;
--- Test module check
-SELECT test_bms_copy(NULL) AS result;
-- bms_add_members()
SELECT test_bms_add_members('(b 1 3)', '(b 5 7)') AS result;
@@ -388,7 +367,7 @@ SELECT (test_bitmap_match('(b 1 3 5)', '(b 2 4 6)') = 0) =
test_bms_equal('(b 1 3 5)', '(b 2 4 6)') AS result;
SELECT (test_bitmap_match('(b)', '(b)') = 0) =
test_bms_equal('(b)', '(b)') AS result;
--- Test module checks
+-- NULL inputs
SELECT test_bitmap_match('(b 5)', NULL) AS result;
SELECT test_bitmap_match(NULL, '(b 5)') AS result;
SELECT test_bitmap_match(NULL, NULL) AS result;
@@ -404,7 +383,7 @@ SELECT test_bms_overlap_list('(b 1)', ARRAY[]::integer[]) AS result;
-- Overlap list with negative numbers
SELECT test_bms_overlap_list('(b 5 10)', ARRAY[-1,5]) AS result; -- error
SELECT test_bms_overlap_list('(b 1 2 3)', ARRAY[-5,-1,0]) AS result; -- error
--- Test module checks
+-- NULL inputs
SELECT test_bms_overlap_list('(b 5)', NULL) AS result;
SELECT test_bms_overlap_list(NULL, ARRAY[1,2,3]) AS result;
SELECT test_bms_overlap_list(NULL, NULL) AS result;
@@ -412,6 +391,7 @@ SELECT test_bms_overlap_list(NULL, NULL) AS result;
-- bms_nonempty_difference()
SELECT test_bms_nonempty_difference(NULL, '(b 1 3 5)') AS result;
SELECT test_bms_nonempty_difference('(b 1 3 5)', NULL) AS result;
+SELECT test_bms_nonempty_difference(NULL, NULL) AS result;
SELECT test_bms_nonempty_difference('(b 1 3 5)', '(b 2 4 6)') AS result;
SELECT test_bms_nonempty_difference('(b 1 3 5)', '(b 1 5)') AS result;
SELECT test_bms_nonempty_difference('(b 1 3 5)', '(b 1 3 5)') AS result;
@@ -419,10 +399,6 @@ SELECT test_bms_nonempty_difference('(b 1 3 5)', '(b 1 3 5)') AS result;
SELECT test_bms_nonempty_difference('(b 5)', '(b 100)') AS result;
SELECT test_bms_nonempty_difference('(b 100)', '(b 5)') AS result;
SELECT test_bms_nonempty_difference('(b 1 2)', '(b 50 100)') AS result;
--- Test module checks
-SELECT test_bms_nonempty_difference('(b 5)', NULL) AS result;
-SELECT test_bms_nonempty_difference(NULL, '(b 5)') AS result;
-SELECT test_bms_nonempty_difference(NULL, NULL) AS result;
-- random operations
SELECT test_random_operations(-1, 10000, 81920, 0) > 0 AS result;
diff --git a/src/test/modules/test_bitmapset/test_bitmapset--1.0.sql b/src/test/modules/test_bitmapset/test_bitmapset--1.0.sql
index b95c4d0dda5..227ecb5aa3b 100644
--- a/src/test/modules/test_bitmapset/test_bitmapset--1.0.sql
+++ b/src/test/modules/test_bitmapset/test_bitmapset--1.0.sql
@@ -68,7 +68,7 @@ CREATE FUNCTION test_bms_singleton_member(text)
RETURNS integer STRICT
AS 'MODULE_PATHNAME' LANGUAGE C;
-CREATE FUNCTION test_bms_get_singleton_member(text, integer)
+CREATE FUNCTION test_bms_get_singleton_member(text)
RETURNS integer
AS 'MODULE_PATHNAME' LANGUAGE C;
diff --git a/src/test/modules/test_bitmapset/test_bitmapset.c b/src/test/modules/test_bitmapset/test_bitmapset.c
index 2e821320836..6cf8a257187 100644
--- a/src/test/modules/test_bitmapset/test_bitmapset.c
+++ b/src/test/modules/test_bitmapset/test_bitmapset.c
@@ -26,7 +26,6 @@
#include "nodes/pg_list.h"
#include "utils/builtins.h"
#include "utils/timestamp.h"
-#include "varatt.h"
PG_MODULE_MAGIC;
@@ -89,100 +88,102 @@ PG_FUNCTION_INFO_V1(test_random_operations);
#define TEXT_TO_BITMAPSET(str) ((Bitmapset *) stringToNode(text_to_cstring(str)))
/*
+ * Helper macro to fetch text parameters as Bitmapsets. SQL-NULL means empty
+ * set.
+ */
+#define PG_ARG_GETBITMAPSET(n) \
+ (PG_ARGISNULL(n) ? NULL : TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(n)))
+
+/*
+ * Helper macro to handle converting sets back to text, freeing the set and
+ * returning the resulting text representation of the set. Beware of double
+ * evaluation hazard of 'bms'.
+ */
+#define PG_RETURN_BITMAPSET_AS_TEXT(bms) \
+ do { \
+ text *result = BITMAPSET_TO_TEXT(bms); \
+ PG_RETURN_TEXT_P(result); \
+ } while (0);
+
+/*
* Individual test functions for each bitmapset API function
+ *
+ * Primarily, we aim to keep these as close to simple wrapper functions as
+ * possible in order to publish the functions of bitmapset.c to the SQL layer
+ * with as little interference as possible. We opt to return SQL NULL in
+ * cases where the input given to the SQL function isn't valid to pass to the
+ * underlying bitmapset.c function. For example we cannot do much useful
+ * testing if someone calls test_bms_make_singleton(NULL) since
+ * bms_make_singleton() expects an integer argument.
+ *
+ * For function arguments which are to be converted to Bitmapsets, we accept
+ * SQL NULL as a valid argument to mean an empty set. Optionally callers may
+ * pass '(b)'.
+ *
+ * For the test functions which return a Bitmapset, these are converted back
+ * to text with result generated by nodeToString().
*/
Datum
test_bms_add_member(PG_FUNCTION_ARGS)
{
+ Bitmapset *bms;
int member;
- Bitmapset *bms = NULL;
- text *result;
if (PG_ARGISNULL(1))
- PG_RETURN_NULL();
-
- if (!PG_ARGISNULL(0))
- bms = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
+ PG_RETURN_NULL(); /* invalid input */
+ bms = PG_ARG_GETBITMAPSET(0);
member = PG_GETARG_INT32(1);
- bms = bms_add_member(bms, member);
- result = BITMAPSET_TO_TEXT(bms);
- if (bms)
- bms_free(bms);
+ bms = bms_add_member(bms, member);
- PG_RETURN_TEXT_P(result);
+ PG_RETURN_BITMAPSET_AS_TEXT(bms);
}
Datum
test_bms_add_members(PG_FUNCTION_ARGS)
{
- Bitmapset *bms1 = NULL,
- *bms2 = NULL;
- text *result;
-
- if (!PG_ARGISNULL(0))
- bms1 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
-
- if (!PG_ARGISNULL(1))
- bms2 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(1));
+ Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
+ Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
- /* IMPORTANT: bms_add_members modifies/frees the first argument */
+ /* left input is recycled */
bms1 = bms_add_members(bms1, bms2);
- if (bms2)
- bms_free(bms2);
-
- result = BITMAPSET_TO_TEXT(bms1);
- bms_free(bms1);
-
- PG_RETURN_TEXT_P(result);
+ PG_RETURN_BITMAPSET_AS_TEXT(bms1);
}
Datum
test_bms_del_member(PG_FUNCTION_ARGS)
{
- Bitmapset *bms = NULL;
+ Bitmapset *bms;
int32 member;
- text *result;
if (PG_ARGISNULL(1))
- PG_RETURN_NULL();
-
- if (!PG_ARGISNULL(0))
- bms = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
+ PG_RETURN_NULL(); /* invalid input */
+ bms = PG_ARG_GETBITMAPSET(0);
member = PG_GETARG_INT32(1);
- bms = bms_del_member(bms, member);
-
- if (bms_is_empty(bms))
- PG_RETURN_NULL();
- result = BITMAPSET_TO_TEXT(bms);
- bms_free(bms);
+ bms = bms_del_member(bms, member);
- PG_RETURN_TEXT_P(result);
+ PG_RETURN_BITMAPSET_AS_TEXT(bms);
}
Datum
test_bms_is_member(PG_FUNCTION_ARGS)
{
- Bitmapset *bms = NULL;
+ Bitmapset *bms;
int32 member;
bool result;
if (PG_ARGISNULL(1))
- PG_RETURN_BOOL(false);
-
- if (!PG_ARGISNULL(0))
- bms = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
+ PG_RETURN_NULL(); /* invalid input */
+ bms = PG_ARG_GETBITMAPSET(0);
member = PG_GETARG_INT32(1);
- result = bms_is_member(member, bms);
- if (bms)
- bms_free(bms);
+ result = bms_is_member(member, bms);
PG_RETURN_BOOL(result);
}
@@ -190,150 +191,89 @@ test_bms_is_member(PG_FUNCTION_ARGS)
Datum
test_bms_num_members(PG_FUNCTION_ARGS)
{
- Bitmapset *bms = NULL;
- int result = 0;
-
- if (!PG_ARGISNULL(0))
- bms = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
+ Bitmapset *bms = PG_ARG_GETBITMAPSET(0);
+ int result;
result = bms_num_members(bms);
- if (bms)
- bms_free(bms);
-
PG_RETURN_INT32(result);
}
Datum
test_bms_make_singleton(PG_FUNCTION_ARGS)
{
- int32 member;
Bitmapset *bms;
- text *result;
+ int32 member;
if (PG_ARGISNULL(0))
- PG_RETURN_NULL();
+ PG_RETURN_NULL(); /* invalid input */
member = PG_GETARG_INT32(0);
bms = bms_make_singleton(member);
- result = BITMAPSET_TO_TEXT(bms);
- bms_free(bms);
-
- PG_RETURN_TEXT_P(result);
+ PG_RETURN_BITMAPSET_AS_TEXT(bms);
}
Datum
test_bms_copy(PG_FUNCTION_ARGS)
{
- text *bms_data;
- Bitmapset *bms = NULL;
+ Bitmapset *bms = PG_ARG_GETBITMAPSET(0);
Bitmapset *copy_bms;
- text *result;
-
- if (PG_ARGISNULL(0))
- PG_RETURN_NULL();
- bms_data = PG_GETARG_TEXT_PP(0);
- bms = TEXT_TO_BITMAPSET(bms_data);
copy_bms = bms_copy(bms);
- result = BITMAPSET_TO_TEXT(copy_bms);
- if (bms)
- bms_free(bms);
- if (copy_bms)
- bms_free(copy_bms);
-
- PG_RETURN_TEXT_P(result);
+ PG_RETURN_BITMAPSET_AS_TEXT(copy_bms);
}
Datum
test_bms_equal(PG_FUNCTION_ARGS)
{
- Bitmapset *bms1 = NULL,
- *bms2 = NULL;
+ Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
+ Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
bool result;
- if (!PG_ARGISNULL(0))
- bms1 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
-
- if (!PG_ARGISNULL(1))
- bms2 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(1));
-
result = bms_equal(bms1, bms2);
- if (bms1)
- bms_free(bms1);
- if (bms2)
- bms_free(bms2);
-
PG_RETURN_BOOL(result);
}
Datum
test_bms_union(PG_FUNCTION_ARGS)
{
- Bitmapset *bms1 = NULL,
- *bms2 = NULL;
+ Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
+ Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
Bitmapset *result_bms;
- text *result;
-
- if (!PG_ARGISNULL(0))
- bms1 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
-
- if (!PG_ARGISNULL(1))
- bms2 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(1));
result_bms = bms_union(bms1, bms2);
- if (bms1)
- bms_free(bms1);
- if (bms2)
- bms_free(bms2);
-
- if (result_bms == NULL)
- PG_RETURN_NULL();
-
- result = BITMAPSET_TO_TEXT(result_bms);
- bms_free(result_bms);
-
- PG_RETURN_TEXT_P(result);
+ PG_RETURN_BITMAPSET_AS_TEXT(result_bms);
}
Datum
test_bms_membership(PG_FUNCTION_ARGS)
{
- Bitmapset *bms = NULL;
+ Bitmapset *bms = PG_ARG_GETBITMAPSET(0);
BMS_Membership result;
- if (PG_ARGISNULL(0))
- PG_RETURN_INT32(BMS_EMPTY_SET);
-
- bms = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
result = bms_membership(bms);
- if (bms)
- bms_free(bms);
-
PG_RETURN_INT32((int32) result);
}
Datum
test_bms_next_member(PG_FUNCTION_ARGS)
{
- Bitmapset *bms = NULL;
+ Bitmapset *bms;
int32 prevmember;
int result;
- if (PG_ARGISNULL(0) || PG_ARGISNULL(1))
- PG_RETURN_INT32(-2);
+ if (PG_ARGISNULL(1))
+ PG_RETURN_NULL(); /* invalid input */
- bms = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
+ bms = PG_ARG_GETBITMAPSET(0);
prevmember = PG_GETARG_INT32(1);
- result = bms_next_member(bms, prevmember);
- if (bms)
- bms_free(bms);
+ result = bms_next_member(bms, prevmember);
PG_RETURN_INT32(result);
}
@@ -341,212 +281,115 @@ test_bms_next_member(PG_FUNCTION_ARGS)
Datum
test_bms_intersect(PG_FUNCTION_ARGS)
{
- Bitmapset *bms1 = NULL,
- *bms2 = NULL;
+ Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
+ Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
Bitmapset *result_bms;
- text *result;
-
- if (!PG_ARGISNULL(0))
- bms1 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
-
- if (!PG_ARGISNULL(1))
- bms2 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(1));
result_bms = bms_intersect(bms1, bms2);
- if (bms1)
- bms_free(bms1);
- if (bms2)
- bms_free(bms2);
-
- if (result_bms == NULL)
- PG_RETURN_NULL();
-
- result = BITMAPSET_TO_TEXT(result_bms);
- bms_free(result_bms);
-
- PG_RETURN_TEXT_P(result);
+ PG_RETURN_BITMAPSET_AS_TEXT(result_bms);
}
Datum
test_bms_difference(PG_FUNCTION_ARGS)
{
- Bitmapset *bms1 = NULL,
- *bms2 = NULL;
+ Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
+ Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
Bitmapset *result_bms;
- text *result;
-
- if (!PG_ARGISNULL(0))
- bms1 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
-
- if (!PG_ARGISNULL(1))
- bms2 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(1));
result_bms = bms_difference(bms1, bms2);
- if (bms1)
- bms_free(bms1);
- if (bms2)
- bms_free(bms2);
-
- if (result_bms == NULL)
- PG_RETURN_NULL();
-
- result = BITMAPSET_TO_TEXT(result_bms);
- bms_free(result_bms);
-
- PG_RETURN_TEXT_P(result);
+ PG_RETURN_BITMAPSET_AS_TEXT(result_bms);
}
Datum
test_bms_compare(PG_FUNCTION_ARGS)
{
- Bitmapset *bms1 = NULL,
- *bms2 = NULL;
+ Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
+ Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
int result;
- if (!PG_ARGISNULL(0))
- bms1 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
-
- if (!PG_ARGISNULL(1))
- bms2 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(1));
-
result = bms_compare(bms1, bms2);
- if (bms1)
- bms_free(bms1);
- if (bms2)
- bms_free(bms2);
-
PG_RETURN_INT32(result);
}
Datum
test_bms_is_empty(PG_FUNCTION_ARGS)
{
- Bitmapset *bms = NULL;
+ Bitmapset *bms = PG_ARG_GETBITMAPSET(0);
bool result;
- if (!PG_ARGISNULL(0))
- bms = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
-
result = bms_is_empty(bms);
- if (bms)
- bms_free(bms);
-
PG_RETURN_BOOL(result);
}
Datum
test_bms_is_subset(PG_FUNCTION_ARGS)
{
- Bitmapset *bms1 = NULL,
- *bms2 = NULL;
+ Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
+ Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
bool result;
- if (!PG_ARGISNULL(0))
- bms1 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
-
- if (!PG_ARGISNULL(1))
- bms2 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(1));
-
result = bms_is_subset(bms1, bms2);
- if (bms1)
- bms_free(bms1);
- if (bms2)
- bms_free(bms2);
-
PG_RETURN_BOOL(result);
}
Datum
test_bms_subset_compare(PG_FUNCTION_ARGS)
{
- Bitmapset *bms1 = NULL,
- *bms2 = NULL;
+ Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
+ Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
BMS_Comparison result;
- if (!PG_ARGISNULL(0))
- bms1 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
-
- if (!PG_ARGISNULL(1))
- bms2 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(1));
-
result = bms_subset_compare(bms1, bms2);
- if (bms1)
- bms_free(bms1);
- if (bms2)
- bms_free(bms2);
-
PG_RETURN_INT32((int32) result);
}
Datum
test_bms_singleton_member(PG_FUNCTION_ARGS)
{
- Bitmapset *bms = NULL;
+ Bitmapset *bms = PG_ARG_GETBITMAPSET(0);
int result;
- if (!PG_ARGISNULL(0))
- bms = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
-
result = bms_singleton_member(bms);
- if (bms)
- bms_free(bms);
-
PG_RETURN_INT32(result);
}
Datum
test_bms_get_singleton_member(PG_FUNCTION_ARGS)
{
- Bitmapset *bms = NULL;
- int32 default_member = PG_GETARG_INT32(1);
- bool success;
- int member = -1;
-
- if (PG_ARGISNULL(0))
- PG_RETURN_INT32(default_member);
-
- bms = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
+ Bitmapset *bms = PG_ARG_GETBITMAPSET(0);
+ int member;
/*
- * bms_get_singleton_member returns bool and stores result in member
- * pointer
+ * Keep this simple. Return -1 when we detect the set is not a singleton
+ * set, otherwise return the singleton member.
*/
- success = bms_get_singleton_member(bms, &member);
- bms_free(bms);
-
- if (success)
- PG_RETURN_INT32(member);
+ if (!bms_get_singleton_member(bms, &member))
+ member = -1;
- PG_RETURN_INT32(default_member);
+ PG_RETURN_INT32(member);
}
Datum
test_bms_prev_member(PG_FUNCTION_ARGS)
{
- text *bms_data;
- Bitmapset *bms = NULL;
+ Bitmapset *bms;
int32 prevmember;
int result;
- if (PG_ARGISNULL(0))
- PG_RETURN_INT32(-2);
+ if (PG_ARGISNULL(1))
+ PG_RETURN_NULL(); /* invalid input */
- bms_data = PG_GETARG_TEXT_PP(0);
+ bms = PG_ARG_GETBITMAPSET(0);
prevmember = PG_GETARG_INT32(1);
- if (VARSIZE_ANY_EXHDR(bms_data) == 0)
- PG_RETURN_INT32(-2);
-
- bms = TEXT_TO_BITMAPSET(bms_data);
result = bms_prev_member(bms, prevmember);
- bms_free(bms);
PG_RETURN_INT32(result);
}
@@ -554,75 +397,57 @@ test_bms_prev_member(PG_FUNCTION_ARGS)
Datum
test_bms_overlap(PG_FUNCTION_ARGS)
{
- Bitmapset *bms1 = NULL,
- *bms2 = NULL;
+ Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
+ Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
bool result;
- if (!PG_ARGISNULL(0))
- bms1 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
-
- if (!PG_ARGISNULL(1))
- bms2 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(1));
-
result = bms_overlap(bms1, bms2);
- if (bms1)
- bms_free(bms1);
- if (bms2)
- bms_free(bms2);
-
PG_RETURN_BOOL(result);
}
Datum
test_bms_overlap_list(PG_FUNCTION_ARGS)
{
- Bitmapset *bms = NULL;
+ Bitmapset *bms;
ArrayType *array;
List *int_list = NIL;
bool result;
- Datum *elem_datums;
- bool *elem_nulls;
+ Datum *elem_datums = NULL;
+ bool *elem_nulls = NULL;
int elem_count;
int i;
- if (PG_ARGISNULL(0))
- PG_RETURN_BOOL(false);
-
- bms = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
+ bms = PG_ARG_GETBITMAPSET(0);
- if (PG_ARGISNULL(1))
+ if (!PG_ARGISNULL(1))
{
- if (bms)
- bms_free(bms);
- PG_RETURN_BOOL(false);
- }
-
- array = PG_GETARG_ARRAYTYPE_P(1);
+ array = PG_GETARG_ARRAYTYPE_P(1);
- deconstruct_array(array,
- INT4OID, sizeof(int32), true, 'i',
- &elem_datums, &elem_nulls, &elem_count);
+ deconstruct_array(array,
+ INT4OID, sizeof(int32), true, 'i',
+ &elem_datums, &elem_nulls, &elem_count);
- for (i = 0; i < elem_count; i++)
- {
- if (!elem_nulls[i])
+ for (i = 0; i < elem_count; i++)
{
- int32 member = DatumGetInt32(elem_datums[i]);
+ if (!elem_nulls[i])
+ {
+ int32 member = DatumGetInt32(elem_datums[i]);
- int_list = lappend_int(int_list, member);
+ int_list = lappend_int(int_list, member);
+ }
}
}
result = bms_overlap_list(bms, int_list);
- if (bms)
- bms_free(bms);
-
list_free(int_list);
- pfree(elem_datums);
- pfree(elem_nulls);
+ if (elem_datums)
+ pfree(elem_datums);
+
+ if (elem_nulls)
+ pfree(elem_nulls);
PG_RETURN_BOOL(result);
}
@@ -630,47 +455,29 @@ test_bms_overlap_list(PG_FUNCTION_ARGS)
Datum
test_bms_nonempty_difference(PG_FUNCTION_ARGS)
{
- Bitmapset *bms1 = NULL,
- *bms2 = NULL;
+ Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
+ Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
bool result;
- if (!PG_ARGISNULL(0))
- bms1 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
-
- if (!PG_ARGISNULL(1))
- bms2 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(1));
-
result = bms_nonempty_difference(bms1, bms2);
- if (bms1)
- bms_free(bms1);
- if (bms2)
- bms_free(bms2);
-
PG_RETURN_BOOL(result);
}
Datum
test_bms_member_index(PG_FUNCTION_ARGS)
{
- text *bms_data;
- Bitmapset *bms = NULL;
+ Bitmapset *bms;
int32 member;
int result;
- if (PG_ARGISNULL(0))
- PG_RETURN_INT32(-1);
+ if (PG_ARGISNULL(1))
+ PG_RETURN_NULL(); /* invalid input */
- bms_data = PG_GETARG_TEXT_PP(0);
+ bms = PG_ARG_GETBITMAPSET(0);
member = PG_GETARG_INT32(1);
- if (VARSIZE_ANY_EXHDR(bms_data) == 0)
- PG_RETURN_INT32(-1);
-
- bms = TEXT_TO_BITMAPSET(bms_data);
-
result = bms_member_index(bms, member);
- bms_free(bms);
PG_RETURN_INT32(result);
}
@@ -678,191 +485,92 @@ test_bms_member_index(PG_FUNCTION_ARGS)
Datum
test_bms_add_range(PG_FUNCTION_ARGS)
{
- Bitmapset *bms = NULL;
+ Bitmapset *bms;
int32 lower,
upper;
- text *result;
if (PG_ARGISNULL(1) || PG_ARGISNULL(2))
- PG_RETURN_NULL();
-
- if (!PG_ARGISNULL(0))
- bms = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
+ PG_RETURN_NULL(); /* invalid input */
+ bms = PG_ARG_GETBITMAPSET(0);
lower = PG_GETARG_INT32(1);
upper = PG_GETARG_INT32(2);
- /* Check for invalid range */
- if (upper < lower)
- {
- if (bms)
- bms_free(bms);
- PG_RETURN_NULL();
- }
-
bms = bms_add_range(bms, lower, upper);
- result = BITMAPSET_TO_TEXT(bms);
- if (bms)
- bms_free(bms);
-
- PG_RETURN_TEXT_P(result);
+ PG_RETURN_BITMAPSET_AS_TEXT(bms);
}
Datum
test_bms_int_members(PG_FUNCTION_ARGS)
{
- Bitmapset *bms1 = NULL,
- *bms2 = NULL;
- text *result;
-
- if (!PG_ARGISNULL(0))
- bms1 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
-
- if (!PG_ARGISNULL(1))
- bms2 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(1));
+ Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
+ Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
+ /* left input gets recycled */
bms1 = bms_int_members(bms1, bms2);
- if (bms2)
- bms_free(bms2);
-
- if (bms1 == NULL)
- PG_RETURN_NULL();
-
- result = BITMAPSET_TO_TEXT(bms1);
-
- if (bms1)
- bms_free(bms1);
-
- PG_RETURN_TEXT_P(result);
+ PG_RETURN_BITMAPSET_AS_TEXT(bms1);
}
Datum
test_bms_del_members(PG_FUNCTION_ARGS)
{
- Bitmapset *bms1 = NULL,
- *bms2 = NULL;
- Bitmapset *result_bms;
- text *result;
+ Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
+ Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
- if (!PG_ARGISNULL(0))
- bms1 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
+ /* left input gets recycled */
+ bms1 = bms_del_members(bms1, bms2);
- if (!PG_ARGISNULL(1))
- bms2 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(1));
-
- /* IMPORTANT: bms_del_members modifies/frees the first argument */
- result_bms = bms_del_members(bms1, bms2);
-
- /* bms1 is now invalid, do not free it */
-
- if (bms2)
- bms_free(bms2);
-
- if (result_bms == NULL)
- PG_RETURN_NULL();
-
- result = BITMAPSET_TO_TEXT(result_bms);
- bms_free(result_bms);
-
- PG_RETURN_TEXT_P(result);
+ PG_RETURN_BITMAPSET_AS_TEXT(bms1);
}
Datum
test_bms_replace_members(PG_FUNCTION_ARGS)
{
- Bitmapset *bms1 = NULL,
- *bms2 = NULL;
- Bitmapset *result_bms;
- text *result;
-
- if (!PG_ARGISNULL(0))
- bms1 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
-
- if (!PG_ARGISNULL(1))
- bms2 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(1));
+ Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
+ Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
- /* IMPORTANT: bms_replace_members modifies/frees the first argument */
- result_bms = bms_replace_members(bms1, bms2);
+ /* left input gets recycled */
+ bms1 = bms_replace_members(bms1, bms2);
- /* bms1 is now invalid, do not free it */
-
- if (bms2)
- bms_free(bms2);
-
- if (result_bms == NULL)
- PG_RETURN_NULL();
-
- result = BITMAPSET_TO_TEXT(result_bms);
- bms_free(result_bms);
-
- PG_RETURN_TEXT_P(result);
+ PG_RETURN_BITMAPSET_AS_TEXT(bms1);
}
Datum
test_bms_join(PG_FUNCTION_ARGS)
{
- Bitmapset *bms1 = NULL,
- *bms2 = NULL;
+ Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
+ Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
Bitmapset *result_bms;
- text *result;
-
- if (!PG_ARGISNULL(0))
- bms1 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
- if (!PG_ARGISNULL(1))
- bms2 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(1));
-
- /* IMPORTANT: bms_join may recycle either input arguments */
+ /* either input can be recycled */
result_bms = bms_join(bms1, bms2);
- /* bms1 and bms2 may have been recycled! Do not free any of them. */
-
- if (result_bms == NULL)
- PG_RETURN_NULL();
-
- result = BITMAPSET_TO_TEXT(result_bms);
- bms_free(result_bms);
+ /* memory cleanup seems more tricky than it's worth here */
- PG_RETURN_TEXT_P(result);
+ PG_RETURN_BITMAPSET_AS_TEXT(result_bms);
}
Datum
test_bms_hash_value(PG_FUNCTION_ARGS)
{
- Bitmapset *bms = NULL;
+ Bitmapset *bms = PG_ARG_GETBITMAPSET(0);
uint32 hash_result;
- if (!PG_ARGISNULL(0))
- bms = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
-
hash_result = bms_hash_value(bms);
- if (bms)
- bms_free(bms);
-
PG_RETURN_INT32(hash_result);
}
Datum
test_bitmap_hash(PG_FUNCTION_ARGS)
{
- Bitmapset *bms = NULL;
- Bitmapset *bms_ptr;
+ Bitmapset *bms = PG_ARG_GETBITMAPSET(0);
uint32 hash_result;
- if (!PG_ARGISNULL(0))
- bms = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
-
- bms_ptr = bms;
-
/* Call bitmap_hash */
- hash_result = bitmap_hash(&bms_ptr, sizeof(Bitmapset *));
-
- /* Clean up */
- if (!PG_ARGISNULL(0) && bms_ptr)
- bms_free(bms_ptr);
+ hash_result = bitmap_hash(&bms, sizeof(Bitmapset *));
PG_RETURN_INT32(hash_result);
}
@@ -870,30 +578,12 @@ test_bitmap_hash(PG_FUNCTION_ARGS)
Datum
test_bitmap_match(PG_FUNCTION_ARGS)
{
- Bitmapset *bms1 = NULL,
- *bms2 = NULL;
- Bitmapset *bms_ptr1,
- *bms_ptr2;
+ Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
+ Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
int match_result;
- if (!PG_ARGISNULL(0))
- bms1 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
-
- if (!PG_ARGISNULL(1))
- bms2 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(1));
-
- /* Set up pointers to the Bitmapsets */
- bms_ptr1 = bms1;
- bms_ptr2 = bms2;
-
/* Call bitmap_match with addresses of the Bitmapset pointers */
- match_result = bitmap_match(&bms_ptr1, &bms_ptr2, sizeof(Bitmapset *));
-
- /* Clean up */
- if (bms1)
- bms_free(bms1);
- if (bms2)
- bms_free(bms2);
+ match_result = bitmap_match(&bms1, &bms2, sizeof(Bitmapset *));
PG_RETURN_INT32(match_result);
}
@@ -1031,8 +721,7 @@ test_random_operations(PG_FUNCTION_ARGS)
total_ops++;
}
- if (bms)
- bms_free(bms);
+ bms_free(bms);
PG_RETURN_INT32(total_ops);
}