Hi Now concat is 2x times slower than || operator. With cached FmgrInfo for output function it will be only 5%.
Regards Pavel
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c index be399f4..d3f04f8 100644 --- a/src/backend/utils/adt/varlena.c +++ b/src/backend/utils/adt/varlena.c @@ -4718,6 +4718,28 @@ string_agg_finalfn(PG_FUNCTION_ARGS) PG_RETURN_NULL(); } +static void +rebuildConcatCache(FmgrInfo *typcache, FunctionCallInfo fcinfo, int argidx) +{ + int i; + + Assert(typcache != NULL); + + for (i = argidx; i < PG_NARGS(); i++) + { + Oid valtype; + Oid typOutput; + bool typIsVarlena; + + valtype = get_fn_expr_argtype(fcinfo->flinfo, i); + if (!OidIsValid(valtype)) + elog(ERROR, "could not determine data type of concat() input"); + + getTypeOutputInfo(valtype, &typOutput, &typIsVarlena); + fmgr_info_cxt(typOutput, &typcache[i-argidx], fcinfo->flinfo->fn_mcxt); + } +} + /* * Implementation of both concat() and concat_ws(). * @@ -4733,6 +4755,7 @@ concat_internal(const char *sepstr, int argidx, StringInfoData str; bool first_arg = true; int i; + FmgrInfo *typcache; /* * concat(VARIADIC some-array) is essentially equivalent to @@ -4772,14 +4795,20 @@ concat_internal(const char *sepstr, int argidx, /* Normal case without explicit VARIADIC marker */ initStringInfo(&str); + typcache = (FmgrInfo *) fcinfo->flinfo->fn_extra; + if (typcache == NULL) + { + fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, + PG_NARGS() * sizeof(FmgrInfo)); + typcache = (FmgrInfo *) fcinfo->flinfo->fn_extra; + rebuildConcatCache(typcache, fcinfo, argidx); + } + for (i = argidx; i < PG_NARGS(); i++) { if (!PG_ARGISNULL(i)) { Datum value = PG_GETARG_DATUM(i); - Oid valtype; - Oid typOutput; - bool typIsVarlena; /* add separator if appropriate */ if (first_arg) @@ -4787,13 +4816,8 @@ concat_internal(const char *sepstr, int argidx, else appendStringInfoString(&str, sepstr); - /* call the appropriate type output function, append the result */ - valtype = get_fn_expr_argtype(fcinfo->flinfo, i); - if (!OidIsValid(valtype)) - elog(ERROR, "could not determine data type of concat() input"); - getTypeOutputInfo(valtype, &typOutput, &typIsVarlena); appendStringInfoString(&str, - OidOutputFunctionCall(typOutput, value)); + OutputFunctionCall(&typcache[i-argidx], value)); } }
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers