Some PL/PgSQL documentation improvements from Neil Conway.
authorTom Lane
Sat, 14 Sep 2002 20:11:16 +0000 (20:11 +0000)
committerTom Lane
Sat, 14 Sep 2002 20:11:16 +0000 (20:11 +0000)
doc/src/sgml/plpgsql.sgml

index 998ed72089e32f4b6849f878cda452ccfd1fbc1c..a4cff1d3af5c068f97e5e97bc08e8da2e47de4c0 100644 (file)
@@ -1,5 +1,5 @@
 
 
  
@@ -70,18 +70,19 @@ $Header: /cvsroot/pgsql/doc/src/sgml/plpgsql.sgml,v 1.6 2002/09/01 16:28:05 tgl
    
    
     As each expression and SQL query is first used
-    in the function, the PL/pgSQL interpreter creates a
-    prepared execution plan (using the SPI manager's 
-    SPI_prepare and
-    SPI_saveplan functions).  Subsequent visits
-    to that expression or query re-use the prepared plan.  Thus, a function
-    with conditional code that contains many statements for which execution
-    plans might be required, will only prepare and save those plans
-    that are really used during the lifetime of the database
-    connection.  This can provide a considerable savings of parsing
-    activity.  A disadvantage is that errors in a specific expression
-    or query may not be detected until that part of the function is
-    reached in execution.
+   in the function, the PL/pgSQL interpreter creates
+   a prepared execution plan (using the SPI
+   manager's SPI_prepare and
+   SPI_saveplan functions).  Subsequent visits
+   to that expression or query re-use the prepared plan.  Thus, a
+   function with conditional code that contains many statements for
+   which execution plans might be required will only prepare and save
+   those plans that are really used during the lifetime of the
+   database connection.  This can substantially reduce the total
+   amount of time required to parse, and generate query plans for the
+   statements in a procedural language function. A disadvantage is
+   that errors in a specific expression or query may not be detected
+   until that part of the function is reached in execution.
    
   
    Once PL/pgSQL has made a query plan for a particular
@@ -110,14 +111,26 @@ END;
    
 
    
-    Because PL/pgSQL saves execution plans in this way, queries that appear
-    directly in a PL/pgSQL function must refer to the same tables and fields
-    on every execution; that is, you cannot use a parameter as the name of
-    a table or field in a query.  To get around
-    this restriction, you can construct dynamic queries using the PL/pgSQL
-    EXECUTE statement --- at the price of constructing a new query plan
-    on every execution.
+    Because PL/pgSQL saves execution plans
+   in this way, queries that appear directly in a
+   PL/pgSQL function must refer to the
+   same tables and fields on every execution; that is, you cannot use
+   a parameter as the name of a table or field in a query.  To get
+   around this restriction, you can construct dynamic queries using
+   the PL/pgSQL EXECUTE statement --- at
+   the price of constructing a new query plan on every execution.
    
+
+   
+   
+    The PL/pgSQL EXECUTE statement is not
+    related to the EXECUTE statement supported by the
+    PostgreSQL backend. The backend
+    EXECUTE statement cannot be used within PL/PgSQL functions (and
+    is not needed).
+   
+   
+
    
     Except for input/output conversion and calculation functions
     for user defined types, anything that can be defined in C language
@@ -152,11 +165,11 @@ END;
     Better Performance
 
     
-     SQL is the language PostgreSQL (and
-     most other Relational Databases) use as query
-     language. It's portable and easy to learn. But every
-     SQL statement must be executed
-     individually by the database server.
+     SQL is the language
+     PostgreSQL (and most other relational databases)
+     use as query language. It's portable and easy to learn. But
+     every SQL statement must be executed
+     individually by the database server.
     
 
     
@@ -195,9 +208,10 @@ END;
     Portability
 
     
-     Because PL/pgSQL functions run inside PostgreSQL, these
-     functions will run on any platform where PostgreSQL
-     runs. Thus you can reuse code and have less development costs.
+     Because PL/pgSQL functions run inside
+     PostgreSQL, these functions will run on any
+     platform where PostgreSQL runs. Thus you can
+     reuse code and reduce development costs.
     
    
   
@@ -227,16 +241,17 @@ END;
    
 
    
