Commit 766948be authored by Tom Lane's avatar Tom Lane

Still more review for range-types patch.

Per discussion, relax the range input/construction rules so that the
only hard error is lower bound > upper bound.  Cases where the lower
bound is <= upper bound, but the range nonetheless normalizes to empty,
are now permitted.

Fix core dump in range_adjacent when bounds are infinite.  Marginal
cleanup of regression test cases, some more code commenting.
parent 024ea25c
This diff is collapsed.
...@@ -35,8 +35,6 @@ ...@@ -35,8 +35,6 @@
#define RANGESTRAT_EQ 18 #define RANGESTRAT_EQ 18
#define RANGESTRAT_NE 19 #define RANGESTRAT_NE 19
#define RangeIsEmpty(r) (range_get_flags(r) & RANGE_EMPTY)
/* /*
* Auxiliary structure for picksplit method. * Auxiliary structure for picksplit method.
*/ */
...@@ -58,6 +56,7 @@ static bool range_gist_consistent_leaf(FmgrInfo *flinfo, ...@@ -58,6 +56,7 @@ static bool range_gist_consistent_leaf(FmgrInfo *flinfo,
static int sort_item_cmp(const void *a, const void *b); static int sort_item_cmp(const void *a, const void *b);
/* GiST query consistency check */
Datum Datum
range_gist_consistent(PG_FUNCTION_ARGS) range_gist_consistent(PG_FUNCTION_ARGS)
{ {
...@@ -69,8 +68,6 @@ range_gist_consistent(PG_FUNCTION_ARGS) ...@@ -69,8 +68,6 @@ range_gist_consistent(PG_FUNCTION_ARGS)
RangeType *key = DatumGetRangeType(entry->key); RangeType *key = DatumGetRangeType(entry->key);
TypeCacheEntry *typcache; TypeCacheEntry *typcache;
RangeType *query; RangeType *query;
RangeBound lower;
RangeBound upper;
/* All operators served by this function are exact */ /* All operators served by this function are exact */
*recheck = false; *recheck = false;
...@@ -78,25 +75,18 @@ range_gist_consistent(PG_FUNCTION_ARGS) ...@@ -78,25 +75,18 @@ range_gist_consistent(PG_FUNCTION_ARGS)
switch (strategy) switch (strategy)
{ {
/* /*
* For contains and contained by operators, the other operand is a * For element contains and contained by operators, the other operand
* "point" of the subtype. Construct a singleton range containing * is a "point" of the subtype. Construct a singleton range
* just that value. * containing just that value. (Since range_contains_elem and
* elem_contained_by_range would do that anyway, it's actually more
* efficient not less so to merge these cases into range containment
* at this step. But revisit this if we ever change the implementation
* of those functions.)
*/ */
case RANGESTRAT_CONTAINS_ELEM: case RANGESTRAT_CONTAINS_ELEM:
case RANGESTRAT_ELEM_CONTAINED_BY: case RANGESTRAT_ELEM_CONTAINED_BY:
typcache = range_get_typcache(fcinfo, RangeTypeGetOid(key)); typcache = range_get_typcache(fcinfo, RangeTypeGetOid(key));
query = make_singleton_range(typcache, dquery);
lower.val = dquery;
lower.infinite = false;
lower.inclusive = true;
lower.lower = true;
upper.val = dquery;
upper.infinite = false;
upper.inclusive = true;
upper.lower = false;
query = make_range(typcache, &lower, &upper, false);
break; break;
default: default:
...@@ -112,6 +102,7 @@ range_gist_consistent(PG_FUNCTION_ARGS) ...@@ -112,6 +102,7 @@ range_gist_consistent(PG_FUNCTION_ARGS)
key, query)); key, query));
} }
/* form union range */
Datum Datum
range_gist_union(PG_FUNCTION_ARGS) range_gist_union(PG_FUNCTION_ARGS)
{ {
...@@ -134,6 +125,7 @@ range_gist_union(PG_FUNCTION_ARGS) ...@@ -134,6 +125,7 @@ range_gist_union(PG_FUNCTION_ARGS)
PG_RETURN_RANGE(result_range); PG_RETURN_RANGE(result_range);
} }
/* compress, decompress are no-ops */
Datum Datum
range_gist_compress(PG_FUNCTION_ARGS) range_gist_compress(PG_FUNCTION_ARGS)
{ {
...@@ -150,6 +142,7 @@ range_gist_decompress(PG_FUNCTION_ARGS) ...@@ -150,6 +142,7 @@ range_gist_decompress(PG_FUNCTION_ARGS)
PG_RETURN_POINTER(entry); PG_RETURN_POINTER(entry);
} }
/* page split penalty function */
Datum Datum
range_gist_penalty(PG_FUNCTION_ARGS) range_gist_penalty(PG_FUNCTION_ARGS)
{ {
...@@ -177,6 +170,7 @@ range_gist_penalty(PG_FUNCTION_ARGS) ...@@ -177,6 +170,7 @@ range_gist_penalty(PG_FUNCTION_ARGS)
subtype_diff = &typcache->rng_subdiff_finfo; subtype_diff = &typcache->rng_subdiff_finfo;
/* we want to compare the size of "orig" to size of "orig union new" */
s_union = range_super_union(typcache, orig, new); s_union = range_super_union(typcache, orig, new);
range_deserialize(typcache, orig, &lower1, &upper1, &empty1); range_deserialize(typcache, orig, &lower1, &upper1, &empty1);
...@@ -268,9 +262,9 @@ range_gist_penalty(PG_FUNCTION_ARGS) ...@@ -268,9 +262,9 @@ range_gist_penalty(PG_FUNCTION_ARGS)
/* /*
* The GiST PickSplit method for ranges * The GiST PickSplit method for ranges
* *
* Algorithm based on sorting. Incoming array of periods is sorted using * Algorithm based on sorting. Incoming array of ranges is sorted using
* sort_item_cmp function. After that first half of periods goes to the left * sort_item_cmp function. After that first half of ranges goes to the left
* datum, and the second half of periods goes to the right datum. * output, and the second half of ranges goes to the right output.
*/ */
Datum Datum
range_gist_picksplit(PG_FUNCTION_ARGS) range_gist_picksplit(PG_FUNCTION_ARGS)
...@@ -318,7 +312,7 @@ range_gist_picksplit(PG_FUNCTION_ARGS) ...@@ -318,7 +312,7 @@ range_gist_picksplit(PG_FUNCTION_ARGS)
v->spl_nright = 0; v->spl_nright = 0;
/* /*
* First half of items goes to the left datum. * First half of items goes to the left output.
*/ */
pred_left = sortItems[0].data; pred_left = sortItems[0].data;
*left++ = sortItems[0].index; *left++ = sortItems[0].index;
...@@ -331,7 +325,7 @@ range_gist_picksplit(PG_FUNCTION_ARGS) ...@@ -331,7 +325,7 @@ range_gist_picksplit(PG_FUNCTION_ARGS)
} }
/* /*
* Second half of items goes to the right datum. * Second half of items goes to the right output.
*/ */
pred_right = sortItems[split_idx].data; pred_right = sortItems[split_idx].data;
*right++ = sortItems[split_idx].index; *right++ = sortItems[split_idx].index;
...@@ -351,6 +345,7 @@ range_gist_picksplit(PG_FUNCTION_ARGS) ...@@ -351,6 +345,7 @@ range_gist_picksplit(PG_FUNCTION_ARGS)
PG_RETURN_POINTER(v); PG_RETURN_POINTER(v);
} }
/* equality comparator for GiST */
Datum Datum
range_gist_same(PG_FUNCTION_ARGS) range_gist_same(PG_FUNCTION_ARGS)
{ {
...@@ -375,6 +370,8 @@ range_gist_same(PG_FUNCTION_ARGS) ...@@ -375,6 +370,8 @@ range_gist_same(PG_FUNCTION_ARGS)
/* /*
* Return the smallest range that contains r1 and r2 * Return the smallest range that contains r1 and r2
*
* XXX would it be better to redefine range_union as working this way?
*/ */
static RangeType * static RangeType *
range_super_union(TypeCacheEntry *typcache, RangeType * r1, RangeType * r2) range_super_union(TypeCacheEntry *typcache, RangeType * r1, RangeType * r2)
......
...@@ -49,6 +49,8 @@ typedef struct ...@@ -49,6 +49,8 @@ typedef struct
RANGE_UB_NULL | \ RANGE_UB_NULL | \
RANGE_UB_INF))) RANGE_UB_INF)))
#define RangeIsEmpty(r) (range_get_flags(r) & RANGE_EMPTY)
/* Internal representation of either bound of a range (not what's on disk) */ /* Internal representation of either bound of a range (not what's on disk) */
typedef struct typedef struct
...@@ -153,7 +155,10 @@ extern RangeType *make_range(TypeCacheEntry *typcache, RangeBound *lower, ...@@ -153,7 +155,10 @@ extern RangeType *make_range(TypeCacheEntry *typcache, RangeBound *lower,
RangeBound *upper, bool empty); RangeBound *upper, bool empty);
extern int range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1, extern int range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1,
RangeBound *b2); RangeBound *b2);
extern int range_cmp_bound_values(TypeCacheEntry *typcache, RangeBound *b1,
RangeBound *b2);
extern RangeType *make_empty_range(TypeCacheEntry *typcache); extern RangeType *make_empty_range(TypeCacheEntry *typcache);
extern RangeType *make_singleton_range(TypeCacheEntry *typcache, Datum val);
/* GiST support (in rangetypes_gist.c) */ /* GiST support (in rangetypes_gist.c) */
extern Datum range_gist_consistent(PG_FUNCTION_ARGS); extern Datum range_gist_consistent(PG_FUNCTION_ARGS);
......
This diff is collapsed.
-- Tests for range data types.
create type textrange as range (subtype=text, collation="C");
-- --
-- test parser -- test input parser
-- --
create type textrange as range (subtype=text, collation="C");
-- negative tests; should fail -- negative tests; should fail
select ''::textrange; select ''::textrange;
select '-[a,z)'::textrange; select '-[a,z)'::textrange;
...@@ -15,12 +16,7 @@ select '(),a)'::textrange; ...@@ -15,12 +16,7 @@ select '(),a)'::textrange;
select '(a,))'::textrange; select '(a,))'::textrange;
select '(],a)'::textrange; select '(],a)'::textrange;
select '(a,])'::textrange; select '(a,])'::textrange;
select '( , )'::textrange; select '[z,a]'::textrange;
select '("","")'::textrange;
select '(",",",")'::textrange;
select '("\\","\\")'::textrange;
select '[a,a)'::textrange;
select '(a,a]'::textrange;
-- should succeed -- should succeed
select ' empty '::textrange; select ' empty '::textrange;
...@@ -31,6 +27,7 @@ select '(a,)'::textrange; ...@@ -31,6 +27,7 @@ select '(a,)'::textrange;
select '[,z]'::textrange; select '[,z]'::textrange;
select '[a,]'::textrange; select '[a,]'::textrange;
select '(,)'::textrange; select '(,)'::textrange;
select '[ , ]'::textrange;
select '["",""]'::textrange; select '["",""]'::textrange;
select '[",",","]'::textrange; select '[",",","]'::textrange;
select '["\\","\\"]'::textrange; select '["\\","\\"]'::textrange;
...@@ -39,6 +36,11 @@ select '((,z)'::textrange; ...@@ -39,6 +36,11 @@ select '((,z)'::textrange;
select '([,z)'::textrange; select '([,z)'::textrange;
select '(!,()'::textrange; select '(!,()'::textrange;
select '(!,[)'::textrange; select '(!,[)'::textrange;
select '[a,a]'::textrange;
-- these are allowed but normalize to empty:
select '[a,a)'::textrange;
select '(a,a]'::textrange;
select '(a,a)'::textrange;
-- --
-- create some test data and test the operators -- create some test data and test the operators
...@@ -46,7 +48,6 @@ select '(!,[)'::textrange; ...@@ -46,7 +48,6 @@ select '(!,[)'::textrange;
CREATE TABLE numrange_test (nr NUMRANGE); CREATE TABLE numrange_test (nr NUMRANGE);
create index numrange_test_btree on numrange_test(nr); create index numrange_test_btree on numrange_test(nr);
SET enable_seqscan = f;
INSERT INTO numrange_test VALUES('[,)'); INSERT INTO numrange_test VALUES('[,)');
INSERT INTO numrange_test VALUES('[3,]'); INSERT INTO numrange_test VALUES('[3,]');
...@@ -55,22 +56,29 @@ INSERT INTO numrange_test VALUES(numrange(1.1, 2.2)); ...@@ -55,22 +56,29 @@ INSERT INTO numrange_test VALUES(numrange(1.1, 2.2));
INSERT INTO numrange_test VALUES('empty'); INSERT INTO numrange_test VALUES('empty');
INSERT INTO numrange_test VALUES(numrange(1.7)); INSERT INTO numrange_test VALUES(numrange(1.7));
SELECT isempty(nr) FROM numrange_test; SELECT nr, isempty(nr), lower(nr), upper(nr) FROM numrange_test;
SELECT lower_inc(nr), lower(nr), upper(nr), upper_inc(nr) FROM numrange_test SELECT nr, lower_inc(nr), lower_inf(nr), upper_inc(nr), upper_inf(nr) FROM numrange_test;
WHERE NOT isempty(nr) AND NOT lower_inf(nr) AND NOT upper_inf(nr);
SELECT * FROM numrange_test WHERE range_contains(nr, numrange(1.9,1.91)); SELECT * FROM numrange_test WHERE range_contains(nr, numrange(1.9,1.91));
SELECT * FROM numrange_test WHERE nr @> numrange(1.0,10000.1); SELECT * FROM numrange_test WHERE nr @> numrange(1.0,10000.1);
SELECT * FROM numrange_test WHERE range_contained_by(numrange(-1e7,-10000.1), nr); SELECT * FROM numrange_test WHERE range_contained_by(numrange(-1e7,-10000.1), nr);
SELECT * FROM numrange_test WHERE 1.9 <@ nr; SELECT * FROM numrange_test WHERE 1.9 <@ nr;
SELECT * FROM numrange_test WHERE nr = 'empty';
SELECT * FROM numrange_test WHERE range_eq(nr, '(1.1, 2.2)'); select * from numrange_test where nr = 'empty';
SELECT * FROM numrange_test WHERE nr = '[1.1, 2.2)'; select * from numrange_test where nr = '(1.1, 2.2)';
select * from numrange_test where nr = '[1.1, 2.2)';
select * from numrange_test where nr < numrange(-1000.0, -1000.0,'[]');
select * from numrange_test where nr < numrange(0.0, 1.0,'[]');
select * from numrange_test where nr < numrange(1000.0, 1001.0,'[]');
select * from numrange_test where nr > numrange(-1001.0, -1000.0,'[]');
select * from numrange_test where nr > numrange(0.0, 1.0,'[]');
select * from numrange_test where nr > numrange(1000.0, 1000.0,'[]');
select numrange(2.0, 1.0); select numrange(2.0, 1.0);
select numrange(2.0, 3.0) -|- numrange(3.0, 4.0); select numrange(2.0, 3.0) -|- numrange(3.0, 4.0);
select range_adjacent(numrange(2.0, 3.0), numrange(3.1, 4.0)); select range_adjacent(numrange(2.0, 3.0), numrange(3.1, 4.0));
select range_adjacent(numrange(2.0, 3.0), numrange(3.1, null));
select numrange(2.0, 3.0, '[]') -|- numrange(3.0, 4.0, '()'); select numrange(2.0, 3.0, '[]') -|- numrange(3.0, 4.0, '()');
select numrange(1.0, 2.0) -|- numrange(2.0, 3.0,'[]'); select numrange(1.0, 2.0) -|- numrange(2.0, 3.0,'[]');
select range_adjacent(numrange(2.0, 3.0, '(]'), numrange(1.0, 2.0, '(]')); select range_adjacent(numrange(2.0, 3.0, '(]'), numrange(1.0, 2.0, '(]'));
...@@ -102,15 +110,9 @@ select numrange(1.0, 2.0) * numrange(2.0, 3.0); ...@@ -102,15 +110,9 @@ select numrange(1.0, 2.0) * numrange(2.0, 3.0);
select numrange(1.0, 2.0) * numrange(1.5, 3.0); select numrange(1.0, 2.0) * numrange(1.5, 3.0);
select numrange(1.0, 2.0) * numrange(2.5, 3.0); select numrange(1.0, 2.0) * numrange(2.5, 3.0);
select * from numrange_test where nr < numrange(-1000.0, -1000.0,'[]');
select * from numrange_test where nr < numrange(0.0, 1.0,'[]');
select * from numrange_test where nr < numrange(1000.0, 1001.0,'[]');
select * from numrange_test where nr > numrange(-1001.0, -1000.0,'[]');
select * from numrange_test where nr > numrange(0.0, 1.0,'[]');
select * from numrange_test where nr > numrange(1000.0, 1000.0,'[]');
create table numrange_test2(nr numrange); create table numrange_test2(nr numrange);
create index numrange_test2_hash_idx on numrange_test2 (nr); create index numrange_test2_hash_idx on numrange_test2 (nr);
INSERT INTO numrange_test2 VALUES('[, 5)'); INSERT INTO numrange_test2 VALUES('[, 5)');
INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2)); INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2));
INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2)); INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2));
...@@ -137,21 +139,24 @@ select * from numrange_test natural join numrange_test2 order by nr; ...@@ -137,21 +139,24 @@ select * from numrange_test natural join numrange_test2 order by nr;
set enable_nestloop to default; set enable_nestloop to default;
set enable_hashjoin to default; set enable_hashjoin to default;
set enable_mergejoin to default; set enable_mergejoin to default;
SET enable_seqscan TO DEFAULT;
DROP TABLE numrange_test; DROP TABLE numrange_test;
DROP TABLE numrange_test2; DROP TABLE numrange_test2;
-- test canonical form for int4range -- test canonical form for int4range
select int4range(1,10,'[]'); select int4range(1, 10, '[]');
select int4range(1,10,'[)'); select int4range(1, 10, '[)');
select int4range(1,10,'(]'); select int4range(1, 10, '(]');
select int4range(1,10,'[]'); select int4range(1, 10, '()');
select int4range(1, 2, '()');
-- test canonical form for daterange -- test canonical form for daterange
select daterange('2000-01-10'::date, '2000-01-20'::date,'[]'); select daterange('2000-01-10'::date, '2000-01-20'::date, '[]');
select daterange('2000-01-10'::date, '2000-01-20'::date,'[)'); select daterange('2000-01-10'::date, '2000-01-20'::date, '[)');
select daterange('2000-01-10'::date, '2000-01-20'::date,'(]'); select daterange('2000-01-10'::date, '2000-01-20'::date, '(]');
select daterange('2000-01-10'::date, '2000-01-20'::date,'[]'); select daterange('2000-01-10'::date, '2000-01-20'::date, '()');
select daterange('2000-01-10'::date, '2000-01-11'::date, '()');
select daterange('2000-01-10'::date, '2000-01-11'::date, '(]');
-- test GiST index that's been built incrementally -- test GiST index that's been built incrementally
create table test_range_gist(ir int4range); create table test_range_gist(ir int4range);
...@@ -238,11 +243,11 @@ insert into test_range_excl ...@@ -238,11 +243,11 @@ insert into test_range_excl
insert into test_range_excl insert into test_range_excl
values(int4range(123), int4range(2), '[2010-01-02 11:00, 2010-01-02 12:00)'); values(int4range(123), int4range(2), '[2010-01-02 11:00, 2010-01-02 12:00)');
insert into test_range_excl insert into test_range_excl
values(int4range(123), int4range(3), '[2010-01-02 10:10, 2010-01-02 11:10)'); values(int4range(123), int4range(3), '[2010-01-02 10:10, 2010-01-02 11:00)');
insert into test_range_excl insert into test_range_excl
values(int4range(124), int4range(3), '[2010-01-02 10:10, 2010-01-02 11:10)'); values(int4range(124), int4range(3), '[2010-01-02 10:10, 2010-01-02 11:10)');
insert into test_range_excl insert into test_range_excl
values(int4range(125), int4range(1), '[2010-01-02 10:10, 2010-01-02 11:10)'); values(int4range(125), int4range(1), '[2010-01-02 10:10, 2010-01-02 11:00)');
-- test bigint ranges -- test bigint ranges
select int8range(10000000000::int8, 20000000000::int8,'(]'); select int8range(10000000000::int8, 20000000000::int8,'(]');
...@@ -264,7 +269,7 @@ create type float8range as range (subtype=float8, subtype_diff=float4mi); ...@@ -264,7 +269,7 @@ create type float8range as range (subtype=float8, subtype_diff=float4mi);
create type float8range as range (subtype=float8, subtype_diff=float8mi); create type float8range as range (subtype=float8, subtype_diff=float8mi);
select '[123.001, 5.e9)'::float8range @> 888.882::float8; select '[123.001, 5.e9)'::float8range @> 888.882::float8;
create table float8range_test(f8r float8range, i int); create table float8range_test(f8r float8range, i int);
insert into float8range_test values(float8range(-100.00007, '1.111113e9')); insert into float8range_test values(float8range(-100.00007, '1.111113e9'), 42);
select * from float8range_test; select * from float8range_test;
drop table float8range_test; drop table float8range_test;
...@@ -275,14 +280,14 @@ drop table float8range_test; ...@@ -275,14 +280,14 @@ drop table float8range_test;
create domain mydomain as int4; create domain mydomain as int4;
create type mydomainrange as range(subtype=mydomain); create type mydomainrange as range(subtype=mydomain);
select '[4,50)'::mydomainrange @> 7::mydomain; select '[4,50)'::mydomainrange @> 7::mydomain;
drop type mydomainrange; drop domain mydomain; -- fail
drop domain mydomain; drop domain mydomain cascade;
-- --
-- Test domains over range types -- Test domains over range types
-- --
create domain restrictedrange as int4range check (upper(value) < 10); create domain restrictedrange as int4range check (upper(value) < 10);
select '[4,5)'::restrictedrange @> 7; select '[4,5)'::restrictedrange @> 7;
select '[4,50)'::restrictedrange @> 7; -- should fail select '[4,50)'::restrictedrange @> 7; -- should fail
drop domain restrictedrange; drop domain restrictedrange;
...@@ -301,7 +306,7 @@ drop type textrange1; ...@@ -301,7 +306,7 @@ drop type textrange1;
drop type textrange2; drop type textrange2;
-- --
-- Test out polymorphic type system -- Test polymorphic type system
-- --
create function anyarray_anyrange_func(a anyarray, r anyrange) create function anyarray_anyrange_func(a anyarray, r anyrange)
...@@ -325,6 +330,7 @@ create function bogus_func(int) ...@@ -325,6 +330,7 @@ create function bogus_func(int)
create function range_add_bounds(anyrange) create function range_add_bounds(anyrange)
returns anyelement as 'select lower($1) + upper($1)' language sql; returns anyelement as 'select lower($1) + upper($1)' language sql;
select range_add_bounds(int4range(1, 17));
select range_add_bounds(numrange(1.0001, 123.123)); select range_add_bounds(numrange(1.0001, 123.123));
create function rangetypes_sql(q anyrange, b anyarray, out c anyelement) create function rangetypes_sql(q anyrange, b anyarray, out c anyelement)
...@@ -352,6 +358,7 @@ drop table i8r_array; ...@@ -352,6 +358,7 @@ drop table i8r_array;
create type arrayrange as range (subtype=int4[]); create type arrayrange as range (subtype=int4[]);
select arrayrange(ARRAY[1,2], ARRAY[2,1]); select arrayrange(ARRAY[1,2], ARRAY[2,1]);
select arrayrange(ARRAY[2,1], ARRAY[1,2]); -- fail
select array[1,1] <@ arrayrange(array[1,2], array[2,1]); select array[1,1] <@ arrayrange(array[1,2], array[2,1]);
select array[1,3] <@ arrayrange(array[1,2], array[2,1]); select array[1,3] <@ arrayrange(array[1,2], array[2,1]);
...@@ -361,14 +368,20 @@ select array[1,3] <@ arrayrange(array[1,2], array[2,1]); ...@@ -361,14 +368,20 @@ select array[1,3] <@ arrayrange(array[1,2], array[2,1]);
-- --
create function outparam_succeed(i anyrange, out r anyrange, out t text) create function outparam_succeed(i anyrange, out r anyrange, out t text)
as $$ select $1, 'foo' $$ language sql; as $$ select $1, 'foo'::text $$ language sql;
select * from outparam_succeed(int4range(1,2));
create function inoutparam_succeed(out i anyelement, inout r anyrange) create function inoutparam_succeed(out i anyelement, inout r anyrange)
as $$ select $1, $2 $$ language sql; as $$ select upper($1), $1 $$ language sql;
select * from inoutparam_succeed(int4range(1,2));
create function table_succeed(i anyelement, r anyrange) returns table(i anyelement, r anyrange) create function table_succeed(i anyelement, r anyrange) returns table(i anyelement, r anyrange)
as $$ select $1, $2 $$ language sql; as $$ select $1, $2 $$ language sql;
select * from table_succeed(123, int4range(1,11));
-- should fail -- should fail
create function outparam_fail(i anyelement, out r anyrange, out t text) create function outparam_fail(i anyelement, out r anyrange, out t text)
as $$ select '[1,10]', 'foo' $$ language sql; as $$ select '[1,10]', 'foo' $$ language sql;
...@@ -378,5 +391,5 @@ create function inoutparam_fail(inout i anyelement, out r anyrange) ...@@ -378,5 +391,5 @@ create function inoutparam_fail(inout i anyelement, out r anyrange)
as $$ select $1, '[1,10]' $$ language sql; as $$ select $1, '[1,10]' $$ language sql;
--should fail --should fail
create function table_succeed(i anyelement) returns table(i anyelement, r anyrange) create function table_fail(i anyelement) returns table(i anyelement, r anyrange)
as $$ select $1, '[1,10]' $$ language sql; as $$ select $1, '[1,10]' $$ language sql;
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