diff options
| author | Alexander Korotkov | 2020-12-20 04:20:33 +0000 |
|---|---|---|
| committer | Alexander Korotkov | 2020-12-20 04:20:33 +0000 |
| commit | 6df7a9698bb036610c1e8c6d375e1be38cb26d5f (patch) | |
| tree | dc5985310422e2b41e06bc1770f9e384e0bd6525 /src/test/regress/expected | |
| parent | 08b01d4dd982b491a2f9641804b368185b8f4c53 (diff) | |
Multirange datatypes
Multiranges are basically sorted arrays of non-overlapping ranges with
set-theoretic operations defined over them.
Since v14, each range type automatically gets a corresponding multirange
datatype. There are both manual and automatic mechanisms for naming multirange
types. Once can specify multirange type name using multirange_type_name
attribute in CREATE TYPE. Otherwise, a multirange type name is generated
automatically. If the range type name contains "range" then we change that to
"multirange". Otherwise, we add "_multirange" to the end.
Implementation of multiranges comes with a space-efficient internal
representation format, which evades extra paddings and duplicated storage of
oids. Altogether this format allows fetching a particular range by its index
in O(n).
Statistic gathering and selectivity estimation are implemented for multiranges.
For this purpose, stored multirange is approximated as union range without gaps.
This field will likely need improvements in the future.
Catversion is bumped.
Discussion: https://postgr.es/m/CALNJ-vSUpQ_Y%3DjXvTxt1VYFztaBSsWVXeF1y6gTYQ4bOiWDLgQ%40mail.gmail.com
Discussion: https://postgr.es/m/a0b8026459d1e6167933be2104a6174e7d40d0ab.camel%40j-davis.com#fe7218c83b08068bfffb0c5293eceda0
Author: Paul Jungwirth, revised by me
Reviewed-by: David Fetter, Corey Huinker, Jeff Davis, Pavel Stehule
Reviewed-by: Alvaro Herrera, Tom Lane, Isaac Morland, David G. Johnston
Reviewed-by: Zhihong Yu, Alexander Korotkov
Diffstat (limited to 'src/test/regress/expected')
| -rw-r--r-- | src/test/regress/expected/dependency.out | 1 | ||||
| -rw-r--r-- | src/test/regress/expected/hash_func.out | 13 | ||||
| -rw-r--r-- | src/test/regress/expected/multirangetypes.out | 2466 | ||||
| -rw-r--r-- | src/test/regress/expected/opr_sanity.out | 32 | ||||
| -rw-r--r-- | src/test/regress/expected/plpgsql.out | 4 | ||||
| -rw-r--r-- | src/test/regress/expected/polymorphism.out | 125 | ||||
| -rw-r--r-- | src/test/regress/expected/rangefuncs.out | 2 | ||||
| -rw-r--r-- | src/test/regress/expected/rangetypes.out | 42 | ||||
| -rw-r--r-- | src/test/regress/expected/sanity_check.out | 2 | ||||
| -rw-r--r-- | src/test/regress/expected/type_sanity.out | 46 |
10 files changed, 2679 insertions, 54 deletions
diff --git a/src/test/regress/expected/dependency.out b/src/test/regress/expected/dependency.out index b4a11b8aa9b..82327951487 100644 --- a/src/test/regress/expected/dependency.out +++ b/src/test/regress/expected/dependency.out @@ -140,6 +140,7 @@ owner of sequence deptest_a_seq owner of table deptest owner of function deptest_func() owner of type deptest_enum +owner of type deptest_multirange owner of type deptest_range owner of table deptest2 owner of sequence ss1 diff --git a/src/test/regress/expected/hash_func.out b/src/test/regress/expected/hash_func.out index 827e69fc7ab..dca31365bcf 100644 --- a/src/test/regress/expected/hash_func.out +++ b/src/test/regress/expected/hash_func.out @@ -305,6 +305,19 @@ WHERE hash_range(v)::bit(32) != hash_range_extended(v, 0)::bit(32) -------+----------+-----------+----------- (0 rows) +SELECT v as value, hash_multirange(v)::bit(32) as standard, + hash_multirange_extended(v, 0)::bit(32) as extended0, + hash_multirange_extended(v, 1)::bit(32) as extended1 +FROM (VALUES ('{[10,20)}'::int4multirange), ('{[23, 43]}'::int4multirange), + ('{[5675, 550273)}'::int4multirange), + ('{[550274, 1550274)}'::int4multirange), + ('{[1550275, 208112489)}'::int4multirange)) x(v) +WHERE hash_multirange(v)::bit(32) != hash_multirange_extended(v, 0)::bit(32) + OR hash_multirange(v)::bit(32) = hash_multirange_extended(v, 1)::bit(32); + value | standard | extended0 | extended1 +-------+----------+-----------+----------- +(0 rows) + CREATE TYPE hash_test_t1 AS (a int, b text); SELECT v as value, hash_record(v)::bit(32) as standard, hash_record_extended(v, 0)::bit(32) as extended0, diff --git a/src/test/regress/expected/multirangetypes.out b/src/test/regress/expected/multirangetypes.out new file mode 100644 index 00000000000..e81e565cab7 --- /dev/null +++ b/src/test/regress/expected/multirangetypes.out @@ -0,0 +1,2466 @@ +-- Tests for multirange data types. +-- +-- test input parser +-- +-- negative tests; should fail +select ''::textmultirange; +ERROR: malformed multirange literal: "" +LINE 1: select ''::textmultirange; + ^ +DETAIL: Missing left bracket. +select '{,}'::textmultirange; +ERROR: malformed multirange literal: "{,}" +LINE 1: select '{,}'::textmultirange; + ^ +DETAIL: Expected range start. +select '{[a,c),}'::textmultirange; +ERROR: malformed multirange literal: "{[a,c),}" +LINE 1: select '{[a,c),}'::textmultirange; + ^ +DETAIL: Expected range start. +select '{,[a,c)}'::textmultirange; +ERROR: malformed multirange literal: "{,[a,c)}" +LINE 1: select '{,[a,c)}'::textmultirange; + ^ +DETAIL: Expected range start. +select '{-[a,z)}'::textmultirange; +ERROR: malformed multirange literal: "{-[a,z)}" +LINE 1: select '{-[a,z)}'::textmultirange; + ^ +DETAIL: Expected range start. +select '{[a,z) - }'::textmultirange; +ERROR: malformed multirange literal: "{[a,z) - }" +LINE 1: select '{[a,z) - }'::textmultirange; + ^ +DETAIL: Expected comma or end of multirange. +select '{(",a)}'::textmultirange; +ERROR: malformed multirange literal: "{(",a)}" +LINE 1: select '{(",a)}'::textmultirange; + ^ +DETAIL: Unexpected end of input. +select '{(,,a)}'::textmultirange; +ERROR: malformed range literal: "(,,a)" +LINE 1: select '{(,,a)}'::textmultirange; + ^ +DETAIL: Too many commas. +select '{(),a)}'::textmultirange; +ERROR: malformed range literal: "()" +LINE 1: select '{(),a)}'::textmultirange; + ^ +DETAIL: Missing comma after lower bound. +select '{(a,))}'::textmultirange; +ERROR: malformed multirange literal: "{(a,))}" +LINE 1: select '{(a,))}'::textmultirange; + ^ +DETAIL: Expected comma or end of multirange. +select '{(],a)}'::textmultirange; +ERROR: malformed range literal: "(]" +LINE 1: select '{(],a)}'::textmultirange; + ^ +DETAIL: Missing comma after lower bound. +select '{(a,])}'::textmultirange; +ERROR: malformed multirange literal: "{(a,])}" +LINE 1: select '{(a,])}'::textmultirange; + ^ +DETAIL: Expected comma or end of multirange. +select '{[z,a]}'::textmultirange; +ERROR: range lower bound must be less than or equal to range upper bound +LINE 1: select '{[z,a]}'::textmultirange; + ^ +-- should succeed +select '{}'::textmultirange; + textmultirange +---------------- + {} +(1 row) + +select ' {} '::textmultirange; + textmultirange +---------------- + {} +(1 row) + +select ' { empty, empty } '::textmultirange; + textmultirange +---------------- + {} +(1 row) + +select ' {( " a " " a ", " z " " z " ) }'::textmultirange; + textmultirange +---------------------------- + {(" a a "," z z ")} +(1 row) + +select '{(,z)}'::textmultirange; + textmultirange +---------------- + {(,z)} +(1 row) + +select '{(a,)}'::textmultirange; + textmultirange +---------------- + {(a,)} +(1 row) + +select '{[,z]}'::textmultirange; + textmultirange +---------------- + {(,z]} +(1 row) + +select '{[a,]}'::textmultirange; + textmultirange +---------------- + {[a,)} +(1 row) + +select '{(,)}'::textmultirange; + textmultirange +---------------- + {(,)} +(1 row) + +select '{[ , ]}'::textmultirange; + textmultirange +---------------- + {[" "," "]} +(1 row) + +select '{["",""]}'::textmultirange; + textmultirange +---------------- + {["",""]} +(1 row) + +select '{[",",","]}'::textmultirange; + textmultirange +---------------- + {[",",","]} +(1 row) + +select '{["\\","\\"]}'::textmultirange; + textmultirange +---------------- + {["\\","\\"]} +(1 row) + +select '{["""","\""]}'::textmultirange; + textmultirange +---------------- + {["""",""""]} +(1 row) + +select '{(\\,a)}'::textmultirange; + textmultirange +---------------- + {("\\",a)} +(1 row) + +select '{((,z)}'::textmultirange; + textmultirange +---------------- + {("(",z)} +(1 row) + +select '{([,z)}'::textmultirange; + textmultirange +---------------- + {("[",z)} +(1 row) + +select '{(!,()}'::textmultirange; + textmultirange +---------------- + {(!,"(")} +(1 row) + +select '{(!,[)}'::textmultirange; + textmultirange +---------------- + {(!,"[")} +(1 row) + +select '{[a,a]}'::textmultirange; + textmultirange +---------------- + {[a,a]} +(1 row) + +select '{[a,a],[a,b]}'::textmultirange; + textmultirange +---------------- + {[a,b]} +(1 row) + +select '{[a,b), [b,e]}'::textmultirange; + textmultirange +---------------- + {[a,e]} +(1 row) + +select '{[a,d), [b,f]}'::textmultirange; + textmultirange +---------------- + {[a,f]} +(1 row) + +select '{[a,a],[b,b]}'::textmultirange; + textmultirange +---------------- + {[a,a],[b,b]} +(1 row) + +-- without canonicalization, we can't join these: +select '{[a,a], [b,b]}'::textmultirange; + textmultirange +---------------- + {[a,a],[b,b]} +(1 row) + +-- with canonicalization, we can join these: +select '{[1,2], [3,4]}'::int4multirange; + int4multirange +---------------- + {[1,5)} +(1 row) + +select '{[a,a], [b,b], [c,c]}'::textmultirange; + textmultirange +--------------------- + {[a,a],[b,b],[c,c]} +(1 row) + +select '{[a,d], [b,e]}'::textmultirange; + textmultirange +---------------- + {[a,e]} +(1 row) + +select '{[a,d), [d,e)}'::textmultirange; + textmultirange +---------------- + {[a,e)} +(1 row) + +-- these are allowed but normalize to empty: +select '{[a,a)}'::textmultirange; + textmultirange +---------------- + {} +(1 row) + +select '{(a,a]}'::textmultirange; + textmultirange +---------------- + {} +(1 row) + +select '{(a,a)}'::textmultirange; + textmultirange +---------------- + {} +(1 row) + +-- +-- test the constructor +--- +select textmultirange(); + textmultirange +---------------- + {} +(1 row) + +select textmultirange(textrange('a', 'c')); + textmultirange +---------------- + {[a,c)} +(1 row) + +select textmultirange(textrange('a', 'c'), textrange('f', 'g')); + textmultirange +---------------- + {[a,c),[f,g)} +(1 row) + +select textmultirange(textrange('a', 'c'), textrange('b', 'd')); + textmultirange +---------------- + {[a,d)} +(1 row) + +-- +-- test casts, both a built-in range type and a user-defined one: +-- +select 'empty'::int4range::int4multirange; + int4multirange +---------------- + {} +(1 row) + +select int4range(1, 3)::int4multirange; + int4range +----------- + {[1,3)} +(1 row) + +select int4range(1, null)::int4multirange; + int4range +----------- + {[1,)} +(1 row) + +select int4range(null, null)::int4multirange; + int4range +----------- + {(,)} +(1 row) + +select 'empty'::textrange::textmultirange; + textmultirange +---------------- + {} +(1 row) + +select textrange('a', 'c')::textmultirange; + textrange +----------- + {[a,c)} +(1 row) + +select textrange('a', null)::textmultirange; + textrange +----------- + {[a,)} +(1 row) + +select textrange(null, null)::textmultirange; + textrange +----------- + {(,)} +(1 row) + +-- +-- create some test data and test the operators +-- +CREATE TABLE nummultirange_test (nmr NUMMULTIRANGE); +CREATE INDEX nummultirange_test_btree ON nummultirange_test(nmr); +INSERT INTO nummultirange_test VALUES('{}'); +INSERT INTO nummultirange_test VALUES('{[,)}'); +INSERT INTO nummultirange_test VALUES('{[3,]}'); +INSERT INTO nummultirange_test VALUES('{[,), [3,]}'); +INSERT INTO nummultirange_test VALUES('{[, 5)}'); +INSERT INTO nummultirange_test VALUES(nummultirange()); +INSERT INTO nummultirange_test VALUES(nummultirange(variadic '{}'::numrange[])); +INSERT INTO nummultirange_test VALUES(nummultirange(numrange(1.1, 2.2))); +INSERT INTO nummultirange_test VALUES('{empty}'); +INSERT INTO nummultirange_test VALUES(nummultirange(numrange(1.7, 1.7, '[]'), numrange(1.7, 1.9))); +INSERT INTO nummultirange_test VALUES(nummultirange(numrange(1.7, 1.7, '[]'), numrange(1.9, 2.1))); +SELECT nmr, isempty(nmr), lower(nmr), upper(nmr) FROM nummultirange_test ORDER BY nmr; + nmr | isempty | lower | upper +-----------------------+---------+-------+------- + {} | t | | + {} | t | | + {} | t | | + {} | t | | + {(,5)} | f | | 5 + {(,)} | f | | + {(,)} | f | | + {[1.1,2.2)} | f | 1.1 | 2.2 + {[1.7,1.7],[1.9,2.1)} | f | 1.7 | 2.1 + {[1.7,1.9)} | f | 1.7 | 1.9 + {[3,)} | f | 3 | +(11 rows) + +SELECT nmr, lower_inc(nmr), lower_inf(nmr), upper_inc(nmr), upper_inf(nmr) FROM nummultirange_test ORDER BY nmr; + nmr | lower_inc | lower_inf | upper_inc | upper_inf +-----------------------+-----------+-----------+-----------+----------- + {} | f | f | f | f + {} | f | f | f | f + {} | f | f | f | f + {} | f | f | f | f + {(,5)} | f | t | f | f + {(,)} | f | t | f | t + {(,)} | f | t | f | t + {[1.1,2.2)} | t | f | f | f + {[1.7,1.7],[1.9,2.1)} | t | f | f | f + {[1.7,1.9)} | t | f | f | f + {[3,)} | t | f | f | t +(11 rows) + +SELECT * FROM nummultirange_test WHERE nmr = '{}'; + nmr +----- + {} + {} + {} + {} +(4 rows) + +SELECT * FROM nummultirange_test WHERE nmr = '{(,5)}'; + nmr +-------- + {(,5)} +(1 row) + +SELECT * FROM nummultirange_test WHERE nmr = '{[3,)}'; + nmr +-------- + {[3,)} +(1 row) + +SELECT * FROM nummultirange_test WHERE nmr = '{[1.7,1.7]}'; + nmr +----- +(0 rows) + +SELECT * FROM nummultirange_test WHERE nmr = '{[1.7,1.7],[1.9,2.1)}'; + nmr +----------------------- + {[1.7,1.7],[1.9,2.1)} +(1 row) + +SELECT * FROM nummultirange_test WHERE nmr < '{}'; + nmr +----- +(0 rows) + +SELECT * FROM nummultirange_test WHERE nmr < '{[-1000.0, -1000.0]}'; + nmr +-------- + {} + {(,)} + {(,)} + {(,5)} + {} + {} + {} +(7 rows) + +SELECT * FROM nummultirange_test WHERE nmr < '{[0.0, 1.0]}'; + nmr +-------- + {} + {(,)} + {(,)} + {(,5)} + {} + {} + {} +(7 rows) + +SELECT * FROM nummultirange_test WHERE nmr < '{[1000.0, 1001.0]}'; + nmr +----------------------- + {} + {(,)} + {[3,)} + {(,)} + {(,5)} + {} + {} + {[1.1,2.2)} + {} + {[1.7,1.9)} + {[1.7,1.7],[1.9,2.1)} +(11 rows) + +SELECT * FROM nummultirange_test WHERE nmr <= '{}'; + nmr +----- + {} + {} + {} + {} +(4 rows) + +SELECT * FROM nummultirange_test WHERE nmr <= '{[3,)}'; + nmr +----------------------- + {} + {(,)} + {[3,)} + {(,)} + {(,5)} + {} + {} + {[1.1,2.2)} + {} + {[1.7,1.9)} + {[1.7,1.7],[1.9,2.1)} +(11 rows) + +SELECT * FROM nummultirange_test WHERE nmr >= '{}'; + nmr +----------------------- + {} + {(,)} + {[3,)} + {(,)} + {(,5)} + {} + {} + {[1.1,2.2)} + {} + {[1.7,1.9)} + {[1.7,1.7],[1.9,2.1)} +(11 rows) + +SELECT * FROM nummultirange_test WHERE nmr >= '{[3,)}'; + nmr +-------- + {[3,)} +(1 row) + +SELECT * FROM nummultirange_test WHERE nmr > '{}'; + nmr +----------------------- + {(,)} + {[3,)} + {(,)} + {(,5)} + {[1.1,2.2)} + {[1.7,1.9)} + {[1.7,1.7],[1.9,2.1)} +(7 rows) + +SELECT * FROM nummultirange_test WHERE nmr > '{[-1000.0, -1000.0]}'; + nmr +----------------------- + {[3,)} + {[1.1,2.2)} + {[1.7,1.9)} + {[1.7,1.7],[1.9,2.1)} +(4 rows) + +SELECT * FROM nummultirange_test WHERE nmr > '{[0.0, 1.0]}'; + nmr +----------------------- + {[3,)} + {[1.1,2.2)} + {[1.7,1.9)} + {[1.7,1.7],[1.9,2.1)} +(4 rows) + +SELECT * FROM nummultirange_test WHERE nmr > '{[1000.0, 1001.0]}'; + nmr +----- +(0 rows) + +SELECT * FROM nummultirange_test WHERE nmr <> '{}'; + nmr +----------------------- + {(,)} + {[3,)} + {(,)} + {(,5)} + {[1.1,2.2)} + {[1.7,1.9)} + {[1.7,1.7],[1.9,2.1)} +(7 rows) + +SELECT * FROM nummultirange_test WHERE nmr <> '{(,5)}'; + nmr +----------------------- + {} + {(,)} + {[3,)} + {(,)} + {} + {} + {[1.1,2.2)} + {} + {[1.7,1.9)} + {[1.7,1.7],[1.9,2.1)} +(10 rows) + +select nummultirange(numrange(2.0, 1.0)); +ERROR: range lower bound must be less than or equal to range upper bound +select nummultirange(numrange(5.0, 6.0), numrange(1.0, 2.0)); + nummultirange +----------------------- + {[1.0,2.0),[5.0,6.0)} +(1 row) + +analyze nummultirange_test; +-- overlaps +SELECT * FROM nummultirange_test WHERE range_overlaps_multirange(numrange(4.0, 4.2), nmr); + nmr +-------- + {(,)} + {[3,)} + {(,)} + {(,5)} +(4 rows) + +SELECT * FROM nummultirange_test WHERE numrange(4.0, 4.2) && nmr; + nmr +-------- + {(,)} + {[3,)} + {(,)} + {(,5)} +(4 rows) + +SELECT * FROM nummultirange_test WHERE multirange_overlaps_range(nmr, numrange(4.0, 4.2)); + nmr +-------- + {(,)} + {[3,)} + {(,)} + {(,5)} +(4 rows) + +SELECT * FROM nummultirange_test WHERE nmr && numrange(4.0, 4.2); + nmr +-------- + {(,)} + {[3,)} + {(,)} + {(,5)} +(4 rows) + +SELECT * FROM nummultirange_test WHERE multirange_overlaps_multirange(nmr, nummultirange(numrange(4.0, 4.2), numrange(6.0, 7.0))); + nmr +-------- + {(,)} + {[3,)} + {(,)} + {(,5)} +(4 rows) + +SELECT * FROM nummultirange_test WHERE nmr && nummultirange(numrange(4.0, 4.2), numrange(6.0, 7.0)); + nmr +-------- + {(,)} + {[3,)} + {(,)} + {(,5)} +(4 rows) + +SELECT * FROM nummultirange_test WHERE nmr && nummultirange(numrange(6.0, 7.0)); + nmr +-------- + {(,)} + {[3,)} + {(,)} +(3 rows) + +SELECT * FROM nummultirange_test WHERE nmr && nummultirange(numrange(6.0, 7.0), numrange(8.0, 9.0)); + nmr +-------- + {(,)} + {[3,)} + {(,)} +(3 rows) + +-- mr contains x +SELECT * FROM nummultirange_test WHERE multirange_contains_elem(nmr, 4.0); + nmr +-------- + {(,)} + {[3,)} + {(,)} + {(,5)} +(4 rows) + +SELECT * FROM nummultirange_test WHERE nmr @> 4.0; + nmr +-------- + {(,)} + {[3,)} + {(,)} + {(,5)} +(4 rows) + +SELECT * FROM nummultirange_test WHERE multirange_contains_range(nmr, numrange(4.0, 4.2)); + nmr +-------- + {(,)} + {[3,)} + {(,)} + {(,5)} +(4 rows) + +SELECT * FROM nummultirange_test WHERE nmr @> numrange(4.0, 4.2); + nmr +-------- + {(,)} + {[3,)} + {(,)} + {(,5)} +(4 rows) + +SELECT * FROM nummultirange_test WHERE multirange_contains_multirange(nmr, '{[4.0,4.2), [6.0, 8.0)}'); + nmr +-------- + {(,)} + {[3,)} + {(,)} +(3 rows) + +SELECT * FROM nummultirange_test WHERE nmr @> '{[4.0,4.2), [6.0, 8.0)}'::nummultirange; + nmr +-------- + {(,)} + {[3,)} + {(,)} +(3 rows) + +-- x is contained by mr +SELECT * FROM nummultirange_test WHERE elem_contained_by_multirange(4.0, nmr); + nmr +-------- + {(,)} + {[3,)} + {(,)} + {(,5)} +(4 rows) + +SELECT * FROM nummultirange_test WHERE 4.0 <@ nmr; + nmr +-------- + {(,)} + {[3,)} + {(,)} + {(,5)} +(4 rows) + +SELECT * FROM nummultirange_test WHERE range_contained_by_multirange(numrange(4.0, 4.2), nmr); + nmr +-------- + {(,)} + {[3,)} + {(,)} + {(,5)} +(4 rows) + +SELECT * FROM nummultirange_test WHERE numrange(4.0, 4.2) <@ nmr; + nmr +-------- + {(,)} + {[3,)} + {(,)} + {(,5)} +(4 rows) + +SELECT * FROM nummultirange_test WHERE multirange_contained_by_multirange('{[4.0,4.2), [6.0, 8.0)}', nmr); + nmr +-------- + {(,)} + {[3,)} + {(,)} +(3 rows) + +SELECT * FROM nummultirange_test WHERE '{[4.0,4.2), [6.0, 8.0)}'::nummultirange <@ nmr; + nmr +-------- + {(,)} + {[3,)} + {(,)} +(3 rows) + +-- overlaps +SELECT 'empty'::numrange && nummultirange(); + ?column? +---------- + f +(1 row) + +SELECT 'empty'::numrange && nummultirange(numrange(1,2)); + ?column? +---------- + f +(1 row) + +SELECT nummultirange() && 'empty'::numrange; + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(1,2)) && 'empty'::numrange; + ?column? +---------- + f +(1 row) + +SELECT nummultirange() && nummultirange(); + ?column? +---------- + f +(1 row) + +SELECT nummultirange() && nummultirange(numrange(1,2)); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(1,2)) && nummultirange(); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(3,4)) && nummultirange(numrange(1,2), numrange(7,8)); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(1,2), numrange(7,8)) && nummultirange(numrange(3,4)); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(3,4)) && nummultirange(numrange(1,2), numrange(3.5,8)); + ?column? +---------- + t +(1 row) + +SELECT nummultirange(numrange(1,2), numrange(3.5,8)) && numrange(3,4); + ?column? +---------- + t +(1 row) + +SELECT nummultirange(numrange(1,2), numrange(3.5,8)) && nummultirange(numrange(3,4)); + ?column? +---------- + t +(1 row) + +-- contains +SELECT nummultirange() @> nummultirange(); + ?column? +---------- + t +(1 row) + +SELECT nummultirange() @> 'empty'::numrange; + ?column? +---------- + t +(1 row) + +SELECT nummultirange(numrange(null,null)) @> numrange(1,2); + ?column? +---------- + t +(1 row) + +SELECT nummultirange(numrange(null,null)) @> numrange(null,2); + ?column? +---------- + t +(1 row) + +SELECT nummultirange(numrange(null,null)) @> numrange(2,null); + ?column? +---------- + t +(1 row) + +SELECT nummultirange(numrange(null,5)) @> numrange(null,3); + ?column? +---------- + t +(1 row) + +SELECT nummultirange(numrange(null,5)) @> numrange(null,8); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(5,null)) @> numrange(8,null); + ?column? +---------- + t +(1 row) + +SELECT nummultirange(numrange(5,null)) @> numrange(3,null); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(1,5)) @> numrange(8,9); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(1,5)) @> numrange(3,9); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(1,5)) @> numrange(1,4); + ?column? +---------- + t +(1 row) + +SELECT nummultirange(numrange(1,5)) @> numrange(1,5); + ?column? +---------- + t +(1 row) + +SELECT nummultirange(numrange(-4,-2), numrange(1,5)) @> numrange(1,5); + ?column? +---------- + t +(1 row) + +SELECT nummultirange(numrange(1,5), numrange(8,9)) @> numrange(1,5); + ?column? +---------- + t +(1 row) + +SELECT nummultirange(numrange(1,5), numrange(8,9)) @> numrange(6,7); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(1,5), numrange(6,9)) @> numrange(6,7); + ?column? +---------- + t +(1 row) + +SELECT '{[1,5)}'::nummultirange @> '{[1,5)}'; + ?column? +---------- + t +(1 row) + +SELECT '{[-4,-2), [1,5)}'::nummultirange @> '{[1,5)}'; + ?column? +---------- + t +(1 row) + +SELECT '{[1,5), [8,9)}'::nummultirange @> '{[1,5)}'; + ?column? +---------- + t +(1 row) + +SELECT '{[1,5), [8,9)}'::nummultirange @> '{[6,7)}'; + ?column? +---------- + f +(1 row) + +SELECT '{[1,5), [6,9)}'::nummultirange @> '{[6,7)}'; + ?column? +---------- + t +(1 row) + +-- is contained by +SELECT nummultirange() <@ nummultirange(); + ?column? +---------- + t +(1 row) + +SELECT 'empty'::numrange <@ nummultirange(); + ?column? +---------- + t +(1 row) + +SELECT numrange(1,2) <@ nummultirange(numrange(null,null)); + ?column? +---------- + t +(1 row) + +SELECT numrange(null,2) <@ nummultirange(numrange(null,null)); + ?column? +---------- + t +(1 row) + +SELECT numrange(2,null) <@ nummultirange(numrange(null,null)); + ?column? +---------- + t +(1 row) + +SELECT numrange(null,3) <@ nummultirange(numrange(null,5)); + ?column? +---------- + t +(1 row) + +SELECT numrange(null,8) <@ nummultirange(numrange(null,5)); + ?column? +---------- + f +(1 row) + +SELECT numrange(8,null) <@ nummultirange(numrange(5,null)); + ?column? +---------- + t +(1 row) + +SELECT numrange(3,null) <@ nummultirange(numrange(5,null)); + ?column? +---------- + f +(1 row) + +SELECT numrange(8,9) <@ nummultirange(numrange(1,5)); + ?column? +---------- + f +(1 row) + +SELECT numrange(3,9) <@ nummultirange(numrange(1,5)); + ?column? +---------- + f +(1 row) + +SELECT numrange(1,4) <@ nummultirange(numrange(1,5)); + ?column? +---------- + t +(1 row) + +SELECT numrange(1,5) <@ nummultirange(numrange(1,5)); + ?column? +---------- + t +(1 row) + +SELECT numrange(1,5) <@ nummultirange(numrange(-4,-2), numrange(1,5)); + ?column? +---------- + t +(1 row) + +SELECT numrange(1,5) <@ nummultirange(numrange(1,5), numrange(8,9)); + ?column? +---------- + t +(1 row) + +SELECT numrange(6,7) <@ nummultirange(numrange(1,5), numrange(8,9)); + ?column? +---------- + f +(1 row) + +SELECT numrange(6,7) <@ nummultirange(numrange(1,5), numrange(6,9)); + ?column? +---------- + t +(1 row) + +SELECT '{[1,5)}' <@ '{[1,5)}'::nummultirange; + ?column? +---------- + t +(1 row) + +SELECT '{[1,5)}' <@ '{[-4,-2), [1,5)}'::nummultirange; + ?column? +---------- + t +(1 row) + +SELECT '{[1,5)}' <@ '{[1,5), [8,9)}'::nummultirange; + ?column? +---------- + t +(1 row) + +SELECT '{[6,7)}' <@ '{[1,5), [8,9)}'::nummultirange; + ?column? +---------- + f +(1 row) + +SELECT '{[6,7)}' <@ '{[1,5), [6,9)}'::nummultirange; + ?column? +---------- + t +(1 row) + +-- overleft +SELECT 'empty'::numrange &< nummultirange(); + ?column? +---------- + f +(1 row) + +SELECT 'empty'::numrange &< nummultirange(numrange(1,2)); + ?column? +---------- + f +(1 row) + +SELECT nummultirange() &< 'empty'::numrange; + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(1,2)) &< 'empty'::numrange; + ?column? +---------- + f +(1 row) + +SELECT nummultirange() &< nummultirange(); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(1,2)) &< nummultirange(); + ?column? +---------- + f +(1 row) + +SELECT nummultirange() &< nummultirange(numrange(1,2)); + ?column? +---------- + f +(1 row) + +SELECT numrange(6,7) &< nummultirange(numrange(3,4)); + ?column? +---------- + f +(1 row) + +SELECT numrange(1,2) &< nummultirange(numrange(3,4)); + ?column? +---------- + t +(1 row) + +SELECT numrange(1,4) &< nummultirange(numrange(3,4)); + ?column? +---------- + t +(1 row) + +SELECT numrange(1,6) &< nummultirange(numrange(3,4)); + ?column? +---------- + f +(1 row) + +SELECT numrange(3.5,6) &< nummultirange(numrange(3,4)); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(6,7)) &< numrange(3,4); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(1,2)) &< numrange(3,4); + ?column? +---------- + t +(1 row) + +SELECT nummultirange(numrange(1,4)) &< numrange(3,4); + ?column? +---------- + t +(1 row) + +SELECT nummultirange(numrange(1,6)) &< numrange(3,4); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(3.5,6)) &< numrange(3,4); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(6,7)) &< nummultirange(numrange(3,4)); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(1,2)) &< nummultirange(numrange(3,4)); + ?column? +---------- + t +(1 row) + +SELECT nummultirange(numrange(1,4)) &< nummultirange(numrange(3,4)); + ?column? +---------- + t +(1 row) + +SELECT nummultirange(numrange(1,6)) &< nummultirange(numrange(3,4)); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(3.5,6)) &< nummultirange(numrange(3,4)); + ?column? +---------- + f +(1 row) + +-- overright +SELECT nummultirange() &> 'empty'::numrange; + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(1,2)) &> 'empty'::numrange; + ?column? +---------- + f +(1 row) + +SELECT 'empty'::numrange &> nummultirange(); + ?column? +---------- + f +(1 row) + +SELECT 'empty'::numrange &> nummultirange(numrange(1,2)); + ?column? +---------- + f +(1 row) + +SELECT nummultirange() &> nummultirange(); + ?column? +---------- + f +(1 row) + +SELECT nummultirange() &> nummultirange(numrange(1,2)); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(1,2)) &> nummultirange(); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(3,4)) &> numrange(6,7); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(3,4)) &> numrange(1,2); + ?column? +---------- + t +(1 row) + +SELECT nummultirange(numrange(3,4)) &> numrange(1,4); + ?column? +---------- + t +(1 row) + +SELECT nummultirange(numrange(3,4)) &> numrange(1,6); + ?column? +---------- + t +(1 row) + +SELECT nummultirange(numrange(3,4)) &> numrange(3.5,6); + ?column? +---------- + f +(1 row) + +SELECT numrange(3,4) &> nummultirange(numrange(6,7)); + ?column? +---------- + f +(1 row) + +SELECT numrange(3,4) &> nummultirange(numrange(1,2)); + ?column? +---------- + t +(1 row) + +SELECT numrange(3,4) &> nummultirange(numrange(1,4)); + ?column? +---------- + t +(1 row) + +SELECT numrange(3,4) &> nummultirange(numrange(1,6)); + ?column? +---------- + t +(1 row) + +SELECT numrange(3,4) &> nummultirange(numrange(3.5,6)); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(3,4)) &> nummultirange(numrange(6,7)); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(3,4)) &> nummultirange(numrange(1,2)); + ?column? +---------- + t +(1 row) + +SELECT nummultirange(numrange(3,4)) &> nummultirange(numrange(1,4)); + ?column? +---------- + t +(1 row) + +SELECT nummultirange(numrange(3,4)) &> nummultirange(numrange(1,6)); + ?column? +---------- + t +(1 row) + +SELECT nummultirange(numrange(3,4)) &> nummultirange(numrange(3.5,6)); + ?column? +---------- + f +(1 row) + +-- meets +SELECT 'empty'::numrange -|- nummultirange(); + ?column? +---------- + f +(1 row) + +SELECT 'empty'::numrange -|- nummultirange(numrange(1,2)); + ?column? +---------- + f +(1 row) + +SELECT nummultirange() -|- 'empty'::numrange; + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(1,2)) -|- 'empty'::numrange; + ?column? +---------- + f +(1 row) + +SELECT nummultirange() -|- nummultirange(); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(1,2)) -|- nummultirange(); + ?column? +---------- + f +(1 row) + +SELECT nummultirange() -|- nummultirange(numrange(1,2)); + ?column? +---------- + f +(1 row) + +SELECT numrange(1,2) -|- nummultirange(numrange(2,4)); + ?column? +---------- + t +(1 row) + +SELECT numrange(1,2) -|- nummultirange(numrange(3,4)); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(1,2)) -|- numrange(2,4); + ?column? +---------- + t +(1 row) + +SELECT nummultirange(numrange(1,2)) -|- numrange(3,4); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(1,2)) -|- nummultirange(numrange(2,4)); + ?column? +---------- + t +(1 row) + +SELECT nummultirange(numrange(1,2)) -|- nummultirange(numrange(3,4)); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(1,2), numrange(5,6)) -|- nummultirange(numrange(3,4)); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(1,2), numrange(5,6)) -|- nummultirange(numrange(6,7)); + ?column? +---------- + t +(1 row) + +SELECT nummultirange(numrange(1,2), numrange(5,6)) -|- nummultirange(numrange(8,9)); + ?column? +---------- + f +(1 row) + +SELECT nummultirange(numrange(1,2)) -|- nummultirange(numrange(2,4), numrange(6,7)); + ?column? +---------- + t +(1 row) + +-- strictly left +select 'empty'::numrange << nummultirange(); + ?column? +---------- + f +(1 row) + +select numrange(1,2) << nummultirange(); + ?column? +---------- + f +(1 row) + +select numrange(1,2) << nummultirange(numrange(3,4)); + ?column? +---------- + t +(1 row) + +select numrange(1,2) << nummultirange(numrange(0,4)); + ?column? +---------- + f +(1 row) + +select numrange(1,2) << nummultirange(numrange(0,4), numrange(7,8)); + ?column? +---------- + f +(1 row) + +select nummultirange() << 'empty'::numrange; + ?column? +---------- + f +(1 row) + +select nummultirange() << numrange(1,2); + ?column? +---------- + f +(1 row) + +select nummultirange(numrange(3,4)) << numrange(3,6); + ?column? +---------- + f +(1 row) + +select nummultirange(numrange(0,2)) << numrange(3,6); + ?column? +---------- + t +(1 row) + +select nummultirange(numrange(0,2), numrange(7,8)) << numrange(3,6); + ?column? +---------- + f +(1 row) + +select nummultirange(numrange(-4,-2), numrange(0,2)) << numrange(3,6); + ?column? +---------- + t +(1 row) + +select nummultirange() << nummultirange(); + ?column? +---------- + f +(1 row) + +select nummultirange() << nummultirange(numrange(1,2)); + ?column? +---------- + f +(1 row) + +select nummultirange(numrange(1,2)) << nummultirange(); + ?column? +---------- + f +(1 row) + +select nummultirange(numrange(1,2)) << nummultirange(numrange(1,2)); + ?column? +---------- + f +(1 row) + +select nummultirange(numrange(1,2)) << nummultirange(numrange(3,4)); + ?column? +---------- + t +(1 row) + +select nummultirange(numrange(1,2)) << nummultirange(numrange(3,4), numrange(7,8)); + ?column? +---------- + t +(1 row) + +select nummultirange(numrange(1,2), numrange(4,5)) << nummultirange(numrange(3,4), numrange(7,8)); + ?column? +---------- + f +(1 row) + +-- strictly right +select nummultirange() >> 'empty'::numrange; + ?column? +---------- + f +(1 row) + +select nummultirange() >> numrange(1,2); + ?column? +---------- + f +(1 row) + +select nummultirange(numrange(3,4)) >> numrange(1,2); + ?column? +---------- + t +(1 row) + +select nummultirange(numrange(0,4)) >> numrange(1,2); + ?column? +---------- + f +(1 row) + +select nummultirange(numrange(0,4), numrange(7,8)) >> numrange(1,2); + ?column? +---------- + f +(1 row) + +select 'empty'::numrange >> nummultirange(); + ?column? +---------- + f +(1 row) + +select numrange(1,2) >> nummultirange(); + ?column? +---------- + f +(1 row) + +select numrange(3,6) >> nummultirange(numrange(3,4)); + ?column? +---------- + f +(1 row) + +select numrange(3,6) >> nummultirange(numrange(0,2)); + ?column? +---------- + t +(1 row) + +select numrange(3,6) >> nummultirange(numrange(0,2), numrange(7,8)); + ?column? +---------- + f +(1 row) + +select numrange(3,6) >> nummultirange(numrange(-4,-2), numrange(0,2)); + ?column? +---------- + t +(1 row) + +select nummultirange() >> nummultirange(); + ?column? +---------- + f +(1 row) + +select nummultirange(numrange(1,2)) >> nummultirange(); + ?column? +---------- + f +(1 row) + +select nummultirange() >> nummultirange(numrange(1,2)); + ?column? +---------- + f +(1 row) + +select nummultirange(numrange(1,2)) >> nummultirange(numrange(1,2)); + ?column? +---------- + f +(1 row) + +select nummultirange(numrange(3,4)) >> nummultirange(numrange(1,2)); + ?column? +---------- + t +(1 row) + +select nummultirange(numrange(3,4), numrange(7,8)) >> nummultirange(numrange(1,2)); + ?column? +---------- + t +(1 row) + +select nummultirange(numrange(3,4), numrange(7,8)) >> nummultirange(numrange(1,2), numrange(4,5)); + ?column? +---------- + f +(1 row) + +-- union +SELECT nummultirange() + nummultirange(); + ?column? +---------- + {} +(1 row) + +SELECT nummultirange() + nummultirange(numrange(1,2)); + ?column? +---------- + {[1,2)} +(1 row) + +SELECT nummultirange(numrange(1,2)) + nummultirange(); + ?column? +---------- + {[1,2)} +(1 row) + +SELECT nummultirange(numrange(1,2)) + nummultirange(numrange(1,2)); + ?column? +---------- + {[1,2)} +(1 row) + +SELECT nummultirange(numrange(1,2)) + nummultirange(numrange(2,4)); + ?column? +---------- + {[1,4)} +(1 row) + +SELECT nummultirange(numrange(1,2)) + nummultirange(numrange(3,4)); + ?column? +--------------- + {[1,2),[3,4)} +(1 row) + +SELECT nummultirange(numrange(1,2), numrange(4,5)) + nummultirange(numrange(2,4)); + ?column? +---------- + {[1,5)} +(1 row) + +SELECT nummultirange(numrange(1,2), numrange(4,5)) + nummultirange(numrange(3,4)); + ?column? +--------------- + {[1,2),[3,5)} +(1 row) + +SELECT nummultirange(numrange(1,2), numrange(4,5)) + nummultirange(numrange(0,9)); + ?column? +---------- + {[0,9)} +(1 row) + +-- merge +SELECT range_merge(nummultirange()); + range_merge +------------- + empty +(1 row) + +SELECT range_merge(nummultirange(numrange(1,2))); + range_merge +------------- + [1,2) +(1 row) + +SELECT range_merge(nummultirange(numrange(1,2), numrange(7,8))); + range_merge +------------- + [1,8) +(1 row) + +-- minus +SELECT nummultirange() - nummultirange(); + ?column? +---------- + {} +(1 row) + +SELECT nummultirange() - nummultirange(numrange(1,2)); + ?column? +---------- + {} +(1 row) + +SELECT nummultirange(numrange(1,2)) - nummultirange(); + ?column? +---------- + {[1,2)} +(1 row) + +SELECT nummultirange(numrange(1,2), numrange(3,4)) - nummultirange(); + ?column? +--------------- + {[1,2),[3,4)} +(1 row) + +SELECT nummultirange(numrange(1,2)) - nummultirange(numrange(1,2)); + ?column? +---------- + {} +(1 row) + +SELECT nummultirange(numrange(1,2)) - nummultirange(numrange(2,4)); + ?column? +---------- + {[1,2)} +(1 row) + +SELECT nummultirange(numrange(1,2)) - nummultirange(numrange(3,4)); + ?column? +---------- + {[1,2)} +(1 row) + +SELECT nummultirange(numrange(1,4)) - nummultirange(numrange(1,2)); + ?column? +---------- + {[2,4)} +(1 row) + +SELECT nummultirange(numrange(1,4)) - nummultirange(numrange(2,3)); + ?column? +--------------- + {[1,2),[3,4)} +(1 row) + +SELECT nummultirange(numrange(1,4)) - nummultirange(numrange(0,8)); + ?column? +---------- + {} +(1 row) + +SELECT nummultirange(numrange(1,4)) - nummultirange(numrange(0,2)); + ?column? +---------- + {[2,4)} +(1 row) + +SELECT nummultirange(numrange(1,8)) - nummultirange(numrange(0,2), numrange(3,4)); + ?column? +--------------- + {[2,3),[4,8)} +(1 row) + +SELECT nummultirange(numrange(1,8)) - nummultirange(numrange(2,3), numrange(5,null)); + ?column? +--------------- + {[1,2),[3,5)} +(1 row) + +SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(-2,0)); + ?column? +--------------- + {[1,2),[4,5)} +(1 row) + +SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(2,4)); + ?column? +--------------- + {[1,2),[4,5)} +(1 row) + +SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(3,5)); + ?column? +---------- + {[1,2)} +(1 row) + +SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(0,9)); + ?column? +---------- + {} +(1 row) + +SELECT nummultirange(numrange(1,3), numrange(4,5)) - nummultirange(numrange(2,9)); + ?column? +---------- + {[1,2)} +(1 row) + +SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(8,9)); + ?column? +--------------- + {[1,2),[4,5)} +(1 row) + +SELECT nummultirange(numrange(1,2), numrange(4,5)) - nummultirange(numrange(-2,0), numrange(8,9)); + ?column? +--------------- + {[1,2),[4,5)} +(1 row) + +-- intersection +SELECT nummultirange() * nummultirange(); + ?column? +---------- + {} +(1 row) + +SELECT nummultirange() * nummultirange(numrange(1,2)); + ?column? +---------- + {} +(1 row) + +SELECT nummultirange(numrange(1,2)) * nummultirange(); + ?column? +---------- + {} +(1 row) + +SELECT '{[1,3)}'::nummultirange * '{[1,5)}'::nummultirange; + ?column? +---------- + {[1,3)} +(1 row) + +SELECT '{[1,3)}'::nummultirange * '{[0,5)}'::nummultirange; + ?column? +---------- + {[1,3)} +(1 row) + +SELECT '{[1,3)}'::nummultirange * '{[0,2)}'::nummultirange; + ?column? +---------- + {[1,2)} +(1 row) + +SELECT '{[1,3)}'::nummultirange * '{[2,5)}'::nummultirange; + ?column? +---------- + {[2,3)} +(1 row) + +SELECT '{[1,4)}'::nummultirange * '{[2,3)}'::nummultirange; + ?column? +---------- + {[2,3)} +(1 row) + +SELECT '{[1,4)}'::nummultirange * '{[0,2), [3,5)}'::nummultirange; + ?column? +--------------- + {[1,2),[3,4)} +(1 row) + +SELECT '{[1,4), [7,10)}'::nummultirange * '{[0,8), [9,12)}'::nummultirange; + ?column? +---------------------- + {[1,4),[7,8),[9,10)} +(1 row) + +SELECT '{[1,4), [7,10)}'::nummultirange * '{[9,12)}'::nummultirange; + ?column? +---------- + {[9,10)} +(1 row) + +SELECT '{[1,4), [7,10)}'::nummultirange * '{[-5,-4), [5,6), [9,12)}'::nummultirange; + ?column? +---------- + {[9,10)} +(1 row) + +SELECT '{[1,4), [7,10)}'::nummultirange * '{[0,2), [3,8), [9,12)}'::nummultirange; + ?column? +---------------------------- + {[1,2),[3,4),[7,8),[9,10)} +(1 row) + +SELECT '{[1,4), [7,10)}'::nummultirange * '{[0,2), [3,8), [9,12)}'::nummultirange; + ?column? +---------------------------- + {[1,2),[3,4),[7,8),[9,10)} +(1 row) + +-- +-- range_agg function +-- +create table reservations ( room_id integer not null, booked_during daterange ); +insert into reservations values +-- 1: has a meets and a gap +(1, daterange('2018-07-01', '2018-07-07')), +(1, daterange('2018-07-07', '2018-07-14')), +(1, daterange('2018-07-20', '2018-07-22')), +-- 2: just a single row +(2, daterange('2018-07-01', '2018-07-03')), +-- 3: one null range +(3, NULL), +-- 4: two null ranges +(4, NULL), +(4, NULL), +-- 5: a null range and a non-null range +(5, NULL), +(5, daterange('2018-07-01', '2018-07-03')), +-- 6: has overlap +(6, daterange('2018-07-01', '2018-07-07')), +(6, daterange('2018-07-05', '2018-07-10')), +-- 7: two ranges that meet: no gap or overlap +(7, daterange('2018-07-01', '2018-07-07')), +(7, daterange('2018-07-07', '2018-07-14')), +-- 8: an empty range +(8, 'empty'::daterange) +; +SELECT room_id, range_agg(booked_during) +FROM reservations +GROUP BY room_id +ORDER BY room_id; + room_id | range_agg +---------+--------------------------------------------------- + 1 | {[07-01-2018,07-14-2018),[07-20-2018,07-22-2018)} + 2 | {[07-01-2018,07-03-2018)} + 3 | + 4 | + 5 | {[07-01-2018,07-03-2018)} + 6 | {[07-01-2018,07-10-2018)} + 7 | {[07-01-2018,07-14-2018)} + 8 | {} +(8 rows) + +-- range_agg on a custom range type too +SELECT range_agg(r) +FROM (VALUES + ('[a,c]'::textrange), + ('[b,b]'::textrange), + ('[c,f]'::textrange), + ('[g,h)'::textrange), + ('[h,j)'::textrange) + ) t(r); + range_agg +--------------- + {[a,f],[g,j)} +(1 row) + +select range_intersect_agg(nmr) from nummultirange_test; + range_intersect_agg +--------------------- + {} +(1 row) + +select range_intersect_agg(nmr) from nummultirange_test where false; + range_intersect_agg +--------------------- + +(1 row) + +-- test with just one input: +select range_intersect_agg(nmr) from (values ('{[1,2]}'::nummultirange)) t(nmr); + range_intersect_agg +--------------------- + {[1,2]} +(1 row) + +select range_intersect_agg(nmr) from nummultirange_test where nmr @> 4.0; + range_intersect_agg +--------------------- + {[3,5)} +(1 row) + +create table nummultirange_test2(nmr nummultirange); +create index nummultirange_test2_hash_idx on nummultirange_test2 using hash (nmr); +INSERT INTO nummultirange_test2 VALUES('{[, 5)}'); +INSERT INTO nummultirange_test2 VALUES(nummultirange(numrange(1.1, 2.2))); +INSERT INTO nummultirange_test2 VALUES(nummultirange(numrange(1.1, 2.2))); +INSERT INTO nummultirange_test2 VALUES(nummultirange(numrange(1.1, 2.2,'()'))); +INSERT INTO nummultirange_test2 VALUES('{}'); +select * from nummultirange_test2 where nmr = '{}'; + nmr +----- + {} +(1 row) + +select * from nummultirange_test2 where nmr = nummultirange(numrange(1.1, 2.2)); + nmr +------------- + {[1.1,2.2)} + {[1.1,2.2)} +(2 rows) + +select * from nummultirange_test2 where nmr = nummultirange(numrange(1.1, 2.3)); + nmr +----- +(0 rows) + +set enable_nestloop=t; +set enable_hashjoin=f; +set enable_mergejoin=f; +select * from nummultirange_test natural join nummultirange_test2 order by nmr; + nmr +------------- + {} + {} + {} + {} + {(,5)} + {[1.1,2.2)} + {[1.1,2.2)} +(7 rows) + +set enable_nestloop=f; +set enable_hashjoin=t; +set enable_mergejoin=f; +select * from nummultirange_test natural join nummultirange_test2 order by nmr; + nmr +------------- + {} + {} + {} + {} + {(,5)} + {[1.1,2.2)} + {[1.1,2.2)} +(7 rows) + +set enable_nestloop=f; +set enable_hashjoin=f; +set enable_mergejoin=t; +select * from nummultirange_test natural join nummultirange_test2 order by nmr; + nmr +------------- + {} + {} + {} + {} + {(,5)} + {[1.1,2.2)} + {[1.1,2.2)} +(7 rows) + +set enable_nestloop to default; +set enable_hashjoin to default; +set enable_mergejoin to default; +DROP TABLE nummultirange_test2; +-- +-- Test user-defined multirange of floats +-- +select '{[123.001, 5.e9)}'::float8multirange @> 888.882::float8; + ?column? +---------- + t +(1 row) + +create table float8multirange_test(f8mr float8multirange, i int); +insert into float8multirange_test values(float8multirange(float8range(-100.00007, '1.111113e9')), 42); +select * from float8multirange_test; + f8mr | i +---------------------------+---- + {[-100.00007,1111113000)} | 42 +(1 row) + +drop table float8multirange_test; +-- +-- Test multirange types over domains +-- +create domain mydomain as int4; +create type mydomainrange as range(subtype=mydomain); +select '{[4,50)}'::mydomainmultirange @> 7::mydomain; + ?column? +---------- + t +(1 row) + +drop domain mydomain cascade; +NOTICE: drop cascades to type mydomainrange +-- +-- Test domains over multirange types +-- +create domain restrictedmultirange as int4multirange check (upper(value) < 10); +select '{[4,5)}'::restrictedmultirange @> 7; + ?column? +---------- + f +(1 row) + +select '{[4,50)}'::restrictedmultirange @> 7; -- should fail +ERROR: value for domain restrictedmultirange violates check constraint "restrictedmultirange_check" +drop domain restrictedmultirange; +--- +-- Check automatic naming of multiranges +--- +create type intr as range(subtype=int); +select intr_multirange(intr(1,10)); + intr_multirange +----------------- + {[1,10)} +(1 row) + +drop type intr; +create type intmultirange as (x int, y int); +create type intrange as range(subtype=int); -- should fail +ERROR: type "intmultirange" already exists +DETAIL: Failed while creating a multirange type for type "intrange". +HINT: You can manually specify a multirange type name using the "multirange_type_name" attribute +drop type intmultirange; +create type intr_multirange as (x int, y int); +create type intr as range(subtype=int); -- should fail +ERROR: type "intr_multirange" already exists +DETAIL: Failed while creating a multirange type for type "intr". +HINT: You can manually specify a multirange type name using the "multirange_type_name" attribute +drop type intr_multirange; +-- +-- Test multiple multirange types over the same subtype and manual naming of +-- the multirange type. +-- +-- should fail +create type textrange1 as range(subtype=text, multirange_type_name=int, collation="C"); +ERROR: type "int4" already exists +-- should pass +create type textrange1 as range(subtype=text, multirange_type_name=multirange_of_text, collation="C"); +-- should pass, because existing _textrange1 is automatically renamed +create type textrange2 as range(subtype=text, multirange_type_name=_textrange1, collation="C"); +select multirange_of_text(textrange2('a','Z')); -- should fail +ERROR: function multirange_of_text(textrange2) does not exist +LINE 1: select multirange_of_text(textrange2('a','Z')); + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +select multirange_of_text(textrange1('a','Z')) @> 'b'::text; +ERROR: range lower bound must be less than or equal to range upper bound +select _textrange1(textrange2('a','z')) @> 'b'::text; + ?column? +---------- + t +(1 row) + +drop type textrange1; +drop type textrange2; +-- +-- Test polymorphic type system +-- +create function anyarray_anymultirange_func(a anyarray, r anymultirange) + returns anyelement as 'select $1[1] + lower($2);' language sql; +select anyarray_anymultirange_func(ARRAY[1,2], int4multirange(int4range(10,20))); + anyarray_anymultirange_func +----------------------------- + 11 +(1 row) + +-- should fail +select anyarray_anymultirange_func(ARRAY[1,2], nummultirange(numrange(10,20))); +ERROR: function anyarray_anymultirange_func(integer[], nummultirange) does not exist +LINE 1: select anyarray_anymultirange_func(ARRAY[1,2], nummultirange... + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +drop function anyarray_anymultirange_func(anyarray, anymultirange); +-- should fail +create function bogus_func(anyelement) + returns anymultirange as 'select int4multirange(int4range(1,10))' language sql; +ERROR: cannot determine result data type +DETAIL: A result of type anymultirange requires at least one input of type anyrange or anymultirange. +-- should fail +create function bogus_func(int) + returns anymultirange as 'select int4multirange(int4range(1,10))' language sql; +ERROR: cannot determine result data type +DETAIL: A result of type anymultirange requires at least one input of type anyrange or anymultirange. +create function range_add_bounds(anymultirange) + returns anyelement as 'select lower($1) + upper($1)' language sql; +select range_add_bounds(int4multirange(int4range(1, 17))); + range_add_bounds +------------------ + 18 +(1 row) + +select range_add_bounds(nummultirange(numrange(1.0001, 123.123))); + range_add_bounds +------------------ + 124.1231 +(1 row) + +create function multirangetypes_sql(q anymultirange, b anyarray, out c anyelement) + as $$ select upper($1) + $2[1] $$ + language sql; +select multirangetypes_sql(int4multirange(int4range(1,10)), ARRAY[2,20]); + multirangetypes_sql +--------------------- + 12 +(1 row) + +select multirangetypes_sql(nummultirange(numrange(1,10)), ARRAY[2,20]); -- match failure +ERROR: function multirangetypes_sql(nummultirange, integer[]) does not exist +LINE 1: select multirangetypes_sql(nummultirange(numrange(1,10)), AR... + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +create function anycompatiblearray_anycompatiblemultirange_func(a anycompatiblearray, mr anycompatiblemultirange) + returns anycompatible as 'select $1[1] + lower($2);' language sql; +select anycompatiblearray_anycompatiblemultirange_func(ARRAY[1,2], multirange(int4range(10,20))); + anycompatiblearray_anycompatiblemultirange_func +------------------------------------------------- + 11 +(1 row) + +select anycompatiblearray_anycompatiblemultirange_func(ARRAY[1,2], multirange(numrange(10,20))); + anycompatiblearray_anycompatiblemultirange_func +------------------------------------------------- + 11 +(1 row) + +-- should fail +select anycompatiblearray_anycompatiblemultirange_func(ARRAY[1.1,2], multirange(int4range(10,20))); +ERROR: function anycompatiblearray_anycompatiblemultirange_func(numeric[], int4multirange) does not exist +LINE 1: select anycompatiblearray_anycompatiblemultirange_func(ARRAY... + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +drop function anycompatiblearray_anycompatiblemultirange_func(anycompatiblearray, anycompatiblemultirange); +create function anycompatiblerange_anycompatiblemultirange_func(r anycompatiblerange, mr anycompatiblemultirange) + returns anycompatible as 'select lower($1) + lower($2);' language sql; +select anycompatiblerange_anycompatiblemultirange_func(int4range(1,2), multirange(int4range(10,20))); + anycompatiblerange_anycompatiblemultirange_func +------------------------------------------------- + 11 +(1 row) + +-- should fail +select anycompatiblerange_anycompatiblemultirange_func(numrange(1,2), multirange(int4range(10,20))); +ERROR: function anycompatiblerange_anycompatiblemultirange_func(numrange, int4multirange) does not exist +LINE 1: select anycompatiblerange_anycompatiblemultirange_func(numra... + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +drop function anycompatiblerange_anycompatiblemultirange_func(anycompatiblerange, anycompatiblemultirange); +-- should fail +create function bogus_func(anycompatible) + returns anycompatiblerange as 'select int4range(1,10)' language sql; +ERROR: cannot determine result data type +DETAIL: A result of type anycompatiblerange requires at least one input of type anycompatiblerange or anycompatiblemultirange. +-- +-- Arrays of multiranges +-- +select ARRAY[nummultirange(numrange(1.1, 1.2)), nummultirange(numrange(12.3, 155.5))]; + array +---------------------------------- + {"{[1.1,1.2)}","{[12.3,155.5)}"} +(1 row) + +create table i8mr_array (f1 int, f2 int8multirange[]); +insert into i8mr_array values (42, array[int8multirange(int8range(1,10)), int8multirange(int8range(2,20))]); +select * from i8mr_array; + f1 | f2 +----+------------------------- + 42 | {"{[1,10)}","{[2,20)}"} +(1 row) + +drop table i8mr_array; +-- +-- Multiranges of arrays +-- +select arraymultirange(arrayrange(ARRAY[1,2], ARRAY[2,1])); + arraymultirange +--------------------- + {["{1,2}","{2,1}")} +(1 row) + +select arraymultirange(arrayrange(ARRAY[2,1], ARRAY[1,2])); -- fail +ERROR: range lower bound must be less than or equal to range upper bound +select array[1,1] <@ arraymultirange(arrayrange(array[1,2], array[2,1])); + ?column? +---------- + f +(1 row) + +select array[1,3] <@ arraymultirange(arrayrange(array[1,2], array[2,1])); + ?column? +---------- + t +(1 row) + +-- +-- Ranges of composites +-- +create type two_ints as (a int, b int); +create type two_ints_range as range (subtype = two_ints); +-- with force_parallel_mode on, this exercises tqueue.c's range remapping +select *, row_to_json(upper(t)) as u from + (values (two_ints_multirange(two_ints_range(row(1,2), row(3,4)))), + (two_ints_multirange(two_ints_range(row(5,6), row(7,8))))) v(t); + t | u +---------------------+--------------- + {["(1,2)","(3,4)")} | {"a":3,"b":4} + {["(5,6)","(7,8)")} | {"a":7,"b":8} +(2 rows) + +drop type two_ints cascade; +NOTICE: drop cascades to type two_ints_range +-- +-- Check behavior when subtype lacks a hash function +-- +set enable_sort = off; -- try to make it pick a hash setop implementation +select '{(2,5)}'::cashmultirange except select '{(5,6)}'::cashmultirange; + cashmultirange +----------------- + {($2.00,$5.00)} +(1 row) + +reset enable_sort; +-- +-- OUT/INOUT/TABLE functions +-- +-- infer anymultirange from anymultirange +create function mr_outparam_succeed(i anymultirange, out r anymultirange, out t text) + as $$ select $1, 'foo'::text $$ language sql; +select * from mr_outparam_succeed(int4multirange(int4range(1,2))); + r | t +---------+----- + {[1,2)} | foo +(1 row) + +-- infer anyarray from anymultirange +create function mr_outparam_succeed2(i anymultirange, out r anyarray, out t text) + as $$ select ARRAY[upper($1)], 'foo'::text $$ language sql; +select * from mr_outparam_succeed2(int4multirange(int4range(1,2))); + r | t +-----+----- + {2} | foo +(1 row) + +-- infer anyrange from anymultirange +create function mr_outparam_succeed3(i anymultirange, out r anyrange, out t text) + as $$ select range_merge($1), 'foo'::text $$ language sql; +select * from mr_outparam_succeed3(int4multirange(int4range(1,2))); + r | t +-------+----- + [1,2) | foo +(1 row) + +-- infer anymultirange from anyrange +create function mr_outparam_succeed4(i anyrange, out r anymultirange, out t text) + as $$ select multirange($1), 'foo'::text $$ language sql; +select * from mr_outparam_succeed4(int4range(1,2)); + r | t +---------+----- + {[1,2)} | foo +(1 row) + +-- infer anyelement from anymultirange +create function mr_inoutparam_succeed(out i anyelement, inout r anymultirange) + as $$ select upper($1), $1 $$ language sql; +select * from mr_inoutparam_succeed(int4multirange(int4range(1,2))); + i | r +---+--------- + 2 | {[1,2)} +(1 row) + +-- infer anyelement+anymultirange from anyelement+anymultirange +create function mr_table_succeed(i anyelement, r anymultirange) returns table(i anyelement, r anymultirange) + as $$ select $1, $2 $$ language sql; +select * from mr_table_succeed(123, int4multirange(int4range(1,11))); + i | r +-----+---------- + 123 | {[1,11)} +(1 row) + +-- use anymultirange in plpgsql +create function mr_polymorphic(i anyrange) returns anymultirange + as $$ begin return multirange($1); end; $$ language plpgsql; +select mr_polymorphic(int4range(1, 4)); + mr_polymorphic +---------------- + {[1,4)} +(1 row) + +-- should fail +create function mr_outparam_fail(i anyelement, out r anymultirange, out t text) + as $$ select '[1,10]', 'foo' $$ language sql; +ERROR: cannot determine result data type +DETAIL: A result of type anymultirange requires at least one input of type anyrange or anymultirange. +--should fail +create function mr_inoutparam_fail(inout i anyelement, out r anymultirange) + as $$ select $1, '[1,10]' $$ language sql; +ERROR: cannot determine result data type +DETAIL: A result of type anymultirange requires at least one input of type anyrange or anymultirange. +--should fail +create function mr_table_fail(i anyelement) returns table(i anyelement, r anymultirange) + as $$ select $1, '[1,10]' $$ language sql; +ERROR: cannot determine result data type +DETAIL: A result of type anymultirange requires at least one input of type anyrange or anymultirange. diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out index 507b474b1bb..254ca06d3dd 100644 --- a/src/test/regress/expected/opr_sanity.out +++ b/src/test/regress/expected/opr_sanity.out @@ -39,6 +39,10 @@ begin if (select typtype from pg_catalog.pg_type where oid = $1) = 'r' then return true; end if; end if; + if $2 = 'pg_catalog.anymultirange'::pg_catalog.regtype then + if (select typtype from pg_catalog.pg_type where oid = $1) = 'm' + then return true; end if; + end if; return false; end $$ language plpgsql strict stable; @@ -183,7 +187,8 @@ WHERE p1.oid < p2.oid AND -- need to be modified whenever new pairs of types are made binary-equivalent, -- or when new polymorphic built-in functions are added! -- Note: ignore aggregate functions here, since they all point to the same --- dummy built-in function. Likewise, ignore range constructor functions. +-- dummy built-in function. Likewise, ignore range and multirange constructor +-- functions. SELECT DISTINCT p1.prorettype::regtype, p2.prorettype::regtype FROM pg_proc AS p1, pg_proc AS p2 WHERE p1.oid != p2.oid AND @@ -192,6 +197,8 @@ WHERE p1.oid != p2.oid AND p1.prokind != 'a' AND p2.prokind != 'a' AND p1.prosrc NOT LIKE E'range\\_constructor_' AND p2.prosrc NOT LIKE E'range\\_constructor_' AND + p1.prosrc NOT LIKE E'multirange\\_constructor_' AND + p2.prosrc NOT LIKE E'multirange\\_constructor_' AND (p1.prorettype < p2.prorettype) ORDER BY 1, 2; prorettype | prorettype @@ -210,6 +217,8 @@ WHERE p1.oid != p2.oid AND p1.prokind != 'a' AND p2.prokind != 'a' AND p1.prosrc NOT LIKE E'range\\_constructor_' AND p2.prosrc NOT LIKE E'range\\_constructor_' AND + p1.prosrc NOT LIKE E'multirange\\_constructor_' AND + p2.prosrc NOT LIKE E'multirange\\_constructor_' AND (p1.proargtypes[0] < p2.proargtypes[0]) ORDER BY 1, 2; proargtypes | proargtypes @@ -230,6 +239,8 @@ WHERE p1.oid != p2.oid AND p1.prokind != 'a' AND p2.prokind != 'a' AND p1.prosrc NOT LIKE E'range\\_constructor_' AND p2.prosrc NOT LIKE E'range\\_constructor_' AND + p1.prosrc NOT LIKE E'multirange\\_constructor_' AND + p2.prosrc NOT LIKE E'multirange\\_constructor_' AND (p1.proargtypes[1] < p2.proargtypes[1]) ORDER BY 1, 2; proargtypes | proargtypes @@ -342,7 +353,8 @@ WHERE p1.prorettype IN 'anyarray'::regtype = ANY (p1.proargtypes) OR 'anynonarray'::regtype = ANY (p1.proargtypes) OR 'anyenum'::regtype = ANY (p1.proargtypes) OR - 'anyrange'::regtype = ANY (p1.proargtypes)) + 'anyrange'::regtype = ANY (p1.proargtypes) OR + 'anymultirange'::regtype = ANY (p1.proargtypes)) ORDER BY 2; oid | proname ------+---------------- @@ -357,20 +369,25 @@ ORDER BY 2; 3532 | enum_recv (9 rows) --- anyrange is tighter than the rest, can only resolve from anyrange input +-- anyrange and anymultirange are tighter than the rest, can only resolve +-- from each other SELECT p1.oid, p1.proname FROM pg_proc as p1 -WHERE p1.prorettype = 'anyrange'::regtype +WHERE p1.prorettype IN ('anyrange'::regtype, 'anymultirange'::regtype) AND NOT - 'anyrange'::regtype = ANY (p1.proargtypes) + ('anyrange'::regtype = ANY (p1.proargtypes) OR + 'anymultirange'::regtype = ANY (p1.proargtypes)) ORDER BY 2; oid | proname ------+------------------ + 4229 | anymultirange_in 3832 | anyrange_in + 4231 | multirange_in + 4233 | multirange_recv 3876 | range_gist_union 3834 | range_in 3836 | range_recv -(4 rows) +(7 rows) -- similarly for the anycompatible family SELECT p1.oid, p1.proname @@ -2204,13 +2221,14 @@ ORDER BY 1, 2, 3; | float_ops | float4_ops | real | float_ops | float8_ops | double precision | jsonb_ops | jsonb_ops | jsonb + | multirange_ops | multirange_ops | anymultirange | numeric_ops | numeric_ops | numeric | range_ops | range_ops | anyrange | record_image_ops | record_image_ops | record | record_ops | record_ops | record | tsquery_ops | tsquery_ops | tsquery | tsvector_ops | tsvector_ops | tsvector -(14 rows) +(15 rows) -- **************** pg_index **************** -- Look for illegal values in pg_index fields. diff --git a/src/test/regress/expected/plpgsql.out b/src/test/regress/expected/plpgsql.out index d0a6b630b8f..d55006d8c95 100644 --- a/src/test/regress/expected/plpgsql.out +++ b/src/test/regress/expected/plpgsql.out @@ -1811,7 +1811,7 @@ begin return array[x + 1, x + 2]; end$$ language plpgsql; ERROR: cannot determine result data type -DETAIL: A result of type anyrange requires at least one input of type anyrange. +DETAIL: A result of type anyrange requires at least one input of type anyrange or anymultirange. create function f1(x anyrange) returns anyarray as $$ begin return array[lower(x), upper(x)]; @@ -1856,7 +1856,7 @@ begin return array[x + 1, x + 2]; end$$ language plpgsql; ERROR: cannot determine result data type -DETAIL: A result of type anycompatiblerange requires at least one input of type anycompatiblerange. +DETAIL: A result of type anycompatiblerange requires at least one input of type anycompatiblerange or anycompatiblemultirange. create function f1(x anycompatiblerange, y anycompatiblearray) returns anycompatiblerange as $$ begin return x; diff --git a/src/test/regress/expected/polymorphism.out b/src/test/regress/expected/polymorphism.out index f5dfdf617fd..772345584f0 100644 --- a/src/test/regress/expected/polymorphism.out +++ b/src/test/regress/expected/polymorphism.out @@ -61,7 +61,7 @@ create function polyf(x anyelement) returns anyrange as $$ select array[x + 1, x + 2] $$ language sql; ERROR: cannot determine result data type -DETAIL: A result of type anyrange requires at least one input of type anyrange. +DETAIL: A result of type anyrange requires at least one input of type anyrange or anymultirange. create function polyf(x anyrange) returns anyarray as $$ select array[lower(x), upper(x)] $$ language sql; @@ -97,12 +97,27 @@ LINE 1: select polyf(int4range(42, 49), 11, 4.5) as fail; ^ HINT: No function matches the given name and argument types. You might need to add explicit type casts. drop function polyf(x anycompatiblerange, y anycompatible, z anycompatible); +create function polyf(x anycompatiblemultirange, y anycompatible, z anycompatible) returns anycompatiblearray as $$ + select array[lower(x), upper(x), y, z] +$$ language sql; +select polyf(multirange(int4range(42, 49)), 11, 2::smallint) as int, polyf(multirange(float8range(4.5, 7.8)), 7.8, 11::real) as num; + int | num +--------------+------------------ + {42,49,11,2} | {4.5,7.8,7.8,11} +(1 row) + +select polyf(multirange(int4range(42, 49)), 11, 4.5) as fail; -- range type doesn't fit +ERROR: function polyf(int4multirange, integer, numeric) does not exist +LINE 1: select polyf(multirange(int4range(42, 49)), 11, 4.5) as fail... + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +drop function polyf(x anycompatiblemultirange, y anycompatible, z anycompatible); -- fail, can't infer type: create function polyf(x anycompatible) returns anycompatiblerange as $$ select array[x + 1, x + 2] $$ language sql; ERROR: cannot determine result data type -DETAIL: A result of type anycompatiblerange requires at least one input of type anycompatiblerange. +DETAIL: A result of type anycompatiblerange requires at least one input of type anycompatiblerange or anycompatiblemultirange. create function polyf(x anycompatiblerange, y anycompatiblearray) returns anycompatiblerange as $$ select x $$ language sql; @@ -113,6 +128,22 @@ select polyf(int4range(42, 49), array[11]) as int, polyf(float8range(4.5, 7.8), (1 row) drop function polyf(x anycompatiblerange, y anycompatiblearray); +-- fail, can't infer type: +create function polyf(x anycompatible) returns anycompatiblemultirange as $$ + select array[x + 1, x + 2] +$$ language sql; +ERROR: cannot determine result data type +DETAIL: A result of type anycompatiblemultirange requires at least one input of type anycompatiblerange or anycompatiblemultirange. +create function polyf(x anycompatiblemultirange, y anycompatiblearray) returns anycompatiblemultirange as $$ + select x +$$ language sql; +select polyf(multirange(int4range(42, 49)), array[11]) as int, polyf(multirange(float8range(4.5, 7.8)), array[7]) as num; + int | num +-----------+------------- + {[42,49)} | {[4.5,7.8)} +(1 row) + +drop function polyf(x anycompatiblemultirange, y anycompatiblearray); create function polyf(a anyelement, b anyarray, c anycompatible, d anycompatible, OUT x anyarray, OUT y anycompatiblearray) @@ -231,7 +262,7 @@ CREATE AGGREGATE myaggp01a(*) (SFUNC = stfnp, STYPE = int4[], CREATE AGGREGATE myaggp02a(*) (SFUNC = stfnp, STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}'); ERROR: cannot determine transition data type -DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange. +DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange. -- N P -- should CREATE CREATE AGGREGATE myaggp03a(*) (SFUNC = stfp, STYPE = int4[], @@ -243,11 +274,11 @@ CREATE AGGREGATE myaggp03b(*) (SFUNC = stfp, STYPE = int4[], CREATE AGGREGATE myaggp04a(*) (SFUNC = stfp, STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}'); ERROR: cannot determine transition data type -DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange. +DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange. CREATE AGGREGATE myaggp04b(*) (SFUNC = stfp, STYPE = anyarray, INITCOND = '{}'); ERROR: cannot determine transition data type -DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange. +DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange. -- Case2 (R = P) && ((B = P) || (B = N)) -- ------------------------------------- -- S tf1 B tf2 @@ -302,13 +333,13 @@ ERROR: function tfp(integer[], anyelement) does not exist CREATE AGGREGATE myaggp13a(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}'); ERROR: cannot determine transition data type -DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange. +DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange. -- P N N P -- should ERROR: tf2p(anyarray, int) not matched by tf2p(int[],anyelement) CREATE AGGREGATE myaggp14a(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}'); ERROR: cannot determine transition data type -DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange. +DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange. -- P N P N -- should ERROR: tfnp(anyarray, anyelement) not matched by tfnp(int[],int) CREATE AGGREGATE myaggp15a(BASETYPE = anyelement, SFUNC = tfnp, @@ -324,21 +355,21 @@ ERROR: function tf2p(anyarray, anyelement) does not exist CREATE AGGREGATE myaggp17a(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}'); ERROR: cannot determine transition data type -DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange. +DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange. CREATE AGGREGATE myaggp17b(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray, INITCOND = '{}'); ERROR: cannot determine transition data type -DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange. +DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange. -- P P N P -- should ERROR: tfp(anyarray, int) not matched by tfp(anyarray, anyelement) CREATE AGGREGATE myaggp18a(BASETYPE = int, SFUNC = tfp, STYPE = anyarray, FINALFUNC = ffp, INITCOND = '{}'); ERROR: cannot determine transition data type -DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange. +DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange. CREATE AGGREGATE myaggp18b(BASETYPE = int, SFUNC = tfp, STYPE = anyarray, INITCOND = '{}'); ERROR: cannot determine transition data type -DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange. +DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange. -- P P P N -- should ERROR: tf1p(anyarray, anyelement) not matched by tf1p(anyarray, int) CREATE AGGREGATE myaggp19a(BASETYPE = anyelement, SFUNC = tf1p, @@ -368,11 +399,11 @@ CREATE AGGREGATE myaggn01b(*) (SFUNC = stfnp, STYPE = int4[], CREATE AGGREGATE myaggn02a(*) (SFUNC = stfnp, STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}'); ERROR: cannot determine transition data type -DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange. +DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange. CREATE AGGREGATE myaggn02b(*) (SFUNC = stfnp, STYPE = anyarray, INITCOND = '{}'); ERROR: cannot determine transition data type -DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange. +DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange. -- N P -- should CREATE CREATE AGGREGATE myaggn03a(*) (SFUNC = stfp, STYPE = int4[], @@ -382,7 +413,7 @@ CREATE AGGREGATE myaggn03a(*) (SFUNC = stfp, STYPE = int4[], CREATE AGGREGATE myaggn04a(*) (SFUNC = stfp, STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}'); ERROR: cannot determine transition data type -DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange. +DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange. -- Case4 (R = N) && ((B = P) || (B = N)) -- ------------------------------------- -- S tf1 B tf2 @@ -436,21 +467,21 @@ ERROR: function tfp(integer[], anyelement) does not exist CREATE AGGREGATE myaggn13a(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}'); ERROR: cannot determine transition data type -DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange. +DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange. CREATE AGGREGATE myaggn13b(BASETYPE = int, SFUNC = tfnp, STYPE = anyarray, INITCOND = '{}'); ERROR: cannot determine transition data type -DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange. +DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange. -- P N N P -- should ERROR: tf2p(anyarray, int) not matched by tf2p(int[],anyelement) CREATE AGGREGATE myaggn14a(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}'); ERROR: cannot determine transition data type -DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange. +DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange. CREATE AGGREGATE myaggn14b(BASETYPE = int, SFUNC = tf2p, STYPE = anyarray, INITCOND = '{}'); ERROR: cannot determine transition data type -DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange. +DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange. -- P N P N -- should ERROR: tfnp(anyarray, anyelement) not matched by tfnp(int[],int) CREATE AGGREGATE myaggn15a(BASETYPE = anyelement, SFUNC = tfnp, @@ -472,13 +503,13 @@ ERROR: function tf2p(anyarray, anyelement) does not exist CREATE AGGREGATE myaggn17a(BASETYPE = int, SFUNC = tf1p, STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}'); ERROR: cannot determine transition data type -DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange. +DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange. -- P P N P -- should ERROR: tfp(anyarray, int) not matched by tfp(anyarray, anyelement) CREATE AGGREGATE myaggn18a(BASETYPE = int, SFUNC = tfp, STYPE = anyarray, FINALFUNC = ffnp, INITCOND = '{}'); ERROR: cannot determine transition data type -DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange. +DETAIL: A result of type anyarray requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange. -- P P P N -- should ERROR: tf1p(anyarray, anyelement) not matched by tf1p(anyarray, int) CREATE AGGREGATE myaggn19a(BASETYPE = anyelement, SFUNC = tf1p, @@ -1855,7 +1886,59 @@ returns anycompatiblerange as $$ select $1 $$ language sql; ERROR: cannot determine result data type -DETAIL: A result of type anycompatiblerange requires at least one input of type anycompatiblerange. +DETAIL: A result of type anycompatiblerange requires at least one input of type anycompatiblerange or anycompatiblemultirange. +create function anyctest(anycompatible, anycompatiblemultirange) +returns anycompatiblemultirange as $$ + select $2 +$$ language sql; +select x, pg_typeof(x) from anyctest(11, multirange(int4range(4,7))) x; + x | pg_typeof +---------+---------------- + {[4,7)} | int4multirange +(1 row) + +select x, pg_typeof(x) from anyctest(11, multirange(numrange(4,7))) x; + x | pg_typeof +---------+--------------- + {[4,7)} | nummultirange +(1 row) + +select x, pg_typeof(x) from anyctest(11, 12) x; -- fail +ERROR: function anyctest(integer, integer) does not exist +LINE 1: select x, pg_typeof(x) from anyctest(11, 12) x; + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +select x, pg_typeof(x) from anyctest(11.2, multirange(int4range(4,7))) x; -- fail +ERROR: function anyctest(numeric, int4multirange) does not exist +LINE 1: select x, pg_typeof(x) from anyctest(11.2, multirange(int4ra... + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +select x, pg_typeof(x) from anyctest(11.2, '{[4,7)}') x; -- fail +ERROR: could not identify anycompatiblemultirange type +drop function anyctest(anycompatible, anycompatiblemultirange); +create function anyctest(anycompatiblemultirange, anycompatiblemultirange) +returns anycompatible as $$ + select lower($1) + upper($2) +$$ language sql; +select x, pg_typeof(x) from anyctest(multirange(int4range(11,12)), multirange(int4range(4,7))) x; + x | pg_typeof +----+----------- + 18 | integer +(1 row) + +select x, pg_typeof(x) from anyctest(multirange(int4range(11,12)), multirange(numrange(4,7))) x; -- fail +ERROR: function anyctest(int4multirange, nummultirange) does not exist +LINE 1: select x, pg_typeof(x) from anyctest(multirange(int4range(11... + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +drop function anyctest(anycompatiblemultirange, anycompatiblemultirange); +-- fail, can't infer result type: +create function anyctest(anycompatible) +returns anycompatiblemultirange as $$ + select $1 +$$ language sql; +ERROR: cannot determine result data type +DETAIL: A result of type anycompatiblemultirange requires at least one input of type anycompatiblerange or anycompatiblemultirange. create function anyctest(anycompatiblenonarray, anycompatiblenonarray) returns anycompatiblearray as $$ select array[$1, $2] diff --git a/src/test/regress/expected/rangefuncs.out b/src/test/regress/expected/rangefuncs.out index 06bd129fd22..5bbd5f6c0bd 100644 --- a/src/test/regress/expected/rangefuncs.out +++ b/src/test/regress/expected/rangefuncs.out @@ -1556,7 +1556,7 @@ DROP FUNCTION dup(anyelement); CREATE FUNCTION bad (f1 int, out f2 anyelement, out f3 anyarray) AS 'select $1, array[$1,$1]' LANGUAGE sql; ERROR: cannot determine result data type -DETAIL: A result of type anyelement requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange. +DETAIL: A result of type anyelement requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange. CREATE FUNCTION dup (f1 anycompatible, f2 anycompatiblearray, f3 out anycompatible, f4 out anycompatiblearray) AS 'select $1, $2' LANGUAGE sql; SELECT dup(22, array[44]); diff --git a/src/test/regress/expected/rangetypes.out b/src/test/regress/expected/rangetypes.out index c421f5394fe..6a1bbadc91a 100644 --- a/src/test/regress/expected/rangetypes.out +++ b/src/test/regress/expected/rangetypes.out @@ -518,6 +518,25 @@ select numrange(1.0, 2.0) * numrange(2.5, 3.0); empty (1 row) +select range_intersect_agg(nr) from numrange_test; + range_intersect_agg +--------------------- + empty +(1 row) + +select range_intersect_agg(nr) from numrange_test where false; + range_intersect_agg +--------------------- + +(1 row) + +select range_intersect_agg(nr) from numrange_test where nr @> 4.0; + range_intersect_agg +--------------------- + [3,5) +(1 row) + +analyze numrange_test; create table numrange_test2(nr numrange); create index numrange_test2_hash_idx on numrange_test2 using hash (nr); INSERT INTO numrange_test2 VALUES('[, 5)'); @@ -1371,12 +1390,12 @@ drop function anyarray_anyrange_func(anyarray, anyrange); create function bogus_func(anyelement) returns anyrange as 'select int4range(1,10)' language sql; ERROR: cannot determine result data type -DETAIL: A result of type anyrange requires at least one input of type anyrange. +DETAIL: A result of type anyrange requires at least one input of type anyrange or anymultirange. -- should fail create function bogus_func(int) returns anyrange as 'select int4range(1,10)' language sql; ERROR: cannot determine result data type -DETAIL: A result of type anyrange requires at least one input of type anyrange. +DETAIL: A result of type anyrange requires at least one input of type anyrange or anymultirange. create function range_add_bounds(anyrange) returns anyelement as 'select lower($1) + upper($1)' language sql; select range_add_bounds(int4range(1, 17)); @@ -1430,7 +1449,7 @@ drop function anycompatiblearray_anycompatiblerange_func(anycompatiblearray, any create function bogus_func(anycompatible) returns anycompatiblerange as 'select int4range(1,10)' language sql; ERROR: cannot determine result data type -DETAIL: A result of type anycompatiblerange requires at least one input of type anycompatiblerange. +DETAIL: A result of type anycompatiblerange requires at least one input of type anycompatiblerange or anycompatiblemultirange. -- -- Arrays of ranges -- @@ -1508,6 +1527,7 @@ reset enable_sort; -- -- OUT/INOUT/TABLE functions -- +-- infer anyrange from anyrange create function outparam_succeed(i anyrange, out r anyrange, out t text) as $$ select $1, 'foo'::text $$ language sql; select * from outparam_succeed(int4range(1,2)); @@ -1525,6 +1545,16 @@ select * from outparam2_succeed(int4range(1,11)); {1,11} | {11,1} (1 row) +-- infer anyarray from anyrange +create function outparam_succeed2(i anyrange, out r anyarray, out t text) + as $$ select ARRAY[upper($1)], 'foo'::text $$ language sql; +select * from outparam_succeed2(int4range(int4range(1,2))); + r | t +-----+----- + {2} | foo +(1 row) + +-- infer anyelement from anyrange create function inoutparam_succeed(out i anyelement, inout r anyrange) as $$ select upper($1), $1 $$ language sql; select * from inoutparam_succeed(int4range(1,2)); @@ -1547,14 +1577,14 @@ select * from table_succeed(int4range(1,11)); create function outparam_fail(i anyelement, out r anyrange, out t text) as $$ select '[1,10]', 'foo' $$ language sql; ERROR: cannot determine result data type -DETAIL: A result of type anyrange requires at least one input of type anyrange. +DETAIL: A result of type anyrange requires at least one input of type anyrange or anymultirange. --should fail create function inoutparam_fail(inout i anyelement, out r anyrange) as $$ select $1, '[1,10]' $$ language sql; ERROR: cannot determine result data type -DETAIL: A result of type anyrange requires at least one input of type anyrange. +DETAIL: A result of type anyrange requires at least one input of type anyrange or anymultirange. --should fail create function table_fail(i anyelement) returns table(i anyelement, r anyrange) as $$ select $1, '[1,10]' $$ language sql; ERROR: cannot determine result data type -DETAIL: A result of type anyrange requires at least one input of type anyrange. +DETAIL: A result of type anyrange requires at least one input of type anyrange or anymultirange. diff --git a/src/test/regress/expected/sanity_check.out b/src/test/regress/expected/sanity_check.out index 192445878d2..d9ce961be2b 100644 --- a/src/test/regress/expected/sanity_check.out +++ b/src/test/regress/expected/sanity_check.out @@ -92,6 +92,7 @@ num_exp_sqrt|t num_exp_sub|t num_input_test|f num_result|f +nummultirange_test|t numrange_test|t onek|t onek2|t @@ -172,6 +173,7 @@ quad_poly_tbl|t radix_text_tbl|t ramp|f real_city|f +reservations|f road|t shighway|t slow_emp4000|f diff --git a/src/test/regress/expected/type_sanity.out b/src/test/regress/expected/type_sanity.out index 13567ddf84b..0c74dc96a87 100644 --- a/src/test/regress/expected/type_sanity.out +++ b/src/test/regress/expected/type_sanity.out @@ -17,7 +17,7 @@ SELECT p1.oid, p1.typname FROM pg_type as p1 WHERE p1.typnamespace = 0 OR (p1.typlen <= 0 AND p1.typlen != -1 AND p1.typlen != -2) OR - (p1.typtype not in ('b', 'c', 'd', 'e', 'p', 'r')) OR + (p1.typtype not in ('b', 'c', 'd', 'e', 'p', 'r', 'm')) OR NOT p1.typisdefined OR (p1.typalign not in ('c', 's', 'i', 'd')) OR (p1.typstorage not in ('p', 'x', 'e', 'm')); @@ -196,18 +196,19 @@ WHERE p1.typinput = p2.oid AND p2.provolatile NOT IN ('i', 's'); -----+---------+-----+--------- (0 rows) --- Composites, domains, enums, ranges should all use the same input routines +-- Composites, domains, enums, multiranges, ranges should all use the same input routines SELECT DISTINCT typtype, typinput FROM pg_type AS p1 WHERE p1.typtype not in ('b', 'p') ORDER BY 1; - typtype | typinput ----------+----------- + typtype | typinput +---------+--------------- c | record_in d | domain_in e | enum_in + m | multirange_in r | range_in -(4 rows) +(5 rows) -- Check for bogus typoutput routines -- As of 8.0, this check finds refcursor, which is borrowing @@ -241,17 +242,18 @@ WHERE p1.typoutput = p2.oid AND p2.provolatile NOT IN ('i', 's'); -----+---------+-----+--------- (0 rows) --- Composites, enums, ranges should all use the same output routines +-- Composites, enums, multiranges, ranges should all use the same output routines SELECT DISTINCT typtype, typoutput FROM pg_type AS p1 WHERE p1.typtype not in ('b', 'd', 'p') ORDER BY 1; - typtype | typoutput ----------+------------ + typtype | typoutput +---------+---------------- c | record_out e | enum_out + m | multirange_out r | range_out -(3 rows) +(4 rows) -- Domains should have same typoutput as their base types SELECT p1.oid, p1.typname, p2.oid, p2.typname @@ -319,18 +321,19 @@ WHERE p1.typreceive = p2.oid AND p2.provolatile NOT IN ('i', 's'); -----+---------+-----+--------- (0 rows) --- Composites, domains, enums, ranges should all use the same receive routines +-- Composites, domains, enums, multiranges, ranges should all use the same receive routines SELECT DISTINCT typtype, typreceive FROM pg_type AS p1 WHERE p1.typtype not in ('b', 'p') ORDER BY 1; - typtype | typreceive ----------+------------- + typtype | typreceive +---------+----------------- c | record_recv d | domain_recv e | enum_recv + m | multirange_recv r | range_recv -(4 rows) +(5 rows) -- Check for bogus typsend routines -- As of 7.4, this check finds refcursor, which is borrowing @@ -364,17 +367,18 @@ WHERE p1.typsend = p2.oid AND p2.provolatile NOT IN ('i', 's'); -----+---------+-----+--------- (0 rows) --- Composites, enums, ranges should all use the same send routines +-- Composites, enums, multiranges, ranges should all use the same send routines SELECT DISTINCT typtype, typsend FROM pg_type AS p1 WHERE p1.typtype not in ('b', 'd', 'p') ORDER BY 1; - typtype | typsend ----------+------------- + typtype | typsend +---------+----------------- c | record_send e | enum_send + m | multirange_send r | range_send -(3 rows) +(4 rows) -- Domains should have same typsend as their base types SELECT p1.oid, p1.typname, p2.oid, p2.typname @@ -660,3 +664,11 @@ WHERE pronargs != 2 ----------+------------+--------- (0 rows) +-- every range should have a valid multirange +SELECT p1.rngtypid, p1.rngsubtype, p1.rngmultitypid +FROM pg_range p1 +WHERE p1.rngmultitypid IS NULL OR p1.rngmultitypid = 0; + rngtypid | rngsubtype | rngmultitypid +----------+------------+--------------- +(0 rows) + |
