diff options
| author | Tom Lane | 2020-03-17 18:54:46 +0000 |
|---|---|---|
| committer | Tom Lane | 2020-03-17 18:54:46 +0000 |
| commit | 9d9784c840f3ac98eb41d021c981eea0fe1735ed (patch) | |
| tree | ac05be6df6d01eea30cc91b2ad8bd3e51e639fea /src/test | |
| parent | 0bc8cebdb889368abdf224aeac8bc197fe4c9ae6 (diff) | |
Remove bogus assertion about polymorphic SQL function result.
It is possible to reach check_sql_fn_retval() with an unresolved
polymorphic rettype, resulting in an assertion failure as demonstrated
by one of the added test cases. However, the code following that
throws what seems an acceptable error message, so just remove the
Assert and adjust commentary.
While here, I thought it'd be a good idea to provide some parallel
tests of SQL-function and PL/pgSQL-function polymorphism behavior.
Some of these cases are perhaps duplicative of tests elsewhere,
but we hadn't any organized coverage of the topic AFAICS.
Although that assertion's been wrong all along, it won't have any
effect in production builds, so I'm not bothering to back-patch.
Discussion: https://postgr.es/m/21569.1584314271@sss.pgh.pa.us
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/regress/expected/plpgsql.out | 77 | ||||
| -rw-r--r-- | src/test/regress/expected/polymorphism.out | 78 | ||||
| -rw-r--r-- | src/test/regress/sql/plpgsql.sql | 60 | ||||
| -rw-r--r-- | src/test/regress/sql/polymorphism.sql | 58 |
4 files changed, 269 insertions, 4 deletions
diff --git a/src/test/regress/expected/plpgsql.out b/src/test/regress/expected/plpgsql.out index cd2c79f4d5..731db2c776 100644 --- a/src/test/regress/expected/plpgsql.out +++ b/src/test/regress/expected/plpgsql.out @@ -1747,6 +1747,83 @@ SELECT * FROM test_ret_rec_dyn(5) AS (a int, b numeric, c text); (1 row) -- +-- Test some simple polymorphism cases. +-- +create function f1(x anyelement) returns anyelement as $$ +begin + return x + 1; +end$$ language plpgsql; +select f1(42) as int, f1(4.5) as num; + int | num +-----+----- + 43 | 5.5 +(1 row) + +select f1(point(3,4)); -- fail for lack of + operator +ERROR: operator does not exist: point + integer +LINE 1: SELECT x + 1 + ^ +HINT: No operator matches the given name and argument types. You might need to add explicit type casts. +QUERY: SELECT x + 1 +CONTEXT: PL/pgSQL function f1(anyelement) line 3 at RETURN +drop function f1(x anyelement); +create function f1(x anyelement) returns anyarray as $$ +begin + return array[x + 1, x + 2]; +end$$ language plpgsql; +select f1(42) as int, f1(4.5) as num; + int | num +---------+----------- + {43,44} | {5.5,6.5} +(1 row) + +drop function f1(x anyelement); +create function f1(x anyarray) returns anyelement as $$ +begin + return x[1]; +end$$ language plpgsql; +select f1(array[2,4]) as int, f1(array[4.5, 7.7]) as num; + int | num +-----+----- + 2 | 4.5 +(1 row) + +select f1(stavalues1) from pg_statistic; -- fail, can't infer element type +ERROR: argument declared anyarray is not an array but type anyarray +drop function f1(x anyarray); +create function f1(x anyarray) returns anyarray as $$ +begin + return x; +end$$ language plpgsql; +select f1(array[2,4]) as int, f1(array[4.5, 7.7]) as num; + int | num +-------+----------- + {2,4} | {4.5,7.7} +(1 row) + +select f1(stavalues1) from pg_statistic; -- fail, can't infer element type +ERROR: PL/pgSQL functions cannot accept type anyarray +CONTEXT: compilation of PL/pgSQL function "f1" near line 1 +drop function f1(x anyarray); +-- fail, can't infer type: +create function f1(x anyelement) returns anyrange as $$ +begin + return array[x + 1, x + 2]; +end$$ language plpgsql; +ERROR: cannot determine result data type +DETAIL: A function returning "anyrange" must have at least one "anyrange" argument. +create function f1(x anyrange) returns anyarray as $$ +begin + return array[lower(x), upper(x)]; +end$$ language plpgsql; +select f1(int4range(42, 49)) as int, f1(float8range(4.5, 7.8)) as num; + int | num +---------+----------- + {42,49} | {4.5,7.8} +(1 row) + +drop function f1(x anyrange); +-- -- Test handling of OUT parameters, including polymorphic cases. -- Note that RETURN is optional with OUT params; we try both ways. -- diff --git a/src/test/regress/expected/polymorphism.out b/src/test/regress/expected/polymorphism.out index 986417a188..20f8c511b9 100644 --- a/src/test/regress/expected/polymorphism.out +++ b/src/test/regress/expected/polymorphism.out @@ -1,6 +1,80 @@ --- Currently this tests polymorphic aggregates and indirectly does some --- testing of polymorphic SQL functions. It ought to be extended. +-- +-- Tests for polymorphic SQL functions and aggregates based on them. -- Tests for other features related to function-calling have snuck in, too. +-- +create function polyf(x anyelement) returns anyelement as $$ + select x + 1 +$$ language sql; +select polyf(42) as int, polyf(4.5) as num; + int | num +-----+----- + 43 | 5.5 +(1 row) + +select polyf(point(3,4)); -- fail for lack of + operator +ERROR: operator does not exist: point + integer +LINE 2: select x + 1 + ^ +HINT: No operator matches the given name and argument types. You might need to add explicit type casts. +QUERY: + select x + 1 + +CONTEXT: SQL function "polyf" during inlining +drop function polyf(x anyelement); +create function polyf(x anyelement) returns anyarray as $$ + select array[x + 1, x + 2] +$$ language sql; +select polyf(42) as int, polyf(4.5) as num; + int | num +---------+----------- + {43,44} | {5.5,6.5} +(1 row) + +drop function polyf(x anyelement); +create function polyf(x anyarray) returns anyelement as $$ + select x[1] +$$ language sql; +select polyf(array[2,4]) as int, polyf(array[4.5, 7.7]) as num; + int | num +-----+----- + 2 | 4.5 +(1 row) + +select polyf(stavalues1) from pg_statistic; -- fail, can't infer element type +ERROR: argument declared anyarray is not an array but type anyarray +drop function polyf(x anyarray); +create function polyf(x anyarray) returns anyarray as $$ + select x +$$ language sql; +select polyf(array[2,4]) as int, polyf(array[4.5, 7.7]) as num; + int | num +-------+----------- + {2,4} | {4.5,7.7} +(1 row) + +select polyf(stavalues1) from pg_statistic; -- fail, can't infer element type +ERROR: return type anyarray is not supported for SQL functions +CONTEXT: SQL function "polyf" during inlining +drop function polyf(x anyarray); +-- fail, can't infer type: +create function polyf(x anyelement) returns anyrange as $$ + select array[x + 1, x + 2] +$$ language sql; +ERROR: cannot determine result data type +DETAIL: A function returning "anyrange" must have at least one "anyrange" argument. +create function polyf(x anyrange) returns anyarray as $$ + select array[lower(x), upper(x)] +$$ language sql; +select polyf(int4range(42, 49)) as int, polyf(float8range(4.5, 7.8)) as num; + int | num +---------+----------- + {42,49} | {4.5,7.8} +(1 row) + +drop function polyf(x anyrange); +-- +-- Polymorphic aggregate tests +-- -- Legend: ----------- -- A = type is ANY diff --git a/src/test/regress/sql/plpgsql.sql b/src/test/regress/sql/plpgsql.sql index d841d8c0f9..c5e6e6e5ed 100644 --- a/src/test/regress/sql/plpgsql.sql +++ b/src/test/regress/sql/plpgsql.sql @@ -1559,6 +1559,66 @@ SELECT * FROM test_ret_rec_dyn(1500) AS (a int, b int, c int); SELECT * FROM test_ret_rec_dyn(5) AS (a int, b numeric, c text); -- +-- Test some simple polymorphism cases. +-- + +create function f1(x anyelement) returns anyelement as $$ +begin + return x + 1; +end$$ language plpgsql; + +select f1(42) as int, f1(4.5) as num; +select f1(point(3,4)); -- fail for lack of + operator + +drop function f1(x anyelement); + +create function f1(x anyelement) returns anyarray as $$ +begin + return array[x + 1, x + 2]; +end$$ language plpgsql; + +select f1(42) as int, f1(4.5) as num; + +drop function f1(x anyelement); + +create function f1(x anyarray) returns anyelement as $$ +begin + return x[1]; +end$$ language plpgsql; + +select f1(array[2,4]) as int, f1(array[4.5, 7.7]) as num; + +select f1(stavalues1) from pg_statistic; -- fail, can't infer element type + +drop function f1(x anyarray); + +create function f1(x anyarray) returns anyarray as $$ +begin + return x; +end$$ language plpgsql; + +select f1(array[2,4]) as int, f1(array[4.5, 7.7]) as num; + +select f1(stavalues1) from pg_statistic; -- fail, can't infer element type + +drop function f1(x anyarray); + +-- fail, can't infer type: +create function f1(x anyelement) returns anyrange as $$ +begin + return array[x + 1, x + 2]; +end$$ language plpgsql; + +create function f1(x anyrange) returns anyarray as $$ +begin + return array[lower(x), upper(x)]; +end$$ language plpgsql; + +select f1(int4range(42, 49)) as int, f1(float8range(4.5, 7.8)) as num; + +drop function f1(x anyrange); + +-- -- Test handling of OUT parameters, including polymorphic cases. -- Note that RETURN is optional with OUT params; we try both ways. -- diff --git a/src/test/regress/sql/polymorphism.sql b/src/test/regress/sql/polymorphism.sql index 03606671d9..9c7b43efeb 100644 --- a/src/test/regress/sql/polymorphism.sql +++ b/src/test/regress/sql/polymorphism.sql @@ -1,8 +1,62 @@ --- Currently this tests polymorphic aggregates and indirectly does some --- testing of polymorphic SQL functions. It ought to be extended. +-- +-- Tests for polymorphic SQL functions and aggregates based on them. -- Tests for other features related to function-calling have snuck in, too. +-- + +create function polyf(x anyelement) returns anyelement as $$ + select x + 1 +$$ language sql; + +select polyf(42) as int, polyf(4.5) as num; +select polyf(point(3,4)); -- fail for lack of + operator + +drop function polyf(x anyelement); + +create function polyf(x anyelement) returns anyarray as $$ + select array[x + 1, x + 2] +$$ language sql; + +select polyf(42) as int, polyf(4.5) as num; + +drop function polyf(x anyelement); + +create function polyf(x anyarray) returns anyelement as $$ + select x[1] +$$ language sql; + +select polyf(array[2,4]) as int, polyf(array[4.5, 7.7]) as num; + +select polyf(stavalues1) from pg_statistic; -- fail, can't infer element type +drop function polyf(x anyarray); +create function polyf(x anyarray) returns anyarray as $$ + select x +$$ language sql; + +select polyf(array[2,4]) as int, polyf(array[4.5, 7.7]) as num; + +select polyf(stavalues1) from pg_statistic; -- fail, can't infer element type + +drop function polyf(x anyarray); + +-- fail, can't infer type: +create function polyf(x anyelement) returns anyrange as $$ + select array[x + 1, x + 2] +$$ language sql; + +create function polyf(x anyrange) returns anyarray as $$ + select array[lower(x), upper(x)] +$$ language sql; + +select polyf(int4range(42, 49)) as int, polyf(float8range(4.5, 7.8)) as num; + +drop function polyf(x anyrange); + + +-- +-- Polymorphic aggregate tests +-- -- Legend: ----------- -- A = type is ANY |
