diff options
Diffstat (limited to 'doc/src')
-rw-r--r-- | doc/src/sgml/acronyms.sgml | 2 | ||||
-rw-r--r-- | doc/src/sgml/catalogs.sgml | 195 | ||||
-rw-r--r-- | doc/src/sgml/extend.sgml | 715 | ||||
-rw-r--r-- | doc/src/sgml/ref/allfiles.sgml | 3 | ||||
-rw-r--r-- | doc/src/sgml/ref/alter_extension.sgml | 98 | ||||
-rw-r--r-- | doc/src/sgml/ref/comment.sgml | 1 | ||||
-rw-r--r-- | doc/src/sgml/ref/create_extension.sgml | 118 | ||||
-rw-r--r-- | doc/src/sgml/ref/drop_extension.sgml | 121 | ||||
-rw-r--r-- | doc/src/sgml/ref/psql-ref.sgml | 14 | ||||
-rw-r--r-- | doc/src/sgml/reference.sgml | 3 | ||||
-rw-r--r-- | doc/src/sgml/release-9.0.sgml | 5 | ||||
-rw-r--r-- | doc/src/sgml/xfunc.sgml | 331 |
12 files changed, 1296 insertions, 310 deletions
diff --git a/doc/src/sgml/acronyms.sgml b/doc/src/sgml/acronyms.sgml index d1ef489e366..8f6752f05d7 100644 --- a/doc/src/sgml/acronyms.sgml +++ b/doc/src/sgml/acronyms.sgml @@ -485,7 +485,7 @@ <term><acronym>PGXS</acronym></term> <listitem> <para> - <link linkend="xfunc-c-pgxs"><productname>PostgreSQL</> Extension System</link> + <link linkend="extend-pgxs"><productname>PostgreSQL</> Extension System</link> </para> </listitem> </varlistentry> diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index f31662c2720..24aa22cbced 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -144,6 +144,11 @@ </row> <row> + <entry><link linkend="catalog-pg-extension"><structname>pg_extension</structname></link></entry> + <entry>installed extensions</entry> + </row> + + <row> <entry><link linkend="catalog-pg-foreign-data-wrapper"><structname>pg_foreign_data_wrapper</structname></link></entry> <entry>foreign-data wrapper definitions</entry> </row> @@ -2680,6 +2685,21 @@ </varlistentry> <varlistentry> + <term><symbol>DEPENDENCY_EXTENSION</> (<literal>e</>)</term> + <listitem> + <para> + The dependent object is a member of the <firstterm>extension</> that is + the referenced object (see + <link linkend="catalog-pg-extension"><structname>pg_extension</structname></link>). + The dependent object can be dropped only via + <command>DROP EXTENSION</> on the referenced object. Functionally + this dependency type acts the same as an internal dependency, but + it's kept separate for clarity and to simplify <application>pg_dump</>. + </para> + </listitem> + </varlistentry> + + <varlistentry> <term><symbol>DEPENDENCY_PIN</> (<literal>p</>)</term> <listitem> <para> @@ -2848,6 +2868,101 @@ </sect1> + <sect1 id="catalog-pg-extension"> + <title><structname>pg_extension</structname></title> + + <indexterm zone="catalog-pg-extension"> + <primary>pg_extension</primary> + </indexterm> + + <para> + The catalog <structname>pg_extension</structname> stores information + about the installed extensions. See <xref linkend="extend-extensions"> + for details about extensions. + </para> + + <table> + <title><structname>pg_extension</> Columns</title> + + <tgroup cols="4"> + <thead> + <row> + <entry>Name</entry> + <entry>Type</entry> + <entry>References</entry> + <entry>Description</entry> + </row> + </thead> + + <tbody> + <row> + <entry><structfield>extname</structfield></entry> + <entry><type>name</type></entry> + <entry></entry> + <entry>Name of the extension</entry> + </row> + + <row> + <entry><structfield>extowner</structfield></entry> + <entry><type>oid</type></entry> + <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry> + <entry>Owner of the extension</entry> + </row> + + <row> + <entry><structfield>extnamespace</structfield></entry> + <entry><type>oid</type></entry> + <entry><literal><link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.oid</literal></entry> + <entry>Schema containing the extension's exported objects</entry> + </row> + + <row> + <entry><structfield>extrelocatable</structfield></entry> + <entry><type>bool</type></entry> + <entry></entry> + <entry>True if extension can be relocated to another schema</entry> + </row> + + <row> + <entry><structfield>extversion</structfield></entry> + <entry><type>text</type></entry> + <entry></entry> + <entry>Version string for the extension, or <literal>NULL</> if none</entry> + </row> + + <row> + <entry><structfield>extconfig</structfield></entry> + <entry><type>oid[]</type></entry> + <entry><literal><link linkend="catalog-pg-class"><structname>pg_class</structname></link>.oid</literal></entry> + <entry>Array of <type>regclass</> OIDs for the extension's configuration + table(s), or <literal>NULL</> if none</entry> + </row> + + <row> + <entry><structfield>extcondition</structfield></entry> + <entry><type>text[]</type></entry> + <entry></entry> + <entry>Array of <literal>WHERE</>-clause filter conditions for the + extension's configuration table(s), or <literal>NULL</> if none</entry> + </row> + + </tbody> + </tgroup> + </table> + + <para> + Note that unlike most catalogs with a <quote>namespace</> column, + <structfield>extnamespace</structfield> is not meant to imply + that the extension belongs to that schema. Extension names are never + schema-qualified. Rather, <structfield>extnamespace</structfield> + indicates the schema that contains most or all of the extension's + objects. If <structfield>extrelocatable</structfield> is true, then + this schema must in fact contain all schema-qualifiable objects + belonging to the extension. + </para> + </sect1> + + <sect1 id="catalog-pg-foreign-data-wrapper"> <title><structname>pg_foreign_data_wrapper</structname></title> @@ -6192,6 +6307,11 @@ <tbody> <row> + <entry><link linkend="view-pg-available-extensions"><structname>pg_available_extensions</structname></link></entry> + <entry>available extensions</entry> + </row> + + <row> <entry><link linkend="view-pg-cursors"><structname>pg_cursors</structname></link></entry> <entry>open cursors</entry> </row> @@ -6286,6 +6406,81 @@ </table> </sect1> + <sect1 id="view-pg-available-extensions"> + <title><structname>pg_available_extensions</structname></title> + + <indexterm zone="view-pg-available-extensions"> + <primary>pg_available_extensions</primary> + </indexterm> + + <para> + The <structname>pg_available_extensions</structname> view lists the + extensions that are available for installation. This view can only + be read by superusers. See also the + <link linkend="catalog-pg-extension"><structname>pg_extension</structname></link> + catalog, which shows the extensions currently installed. + </para> + + <table> + <title><structname>pg_available_extensions</> Columns</title> + + <tgroup cols="3"> + <thead> + <row> + <entry>Name</entry> + <entry>Type</entry> + <entry>Description</entry> + </row> + </thead> + + <tbody> + <row> + <entry><structfield>name</structfield></entry> + <entry><type>name</type></entry> + <entry>Extension name</entry> + </row> + + <row> + <entry><structfield>version</structfield></entry> + <entry><type>text</type></entry> + <entry>Version string from the extension's control file</entry> + </row> + + <row> + <entry><structfield>installed</structfield></entry> + <entry><type>text</type></entry> + <entry>Currently installed version of the extension, + or <literal>NULL</literal> if not installed</entry> + </row> + + <row> + <entry><structfield>schema</structfield></entry> + <entry><type>name</type></entry> + <entry>Name of the schema where the extension is installed, + or <literal>NULL</literal> if not installed</entry> + </row> + + <row> + <entry><structfield>relocatable</structfield></entry> + <entry><type>bool</type></entry> + <entry>True if extension can be relocated to another schema</entry> + </row> + + <row> + <entry><structfield>comment</structfield></entry> + <entry><type>text</type></entry> + <entry>Comment string from the extension's control file</entry> + </row> + </tbody> + </tgroup> + </table> + + <para> + The <structname>pg_available_extensions</structname> view is read only. + </para> + + </sect1> + <sect1 id="view-pg-cursors"> <title><structname>pg_cursors</structname></title> diff --git a/doc/src/sgml/extend.sgml b/doc/src/sgml/extend.sgml index 2033ae21ba5..206eb6b9017 100644 --- a/doc/src/sgml/extend.sgml +++ b/doc/src/sgml/extend.sgml @@ -38,6 +38,11 @@ operator classes for indexes (starting in <xref linkend="xindex">) </para> </listitem> + <listitem> + <para> + packages of related objects (starting in <xref linkend="extend-extensions">) + </para> + </listitem> </itemizedlist> </para> @@ -273,67 +278,701 @@ &xoper; &xindex; - <sect1 id="extend-Cpp"> - <title>Using C++ for Extensibility</title> - <indexterm zone="extend-Cpp"> - <primary>C++</primary> + <sect1 id="extend-extensions"> + <title>Packaging Related Objects into an Extension</title> + + <indexterm zone="extend-extensions"> + <primary>extension</primary> </indexterm> <para> - It is possible to use a compiler in C++ mode to build - <productname>PostgreSQL</productname> extensions by following these - guidelines: + A useful extension to <productname>PostgreSQL</> typically includes + multiple SQL objects; for example, a new datatype will require new + functions, new operators, and probably new index operator classes. + It is helpful to collect all these objects into a single package + to simplify database management. <productname>PostgreSQL</> calls + such a package an <firstterm>extension</>. To define an extension, + you need at least a <firstterm>script file</> that contains the + <acronym>SQL</> commands to create the extension's objects, and a + <firstterm>control file</> that specifies a few basic properties + of the extension itself. If the extension includes C code, there + will typically also be a shared library file into which the C code + has been built. Once you have these files, a simple + <xref linkend="sql-createextension"> command loads the objects into + your database. + </para> + + <para> + The advantage of using an extension, rather than just running the + <acronym>SQL</> script to load a bunch of <quote>loose</> objects + into your database, is that <productname>PostgreSQL</> will then + understand that the objects of the extension go together. You can + drop all the objects with a single <xref linkend="sql-dropextension"> + command (no need to maintain a separate <quote>uninstall</> script). + Even more useful, <application>pg_dump</> knows that it should not + dump the individual member objects of the extension — it will + just include a <command>CREATE EXTENSION</> command in dumps, instead. + This vastly simplifies migration to a new version of the extension + that might contain more or different objects than the old version. + Note however that you must have the extension's control, script, and + other files available when loading such a dump into a new database. + </para> + + <para> + <productname>PostgreSQL</> will not let you drop an individual object + contained in an extension, except by dropping the whole extension. + Also, while you can change the definition of an extension member object + (for example, via <command>CREATE OR REPLACE FUNCTION</command> for a + function), bear in mind that the modified definition will not be dumped + by <application>pg_dump</>. Such a change is usually only sensible if + you concurrently make the same change in the extension's script file. + (But there are special provisions for tables containing configuration + data; see below.) + </para> + + <sect2> + <title>Extension Files</title> + + <indexterm> + <primary>control file</primary> + </indexterm> + + <para> + The <xref linkend="sql-createextension"> command relies on a control + file for each extension, which must be named the same as the extension + with a suffix of <literal>.control</>, and must be placed in the + installation's <literal>SHAREDIR/contrib</literal> directory. There + must also be a <acronym>SQL</> script file, which typically is + named after the extension with a suffix of <literal>.sql</>, and is also + placed in the <literal>SHAREDIR/contrib</literal> directory; but these + defaults can be overridden by the control file. + </para> + + <para> + The file format for an extension control file is the same as for the + <filename>postgresql.conf</> file, namely a list of + <replaceable>parameter-name</> <literal>=</> <replaceable>value</> + assignments, one per line. Blank lines and comments introduced by + <literal>#</> are allowed. Be sure to quote any value that is not + a single word or number. + </para> + + <para> + A control file can set the following parameters: + </para> + + <variablelist> + <varlistentry> + <term><varname>script</varname> (<type>string</type>)</term> + <listitem> + <para> + The filename of the extension's <acronym>SQL</> script. + Defaults to the same name as the control file, but with the + <literal>.sql</literal> extension. Unless an absolute path is + given, the name is relative to the <literal>SHAREDIR/contrib</literal> + directory. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><varname>version</varname> (<type>string</type>)</term> + <listitem> + <para> + The version of the extension. Any string can be given. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><varname>comment</varname> (<type>string</type>)</term> + <listitem> + <para> + A comment (any string) about the extension. Alternatively, + the comment can be set by means of the <xref linkend="sql-comment"> + command. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><varname>requires</varname> (<type>string</type>)</term> + <listitem> + <para> + A list of names of extensions that this extension depends on, + for example <literal>requires = 'foo, bar'</literal>. Those + extensions must be installed before this one can be installed. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><varname>encoding</varname> (<type>string</type>)</term> + <listitem> + <para> + The character set encoding used by the script file. This should + be specified if the script file contains any non-ASCII characters. + Otherwise the script will be assumed to be in the encoding of the + database it is loaded into. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><varname>relocatable</varname> (<type>boolean</type>)</term> + <listitem> + <para> + An extension is <firstterm>relocatable</> if it is possible to move + its contained objects into a different schema after initial creation + of the extension. The default is <literal>false</>, i.e. the + extension is not relocatable. + See below for more information. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><varname>schema</varname> (<type>string</type>)</term> + <listitem> + <para> + This parameter can only be set for non-relocatable extensions. + It forces the extension to be loaded into exactly the named schema + and not any other. See below for more information. + </para> + </listitem> + </varlistentry> + </variablelist> + + <para> + An extension's <acronym>SQL</> script file can contain any SQL commands, + except for transaction control commands (<command>BEGIN</>, + <command>COMMIT</>, etc) and commands that cannot be executed inside a + transaction block (such as <command>VACUUM</>). This is because the + script file is implicitly executed within a transaction block. + </para> + + <para> + While the script file can contain any characters allowed by the specified + encoding, the control file should contain only plain ASCII, because there + is no way for <productname>PostgreSQL</> to know what encoding the + control file is in. In practice this is only an issue if you want to + use non-ASCII characters in the extension's comment. Recommended + practice in that case is to not use the <varname>comment</> parameter + in the control file, but instead use <command>COMMENT ON EXTENSION</> + within the script file to set the comment. + </para> + + </sect2> + + <sect2> + <title>Extension Relocatability</title> + + <para> + Users often wish to load the objects contained in an extension into a + different schema than the extension's author had in mind. There are + three supported levels of relocatability: + </para> <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, i.e. using C++ - <function>delete()</> in such cases will fail. + A fully relocatable extension can be moved into another schema + at any time, even after it's been loaded into a database. + This is done with the <command>ALTER EXTENSION SET SCHEMA</> + command, which automatically renames all the member objects into + the new schema. Normally, this is only possible if the extension + contains no internal assumptions about what schema any of its + objects are in. Also, the extension's objects must all be in one + schema to begin with (ignoring objects that do not belong to any + schema, such as procedural languages). Mark a fully relocatable + extension by setting <literal>relocatable = true</> in its control + file. </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 - throw any exceptions because events like out-of-memory 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()</>. + An extension might be relocatable during installation but not + afterwards. This is typically the case if the extension's script + file needs to reference the target schema explicitly, for example + in setting <literal>search_path</> properties for SQL functions. + For such an extension, set <literal>relocatable = false</> in its + control file, and use <literal>@extschema@</> to refer to the target + schema in the script file. All occurrences of this string will be + replaced by the actual target schema's name before the script is + executed. The user can set the target schema using the + <literal>SCHEMA</> option of <command>CREATE EXTENSION</>. </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. + If the extension does not support relocation at all, set + <literal>relocatable = false</> in its control file, and also set + <literal>schema</> to the name of the intended target schema. This + will prevent use of the <literal>SCHEMA</> option of <command>CREATE + EXTENSION</>, unless it specifies the same schema named in the control + file. This choice is typically necessary if the extension contains + internal assumptions about schema names that can't be replaced by + uses of <literal>@extschema@</>. The <literal>@extschema@</> + substitution mechanism is available in this case too, although it is + of limited use since the schema name is determined by the control file. </para> </listitem> </itemizedlist> + + <para> + In all cases, the script file will be executed with + <xref linkend="guc-search-path"> initially set to point to the target + schema; that is, <command>CREATE EXTENSION</> does the equivalent of + this: +<programlisting> +SET LOCAL search_path TO @extschema@; +</programlisting> + This allows the objects created by the script file to go into the target + schema. The script file can change <varname>search_path</> if it wishes, + but that is generally undesirable. <varname>search_path</> is restored + to its previous setting upon completion of <command>CREATE EXTENSION</>. + </para> + + <para> + The target schema is determined by the <varname>schema</> parameter in + the control file if that is given, otherwise by the <literal>SCHEMA</> + option of <command>CREATE EXTENSION</> if that is given, otherwise the + current default object creation schema (the first one in the caller's + <varname>search_path</>). When the control file <varname>schema</> + parameter is used, the target schema will be created if it doesn't + already exist, but in the other two cases it must already exist. + </para> + + <para> + If any prerequisite extensions are listed in <varname>requires</varname> + in the control file, their target schemas are appended to the initial + setting of <varname>search_path</>. This allows their objects to be + visible to the new extension's script file. + </para> + + <para> + Although a non-relocatable extension can contain objects spread across + multiple schemas, it is usually desirable to place all the objects meant + for external use into a single schema, which is considered the extension's + target schema. Such an arrangement works conveniently with the default + setting of <varname>search_path</> during creation of dependent + extensions. + </para> + </sect2> + + <sect2> + <title>Extension Configuration Tables</title> + + <para> + Some extensions include configuration tables, which contain data that + might be added or changed by the user after installation of the + extension. Ordinarily, if a table is part of an extension, neither + the table's definition nor its content will be dumped by + <application>pg_dump</>. But that behavior is undesirable for a + configuration table; any data changes made by the user need to be + included in dumps, or the extension will behave differently after a dump + and reload. + </para> + + <para> + To solve this problem, an extension's script file can mark a table + it has created as a configuration table, which will cause + <application>pg_dump</> to include the table's contents (not its + definition) in dumps. To do that, call the function + <function>pg_extension_config_dump(regclass, text)</> after creating the + table, for example +<programlisting> +CREATE TABLE my_config (key text, value text); + +SELECT pg_catalog.pg_extension_config_dump('my_config', ''); +</programlisting> + Any number of tables can be marked this way. + </para> + + <para> + When the second argument of <function>pg_extension_config_dump</> is + an empty string, the entire contents of the table are dumped by + <application>pg_dump</>. This is usually only correct if the table + is initially empty as created by the extension script. If there is + a mixture of initial data and user-provided data in the table, + the second argument of <function>pg_extension_config_dump</> provides + a <literal>WHERE</> condition that selects the data to be dumped. + For example, you might do +<programlisting> +CREATE TABLE my_config (key text, value text, standard_entry boolean); + +SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entry'); +</programlisting> + and then make sure that <structfield>standard_entry</> is true only + in the rows created by the extension's script. + </para> + + <para> + More complicated situations, such as initially-provided rows that might + be modified by users, can be handled by creating triggers on the + configuration table to ensure that modified rows are marked correctly. + </para> + </sect2> + + <sect2> + <title>Extension Example</title> + + <para> + Here is a complete example of an <acronym>SQL</>-only + extension, a two-element composite type that can store any type of value + in its slots, which are named <quote>k</> and <quote>v</>. Non-text + values are automatically coerced to text for storage. + </para> + + <para> + The script file <filename>pair.sql</> looks like this: + +<programlisting><![CDATA[ +CREATE TYPE pair AS ( k text, v text ); + +CREATE OR REPLACE FUNCTION pair(anyelement, text) +RETURNS pair LANGUAGE SQL AS 'SELECT ROW($1, $2)::pair'; + +CREATE OR REPLACE FUNCTION pair(text, anyelement) +RETURNS pair LANGUAGE SQL AS 'SELECT ROW($1, $2)::pair'; + +CREATE OR REPLACE FUNCTION pair(anyelement, anyelement) +RETURNS pair LANGUAGE SQL AS 'SELECT ROW($1, $2)::pair'; + +CREATE OR REPLACE FUNCTION pair(text, text) +RETURNS pair LANGUAGE SQL AS 'SELECT ROW($1, $2)::pair;'; + +CREATE OPERATOR ~> (LEFTARG = text, RIGHTARG = anyelement, PROCEDURE = pair); +CREATE OPERATOR ~> (LEFTARG = anyelement, RIGHTARG = text, PROCEDURE = pair); +CREATE OPERATOR ~> (LEFTARG = anyelement, RIGHTARG = anyelement, PROCEDURE = pair); +CREATE OPERATOR ~> (LEFTARG = text, RIGHTARG = text, PROCEDURE = pair); +]]> +</programlisting> + </para> + + <para> + The control file <filename>pair.control</> looks like this: + +<programlisting> +# pair extension +comment = 'A key/value pair data type' +version = '0.1.2' +relocatable = true +</programlisting> + </para> + + <para> + While you hardly need a makefile to install these two files into the + correct directory, you could use a <filename>Makefile</> containing this: + +<programlisting> +EXTENSION = pair +DATA = pair.sql + +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +</programlisting> + + This makefile relies on <acronym>PGXS</acronym>, which is described + in <xref linkend="extend-pgxs">. The command <literal>make install</> + will then install the control and script files into the correct + directory as reported by <application>pg_config</>. + </para> + + <para> + Once the files are installed, use the + <xref linkend="sql-createextension"> command to load the objects into + any particular database. + </para> + </sect2> + </sect1> + + <sect1 id="extend-pgxs"> + <title>Extension Building Infrastructure</title> + + <indexterm zone="extend-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. <acronym>PGXS</acronym> is mainly intended + for extensions that include C code, although it can be used for + pure-SQL extensions too. Note that <acronym>PGXS</acronym> is not + intended to be a universal build system framework that can be used + to build any software interfacing to <productname>PostgreSQL</>; + it simply automates common build rules for simple server extension + modules. For more complicated packages, you might need to write your + own build system. </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. + To use the <acronym>PGXS</acronym> infrastructure for your extension, + you must write a simple makefile. + In the 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 containing + some C code, an extension control file, a SQL script, and a documentation + text file: +<programlisting> +MODULES = isbn_issn +EXTENSION = 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-library objects to be built from source files with same + stem (do not include library suffixes in this list) + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><varname>MODULE_big</varname></term> + <listitem> + <para> + a shared library to build from multiple source files + (list object files in <varname>OBJS</varname>) + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><varname>PROGRAM</varname></term> + <listitem> + <para> + an executable 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 EXTENSION, DATA and DOCS files should be + installed (if not set, default is <literal>contrib</literal>) + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><varname>EXTENSION</varname></term> + <listitem> + <para> + extension name(s); for each name you must provide an + <literal><replaceable>extension</replaceable>.control</literal> file, + which will be installed into + <literal><replaceable>prefix</replaceable>/share/$MODULEDIR</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 then <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 <varname>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, which can be invoked by <literal>make + installcheck</literal> after doing <literal>make install</>. For this to + work you must have a running <productname>PostgreSQL</productname> server. + The script files listed in <varname>REGRESS</> must appear in a + subdirectory named <literal>sql/</literal> in your extension's directory. + These files must have extension <literal>.sql</literal>, which must not be + included in the <varname>REGRESS</varname> list in the makefile. For each + test there should also be a file containing the expected output in a + subdirectory named <literal>expected/</literal>, with the same stem and + extension <literal>.out</literal>. <literal>make installcheck</literal> + executes each test script with <application>psql</>, and compares the + resulting output to the matching expected file. Any differences will be + written to the file <literal>regression.diffs</literal> in <command>diff + -c</command> format. Note that trying to run a test that is missing its + expected file will be reported as <quote>trouble</quote>, so make sure you + have all expected files. + </para> + + <tip> + <para> + The easiest way to create the expected files is to create empty files, + then do a test run (which will of course report differences). Inspect + the actual result files found in the <literal>results/</literal> + directory, then copy them to <literal>expected/</literal> if they match + what you expect from the test. + </para> + + </tip> </sect1> </chapter> diff --git a/doc/src/sgml/ref/allfiles.sgml b/doc/src/sgml/ref/allfiles.sgml index c44d11ef91b..ba85cae0837 100644 --- a/doc/src/sgml/ref/allfiles.sgml +++ b/doc/src/sgml/ref/allfiles.sgml @@ -11,6 +11,7 @@ Complete list of usable sgml source files in this directory. <!entity alterDatabase system "alter_database.sgml"> <!entity alterDefaultPrivileges system "alter_default_privileges.sgml"> <!entity alterDomain system "alter_domain.sgml"> +<!entity alterExtension system "alter_extension.sgml"> <!entity alterForeignDataWrapper system "alter_foreign_data_wrapper.sgml"> <!entity alterForeignTable system "alter_foreign_table.sgml"> <!entity alterFunction system "alter_function.sgml"> @@ -50,6 +51,7 @@ Complete list of usable sgml source files in this directory. <!entity createConversion system "create_conversion.sgml"> <!entity createDatabase system "create_database.sgml"> <!entity createDomain system "create_domain.sgml"> +<!entity createExtension system "create_extension.sgml"> <!entity createForeignDataWrapper system "create_foreign_data_wrapper.sgml"> <!entity createForeignTable system "create_foreign_table.sgml"> <!entity createFunction system "create_function.sgml"> @@ -86,6 +88,7 @@ Complete list of usable sgml source files in this directory. <!entity dropConversion system "drop_conversion.sgml"> <!entity dropDatabase system "drop_database.sgml"> <!entity dropDomain system "drop_domain.sgml"> +<!entity dropExtension system "drop_extension.sgml"> <!entity dropForeignDataWrapper system "drop_foreign_data_wrapper.sgml"> <!entity dropForeignTable system "drop_foreign_table.sgml"> <!entity dropFunction system "drop_function.sgml"> diff --git a/doc/src/sgml/ref/alter_extension.sgml b/doc/src/sgml/ref/alter_extension.sgml new file mode 100644 index 00000000000..1b29d274cd6 --- /dev/null +++ b/doc/src/sgml/ref/alter_extension.sgml @@ -0,0 +1,98 @@ +<!-- +doc/src/sgml/ref/alter_extension.sgml +PostgreSQL documentation +--> + +<refentry id="SQL-ALTEREXTENSION"> + <refmeta> + <refentrytitle>ALTER EXTENSION</refentrytitle> + <manvolnum>7</manvolnum> + <refmiscinfo>SQL - Language Statements</refmiscinfo> + </refmeta> + + <refnamediv> + <refname>ALTER EXTENSION</refname> + <refpurpose> + change the definition of an extension + </refpurpose> + </refnamediv> + + <indexterm zone="sql-alterextension"> + <primary>ALTER EXTENSION</primary> + </indexterm> + + <refsynopsisdiv> +<synopsis> +ALTER EXTENSION <replaceable class="PARAMETER">name</replaceable> SET SCHEMA <replaceable class="PARAMETER">new_schema</replaceable> +</synopsis> + </refsynopsisdiv> + + <refsect1> + <title>Description</title> + + <para> + <command>ALTER EXTENSION</command> changes the definition of an existing extension. + Currently there is only one subform: + + <variablelist> + <varlistentry> + <term><literal>SET SCHEMA</literal></term> + <listitem> + <para> + This form moves the extension's objects into another schema. The + extension has to be <firstterm>relocatable</> for this command to + succeed. See <xref linkend="extend-extensions"> for details. + </para> + </listitem> + </varlistentry> + </variablelist> + </para> + </refsect1> + + <refsect1> + <title>Parameters</title> + + <para> + <variablelist> + <varlistentry> + <term><replaceable class="PARAMETER">name</replaceable></term> + <listitem> + <para> + The name of an installed extension. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><replaceable class="PARAMETER">new_schema</replaceable></term> + <listitem> + <para> + The new schema for the extension. + </para> + </listitem> + </varlistentry> + </variablelist> + </para> + </refsect1> + + <refsect1> + <title>Examples</title> + + <para> + To change the schema of the extension <literal>hstore</literal> + to <literal>utils</literal>: +<programlisting> +ALTER EXTENSION hstore SET SCHEMA utils; +</programlisting> + </para> + </refsect1> + + <refsect1 id="SQL-ALTEREXTENSION-see-also"> + <title>See Also</title> + + <simplelist type="inline"> + <member><xref linkend="sql-createextension"></member> + <member><xref linkend="sql-dropextension"></member> + </simplelist> + </refsect1> +</refentry> diff --git a/doc/src/sgml/ref/comment.sgml b/doc/src/sgml/ref/comment.sgml index f1a1605df3c..e1fe0c16f9a 100644 --- a/doc/src/sgml/ref/comment.sgml +++ b/doc/src/sgml/ref/comment.sgml @@ -31,6 +31,7 @@ COMMENT ON CONVERSION <replaceable class="PARAMETER">object_name</replaceable> | DATABASE <replaceable class="PARAMETER">object_name</replaceable> | DOMAIN <replaceable class="PARAMETER">object_name</replaceable> | + EXTENSION <replaceable class="PARAMETER">object_name</replaceable> | FOREIGN TABLE <replaceable class="PARAMETER">object_name</replaceable> | FUNCTION <replaceable class="PARAMETER">function_name</replaceable> ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) | INDEX <replaceable class="PARAMETER">object_name</replaceable> | diff --git a/doc/src/sgml/ref/create_extension.sgml b/doc/src/sgml/ref/create_extension.sgml new file mode 100644 index 00000000000..961cab3839e --- /dev/null +++ b/doc/src/sgml/ref/create_extension.sgml @@ -0,0 +1,118 @@ +<!-- +doc/src/sgml/ref/create_extension.sgml +PostgreSQL documentation +--> + +<refentry id="SQL-CREATEEXTENSION"> + <refmeta> + <refentrytitle>CREATE EXTENSION</refentrytitle> + <manvolnum>7</manvolnum> + <refmiscinfo>SQL - Language Statements</refmiscinfo> + </refmeta> + + <refnamediv> + <refname>CREATE EXTENSION</refname> + <refpurpose>install an extension</refpurpose> + </refnamediv> + + <indexterm zone="sql-createextension"> + <primary>CREATE EXTENSION</primary> + </indexterm> + + <refsynopsisdiv> +<synopsis> +CREATE EXTENSION <replaceable class="parameter">extension_name</replaceable> + [ WITH ] [ SCHEMA [=] <replaceable class="parameter">schema</replaceable> ] +</synopsis> + </refsynopsisdiv> + + <refsect1> + <title>Description</title> + + <para> + <command>CREATE EXTENSION</command> loads a new extension into the current + database. There must not be an extension of the same name already loaded. + </para> + + <para> + Loading an extension essentially amounts to running the extension's script + file. The script will typically create new <acronym>SQL</> objects such as + functions, data types, operators and index support methods. + <command>CREATE EXTENSION</command> additionally records the identities + of all the created objects, so that they can be dropped again if + <command>DROP EXTENSION</command> is issued. + </para> + + <para> + For information about writing new extensions, see + <xref linkend="extend-extensions">. + </para> + + <para> + Only superusers can execute <command>CREATE EXTENSION</command>. + </para> + + </refsect1> + + <refsect1> + <title>Parameters</title> + + <variablelist> + <varlistentry> + <term><replaceable class="parameter">extension_name</replaceable></term> + <listitem> + <para> + The name of the extension to be + installed. <productname>PostgreSQL</productname> will create the + extension using details from the file + <literal>SHAREDIR/contrib/</literal><replaceable class="parameter">extension</replaceable><literal>.control</literal>. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><replaceable class="parameter">schema</replaceable></term> + <listitem> + <para> + The name of the schema in which to install the extension's + objects, given that the extension allows its contents to be + relocated. The named schema must already exist. + If not specified, and the extension's control file does not specify a + schema either, the current default object creation schema is used. + </para> + </listitem> + </varlistentry> + </variablelist> + </refsect1> + + <refsect1> + <title>Examples</title> + + <para> + Install the <link linkend="hstore">hstore</link> extension into the + current database: +<programlisting> +CREATE EXTENSION hstore; +</programlisting> + </para> + </refsect1> + + <refsect1> + <title>Compatibility</title> + + <para> + <command>CREATE EXTENSION</command> is a <productname>PostgreSQL</> + extension. + </para> + </refsect1> + + <refsect1> + <title>See Also</title> + + <simplelist type="inline"> + <member><xref linkend="sql-alterextension"></member> + <member><xref linkend="sql-dropextension"></member> + </simplelist> + </refsect1> + +</refentry> diff --git a/doc/src/sgml/ref/drop_extension.sgml b/doc/src/sgml/ref/drop_extension.sgml new file mode 100644 index 00000000000..1e09ec4c7a7 --- /dev/null +++ b/doc/src/sgml/ref/drop_extension.sgml @@ -0,0 +1,121 @@ +<!-- +doc/src/sgml/ref/drop_extension.sgml +PostgreSQL documentation +--> + +<refentry id="SQL-DROPEXTENSION"> + <refmeta> + <refentrytitle>DROP EXTENSION</refentrytitle> + <manvolnum>7</manvolnum> + <refmiscinfo>SQL - Language Statements</refmiscinfo> + </refmeta> + + <refnamediv> + <refname>DROP EXTENSION</refname> + <refpurpose>remove an extension</refpurpose> + </refnamediv> + + <indexterm zone="sql-dropextension"> + <primary>DROP EXTENSION</primary> + </indexterm> + + <refsynopsisdiv> +<synopsis> +DROP EXTENSION [ IF EXISTS ] <replaceable class="PARAMETER">extension_name</replaceable> [, ...] [ CASCADE | RESTRICT ] +</synopsis> + </refsynopsisdiv> + + <refsect1> + <title>Description</title> + + <para> + <command>DROP EXTENSION</command> removes extensions from the database. + Dropping an extension causes its component objects to be dropped as well. + </para> + + <para> + An extension can only be dropped by a superuser. + </para> + </refsect1> + + <refsect1> + <title>Parameters</title> + + <variablelist> + + <varlistentry> + <term><literal>IF EXISTS</literal></term> + <listitem> + <para> + Do not throw an error if the extension does not exist. A notice is issued + in this case. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><replaceable class="PARAMETER">extension_name</replaceable></term> + <listitem> + <para> + The name of an installed extension. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>CASCADE</literal></term> + <listitem> + <para> + Automatically drop objects that depend on the extension. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>RESTRICT</literal></term> + <listitem> + <para> + Refuse to drop the extension if any objects depend on it (other than + its own member objects and other extensions listed in the same + <command>DROP</> command). This is the default. + </para> + </listitem> + </varlistentry> + </variablelist> + </refsect1> + + <refsect1> + <title>Examples</title> + + <para> + To remove the extension <literal>hstore</literal> from the current + database: +<programlisting> +DROP EXTENSION hstore; +</programlisting> + This command will fail if any of <literal>hstore</literal>'s objects + are in use in the database, for example if any tables have columns + of the <type>hstore</> type. Add the <literal>CASCADE</> option to + forcibly remove those dependent objects as well. + </para> + </refsect1> + + <refsect1> + <title>Compatibility</title> + + <para> + <command>DROP EXTENSION</command> is a <productname>PostgreSQL</> + extension. + </para> + </refsect1> + + <refsect1> + <title>See Also</title> + + <simplelist type="inline"> + <member><xref linkend="sql-createextension"></member> + <member><xref linkend="sql-alterextension"></member> + </simplelist> + </refsect1> + +</refentry> diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index eacae71cdc7..cdf1abfa956 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -1357,7 +1357,6 @@ testdb=> </listitem> </varlistentry> - <varlistentry> <term><literal>\du[+] [ <link linkend="APP-PSQL-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term> <listitem> @@ -1371,6 +1370,19 @@ testdb=> </listitem> </varlistentry> + <varlistentry> + <term><literal>\dx[+] [ <link linkend="APP-PSQL-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term> + <listitem> + <para> + Lists installed extensions. + If <replaceable class="parameter">pattern</replaceable> + is specified, only those extensions whose names match the pattern + are listed. + If the form <literal>\dx+</literal> is used, all the objects belonging + to each matching extension are listed. + </para> + </listitem> + </varlistentry> <varlistentry> <term><literal>\edit</> (or <literal>\e</>) <literal> <optional> <replaceable class="parameter">filename</> </optional> <optional> <replaceable class="parameter">line_number</> </optional> </literal></term> diff --git a/doc/src/sgml/reference.sgml b/doc/src/sgml/reference.sgml index 6ee8e5bcff8..47cd01f58e2 100644 --- a/doc/src/sgml/reference.sgml +++ b/doc/src/sgml/reference.sgml @@ -39,6 +39,7 @@ &alterDatabase; &alterDefaultPrivileges; &alterDomain; + &alterExtension; &alterForeignDataWrapper; &alterForeignTable; &alterFunction; @@ -78,6 +79,7 @@ &createConversion; &createDatabase; &createDomain; + &createExtension; &createForeignDataWrapper; &createForeignTable; &createFunction; @@ -114,6 +116,7 @@ &dropConversion; &dropDatabase; &dropDomain; + &dropExtension; &dropForeignDataWrapper; &dropForeignTable; &dropFunction; diff --git a/doc/src/sgml/release-9.0.sgml b/doc/src/sgml/release-9.0.sgml index 2288f1b0e64..4902c058a96 100644 --- a/doc/src/sgml/release-9.0.sgml +++ b/doc/src/sgml/release-9.0.sgml @@ -3520,9 +3520,8 @@ if TG_OP = 'INSERT' and NEW.col1 = ... then <listitem> <para> - Add data and documentation installation location control to <link - linkend="xfunc-c-pgxs"><acronym>PGXS</></link> Makefiles - (Mark Cave-Ayland) + Add data and documentation installation location control to + <acronym>PGXS</> Makefiles (Mark Cave-Ayland) </para> </listitem> 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> |