Copy Tuple Desc in internal_get_result_type

Started by Lakshmi Narayana Velayudam8 months ago1 messages
#1Lakshmi Narayana Velayudam
dev.narayana.v@gmail.com
1 attachment(s)

Hello,
I would like to propose a modification to the internal_get_result_type
function, which is called from *get_call_result_type*. Specifically, I
recommend altering it to return a copy of *rsinfo->expectedDesc*.

Currently, callers are responsible for copying the tuple descriptor
returned from *get_call_result_type* before assigning it to rsinfo->setDesc
as part of set-returning functions in mode *SFRM_Materialize *if not copied
then it can lead to unexpected behavior because rsinfo->expectedDesc will
be unintentionally freed at the end of ExecMakeTableFunctionResult as
rsinfo->setDesc holds its reference. This can be overlooked, unless a
user-defined function (UDF) is invoked multiple times within the same query.

*Example*: Queries involving lateral joins with user-defined functions
(UDFs).

For your convenience, I have created a GitHub repository demonstrating the
issue with a C extension: https://github.com/narayana-dev/srfbug

Additionally, I have attached the patch file for your review.

I look forward to your feedback.

Best regards,
Lakshmi Narayana Velayudam

Attachments:

copy_tup_desc.patchapplication/octet-stream; name=copy_tup_desc.patchDownload
diff --git a/src/backend/utils/fmgr/funcapi.c b/src/backend/utils/fmgr/funcapi.c
index 5f2317211c9..093d2b04f8d 100644
--- a/src/backend/utils/fmgr/funcapi.c
+++ b/src/backend/utils/fmgr/funcapi.c
@@ -523,7 +523,7 @@ internal_get_result_type(Oid funcid,
 			{
 				result = TYPEFUNC_COMPOSITE;
 				if (resultTupleDesc)
-					*resultTupleDesc = rsinfo->expectedDesc;
+					*resultTupleDesc = CreateTupleDescCopyConstr(rsinfo->expectedDesc);
 				/* Assume no polymorphic columns here, either */
 			}
 			break;