-    One good way to develop in PL/pgSQL is to simply use the text
-    editor of your choice to create your functions, and in another
-    console, use psql (PostgreSQL's interactive monitor) to load
-    those functions. If you are doing it this way, it is a good
-    idea to write the function using CREATE OR REPLACE
-    FUNCTION. That way you can reload the file to update
-    the function definition.  For example:
+    One good way to develop in PL/pgSQL is to simply
+    use the text editor of your choice to create your functions, and
+    in another window, use psql
+    (PostgreSQL's interactive monitor) to load those
+    functions. If you are doing it this way, it is a good idea to
+    write the function using CREATE OR REPLACE
+    FUNCTION. That way you can reload the file to update the
+    function definition.  For example:
 
 CREATE OR REPLACE FUNCTION testfunc(INTEGER) RETURNS INTEGER AS '
-    ....
+     ....
 end;
 ' LANGUAGE 'plpgsql';
 
@@ -645,9 +660,9 @@ RENAME this_var TO that_var;
 
     
     
-     RENAME appears to be broken as of PostgreSQL 7.2.  Fixing this is
-     of low priority, since ALIAS covers most of the practical uses of
-     RENAME.
+     RENAME appears to be broken as of PostgreSQL
+     7.3.  Fixing this is of low priority, since ALIAS covers most of
+     the practical uses of RENAME.
     
     
 
@@ -898,7 +913,7 @@ END;
 PERFORM query;
 
 
-     This executes a <literal>SELECT>
+     This executes a <command>SELECT>
      query and discards the
      result. PL/pgSQL variables are
      substituted in the query as usual.  Also, the special variable
@@ -1044,6 +1059,10 @@ END;
     Obtaining result status
 
     
+    There are several ways to determine the effect of a command. The
+    first method is to use the GET DIAGNOSTICS,
+    which has the form:
+
 
 GET DIAGNOSTICS variable = item  , ...  ;
 
@@ -1166,10 +1185,19 @@ RETURN expression;
     
      When a PL/pgSQL function is declared to return
      SETOF sometype, the procedure
-     to follow is slightly different.  The individual items to be returned
-     are specified in RETURN NEXT commands, and then a final RETURN with
-     no argument is given to indicate that the function is done generating
-     items.
+     to follow is slightly different.  In that case, the individual
+     items to return are specified in RETURN NEXT commands, and then a
+     final RETURN command with no arguments is used to indicate that
+     the function has finished executing.  RETURN NEXT can be used with
+     both scalar and composite data types; in the later case, an
+     entire "table" of results will be returned.  Functions that use
+     RETURN NEXT should be called in the following fashion:
+
+
+SELECT * FROM some_func();
+
+
+     That is, the function is used as a table source in a FROM clause.
 
 
 RETURN NEXT expression;
@@ -1184,6 +1212,24 @@ RETURN NEXT expression;
      RETURN, which need have no argument, causes control to exit
      the function.
     
+
+   
+    
+     The current implementation of RETURN NEXT for PL/PgSQL stores
+     the entire result set before returning from the function, as
+     discussed above.  That means that if a PL/PgSQL function
+     produces a very large result set, performance may be poor: data
+     will be written to disk to avoid memory exhaustion, but the
+     function itself will not return until the entire
+     result set has been generated.  A future version of PL/PgSQL may
+     allow users to allow users to define set-returning functions
+     that do not have this limitation.  Currently, the point at which
+     data begins being written to disk is controlled by the
+     
+     have sufficient memory to store larger result sets in memory
+     should consider increasing this parameter.
+     
+   
    
     
    
@@ -1904,13 +1950,14 @@ RAISE EXCEPTION ''Inexistent ID --> %'',user_id;
   Trigger Procedures
 
   
-   PL/pgSQL can be used to define trigger
-   procedures. A trigger procedure is created with the CREATE
-   FUNCTION command as a function with no arguments and a return
-   type of TRIGGER.  Note that the function must be declared
-   with no arguments even if it expects to receive arguments specified
-   in CREATE TRIGGER --- trigger arguments are passed via
-   TG_ARGV, as described below.
+   PL/pgSQL can be used to define trigger
+   procedures. A trigger procedure is created with the
+   CREATE FUNCTION command as a function with no
+   arguments and a return type of TRIGGER.  Note that
+   the function must be declared with no arguments even if it expects
+   to receive arguments specified in CREATE TRIGGER ---
+   trigger arguments are passed via TG_ARGV, as described
+   below.
   
 
   
@@ -2106,14 +2153,15 @@ CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp
    
 
    
-    One painful detail in writing functions in PL/pgSQL is the handling
-    of single quotes. The function's source text in CREATE FUNCTION must
-    be a literal string. Single quotes inside of literal strings must be
-    either doubled or quoted with a backslash. We are still looking for
-    an elegant alternative. In the meantime, doubling the single quotes
-    as in the examples below should be used. Any solution for this
-    in future versions of PostgreSQL will be
-    forward compatible.
+    One painful detail in writing functions in
+   PL/pgSQL is the handling of single
+   quotes. The function's source text in CREATE FUNCTION
+   must be a literal string. Single quotes inside of literal strings
+   must be either doubled or quoted with a backslash. We are still
+   looking for an elegant alternative. In the meantime, doubling the
+   single quotes as in the examples below should be used. Any
+   solution for this in future versions of
+   PostgreSQL will be forward compatible.
    
 
    
@@ -2504,7 +2552,7 @@ END;
 
     
      The following procedure grabs rows from a
-     <literal>SELECT> statement and builds a large function
+     <command>SELECT> statement and builds a large function
      with the results in IF statements, for the
      sake of efficiency. Notice particularly the differences in
      cursors, FOR loops, and the need to escape
@@ -2735,7 +2783,7 @@ show errors
 
      
       
-       If you do a <literal>LOCK TABLE> in PL/pgSQL, the lock
+       If you do a <command>LOCK TABLE> in PL/pgSQL, the lock
        will not be released until the calling transaction is finished.
       
      
@@ -2746,7 +2794,7 @@ show errors
        entire function (and other functions called from therein) is
        executed in a transaction and PostgreSQL rolls back the results if
        something goes wrong. Therefore only one
-       <literal>BEGIN> statement is allowed.
+       <command>BEGIN> statement is allowed.
       
      
 
@@ -2895,7 +2943,7 @@ END;
     EXECUTE
 
     
-     The PostgreSQL version of <literal>EXECUTE> works
+     The PostgreSQL version of <command>EXECUTE> works
      nicely, but you have to remember to use
      quote_literal(TEXT) and
      quote_string(TEXT) as described in