summaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_relation.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2020-09-22 10:49:11 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2020-09-22 10:49:11 -0400
commitce90f075f0d831ca4085ba73891b7da2a2f7047e (patch)
tree19008cdd70128f1a418ec326444eb876168c7245 /src/backend/parser/parse_relation.c
parentf859c2ffa01d83a079652ce7d953cd61eb3d7171 (diff)
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
Diffstat (limited to 'src/backend/parser/parse_relation.c')
-rw-r--r--src/backend/parser/parse_relation.c44
1 files changed, 37 insertions, 7 deletions
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
index b875a506463..a56bd86181a 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -1737,16 +1737,46 @@ addRangeTableEntryForFunction(ParseState *pstate,
/*
* A coldeflist is required if the function returns RECORD and hasn't
- * got a predetermined record type, and is prohibited otherwise.
+ * got a predetermined record type, and is prohibited otherwise. This
+ * can be a bit confusing, so we expend some effort on delivering a
+ * relevant error message.
*/
if (coldeflist != NIL)
{
- if (functypclass != TYPEFUNC_RECORD)
- ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("a column definition list is only allowed for functions returning \"record\""),
- parser_errposition(pstate,
- exprLocation((Node *) coldeflist))));
+ switch (functypclass)
+ {
+ case TYPEFUNC_RECORD:
+ /* ok */
+ break;
+ case TYPEFUNC_COMPOSITE:
+ case TYPEFUNC_COMPOSITE_DOMAIN:
+
+ /*
+ * If the function's raw result type is RECORD, we must
+ * have resolved it using its OUT parameters. Otherwise,
+ * it must have a named composite type.
+ */
+ if (exprType(funcexpr) == RECORDOID)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("a column definition list is redundant for a function with OUT parameters"),
+ parser_errposition(pstate,
+ exprLocation((Node *) coldeflist))));
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("a column definition list is redundant for a function returning a named composite type"),
+ parser_errposition(pstate,
+ exprLocation((Node *) coldeflist))));
+ break;
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("a column definition list is only allowed for functions returning \"record\""),
+ parser_errposition(pstate,
+ exprLocation((Node *) coldeflist))));
+ break;
+ }
}
else
{