Fix documentation of EXECUTE, add documentation of FOR ... EXECUTE.
authorTom Lane
Sat, 10 Feb 2001 05:32:33 +0000 (05:32 +0000)
committerTom Lane
Sat, 10 Feb 2001 05:32:33 +0000 (05:32 +0000)
doc/src/sgml/plsql.sgml

index def5e07f0845b0cb80e8292391df5ba2a675b06e..72dabd824b008ca0c1b24f7f42b0975541dbc67d 100644 (file)
@@ -1,5 +1,5 @@
 
 
  
@@ -54,26 +54,35 @@ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/plsql.sgml,v 2.18 2001/01/20 20:59:29
     
    
    
-    The PL/pgSQL call handler parses the functions source text and
-    produces an internal binary instruction tree on the first time the
+    The PL/pgSQL call handler parses the function's source text and
+    produces an internal binary instruction tree the first time the
     function is called. The produced bytecode is identified
-    in the call handler by the object ID of the function. This ensures,
+    in the call handler by the object ID of the function. This ensures
     that changing a function by a DROP/CREATE sequence will take effect
     without establishing a new database connection. 
    
    
     For all expressions and SQL statements used in
     the function, the PL/pgSQL bytecode interpreter creates a
-    prepared execution plan using the SPI managers SPI_prepare() and
-    SPI_saveplan() functions. This is done the first time, the individual
+    prepared execution plan using the SPI manager's SPI_prepare() and
+    SPI_saveplan() functions. This is done the first time the individual
     statement is processed in the PL/pgSQL function. Thus, a function with
     conditional code that contains many statements for which execution
     plans would be required, will only prepare and save those plans
-    that are really used during the entire lifetime of the database
+    that are really used during the lifetime of the database
     connection.
    
    
-    Except for input-/output-conversion and calculation functions
+    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.
+   
+   
+    Except for input/output conversion and calculation functions
     for user defined types, anything that can be defined in C language
     functions can also be done with PL/pgSQL. It is possible to
     create complex conditional computation functions and later use
@@ -118,11 +127,13 @@ END;
     
 
     
-     It is important not to misunderstand the meaning of BEGIN/END for
-     grouping statements in PL/pgSQL and the database commands for
-     transaction control. Functions and trigger procedures cannot
-     start or commit transactions and Postgres
-     does not have nested transactions.
+     It is important not to confuse the use of BEGIN/END for
+     grouping statements in PL/pgSQL with the database commands for
+     transaction control.  PL/pgSQL's BEGIN/END are only for grouping;
+     they do not start or end a transaction.  Functions and trigger procedures
+     are always executed within a transaction established by an outer query
+     --- they cannot start or commit transactions, since
+     Postgres does not have nested transactions.
     
    
 
@@ -146,8 +157,8 @@ END;
 
     
      All variables, rows and records used in a block or its
-     sub-blocks must be declared in the declarations section of a block
-     except for the loop variable of a FOR loop iterating over a range
+     sub-blocks must be declared in the declarations section of a block,
+     except for the loop variable of a FOR-loop iterating over a range
      of integer values. Parameters given to a PL/pgSQL function are
      automatically declared with the usual identifiers $n.
      The declarations have the following syntax:
@@ -439,7 +450,11 @@ CREATE FUNCTION logfunc2 (text) RETURNS timestamp AS '
 SELECT  INTO target expressions FROM ...;
    
    target can be a record, a row variable or a
-   comma separated list of variables and record-/row-fields.
+   comma separated list of variables and record-/row-fields.  Note that
+   this is quite different from Postgres' normal interpretation of
+   SELECT INTO, which is that the INTO target is a newly created table.
+   (If you want to create a table from a SELECT result inside a PL/pgSQL
+   function, use the equivalent syntax CREATE TABLE AS SELECT.)
        
        
    if a row or a variable list is used as target, the selected values
@@ -506,10 +521,12 @@ PERFORM query
         within the procedure to perform actions on variable tables and
         fields.
        
-       
+
        
-       The results from SELECT queries are discarded by EXECUTE unless
-       SELECT INTO is used to save the results into a table.
+   The results from SELECT queries are discarded by EXECUTE, and
+   SELECT INTO is not currently supported within EXECUTE.  So, the
+   only way to extract a result from a dynamically-created SELECT
+   is to use the FOR ... EXECUTE form described later.
        
 
        
@@ -531,7 +548,7 @@ EXECUTE ''UPDATE tbl SET ''
         quote_literal().  Both take the
         appropriate steps to return the input text enclosed in single
         or double quotes and with any embedded special characters
-        intact.
+        properly escaped.
        
       
      
@@ -587,7 +604,7 @@ IF expression THEN
 END IF;
    
    The expression must return a value that
-   at least can be casted into a boolean type.
+   is a boolean or can be casted into a boolean.
        
       
      
@@ -635,9 +652,21 @@ FOR record | row IN select_clause
 END LOOP;
    
    The record or row is assigned all the rows resulting from the select
-   clause and the statements executed for each. If the loop is terminated
-   with an EXIT statement, the last assigned row is still accessible 
-   after the loop.
+   clause and the loop body is executed for each row. If the loop is
+   terminated with an EXIT statement, the last assigned row is still
+   accessible after the loop.
+   
+[<<label>>]
+FOR record | row IN EXECUTE text_expression LOOP
+    statements
+END LOOP;
+   
+   This is like the previous form, except that the source SELECT
+   statement is specified as a string expression, which is evaluated
+   and re-planned on each entry to the FOR loop.  This allows the
+   programmer to choose the speed of a pre-planned query or the
+   flexibility of a dynamic query, just as with a plain EXECUTE
+   statement.
    
 EXIT [ label ] [ WHEN expression ];