Skip to content

Commit ce90f07

Browse files
committed
Improve the error message for an inappropriate column definition list.
The existing message about "a column definition list is only allowed for functions returning "record"" could be given in some cases where it was fairly confusing; in particular, a function with multiple OUT parameters *does* return record according to pg_proc. Break it down into a couple more cases to deliver a more on-point complaint. Per complaint from Bruce Momjian. Discussion: https://postgr.es/m/798909.1600562993@sss.pgh.pa.us
1 parent f859c2f commit ce90f07

File tree

3 files changed

+55
-7
lines changed

3 files changed

+55
-7
lines changed

src/backend/parser/parse_relation.c

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1737,16 +1737,46 @@ addRangeTableEntryForFunction(ParseState *pstate,
17371737

17381738
/*
17391739
* A coldeflist is required if the function returns RECORD and hasn't
1740-
* got a predetermined record type, and is prohibited otherwise.
1740+
* got a predetermined record type, and is prohibited otherwise. This
1741+
* can be a bit confusing, so we expend some effort on delivering a
1742+
* relevant error message.
17411743
*/
17421744
if (coldeflist != NIL)
17431745
{
1744-
if (functypclass != TYPEFUNC_RECORD)
1745-
ereport(ERROR,
1746-
(errcode(ERRCODE_SYNTAX_ERROR),
1747-
errmsg("a column definition list is only allowed for functions returning \"record\""),
1748-
parser_errposition(pstate,
1749-
exprLocation((Node *) coldeflist))));
1746+
switch (functypclass)
1747+
{
1748+
case TYPEFUNC_RECORD:
1749+
/* ok */
1750+
break;
1751+
case TYPEFUNC_COMPOSITE:
1752+
case TYPEFUNC_COMPOSITE_DOMAIN:
1753+
1754+
/*
1755+
* If the function's raw result type is RECORD, we must
1756+
* have resolved it using its OUT parameters. Otherwise,
1757+
* it must have a named composite type.
1758+
*/
1759+
if (exprType(funcexpr) == RECORDOID)
1760+
ereport(ERROR,
1761+
(errcode(ERRCODE_SYNTAX_ERROR),
1762+
errmsg("a column definition list is redundant for a function with OUT parameters"),
1763+
parser_errposition(pstate,
1764+
exprLocation((Node *) coldeflist))));
1765+
else
1766+
ereport(ERROR,
1767+
(errcode(ERRCODE_SYNTAX_ERROR),
1768+
errmsg("a column definition list is redundant for a function returning a named composite type"),
1769+
parser_errposition(pstate,
1770+
exprLocation((Node *) coldeflist))));
1771+
break;
1772+
default:
1773+
ereport(ERROR,
1774+
(errcode(ERRCODE_SYNTAX_ERROR),
1775+
errmsg("a column definition list is only allowed for functions returning \"record\""),
1776+
parser_errposition(pstate,
1777+
exprLocation((Node *) coldeflist))));
1778+
break;
1779+
}
17501780
}
17511781
else
17521782
{

src/test/regress/expected/rangefuncs.out

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2109,6 +2109,19 @@ select * from testrngfunc();
21092109
7.136178 | 7.14
21102110
(1 row)
21112111

2112+
-- Check a couple of error cases while we're here
2113+
select * from testrngfunc() as t(f1 int8,f2 int8); -- fail, composite result
2114+
ERROR: a column definition list is redundant for a function returning a named composite type
2115+
LINE 1: select * from testrngfunc() as t(f1 int8,f2 int8);
2116+
^
2117+
select * from pg_get_keywords() as t(f1 int8,f2 int8); -- fail, OUT params
2118+
ERROR: a column definition list is redundant for a function with OUT parameters
2119+
LINE 1: select * from pg_get_keywords() as t(f1 int8,f2 int8);
2120+
^
2121+
select * from sin(3) as t(f1 int8,f2 int8); -- fail, scalar result type
2122+
ERROR: a column definition list is only allowed for functions returning "record"
2123+
LINE 1: select * from sin(3) as t(f1 int8,f2 int8);
2124+
^
21122125
drop type rngfunc_type cascade;
21132126
NOTICE: drop cascades to function testrngfunc()
21142127
--

src/test/regress/sql/rangefuncs.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,11 @@ explain (verbose, costs off)
629629
select * from testrngfunc();
630630
select * from testrngfunc();
631631

632+
-- Check a couple of error cases while we're here
633+
select * from testrngfunc() as t(f1 int8,f2 int8); -- fail, composite result
634+
select * from pg_get_keywords() as t(f1 int8,f2 int8); -- fail, OUT params
635+
select * from sin(3) as t(f1 int8,f2 int8); -- fail, scalar result type
636+
632637
drop type rngfunc_type cascade;
633638

634639
--

0 commit comments

Comments
 (0)