Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
22ae53d4
Commit
22ae53d4
authored
Sep 06, 2001
by
Peter Eisentraut
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move the "how to write a PL call handler" parts from the CREATE LANGUAGE
man page to the Programmer's Guide.
parent
f25ed23c
Changes
2
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
386 additions
and
321 deletions
+386
-321
doc/src/sgml/ref/create_language.sgml
doc/src/sgml/ref/create_language.sgml
+213
-315
doc/src/sgml/xfunc.sgml
doc/src/sgml/xfunc.sgml
+173
-6
No files found.
doc/src/sgml/ref/create_language.sgml
View file @
22ae53d4
This diff is collapsed.
Click to expand it.
doc/src/sgml/xfunc.sgml
View file @
22ae53d4
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.3
3 2001/08/28 14:20:26
petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.3
4 2001/09/06 10:28:39
petere Exp $
-->
<chapter id="xfunc">
...
...
@@ -337,11 +337,11 @@ SELECT clean_EMP();
</para>
<para>
There are currently
three procedural languages available in the standard
<productname>Postgres</productname> distribution (PLSQL, PLTCL and
PL
PERL), and other languages can be defined.
Refer to <xref linkend="xplang"> for
more
information.
There are currently
four procedural languages available in the
standard <productname>PostgreSQL</productname> distribution:
PL
/pgSQL, PL/Tcl, PL/Perl, and PL/Python. Other languages can be
defined by users. Refer to <xref linkend="xplang"> for more
information.
</para>
</sect1>
...
...
@@ -1357,6 +1357,173 @@ LANGUAGE 'c';
</sect3>
</sect2>
</sect1>
<sect1 id="xfunc-plhandler">
<title>Procedural Language Handlers</title>
<para>
All calls to functions that are written in a language other than
the current <quote>version 1</quote> interface for compiled
languages, in particular in user-defined procedural languages, but
also functions written in SQL or the version 0 compiled language
interface, go through a <firstterm>call handler</firstterm>
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 <productname>PostgreSQL</productname>, but the
topic naturally belongs in this chapter, and the material might
give some insight into the extensible nature of the
<productname>PostgreSQL</productname> system.
</para>
<para>
The call handler for a procedural language is a
<quote>normal</quote> function, which must be written in a
compiled language such as C and registered with
<productname>PostgreSQL</productname> as taking no arguments and
returning the <type>opaque</type> type, a placeholder for
unspecified or undefined types. This prevents the call handler
from being called directly as a function from queries. (However,
arguments may be supplied in the actual call to the handler when a
function in the language offered by the handler is to be
executed.)
</para>
<note>
<para>
In <productname>PostgreSQL</productname> 7.1 and later, call
handlers must adhere to the <quote>version 1</quote> function
manager interface, not the old-style interface.
</para>
</note>
<para>
The call handler is called in the same way as any other function:
It receives a pointer to a
<structname>FunctionCallInfoData</structname> struct containing
argument values and information about the called function, and it
is expected to return a <type>Datum</type> result (and possibly
set the <structfield>isnull</structfield> field of the
<structname>FunctionCallInfoData</structname> struct, if it wishes
to return an SQL NULL result). The difference between a call
handler and an ordinary callee function is that the
<structfield>flinfo->fn_oid</structfield> field of the
<structname>FunctionCallInfoData</structname> struct 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.
</para>
<para>
It's up to the call handler to fetch the
<classname>pg_proc</classname> entry and to analyze the argument
and return types of the called procedure. The AS clause from the
<command>CREATE FUNCTION</command> of the procedure will be found
in the <literal>prosrc</literal> attribute of the
<classname>pg_proc</classname> table entry. This may be the source
text in the procedural language itself (like for PL/Tcl), a
pathname to a file, or anything else that tells the call handler
what to do in detail.
</para>
<para>
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
<structfield>flinfo->fn_extra</structfield> field. This will
initially be NULL, but can be set by the call handler to point at
information about the PL function. On subsequent calls, if
<structfield>flinfo->fn_extra</structfield> is already non-NULL
then it can be used and the information lookup step skipped. The
call handler must be careful that
<structfield>flinfo->fn_extra</structfield> is made to point at
memory that will live at least until the end of the current query,
since an <structname>FmgrInfo</structname> data structure could be
kept that long. One way to do this is to allocate the extra data
in the memory context specified by
<structfield>flinfo->fn_mcxt</structfield>; such data will
normally have the same lifespan as the
<structname>FmgrInfo</structname> itself. But the handler could
also choose to use a longer-lived context so that it can cache
function definition information across queries.
</para>
<para>
When a PL function is invoked as a trigger, no explicit arguments
are passed, but the
<structname>FunctionCallInfoData</structname>'s
<structfield>context</structfield> field points at a
<structname>TriggerData</structname> node, rather than being NULL
as it is in a plain function call. A language handler should
provide mechanisms for PL functions to get at the trigger
information.
</para>
<para>
This is a template for a PL handler written in C:
<programlisting>
#include "postgres.h"
#include "executor/spi.h"
#include "commands/trigger.h"
#include "utils/elog.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;
}
</programlisting>
</para>
<para>
Only a few thousand lines of code have to be added instead of the
dots to complete the call handler. See <xref linkend="xfunc-c">
for information on how to compile it into a loadable module.
</para>
<para>
The following commands then register the sample procedural
language:
<programlisting>
CREATE FUNCTION plsample_call_handler () RETURNS opaque
AS '/usr/local/pgsql/lib/plsample.so'
LANGUAGE C;
CREATE LANGUAGE plsample
HANDLER plsample_call_handler;
</programlisting>
</para>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment