3 <chapter id=
"plhandler">
4 <title>Writing A Procedural Language Handler
</title>
6 <indexterm zone=
"plhandler">
7 <primary>procedural language
</primary>
8 <secondary>handler for
</secondary>
12 All calls to functions that are written in a language other than
13 the current
<quote>version
1</quote> interface for compiled
14 languages (this includes functions in user-defined procedural languages,
15 functions written in SQL, and functions using the version
0 compiled
16 language interface), go through a
<firstterm>call handler
</firstterm>
17 function for the specific language. It is the responsibility of
18 the call handler to execute the function in a meaningful way, such
19 as by interpreting the supplied source text. This chapter outlines
20 how a new procedural language's call handler can be written.
24 The call handler for a procedural language is a
25 <quote>normal
</quote> function that must be written in a compiled
26 language such as C, using the version-
1 interface, and registered
27 with
<productname>PostgreSQL
</productname> as taking no arguments
28 and returning the type
<type>language_handler
</type>. This
29 special pseudotype identifies the function as a call handler and
30 prevents it from being called directly in SQL commands.
34 The call handler is called in the same way as any other function:
35 It receives a pointer to a
36 <structname>FunctionCallInfoData
</structname> <type>struct<
/> containing
37 argument values and information about the called function, and it
38 is expected to return a
<type>Datum
</type> result (and possibly
39 set the
<structfield>isnull
</structfield> field of the
40 <structname>FunctionCallInfoData
</structname> structure, if it wishes
41 to return an SQL null result). The difference between a call
42 handler and an ordinary callee function is that the
43 <structfield>flinfo-
>fn_oid
</structfield> field of the
44 <structname>FunctionCallInfoData
</structname> structure will contain
45 the OID of the actual function to be called, not of the call
46 handler itself. The call handler must use this field to determine
47 which function to execute. Also, the passed argument list has
48 been set up according to the declaration of the target function,
49 not of the call handler.
53 It's up to the call handler to fetch the entry of the function from the
55 <classname>pg_proc
</classname> and to analyze the argument
56 and return types of the called function. The
<literal>AS<
/> clause from the
57 <command>CREATE FUNCTION
</command> command for the function will be found
58 in the
<literal>prosrc
</literal> column of the
59 <classname>pg_proc
</classname> row. This is commonly source
60 text in the procedural language, but in theory it could be something else,
61 such as a path name to a file, or anything else that tells the call handler
66 Often, the same function is called many times per SQL statement.
67 A call handler can avoid repeated lookups of information about the
68 called function by using the
69 <structfield>flinfo-
>fn_extra
</structfield> field. This will
70 initially be
<symbol>NULL<
/>, but can be set by the call handler to point at
71 information about the called function. On subsequent calls, if
72 <structfield>flinfo-
>fn_extra
</structfield> is already non-
<symbol>NULL<
/>
73 then it can be used and the information lookup step skipped. The
74 call handler must make sure that
75 <structfield>flinfo-
>fn_extra
</structfield> is made to point at
76 memory that will live at least until the end of the current query,
77 since an
<structname>FmgrInfo
</structname> data structure could be
78 kept that long. One way to do this is to allocate the extra data
79 in the memory context specified by
80 <structfield>flinfo-
>fn_mcxt
</structfield>; such data will
81 normally have the same lifespan as the
82 <structname>FmgrInfo
</structname> itself. But the handler could
83 also choose to use a longer-lived memory context so that it can cache
84 function definition information across queries.
88 When a procedural-language function is invoked as a trigger, no arguments
89 are passed in the usual way, but the
90 <structname>FunctionCallInfoData
</structname>'s
91 <structfield>context
</structfield> field points at a
92 <structname>TriggerData
</structname> structure, rather than being
<symbol>NULL<
/>
93 as it is in a plain function call. A language handler should
94 provide mechanisms for procedural-language functions to get at the trigger
99 This is a template for a procedural-language handler written in C:
101 #include
"postgres.h"
102 #include
"executor/spi.h"
103 #include
"commands/trigger.h"
105 #include
"access/heapam.h"
106 #include
"utils/syscache.h"
107 #include
"catalog/pg_proc.h"
108 #include
"catalog/pg_type.h"
110 PG_FUNCTION_INFO_V1(plsample_call_handler);
113 plsample_call_handler(PG_FUNCTION_ARGS)
117 if (CALLED_AS_TRIGGER(fcinfo))
120 * Called as a trigger procedure
122 TriggerData *trigdata = (TriggerData *) fcinfo-
>context;
129 * Called as a function
138 Only a few thousand lines of code have to be added instead of the
139 dots to complete the call handler.
143 After having compiled the handler function into a loadable module
144 (see
<xref linkend=
"dfunc">), the following commands then
145 register the sample procedural language:
147 CREATE FUNCTION plsample_call_handler() RETURNS language_handler
148 AS '
<replaceable>filename
</replaceable>'
150 CREATE LANGUAGE plsample
151 HANDLER plsample_call_handler;
156 The procedural languages included in the standard distribution
157 are good references when trying to write your own call handler.
158 Look into the
<filename>src/pl<
/> subdirectory of the source tree.