- linkend="xfunc-plhandler">). Version-1 code is also more
+ linkend="plhandler">). Version-1 code is also more
portable than version-0, because it does not break restrictions
on function call protocol in the C standard. For more details
see src/backend/utils/fmgr/README in the
-
-
Procedural Language Handlers
-
-
- handler for
-
-
- 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 section
- describes how a language call handler can be written. This is not
- a common task, in fact, it has only been done a handful of times
- in the history of
PostgreSQL, but the
- topic naturally belongs in this chapter, and the material might
- give some insight into the extensible nature of the
-
-
- 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
- FunctionCallInfoData struct> 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 of the function will be found
- in the prosrc column of the
- pg_proc row. This may be the source
- text in the procedural language itself (like for PL/Tcl), 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.
-
-
- This is a template for a procedural-language handler written in C:
-#include "postgres.h"
-#include "executor/spi.h"
-#include "commands/trigger.h"
-#include "fmgr.h"
-#include "access/heapam.h"
-#include "utils/syscache.h"
-#include "catalog/pg_proc.h"
-#include "catalog/pg_type.h"
-
-PG_FUNCTION_INFO_V1(plsample_call_handler);
-
-Datum
-plsample_call_handler(PG_FUNCTION_ARGS)
-{
- Datum retval;
-
- if (CALLED_AS_TRIGGER(fcinfo))
- {
- /*
- * Called as a trigger procedure
- */
- TriggerData *trigdata = (TriggerData *) fcinfo->context;
-
- retval = ...
- }
- else
- {
- /*
- * Called as a function
- */
-
- retval = ...
- }
-
- return retval;
-}
-
- Only a few thousand lines of code have to be added instead of the
- dots to complete the call handler.
-
-
- After having compiled the handler function into a loadable module
- (see ), the following commands then
- register the sample procedural language:
-CREATE FUNCTION plsample_call_handler() RETURNS language_handler
- AS 'filename'
- LANGUAGE C;
-CREATE LANGUAGE plsample
- HANDLER plsample_call_handler;
-
-
-
-
Writing a handler for a new procedural language is described in
- xfunc-plhandler">. Several procedural languages are
+ . Several procedural languages are
available in the standard
PostgreSQL
distribution, which can serve as examples.