1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-17 17:02:08 +03:00

When a function not returning RECORD has a single OUT parameter, use

the parameter's name (if any) as the default column name for SELECT FROM
the function, rather than the function name as previously.  I still think
this is a bad idea, but I lost the argument.  Force decompilation of
function RTEs to specify full aliases always, to reduce the odds of this
decision breaking dumped views.
This commit is contained in:
Tom Lane
2005-10-06 19:51:16 +00:00
parent fa63749d21
commit 9ea14ef56a
6 changed files with 215 additions and 41 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.113 2005/08/01 20:31:10 tgl Exp $
* $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.114 2005/10/06 19:51:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -505,6 +505,59 @@ buildRelationAliases(TupleDesc tupdesc, Alias *alias, Alias *eref)
eref->aliasname, maxattrs - numdropped, numaliases)));
}
/*
* buildScalarFunctionAlias
* Construct the eref column name list for a function RTE,
* when the function returns a scalar type (not composite or RECORD).
*
* funcexpr: transformed expression tree for the function call
* funcname: function name (used only for error message)
* alias: the user-supplied alias, or NULL if none
* eref: the eref Alias to store column names in
*
* eref->colnames is filled in.
*/
static void
buildScalarFunctionAlias(Node *funcexpr, char *funcname,
Alias *alias, Alias *eref)
{
char *pname;
Assert(eref->colnames == NIL);
/* Use user-specified column alias if there is one. */
if (alias && alias->colnames != NIL)
{
if (list_length(alias->colnames) != 1)
ereport(ERROR,
(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
errmsg("too many column aliases specified for function %s",
funcname)));
eref->colnames = copyObject(alias->colnames);
return;
}
/*
* If the expression is a simple function call, and the function has a
* single OUT parameter that is named, use the parameter's name.
*/
if (funcexpr && IsA(funcexpr, FuncExpr))
{
pname = get_func_result_name(((FuncExpr *) funcexpr)->funcid);
if (pname)
{
eref->colnames = list_make1(makeString(pname));
return;
}
}
/*
* Otherwise use the previously-determined alias (not necessarily the
* function name!)
*/
eref->colnames = list_make1(makeString(eref->aliasname));
}
/*
* Add an entry for a relation to the pstate's range table (p_rtable).
*
@ -776,18 +829,7 @@ addRangeTableEntryForFunction(ParseState *pstate,
else if (functypclass == TYPEFUNC_SCALAR)
{
/* Base data type, i.e. scalar */
/* Just add one alias column named for the function. */
if (alias && alias->colnames != NIL)
{
if (list_length(alias->colnames) != 1)
ereport(ERROR,
(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
errmsg("too many column aliases specified for function %s",
funcname)));
eref->colnames = copyObject(alias->colnames);
}
else
eref->colnames = list_make1(makeString(eref->aliasname));
buildScalarFunctionAlias(funcexpr, funcname, alias, eref);
}
else if (functypclass == TYPEFUNC_RECORD)
{