Functions with LANGUAGE SQL
are basically just batch files with plain SQL commands in a function wrapper accepting parameters. For anything more, as Jack wrote, the most mature language is PL/pgSQL (LANGUAGE plpgsql
). It works well and has been improved with every release over the last decade, but it serves best as glue for SQL commands. It is not meant for heavy computations (other than with SQL commands).
Functions in PostgreSQL execute queries like prepared statements, which cuts off some of the overhead and make them generally faster that the equivalent SQL statements. This may be a noticeable effect depending on circumstances.
This carries the advantages and disadvantages of prepared statement - as described in the linked manual page. In the case of queries with very uneven data distribution and varying parameters and results it may be of advantage to use dynamic SQL with EXECUTE, because the gain from an optimized execution plan is bigger than the loss due to re-planning every time.
PostgreSQL 9.2 brought a major improvement in this area: The planner now plans the query at execution and decides whether it could be worth to replan with the current parameter values. So you get the best of both worlds, performance-wise, and you don't have to (ab)use EXECUTE
for this purpose any more. Details in What's new in PostgreSQL 9.2 of the PostgreSQL Wiki.
You can win big with server side functions when you prevent additional journeys to the database server from your application. Have the server execute as much as possible at once and only return a well defined result.
Avoid nesting of complex functions, especially table functions (RETURNING SETOF record
or TABLE (..)
), where the query planner might otherwise optimize away redundant operations. Functions are black boxes for the query planner. They cannot be further optimized. And cost and result size of functions can not effectively be predicted.
The exception to this rule are simple SQL functions (language SQL
), which can be "inlined". Read more about how the query planner works in this presentation by Neil Conway. (Advanced stuff.)
In PostgreSQL a function is always an automatic transaction. All of it succeeds or nothing. If an exception occurs, everything is rolled back. But there is error handling ...
Here is a somewhat conservative but informative review of the capabilities of PL/pgSQL by the Czech PostgreSQL community. Note that it is a bit outdated by now (written for 8.1) and PL/pgSQL has seen a number of major improvements since.
I have written thousands of plpgsql functions over the years.