Index: doc/src/sgml/plpgsql.sgml
===================================================================
RCS file: /var/lib/cvs/pgsql-server/doc/src/sgml/plpgsql.sgml,v
retrieving revision 1.6
diff -c -r1.6 plpgsql.sgml
*** doc/src/sgml/plpgsql.sgml	1 Sep 2002 16:28:05 -0000	1.6
--- doc/src/sgml/plpgsql.sgml	13 Sep 2002 19:12:35 -0000
***************
*** 70,87 ****
     </para>
     <para>
      As each expression and <acronym>SQL</acronym> query is first used
!     in the function, the <application>PL/pgSQL</> interpreter creates a
!     prepared execution plan (using the <acronym>SPI</acronym> manager's 
!     <function>SPI_prepare</function> and
!     <function>SPI_saveplan</function> 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.
     </para>
    <para>
     Once <application>PL/pgSQL</> has made a query plan for a particular
--- 70,88 ----
     </para>
     <para>
      As each expression and <acronym>SQL</acronym> query is first used
! 	in the function, the <application>PL/pgSQL</> interpreter creates
! 	a prepared execution plan (using the <acronym>SPI</acronym>
! 	manager's <function>SPI_prepare</function> and
! 	<function>SPI_saveplan</function> 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.
     </para>
    <para>
     Once <application>PL/pgSQL</> has made a query plan for a particular
***************
*** 110,123 ****
     </para>
  
     <para>
!     Because <application>PL/pgSQL</application> saves execution plans in this way, queries that appear
!     directly in a <application>PL/pgSQL</application> 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 <application>PL/pgSQL</application>
!     EXECUTE statement --- at the price of constructing a new query plan
!     on every execution.
     </para>
     <para>
      Except for input/output conversion and calculation functions
      for user defined types, anything that can be defined in C language
--- 111,136 ----
     </para>
  
     <para>
!     Because <application>PL/pgSQL</application> saves execution plans
! 	in this way, queries that appear directly in a
! 	<application>PL/pgSQL</application> 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 <application>PL/pgSQL</application> EXECUTE statement --- at
! 	the price of constructing a new query plan on every execution.
     </para>
+ 
+    <note>
+ 	<para>
+ 	 The <application>PL/pgSQL</application> EXECUTE statement is not
+ 	 related to the EXECUTE statement supported by the
+ 	 <productname>PostgreSQL</productname> backend. The backend
+ 	 EXECUTE statement cannot be used within PL/PgSQL functions (and
+ 	 is not needed).
+ 	</para>
+    </note>
+ 
     <para>
      Except for input/output conversion and calculation functions
      for user defined types, anything that can be defined in C language
***************
*** 152,162 ****
      <title>Better Performance</title>
  
      <para>
!      <acronym>SQL</acronym> is the language <productname>PostgreSQL</> (and
!      most other Relational Databases) use as query
!      language. It's portable and easy to learn. But every
!      <acronym>SQL</acronym> statement must be executed
!      individually by the database server.
      </para>
  
      <para>
--- 165,175 ----
      <title>Better Performance</title>
  
      <para>
! 	  <acronym>SQL</acronym> is the language
! 	  <productname>PostgreSQL</> (and most other relational databases)
! 	  use as query language. It's portable and easy to learn. But
! 	  every <acronym>SQL</acronym> statement must be executed
! 	  individually by the database server.
      </para>
  
      <para>
***************
*** 195,203 ****
      <title>Portability</title>
  
      <para>
!      Because <application>PL/pgSQL</application> functions run inside <productname>PostgreSQL</>, these
!      functions will run on any platform where <productname>PostgreSQL</>
!      runs. Thus you can reuse code and have less development costs.
      </para>
     </sect3>
    </sect2>
--- 208,217 ----
      <title>Portability</title>
  
      <para>
! 	  Because <application>PL/pgSQL</application> functions run inside
! 	  <productname>PostgreSQL</>, these functions will run on any
! 	  platform where <productname>PostgreSQL</> runs. Thus you can
! 	  reuse code and have reduce development costs.
      </para>
     </sect3>
    </sect2>
***************
*** 227,242 ****
     </para>
  
     <para>
!     One good way to develop in <application>PL/pgSQL</> is to simply use the text
!     editor of your choice to create your functions, and in another
!     console, use <command>psql</command> (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 <command>CREATE OR REPLACE
!     FUNCTION</command>. That way you can reload the file to update
!     the function definition.  For example:
  <programlisting>
  CREATE OR REPLACE FUNCTION testfunc(INTEGER) RETURNS INTEGER AS '
!     ....
  end;
  ' LANGUAGE 'plpgsql';
  </programlisting>
--- 241,257 ----
     </para>
  
     <para>
! 	 One good way to develop in <application>PL/pgSQL</> is to simply
! 	 use the text editor of your choice to create your functions, and
! 	 in another console, use <command>psql</command>
! 	 (<productname>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 <command>CREATE OR REPLACE
! 	 FUNCTION</>. That way you can reload the file to update the
! 	 function definition.  For example:
  <programlisting>
  CREATE OR REPLACE FUNCTION testfunc(INTEGER) RETURNS INTEGER AS '
! 	  ....
  end;
  ' LANGUAGE 'plpgsql';
  </programlisting>
***************
*** 645,653 ****
  
      <note>
      <para>
!      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.
      </para>
      </note>
  
--- 660,668 ----
  
      <note>
      <para>
! 	  RENAME appears to be broken as of <productname>PostgreSQL</>
! 	  7.2.  Fixing this is of low priority, since ALIAS covers most of
! 	  the practical uses of RENAME.
      </para>
      </note>
  
***************
*** 898,904 ****
  PERFORM <replaceable>query</replaceable>;
  </synopsis>
  
!      This executes a <literal>SELECT</literal>
       <replaceable>query</replaceable> and discards the
       result. <application>PL/pgSQL</application> variables are
       substituted in the query as usual.  Also, the special variable
--- 913,919 ----
  PERFORM <replaceable>query</replaceable>;
  </synopsis>
  
!      This executes a <command>SELECT</command>
       <replaceable>query</replaceable> and discards the
       result. <application>PL/pgSQL</application> variables are
       substituted in the query as usual.  Also, the special variable
***************
*** 1044,1049 ****
--- 1059,1068 ----
      <title>Obtaining result status</title>
  
      <para>
+ 	 There are several ways to determine the effect of a command. The
+ 	 first method is to use the <literal>GET DIAGNOSTICS</literal>,
+ 	 which has the form:
+ 
  <synopsis>
  GET DIAGNOSTICS <replaceable>variable</replaceable> = <replaceable>item</replaceable> <optional> , ... </optional> ;
  </synopsis>
***************
*** 1166,1175 ****
      <para>
       When a <application>PL/pgSQL</> function is declared to return
       <literal>SETOF</literal> <replaceable>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.
  
  <synopsis>
  RETURN NEXT <replaceable>expression</replaceable>;
--- 1185,1204 ----
      <para>
       When a <application>PL/pgSQL</> function is declared to return
       <literal>SETOF</literal> <replaceable>sometype</>, the procedure
!      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 program 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:
! 
! <programlisting>
! SELECT * FROM some_func();
! </programlisting>
! 
! 	 (Namely, a column list such as <literal>*</literal> must be
! 	 specified).
  
  <synopsis>
  RETURN NEXT <replaceable>expression</replaceable>;
***************
*** 1184,1189 ****
--- 1213,1236 ----
       RETURN, which need have no argument, causes control to exit
       the function.
      </para>
+ 
+ 	<note>
+ 	 <para>
+ 	  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 buffered to disk to avoid memory exhaustion, but the
+ 	  function itself will not return any results 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 is buffered to disk is controlled by the
+ 	  <option>SORT_MEM</> configuration variable; administrators who
+ 	  have sufficient memory to store larger result sets in memory
+ 	  should consider increasing this parameter.
+ 	  </para>
+ 	</note>
     </sect2>
      
     <sect2 id="plpgsql-conditionals">
***************
*** 1904,1916 ****
    <title>Trigger Procedures</title>
  
    <para>
!    <application>PL/pgSQL</application> can be used to define trigger
!    procedures. A trigger procedure is created with the <command>CREATE
!    FUNCTION</command> command as a function with no arguments and a return
!    type of <type>TRIGGER</type>.  Note that the function must be declared
!    with no arguments even if it expects to receive arguments specified
!    in <command>CREATE TRIGGER</> --- trigger arguments are passed via
!    <varname>TG_ARGV</>, as described below.
    </para>
  
    <para>
--- 1951,1964 ----
    <title>Trigger Procedures</title>
  
    <para>
! 	<application>PL/pgSQL</application> can be used to define trigger
! 	procedures. A trigger procedure is created with the
! 	<command>CREATE FUNCTION</> command as a function with no
! 	arguments and a return type of <type>TRIGGER</type>.  Note that
! 	the function must be declared with no arguments even if it expects
! 	to receive arguments specified in <command>CREATE TRIGGER</> ---
! 	trigger arguments are passed via <varname>TG_ARGV</>, as described
! 	below.
    </para>
  
    <para>
***************
*** 2106,2119 ****
     </para>
  
     <para>
!     One painful detail in writing functions in <application>PL/pgSQL</application> is the handling
!     of single quotes. The function's source text in <command>CREATE FUNCTION</command> 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 <productname>PostgreSQL</productname> will be
!     forward compatible.
     </para>
  
     <para>
--- 2154,2168 ----
     </para>
  
     <para>
!     One painful detail in writing functions in
! 	<application>PL/pgSQL</application> is the handling of single
! 	quotes. The function's source text in <command>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
! 	<productname>PostgreSQL</productname> will be forward compatible.
     </para>
  
     <para>
***************
*** 2504,2510 ****
  
      <para>
       The following procedure grabs rows from a
!      <literal>SELECT</literal> statement and builds a large function
       with the results in <literal>IF</literal> statements, for the
       sake of efficiency. Notice particularly the differences in
       cursors, <literal>FOR</literal> loops, and the need to escape
--- 2553,2559 ----
  
      <para>
       The following procedure grabs rows from a
!      <command>SELECT</command> statement and builds a large function
       with the results in <literal>IF</literal> statements, for the
       sake of efficiency. Notice particularly the differences in
       cursors, <literal>FOR</literal> loops, and the need to escape
***************
*** 2735,2741 ****
  
       <callout arearefs="co.plpgsql-porting-locktable">
        <para>
!        If you do a <literal>LOCK TABLE</literal> in <application>PL/pgSQL</>, the lock
         will not be released until the calling transaction is finished.
        </para>
       </callout>
--- 2784,2790 ----
  
       <callout arearefs="co.plpgsql-porting-locktable">
        <para>
!        If you do a <command>LOCK TABLE</command> in <application>PL/pgSQL</>, the lock
         will not be released until the calling transaction is finished.
        </para>
       </callout>
***************
*** 2746,2752 ****
         entire function (and other functions called from therein) is
         executed in a transaction and <productname>PostgreSQL</> rolls back the results if
         something goes wrong. Therefore only one
!        <literal>BEGIN</literal> statement is allowed.
        </para>
       </callout>
  
--- 2795,2801 ----
         entire function (and other functions called from therein) is
         executed in a transaction and <productname>PostgreSQL</> rolls back the results if
         something goes wrong. Therefore only one
!        <command>BEGIN</command> statement is allowed.
        </para>
       </callout>
  
***************
*** 2895,2901 ****
      <title>EXECUTE</title>
  
      <para>
!      The <productname>PostgreSQL</> version of <literal>EXECUTE</literal> works
       nicely, but you have to remember to use
       <function>quote_literal(TEXT)</function> and
       <function>quote_string(TEXT)</function> as described in <xref
--- 2944,2950 ----
      <title>EXECUTE</title>
  
      <para>
!      The <productname>PostgreSQL</> version of <command>EXECUTE</command> works
       nicely, but you have to remember to use
       <function>quote_literal(TEXT)</function> and
       <function>quote_string(TEXT)</function> as described in <xref
