aboutsummaryrefslogtreecommitdiff
path: root/doc/src/sgml/xfunc.sgml
diff options
context:
space:
mode:
Diffstat (limited to 'doc/src/sgml/xfunc.sgml')
-rw-r--r--doc/src/sgml/xfunc.sgml331
1 files changed, 64 insertions, 267 deletions
diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml
index 4ad50ec0cb5..4f2c23fab7a 100644
--- a/doc/src/sgml/xfunc.sgml
+++ b/doc/src/sgml/xfunc.sgml
@@ -2392,273 +2392,6 @@ concat_text(PG_FUNCTION_ARGS)
&dfunc;
- <sect2 id="xfunc-c-pgxs">
- <title>Extension Building Infrastructure</title>
-
- <indexterm zone="xfunc-c-pgxs">
- <primary>pgxs</primary>
- </indexterm>
-
- <para>
- If you are thinking about distributing your
- <productname>PostgreSQL</> extension modules, setting up a
- portable build system for them can be fairly difficult. Therefore
- the <productname>PostgreSQL</> installation provides a build
- infrastructure for extensions, called <acronym>PGXS</acronym>, so
- that simple extension modules can be built simply against an
- already installed server. Note that this infrastructure is not
- intended to be a universal build system framework that can be used
- to build all software interfacing to <productname>PostgreSQL</>;
- it simply automates common build rules for simple server extension
- modules. For more complicated packages, you need to write your
- own build system.
- </para>
-
- <para>
- To use the infrastructure for your extension, you must write a
- simple makefile. In that makefile, you need to set some variables
- and finally include the global <acronym>PGXS</acronym> makefile.
- Here is an example that builds an extension module named
- <literal>isbn_issn</literal> consisting of a shared library, an
- SQL script, and a documentation text file:
-<programlisting>
-MODULES = isbn_issn
-DATA_built = isbn_issn.sql
-DOCS = README.isbn_issn
-
-PG_CONFIG = pg_config
-PGXS := $(shell $(PG_CONFIG) --pgxs)
-include $(PGXS)
-</programlisting>
- The last three lines should always be the same. Earlier in the
- file, you assign variables or add custom
- <application>make</application> rules.
- </para>
-
- <para>
- Set one of these three variables to specify what is built:
-
- <variablelist>
- <varlistentry>
- <term><varname>MODULES</varname></term>
- <listitem>
- <para>
- list of shared objects to be built from source files with same
- stem (do not include suffix in this list)
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>MODULE_big</varname></term>
- <listitem>
- <para>
- a shared object to build from multiple source files
- (list object files in <varname>OBJS</varname>)
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>PROGRAM</varname></term>
- <listitem>
- <para>
- a binary program to build
- (list object files in <varname>OBJS</varname>)
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
-
- The following variables can also be set:
-
- <variablelist>
- <varlistentry>
- <term><varname>MODULEDIR</varname></term>
- <listitem>
- <para>
- subdirectory into which DATA and DOCS files should be
- installed (if not set, default is <literal>contrib</literal>)
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>DATA</varname></term>
- <listitem>
- <para>
- random files to install into <literal><replaceable>prefix</replaceable>/share/$MODULEDIR</literal>
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>DATA_built</varname></term>
- <listitem>
- <para>
- random files to install into
- <literal><replaceable>prefix</replaceable>/share/$MODULEDIR</literal>,
- which need to be built first
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>DATA_TSEARCH</varname></term>
- <listitem>
- <para>
- random files to install under
- <literal><replaceable>prefix</replaceable>/share/tsearch_data</literal>
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>DOCS</varname></term>
- <listitem>
- <para>
- random files to install under
- <literal><replaceable>prefix</replaceable>/doc/$MODULEDIR</literal>
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>SCRIPTS</varname></term>
- <listitem>
- <para>
- script files (not binaries) to install into
- <literal><replaceable>prefix</replaceable>/bin</literal>
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>SCRIPTS_built</varname></term>
- <listitem>
- <para>
- script files (not binaries) to install into
- <literal><replaceable>prefix</replaceable>/bin</literal>,
- which need to be built first
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>REGRESS</varname></term>
- <listitem>
- <para>
- list of regression test cases (without suffix), see below
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>EXTRA_CLEAN</varname></term>
- <listitem>
- <para>
- extra files to remove in <literal>make clean</literal>
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>PG_CPPFLAGS</varname></term>
- <listitem>
- <para>
- will be added to <varname>CPPFLAGS</varname>
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>PG_LIBS</varname></term>
- <listitem>
- <para>
- will be added to <varname>PROGRAM</varname> link line
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>SHLIB_LINK</varname></term>
- <listitem>
- <para>
- will be added to <varname>MODULE_big</varname> link line
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>PG_CONFIG</varname></term>
- <listitem>
- <para>
- path to <application>pg_config</> program for the
- <productname>PostgreSQL</productname> installation to build against
- (typically just <literal>pg_config</> to use the first one in your
- <varname>PATH</>)
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </para>
-
- <para>
- Put this makefile as <literal>Makefile</literal> in the directory
- which holds your extension. Then you can do
- <literal>make</literal> to compile, and later <literal>make
- install</literal> to install your module. By default, the extension is
- compiled and installed for the
- <productname>PostgreSQL</productname> installation that
- corresponds to the first <command>pg_config</command> program
- found in your path. You can use a different installation by
- setting <varname>PG_CONFIG</varname> to point to its
- <command>pg_config</command> program, either within the makefile
- or on the <literal>make</literal> command line.
- </para>
-
- <caution>
- <para>
- Changing <varname>PG_CONFIG</varname> only works when building
- against <productname>PostgreSQL</productname> 8.3 or later.
- With older releases it does not work to set it to anything except
- <literal>pg_config</>; you must alter your <varname>PATH</>
- to select the installation to build against.
- </para>
- </caution>
-
- <para>
- The scripts listed in the <varname>REGRESS</> variable are used for
- regression testing of your module, just like <literal>make
- installcheck</literal> is used for the main
- <productname>PostgreSQL</productname> server. For this to work you need
- to have a subdirectory named <literal>sql/</literal> in your extension's
- directory, within which you put one file for each group of tests you want
- to run. The files should have extension <literal>.sql</literal>, which
- should not be included in the <varname>REGRESS</varname> list in the
- makefile. For each test there should be a file containing the expected
- result in a subdirectory named <literal>expected/</literal>, with extension
- <literal>.out</literal>. The tests are run by executing <literal>make
- installcheck</literal>, and the resulting output will be compared to the
- expected files. The differences will be written to the file
- <literal>regression.diffs</literal> in <command>diff -c</command> format.
- Note that trying to run a test which is missing the expected file will be
- reported as <quote>trouble</quote>, so make sure you have all expected
- files.
- </para>
-
- <tip>
- <para>
- The easiest way of creating the expected files is creating empty files,
- then carefully inspecting the result files after a test run (to be found
- in the <literal>results/</literal> directory), and copying them to
- <literal>expected/</literal> if they match what you want from the test.
- </para>
-
- </tip>
- </sect2>
-
-
<sect2>
<title>Composite-type Arguments</title>
@@ -3385,4 +3118,68 @@ if (!ptr)
</programlisting>
</para>
</sect2>
+
+ <sect2 id="extend-Cpp">
+ <title>Using C++ for Extensibility</title>
+
+ <indexterm zone="extend-Cpp">
+ <primary>C++</primary>
+ </indexterm>
+
+ <para>
+ Although the <productname>PostgreSQL</productname> backend is written in
+ C, it is possible to write extensions in C++ if these guidelines are
+ followed:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ All functions accessed by the backend must present a C interface
+ to the backend; these C functions can then call C++ functions.
+ For example, <literal>extern C</> linkage is required for
+ backend-accessed functions. This is also necessary for any
+ functions that are passed as pointers between the backend and
+ C++ code.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Free memory using the appropriate deallocation method. For example,
+ most backend memory is allocated using <function>palloc()</>, so use
+ <function>pfree()</> to free it. Using C++
+ <function>delete</> in such cases will fail.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Prevent exceptions from propagating into the C code (use a catch-all
+ block at the top level of all <literal>extern C</> functions). This
+ is necessary even if the C++ code does not explicitly throw any
+ exceptions, because events like out-of-memory can still throw
+ exceptions. Any exceptions must be caught and appropriate errors
+ passed back to the C interface. If possible, compile C++ with
+ <option>-fno-exceptions</> to eliminate exceptions entirely; in such
+ cases, you must check for failures in your C++ code, e.g. check for
+ NULL returned by <function>new()</>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If calling backend functions from C++ code, be sure that the
+ C++ call stack contains only plain old data structures
+ (<acronym>POD</>). This is necessary because backend errors
+ generate a distant <function>longjmp()</> that does not properly
+ unroll a C++ call stack with non-POD objects.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ In summary, it is best to place C++ code behind a wall of
+ <literal>extern C</> functions that interface to the backend,
+ and avoid exception, memory, and call stack leakage.
+ </para>
+ </sect2>
+
</sect1>