aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/functioncmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/functioncmds.c')
-rw-r--r--src/backend/commands/functioncmds.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 9cf3fe8275e..6593fd7d811 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -52,6 +52,7 @@
#include "executor/functions.h"
#include "funcapi.h"
#include "miscadmin.h"
+#include "nodes/nodeFuncs.h"
#include "optimizer/optimizer.h"
#include "parser/analyze.h"
#include "parser/parse_coerce.h"
@@ -2364,5 +2365,32 @@ CallStmtResultDesc(CallStmt *stmt)
ReleaseSysCache(tuple);
+ /*
+ * The result of build_function_result_tupdesc_t has the right column
+ * names, but it just has the declared output argument types, which is the
+ * wrong thing in polymorphic cases. Get the correct types by examining
+ * stmt->outargs. We intentionally keep the atttypmod as -1 and the
+ * attcollation as the type's default, since that's always the appropriate
+ * thing for function outputs; there's no point in considering any
+ * additional info available from outargs. Note that tupdesc is null if
+ * there are no outargs.
+ */
+ if (tupdesc)
+ {
+ Assert(tupdesc->natts == list_length(stmt->outargs));
+ for (int i = 0; i < tupdesc->natts; i++)
+ {
+ Form_pg_attribute att = TupleDescAttr(tupdesc, i);
+ Node *outarg = (Node *) list_nth(stmt->outargs, i);
+
+ TupleDescInitEntry(tupdesc,
+ i + 1,
+ NameStr(att->attname),
+ exprType(outarg),
+ -1,
+ 0);
+ }
+ }
+
return tupdesc;
}