From 515e813543dad5464c1a226fd068fd4daf26a7f9 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Thu, 3 Nov 2011 17:53:13 -0400
Subject: [PATCH] Fix inline_set_returning_function() to allow multiple OUT
 parameters.

inline_set_returning_function failed to distinguish functions returning
generic RECORD (which require a column list in the RTE, as well as run-time
type checking) from those with multiple OUT parameters (which do not).
This prevented inlining from happening.  Per complaint from Jay Levitt.
Back-patch to 8.4 where this capability was introduced.
---
 src/backend/optimizer/util/clauses.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index baa90fa9b20..20e315e77a6 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -26,6 +26,7 @@
 #include "catalog/pg_type.h"
 #include "executor/executor.h"
 #include "executor/functions.h"
+#include "funcapi.h"
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
@@ -4516,9 +4517,12 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte)
 	 * If it returns RECORD, we have to check against the column type list
 	 * provided in the RTE; check_sql_fn_retval can't do that.  (If no match,
 	 * we just fail to inline, rather than complaining; see notes for
-	 * tlist_matches_coltypelist.)
+	 * tlist_matches_coltypelist.)  We don't have to do this for functions
+	 * with declared OUT parameters, even though their funcresulttype is
+	 * RECORDOID, so check get_func_result_type too.
 	 */
 	if (fexpr->funcresulttype == RECORDOID &&
+		get_func_result_type(func_oid, NULL, NULL) == TYPEFUNC_RECORD &&
 		!tlist_matches_coltypelist(querytree->targetList, rte->funccoltypes))
 		goto fail;
 
-- 
GitLab