Commit db6335b5 authored by Alexander Korotkov's avatar Alexander Korotkov

Add support of multirange matching to the existing range GiST indexes

6df7a969 has introduced a set of operators between ranges and multiranges.
Existing GiST indexes for ranges could easily support majority of them.
This commit adds support for new operators to the existing range GiST indexes.
New operators resides the same strategy numbers as existing ones.  Appropriate
check function is determined using the subtype.

Catversion is bumped.
parent d1d61a8b
......@@ -116,6 +116,29 @@
<row><entry><literal>&gt;= (inet,inet)</literal></entry></row>
<row><entry><literal>&amp;&amp; (inet,inet)</literal></entry></row>
<row>
<entry valign="middle" morerows="17"><literal>multirange_ops</literal></entry>
<entry><literal>= (anymultirange,anymultirange)</literal></entry>
<entry valign="middle" morerows="17"></entry>
</row>
<row><entry><literal>&amp;&amp; (anymultirange,anymultirange)</literal></entry></row>
<row><entry><literal>&amp;&amp; (anymultirange,anyrange)</literal></entry></row>
<row><entry><literal>@&gt; (anymultirange,anyelement)</literal></entry></row>
<row><entry><literal>@&gt; (anymultirange,anymultirange)</literal></entry></row>
<row><entry><literal>@&gt; (anymultirange,anyrange)</literal></entry></row>
<row><entry><literal>&lt;@ (anymultirange,anymultirange)</literal></entry></row>
<row><entry><literal>&lt;@ (anymultirange,anyrange)</literal></entry></row>
<row><entry><literal>&lt;&lt; (anymultirange,anymultirange)</literal></entry></row>
<row><entry><literal>&lt;&lt; (anymultirange,anyrange)</literal></entry></row>
<row><entry><literal>&gt;&gt; (anymultirange,anymultirange)</literal></entry></row>
<row><entry><literal>&gt;&gt; (anymultirange,anyrange)</literal></entry></row>
<row><entry><literal>&amp;&lt; (anymultirange,anymultirange)</literal></entry></row>
<row><entry><literal>&amp;&lt; (anymultirange,anyrange)</literal></entry></row>
<row><entry><literal>&amp;&gt; (anymultirange,anymultirange)</literal></entry></row>
<row><entry><literal>&amp;&gt; (anymultirange,anyrange)</literal></entry></row>
<row><entry><literal>-|- (anymultirange,anymultirange)</literal></entry></row>
<row><entry><literal>-|- (anymultirange,anyrange)</literal></entry></row>
<row>
<entry valign="middle" morerows="7"><literal>point_ops</literal></entry>
<entry><literal>|&gt;&gt; (point,point)</literal></entry>
......@@ -149,19 +172,27 @@
<row><entry><literal>~ (polygon,polygon)</literal></entry></row>
<row>
<entry valign="middle" morerows="9"><literal>range_ops</literal></entry>
<entry valign="middle" morerows="17"><literal>range_ops</literal></entry>
<entry><literal>= (anyrange,anyrange)</literal></entry>
<entry valign="middle" morerows="9"></entry>
<entry valign="middle" morerows="17"></entry>
</row>
<row><entry><literal>&amp;&amp; (anyrange,anyrange)</literal></entry></row>
<row><entry><literal>&amp;&amp; (anyrange,anymultirange)</literal></entry></row>
<row><entry><literal>@&gt; (anyrange,anyelement)</literal></entry></row>
<row><entry><literal>@&gt; (anyrange,anyrange)</literal></entry></row>
<row><entry><literal>@&gt; (anyrange,anymultirange)</literal></entry></row>
<row><entry><literal>&lt;@ (anyrange,anyrange)</literal></entry></row>
<row><entry><literal>&lt;@ (anyrange,anymultirange)</literal></entry></row>
<row><entry><literal>&lt;&lt; (anyrange,anyrange)</literal></entry></row>
<row><entry><literal>&lt;&lt; (anyrange,anymultirange)</literal></entry></row>
<row><entry><literal>&gt;&gt; (anyrange,anyrange)</literal></entry></row>
<row><entry><literal>&gt;&gt; (anyrange,anymultirange)</literal></entry></row>
<row><entry><literal>&amp;&lt; (anyrange,anyrange)</literal></entry></row>
<row><entry><literal>&amp;&lt; (anyrange,anymultirange)</literal></entry></row>
<row><entry><literal>&amp;&gt; (anyrange,anyrange)</literal></entry></row>
<row><entry><literal>&amp;&gt; (anyrange,anymultirange)</literal></entry></row>
<row><entry><literal>-|- (anyrange,anyrange)</literal></entry></row>
<row><entry><literal>-|- (anyrange,anymultirange)</literal></entry></row>
<row>
<entry valign="middle" morerows="1"><literal>tsquery_ops</literal></entry>
......
......@@ -469,11 +469,13 @@ SELECT '[11:10, 23:00]'::timerange;
<para>
GiST and SP-GiST indexes can be created for table columns of range types.
GiST indexes can be also created for table columns of multirange types.
For instance, to create a GiST index:
<programlisting>
CREATE INDEX reservation_idx ON reservation USING GIST (during);
</programlisting>
A GiST or SP-GiST index can accelerate queries involving these range operators:
A GiST or SP-GiST index on ranges can accelerate queries involving these
range operators:
<literal>=</literal>,
<literal>&amp;&amp;</literal>,
<literal>&lt;@</literal>,
......@@ -482,8 +484,21 @@ CREATE INDEX reservation_idx ON reservation USING GIST (during);
<literal>&gt;&gt;</literal>,
<literal>-|-</literal>,
<literal>&amp;&lt;</literal>, and
<literal>&amp;&gt;</literal>
(see <xref linkend="range-operators-table"/> for more information).
<literal>&amp;&gt;</literal>.
A GiST index on multiranges can accelerate queries involving the same
set of multirange operators.
A GiST index on ranges and GiST index on multiranges can also accelerate
queries involving these cross-type range to multirange and multirange to
range operators correspondingly:
<literal>&amp;&amp;</literal>,
<literal>&lt;@</literal>,
<literal>@&gt;</literal>,
<literal>&lt;&lt;</literal>,
<literal>&gt;&gt;</literal>,
<literal>-|-</literal>,
<literal>&amp;&lt;</literal>, and
<literal>&amp;&gt;</literal>.
See <xref linkend="range-operators-table"/> for more information.
</para>
<para>
......
......@@ -768,6 +768,27 @@ multirange_get_bounds(TypeCacheEntry *rangetyp,
upper->lower = false;
}
/*
* Construct union range from the multirange.
*/
RangeType *
multirange_get_union_range(TypeCacheEntry *rangetyp,
const MultirangeType *mr)
{
RangeBound lower,
upper,
tmp;
if (MultirangeIsEmpty(mr))
return make_empty_range(rangetyp);
multirange_get_bounds(rangetyp, mr, 0, &lower, &tmp);
multirange_get_bounds(rangetyp, mr, mr->rangeCount - 1, &tmp, &upper);
return make_range(rangetyp, &lower, &upper, false);
}
/*
* multirange_deserialize: deconstruct a multirange value
*
......
This diff is collapsed.
......@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 202012291
#define CATALOG_VERSION_NO 202012293
#endif
......@@ -1346,27 +1346,51 @@
{ amopfamily => 'gist/range_ops', amoplefttype => 'anyrange',
amoprighttype => 'anyrange', amopstrategy => '1',
amopopr => '<<(anyrange,anyrange)', amopmethod => 'gist' },
{ amopfamily => 'gist/range_ops', amoplefttype => 'anyrange',
amoprighttype => 'anymultirange', amopstrategy => '1',
amopopr => '<<(anyrange,anymultirange)', amopmethod => 'gist' },
{ amopfamily => 'gist/range_ops', amoplefttype => 'anyrange',
amoprighttype => 'anyrange', amopstrategy => '2',
amopopr => '&<(anyrange,anyrange)', amopmethod => 'gist' },
{ amopfamily => 'gist/range_ops', amoplefttype => 'anyrange',
amoprighttype => 'anymultirange', amopstrategy => '2',
amopopr => '&<(anyrange,anymultirange)', amopmethod => 'gist' },
{ amopfamily => 'gist/range_ops', amoplefttype => 'anyrange',
amoprighttype => 'anyrange', amopstrategy => '3',
amopopr => '&&(anyrange,anyrange)', amopmethod => 'gist' },
{ amopfamily => 'gist/range_ops', amoplefttype => 'anyrange',
amoprighttype => 'anymultirange', amopstrategy => '3',
amopopr => '&&(anyrange,anymultirange)', amopmethod => 'gist' },
{ amopfamily => 'gist/range_ops', amoplefttype => 'anyrange',
amoprighttype => 'anyrange', amopstrategy => '4',
amopopr => '&>(anyrange,anyrange)', amopmethod => 'gist' },
{ amopfamily => 'gist/range_ops', amoplefttype => 'anyrange',
amoprighttype => 'anymultirange', amopstrategy => '4',
amopopr => '&>(anyrange,anymultirange)', amopmethod => 'gist' },
{ amopfamily => 'gist/range_ops', amoplefttype => 'anyrange',
amoprighttype => 'anyrange', amopstrategy => '5',
amopopr => '>>(anyrange,anyrange)', amopmethod => 'gist' },
{ amopfamily => 'gist/range_ops', amoplefttype => 'anyrange',
amoprighttype => 'anymultirange', amopstrategy => '5',
amopopr => '>>(anyrange,anymultirange)', amopmethod => 'gist' },
{ amopfamily => 'gist/range_ops', amoplefttype => 'anyrange',
amoprighttype => 'anyrange', amopstrategy => '6',
amopopr => '-|-(anyrange,anyrange)', amopmethod => 'gist' },
{ amopfamily => 'gist/range_ops', amoplefttype => 'anyrange',
amoprighttype => 'anymultirange', amopstrategy => '6',
amopopr => '-|-(anyrange,anymultirange)', amopmethod => 'gist' },
{ amopfamily => 'gist/range_ops', amoplefttype => 'anyrange',
amoprighttype => 'anyrange', amopstrategy => '7',
amopopr => '@>(anyrange,anyrange)', amopmethod => 'gist' },
{ amopfamily => 'gist/range_ops', amoplefttype => 'anyrange',
amoprighttype => 'anymultirange', amopstrategy => '7',
amopopr => '@>(anyrange,anymultirange)', amopmethod => 'gist' },
{ amopfamily => 'gist/range_ops', amoplefttype => 'anyrange',
amoprighttype => 'anyrange', amopstrategy => '8',
amopopr => '<@(anyrange,anyrange)', amopmethod => 'gist' },
{ amopfamily => 'gist/range_ops', amoplefttype => 'anyrange',
amoprighttype => 'anymultirange', amopstrategy => '8',
amopopr => '<@(anyrange,anymultirange)', amopmethod => 'gist' },
{ amopfamily => 'gist/range_ops', amoplefttype => 'anyrange',
amoprighttype => 'anyelement', amopstrategy => '16',
amopopr => '@>(anyrange,anyelement)', amopmethod => 'gist' },
......@@ -1374,6 +1398,62 @@
amoprighttype => 'anyrange', amopstrategy => '18',
amopopr => '=(anyrange,anyrange)', amopmethod => 'gist' },
# GiST multirange_ops
{ amopfamily => 'gist/multirange_ops', amoplefttype => 'anymultirange',
amoprighttype => 'anymultirange', amopstrategy => '1',
amopopr => '<<(anymultirange,anymultirange)', amopmethod => 'gist' },
{ amopfamily => 'gist/multirange_ops', amoplefttype => 'anymultirange',
amoprighttype => 'anyrange', amopstrategy => '1',
amopopr => '<<(anymultirange,anyrange)', amopmethod => 'gist' },
{ amopfamily => 'gist/multirange_ops', amoplefttype => 'anymultirange',
amoprighttype => 'anymultirange', amopstrategy => '2',
amopopr => '&<(anymultirange,anymultirange)', amopmethod => 'gist' },
{ amopfamily => 'gist/multirange_ops', amoplefttype => 'anymultirange',
amoprighttype => 'anyrange', amopstrategy => '2',
amopopr => '&<(anymultirange,anyrange)', amopmethod => 'gist' },
{ amopfamily => 'gist/multirange_ops', amoplefttype => 'anymultirange',
amoprighttype => 'anymultirange', amopstrategy => '3',
amopopr => '&&(anymultirange,anymultirange)', amopmethod => 'gist' },
{ amopfamily => 'gist/multirange_ops', amoplefttype => 'anymultirange',
amoprighttype => 'anyrange', amopstrategy => '3',
amopopr => '&&(anymultirange,anyrange)', amopmethod => 'gist' },
{ amopfamily => 'gist/multirange_ops', amoplefttype => 'anymultirange',
amoprighttype => 'anymultirange', amopstrategy => '4',
amopopr => '&>(anymultirange,anymultirange)', amopmethod => 'gist' },
{ amopfamily => 'gist/multirange_ops', amoplefttype => 'anymultirange',
amoprighttype => 'anyrange', amopstrategy => '4',
amopopr => '&>(anymultirange,anyrange)', amopmethod => 'gist' },
{ amopfamily => 'gist/multirange_ops', amoplefttype => 'anymultirange',
amoprighttype => 'anymultirange', amopstrategy => '5',
amopopr => '>>(anymultirange,anymultirange)', amopmethod => 'gist' },
{ amopfamily => 'gist/multirange_ops', amoplefttype => 'anymultirange',
amoprighttype => 'anyrange', amopstrategy => '5',
amopopr => '>>(anymultirange,anyrange)', amopmethod => 'gist' },
{ amopfamily => 'gist/multirange_ops', amoplefttype => 'anymultirange',
amoprighttype => 'anymultirange', amopstrategy => '6',
amopopr => '-|-(anymultirange,anymultirange)', amopmethod => 'gist' },
{ amopfamily => 'gist/multirange_ops', amoplefttype => 'anymultirange',
amoprighttype => 'anyrange', amopstrategy => '6',
amopopr => '-|-(anymultirange,anyrange)', amopmethod => 'gist' },
{ amopfamily => 'gist/multirange_ops', amoplefttype => 'anymultirange',
amoprighttype => 'anymultirange', amopstrategy => '7',
amopopr => '@>(anymultirange,anymultirange)', amopmethod => 'gist' },
{ amopfamily => 'gist/multirange_ops', amoplefttype => 'anymultirange',
amoprighttype => 'anyrange', amopstrategy => '7',
amopopr => '@>(anymultirange,anyrange)', amopmethod => 'gist' },
{ amopfamily => 'gist/multirange_ops', amoplefttype => 'anymultirange',
amoprighttype => 'anymultirange', amopstrategy => '8',
amopopr => '<@(anymultirange,anymultirange)', amopmethod => 'gist' },
{ amopfamily => 'gist/multirange_ops', amoplefttype => 'anymultirange',
amoprighttype => 'anyrange', amopstrategy => '8',
amopopr => '<@(anymultirange,anyrange)', amopmethod => 'gist' },
{ amopfamily => 'gist/multirange_ops', amoplefttype => 'anymultirange',
amoprighttype => 'anyelement', amopstrategy => '16',
amopopr => '@>(anymultirange,anyelement)', amopmethod => 'gist' },
{ amopfamily => 'gist/multirange_ops', amoplefttype => 'anymultirange',
amoprighttype => 'anymultirange', amopstrategy => '18',
amopopr => '=(anymultirange,anymultirange)', amopmethod => 'gist' },
# btree multirange_ops
{ amopfamily => 'btree/multirange_ops', amoplefttype => 'anymultirange',
amoprighttype => 'anymultirange', amopstrategy => '1',
......
......@@ -612,6 +612,24 @@
amprocrighttype => 'inet', amprocnum => '7', amproc => 'inet_gist_same' },
{ amprocfamily => 'gist/network_ops', amproclefttype => 'inet',
amprocrighttype => 'inet', amprocnum => '9', amproc => 'inet_gist_fetch' },
{ amprocfamily => 'gist/multirange_ops', amproclefttype => 'anymultirange',
amprocrighttype => 'anymultirange', amprocnum => '1',
amproc => 'multirange_gist_consistent' },
{ amprocfamily => 'gist/multirange_ops', amproclefttype => 'anymultirange',
amprocrighttype => 'anymultirange', amprocnum => '2',
amproc => 'range_gist_union' },
{ amprocfamily => 'gist/multirange_ops', amproclefttype => 'anymultirange',
amprocrighttype => 'anymultirange', amprocnum => '3',
amproc => 'multirange_gist_compress' },
{ amprocfamily => 'gist/multirange_ops', amproclefttype => 'anymultirange',
amprocrighttype => 'anymultirange', amprocnum => '5',
amproc => 'range_gist_penalty' },
{ amprocfamily => 'gist/multirange_ops', amproclefttype => 'anymultirange',
amprocrighttype => 'anymultirange', amprocnum => '6',
amproc => 'range_gist_picksplit' },
{ amprocfamily => 'gist/multirange_ops', amproclefttype => 'anymultirange',
amprocrighttype => 'anymultirange', amprocnum => '7',
amproc => 'range_gist_same' },
# gin
{ amprocfamily => 'gin/array_ops', amproclefttype => 'anyarray',
......
......@@ -236,6 +236,8 @@
opcintype => 'anymultirange' },
{ opcmethod => 'hash', opcname => 'multirange_ops', opcfamily => 'hash/multirange_ops',
opcintype => 'anymultirange' },
{ opcmethod => 'gist', opcname => 'multirange_ops', opcfamily => 'gist/multirange_ops',
opcintype => 'anymultirange', opckeytype => 'anyrange' },
{ opcmethod => 'spgist', opcname => 'box_ops', opcfamily => 'spgist/box_ops',
opcintype => 'box' },
{ opcmethod => 'spgist', opcname => 'quad_point_ops',
......
......@@ -236,5 +236,7 @@
opfmethod => 'btree', opfname => 'multirange_ops' },
{ oid => '4225',
opfmethod => 'hash', opfname => 'multirange_ops' },
{ oid => '8021',
opfmethod => 'gist', opfname => 'multirange_ops' },
]
......@@ -9922,6 +9922,14 @@
{ oid => '3881', descr => 'GiST support',
proname => 'range_gist_same', prorettype => 'internal',
proargtypes => 'anyrange anyrange internal', prosrc => 'range_gist_same' },
{ oid => '8017', descr => 'GiST support',
proname => 'multirange_gist_consistent', prorettype => 'bool',
proargtypes => 'internal anymultirange int2 oid internal',
prosrc => 'multirange_gist_consistent' },
{ oid => '8019', descr => 'GiST support',
proname => 'multirange_gist_compress', prorettype => 'internal',
proargtypes => 'internal',
prosrc => 'multirange_gist_compress' },
{ oid => '3902', descr => 'hash a range',
proname => 'hash_range', prorettype => 'int4', proargtypes => 'anyrange',
prosrc => 'hash_range' },
......
......@@ -129,5 +129,7 @@ extern void multirange_get_bounds(TypeCacheEntry *rangetyp,
RangeBound *lower, RangeBound *upper);
extern RangeType *multirange_get_range(TypeCacheEntry *rangetyp,
const MultirangeType *multirange, int i);
extern RangeType *multirange_get_union_range(TypeCacheEntry *rangetyp,
const MultirangeType *mr);
#endif /* MULTIRANGETYPES_H */
......@@ -2219,6 +2219,263 @@ SELECT '{[1,4), [7,10)}'::nummultirange * '{[0,2), [3,8), [9,12)}'::nummultirang
{[1,2),[3,4),[7,8),[9,10)}
(1 row)
-- test GiST index
create table test_multirange_gist(mr int4multirange);
insert into test_multirange_gist select int4multirange(int4range(g, g+10),int4range(g+20, g+30),int4range(g+40, g+50)) from generate_series(1,2000) g;
insert into test_multirange_gist select '{}'::int4multirange from generate_series(1,500) g;
insert into test_multirange_gist select int4multirange(int4range(g, g+10000)) from generate_series(1,1000) g;
insert into test_multirange_gist select int4multirange(int4range(NULL, g*10, '(]'), int4range(g*10, g*20, '(]')) from generate_series(1,100) g;
insert into test_multirange_gist select int4multirange(int4range(g*10, g*20, '(]'), int4range(g*20, NULL, '(]')) from generate_series(1,100) g;
create index test_mulrirange_gist_idx on test_multirange_gist using gist (mr);
-- first, verify non-indexed results
SET enable_seqscan = t;
SET enable_indexscan = f;
SET enable_bitmapscan = f;
select count(*) from test_multirange_gist where mr @> 'empty'::int4range;
count
-------
3700
(1 row)
select count(*) from test_multirange_gist where mr = int4multirange(int4range(10,20), int4range(30,40), int4range(50,60));
count
-------
1
(1 row)
select count(*) from test_multirange_gist where mr @> 10;
count
-------
120
(1 row)
select count(*) from test_multirange_gist where mr @> int4range(10,20);
count
-------
111
(1 row)
select count(*) from test_multirange_gist where mr && int4range(10,20);
count
-------
139
(1 row)
select count(*) from test_multirange_gist where mr <@ int4range(10,50);
count
-------
500
(1 row)
select count(*) from test_multirange_gist where mr << int4range(100,500);
count
-------
54
(1 row)
select count(*) from test_multirange_gist where mr >> int4range(100,500);
count
-------
2053
(1 row)
select count(*) from test_multirange_gist where mr &< int4range(100,500);
count
-------
474
(1 row)
select count(*) from test_multirange_gist where mr &> int4range(100,500);
count
-------
2893
(1 row)
select count(*) from test_multirange_gist where mr -|- int4range(100,500);
count
-------
3
(1 row)
select count(*) from test_multirange_gist where mr @> '{}'::int4multirange;
count
-------
3700
(1 row)
select count(*) from test_multirange_gist where mr @> int4multirange(int4range(10,20), int4range(30,40));
count
-------
110
(1 row)
select count(*) from test_multirange_gist where mr && '{(10,20),(30,40),(50,60)}'::int4multirange;
count
-------
218
(1 row)
select count(*) from test_multirange_gist where mr <@ '{(10,30),(40,60),(70,90)}'::int4multirange;
count
-------
500
(1 row)
select count(*) from test_multirange_gist where mr << int4multirange(int4range(100,200), int4range(400,500));
count
-------
54
(1 row)
select count(*) from test_multirange_gist where mr >> int4multirange(int4range(100,200), int4range(400,500));
count
-------
2053
(1 row)
select count(*) from test_multirange_gist where mr &< int4multirange(int4range(100,200), int4range(400,500));
count
-------
474
(1 row)
select count(*) from test_multirange_gist where mr &> int4multirange(int4range(100,200), int4range(400,500));
count
-------
2893
(1 row)
select count(*) from test_multirange_gist where mr -|- int4multirange(int4range(100,200), int4range(400,500));
count
-------
3
(1 row)
-- now check same queries using index
SET enable_seqscan = f;
SET enable_indexscan = t;
SET enable_bitmapscan = f;
select count(*) from test_multirange_gist where mr @> 'empty'::int4range;
count
-------
3700
(1 row)
select count(*) from test_multirange_gist where mr = int4multirange(int4range(10,20), int4range(30,40), int4range(50,60));
count
-------
1
(1 row)
select count(*) from test_multirange_gist where mr @> 10;
count
-------
120
(1 row)
select count(*) from test_multirange_gist where mr @> int4range(10,20);
count
-------
111
(1 row)
select count(*) from test_multirange_gist where mr && int4range(10,20);
count
-------
139
(1 row)
select count(*) from test_multirange_gist where mr <@ int4range(10,50);
count
-------
500
(1 row)
select count(*) from test_multirange_gist where mr << int4range(100,500);
count
-------
54
(1 row)
select count(*) from test_multirange_gist where mr >> int4range(100,500);
count
-------
2053
(1 row)
select count(*) from test_multirange_gist where mr &< int4range(100,500);
count
-------
474
(1 row)
select count(*) from test_multirange_gist where mr &> int4range(100,500);
count
-------
2893
(1 row)
select count(*) from test_multirange_gist where mr -|- int4range(100,500);
count
-------
3
(1 row)
select count(*) from test_multirange_gist where mr @> '{}'::int4multirange;
count
-------
3700
(1 row)
select count(*) from test_multirange_gist where mr @> int4multirange(int4range(10,20), int4range(30,40));
count
-------
110
(1 row)
select count(*) from test_multirange_gist where mr && '{(10,20),(30,40),(50,60)}'::int4multirange;
count
-------
218
(1 row)
select count(*) from test_multirange_gist where mr <@ '{(10,30),(40,60),(70,90)}'::int4multirange;
count
-------
500
(1 row)
select count(*) from test_multirange_gist where mr << int4multirange(int4range(100,200), int4range(400,500));
count
-------
54
(1 row)
select count(*) from test_multirange_gist where mr >> int4multirange(int4range(100,200), int4range(400,500));
count
-------
2053
(1 row)
select count(*) from test_multirange_gist where mr &< int4multirange(int4range(100,200), int4range(400,500));
count
-------
474
(1 row)
select count(*) from test_multirange_gist where mr &> int4multirange(int4range(100,200), int4range(400,500));
count
-------
2893
(1 row)
select count(*) from test_multirange_gist where mr -|- int4multirange(int4range(100,200), int4range(400,500));
count
-------
3
(1 row)
drop table test_multirange_gist;
--
-- range_agg function
--
......
......@@ -862,6 +862,60 @@ select count(*) from test_range_gist where ir -|- int4range(100,500);
5
(1 row)
select count(*) from test_range_gist where ir @> '{}'::int4multirange;
count
-------
6200
(1 row)
select count(*) from test_range_gist where ir @> int4multirange(int4range(10,20), int4range(30,40));
count
-------
107
(1 row)
select count(*) from test_range_gist where ir && '{(10,20),(30,40),(50,60)}'::int4multirange;
count
-------
271
(1 row)
select count(*) from test_range_gist where ir <@ '{(10,30),(40,60),(70,90)}'::int4multirange;
count
-------
1060
(1 row)
select count(*) from test_range_gist where ir << int4multirange(int4range(100,200), int4range(400,500));
count
-------
189
(1 row)
select count(*) from test_range_gist where ir >> int4multirange(int4range(100,200), int4range(400,500));
count
-------
3554
(1 row)
select count(*) from test_range_gist where ir &< int4multirange(int4range(100,200), int4range(400,500));
count
-------
1029
(1 row)
select count(*) from test_range_gist where ir &> int4multirange(int4range(100,200), int4range(400,500));
count
-------
4794
(1 row)
select count(*) from test_range_gist where ir -|- int4multirange(int4range(100,200), int4range(400,500));
count
-------
5
(1 row)
-- now check same queries using index
SET enable_seqscan = f;
SET enable_indexscan = t;
......@@ -932,6 +986,60 @@ select count(*) from test_range_gist where ir -|- int4range(100,500);
5
(1 row)
select count(*) from test_range_gist where ir @> '{}'::int4multirange;
count
-------
6200
(1 row)
select count(*) from test_range_gist where ir @> int4multirange(int4range(10,20), int4range(30,40));
count
-------
107
(1 row)
select count(*) from test_range_gist where ir && '{(10,20),(30,40),(50,60)}'::int4multirange;
count
-------
271
(1 row)
select count(*) from test_range_gist where ir <@ '{(10,30),(40,60),(70,90)}'::int4multirange;
count
-------
1060
(1 row)
select count(*) from test_range_gist where ir << int4multirange(int4range(100,200), int4range(400,500));
count
-------
189
(1 row)
select count(*) from test_range_gist where ir >> int4multirange(int4range(100,200), int4range(400,500));
count
-------
3554
(1 row)
select count(*) from test_range_gist where ir &< int4multirange(int4range(100,200), int4range(400,500));
count
-------
1029
(1 row)
select count(*) from test_range_gist where ir &> int4multirange(int4range(100,200), int4range(400,500));
count
-------
4794
(1 row)
select count(*) from test_range_gist where ir -|- int4multirange(int4range(100,200), int4range(400,500));
count
-------
5
(1 row)
-- now check same queries using a bulk-loaded index
drop index test_range_gist_idx;
create index test_range_gist_idx on test_range_gist using gist (ir);
......@@ -1001,6 +1109,60 @@ select count(*) from test_range_gist where ir -|- int4range(100,500);
5
(1 row)
select count(*) from test_range_gist where ir @> '{}'::int4multirange;
count
-------
6200
(1 row)
select count(*) from test_range_gist where ir @> int4multirange(int4range(10,20), int4range(30,40));
count
-------
107
(1 row)
select count(*) from test_range_gist where ir && '{(10,20),(30,40),(50,60)}'::int4multirange;
count
-------
271
(1 row)
select count(*) from test_range_gist where ir <@ '{(10,30),(40,60),(70,90)}'::int4multirange;
count
-------
1060
(1 row)
select count(*) from test_range_gist where ir << int4multirange(int4range(100,200), int4range(400,500));
count
-------
189
(1 row)
select count(*) from test_range_gist where ir >> int4multirange(int4range(100,200), int4range(400,500));
count
-------
3554
(1 row)
select count(*) from test_range_gist where ir &< int4multirange(int4range(100,200), int4range(400,500));
count
-------
1029
(1 row)
select count(*) from test_range_gist where ir &> int4multirange(int4range(100,200), int4range(400,500));
count
-------
4794
(1 row)
select count(*) from test_range_gist where ir -|- int4multirange(int4range(100,200), int4range(400,500));
count
-------
5
(1 row)
-- test SP-GiST index that's been built incrementally
create table test_range_spgist(ir int4range);
create index test_range_spgist_idx on test_range_spgist using spgist (ir);
......
......@@ -414,6 +414,69 @@ SELECT '{[1,4), [7,10)}'::nummultirange * '{[-5,-4), [5,6), [9,12)}'::nummultira
SELECT '{[1,4), [7,10)}'::nummultirange * '{[0,2), [3,8), [9,12)}'::nummultirange;
SELECT '{[1,4), [7,10)}'::nummultirange * '{[0,2), [3,8), [9,12)}'::nummultirange;
-- test GiST index
create table test_multirange_gist(mr int4multirange);
insert into test_multirange_gist select int4multirange(int4range(g, g+10),int4range(g+20, g+30),int4range(g+40, g+50)) from generate_series(1,2000) g;
insert into test_multirange_gist select '{}'::int4multirange from generate_series(1,500) g;
insert into test_multirange_gist select int4multirange(int4range(g, g+10000)) from generate_series(1,1000) g;
insert into test_multirange_gist select int4multirange(int4range(NULL, g*10, '(]'), int4range(g*10, g*20, '(]')) from generate_series(1,100) g;
insert into test_multirange_gist select int4multirange(int4range(g*10, g*20, '(]'), int4range(g*20, NULL, '(]')) from generate_series(1,100) g;
create index test_mulrirange_gist_idx on test_multirange_gist using gist (mr);
-- first, verify non-indexed results
SET enable_seqscan = t;
SET enable_indexscan = f;
SET enable_bitmapscan = f;
select count(*) from test_multirange_gist where mr @> 'empty'::int4range;
select count(*) from test_multirange_gist where mr = int4multirange(int4range(10,20), int4range(30,40), int4range(50,60));
select count(*) from test_multirange_gist where mr @> 10;
select count(*) from test_multirange_gist where mr @> int4range(10,20);
select count(*) from test_multirange_gist where mr && int4range(10,20);
select count(*) from test_multirange_gist where mr <@ int4range(10,50);
select count(*) from test_multirange_gist where mr << int4range(100,500);
select count(*) from test_multirange_gist where mr >> int4range(100,500);
select count(*) from test_multirange_gist where mr &< int4range(100,500);
select count(*) from test_multirange_gist where mr &> int4range(100,500);
select count(*) from test_multirange_gist where mr -|- int4range(100,500);
select count(*) from test_multirange_gist where mr @> '{}'::int4multirange;
select count(*) from test_multirange_gist where mr @> int4multirange(int4range(10,20), int4range(30,40));
select count(*) from test_multirange_gist where mr && '{(10,20),(30,40),(50,60)}'::int4multirange;
select count(*) from test_multirange_gist where mr <@ '{(10,30),(40,60),(70,90)}'::int4multirange;
select count(*) from test_multirange_gist where mr << int4multirange(int4range(100,200), int4range(400,500));
select count(*) from test_multirange_gist where mr >> int4multirange(int4range(100,200), int4range(400,500));
select count(*) from test_multirange_gist where mr &< int4multirange(int4range(100,200), int4range(400,500));
select count(*) from test_multirange_gist where mr &> int4multirange(int4range(100,200), int4range(400,500));
select count(*) from test_multirange_gist where mr -|- int4multirange(int4range(100,200), int4range(400,500));
-- now check same queries using index
SET enable_seqscan = f;
SET enable_indexscan = t;
SET enable_bitmapscan = f;
select count(*) from test_multirange_gist where mr @> 'empty'::int4range;
select count(*) from test_multirange_gist where mr = int4multirange(int4range(10,20), int4range(30,40), int4range(50,60));
select count(*) from test_multirange_gist where mr @> 10;
select count(*) from test_multirange_gist where mr @> int4range(10,20);
select count(*) from test_multirange_gist where mr && int4range(10,20);
select count(*) from test_multirange_gist where mr <@ int4range(10,50);
select count(*) from test_multirange_gist where mr << int4range(100,500);
select count(*) from test_multirange_gist where mr >> int4range(100,500);
select count(*) from test_multirange_gist where mr &< int4range(100,500);
select count(*) from test_multirange_gist where mr &> int4range(100,500);
select count(*) from test_multirange_gist where mr -|- int4range(100,500);
select count(*) from test_multirange_gist where mr @> '{}'::int4multirange;
select count(*) from test_multirange_gist where mr @> int4multirange(int4range(10,20), int4range(30,40));
select count(*) from test_multirange_gist where mr && '{(10,20),(30,40),(50,60)}'::int4multirange;
select count(*) from test_multirange_gist where mr <@ '{(10,30),(40,60),(70,90)}'::int4multirange;
select count(*) from test_multirange_gist where mr << int4multirange(int4range(100,200), int4range(400,500));
select count(*) from test_multirange_gist where mr >> int4multirange(int4range(100,200), int4range(400,500));
select count(*) from test_multirange_gist where mr &< int4multirange(int4range(100,200), int4range(400,500));
select count(*) from test_multirange_gist where mr &> int4multirange(int4range(100,200), int4range(400,500));
select count(*) from test_multirange_gist where mr -|- int4multirange(int4range(100,200), int4range(400,500));
drop table test_multirange_gist;
--
-- range_agg function
--
......
......@@ -232,6 +232,15 @@ select count(*) from test_range_gist where ir >> int4range(100,500);
select count(*) from test_range_gist where ir &< int4range(100,500);
select count(*) from test_range_gist where ir &> int4range(100,500);
select count(*) from test_range_gist where ir -|- int4range(100,500);
select count(*) from test_range_gist where ir @> '{}'::int4multirange;
select count(*) from test_range_gist where ir @> int4multirange(int4range(10,20), int4range(30,40));
select count(*) from test_range_gist where ir && '{(10,20),(30,40),(50,60)}'::int4multirange;
select count(*) from test_range_gist where ir <@ '{(10,30),(40,60),(70,90)}'::int4multirange;
select count(*) from test_range_gist where ir << int4multirange(int4range(100,200), int4range(400,500));
select count(*) from test_range_gist where ir >> int4multirange(int4range(100,200), int4range(400,500));
select count(*) from test_range_gist where ir &< int4multirange(int4range(100,200), int4range(400,500));
select count(*) from test_range_gist where ir &> int4multirange(int4range(100,200), int4range(400,500));
select count(*) from test_range_gist where ir -|- int4multirange(int4range(100,200), int4range(400,500));
-- now check same queries using index
SET enable_seqscan = f;
......@@ -249,6 +258,15 @@ select count(*) from test_range_gist where ir >> int4range(100,500);
select count(*) from test_range_gist where ir &< int4range(100,500);
select count(*) from test_range_gist where ir &> int4range(100,500);
select count(*) from test_range_gist where ir -|- int4range(100,500);
select count(*) from test_range_gist where ir @> '{}'::int4multirange;
select count(*) from test_range_gist where ir @> int4multirange(int4range(10,20), int4range(30,40));
select count(*) from test_range_gist where ir && '{(10,20),(30,40),(50,60)}'::int4multirange;
select count(*) from test_range_gist where ir <@ '{(10,30),(40,60),(70,90)}'::int4multirange;
select count(*) from test_range_gist where ir << int4multirange(int4range(100,200), int4range(400,500));
select count(*) from test_range_gist where ir >> int4multirange(int4range(100,200), int4range(400,500));
select count(*) from test_range_gist where ir &< int4multirange(int4range(100,200), int4range(400,500));
select count(*) from test_range_gist where ir &> int4multirange(int4range(100,200), int4range(400,500));
select count(*) from test_range_gist where ir -|- int4multirange(int4range(100,200), int4range(400,500));
-- now check same queries using a bulk-loaded index
drop index test_range_gist_idx;
......@@ -265,6 +283,15 @@ select count(*) from test_range_gist where ir >> int4range(100,500);
select count(*) from test_range_gist where ir &< int4range(100,500);
select count(*) from test_range_gist where ir &> int4range(100,500);
select count(*) from test_range_gist where ir -|- int4range(100,500);
select count(*) from test_range_gist where ir @> '{}'::int4multirange;
select count(*) from test_range_gist where ir @> int4multirange(int4range(10,20), int4range(30,40));
select count(*) from test_range_gist where ir && '{(10,20),(30,40),(50,60)}'::int4multirange;
select count(*) from test_range_gist where ir <@ '{(10,30),(40,60),(70,90)}'::int4multirange;
select count(*) from test_range_gist where ir << int4multirange(int4range(100,200), int4range(400,500));
select count(*) from test_range_gist where ir >> int4multirange(int4range(100,200), int4range(400,500));
select count(*) from test_range_gist where ir &< int4multirange(int4range(100,200), int4range(400,500));
select count(*) from test_range_gist where ir &> int4multirange(int4range(100,200), int4range(400,500));
select count(*) from test_range_gist where ir -|- int4multirange(int4range(100,200), int4range(400,500));
-- test SP-GiST index that's been built incrementally
create table test_range_spgist(ir int4range);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment