From 22ae53d4cdca7244b0de25f1d28255e1649aa936 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Thu, 6 Sep 2001 10:28:39 +0000 Subject: [PATCH] Move the "how to write a PL call handler" parts from the CREATE LANGUAGE man page to the Programmer's Guide. --- doc/src/sgml/ref/create_language.sgml | 528 +++++++++++--------------- doc/src/sgml/xfunc.sgml | 179 ++++++++- 2 files changed, 386 insertions(+), 321 deletions(-) diff --git a/doc/src/sgml/ref/create_language.sgml b/doc/src/sgml/ref/create_language.sgml index bcce7d6c61..b6af18b1bc 100644 --- a/doc/src/sgml/ref/create_language.sgml +++ b/doc/src/sgml/ref/create_language.sgml @@ -1,252 +1,196 @@ + + 2001-09-05 + + - - CREATE LANGUAGE - + CREATE LANGUAGE SQL - Language Statements + - - CREATE LANGUAGE - - - define a new procedural language - + CREATE LANGUAGE + define a new procedural language + - - 1999-07-20 - - + CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE langname HANDLER call_handler - - - - - 1998-09-09 - - - Inputs - - - - - - TRUSTED - - - TRUSTED 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 Postgres - superuser privilege can use - this language to create new functions. - - - - - - langname - - - 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 - Postgres. - - - For backward compatibility, the name may be enclosed by single - quotes. - - - - - - HANDLER call_handler - - - call_handler is the name - of a previously - registered function that will be called to execute the PL - procedures. - - - - - - - - - - - - 1998-09-09 - - - Outputs - - - - - - -CREATE - - - - This message is returned if the language is successfully - created. - - - - - -ERROR: PL handler function funcname() doesn't exist - - - - This error is returned if the function - funcname() - is not found. - - - - - - + - - - 1998-09-09 - - - Description - + + Description + - Using CREATE LANGUAGE, a - Postgres user can register - a new language with Postgres. - Subsequently, functions and - trigger procedures can be defined in this new language. - The user must have the Postgres - superuser privilege to + Using CREATE LANGUAGE, a + PostgreSQL user can register a new + procedural language with a PostgreSQL + database. Subsequently, functions and trigger procedures can be + defined in this new language. The user must have the + PostgreSQL superuser privilege to register a new language. - - - 1998-09-09 - - - Writing PL handlers - + + CREATE LANGUAGE effectively associates the + language name with a call handler that is responsible for executing + functions written in the language. Refer to the + Programmer's Guide for more information + about language call handlers. + + + + 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 template1 database. + + + + + Parameters + + + + TRUSTED + + + + TRUSTED 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 + PostgreSQL superuser privilege can + use this language to create new functions. + + + + + + PROCEDURAL + + + + This is a noise word. + + + - + + langname + + + + 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 PostgreSQL. + + + + For backward compatibility, the name may be enclosed by single + quotes. + + + + + + HANDLER call_handler + + + + call_handler 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 PostgreSQL as a + function taking no arguments and returning the + opaque type, a placeholder for unspecified or + undefined types. + + + + + + + + Diagnostics + + + + + + + +CREATE + + + + + + - In Postgres 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. - - - - The call handler for a procedural language must be written - in a compiled language such as C and registered with - Postgres as a function taking - no arguments and returning the - opaque 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.) - - - - 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 - isnull 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 - flinfo->fn_oid 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. - - - - It's up to the call handler to fetch the - pg_proc entry and - to analyze the argument and return types of the called - procedure. The AS clause from the - CREATE FUNCTION of - the procedure will be found in the prosrc - attribute of the - pg_proc 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. - - - - 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 flinfo->fn_extra 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 flinfo->fn_extra is already non-NULL then it - can be used and the information lookup step skipped. The call handler - must be careful that flinfo->fn_extra 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 flinfo->fn_mcxt; 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. - - - - When a PL function is invoked as a trigger, no explicit arguments - are passed, but the FunctionCallInfoData's - context 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. - - - - - - 1998-09-09 - - - Notes - - - Use CREATE FUNCTION - to create a function. - - - Use DROP LANGUAGE to drop procedural languages. - - - Refer to the table pg_language - for further information: - - + + + + + + + + +ERROR: PL handler function funcname() doesn't exist + + + + + + + + This error is returned if the function funcname() is not found. + + + + + + + + Notes + + + This command normally should not be executed directly by users. + For the procedural languages supplied in the + PostgreSQL distribution, the program should be used, which will also + install the correct call handler. (createlang + will call CREATE LANGUAGE internally.) + + + + Use the command to create a new + function. + + + + Use , or better yet the program, to drop procedural languages. + + + + The system catalog pg_language records + information about the currently installed procedural languages. + + Table "pg_language" Attribute | Type | Modifier ---------------+---------+---------- @@ -261,107 +205,61 @@ ERROR: PL handler function funcname - - - - - 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. - - - - At present, the definitions for a procedural language cannot be - changed once they have been created. - - - - - - - Usage - - - This is a template for a PL handler written in C: - -#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; -} - + - Only a few thousand lines of code have to be added instead - of the dots to complete the PL call handler. - See CREATE FUNCTION 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. + + + + Examples + - The following commands then register the sample procedural - language: - + The following two commands executed in sequence will register a new + procedural language and the associated call handler. + CREATE FUNCTION plsample_call_handler () RETURNS opaque AS '/usr/local/pgsql/lib/plsample.so' LANGUAGE C; CREATE LANGUAGE plsample HANDLER plsample_call_handler; - + + + + + + Compatibility + + + CREATE LANGUAGE is a + PostgreSQL extension. - - - Compatibility - - - - - 1998-09-09 - - - SQL92 - - - - CREATE LANGUAGE - is a Postgres extension. - There is no CREATE LANGUAGE statement in - SQL92. - - + + History + + + The CREATE LANGUAGE command first appeared in + PostgreSQL 6.3. + + + + + See Also + + + + + + + + PostgreSQL Programmer's Guide + + diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml index be5ab0dd38..1e79981f70 100644 --- a/doc/src/sgml/xfunc.sgml +++ b/doc/src/sgml/xfunc.sgml @@ -1,5 +1,5 @@ @@ -337,11 +337,11 @@ SELECT clean_EMP(); - There are currently three procedural languages available in the standard - Postgres distribution (PLSQL, PLTCL and - PLPERL), and other languages can be defined. - Refer to for - more information. + There are currently four procedural languages available in the + standard PostgreSQL distribution: + PL/pgSQL, PL/Tcl, PL/Perl, and PL/Python. Other languages can be + defined by users. Refer to for more + information. @@ -1357,6 +1357,173 @@ LANGUAGE 'c'; + + + + Procedural Language Handlers + + + All calls to functions that are written in a language other than + the current version 1 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 call handler + 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 PostgreSQL, but the + topic naturally belongs in this chapter, and the material might + give some insight into the extensible nature of the + PostgreSQL system. + + + + The call handler for a procedural language is a + normal function, which must be written in a + compiled language such as C and registered with + PostgreSQL as taking no arguments and + returning the opaque 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.) + + + + + In PostgreSQL 7.1 and later, call + handlers must adhere to the version 1 function + manager interface, not the old-style interface. + + + + + 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 isnull 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 + flinfo->fn_oid field of the + FunctionCallInfoData 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. + + + + It's up to the call handler to fetch the + pg_proc entry and to analyze the argument + and return types of the called procedure. The AS clause from the + CREATE FUNCTION of the procedure will be found + in the prosrc attribute of the + pg_proc 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. + + + + 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 + flinfo->fn_extra 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 + flinfo->fn_extra is already non-NULL + then it can be used and the information lookup step skipped. The + call handler must be careful that + flinfo->fn_extra 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 + flinfo->fn_mcxt; 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. + + + + When a PL function is invoked as a trigger, no explicit arguments + are passed, but the + FunctionCallInfoData's + context field points at a + TriggerData 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. + + + + This is a template for a PL handler written in C: + +#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; +} + + + + + Only a few thousand lines of code have to be added instead of the + dots to complete the call handler. See + for information on how to compile it into a loadable module. + + + + The following commands then register the sample procedural + language: + +CREATE FUNCTION plsample_call_handler () RETURNS opaque + AS '/usr/local/pgsql/lib/plsample.so' + LANGUAGE C; +CREATE LANGUAGE plsample + HANDLER plsample_call_handler; + + +