Chapter 48. Writing A
Procedural Language Handler

All calls to functions that are written in a language other
than the current "version 1" interface
for compiled languages (this includes functions in user-defined
procedural languages, functions written in SQL, and functions
using the version 0 compiled language interface), go through a
call handler function for the specific
language. It is the responsibility of the call handler to execute
the function in a meaningful way, such as by interpreting the
supplied source text. This chapter outlines how a new procedural
language's call handler can be written.

The call handler for a procedural language is a "normal" function that must be written in a
compiled language such as C, using the version-1 interface, and
registered with PostgreSQL as
taking no arguments and returning the type language_handler. This special pseudotype identifies
the function as a call handler and prevents it from being called
directly in SQL commands.

The call handler is called in the same way as any other
function: It receives a pointer to a FunctionCallInfoDatastruct containing argument values and information
about the called function, and it is expected to return a
Datum result (and possibly set the
isnull field of the FunctionCallInfoData structure, if it wishes to
return an SQL null result). The difference between a call handler
and an ordinary callee function is that the flinfo->fn_oid field of the FunctionCallInfoData structure will contain the
OID of the actual function to be called, not of the call handler
itself. The call handler must use this field to determine which
function to execute. Also, the passed argument list has been set
up according to the declaration of the target function, not of
the call handler.

It's up to the call handler to fetch the entry of the function
from the system table pg_proc and
to analyze the argument and return types of the called function.
The AS clause from the CREATE FUNCTION command for the function will be
found in the prosrc column of the
pg_proc row. This is commonly
source text in the procedural language, but in theory it could be
something else, such as a path name to a file, or anything else
that tells the call handler what to do in detail.

Often, the same function is called many times per SQL
statement. A call handler can avoid repeated lookups of
information about the called function by using the flinfo->fn_extra field. This will initially
be NULL, but can be set by the call
handler to point at information about the called function. On
subsequent calls, if flinfo->fn_extra is already non-NULL then it can be used and the information lookup
step skipped. The call handler must make sure that flinfo->fn_extra is made to point at memory
that will live at least until the end of the current query, since
an FmgrInfo data structure could be
kept that long. One way to do this is to allocate the extra data
in the memory context specified by flinfo->fn_mcxt; such data will normally
have the same lifespan as the FmgrInfo itself. But the handler could also
choose to use a longer-lived memory context so that it can cache
function definition information across queries.

When a procedural-language function is invoked as a trigger,
no arguments are passed in the usual way, but the FunctionCallInfoData's context field points at a TriggerData structure, rather than being
NULL as it is in a plain function call. A
language handler should provide mechanisms for
procedural-language functions to get at the trigger
information.