diff --git a/doc/src/sgml/ref/create_language.sgml b/doc/src/sgml/ref/create_language.sgml index bcce7d6c612382be38eb641e653995bf1759e718..b6af18b1bcf3411fa3f9db46add4e0ec357459b3 100644 --- a/doc/src/sgml/ref/create_language.sgml +++ b/doc/src/sgml/ref/create_language.sgml @@ -1,252 +1,196 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_language.sgml,v 1.16 2001/09/03 12:57:49 petere Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_language.sgml,v 1.17 2001/09/06 10:28:39 petere Exp $ Postgres documentation --> <refentry id="SQL-CREATELANGUAGE"> + <docinfo> + <date>2001-09-05</date> + </docinfo> + <refmeta> - <refentrytitle id="sql-createlanguage-title"> - CREATE LANGUAGE - </refentrytitle> + <refentrytitle id="sql-createlanguage-title">CREATE LANGUAGE</refentrytitle> <refmiscinfo>SQL - Language Statements</refmiscinfo> </refmeta> + <refnamediv> - <refname> - CREATE LANGUAGE - </refname> - <refpurpose> - define a new procedural language - </refpurpose> + <refname>CREATE LANGUAGE</refname> + <refpurpose>define a new procedural language</refpurpose> </refnamediv> + <refsynopsisdiv> - <refsynopsisdivinfo> - <date>1999-07-20</date> - </refsynopsisdivinfo> - <synopsis> +<synopsis> CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE <replaceable class="parameter">langname</replaceable> HANDLER <replaceable class="parameter">call_handler</replaceable> - </synopsis> - - <refsect2 id="R2-SQL-CREATELANGUAGE-1"> - <refsect2info> - <date>1998-09-09</date> - </refsect2info> - <title> - Inputs - </title> - <para> - - <variablelist> - <varlistentry> - <term>TRUSTED</term> - <listitem> - <para> - <function> TRUSTED</function> specifies that the call handler for - the language is safe; that is, it offers an unprivileged user - no functionality to bypass access restrictions. If - this keyword is omitted when registering the language, - only users with the <productname>Postgres</productname> - superuser privilege can use - this language to create new functions. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term><replaceable class="parameter">langname</replaceable></term> - <listitem> - <para> - The name of the new procedural language. - The language name is case insensitive. A procedural - language cannot override one of the built-in languages of - <productname>Postgres</productname>. - </para> - <para> - For backward compatibility, the name may be enclosed by single - quotes. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>HANDLER <replaceable class="parameter">call_handler</replaceable></term> - <listitem> - <para> - <replaceable class="parameter">call_handler</replaceable> is the name - of a previously - registered function that will be called to execute the PL - procedures. - </para> - </listitem> - </varlistentry> - - </variablelist> - </para> - - </refsect2> - - <refsect2 id="R2-SQL-CREATELANGUAGE-2"> - <refsect2info> - <date>1998-09-09</date> - </refsect2info> - <title> - Outputs - </title> - <para> - - <variablelist> - <varlistentry> - <term><computeroutput> -CREATE - </computeroutput></term> - <listitem> - <para> - This message is returned if the language is successfully - created. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term><computeroutput> -ERROR: PL handler function <replaceable class="parameter">funcname</replaceable>() doesn't exist - </computeroutput></term> - <listitem> - <para> - This error is returned if the function - <replaceable class="parameter">funcname</replaceable>() - is not found. - </para> - </listitem> - </varlistentry> - </variablelist> - </para> - </refsect2> +</synopsis> </refsynopsisdiv> - <refsect1 id="R1-SQL-CREATELANGUAGE-1"> - <refsect1info> - <date>1998-09-09</date> - </refsect1info> - <title> - Description - </title> + <refsect1 id="sql-createlanguage-description"> + <title>Description</title> + <para> - Using <command>CREATE LANGUAGE</command>, a - <productname>Postgres</productname> user can register - a new language with <productname>Postgres</productname>. - Subsequently, functions and - trigger procedures can be defined in this new language. - The user must have the <productname>Postgres</productname> - superuser privilege to + Using <command>CREATE LANGUAGE</command>, a + <productname>PostgreSQL</productname> user can register a new + procedural language with a <productname>PostgreSQL</productname> + database. Subsequently, functions and trigger procedures can be + defined in this new language. The user must have the + <productname>PostgreSQL</productname> superuser privilege to register a new language. </para> - <refsect2 id="R2-SQL-CREATELANGUAGE-3"> - <refsect2info> - <date>1998-09-09</date> - </refsect2info> - <title> - Writing PL handlers - </title> + <para> + <command>CREATE LANGUAGE</command> effectively associates the + language name with a call handler that is responsible for executing + functions written in the language. Refer to the + <citetitle>Programmer's Guide</citetitle> for more information + about language call handlers. + </para> + + <para> + Note that procedural languages are local to individual databases. + To make a language available in all databases by default, it should + be installed into the <literal>template1</literal> database. + </para> + </refsect1> + + <refsect1 id="sql-createlanguage-parameters"> + <title>Parameters</title> + + <variablelist> + <varlistentry> + <term><literal>TRUSTED</literal></term> + + <listitem> + <para> + <literal>TRUSTED</literal> specifies that the call handler for + the language is safe, that is, it does not offer an + unprivileged user any functionality to bypass access + restrictions. If this keyword is omitted when registering the + language, only users with the + <productname>PostgreSQL</productname> superuser privilege can + use this language to create new functions. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>PROCEDURAL</literal></term> + + <listitem> + <para> + This is a noise word. + </para> + </listitem> + </varlistentry> - <note> + <varlistentry> + <term><replaceable class="parameter">langname</replaceable></term> + + <listitem> + <para> + The name of the new procedural language. The language name is + case insensitive. A procedural language cannot override one of + the built-in languages of <productname>PostgreSQL</productname>. + </para> + + <para> + For backward compatibility, the name may be enclosed by single + quotes. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>HANDLER</literal> <replaceable class="parameter">call_handler</replaceable></term> + + <listitem> + <para> + <replaceable class="parameter">call_handler</replaceable> is + the name of a previously registered function that will be + called to execute the procedural language functions. The call + handler for a procedural language must be written in a compiled + language such as C with version 1 call convention and + registered with <productname>PostgreSQL</productname> as a + function taking no arguments and returning the + <type>opaque</type> type, a placeholder for unspecified or + undefined types. + </para> + </listitem> + </varlistentry> + </variablelist> + </refsect1> + + <refsect1 id="sql-createlanguage-diagnostics"> + <title>Diagnostics</title> + + <msgset> + <msgentry> + <msg> + <msgmain> + <msgtext> +<screen> +CREATE +</screen> + </msgtext> + </msgmain> + </msg> + + <msgexplan> <para> - In <productname>Postgres</productname> 7.1 and later, call handlers - must adhere to the "version 1" function manager interface, not the - old-style interface. + This message is returned if the language is successfully + created. </para> - </note> - - <para> - The call handler for a procedural language must be written - in a compiled language such as C and registered with - <productname>Postgres</productname> as a function 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 when a - PL function in the language offered by the handler is to be executed.) - </para> - - <para> - 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 - <literal>isnull</literal> field of the FunctionCallInfoData struct, - if it wishes to return an SQL NULL result). The difference between - a call handler and an ordinary callee function is that the - <literal>flinfo->fn_oid</literal> field of the FunctionCallInfoData - struct will contain the OID of the PL 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 PL function, - not of the call handler. - </para> - - <para> - It's up to the call handler to fetch the - <filename>pg_proc</filename> 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 - <filename>pg_proc</filename> 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 <literal>flinfo->fn_extra</literal> 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 <literal>flinfo->fn_extra</literal> is already non-NULL then it - can be used and the information lookup step skipped. The call handler - must be careful that <literal>flinfo->fn_extra</literal> 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 <literal>flinfo->fn_mcxt</literal>; such data will - normally have the same lifespan as the FmgrInfo 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 FunctionCallInfoData's - <literal>context</literal> field points at a TriggerData node, - rather than being NULL as it is in a plain function call. - A PL handler should provide mechanisms for PL functions to get - at the trigger information. - </para> - </refsect2> - - <refsect2 id="R2-SQL-CREATELANGUAGE-4"> - <refsect2info> - <date>1998-09-09</date> - </refsect2info> - <title> - Notes - </title> - <para> - Use <command>CREATE FUNCTION</command> - to create a function. - </para> - <para> - Use <command>DROP LANGUAGE</command> to drop procedural languages. - </para> - <para> - Refer to the table <filename>pg_language</filename> - for further information: -<programlisting> -<computeroutput> + </msgexplan> + </msgentry> + + <msgentry> + <msg> + <msgmain> + <msgtext> +<screen> +ERROR: PL handler function <replaceable class="parameter">funcname</replaceable>() doesn't exist +</screen> + </msgtext> + </msgmain> + </msg> + + <msgexplan> + <para> + This error is returned if the function <replaceable + class="parameter">funcname</replaceable>() is not found. + </para> + </msgexplan> + </msgentry> + </msgset> + </refsect1> + + <refsect1 id="sql-createlanguage-notes"> + <title>Notes</title> + + <para> + This command normally should not be executed directly by users. + For the procedural languages supplied in the + <productname>PostgreSQL</productname> distribution, the <xref + linkend="app-createlang"> program should be used, which will also + install the correct call handler. (<command>createlang</command> + will call <command>CREATE LANGUAGE</command> internally.) + </para> + + <para> + Use the <xref linkend="sql-createfunction"> command to create a new + function. + </para> + + <para> + Use <xref linkend="sql-droplanguage">, or better yet the <xref + linkend="app-droplang"> program, to drop procedural languages. + </para> + + <para> + The system catalog <classname>pg_language</classname> records + information about the currently installed procedural languages. + +<screen> Table "pg_language" Attribute | Type | Modifier ---------------+---------+---------- @@ -261,107 +205,61 @@ ERROR: PL handler function <replaceable class="parameter">funcname</replaceable internal | f | f | 0 | n/a C | f | f | 0 | /bin/cc sql | f | f | 0 | postgres -</computeroutput> -</programlisting> - </para> - - <para> - The call handler for a procedural language must normally be written - in C and registered as 'internal' or 'C' language, depending - on whether it is linked into the backend or dynamically loaded. - The call handler cannot use the old-style 'C' function interface. - </para> - - <para> - At present, the definitions for a procedural language cannot be - changed once they have been created. - </para> - </refsect2> - </refsect1> - - <refsect1 id="R1-SQL-CREATELANGUAGE-6"> - <title> - Usage - </title> - <para> - This is a template for a PL handler written in C: - <programlisting> -#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> +</screen> </para> <para> - Only a few thousand lines of code have to be added instead - of the dots to complete the PL call handler. - See <command>CREATE FUNCTION</command> for information on how to compile - it into a loadable module. + At present, the definition of a procedural language cannot be + changed once is has been created. </para> + </refsect1> + + <refsect1 id="sql-createlanguage-examples"> + <title>Examples</title> + <para> - The following commands then register the sample procedural - language: - <programlisting> + The following two commands executed in sequence will register a new + procedural language and the associated call handler. +<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> +</programlisting> + </para> + </refsect1> + + <refsect1 id="sql-createlanguage-compat"> + <title>Compatibility</title> + + <para> + <command>CREATE LANGUAGE</command> is a + <productname>PostgreSQL</productname> extension. </para> </refsect1> - <refsect1 id="R1-SQL-CREATELANGUAGE-7"> - <title> - Compatibility - </title> - - <refsect2 id="R2-SQL-CREATELANGUAGE-5"> - <refsect2info> - <date>1998-09-09</date> - </refsect2info> - <title> - SQL92 - </title> - - <para> - <command>CREATE LANGUAGE</command> - is a <productname>Postgres</productname> extension. - There is no <command>CREATE LANGUAGE</command> statement in - <acronym>SQL92</acronym>. - </para> - </refsect2> + <refsect1> + <title>History</title> + + <para> + The <command>CREATE LANGUAGE</command> command first appeared in + <productname>PostgreSQL</productname> 6.3. + </para> + </refsect1> + + <refsect1> + <title>See Also</title> + + <para> + <simplelist type="inline"> + <member><xref linkend="app-createlang"></member> + <member><xref linkend="sql-createfunction"></member> + <member><xref linkend="app-droplang"></member> + <member><xref linkend="sql-droplanguage"></member> + <member><citetitle>PostgreSQL Programmer's Guide</citetitle></member> + </simplelist> + </para> </refsect1> </refentry> diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml index be5ab0dd38addfc0fd54966c99babbe53a67f0ea..1e79981f700d46a71f9205cf07f9485374856089 100644 --- a/doc/src/sgml/xfunc.sgml +++ b/doc/src/sgml/xfunc.sgml @@ -1,5 +1,5 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.33 2001/08/28 14:20:26 petere Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.34 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 - PLPERL), 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