Improve discussion of SQL functions taking/returning row types.
authorTom Lane
Fri, 7 Jan 2005 22:40:46 +0000 (22:40 +0000)
committerTom Lane
Fri, 7 Jan 2005 22:40:46 +0000 (22:40 +0000)
doc/src/sgml/xfunc.sgml

index dedf4d73f68ebdef4a3c92aba38769c6c01315a6..534ba4c08fe0961eb7d339e228264bef64e114af 100644 (file)
@@ -1,5 +1,5 @@
 
 
  
@@ -111,6 +111,39 @@ $PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.92 2004/12/30 21:45:37 tgl Exp $
     void, the last statement must be a SELECT.
    
 
+    
+     Any collection of commands in the  SQL
+     language can be packaged together and defined as a function.
+     Besides SELECT queries, the commands can include data
+     modification queries (INSERT,
+     UPDATE, and DELETE), as well as
+     other SQL commands. (The only exception is that you can't put
+     BEGIN, COMMIT, ROLLBACK, or
+     SAVEPOINT commands into a SQL function.)
+     However, the final command 
+     must be a SELECT that returns whatever is
+     specified as the function's return type.  Alternatively, if you
+     want to define a SQL function that performs actions but has no
+     useful value to return, you can define it as returning void.
+     In that case, the function body must not end with a SELECT.
+     For example, this function removes rows with negative salaries from
+     the emp table:
+
+
+CREATE FUNCTION clean_emp() RETURNS void AS '
+    DELETE FROM emp
+        WHERE salary < 0;
+' LANGUAGE SQL;
+
+SELECT clean_emp();
+
+ clean_emp
+-----------
+
+(1 row)
+
+    
+
    
     The syntax of the CREATE FUNCTION command requires
     the function body to be written as a string constant.  It is usually
@@ -219,35 +252,6 @@ $$ LANGUAGE SQL;
 
      which adjusts the balance and returns the new balance.
     
-
-    
-     Any collection of commands in the  SQL
-     language can be packaged together and defined as a function.
-     Besides SELECT queries,
-     the commands can include data modification (i.e.,
-     INSERTUPDATE, and
-     DELETE).  However, the final command 
-     must be a SELECT that returns whatever is
-     specified as the function's return type.  Alternatively, if you
-     want to define a SQL function that performs actions but has no
-     useful value to return, you can define it as returning void.
-     In that case, the function body must not end with a SELECT.
-     For example:
-
-
-CREATE FUNCTION clean_emp() RETURNS void AS $$
-    DELETE FROM emp
-        WHERE salary <= 0;
-$$ LANGUAGE SQL;
-
-SELECT clean_emp();
-
- clean_emp
------------
-
-(1 row)
-
-    
    
 
    
@@ -282,7 +286,7 @@ SELECT name, double_salary(emp.*) AS dream
 
  name | dream
 ------+-------
Sam  |  2400
Bill |  8400
 
     
 
@@ -307,7 +311,7 @@ SELECT name, double_salary(emp) AS dream
      on-the-fly.  This can be done with the ROW construct.
      For example, we could adjust the data being passed to the function:
 
-SELECT name, double_salary(row(name, salary*1.1, age, cubicle)) AS dream
+SELECT name, double_salary(ROW(name, salary*1.1, age, cubicle)) AS dream
     FROM emp;
 
     
@@ -320,7 +324,7 @@ SELECT name, double_salary(row(name, salary*1.1, age, cubicle)) AS dream
 
 CREATE FUNCTION new_emp() RETURNS emp AS $$
     SELECT text 'None' AS name,
-        1000 AS salary,
+        1000.0 AS salary,
         25 AS age,
         point '(2,2)' AS cubicle;
 $$ LANGUAGE SQL;
@@ -358,9 +362,46 @@ ERROR:  function declared to return emp returns varchar instead of text at colum
          
 
     
-     When you call a function that returns a row (composite type) in a
-     SQL expression, you might want only one field (attribute) from its
-     result.  You can do that with syntax like this:
+     A different way to define the same function is:
+
+
+CREATE FUNCTION new_emp() RETURNS emp AS $$
+    SELECT ROW('None', 1000.0, 25, '(2,2)')::emp;
+$$ LANGUAGE SQL;
+
+
+     Here we wrote a SELECT that returns just a single
+     column of the correct composite type.  This isn't really better
+     in this situation, but it is a handy alternative in some cases
+     — for example, if we need to compute the result by calling
+     another function that returns the desired composite value.
+         
+
+    
+     We could call this function directly in either of two ways:
+
+
+SELECT new_emp();
+
+         new_emp
+--------------------------
+ (None,1000.0,25,"(2,2)")
+
+SELECT * FROM new_emp();
+
+ name | salary | age | cubicle
+------+--------+-----+---------
+ None | 1000.0 |  25 | (2,2)
+
+
+     The second way is described more fully in 
+     linkend="xfunc-sql-table-functions">.
+         
+
+    
+     When you use a function that returns a composite type,
+     you might want only one field (attribute) from its result.
+     You can do that with syntax like this:
 
 
 SELECT (new_emp()).name;
@@ -398,15 +439,14 @@ SELECT name(new_emp());
 
 
 -- This is the same as:
--- SELECT emp.name AS youngster FROM emp WHERE emp.age < 30
+-- SELECT emp.name AS youngster FROM emp WHERE emp.age < 30;
 
-SELECT name(emp) AS youngster
-    FROM emp
-    WHERE age(emp) < 30;
+SELECT name(emp) AS youngster FROM emp WHERE age(emp) < 30;
 
  youngster
 -----------
  Sam
+ Andy
 
     
 
@@ -433,7 +473,7 @@ SELECT getname(new_emp());
     
    
 
-   
+    id="xfunc-sql-table-functions">
     <acronym>SQL</acronym> Functions as Table Sources