Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9d9784c

Browse files
committed
Remove bogus assertion about polymorphic SQL function result.
It is possible to reach check_sql_fn_retval() with an unresolvedpolymorphic rettype, resulting in an assertion failure as demonstratedby one of the added test cases. However, the code following thatthrows what seems an acceptable error message, so just remove theAssert and adjust commentary.While here, I thought it'd be a good idea to provide some paralleltests 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 anyeffect in production builds, so I'm not bothering to back-patch.Discussion:https://postgr.es/m/21569.1584314271@sss.pgh.pa.us
1 parent0bc8ceb commit9d9784c

File tree

5 files changed

+279
-14
lines changed

5 files changed

+279
-14
lines changed

‎src/backend/executor/functions.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1567,13 +1567,16 @@ check_sql_fn_statements(List *queryTreeList)
15671567
* false even when the declared function return type is a rowtype.
15681568
*
15691569
* For a polymorphic function the passed rettype must be the actual resolved
1570-
* output type of the function; we should never see a polymorphic pseudotype
1571-
* such as ANYELEMENT as rettype. (This means we can't check the type during
1572-
* function definition of a polymorphic function.) If the function returns
1573-
* composite, the passed rettupdesc should describe the expected output.
1574-
* If rettupdesc is NULL, we can't verify that the output matches; that
1575-
* should only happen in fmgr_sql_validator(), or when the function returns
1576-
* RECORD and the caller doesn't actually care which composite type it is.
1570+
* output type of the function. (This means we can't check the type during
1571+
* function definition of a polymorphic function.) If we do see a polymorphic
1572+
* rettype we'll throw an error, saying it is not a supported rettype.
1573+
*
1574+
* If the function returns composite, the passed rettupdesc should describe
1575+
* the expected output. If rettupdesc is NULL, we can't verify that the
1576+
* output matches; that should only happen in fmgr_sql_validator(), or when
1577+
* the function returns RECORD and the caller doesn't actually care which
1578+
* composite type it is.
1579+
*
15771580
* (Typically, rettype and rettupdesc are computed by get_call_result_type
15781581
* or a sibling function.)
15791582
*
@@ -1602,9 +1605,6 @@ check_sql_fn_retval(List *queryTreeList,
16021605
boolupper_tlist_nontrivial= false;
16031606
ListCell*lc;
16041607

1605-
/* Caller must have resolved any polymorphism */
1606-
AssertArg(!IsPolymorphicType(rettype));
1607-
16081608
if (resultTargetList)
16091609
*resultTargetList=NIL;/* initialize in case of VOID result */
16101610

‎src/test/regress/expected/plpgsql.out

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1746,6 +1746,83 @@ SELECT * FROM test_ret_rec_dyn(5) AS (a int, b numeric, c text);
17461746
50 | 5 | xxx
17471747
(1 row)
17481748

1749+
--
1750+
-- Test some simple polymorphism cases.
1751+
--
1752+
create function f1(x anyelement) returns anyelement as $$
1753+
begin
1754+
return x + 1;
1755+
end$$ language plpgsql;
1756+
select f1(42) as int, f1(4.5) as num;
1757+
int | num
1758+
-----+-----
1759+
43 | 5.5
1760+
(1 row)
1761+
1762+
select f1(point(3,4)); -- fail for lack of + operator
1763+
ERROR: operator does not exist: point + integer
1764+
LINE 1: SELECT x + 1
1765+
^
1766+
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
1767+
QUERY: SELECT x + 1
1768+
CONTEXT: PL/pgSQL function f1(anyelement) line 3 at RETURN
1769+
drop function f1(x anyelement);
1770+
create function f1(x anyelement) returns anyarray as $$
1771+
begin
1772+
return array[x + 1, x + 2];
1773+
end$$ language plpgsql;
1774+
select f1(42) as int, f1(4.5) as num;
1775+
int | num
1776+
---------+-----------
1777+
{43,44} | {5.5,6.5}
1778+
(1 row)
1779+
1780+
drop function f1(x anyelement);
1781+
create function f1(x anyarray) returns anyelement as $$
1782+
begin
1783+
return x[1];
1784+
end$$ language plpgsql;
1785+
select f1(array[2,4]) as int, f1(array[4.5, 7.7]) as num;
1786+
int | num
1787+
-----+-----
1788+
2 | 4.5
1789+
(1 row)
1790+
1791+
select f1(stavalues1) from pg_statistic; -- fail, can't infer element type
1792+
ERROR: argument declared anyarray is not an array but type anyarray
1793+
drop function f1(x anyarray);
1794+
create function f1(x anyarray) returns anyarray as $$
1795+
begin
1796+
return x;
1797+
end$$ language plpgsql;
1798+
select f1(array[2,4]) as int, f1(array[4.5, 7.7]) as num;
1799+
int | num
1800+
-------+-----------
1801+
{2,4} | {4.5,7.7}
1802+
(1 row)
1803+
1804+
select f1(stavalues1) from pg_statistic; -- fail, can't infer element type
1805+
ERROR: PL/pgSQL functions cannot accept type anyarray
1806+
CONTEXT: compilation of PL/pgSQL function "f1" near line 1
1807+
drop function f1(x anyarray);
1808+
-- fail, can't infer type:
1809+
create function f1(x anyelement) returns anyrange as $$
1810+
begin
1811+
return array[x + 1, x + 2];
1812+
end$$ language plpgsql;
1813+
ERROR: cannot determine result data type
1814+
DETAIL: A function returning "anyrange" must have at least one "anyrange" argument.
1815+
create function f1(x anyrange) returns anyarray as $$
1816+
begin
1817+
return array[lower(x), upper(x)];
1818+
end$$ language plpgsql;
1819+
select f1(int4range(42, 49)) as int, f1(float8range(4.5, 7.8)) as num;
1820+
int | num
1821+
---------+-----------
1822+
{42,49} | {4.5,7.8}
1823+
(1 row)
1824+
1825+
drop function f1(x anyrange);
17491826
--
17501827
-- Test handling of OUT parameters, including polymorphic cases.
17511828
-- Note that RETURN is optional with OUT params; we try both ways.

‎src/test/regress/expected/polymorphism.out

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,80 @@
1-
-- Currently this tests polymorphic aggregates and indirectly does some
2-
--testing of polymorphic SQL functions. It ought to be extended.
1+
--
2+
--Tests for polymorphic SQL functions and aggregates based on them.
33
-- Tests for other features related to function-calling have snuck in, too.
4+
--
5+
create function polyf(x anyelement) returns anyelement as $$
6+
select x + 1
7+
$$ language sql;
8+
select polyf(42) as int, polyf(4.5) as num;
9+
int | num
10+
-----+-----
11+
43 | 5.5
12+
(1 row)
13+
14+
select polyf(point(3,4)); -- fail for lack of + operator
15+
ERROR: operator does not exist: point + integer
16+
LINE 2: select x + 1
17+
^
18+
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
19+
QUERY:
20+
select x + 1
21+
22+
CONTEXT: SQL function "polyf" during inlining
23+
drop function polyf(x anyelement);
24+
create function polyf(x anyelement) returns anyarray as $$
25+
select array[x + 1, x + 2]
26+
$$ language sql;
27+
select polyf(42) as int, polyf(4.5) as num;
28+
int | num
29+
---------+-----------
30+
{43,44} | {5.5,6.5}
31+
(1 row)
32+
33+
drop function polyf(x anyelement);
34+
create function polyf(x anyarray) returns anyelement as $$
35+
select x[1]
36+
$$ language sql;
37+
select polyf(array[2,4]) as int, polyf(array[4.5, 7.7]) as num;
38+
int | num
39+
-----+-----
40+
2 | 4.5
41+
(1 row)
42+
43+
select polyf(stavalues1) from pg_statistic; -- fail, can't infer element type
44+
ERROR: argument declared anyarray is not an array but type anyarray
45+
drop function polyf(x anyarray);
46+
create function polyf(x anyarray) returns anyarray as $$
47+
select x
48+
$$ language sql;
49+
select polyf(array[2,4]) as int, polyf(array[4.5, 7.7]) as num;
50+
int | num
51+
-------+-----------
52+
{2,4} | {4.5,7.7}
53+
(1 row)
54+
55+
select polyf(stavalues1) from pg_statistic; -- fail, can't infer element type
56+
ERROR: return type anyarray is not supported for SQL functions
57+
CONTEXT: SQL function "polyf" during inlining
58+
drop function polyf(x anyarray);
59+
-- fail, can't infer type:
60+
create function polyf(x anyelement) returns anyrange as $$
61+
select array[x + 1, x + 2]
62+
$$ language sql;
63+
ERROR: cannot determine result data type
64+
DETAIL: A function returning "anyrange" must have at least one "anyrange" argument.
65+
create function polyf(x anyrange) returns anyarray as $$
66+
select array[lower(x), upper(x)]
67+
$$ language sql;
68+
select polyf(int4range(42, 49)) as int, polyf(float8range(4.5, 7.8)) as num;
69+
int | num
70+
---------+-----------
71+
{42,49} | {4.5,7.8}
72+
(1 row)
73+
74+
drop function polyf(x anyrange);
75+
--
76+
-- Polymorphic aggregate tests
77+
--
478
-- Legend:
579
-----------
680
-- A = type is ANY

‎src/test/regress/sql/plpgsql.sql

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1558,6 +1558,66 @@ END;' language plpgsql;
15581558
SELECT*FROM test_ret_rec_dyn(1500)AS (aint, bint, cint);
15591559
SELECT*FROM test_ret_rec_dyn(5)AS (aint, bnumeric, ctext);
15601560

1561+
--
1562+
-- Test some simple polymorphism cases.
1563+
--
1564+
1565+
createfunctionf1(x anyelement) returns anyelementas $$
1566+
begin
1567+
return x+1;
1568+
end$$ language plpgsql;
1569+
1570+
select f1(42)asint, f1(4.5)as num;
1571+
select f1(point(3,4));-- fail for lack of + operator
1572+
1573+
dropfunction f1(x anyelement);
1574+
1575+
createfunctionf1(x anyelement) returns anyarrayas $$
1576+
begin
1577+
return array[x+1, x+2];
1578+
end$$ language plpgsql;
1579+
1580+
select f1(42)asint, f1(4.5)as num;
1581+
1582+
dropfunction f1(x anyelement);
1583+
1584+
createfunctionf1(x anyarray) returns anyelementas $$
1585+
begin
1586+
return x[1];
1587+
end$$ language plpgsql;
1588+
1589+
select f1(array[2,4])asint, f1(array[4.5,7.7])as num;
1590+
1591+
select f1(stavalues1)from pg_statistic;-- fail, can't infer element type
1592+
1593+
dropfunction f1(x anyarray);
1594+
1595+
createfunctionf1(x anyarray) returns anyarrayas $$
1596+
begin
1597+
return x;
1598+
end$$ language plpgsql;
1599+
1600+
select f1(array[2,4])asint, f1(array[4.5,7.7])as num;
1601+
1602+
select f1(stavalues1)from pg_statistic;-- fail, can't infer element type
1603+
1604+
dropfunction f1(x anyarray);
1605+
1606+
-- fail, can't infer type:
1607+
createfunctionf1(x anyelement) returns anyrangeas $$
1608+
begin
1609+
return array[x+1, x+2];
1610+
end$$ language plpgsql;
1611+
1612+
createfunctionf1(x anyrange) returns anyarrayas $$
1613+
begin
1614+
return array[lower(x),upper(x)];
1615+
end$$ language plpgsql;
1616+
1617+
select f1(int4range(42,49))asint, f1(float8range(4.5,7.8))as num;
1618+
1619+
dropfunction f1(x anyrange);
1620+
15611621
--
15621622
-- Test handling of OUT parameters, including polymorphic cases.
15631623
-- Note that RETURN is optional with OUT params; we try both ways.

‎src/test/regress/sql/polymorphism.sql

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,62 @@
1-
-- Currently this tests polymorphic aggregates and indirectly does some
2-
--testing of polymorphic SQL functions. It ought to be extended.
1+
--
2+
--Tests for polymorphic SQL functions and aggregates based on them.
33
-- Tests for other features related to function-calling have snuck in, too.
4+
--
5+
6+
createfunctionpolyf(x anyelement) returns anyelementas $$
7+
select x+1
8+
$$ language sql;
9+
10+
select polyf(42)asint, polyf(4.5)as num;
11+
select polyf(point(3,4));-- fail for lack of + operator
12+
13+
dropfunction polyf(x anyelement);
14+
15+
createfunctionpolyf(x anyelement) returns anyarrayas $$
16+
select array[x+1, x+2]
17+
$$ language sql;
18+
19+
select polyf(42)asint, polyf(4.5)as num;
20+
21+
dropfunction polyf(x anyelement);
22+
23+
createfunctionpolyf(x anyarray) returns anyelementas $$
24+
select x[1]
25+
$$ language sql;
26+
27+
select polyf(array[2,4])asint, polyf(array[4.5,7.7])as num;
28+
29+
select polyf(stavalues1)from pg_statistic;-- fail, can't infer element type
430

31+
dropfunction polyf(x anyarray);
532

33+
createfunctionpolyf(x anyarray) returns anyarrayas $$
34+
select x
35+
$$ language sql;
36+
37+
select polyf(array[2,4])asint, polyf(array[4.5,7.7])as num;
38+
39+
select polyf(stavalues1)from pg_statistic;-- fail, can't infer element type
40+
41+
dropfunction polyf(x anyarray);
42+
43+
-- fail, can't infer type:
44+
createfunctionpolyf(x anyelement) returns anyrangeas $$
45+
select array[x+1, x+2]
46+
$$ language sql;
47+
48+
createfunctionpolyf(x anyrange) returns anyarrayas $$
49+
select array[lower(x),upper(x)]
50+
$$ language sql;
51+
52+
select polyf(int4range(42,49))asint, polyf(float8range(4.5,7.8))as num;
53+
54+
dropfunction polyf(x anyrange);
55+
56+
57+
--
58+
-- Polymorphic aggregate tests
59+
--
660
-- Legend:
761
-----------
862
-- A = type is ANY

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp