Re: PostgreSQL, C-Extension, calling other Functions

From: Andrew Gierth <andrew(at)tao11(dot)riddles(dot)org(dot)uk>
To: "Stefan Wolf" <sw(at)zpmt(dot)de>
Cc: <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: PostgreSQL, C-Extension, calling other Functions
Date: 2019-10-11 15:28:15
Message-ID: 87r23jxsck.fsf@news-spur.riddles.org.uk
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

>>>>> "Stefan" == Stefan Wolf <sw(at)zpmt(dot)de> writes:

Stefan> I´ve written some PostgreSQL C-Extensions (for the first
Stefan> time...) and they work as expected.

Stefan> But now I want to call other functions from inside the
Stefan> C-Extensions (but not via SPI_execute), for example
Stefan> "regexp_match()" or from other extensions like PostGIS
Stefan> "ST_POINT" etc...

Stefan> I think "fmgr" is the key - but I didn't find any examples.

There are a number of levels of difficulty here depending on which
specific functions you need to call and whether you need to handle
NULLs.

The simplest case is using DirectFunctionCall[N][Coll] to call a builtin
(internal-language) function. This _only_ works for functions that don't
require access to an flinfo; many functions either need the flinfo to
get parameter type info or to use fn_extra as a per-callsite cache.
(Also there's no guarantee that a function that works without flinfo now
will continue to do so in future versions.) One restriction of this
method is that neither parameters nor results may be NULL.

The next step up from that is getting a function's Oid and using
OidFunctionCall[N][Coll]. This can call functions in any language,
including dynamic-loaded ones, but it can't handle polymorphic
functions. (Overloaded functions are fine, since each overload has its
own Oid.) This is still fairly simple but is inefficient: it constructs
and populates the flinfo, calls it once, then abandons it (it's not even
freed, it's up to the calling memory context to do that). If you're
going to be invoking a function repeatedly, it's worth avoiding this
one. This still has the restriction of no NULLs either in or out.

The next step from that is calling fmgr_info and FunctionCall[N][Coll]
separately (which is just breaking down OidFunctionCall into its parts);
this allows you to re-use the flinfo for multiple calls. Still no NULLs
allowed, but it's possible to use polymorphic functions if you try hard
enough (it's not documented, but it requires consing up a faked
expression tree and using fmgr_info_set_expr).

Finally, if none of the above apply, you're at the level where you
should seriously consider using SPI regardless; but if you don't want to
do that, you can use fmgr_info, InitFunctionCallInfoData and
FunctionCallInvoke.

--
Andrew (irc:RhodiumToad)

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2019-10-11 15:45:31 Re: stress test for parallel workers
Previous Message Andrew Dunstan 2019-10-11 15:12:28 Re: stress test for parallel workers