diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2005-10-06 19:51:16 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2005-10-06 19:51:16 +0000 |
commit | 9ea14ef56ab8b7d22a4148c4e6765a7874d968a4 (patch) | |
tree | f6005a6fb3a7fd76101c94c6951fbc814eb0f161 /src/backend/parser/parse_relation.c | |
parent | fa63749d2177c3bf700f10a3d297954328ddf3bf (diff) | |
download | postgresql-9ea14ef56ab8b7d22a4148c4e6765a7874d968a4.tar.gz postgresql-9ea14ef56ab8b7d22a4148c4e6765a7874d968a4.zip |
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.
Diffstat (limited to 'src/backend/parser/parse_relation.c')
-rw-r--r-- | src/backend/parser/parse_relation.c | 68 |
1 files changed, 55 insertions, 13 deletions
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index 85984cb1d9e..196936bb094 100644 --- a/src/backend/parser/parse_relation.c +++ b/src/backend/parser/parse_relation.c @@ -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 $ * *------------------------------------------------------------------------- */ @@ -506,6 +506,59 @@ buildRelationAliases(TupleDesc tupdesc, Alias *alias, Alias *eref) } /* + * 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). * * If pstate is NULL, we just build an RTE and return it without adding it @@ -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) { |