aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_relation.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2005-10-06 19:51:16 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2005-10-06 19:51:16 +0000
commit9ea14ef56ab8b7d22a4148c4e6765a7874d968a4 (patch)
treef6005a6fb3a7fd76101c94c6951fbc814eb0f161 /src/backend/parser/parse_relation.c
parentfa63749d2177c3bf700f10a3d297954328ddf3bf (diff)
downloadpostgresql-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.c68
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)
{