From 09b07c29532fe7db87cbfe1c54355cfc80291b6c Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 17 Apr 2025 12:55:58 -0400 Subject: [PATCH] Minor performance improvement for SQL-language functions. Late in the development of commit 0dca5d68d, I added a step to copy the result tlist we extract from the cached final query, because I was afraid that that might not last as long as the JunkFilter that we're passing it off to. However, that turns out to cost a noticeable number of cycles, and it's really quite unnecessary because the JunkFilter will not examine that tlist after it's been created. (ExecFindJunkAttribute would use it, but we don't use that function on this JunkFilter.) Hence, remove the copy step. For safety, reset the might-become-dangling jf_targetList pointer to NIL. In passing, remove DR_sqlfunction.cxt, which we don't use anymore; it's confusing because it's not entirely clear which context it ought to point at. --- src/backend/executor/functions.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c index 53ff614d87b..d3f05c7d2c7 100644 --- a/src/backend/executor/functions.c +++ b/src/backend/executor/functions.c @@ -45,7 +45,6 @@ typedef struct { DestReceiver pub; /* publicly-known function pointers */ Tuplestorestate *tstore; /* where to put result tuples */ - MemoryContext cxt; /* context containing tstore */ JunkFilter *filter; /* filter to convert tuple type */ } DR_sqlfunction; @@ -787,12 +786,6 @@ init_execution_state(SQLFunctionCachePtr fcache) */ resulttlist = get_sql_fn_result_tlist(plansource->query_list); - /* - * We need to make a copy to ensure that it doesn't disappear - * underneath us due to plancache invalidation. - */ - resulttlist = copyObject(resulttlist); - /* * If the result is composite, *and* we are returning the whole tuple * result, we need to insert nulls for any dropped columns. In the @@ -807,6 +800,17 @@ init_execution_state(SQLFunctionCachePtr fcache) slot); else fcache->junkFilter = ExecInitJunkFilter(resulttlist, slot); + + /* + * The resulttlist tree belongs to the plancache and might disappear + * underneath us due to plancache invalidation. While we could + * forestall that by copying it, that'd just be a waste of cycles, + * because the junkfilter doesn't need it anymore. (It'd only be used + * by ExecFindJunkAttribute(), which we don't use here.) To ensure + * there's not a dangling pointer laying about, clear the junkFilter's + * pointer. + */ + fcache->junkFilter->jf_targetList = NIL; } if (fcache->func->returnsTuple) @@ -1245,7 +1249,6 @@ postquel_start(execution_state *es, SQLFunctionCachePtr fcache) myState = (DR_sqlfunction *) dest; Assert(myState->pub.mydest == DestSQLFunction); myState->tstore = fcache->tstore; - myState->cxt = CurrentMemoryContext; myState->filter = fcache->junkFilter; } else