mirror of
https://github.com/postgres/postgres.git
synced 2025-10-03 00:03:21 -04:00
Compare commits
No commits in common. "684a745f55057edd2365a7125ebcb7a54a4db8f8" and "8e2acda2b098bf53120721e16a7b1055c4e5b3a6" have entirely different histories.
684a745f55
...
8e2acda2b0
@ -424,7 +424,7 @@ pgstat_btree_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno,
|
|||||||
/* fully empty page */
|
/* fully empty page */
|
||||||
stat->free_space += BLCKSZ;
|
stat->free_space += BLCKSZ;
|
||||||
}
|
}
|
||||||
else if (PageGetSpecialSize(page) == MAXALIGN(sizeof(BTPageOpaqueData)))
|
else
|
||||||
{
|
{
|
||||||
BTPageOpaque opaque;
|
BTPageOpaque opaque;
|
||||||
|
|
||||||
@ -458,16 +458,10 @@ pgstat_hash_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno,
|
|||||||
Buffer buf;
|
Buffer buf;
|
||||||
Page page;
|
Page page;
|
||||||
|
|
||||||
buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, bstrategy);
|
buf = _hash_getbuf_with_strategy(rel, blkno, HASH_READ, 0, bstrategy);
|
||||||
LockBuffer(buf, HASH_READ);
|
|
||||||
page = BufferGetPage(buf);
|
page = BufferGetPage(buf);
|
||||||
|
|
||||||
if (PageIsNew(page))
|
if (PageGetSpecialSize(page) == MAXALIGN(sizeof(HashPageOpaqueData)))
|
||||||
{
|
|
||||||
/* fully empty page */
|
|
||||||
stat->free_space += BLCKSZ;
|
|
||||||
}
|
|
||||||
else if (PageGetSpecialSize(page) == MAXALIGN(sizeof(HashPageOpaqueData)))
|
|
||||||
{
|
{
|
||||||
HashPageOpaque opaque;
|
HashPageOpaque opaque;
|
||||||
|
|
||||||
@ -508,23 +502,17 @@ pgstat_gist_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno,
|
|||||||
|
|
||||||
buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, bstrategy);
|
buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, bstrategy);
|
||||||
LockBuffer(buf, GIST_SHARE);
|
LockBuffer(buf, GIST_SHARE);
|
||||||
|
gistcheckpage(rel, buf);
|
||||||
page = BufferGetPage(buf);
|
page = BufferGetPage(buf);
|
||||||
if (PageIsNew(page))
|
|
||||||
|
if (GistPageIsLeaf(page))
|
||||||
{
|
{
|
||||||
/* fully empty page */
|
pgstat_index_page(stat, page, FirstOffsetNumber,
|
||||||
stat->free_space += BLCKSZ;
|
PageGetMaxOffsetNumber(page));
|
||||||
}
|
}
|
||||||
else if (PageGetSpecialSize(page) == MAXALIGN(sizeof(GISTPageOpaqueData)))
|
else
|
||||||
{
|
{
|
||||||
if (GistPageIsLeaf(page))
|
/* root or node */
|
||||||
{
|
|
||||||
pgstat_index_page(stat, page, FirstOffsetNumber,
|
|
||||||
PageGetMaxOffsetNumber(page));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* root or node */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UnlockReleaseBuffer(buf);
|
UnlockReleaseBuffer(buf);
|
||||||
|
@ -46,8 +46,7 @@
|
|||||||
|
|
||||||
/* Inhibit mingw CRT's auto-globbing of command line arguments */
|
/* Inhibit mingw CRT's auto-globbing of command line arguments */
|
||||||
#if defined(WIN32) && !defined(_MSC_VER)
|
#if defined(WIN32) && !defined(_MSC_VER)
|
||||||
extern int _CRT_glob;
|
extern int _CRT_glob = 0; /* 0 turns off globbing; 1 turns it on */
|
||||||
int _CRT_glob = 0; /* 0 turns off globbing; 1 turns it on */
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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;
|
SELECT test_bms_replace_members('(b 1 2 3)', NULL) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
<>
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT test_bms_replace_members('(b 1 2 3)', '(b 3 5 6)') AS result;
|
SELECT test_bms_replace_members('(b 1 2 3)', '(b 3 5 6)') AS result;
|
||||||
@ -104,19 +104,44 @@ SELECT test_bms_replace_members('(b 1 2 3 4 5)', '(b 500 600)') AS result;
|
|||||||
(b 500 600)
|
(b 500 600)
|
||||||
(1 row)
|
(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()
|
-- bms_del_member()
|
||||||
SELECT test_bms_del_member('(b)', -20); -- error
|
SELECT test_bms_del_member('(b)', -20); -- error
|
||||||
ERROR: negative bitmapset member not allowed
|
ERROR: negative bitmapset member not allowed
|
||||||
SELECT test_bms_del_member('(b)', 10) AS result;
|
SELECT test_bms_del_member('(b)', 10) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
<>
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT test_bms_del_member('(b 10)', 10) AS result;
|
SELECT test_bms_del_member('(b 10)', 10) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
<>
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT test_bms_del_member('(b 10)', 5) AS result;
|
SELECT test_bms_del_member('(b 10)', 5) AS result;
|
||||||
@ -165,6 +190,12 @@ SELECT test_bms_del_member('(b 1 50 100 200)', 100) AS result;
|
|||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- Test module checks
|
-- 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;
|
SELECT test_bms_del_member('(b 5)', NULL) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
@ -175,13 +206,13 @@ SELECT test_bms_del_member('(b 5)', NULL) AS result;
|
|||||||
SELECT test_bms_del_members('(b)', '(b 10)') AS result;
|
SELECT test_bms_del_members('(b)', '(b 10)') AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
<>
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT test_bms_del_members('(b 10)', '(b 10)') AS result;
|
SELECT test_bms_del_members('(b 10)', '(b 10)') AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
<>
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT test_bms_del_members('(b 10)', '(b 5)') AS result;
|
SELECT test_bms_del_members('(b 10)', '(b 5)') AS result;
|
||||||
@ -221,7 +252,7 @@ SELECT test_bms_del_members('(b 1 2 100 200 300)', '(b 200 300)') AS result;
|
|||||||
(b 1 2 100)
|
(b 1 2 100)
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- NULL inputs
|
-- Test module checks
|
||||||
SELECT test_bms_del_members('(b 5)', NULL) AS result;
|
SELECT test_bms_del_members('(b 5)', NULL) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
@ -231,7 +262,7 @@ SELECT test_bms_del_members('(b 5)', NULL) AS result;
|
|||||||
SELECT test_bms_del_members(NULL, '(b 5)') AS result;
|
SELECT test_bms_del_members(NULL, '(b 5)') AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
<>
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- bms_join()
|
-- bms_join()
|
||||||
@ -272,7 +303,7 @@ SELECT test_bms_join('(b 1 2)', '(b 100 200 300)') AS result;
|
|||||||
(b 1 2 100 200 300)
|
(b 1 2 100 200 300)
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- NULL inputs
|
-- Test module checks
|
||||||
SELECT test_bms_join('(b 5)', NULL) AS result;
|
SELECT test_bms_join('(b 5)', NULL) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
@ -288,7 +319,7 @@ SELECT test_bms_join(NULL, '(b 5)') AS result;
|
|||||||
SELECT test_bms_join(NULL, NULL) AS result;
|
SELECT test_bms_join(NULL, NULL) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
<>
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- bms_union()
|
-- bms_union()
|
||||||
@ -310,7 +341,7 @@ SELECT test_bms_union('(b 1 3 5)', '(b)') AS result;
|
|||||||
SELECT test_bms_union('(b)', '(b)') AS result;
|
SELECT test_bms_union('(b)', '(b)') AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
<>
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- Overlapping ranges
|
-- Overlapping ranges
|
||||||
@ -323,7 +354,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)
|
(b 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20)
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- Union with varying word counts
|
-- Union with varrying word counts
|
||||||
SELECT test_bms_union('(b 1 2)', '(b 100 300)') AS result;
|
SELECT test_bms_union('(b 1 2)', '(b 100 300)') AS result;
|
||||||
result
|
result
|
||||||
-----------------
|
-----------------
|
||||||
@ -336,7 +367,7 @@ SELECT test_bms_union('(b 100 300)', '(b 1 2)') AS result;
|
|||||||
(b 1 2 100 300)
|
(b 1 2 100 300)
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- NULL inputs
|
-- Test module checks
|
||||||
SELECT test_bms_union('(b 5)', NULL) AS result;
|
SELECT test_bms_union('(b 5)', NULL) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
@ -352,7 +383,7 @@ SELECT test_bms_union(NULL, '(b 5)') AS result;
|
|||||||
SELECT test_bms_union(NULL, NULL) AS result;
|
SELECT test_bms_union(NULL, NULL) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
<>
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- bms_intersect()
|
-- bms_intersect()
|
||||||
@ -367,17 +398,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;
|
SELECT test_bms_intersect('(b 1 3 5)', '(b 2 4 6)') AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
<>
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- Intersect with empty
|
-- Intersect with empty
|
||||||
SELECT test_bms_intersect('(b 1 3 5)', '(b)') AS result;
|
SELECT test_bms_intersect('(b 1 3 5)', '(b)') AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
<>
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- Intersect with varying word counts
|
-- Intersect with varrying word counts
|
||||||
SELECT test_bms_intersect('(b 1 300)', '(b 1 2 3 4 5)') AS result;
|
SELECT test_bms_intersect('(b 1 300)', '(b 1 2 3 4 5)') AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
@ -390,23 +421,29 @@ SELECT test_bms_intersect('(b 1 2 3 4 5)', '(b 1 300)') AS result;
|
|||||||
(b 1)
|
(b 1)
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- NULL inputs
|
-- Test module checks
|
||||||
|
SELECT test_bms_intersect('(b 1)', '(b 2)') AS result;
|
||||||
|
result
|
||||||
|
--------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
SELECT test_bms_intersect('(b 5)', NULL) AS result;
|
SELECT test_bms_intersect('(b 5)', NULL) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
<>
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT test_bms_intersect(NULL, '(b 5)') AS result;
|
SELECT test_bms_intersect(NULL, '(b 5)') AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
<>
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT test_bms_intersect(NULL, NULL) AS result;
|
SELECT test_bms_intersect(NULL, NULL) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
<>
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- bms_int_members()
|
-- bms_int_members()
|
||||||
@ -421,14 +458,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;
|
SELECT test_bms_int_members('(b 1 3 5)', '(b 2 4 6)') AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
<>
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- Intersect with empty
|
-- Intersect with empty
|
||||||
SELECT test_bms_int_members('(b 1 3 5)', '(b)') AS result;
|
SELECT test_bms_int_members('(b 1 3 5)', '(b)') AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
<>
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- Multiple members
|
-- Multiple members
|
||||||
@ -438,23 +475,29 @@ SELECT test_bms_int_members('(b 0 31 32 63 64)', '(b 31 32 64 65)') AS result;
|
|||||||
(b 31 32 64)
|
(b 31 32 64)
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- NULL inputs
|
-- Test module checks
|
||||||
|
SELECT test_bms_int_members('(b 1)', '(b 2)') AS result;
|
||||||
|
result
|
||||||
|
--------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
SELECT test_bms_int_members('(b 5)', NULL) AS result;
|
SELECT test_bms_int_members('(b 5)', NULL) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
<>
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT test_bms_int_members(NULL, '(b 5)') AS result;
|
SELECT test_bms_int_members(NULL, '(b 5)') AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
<>
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT test_bms_int_members(NULL, NULL) AS result;
|
SELECT test_bms_int_members(NULL, NULL) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
<>
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- bms_difference()
|
-- bms_difference()
|
||||||
@ -476,14 +519,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;
|
SELECT test_bms_difference('(b 1 3 5)', '(b 1 3 5)') AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
<>
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- Substraction to empty
|
-- Substraction to empty
|
||||||
SELECT test_bms_difference('(b 42)', '(b 42)') AS result;
|
SELECT test_bms_difference('(b 42)', '(b 42)') AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
<>
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- Subtraction edge case
|
-- Subtraction edge case
|
||||||
@ -509,7 +552,13 @@ SELECT test_bms_difference('(b 1 2 100 200)', '(b 1 2)') AS result;
|
|||||||
(b 100 200)
|
(b 100 200)
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- NULL inputs
|
-- Test module checks
|
||||||
|
SELECT test_bms_difference('(b 5)', '(b 5 10)') AS result;
|
||||||
|
result
|
||||||
|
--------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
SELECT test_bms_difference('(b 5)', NULL) AS result;
|
SELECT test_bms_difference('(b 5)', NULL) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
@ -519,13 +568,13 @@ SELECT test_bms_difference('(b 5)', NULL) AS result;
|
|||||||
SELECT test_bms_difference(NULL, '(b 5)') AS result;
|
SELECT test_bms_difference(NULL, '(b 5)') AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
<>
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT test_bms_difference(NULL, NULL) AS result;
|
SELECT test_bms_difference(NULL, NULL) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
<>
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- bms_is_member()
|
-- bms_is_member()
|
||||||
@ -559,7 +608,7 @@ SELECT test_bms_is_member('(b)', 1) AS result;
|
|||||||
SELECT test_bms_is_member('(b 5)', NULL) AS result;
|
SELECT test_bms_is_member('(b 5)', NULL) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
|
f
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- bms_member_index()
|
-- bms_member_index()
|
||||||
@ -606,11 +655,17 @@ SELECT test_bms_member_index('(b 1 50 100 200)', 200) AS result;
|
|||||||
3
|
3
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- Test module check
|
-- Test module checks
|
||||||
SELECT test_bms_member_index('(b 1 3 5)', NULL) AS result;
|
SELECT test_bms_member_index('', 5) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
|
-1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT test_bms_member_index(NULL, 5) AS result;
|
||||||
|
result
|
||||||
|
--------
|
||||||
|
-1
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- bms_num_members()
|
-- bms_num_members()
|
||||||
@ -676,7 +731,7 @@ SELECT test_bms_equal('(b 5 10)', '(b 100 200 300)') AS result;
|
|||||||
f
|
f
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- NULL inputs
|
-- Test module checks
|
||||||
SELECT test_bms_equal('(b 5)', NULL) AS result;
|
SELECT test_bms_equal('(b 5)', NULL) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
@ -741,7 +796,7 @@ SELECT test_bms_compare(
|
|||||||
-1
|
-1
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- NULL inputs
|
-- Test module checks
|
||||||
SELECT test_bms_compare('(b 5)', NULL) AS result;
|
SELECT test_bms_compare('(b 5)', NULL) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
@ -847,7 +902,6 @@ SELECT test_bms_add_range('(b 5)', NULL, NULL) AS result;
|
|||||||
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- NULL inputs
|
|
||||||
SELECT test_bms_add_range(NULL, 5, 10) AS result;
|
SELECT test_bms_add_range(NULL, 5, 10) AS result;
|
||||||
result
|
result
|
||||||
------------------
|
------------------
|
||||||
@ -857,7 +911,13 @@ 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, 10, 5) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
<>
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT test_bms_add_range(NULL, NULL, NULL) AS result;
|
||||||
|
result
|
||||||
|
--------
|
||||||
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- bms_membership()
|
-- bms_membership()
|
||||||
@ -879,7 +939,7 @@ SELECT test_bms_membership('(b 1 2)') AS result;
|
|||||||
2
|
2
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- NULL input
|
-- Test module check
|
||||||
SELECT test_bms_membership(NULL) AS result;
|
SELECT test_bms_membership(NULL) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
@ -905,6 +965,13 @@ SELECT test_bms_is_empty('(b 1)') AS result;
|
|||||||
f
|
f
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
-- Test module check
|
||||||
|
SELECT test_bms_is_empty(NULL) AS result;
|
||||||
|
result
|
||||||
|
--------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
-- bms_singleton_member()
|
-- bms_singleton_member()
|
||||||
SELECT test_bms_singleton_member('(b)'); -- error
|
SELECT test_bms_singleton_member('(b)'); -- error
|
||||||
ERROR: bitmapset is empty
|
ERROR: bitmapset is empty
|
||||||
@ -916,7 +983,7 @@ SELECT test_bms_singleton_member('(b 42)') AS result;
|
|||||||
42
|
42
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- NULL input
|
-- Test module check
|
||||||
SELECT test_bms_singleton_member(NULL) AS result;
|
SELECT test_bms_singleton_member(NULL) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
@ -924,33 +991,39 @@ SELECT test_bms_singleton_member(NULL) AS result;
|
|||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- bms_get_singleton_member()
|
-- bms_get_singleton_member()
|
||||||
SELECT test_bms_get_singleton_member('(b)');
|
SELECT test_bms_get_singleton_member('(b)', 1000);
|
||||||
test_bms_get_singleton_member
|
test_bms_get_singleton_member
|
||||||
-------------------------------
|
-------------------------------
|
||||||
-1
|
1000
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- Try with an empty set
|
|
||||||
SELECT test_bms_get_singleton_member(NULL) AS result;
|
|
||||||
result
|
|
||||||
--------
|
|
||||||
-1
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- Not a singleton, returns input default
|
-- Not a singleton, returns input default
|
||||||
SELECT test_bms_get_singleton_member('(b 3 6)') AS result;
|
SELECT test_bms_get_singleton_member('(b 3 6)', 1000) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
-1
|
1000
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- Singletone, returns sole member
|
-- Singletone, returns sole member
|
||||||
SELECT test_bms_get_singleton_member('(b 400)') AS result;
|
SELECT test_bms_get_singleton_member('(b 400)', 1000) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
400
|
400
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
-- Test module checks
|
||||||
|
SELECT test_bms_get_singleton_member('', 1000) AS result;
|
||||||
|
result
|
||||||
|
--------
|
||||||
|
1000
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT test_bms_get_singleton_member(NULL, -1) AS result;
|
||||||
|
result
|
||||||
|
--------
|
||||||
|
-1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
-- bms_next_member() and bms_prev_member()
|
-- bms_next_member() and bms_prev_member()
|
||||||
-- First member
|
-- First member
|
||||||
SELECT test_bms_next_member('(b 5 10 15 20)', -1) AS result;
|
SELECT test_bms_next_member('(b 5 10 15 20)', -1) AS result;
|
||||||
@ -1015,32 +1088,49 @@ SELECT test_bms_prev_member('(b 0 63 64 127)', -1) AS result;
|
|||||||
127
|
127
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- NULL inputs
|
-- 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)
|
||||||
|
|
||||||
SELECT test_bms_next_member(NULL, 5) AS result;
|
SELECT test_bms_next_member(NULL, 5) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
-2
|
-2
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
SELECT test_bms_next_member(NULL, NULL) AS result;
|
||||||
|
result
|
||||||
|
--------
|
||||||
|
-2
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT test_bms_prev_member('', 5) AS result;
|
||||||
|
result
|
||||||
|
--------
|
||||||
|
-2
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT test_bms_prev_member('(b 5)', NULL) AS result;
|
||||||
|
result
|
||||||
|
--------
|
||||||
|
-2
|
||||||
|
(1 row)
|
||||||
|
|
||||||
SELECT test_bms_prev_member(NULL, 5) AS result;
|
SELECT test_bms_prev_member(NULL, 5) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
-2
|
-2
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- Test module check
|
|
||||||
SELECT test_bms_next_member('(b 5 10)', NULL) AS result;
|
|
||||||
result
|
|
||||||
--------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SELECT test_bms_prev_member('(b 5 10)', NULL) AS result;
|
|
||||||
result
|
|
||||||
--------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- bms_hash_value()
|
-- bms_hash_value()
|
||||||
SELECT test_bms_hash_value('(b)') = 0 AS result;
|
SELECT test_bms_hash_value('(b)') = 0 AS result;
|
||||||
result
|
result
|
||||||
@ -1060,7 +1150,7 @@ SELECT test_bms_hash_value('(b 1 3 5)') != test_bms_hash_value('(b 2 4 6)') AS r
|
|||||||
t
|
t
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- NULL input
|
-- Test module check
|
||||||
SELECT test_bms_hash_value(NULL) AS result;
|
SELECT test_bms_hash_value(NULL) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
@ -1086,7 +1176,7 @@ SELECT test_bms_overlap('(b)', '(b 1 3 5)') AS result;
|
|||||||
f
|
f
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- NULL inputs
|
-- Test module checks
|
||||||
SELECT test_bms_overlap('(b 5)', NULL) AS result;
|
SELECT test_bms_overlap('(b 5)', NULL) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
@ -1150,7 +1240,7 @@ SELECT test_bms_is_subset('(b 1 2 50 100)', '(b 1 2)') AS result;
|
|||||||
f
|
f
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- NULL inputs
|
-- Test module checks
|
||||||
SELECT test_bms_is_subset('(b 5)', NULL) AS result;
|
SELECT test_bms_is_subset('(b 5)', NULL) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
@ -1308,11 +1398,30 @@ SELECT test_bms_subset_compare('(b 2 64 128)', '(b 1 65)') AS result;
|
|||||||
3
|
3
|
||||||
(1 row)
|
(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()
|
-- bms_copy()
|
||||||
SELECT test_bms_copy(NULL) AS result;
|
SELECT test_bms_copy(NULL) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
<>
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT test_bms_copy('(b 1 3 5 7)') AS result;
|
SELECT test_bms_copy('(b 1 3 5 7)') AS result;
|
||||||
@ -1321,6 +1430,13 @@ SELECT test_bms_copy('(b 1 3 5 7)') AS result;
|
|||||||
(b 1 3 5 7)
|
(b 1 3 5 7)
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
-- Test module check
|
||||||
|
SELECT test_bms_copy(NULL) AS result;
|
||||||
|
result
|
||||||
|
--------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
-- bms_add_members()
|
-- bms_add_members()
|
||||||
SELECT test_bms_add_members('(b 1 3)', '(b 5 7)') AS result;
|
SELECT test_bms_add_members('(b 1 3)', '(b 5 7)') AS result;
|
||||||
result
|
result
|
||||||
@ -1431,7 +1547,7 @@ SELECT (test_bitmap_match('(b)', '(b)') = 0) =
|
|||||||
t
|
t
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- NULL inputs
|
-- Test module checks
|
||||||
SELECT test_bitmap_match('(b 5)', NULL) AS result;
|
SELECT test_bitmap_match('(b 5)', NULL) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
@ -1493,7 +1609,7 @@ SELECT test_bms_overlap_list('(b 5 10)', ARRAY[-1,5]) AS result; -- error
|
|||||||
ERROR: negative bitmapset member not allowed
|
ERROR: negative bitmapset member not allowed
|
||||||
SELECT test_bms_overlap_list('(b 1 2 3)', ARRAY[-5,-1,0]) AS result; -- error
|
SELECT test_bms_overlap_list('(b 1 2 3)', ARRAY[-5,-1,0]) AS result; -- error
|
||||||
ERROR: negative bitmapset member not allowed
|
ERROR: negative bitmapset member not allowed
|
||||||
-- NULL inputs
|
-- Test module checks
|
||||||
SELECT test_bms_overlap_list('(b 5)', NULL) AS result;
|
SELECT test_bms_overlap_list('(b 5)', NULL) AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
@ -1525,12 +1641,6 @@ SELECT test_bms_nonempty_difference('(b 1 3 5)', NULL) AS result;
|
|||||||
t
|
t
|
||||||
(1 row)
|
(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;
|
SELECT test_bms_nonempty_difference('(b 1 3 5)', '(b 2 4 6)') AS result;
|
||||||
result
|
result
|
||||||
--------
|
--------
|
||||||
@ -1568,6 +1678,25 @@ SELECT test_bms_nonempty_difference('(b 1 2)', '(b 50 100)') AS result;
|
|||||||
t
|
t
|
||||||
(1 row)
|
(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
|
-- random operations
|
||||||
SELECT test_random_operations(-1, 10000, 81920, 0) > 0 AS result;
|
SELECT test_random_operations(-1, 10000, 81920, 0) > 0 AS result;
|
||||||
result
|
result
|
||||||
|
@ -29,6 +29,11 @@ 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;
|
SELECT test_bms_replace_members('(b 1 2)', '(b 3 5 7)') AS result;
|
||||||
-- Force repalloc() with larger set
|
-- Force repalloc() with larger set
|
||||||
SELECT test_bms_replace_members('(b 1 2 3 4 5)', '(b 500 600)') AS result;
|
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()
|
-- bms_del_member()
|
||||||
SELECT test_bms_del_member('(b)', -20); -- error
|
SELECT test_bms_del_member('(b)', -20); -- error
|
||||||
@ -45,6 +50,7 @@ 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)', 200) AS result;
|
||||||
SELECT test_bms_del_member('(b 1 50 100 200)', 100) AS result;
|
SELECT test_bms_del_member('(b 1 50 100 200)', 100) AS result;
|
||||||
-- Test module checks
|
-- Test module checks
|
||||||
|
SELECT test_bms_del_member('(b 42)', 42) AS result;
|
||||||
SELECT test_bms_del_member('(b 5)', NULL) AS result;
|
SELECT test_bms_del_member('(b 5)', NULL) AS result;
|
||||||
|
|
||||||
-- bms_del_members()
|
-- bms_del_members()
|
||||||
@ -57,7 +63,7 @@ SELECT test_bms_del_members('(b 5 100 200)', '(b 200)') AS result;
|
|||||||
-- Force word count changes
|
-- 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 1 2)') AS result;
|
||||||
SELECT test_bms_del_members('(b 1 2 100 200 300)', '(b 200 300)') AS result;
|
SELECT test_bms_del_members('(b 1 2 100 200 300)', '(b 200 300)') AS result;
|
||||||
-- NULL inputs
|
-- Test module checks
|
||||||
SELECT test_bms_del_members('(b 5)', NULL) AS result;
|
SELECT test_bms_del_members('(b 5)', NULL) AS result;
|
||||||
SELECT test_bms_del_members(NULL, '(b 5)') AS result;
|
SELECT test_bms_del_members(NULL, '(b 5)') AS result;
|
||||||
|
|
||||||
@ -69,7 +75,7 @@ SELECT test_bms_join('(b 1 3 5)', '(b 1 4 5)') AS result;
|
|||||||
-- Force word count changes
|
-- Force word count changes
|
||||||
SELECT test_bms_join('(b 5)', '(b 100)') AS result;
|
SELECT test_bms_join('(b 5)', '(b 100)') AS result;
|
||||||
SELECT test_bms_join('(b 1 2)', '(b 100 200 300)') AS result;
|
SELECT test_bms_join('(b 1 2)', '(b 100 200 300)') AS result;
|
||||||
-- NULL inputs
|
-- Test module checks
|
||||||
SELECT test_bms_join('(b 5)', NULL) AS result;
|
SELECT test_bms_join('(b 5)', NULL) AS result;
|
||||||
SELECT test_bms_join(NULL, '(b 5)') AS result;
|
SELECT test_bms_join(NULL, '(b 5)') AS result;
|
||||||
SELECT test_bms_join(NULL, NULL) AS result;
|
SELECT test_bms_join(NULL, NULL) AS result;
|
||||||
@ -86,10 +92,10 @@ SELECT test_bms_union(
|
|||||||
test_bms_add_range('(b)', 0, 15),
|
test_bms_add_range('(b)', 0, 15),
|
||||||
test_bms_add_range('(b)', 10, 20)
|
test_bms_add_range('(b)', 10, 20)
|
||||||
) AS result;
|
) AS result;
|
||||||
-- Union with varying word counts
|
-- Union with varrying word counts
|
||||||
SELECT test_bms_union('(b 1 2)', '(b 100 300)') AS result;
|
SELECT test_bms_union('(b 1 2)', '(b 100 300)') AS result;
|
||||||
SELECT test_bms_union('(b 100 300)', '(b 1 2)') AS result;
|
SELECT test_bms_union('(b 100 300)', '(b 1 2)') AS result;
|
||||||
-- NULL inputs
|
-- Test module checks
|
||||||
SELECT test_bms_union('(b 5)', NULL) AS result;
|
SELECT test_bms_union('(b 5)', NULL) AS result;
|
||||||
SELECT test_bms_union(NULL, '(b 5)') AS result;
|
SELECT test_bms_union(NULL, '(b 5)') AS result;
|
||||||
SELECT test_bms_union(NULL, NULL) AS result;
|
SELECT test_bms_union(NULL, NULL) AS result;
|
||||||
@ -101,10 +107,11 @@ 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;
|
SELECT test_bms_intersect('(b 1 3 5)', '(b 2 4 6)') AS result;
|
||||||
-- Intersect with empty
|
-- Intersect with empty
|
||||||
SELECT test_bms_intersect('(b 1 3 5)', '(b)') AS result;
|
SELECT test_bms_intersect('(b 1 3 5)', '(b)') AS result;
|
||||||
-- Intersect with varying word counts
|
-- Intersect with varrying word counts
|
||||||
SELECT test_bms_intersect('(b 1 300)', '(b 1 2 3 4 5)') AS result;
|
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;
|
SELECT test_bms_intersect('(b 1 2 3 4 5)', '(b 1 300)') AS result;
|
||||||
-- NULL inputs
|
-- Test module checks
|
||||||
|
SELECT test_bms_intersect('(b 1)', '(b 2)') AS result;
|
||||||
SELECT test_bms_intersect('(b 5)', NULL) AS result;
|
SELECT test_bms_intersect('(b 5)', NULL) AS result;
|
||||||
SELECT test_bms_intersect(NULL, '(b 5)') AS result;
|
SELECT test_bms_intersect(NULL, '(b 5)') AS result;
|
||||||
SELECT test_bms_intersect(NULL, NULL) AS result;
|
SELECT test_bms_intersect(NULL, NULL) AS result;
|
||||||
@ -118,7 +125,8 @@ 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;
|
SELECT test_bms_int_members('(b 1 3 5)', '(b)') AS result;
|
||||||
-- Multiple members
|
-- Multiple members
|
||||||
SELECT test_bms_int_members('(b 0 31 32 63 64)', '(b 31 32 64 65)') AS result;
|
SELECT test_bms_int_members('(b 0 31 32 63 64)', '(b 31 32 64 65)') AS result;
|
||||||
-- NULL inputs
|
-- Test module checks
|
||||||
|
SELECT test_bms_int_members('(b 1)', '(b 2)') AS result;
|
||||||
SELECT test_bms_int_members('(b 5)', NULL) AS result;
|
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, '(b 5)') AS result;
|
||||||
SELECT test_bms_int_members(NULL, NULL) AS result;
|
SELECT test_bms_int_members(NULL, NULL) AS result;
|
||||||
@ -140,7 +148,8 @@ SELECT test_bms_difference(
|
|||||||
-- Difference with different word counts
|
-- Difference with different word counts
|
||||||
SELECT test_bms_difference('(b 5 100)', '(b 5)') AS result;
|
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;
|
SELECT test_bms_difference('(b 1 2 100 200)', '(b 1 2)') AS result;
|
||||||
-- NULL inputs
|
-- Test module checks
|
||||||
|
SELECT test_bms_difference('(b 5)', '(b 5 10)') AS result;
|
||||||
SELECT test_bms_difference('(b 5)', NULL) AS result;
|
SELECT test_bms_difference('(b 5)', NULL) AS result;
|
||||||
SELECT test_bms_difference(NULL, '(b 5)') AS result;
|
SELECT test_bms_difference(NULL, '(b 5)') AS result;
|
||||||
SELECT test_bms_difference(NULL, NULL) AS result;
|
SELECT test_bms_difference(NULL, NULL) AS result;
|
||||||
@ -163,8 +172,9 @@ 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)', 100) AS result;
|
||||||
SELECT test_bms_member_index('(b 100 200)', 200) 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;
|
SELECT test_bms_member_index('(b 1 50 100 200)', 200) AS result;
|
||||||
-- Test module check
|
-- Test module checks
|
||||||
SELECT test_bms_member_index('(b 1 3 5)', NULL) AS result;
|
SELECT test_bms_member_index('', 5) AS result;
|
||||||
|
SELECT test_bms_member_index(NULL, 5) AS result;
|
||||||
|
|
||||||
-- bms_num_members()
|
-- bms_num_members()
|
||||||
SELECT test_bms_num_members('(b)') AS result;
|
SELECT test_bms_num_members('(b)') AS result;
|
||||||
@ -180,7 +190,7 @@ SELECT test_bms_equal('(b 1 3 5)', '(b 2 4 6)') AS result;
|
|||||||
-- Equal with different word counts
|
-- Equal with different word counts
|
||||||
SELECT test_bms_equal('(b 5)', '(b 100)') AS result;
|
SELECT test_bms_equal('(b 5)', '(b 100)') AS result;
|
||||||
SELECT test_bms_equal('(b 5 10)', '(b 100 200 300)') AS result;
|
SELECT test_bms_equal('(b 5 10)', '(b 100 200 300)') AS result;
|
||||||
-- NULL inputs
|
-- Test module checks
|
||||||
SELECT test_bms_equal('(b 5)', NULL) AS result;
|
SELECT test_bms_equal('(b 5)', NULL) AS result;
|
||||||
SELECT test_bms_equal(NULL, '(b 5)') AS result;
|
SELECT test_bms_equal(NULL, '(b 5)') AS result;
|
||||||
SELECT test_bms_equal(NULL, NULL) AS result;
|
SELECT test_bms_equal(NULL, NULL) AS result;
|
||||||
@ -196,7 +206,7 @@ SELECT test_bms_compare(
|
|||||||
test_bms_add_range('(b)', 0, 63),
|
test_bms_add_range('(b)', 0, 63),
|
||||||
test_bms_add_range('(b)', 0, 64)
|
test_bms_add_range('(b)', 0, 64)
|
||||||
) AS result;
|
) AS result;
|
||||||
-- NULL inputs
|
-- Test module checks
|
||||||
SELECT test_bms_compare('(b 5)', NULL) AS result;
|
SELECT test_bms_compare('(b 5)', NULL) AS result;
|
||||||
SELECT test_bms_compare(NULL, '(b 5)') AS result;
|
SELECT test_bms_compare(NULL, '(b 5)') AS result;
|
||||||
SELECT test_bms_compare(NULL, NULL) AS result;
|
SELECT test_bms_compare(NULL, NULL) AS result;
|
||||||
@ -222,37 +232,40 @@ 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)', 5, NULL) AS result;
|
||||||
SELECT test_bms_add_range('(b 5)', NULL, 10) AS result;
|
SELECT test_bms_add_range('(b 5)', NULL, 10) AS result;
|
||||||
SELECT test_bms_add_range('(b 5)', NULL, NULL) 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, 5, 10) AS result;
|
||||||
SELECT test_bms_add_range(NULL, 10, 5) AS result;
|
SELECT test_bms_add_range(NULL, 10, 5) AS result;
|
||||||
|
SELECT test_bms_add_range(NULL, NULL, NULL) AS result;
|
||||||
|
|
||||||
-- bms_membership()
|
-- bms_membership()
|
||||||
SELECT test_bms_membership('(b)') AS result;
|
SELECT test_bms_membership('(b)') AS result;
|
||||||
SELECT test_bms_membership('(b 42)') AS result;
|
SELECT test_bms_membership('(b 42)') AS result;
|
||||||
SELECT test_bms_membership('(b 1 2)') AS result;
|
SELECT test_bms_membership('(b 1 2)') AS result;
|
||||||
-- NULL input
|
-- Test module check
|
||||||
SELECT test_bms_membership(NULL) AS result;
|
SELECT test_bms_membership(NULL) AS result;
|
||||||
|
|
||||||
-- bms_is_empty()
|
-- bms_is_empty()
|
||||||
SELECT test_bms_is_empty(NULL) AS result;
|
SELECT test_bms_is_empty(NULL) AS result;
|
||||||
SELECT test_bms_is_empty('(b)') AS result;
|
SELECT test_bms_is_empty('(b)') AS result;
|
||||||
SELECT test_bms_is_empty('(b 1)') 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()
|
-- bms_singleton_member()
|
||||||
SELECT test_bms_singleton_member('(b)'); -- error
|
SELECT test_bms_singleton_member('(b)'); -- error
|
||||||
SELECT test_bms_singleton_member('(b 1 2)'); -- error
|
SELECT test_bms_singleton_member('(b 1 2)'); -- error
|
||||||
SELECT test_bms_singleton_member('(b 42)') AS result;
|
SELECT test_bms_singleton_member('(b 42)') AS result;
|
||||||
-- NULL input
|
-- Test module check
|
||||||
SELECT test_bms_singleton_member(NULL) AS result;
|
SELECT test_bms_singleton_member(NULL) AS result;
|
||||||
|
|
||||||
-- bms_get_singleton_member()
|
-- bms_get_singleton_member()
|
||||||
SELECT test_bms_get_singleton_member('(b)');
|
SELECT test_bms_get_singleton_member('(b)', 1000);
|
||||||
-- Try with an empty set
|
|
||||||
SELECT test_bms_get_singleton_member(NULL) AS result;
|
|
||||||
-- Not a singleton, returns input default
|
-- Not a singleton, returns input default
|
||||||
SELECT test_bms_get_singleton_member('(b 3 6)') AS result;
|
SELECT test_bms_get_singleton_member('(b 3 6)', 1000) AS result;
|
||||||
-- Singletone, returns sole member
|
-- Singletone, returns sole member
|
||||||
SELECT test_bms_get_singleton_member('(b 400)') AS result;
|
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;
|
||||||
|
|
||||||
-- bms_next_member() and bms_prev_member()
|
-- bms_next_member() and bms_prev_member()
|
||||||
-- First member
|
-- First member
|
||||||
@ -273,25 +286,27 @@ SELECT test_bms_prev_member('(b 5 10 15 20)', 5) AS result;
|
|||||||
SELECT test_bms_prev_member('(b)', 100) AS result;
|
SELECT test_bms_prev_member('(b)', 100) AS result;
|
||||||
-- Negative prevbit should result in highest possible bit in set
|
-- Negative prevbit should result in highest possible bit in set
|
||||||
SELECT test_bms_prev_member('(b 0 63 64 127)', -1) AS result;
|
SELECT test_bms_prev_member('(b 0 63 64 127)', -1) AS result;
|
||||||
-- NULL inputs
|
-- Test module checks
|
||||||
|
SELECT test_bms_next_member('', 5) AS result;
|
||||||
|
SELECT test_bms_next_member('(b 5)', NULL) AS result;
|
||||||
SELECT test_bms_next_member(NULL, 5) AS result;
|
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;
|
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()
|
-- bms_hash_value()
|
||||||
SELECT test_bms_hash_value('(b)') = 0 AS result;
|
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 1 3 5)') AS result;
|
||||||
SELECT test_bms_hash_value('(b 1 3 5)') != test_bms_hash_value('(b 2 4 6)') AS result;
|
SELECT test_bms_hash_value('(b 1 3 5)') != test_bms_hash_value('(b 2 4 6)') AS result;
|
||||||
-- NULL input
|
-- Test module check
|
||||||
SELECT test_bms_hash_value(NULL) AS result;
|
SELECT test_bms_hash_value(NULL) AS result;
|
||||||
|
|
||||||
-- bms_overlap()
|
-- 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 3 5 7)') AS result;
|
||||||
SELECT test_bms_overlap('(b 1 3 5)', '(b 2 4 6)') 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;
|
SELECT test_bms_overlap('(b)', '(b 1 3 5)') AS result;
|
||||||
-- NULL inputs
|
-- Test module checks
|
||||||
SELECT test_bms_overlap('(b 5)', NULL) AS result;
|
SELECT test_bms_overlap('(b 5)', NULL) AS result;
|
||||||
SELECT test_bms_overlap(NULL, '(b 5)') AS result;
|
SELECT test_bms_overlap(NULL, '(b 5)') AS result;
|
||||||
SELECT test_bms_overlap(NULL, NULL) AS result;
|
SELECT test_bms_overlap(NULL, NULL) AS result;
|
||||||
@ -306,7 +321,7 @@ SELECT test_bms_is_subset(test_bms_add_range(NULL, 0, 31),
|
|||||||
-- Is subset with shorter word counts?
|
-- Is subset with shorter word counts?
|
||||||
SELECT test_bms_is_subset('(b 5 100)', '(b 5)') AS result;
|
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;
|
SELECT test_bms_is_subset('(b 1 2 50 100)', '(b 1 2)') AS result;
|
||||||
-- NULL inputs
|
-- Test module checks
|
||||||
SELECT test_bms_is_subset('(b 5)', NULL) AS result;
|
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, '(b 5)') AS result;
|
||||||
SELECT test_bms_is_subset(NULL, NULL) AS result;
|
SELECT test_bms_is_subset(NULL, NULL) AS result;
|
||||||
@ -335,10 +350,16 @@ 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 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 1 64 65)', '(b 1 2 64)') AS result;
|
||||||
SELECT test_bms_subset_compare('(b 2 64 128)', '(b 1 65)') 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()
|
-- bms_copy()
|
||||||
SELECT test_bms_copy(NULL) AS result;
|
SELECT test_bms_copy(NULL) AS result;
|
||||||
SELECT test_bms_copy('(b 1 3 5 7)') 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()
|
-- bms_add_members()
|
||||||
SELECT test_bms_add_members('(b 1 3)', '(b 5 7)') AS result;
|
SELECT test_bms_add_members('(b 1 3)', '(b 5 7)') AS result;
|
||||||
@ -367,7 +388,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;
|
test_bms_equal('(b 1 3 5)', '(b 2 4 6)') AS result;
|
||||||
SELECT (test_bitmap_match('(b)', '(b)') = 0) =
|
SELECT (test_bitmap_match('(b)', '(b)') = 0) =
|
||||||
test_bms_equal('(b)', '(b)') AS result;
|
test_bms_equal('(b)', '(b)') AS result;
|
||||||
-- NULL inputs
|
-- Test module checks
|
||||||
SELECT test_bitmap_match('(b 5)', NULL) AS result;
|
SELECT test_bitmap_match('(b 5)', NULL) AS result;
|
||||||
SELECT test_bitmap_match(NULL, '(b 5)') AS result;
|
SELECT test_bitmap_match(NULL, '(b 5)') AS result;
|
||||||
SELECT test_bitmap_match(NULL, NULL) AS result;
|
SELECT test_bitmap_match(NULL, NULL) AS result;
|
||||||
@ -383,7 +404,7 @@ SELECT test_bms_overlap_list('(b 1)', ARRAY[]::integer[]) AS result;
|
|||||||
-- Overlap list with negative numbers
|
-- 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 5 10)', ARRAY[-1,5]) AS result; -- error
|
||||||
SELECT test_bms_overlap_list('(b 1 2 3)', ARRAY[-5,-1,0]) AS result; -- error
|
SELECT test_bms_overlap_list('(b 1 2 3)', ARRAY[-5,-1,0]) AS result; -- error
|
||||||
-- NULL inputs
|
-- Test module checks
|
||||||
SELECT test_bms_overlap_list('(b 5)', NULL) AS result;
|
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, ARRAY[1,2,3]) AS result;
|
||||||
SELECT test_bms_overlap_list(NULL, NULL) AS result;
|
SELECT test_bms_overlap_list(NULL, NULL) AS result;
|
||||||
@ -391,7 +412,6 @@ SELECT test_bms_overlap_list(NULL, NULL) AS result;
|
|||||||
-- bms_nonempty_difference()
|
-- bms_nonempty_difference()
|
||||||
SELECT test_bms_nonempty_difference(NULL, '(b 1 3 5)') AS result;
|
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('(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 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 5)') AS result;
|
||||||
SELECT test_bms_nonempty_difference('(b 1 3 5)', '(b 1 3 5)') AS result;
|
SELECT test_bms_nonempty_difference('(b 1 3 5)', '(b 1 3 5)') AS result;
|
||||||
@ -399,6 +419,10 @@ 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 5)', '(b 100)') AS result;
|
||||||
SELECT test_bms_nonempty_difference('(b 100)', '(b 5)') 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;
|
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
|
-- random operations
|
||||||
SELECT test_random_operations(-1, 10000, 81920, 0) > 0 AS result;
|
SELECT test_random_operations(-1, 10000, 81920, 0) > 0 AS result;
|
||||||
|
@ -68,7 +68,7 @@ CREATE FUNCTION test_bms_singleton_member(text)
|
|||||||
RETURNS integer STRICT
|
RETURNS integer STRICT
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C;
|
AS 'MODULE_PATHNAME' LANGUAGE C;
|
||||||
|
|
||||||
CREATE FUNCTION test_bms_get_singleton_member(text)
|
CREATE FUNCTION test_bms_get_singleton_member(text, integer)
|
||||||
RETURNS integer
|
RETURNS integer
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE C;
|
AS 'MODULE_PATHNAME' LANGUAGE C;
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "nodes/pg_list.h"
|
#include "nodes/pg_list.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/timestamp.h"
|
#include "utils/timestamp.h"
|
||||||
|
#include "varatt.h"
|
||||||
|
|
||||||
PG_MODULE_MAGIC;
|
PG_MODULE_MAGIC;
|
||||||
|
|
||||||
@ -87,305 +88,465 @@ PG_FUNCTION_INFO_V1(test_random_operations);
|
|||||||
#define BITMAPSET_TO_TEXT(bms) cstring_to_text(nodeToString(bms))
|
#define BITMAPSET_TO_TEXT(bms) cstring_to_text(nodeToString(bms))
|
||||||
#define TEXT_TO_BITMAPSET(str) ((Bitmapset *) stringToNode(text_to_cstring(str)))
|
#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, returning the
|
|
||||||
* resulting text representation of the set.
|
|
||||||
*/
|
|
||||||
#define PG_RETURN_BITMAPSET_AS_TEXT(bms) \
|
|
||||||
PG_RETURN_TEXT_P(BITMAPSET_TO_TEXT(bms))
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Individual test functions for each bitmapset API function
|
* 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
|
Datum
|
||||||
test_bms_add_member(PG_FUNCTION_ARGS)
|
test_bms_add_member(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms;
|
|
||||||
int member;
|
int member;
|
||||||
|
Bitmapset *bms = NULL;
|
||||||
|
text *result;
|
||||||
|
|
||||||
if (PG_ARGISNULL(1))
|
if (PG_ARGISNULL(1))
|
||||||
PG_RETURN_NULL(); /* invalid input */
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
|
if (!PG_ARGISNULL(0))
|
||||||
|
bms = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
|
||||||
|
|
||||||
bms = PG_ARG_GETBITMAPSET(0);
|
|
||||||
member = PG_GETARG_INT32(1);
|
member = PG_GETARG_INT32(1);
|
||||||
|
|
||||||
bms = bms_add_member(bms, member);
|
bms = bms_add_member(bms, member);
|
||||||
|
result = BITMAPSET_TO_TEXT(bms);
|
||||||
|
|
||||||
PG_RETURN_BITMAPSET_AS_TEXT(bms);
|
if (bms)
|
||||||
|
bms_free(bms);
|
||||||
|
|
||||||
|
PG_RETURN_TEXT_P(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bms_add_members(PG_FUNCTION_ARGS)
|
test_bms_add_members(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
|
Bitmapset *bms1 = NULL,
|
||||||
Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
|
*bms2 = NULL;
|
||||||
|
text *result;
|
||||||
|
|
||||||
/* left input is recycled */
|
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_add_members modifies/frees the first argument */
|
||||||
bms1 = bms_add_members(bms1, bms2);
|
bms1 = bms_add_members(bms1, bms2);
|
||||||
|
|
||||||
PG_RETURN_BITMAPSET_AS_TEXT(bms1);
|
if (bms2)
|
||||||
|
bms_free(bms2);
|
||||||
|
|
||||||
|
result = BITMAPSET_TO_TEXT(bms1);
|
||||||
|
bms_free(bms1);
|
||||||
|
|
||||||
|
PG_RETURN_TEXT_P(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bms_del_member(PG_FUNCTION_ARGS)
|
test_bms_del_member(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms;
|
Bitmapset *bms = NULL;
|
||||||
int32 member;
|
int32 member;
|
||||||
|
text *result;
|
||||||
|
|
||||||
if (PG_ARGISNULL(1))
|
if (PG_ARGISNULL(1))
|
||||||
PG_RETURN_NULL(); /* invalid input */
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
|
if (!PG_ARGISNULL(0))
|
||||||
|
bms = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
|
||||||
|
|
||||||
bms = PG_ARG_GETBITMAPSET(0);
|
|
||||||
member = PG_GETARG_INT32(1);
|
member = PG_GETARG_INT32(1);
|
||||||
|
|
||||||
bms = bms_del_member(bms, member);
|
bms = bms_del_member(bms, member);
|
||||||
|
|
||||||
PG_RETURN_BITMAPSET_AS_TEXT(bms);
|
if (bms_is_empty(bms))
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
|
result = BITMAPSET_TO_TEXT(bms);
|
||||||
|
bms_free(bms);
|
||||||
|
|
||||||
|
PG_RETURN_TEXT_P(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bms_is_member(PG_FUNCTION_ARGS)
|
test_bms_is_member(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms;
|
Bitmapset *bms = NULL;
|
||||||
int32 member;
|
int32 member;
|
||||||
bool result;
|
bool result;
|
||||||
|
|
||||||
if (PG_ARGISNULL(1))
|
if (PG_ARGISNULL(1))
|
||||||
PG_RETURN_NULL(); /* invalid input */
|
PG_RETURN_BOOL(false);
|
||||||
|
|
||||||
|
if (!PG_ARGISNULL(0))
|
||||||
|
bms = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
|
||||||
|
|
||||||
bms = PG_ARG_GETBITMAPSET(0);
|
|
||||||
member = PG_GETARG_INT32(1);
|
member = PG_GETARG_INT32(1);
|
||||||
|
|
||||||
result = bms_is_member(member, bms);
|
result = bms_is_member(member, bms);
|
||||||
|
|
||||||
|
if (bms)
|
||||||
|
bms_free(bms);
|
||||||
|
|
||||||
PG_RETURN_BOOL(result);
|
PG_RETURN_BOOL(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bms_num_members(PG_FUNCTION_ARGS)
|
test_bms_num_members(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms = PG_ARG_GETBITMAPSET(0);
|
Bitmapset *bms = NULL;
|
||||||
int result;
|
int result = 0;
|
||||||
|
|
||||||
|
if (!PG_ARGISNULL(0))
|
||||||
|
bms = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
|
||||||
|
|
||||||
result = bms_num_members(bms);
|
result = bms_num_members(bms);
|
||||||
|
|
||||||
|
if (bms)
|
||||||
|
bms_free(bms);
|
||||||
|
|
||||||
PG_RETURN_INT32(result);
|
PG_RETURN_INT32(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bms_make_singleton(PG_FUNCTION_ARGS)
|
test_bms_make_singleton(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms;
|
|
||||||
int32 member;
|
int32 member;
|
||||||
|
Bitmapset *bms;
|
||||||
|
text *result;
|
||||||
|
|
||||||
if (PG_ARGISNULL(0))
|
if (PG_ARGISNULL(0))
|
||||||
PG_RETURN_NULL(); /* invalid input */
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
member = PG_GETARG_INT32(0);
|
member = PG_GETARG_INT32(0);
|
||||||
bms = bms_make_singleton(member);
|
bms = bms_make_singleton(member);
|
||||||
|
|
||||||
PG_RETURN_BITMAPSET_AS_TEXT(bms);
|
result = BITMAPSET_TO_TEXT(bms);
|
||||||
|
bms_free(bms);
|
||||||
|
|
||||||
|
PG_RETURN_TEXT_P(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bms_copy(PG_FUNCTION_ARGS)
|
test_bms_copy(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms = PG_ARG_GETBITMAPSET(0);
|
text *bms_data;
|
||||||
|
Bitmapset *bms = NULL;
|
||||||
Bitmapset *copy_bms;
|
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);
|
copy_bms = bms_copy(bms);
|
||||||
|
result = BITMAPSET_TO_TEXT(copy_bms);
|
||||||
|
|
||||||
PG_RETURN_BITMAPSET_AS_TEXT(copy_bms);
|
if (bms)
|
||||||
|
bms_free(bms);
|
||||||
|
if (copy_bms)
|
||||||
|
bms_free(copy_bms);
|
||||||
|
|
||||||
|
PG_RETURN_TEXT_P(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bms_equal(PG_FUNCTION_ARGS)
|
test_bms_equal(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
|
Bitmapset *bms1 = NULL,
|
||||||
Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
|
*bms2 = NULL;
|
||||||
bool result;
|
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);
|
result = bms_equal(bms1, bms2);
|
||||||
|
|
||||||
|
if (bms1)
|
||||||
|
bms_free(bms1);
|
||||||
|
if (bms2)
|
||||||
|
bms_free(bms2);
|
||||||
|
|
||||||
PG_RETURN_BOOL(result);
|
PG_RETURN_BOOL(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bms_union(PG_FUNCTION_ARGS)
|
test_bms_union(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
|
Bitmapset *bms1 = NULL,
|
||||||
Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
|
*bms2 = NULL;
|
||||||
Bitmapset *result_bms;
|
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);
|
result_bms = bms_union(bms1, bms2);
|
||||||
|
|
||||||
PG_RETURN_BITMAPSET_AS_TEXT(result_bms);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bms_membership(PG_FUNCTION_ARGS)
|
test_bms_membership(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms = PG_ARG_GETBITMAPSET(0);
|
Bitmapset *bms = NULL;
|
||||||
BMS_Membership result;
|
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);
|
result = bms_membership(bms);
|
||||||
|
|
||||||
|
if (bms)
|
||||||
|
bms_free(bms);
|
||||||
|
|
||||||
PG_RETURN_INT32((int32) result);
|
PG_RETURN_INT32((int32) result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bms_next_member(PG_FUNCTION_ARGS)
|
test_bms_next_member(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms;
|
Bitmapset *bms = NULL;
|
||||||
int32 prevmember;
|
int32 prevmember;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (PG_ARGISNULL(1))
|
if (PG_ARGISNULL(0) || PG_ARGISNULL(1))
|
||||||
PG_RETURN_NULL(); /* invalid input */
|
PG_RETURN_INT32(-2);
|
||||||
|
|
||||||
bms = PG_ARG_GETBITMAPSET(0);
|
bms = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
|
||||||
prevmember = PG_GETARG_INT32(1);
|
prevmember = PG_GETARG_INT32(1);
|
||||||
|
|
||||||
result = bms_next_member(bms, prevmember);
|
result = bms_next_member(bms, prevmember);
|
||||||
|
|
||||||
|
if (bms)
|
||||||
|
bms_free(bms);
|
||||||
|
|
||||||
PG_RETURN_INT32(result);
|
PG_RETURN_INT32(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bms_intersect(PG_FUNCTION_ARGS)
|
test_bms_intersect(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
|
Bitmapset *bms1 = NULL,
|
||||||
Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
|
*bms2 = NULL;
|
||||||
Bitmapset *result_bms;
|
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);
|
result_bms = bms_intersect(bms1, bms2);
|
||||||
|
|
||||||
PG_RETURN_BITMAPSET_AS_TEXT(result_bms);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bms_difference(PG_FUNCTION_ARGS)
|
test_bms_difference(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
|
Bitmapset *bms1 = NULL,
|
||||||
Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
|
*bms2 = NULL;
|
||||||
Bitmapset *result_bms;
|
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);
|
result_bms = bms_difference(bms1, bms2);
|
||||||
|
|
||||||
PG_RETURN_BITMAPSET_AS_TEXT(result_bms);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bms_compare(PG_FUNCTION_ARGS)
|
test_bms_compare(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
|
Bitmapset *bms1 = NULL,
|
||||||
Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
|
*bms2 = NULL;
|
||||||
int result;
|
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);
|
result = bms_compare(bms1, bms2);
|
||||||
|
|
||||||
|
if (bms1)
|
||||||
|
bms_free(bms1);
|
||||||
|
if (bms2)
|
||||||
|
bms_free(bms2);
|
||||||
|
|
||||||
PG_RETURN_INT32(result);
|
PG_RETURN_INT32(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bms_is_empty(PG_FUNCTION_ARGS)
|
test_bms_is_empty(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms = PG_ARG_GETBITMAPSET(0);
|
Bitmapset *bms = NULL;
|
||||||
bool result;
|
bool result;
|
||||||
|
|
||||||
|
if (!PG_ARGISNULL(0))
|
||||||
|
bms = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
|
||||||
|
|
||||||
result = bms_is_empty(bms);
|
result = bms_is_empty(bms);
|
||||||
|
|
||||||
|
if (bms)
|
||||||
|
bms_free(bms);
|
||||||
|
|
||||||
PG_RETURN_BOOL(result);
|
PG_RETURN_BOOL(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bms_is_subset(PG_FUNCTION_ARGS)
|
test_bms_is_subset(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
|
Bitmapset *bms1 = NULL,
|
||||||
Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
|
*bms2 = NULL;
|
||||||
bool result;
|
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);
|
result = bms_is_subset(bms1, bms2);
|
||||||
|
|
||||||
|
if (bms1)
|
||||||
|
bms_free(bms1);
|
||||||
|
if (bms2)
|
||||||
|
bms_free(bms2);
|
||||||
|
|
||||||
PG_RETURN_BOOL(result);
|
PG_RETURN_BOOL(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bms_subset_compare(PG_FUNCTION_ARGS)
|
test_bms_subset_compare(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
|
Bitmapset *bms1 = NULL,
|
||||||
Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
|
*bms2 = NULL;
|
||||||
BMS_Comparison result;
|
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);
|
result = bms_subset_compare(bms1, bms2);
|
||||||
|
|
||||||
|
if (bms1)
|
||||||
|
bms_free(bms1);
|
||||||
|
if (bms2)
|
||||||
|
bms_free(bms2);
|
||||||
|
|
||||||
PG_RETURN_INT32((int32) result);
|
PG_RETURN_INT32((int32) result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bms_singleton_member(PG_FUNCTION_ARGS)
|
test_bms_singleton_member(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms = PG_ARG_GETBITMAPSET(0);
|
Bitmapset *bms = NULL;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
if (!PG_ARGISNULL(0))
|
||||||
|
bms = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
|
||||||
|
|
||||||
result = bms_singleton_member(bms);
|
result = bms_singleton_member(bms);
|
||||||
|
|
||||||
|
if (bms)
|
||||||
|
bms_free(bms);
|
||||||
|
|
||||||
PG_RETURN_INT32(result);
|
PG_RETURN_INT32(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bms_get_singleton_member(PG_FUNCTION_ARGS)
|
test_bms_get_singleton_member(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms = PG_ARG_GETBITMAPSET(0);
|
Bitmapset *bms = NULL;
|
||||||
int member;
|
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));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Keep this simple. Return -1 when we detect the set is not a singleton
|
* bms_get_singleton_member returns bool and stores result in member
|
||||||
* set, otherwise return the singleton member.
|
* pointer
|
||||||
*/
|
*/
|
||||||
if (!bms_get_singleton_member(bms, &member))
|
success = bms_get_singleton_member(bms, &member);
|
||||||
member = -1;
|
bms_free(bms);
|
||||||
|
|
||||||
PG_RETURN_INT32(member);
|
if (success)
|
||||||
|
PG_RETURN_INT32(member);
|
||||||
|
|
||||||
|
PG_RETURN_INT32(default_member);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bms_prev_member(PG_FUNCTION_ARGS)
|
test_bms_prev_member(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms;
|
text *bms_data;
|
||||||
|
Bitmapset *bms = NULL;
|
||||||
int32 prevmember;
|
int32 prevmember;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (PG_ARGISNULL(1))
|
if (PG_ARGISNULL(0))
|
||||||
PG_RETURN_NULL(); /* invalid input */
|
PG_RETURN_INT32(-2);
|
||||||
|
|
||||||
bms = PG_ARG_GETBITMAPSET(0);
|
bms_data = PG_GETARG_TEXT_PP(0);
|
||||||
prevmember = PG_GETARG_INT32(1);
|
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);
|
result = bms_prev_member(bms, prevmember);
|
||||||
|
bms_free(bms);
|
||||||
|
|
||||||
PG_RETURN_INT32(result);
|
PG_RETURN_INT32(result);
|
||||||
}
|
}
|
||||||
@ -393,57 +554,75 @@ test_bms_prev_member(PG_FUNCTION_ARGS)
|
|||||||
Datum
|
Datum
|
||||||
test_bms_overlap(PG_FUNCTION_ARGS)
|
test_bms_overlap(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
|
Bitmapset *bms1 = NULL,
|
||||||
Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
|
*bms2 = NULL;
|
||||||
bool result;
|
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);
|
result = bms_overlap(bms1, bms2);
|
||||||
|
|
||||||
|
if (bms1)
|
||||||
|
bms_free(bms1);
|
||||||
|
if (bms2)
|
||||||
|
bms_free(bms2);
|
||||||
|
|
||||||
PG_RETURN_BOOL(result);
|
PG_RETURN_BOOL(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bms_overlap_list(PG_FUNCTION_ARGS)
|
test_bms_overlap_list(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms;
|
Bitmapset *bms = NULL;
|
||||||
ArrayType *array;
|
ArrayType *array;
|
||||||
List *int_list = NIL;
|
List *int_list = NIL;
|
||||||
bool result;
|
bool result;
|
||||||
Datum *elem_datums = NULL;
|
Datum *elem_datums;
|
||||||
bool *elem_nulls = NULL;
|
bool *elem_nulls;
|
||||||
int elem_count;
|
int elem_count;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
bms = PG_ARG_GETBITMAPSET(0);
|
if (PG_ARGISNULL(0))
|
||||||
|
PG_RETURN_BOOL(false);
|
||||||
|
|
||||||
if (!PG_ARGISNULL(1))
|
bms = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
|
||||||
|
|
||||||
|
if (PG_ARGISNULL(1))
|
||||||
{
|
{
|
||||||
array = PG_GETARG_ARRAYTYPE_P(1);
|
if (bms)
|
||||||
|
bms_free(bms);
|
||||||
|
PG_RETURN_BOOL(false);
|
||||||
|
}
|
||||||
|
|
||||||
deconstruct_array(array,
|
array = PG_GETARG_ARRAYTYPE_P(1);
|
||||||
INT4OID, sizeof(int32), true, 'i',
|
|
||||||
&elem_datums, &elem_nulls, &elem_count);
|
|
||||||
|
|
||||||
for (i = 0; i < elem_count; i++)
|
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])
|
||||||
{
|
{
|
||||||
if (!elem_nulls[i])
|
int32 member = DatumGetInt32(elem_datums[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);
|
result = bms_overlap_list(bms, int_list);
|
||||||
|
|
||||||
|
if (bms)
|
||||||
|
bms_free(bms);
|
||||||
|
|
||||||
list_free(int_list);
|
list_free(int_list);
|
||||||
|
|
||||||
if (elem_datums)
|
pfree(elem_datums);
|
||||||
pfree(elem_datums);
|
pfree(elem_nulls);
|
||||||
|
|
||||||
if (elem_nulls)
|
|
||||||
pfree(elem_nulls);
|
|
||||||
|
|
||||||
PG_RETURN_BOOL(result);
|
PG_RETURN_BOOL(result);
|
||||||
}
|
}
|
||||||
@ -451,29 +630,47 @@ test_bms_overlap_list(PG_FUNCTION_ARGS)
|
|||||||
Datum
|
Datum
|
||||||
test_bms_nonempty_difference(PG_FUNCTION_ARGS)
|
test_bms_nonempty_difference(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
|
Bitmapset *bms1 = NULL,
|
||||||
Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
|
*bms2 = NULL;
|
||||||
bool result;
|
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);
|
result = bms_nonempty_difference(bms1, bms2);
|
||||||
|
|
||||||
|
if (bms1)
|
||||||
|
bms_free(bms1);
|
||||||
|
if (bms2)
|
||||||
|
bms_free(bms2);
|
||||||
|
|
||||||
PG_RETURN_BOOL(result);
|
PG_RETURN_BOOL(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bms_member_index(PG_FUNCTION_ARGS)
|
test_bms_member_index(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms;
|
text *bms_data;
|
||||||
|
Bitmapset *bms = NULL;
|
||||||
int32 member;
|
int32 member;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (PG_ARGISNULL(1))
|
if (PG_ARGISNULL(0))
|
||||||
PG_RETURN_NULL(); /* invalid input */
|
PG_RETURN_INT32(-1);
|
||||||
|
|
||||||
bms = PG_ARG_GETBITMAPSET(0);
|
bms_data = PG_GETARG_TEXT_PP(0);
|
||||||
member = PG_GETARG_INT32(1);
|
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);
|
result = bms_member_index(bms, member);
|
||||||
|
bms_free(bms);
|
||||||
|
|
||||||
PG_RETURN_INT32(result);
|
PG_RETURN_INT32(result);
|
||||||
}
|
}
|
||||||
@ -481,92 +678,191 @@ test_bms_member_index(PG_FUNCTION_ARGS)
|
|||||||
Datum
|
Datum
|
||||||
test_bms_add_range(PG_FUNCTION_ARGS)
|
test_bms_add_range(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms;
|
Bitmapset *bms = NULL;
|
||||||
int32 lower,
|
int32 lower,
|
||||||
upper;
|
upper;
|
||||||
|
text *result;
|
||||||
|
|
||||||
if (PG_ARGISNULL(1) || PG_ARGISNULL(2))
|
if (PG_ARGISNULL(1) || PG_ARGISNULL(2))
|
||||||
PG_RETURN_NULL(); /* invalid input */
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
|
if (!PG_ARGISNULL(0))
|
||||||
|
bms = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
|
||||||
|
|
||||||
bms = PG_ARG_GETBITMAPSET(0);
|
|
||||||
lower = PG_GETARG_INT32(1);
|
lower = PG_GETARG_INT32(1);
|
||||||
upper = PG_GETARG_INT32(2);
|
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);
|
bms = bms_add_range(bms, lower, upper);
|
||||||
|
|
||||||
PG_RETURN_BITMAPSET_AS_TEXT(bms);
|
result = BITMAPSET_TO_TEXT(bms);
|
||||||
|
if (bms)
|
||||||
|
bms_free(bms);
|
||||||
|
|
||||||
|
PG_RETURN_TEXT_P(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bms_int_members(PG_FUNCTION_ARGS)
|
test_bms_int_members(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
|
Bitmapset *bms1 = NULL,
|
||||||
Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
|
*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));
|
||||||
|
|
||||||
/* left input gets recycled */
|
|
||||||
bms1 = bms_int_members(bms1, bms2);
|
bms1 = bms_int_members(bms1, bms2);
|
||||||
|
|
||||||
PG_RETURN_BITMAPSET_AS_TEXT(bms1);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bms_del_members(PG_FUNCTION_ARGS)
|
test_bms_del_members(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
|
Bitmapset *bms1 = NULL,
|
||||||
Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
|
*bms2 = NULL;
|
||||||
|
Bitmapset *result_bms;
|
||||||
|
text *result;
|
||||||
|
|
||||||
/* left input gets recycled */
|
if (!PG_ARGISNULL(0))
|
||||||
bms1 = bms_del_members(bms1, bms2);
|
bms1 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
|
||||||
|
|
||||||
PG_RETURN_BITMAPSET_AS_TEXT(bms1);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bms_replace_members(PG_FUNCTION_ARGS)
|
test_bms_replace_members(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
|
Bitmapset *bms1 = NULL,
|
||||||
Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
|
*bms2 = NULL;
|
||||||
|
Bitmapset *result_bms;
|
||||||
|
text *result;
|
||||||
|
|
||||||
/* left input gets recycled */
|
if (!PG_ARGISNULL(0))
|
||||||
bms1 = bms_replace_members(bms1, bms2);
|
bms1 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
|
||||||
|
|
||||||
PG_RETURN_BITMAPSET_AS_TEXT(bms1);
|
if (!PG_ARGISNULL(1))
|
||||||
|
bms2 = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(1));
|
||||||
|
|
||||||
|
/* IMPORTANT: bms_replace_members modifies/frees the first argument */
|
||||||
|
result_bms = 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bms_join(PG_FUNCTION_ARGS)
|
test_bms_join(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
|
Bitmapset *bms1 = NULL,
|
||||||
Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
|
*bms2 = NULL;
|
||||||
Bitmapset *result_bms;
|
Bitmapset *result_bms;
|
||||||
|
text *result;
|
||||||
|
|
||||||
/* either input can be recycled */
|
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 */
|
||||||
result_bms = bms_join(bms1, bms2);
|
result_bms = bms_join(bms1, bms2);
|
||||||
|
|
||||||
/* memory cleanup seems more tricky than it's worth here */
|
/* bms1 and bms2 may have been recycled! Do not free any of them. */
|
||||||
|
|
||||||
PG_RETURN_BITMAPSET_AS_TEXT(result_bms);
|
if (result_bms == NULL)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
|
result = BITMAPSET_TO_TEXT(result_bms);
|
||||||
|
bms_free(result_bms);
|
||||||
|
|
||||||
|
PG_RETURN_TEXT_P(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bms_hash_value(PG_FUNCTION_ARGS)
|
test_bms_hash_value(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms = PG_ARG_GETBITMAPSET(0);
|
Bitmapset *bms = NULL;
|
||||||
uint32 hash_result;
|
uint32 hash_result;
|
||||||
|
|
||||||
|
if (!PG_ARGISNULL(0))
|
||||||
|
bms = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
|
||||||
|
|
||||||
hash_result = bms_hash_value(bms);
|
hash_result = bms_hash_value(bms);
|
||||||
|
|
||||||
|
if (bms)
|
||||||
|
bms_free(bms);
|
||||||
|
|
||||||
PG_RETURN_INT32(hash_result);
|
PG_RETURN_INT32(hash_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
test_bitmap_hash(PG_FUNCTION_ARGS)
|
test_bitmap_hash(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms = PG_ARG_GETBITMAPSET(0);
|
Bitmapset *bms = NULL;
|
||||||
|
Bitmapset *bms_ptr;
|
||||||
uint32 hash_result;
|
uint32 hash_result;
|
||||||
|
|
||||||
|
if (!PG_ARGISNULL(0))
|
||||||
|
bms = TEXT_TO_BITMAPSET(PG_GETARG_TEXT_PP(0));
|
||||||
|
|
||||||
|
bms_ptr = bms;
|
||||||
|
|
||||||
/* Call bitmap_hash */
|
/* Call bitmap_hash */
|
||||||
hash_result = bitmap_hash(&bms, sizeof(Bitmapset *));
|
hash_result = bitmap_hash(&bms_ptr, sizeof(Bitmapset *));
|
||||||
|
|
||||||
|
/* Clean up */
|
||||||
|
if (!PG_ARGISNULL(0) && bms_ptr)
|
||||||
|
bms_free(bms_ptr);
|
||||||
|
|
||||||
PG_RETURN_INT32(hash_result);
|
PG_RETURN_INT32(hash_result);
|
||||||
}
|
}
|
||||||
@ -574,12 +870,30 @@ test_bitmap_hash(PG_FUNCTION_ARGS)
|
|||||||
Datum
|
Datum
|
||||||
test_bitmap_match(PG_FUNCTION_ARGS)
|
test_bitmap_match(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Bitmapset *bms1 = PG_ARG_GETBITMAPSET(0);
|
Bitmapset *bms1 = NULL,
|
||||||
Bitmapset *bms2 = PG_ARG_GETBITMAPSET(1);
|
*bms2 = NULL;
|
||||||
|
Bitmapset *bms_ptr1,
|
||||||
|
*bms_ptr2;
|
||||||
int match_result;
|
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 */
|
/* Call bitmap_match with addresses of the Bitmapset pointers */
|
||||||
match_result = bitmap_match(&bms1, &bms2, sizeof(Bitmapset *));
|
match_result = bitmap_match(&bms_ptr1, &bms_ptr2, sizeof(Bitmapset *));
|
||||||
|
|
||||||
|
/* Clean up */
|
||||||
|
if (bms1)
|
||||||
|
bms_free(bms1);
|
||||||
|
if (bms2)
|
||||||
|
bms_free(bms2);
|
||||||
|
|
||||||
PG_RETURN_INT32(match_result);
|
PG_RETURN_INT32(match_result);
|
||||||
}
|
}
|
||||||
@ -717,7 +1031,8 @@ test_random_operations(PG_FUNCTION_ARGS)
|
|||||||
total_ops++;
|
total_ops++;
|
||||||
}
|
}
|
||||||
|
|
||||||
bms_free(bms);
|
if (bms)
|
||||||
|
bms_free(bms);
|
||||||
|
|
||||||
PG_RETURN_INT32(total_ops);
|
PG_RETURN_INT32(total_ops);
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,10 @@ This module contains two programs for testing the json parsers.
|
|||||||
- `test_json_parser_incremental` is for testing the incremental parser, It
|
- `test_json_parser_incremental` is for testing the incremental parser, It
|
||||||
reads in a file and passes it in very small chunks (default is 60 bytes at a
|
reads in a file and passes it in very small chunks (default is 60 bytes at a
|
||||||
time) to the incremental parser. It's not meant to be a speed test but to
|
time) to the incremental parser. It's not meant to be a speed test but to
|
||||||
test the accuracy of the incremental parser. The option "-c nn" specifies an
|
test the accuracy of the incremental parser. There are two option arguments,
|
||||||
alternative chunk size, "-r nn" runs a range of chunk sizes down to one byte
|
"-c nn" specifies an alternative chunk size, and "-s" specifies using
|
||||||
on the same input (with output separated by null bytes), and "-s" specifies
|
semantic routines. The semantic routines re-output the json, although not in
|
||||||
using semantic routines. The semantic routines re-output the json, although
|
a very pretty form. The required non-option argument is the input file name.
|
||||||
not in a very pretty form. The required non-option argument is the input file
|
|
||||||
name.
|
|
||||||
- `test_json_parser_perf` is for speed testing both the standard
|
- `test_json_parser_perf` is for speed testing both the standard
|
||||||
recursive descent parser and the non-recursive incremental
|
recursive descent parser and the non-recursive incremental
|
||||||
parser. If given the `-i` flag it uses the non-recursive parser,
|
parser. If given the `-i` flag it uses the non-recursive parser,
|
||||||
|
@ -33,37 +33,23 @@ sub test
|
|||||||
print $fh "$json";
|
print $fh "$json";
|
||||||
close($fh);
|
close($fh);
|
||||||
|
|
||||||
# The -r mode runs the parser in a loop, with output separated by nulls.
|
|
||||||
# Unpack that as a list of null-terminated ASCII strings (Z*) and check that
|
|
||||||
# each run produces the same result.
|
|
||||||
my ($all_stdout, $all_stderr) =
|
|
||||||
run_command([ @exe, "-r", $chunk, $fname ]);
|
|
||||||
|
|
||||||
my @stdout = unpack("(Z*)*", $all_stdout);
|
|
||||||
my @stderr = unpack("(Z*)*", $all_stderr);
|
|
||||||
|
|
||||||
is(scalar @stdout, $chunk, "$name: stdout has correct number of entries");
|
|
||||||
is(scalar @stderr, $chunk, "$name: stderr has correct number of entries");
|
|
||||||
|
|
||||||
my $i = 0;
|
|
||||||
|
|
||||||
foreach my $size (reverse(1 .. $chunk))
|
foreach my $size (reverse(1 .. $chunk))
|
||||||
{
|
{
|
||||||
|
my ($stdout, $stderr) = run_command([ @exe, "-c", $size, $fname ]);
|
||||||
|
|
||||||
if (defined($params{error}))
|
if (defined($params{error}))
|
||||||
{
|
{
|
||||||
unlike($stdout[$i], qr/SUCCESS/,
|
unlike($stdout, qr/SUCCESS/,
|
||||||
"$name, chunk size $size: test fails");
|
"$name, chunk size $size: test fails");
|
||||||
like($stderr[$i], $params{error},
|
like($stderr, $params{error},
|
||||||
"$name, chunk size $size: correct error output");
|
"$name, chunk size $size: correct error output");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
like($stdout[$i], qr/SUCCESS/,
|
like($stdout, qr/SUCCESS/,
|
||||||
"$name, chunk size $size: test succeeds");
|
"$name, chunk size $size: test succeeds");
|
||||||
is($stderr[$i], "", "$name, chunk size $size: no error output");
|
is($stderr, "", "$name, chunk size $size: no error output");
|
||||||
}
|
}
|
||||||
|
|
||||||
$i++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,14 +12,9 @@
|
|||||||
* the parser in very small chunks. In practice you would normally use
|
* the parser in very small chunks. In practice you would normally use
|
||||||
* much larger chunks, but doing this makes it more likely that the
|
* much larger chunks, but doing this makes it more likely that the
|
||||||
* full range of increment handling, especially in the lexer, is exercised.
|
* full range of increment handling, especially in the lexer, is exercised.
|
||||||
*
|
|
||||||
* If the "-c SIZE" option is provided, that chunk size is used instead
|
* If the "-c SIZE" option is provided, that chunk size is used instead
|
||||||
* of the default of 60.
|
* of the default of 60.
|
||||||
*
|
*
|
||||||
* If the "-r SIZE" option is provided, a range of chunk sizes from SIZE down to
|
|
||||||
* 1 are run sequentially. A null byte is printed to the streams after each
|
|
||||||
* iteration.
|
|
||||||
*
|
|
||||||
* If the -s flag is given, the program does semantic processing. This should
|
* If the -s flag is given, the program does semantic processing. This should
|
||||||
* just mirror back the json, albeit with white space changes.
|
* just mirror back the json, albeit with white space changes.
|
||||||
*
|
*
|
||||||
@ -93,8 +88,8 @@ main(int argc, char **argv)
|
|||||||
StringInfoData json;
|
StringInfoData json;
|
||||||
int n_read;
|
int n_read;
|
||||||
size_t chunk_size = DEFAULT_CHUNK_SIZE;
|
size_t chunk_size = DEFAULT_CHUNK_SIZE;
|
||||||
bool run_chunk_ranges = false;
|
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
|
off_t bytes_left;
|
||||||
const JsonSemAction *testsem = &nullSemAction;
|
const JsonSemAction *testsem = &nullSemAction;
|
||||||
char *testfile;
|
char *testfile;
|
||||||
int c;
|
int c;
|
||||||
@ -107,14 +102,11 @@ main(int argc, char **argv)
|
|||||||
if (!lex)
|
if (!lex)
|
||||||
pg_fatal("out of memory");
|
pg_fatal("out of memory");
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "r:c:os")) != -1)
|
while ((c = getopt(argc, argv, "c:os")) != -1)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case 'r': /* chunk range */
|
case 'c': /* chunksize */
|
||||||
run_chunk_ranges = true;
|
|
||||||
/* fall through */
|
|
||||||
case 'c': /* chunk size */
|
|
||||||
chunk_size = strtou64(optarg, NULL, 10);
|
chunk_size = strtou64(optarg, NULL, 10);
|
||||||
if (chunk_size > BUFSIZE)
|
if (chunk_size > BUFSIZE)
|
||||||
pg_fatal("chunk size cannot exceed %d", BUFSIZE);
|
pg_fatal("chunk size cannot exceed %d", BUFSIZE);
|
||||||
@ -143,6 +135,8 @@ main(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
makeJsonLexContextIncremental(lex, PG_UTF8, need_strings);
|
||||||
|
setJsonLexContextOwnsTokens(lex, lex_owns_tokens);
|
||||||
initStringInfo(&json);
|
initStringInfo(&json);
|
||||||
|
|
||||||
if ((json_file = fopen(testfile, PG_BINARY_R)) == NULL)
|
if ((json_file = fopen(testfile, PG_BINARY_R)) == NULL)
|
||||||
@ -151,88 +145,61 @@ main(int argc, char **argv)
|
|||||||
if (fstat(fileno(json_file), &statbuf) != 0)
|
if (fstat(fileno(json_file), &statbuf) != 0)
|
||||||
pg_fatal("error statting input: %m");
|
pg_fatal("error statting input: %m");
|
||||||
|
|
||||||
do
|
bytes_left = statbuf.st_size;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
{
|
{
|
||||||
|
/* We will break when there's nothing left to read */
|
||||||
|
|
||||||
|
if (bytes_left < chunk_size)
|
||||||
|
chunk_size = bytes_left;
|
||||||
|
|
||||||
|
n_read = fread(buff, 1, chunk_size, json_file);
|
||||||
|
if (n_read < chunk_size)
|
||||||
|
pg_fatal("error reading input file: %d", ferror(json_file));
|
||||||
|
|
||||||
|
appendBinaryStringInfo(&json, buff, n_read);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This outer loop only repeats in -r mode. Reset the parse state and
|
* Append some trailing junk to the buffer passed to the parser. This
|
||||||
* our position in the input file for the inner loop, which performs
|
* helps us ensure that the parser does the right thing even if the
|
||||||
* the incremental parsing.
|
* chunk isn't terminated with a '\0'.
|
||||||
*/
|
*/
|
||||||
off_t bytes_left = statbuf.st_size;
|
appendStringInfoString(&json, "1+23 trailing junk");
|
||||||
size_t to_read = chunk_size;
|
bytes_left -= n_read;
|
||||||
|
if (bytes_left > 0)
|
||||||
makeJsonLexContextIncremental(lex, PG_UTF8, need_strings);
|
|
||||||
setJsonLexContextOwnsTokens(lex, lex_owns_tokens);
|
|
||||||
|
|
||||||
rewind(json_file);
|
|
||||||
resetStringInfo(&json);
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
{
|
||||||
/* We will break when there's nothing left to read */
|
result = pg_parse_json_incremental(lex, testsem,
|
||||||
|
json.data, n_read,
|
||||||
if (bytes_left < to_read)
|
false);
|
||||||
to_read = bytes_left;
|
if (result != JSON_INCOMPLETE)
|
||||||
|
|
||||||
n_read = fread(buff, 1, to_read, json_file);
|
|
||||||
if (n_read < to_read)
|
|
||||||
pg_fatal("error reading input file: %d", ferror(json_file));
|
|
||||||
|
|
||||||
appendBinaryStringInfo(&json, buff, n_read);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Append some trailing junk to the buffer passed to the parser.
|
|
||||||
* This helps us ensure that the parser does the right thing even
|
|
||||||
* if the chunk isn't terminated with a '\0'.
|
|
||||||
*/
|
|
||||||
appendStringInfoString(&json, "1+23 trailing junk");
|
|
||||||
bytes_left -= n_read;
|
|
||||||
if (bytes_left > 0)
|
|
||||||
{
|
{
|
||||||
result = pg_parse_json_incremental(lex, testsem,
|
fprintf(stderr, "%s\n", json_errdetail(result, lex));
|
||||||
json.data, n_read,
|
ret = 1;
|
||||||
false);
|
goto cleanup;
|
||||||
if (result != JSON_INCOMPLETE)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "%s\n", json_errdetail(result, lex));
|
|
||||||
ret = 1;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
resetStringInfo(&json);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = pg_parse_json_incremental(lex, testsem,
|
|
||||||
json.data, n_read,
|
|
||||||
true);
|
|
||||||
if (result != JSON_SUCCESS)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "%s\n", json_errdetail(result, lex));
|
|
||||||
ret = 1;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
if (!need_strings)
|
|
||||||
printf("SUCCESS!\n");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
resetStringInfo(&json);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = pg_parse_json_incremental(lex, testsem,
|
||||||
|
json.data, n_read,
|
||||||
|
true);
|
||||||
|
if (result != JSON_SUCCESS)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s\n", json_errdetail(result, lex));
|
||||||
|
ret = 1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (!need_strings)
|
||||||
|
printf("SUCCESS!\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
freeJsonLexContext(lex);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* In -r mode, separate output with nulls so that the calling test can
|
|
||||||
* split it up, decrement the chunk size, and loop back to the top.
|
|
||||||
* All other modes immediately fall out of the loop and exit.
|
|
||||||
*/
|
|
||||||
if (run_chunk_ranges)
|
|
||||||
{
|
|
||||||
fputc('\0', stdout);
|
|
||||||
fputc('\0', stderr);
|
|
||||||
}
|
|
||||||
} while (run_chunk_ranges && (--chunk_size > 0));
|
|
||||||
|
|
||||||
fclose(json_file);
|
fclose(json_file);
|
||||||
|
freeJsonLexContext(lex);
|
||||||
free(json.data);
|
free(json.data);
|
||||||
free(lex);
|
free(lex);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user