Move docs about index cost estimation functions and writing a procedural
authorTom Lane
Wed, 22 Oct 2003 22:28:10 +0000 (22:28 +0000)
committerTom Lane
Wed, 22 Oct 2003 22:28:10 +0000 (22:28 +0000)
language handler to the 'Internals' area, per my proposal of yesterday.
Clean up the trigger documentation a bit.  Push SPI chapter to the end
of its part, and reorder the Internals chapters into what seems a more
sensible order (at the moment anyway).

doc/src/sgml/filelist.sgml
doc/src/sgml/plhandler.sgml [new file with mode: 0644]
doc/src/sgml/postgres.sgml
doc/src/sgml/spi.sgml
doc/src/sgml/trigger.sgml
doc/src/sgml/xfunc.sgml
doc/src/sgml/xplang.sgml

index 0333aaa6d586e592da53addfa6f9d7390ab67987..be7050c5c82adde69dc7ed21cbfa5863fdfe0b4b 100644 (file)
@@ -1,4 +1,4 @@
-
+
 
 
 
@@ -7,8 +7,6 @@
 
 
 
-
-
 
 
 
 
 
 
-
 
 
-
-
 
 
-
 
 
 
 
 
 
-
-
-
-
-
-%allfiles;
-
 
 
 
@@ -52,7 +39,6 @@
 
 
 
-
 
 
 
@@ -62,8 +48,6 @@
 
 
 
-
-
 
 
 
 
 
 
+
+
+%allfiles;
+
 
 
-
 
 
 
-
-
-
 
-
+
+
+
 
+
 
 
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 
 
+
+   Writing A Procedural Language Handler
+
+   
+    procedural language
+    handler for
+   
+
+   
+    All calls to functions that are written in a language other than
+    the current version 1 interface for compiled
+    languages (this includes functions in user-defined procedural languages,
+    functions written in SQL, and functions using 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 chapter outlines
+    how a new procedural language's call handler can be written.
+   
+
+   
+    The call handler for a procedural language is a
+    normal function that must be written in a compiled
+    language such as C, using the version-1 interface, and registered
+    with PostgreSQL as taking no arguments
+    and returning the type language_handler.  This
+    special pseudotype identifies the function as a call handler and
+    prevents it from being called directly in SQL commands.
+   
+
+   
+    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 structure, 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 structure 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 entry of the function from the
+    system table
+    pg_proc and to analyze the argument
+    and return types of the called function. The AS clause from the
+    CREATE FUNCTION of the function will be found
+    in the prosrc column of the
+    pg_proc row. This may be the source
+    text in the procedural language itself (like for PL/Tcl), a
+    path name 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 called 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 make sure 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 memory context so that it can cache
+    function definition information across queries.
+   
+
+   
+    When a procedural-language function is invoked as a trigger, no arguments
+    are passed in the usual way, but the
+    FunctionCallInfoData's
+    context field points at a
+    TriggerData structure, rather than being NULL
+    as it is in a plain function call.  A language handler should
+    provide mechanisms for procedural-language functions to get at the trigger
+    information.
+   
+
+   
+    This is a template for a procedural-language handler written in C:
+
+#include "postgres.h"
+#include "executor/spi.h"
+#include "commands/trigger.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.
+   
+
+   
+    After having compiled the handler function into a loadable module
+    (see ), the following commands then
+    register the sample procedural language:
+
+CREATE FUNCTION plsample_call_handler() RETURNS language_handler
+    AS 'filename'
+    LANGUAGE C;
+CREATE LANGUAGE plsample
+    HANDLER plsample_call_handler;
+
+   
+
+
+
index 7247c52de7c4e83b4c36b4c2b2d1c80d2eb904f2..80cb8ecef5402f8f7c1e39f70d005216c7029d59 100644 (file)
@@ -1,5 +1,5 @@
 
 
 
@@ -203,10 +203,8 @@ $Header: /cvsroot/pgsql/doc/src/sgml/postgres.sgml,v 1.57 2003/10/17 18:57:01 tg
   
 
   &extend;
-  &indexcost;
   &rules;
   &trigger;
-  &spi;
 
   &xplang;
   &plsql;
@@ -214,6 +212,8 @@ $Header: /cvsroot/pgsql/doc/src/sgml/postgres.sgml,v 1.57 2003/10/17 18:57:01 tg
   &plperl;
   &plpython;
 
+  &spi;
+
  
 
  &reference;
@@ -231,13 +231,15 @@ $Header: /cvsroot/pgsql/doc/src/sgml/postgres.sgml,v 1.57 2003/10/17 18:57:01 tg
   &arch-dev;
   &catalogs;
   &protocol;
-  &page;
+  &sources;
+  &nls;
+  &plhandler;
   &geqo;
+  &indexcost;
   &gist;
+  &page;
   &bki;
-  &sources;
   &compiler;
-  &nls;
 
  
 
index f8c6c2cd949d04404f527baa6ee70d5f27723346..efcc086a14817fafdce12136f6a039e1ef49990b 100644 (file)
@@ -1,5 +1,5 @@
 
 
 
@@ -11,18 +11,28 @@ $Header: /cvsroot/pgsql/doc/src/sgml/spi.sgml,v 1.27 2003/08/31 17:32:20 petere
 
  
   The Server Programming Interface
-  (SPI) gives users the ability to run
-  SQL commands inside user-defined
-  C functions.  SPI is a set of
+  (SPI) gives writers of user-defined
+  C functions the ability to run
+  SQL commands inside their functions.
+  SPI is a set of
   interface functions to simplify access to the parser, planner,
   optimizer, and executor. SPI also does some
   memory management.
  
 
+  
+   The available procedural languages provide various means to
+   execute SQL commands from procedures.  Some of these are based on or
+   modelled after SPI, so this documentation might be of use for users
+   of those languages as well.
+  
+
  
   To avoid misunderstanding we'll use the term function
   when we speak of SPI interface functions and
-  procedure for user-defined C-functions, which may be
+  procedure for a user-defined C-function that is
   using SPI.
  
 
@@ -50,15 +60,6 @@ $Header: /cvsroot/pgsql/doc/src/sgml/spi.sgml,v 1.27 2003/08/31 17:32:20 petere
   executor/spi.h.
  
 
-  
-   The available procedural languages provide different means to
-   execute SQL commands from procedures.  Some of these are modelled
-   after SPI, so this documentation might be of use for those users as
-   well.
-  
-
 
 
  Interface Functions
index a4eb485bf59ff1d8083bf7b2c11b2662149e5328..fcf1c1753ee454cec2d4660cac77aa4121f62c3e 100644 (file)
@@ -1,5 +1,5 @@
 
 
  
@@ -10,49 +10,44 @@ $Header: /cvsroot/pgsql/doc/src/sgml/trigger.sgml,v 1.30 2003/08/31 17:32:20 pet
   
 
   
-   This chapter describes how to write trigger functions.  In
-   particular, it describes the C-language interface for trigger
-   functions.  The trigger interfaces in most procedural languages
-   work analogously.  (Trigger functions cannot be written in SQL.)
-  
-
-  
-   A trigger function can execute before or after a
-   INSERTUPDATE, or
-   DELETE, either once per modified row, or once
-   per SQL statement.
+   This chapter describes how to write trigger functions.  Trigger
+   functions can be written in C or in some of the available procedural
+   languages.  It is not currently possible to write a SQL-language
+   trigger function.
   
 
   
-   <span class="marked">Trigger Definition</span>
+   <span class="marked">Overview of Trigger Behavior</span>
 
    
-    If a trigger event occurs, the trigger manager is called by the
-    executor.  It sets up an information structure of type
-    TriggerData (described below) and calls the trigger
-    function to handle the event.
+    A trigger can be defined to execute before or after an
+    INSERTUPDATE, or
+    DELETE operation, either once per modified row,
+    or once per SQL statement.
+    If a trigger event occurs, the trigger's function is called
+    at the appropriate time to handle the event.
    
 
    
     The trigger function must be defined before the trigger itself can be
     created.  The trigger function must be declared as a 
     function taking no arguments and returning type trigger.
-    (The trigger function receives its input through a TriggerData
-    structure, not in the form of ordinary function arguments.)
-    If the function is written in C, it must use the version 1
-    function manager interface.
+    (The trigger function receives its input through a specially-passed
+    TriggerData structure, not in the form of ordinary function
+    arguments.)
    
 
    
-    The syntax for creating triggers is described in
+    Once a suitable trigger function has been created, the trigger is
+    established with
     .
+    The same trigger function can be used for multiple triggers.
    
 
    
-    Trigger functions return a value of type HeapTuple,
-    which represents a table row, to the calling executor.  The return
-    value is ignored for triggers fired after an operation, but a
-    triggers fired before an operation has the following choices:
+    Trigger functions return a table row (a value of type
+    HeapTuple) to the calling executor.
+    A trigger fired before an operation has the following choices:
 
     
      
@@ -75,13 +70,19 @@ $Header: /cvsroot/pgsql/doc/src/sgml/trigger.sgml,v 1.30 2003/08/31 17:32:20 pet
     
 
     A before trigger that does not intend to cause either of these
-    behaviors must be careful to return the same row that was passed
-    in as the new row (see below).
+    behaviors must be careful to return as its result the same row that was
+    passed in.
+   
+
+   
+    The return
+    value is ignored for triggers fired after an operation, and so
+    they may as well return NULL.
    
 
    
     If more than one trigger is defined for the same event on the same
-    relation, the triggers will be fired in alphabetical order by
+    relation, the triggers will be fired in alphabetical order by trigger
     name.  In the case of before triggers, the possibly-modified row
     returned by each trigger becomes the input to the next trigger.
     If any before trigger returns a NULL pointer, the
@@ -89,7 +90,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/trigger.sgml,v 1.30 2003/08/31 17:32:20 pet
    
 
    
-    If a trigger function executes SQL commands (using SPI) then these
+    If a trigger function executes SQL commands then these
     commands may fire triggers again. This is known as cascading
     triggers.  There is no direct limitation on the number of cascade
     levels.  It is possible for cascades to cause a recursive invocation
@@ -120,10 +121,57 @@ $Header: /cvsroot/pgsql/doc/src/sgml/trigger.sgml,v 1.30 2003/08/31 17:32:20 pet
 
   
 
-  
-   Interaction with the Trigger Manager
+  
+   Visibility of Data Changes
+
+   
+    If you execute SQL commands in your trigger function, and these
+    commands access the table that the trigger is for, then
+    you need to be aware of the data visibility rules, because they determine
+    whether these SQL commands will see the data change that the trigger
+    is fired for.  Briefly:
+
+    
+     
+      
+       The data change (insertion, update, or deletion) causing the trigger
+       to fire is naturally
+       not visible to SQL commands executed in a
+       before trigger, because it hasn't happened yet.
+      
+     
+
+     
+      
+       However, SQL commands executed in a before trigger
+       will see the effects of data changes
+       for rows previously processed in the same outer command.  This
+       requires caution, since the ordering of these change events
+       is not in general predictable; a SQL command that affects
+       multiple rows may visit the rows in any order.
+      
+     
+
+     
+      
+       When an after trigger is fired, all data changes made by the outer
+       command are already complete, and are visible to executed SQL commands.
+      
+     
+    
+   
+
+   
+    Further information about data visibility rules can be found in
+    .  The example in 
+    linkend="trigger-example"> contains a demonstration of these rules.
+   
+  
 
-   
+  
+   Writing Trigger Functions in C
+
+   
     trigger
     in C
    
@@ -132,7 +180,14 @@ $Header: /cvsroot/pgsql/doc/src/sgml/trigger.sgml,v 1.30 2003/08/31 17:32:20 pet
     This section describes the low-level details of the interface to a
     trigger function.  This information is only needed when writing a
     trigger function in C.  If you are using a higher-level
-    language then these details are handled for you.
+    language then these details are handled for you.  The documentation
+    of each procedural language explains how to write a trigger in that
+    language.
+   
+
+   
+    Trigger functions must use the version 1 function manager
+    interface.
    
 
    
@@ -342,49 +397,12 @@ typedef struct Trigger
      
     
    
-  
-
-  
-   Visibility of Data Changes
-
-   
-    If you are using the SPI interface to execute SQL commands in your
-    trigger functions written in C (or you are using a different
-    language and execute SQL commands in some way, which internally
-    goes through SPI as well), be sure to read 
-    linkend="spi-visibility"> so that you know which data is visible
-    at which point during the execution of a trigger.  For triggers,
-    the most important consequences of the data visibility rules are:
-
-    
-     
-      
-       The row being inserted (tg_trigtuple) is
-       not visible to SQL commands executed in a
-       before trigger.
-      
-     
-
-     
-      
-       The row being inserted (tg_trigtuple)
-       is visible to SQL commands executed in an
-       after trigger (because it was just inserted).
-      
-     
-
-     
-      
-       A just-inserted row is visible to all SQL commands executed
-       within any trigger that is fired later in the execution of the
-       outer command (e.g., for the next row).
-      
-     
-    
-   
 
    
-    The next section contains a demonstration of these rules applied.
+    A trigger function must return either NULL or a
+    HeapTuple pointer.  Be careful to return either
+    tg_trigtuple or tg_newtuple,
+    as appropriate, if you don't want to modify the row being operated on.
    
   
 
@@ -393,6 +411,11 @@ typedef struct Trigger
 
    
     Here is a very simple example of a trigger function written in C.
+    (Examples of triggers written in procedural languages may be found
+    in the documentation of the procedural languages.)
+   
+
+   
     The function trigf reports the number of rows in the
     table ttest and skips the actual operation if the
     command attempts to insert a null value into the column
index f570ce89fd42346d3585329fd499127f33601f95..dc5c3bd4c26a14fd04e22a7a662225fc2296e12b 100644 (file)
@@ -1,5 +1,5 @@
 
 
  
@@ -58,6 +58,8 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.75 2003/09/12 22:17:24 tgl E
   
    It's easiest to define SQL 
    functions, so we'll start by discussing those.
+   Most of the concepts presented for SQL functions
+   will carry over to the other types of functions.
   
 
   
@@ -66,7 +68,8 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.75 2003/09/12 22:17:24 tgl E
    understand the examples better.
    Some examples from this chapter
    can be found in funcs.sql 
-   and funcs.c in the tutorial directory.
+   and funcs.c in the src/tutorial
+   directory in the PostgreSQL source distribution.
   
   
 
@@ -597,19 +600,23 @@ DETAIL:  A function returning ANYARRAY or ANYELEMENT must have at least one argu
    Procedural Language Functions
 
    
-    Procedural languages aren't built into the PostgreSQL server; they are offered
+    Procedural languages aren't built into the
+    PostgreSQL server; they are offered
     by loadable modules. Please refer to the documentation of the
-    procedural language in question for details about the syntax and how the function body
-    is interpreted for each language.
+    procedural language in question for details about the syntax and how the
+    function body is interpreted for each language.
    
 
    
     There are currently four procedural languages available in the
     standard PostgreSQL distribution:
     PL/pgSQLPL/Tcl,
-    PL/Perl, and PL/Python.  Other languages can be
-    defined by users.  Refer to  for more
-    information.  The basics of developing a new procedural language are covered in .
+    PL/Perl, and
+    PL/Python.
+    Refer to  for more information.
+    Other languages can be defined by users.
+    The basics of developing a new procedural language are covered in 
+    linkend="plhandler">.
    
   
 
@@ -1478,7 +1485,7 @@ concat_text(PG_FUNCTION_ARGS)
      to return set results () and
      implement trigger functions () and
      procedural-language call handlers (
-     linkend="xfunc-plhandler">).  Version-1 code is also more
+     linkend="plhandler">).  Version-1 code is also more
      portable than version-0, because it does not break restrictions
      on function call protocol in the C standard.  For more details
      see src/backend/utils/fmgr/README in the
@@ -2247,163 +2254,6 @@ CREATE FUNCTION test(int, int) RETURNS int
    
   
 
-  
-   Procedural Language Handlers
-
-   
-    procedural language
-    handler for
-   
-
-   
-    All calls to functions that are written in a language other than
-    the current version 1 interface for compiled
-    languages (this includes functions in user-defined procedural languages,
-    functions written in SQL, and functions using 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 that must be written in a compiled
-    language such as C, using the version-1 interface, and registered
-    with PostgreSQL as taking no arguments
-    and returning the type language_handler.  This
-    special pseudotype identifies the function as a call handler and
-    prevents it from being called directly in SQL commands.
-   
-
-   
-    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 structure, 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 structure 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 entry of the function from the system table
-    pg_proc and to analyze the argument
-    and return types of the called function. The AS clause from the
-    CREATE FUNCTION of the function will be found
-    in the prosrc column of the
-    pg_proc row. This may be the source
-    text in the procedural language itself (like for PL/Tcl), a
-    path name 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 called 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 make sure 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 memory context so that it can cache
-    function definition information across queries.
-   
-
-   
-    When a procedural-language function is invoked as a trigger, no arguments
-    are passed in the usual way, but the
-    FunctionCallInfoData's
-    context field points at a
-    TriggerData structure, rather than being NULL
-    as it is in a plain function call.  A language handler should
-    provide mechanisms for procedural-language functions to get at the trigger
-    information.
-   
-
-   
-    This is a template for a procedural-language handler written in C:
-
-#include "postgres.h"
-#include "executor/spi.h"
-#include "commands/trigger.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.
-   
-
-   
-    After having compiled the handler function into a loadable module
-    (see ), the following commands then
-    register the sample procedural language:
-
-CREATE FUNCTION plsample_call_handler() RETURNS language_handler
-    AS 'filename'
-    LANGUAGE C;
-CREATE LANGUAGE plsample
-    HANDLER plsample_call_handler;
-
-   
-  
-
 
 
  
@@ -28,7 +28,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xplang.sgml,v 1.24 2003/09/20 20:12:05 tgl
 
   
    Writing a handler for a new procedural language is described in
-   xfunc-plhandler">.  Several procedural languages are
+   .  Several procedural languages are
    available in the standard PostgreSQL
    distribution, which can serve as examples.