aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/functions.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2025-04-17 12:56:40 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2025-04-17 12:56:40 -0400
commit0400ae4a68831250347407463453447daa9548df (patch)
tree9712433d9dc60b1e10226a75aa65a86328eea9dc /src/backend/executor/functions.c
parent0313c5dc627a1407344617fa8dd84ce1374ec915 (diff)
downloadpostgresql-0400ae4a68831250347407463453447daa9548df.tar.gz
postgresql-0400ae4a68831250347407463453447daa9548df.zip
Cache typlens of a SQL function's input arguments.
This gets rid of repetitive get_typlen calls in postquel_sub_params, which show up as costing a few percent of the runtime in simple test cases (more with more parameters). In combination with the preceding patches, this gets us most of the way back down to the amount of per-call overhead that functions.c had before commit 0dca5d68d. There are some more things that could be done, but this seems like an okay place to stop for v18.
Diffstat (limited to 'src/backend/executor/functions.c')
-rw-r--r--src/backend/executor/functions.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index 135fddda3fc..e0bca7cb81c 100644
--- a/src/backend/executor/functions.c
+++ b/src/backend/executor/functions.c
@@ -116,6 +116,7 @@ typedef struct SQLFunctionHashEntry
char *src; /* function body text (for error msgs) */
SQLFunctionParseInfoPtr pinfo; /* data for parser callback hooks */
+ int16 *argtyplen; /* lengths of the input argument types */
Oid rettype; /* actual return type */
int16 typlen; /* length of the return type */
@@ -1101,6 +1102,15 @@ sql_compile_callback(FunctionCallInfo fcinfo,
MemoryContextSwitchTo(oldcontext);
/*
+ * Now that we have the resolved argument types, collect their typlens for
+ * use in postquel_sub_params.
+ */
+ func->argtyplen = (int16 *)
+ MemoryContextAlloc(hcontext, func->pinfo->nargs * sizeof(int16));
+ for (int i = 0; i < func->pinfo->nargs; i++)
+ func->argtyplen[i] = get_typlen(func->pinfo->argtypes[i]);
+
+ /*
* And of course we need the function body text.
*/
tmp = SysCacheGetAttrNotNull(PROCOID, procedureTuple, Anum_pg_proc_prosrc);
@@ -1427,6 +1437,7 @@ postquel_sub_params(SQLFunctionCachePtr fcache,
{
ParamListInfo paramLI;
Oid *argtypes = fcache->func->pinfo->argtypes;
+ int16 *argtyplen = fcache->func->argtyplen;
if (fcache->paramLI == NULL)
{
@@ -1463,7 +1474,7 @@ postquel_sub_params(SQLFunctionCachePtr fcache,
prm->isnull = fcinfo->args[i].isnull;
prm->value = MakeExpandedObjectReadOnly(fcinfo->args[i].value,
prm->isnull,
- get_typlen(argtypes[i]));
+ argtyplen[i]);
/* Allow the value to be substituted into custom plans */
prm->pflags = PARAM_FLAG_CONST;
prm->ptype = argtypes[i];