Commit c3d583dd authored by Tom Lane's avatar Tom Lane

More updates and copy-editing. Rearrange order of sections a little bit

to put more widely useful info before less widely useful info.
parent 1ade4b33
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/extend.sgml,v 1.28 2004/06/07 04:04:47 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/extend.sgml,v 1.29 2004/12/30 03:13:56 tgl Exp $
--> -->
<chapter id="extend"> <chapter id="extend">
...@@ -152,8 +152,8 @@ $PostgreSQL: pgsql/doc/src/sgml/extend.sgml,v 1.28 2004/06/07 04:04:47 tgl Exp $ ...@@ -152,8 +152,8 @@ $PostgreSQL: pgsql/doc/src/sgml/extend.sgml,v 1.28 2004/06/07 04:04:47 tgl Exp $
<para> <para>
Domains can be created using the <acronym>SQL</> command Domains can be created using the <acronym>SQL</> command
<command>CREATE DOMAIN</command>. Their creation and use is not <xref linkend="sql-createdomain" endterm="sql-createdomain-title">.
discussed in this chapter. Their creation and use is not discussed in this chapter.
</para> </para>
</sect2> </sect2>
...@@ -221,7 +221,7 @@ $PostgreSQL: pgsql/doc/src/sgml/extend.sgml,v 1.28 2004/06/07 04:04:47 tgl Exp $ ...@@ -221,7 +221,7 @@ $PostgreSQL: pgsql/doc/src/sgml/extend.sgml,v 1.28 2004/06/07 04:04:47 tgl Exp $
Thus, when more than one argument position is declared with a polymorphic Thus, when more than one argument position is declared with a polymorphic
type, the net effect is that only certain combinations of actual argument type, the net effect is that only certain combinations of actual argument
types are allowed. For example, a function declared as types are allowed. For example, a function declared as
<literal>foo(anyelement, anyelement)</> will take any two input values, <literal>equal(anyelement, anyelement)</> will take any two input values,
so long as they are of the same data type. so long as they are of the same data type.
</para> </para>
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/postgres.sgml,v 1.71 2004/12/29 23:36:47 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/postgres.sgml,v 1.72 2004/12/30 03:13:56 tgl Exp $
--> -->
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.2//EN" [ <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.2//EN" [
...@@ -192,18 +192,19 @@ $PostgreSQL: pgsql/doc/src/sgml/postgres.sgml,v 1.71 2004/12/29 23:36:47 tgl Exp ...@@ -192,18 +192,19 @@ $PostgreSQL: pgsql/doc/src/sgml/postgres.sgml,v 1.71 2004/12/29 23:36:47 tgl Exp
user-defined functions, data types, triggers, etc. These are user-defined functions, data types, triggers, etc. These are
advanced topics which should probably be approached only after all advanced topics which should probably be approached only after all
the other user documentation about <productname>PostgreSQL</> has the other user documentation about <productname>PostgreSQL</> has
been understood. This part also describes the server-side been understood. Later chapters in this part describe the server-side
programming languages available in the programming languages available in the
<productname>PostgreSQL</productname> distribution as well as <productname>PostgreSQL</productname> distribution as well as
general issues concerning server-side programming languages. This general issues concerning server-side programming languages. It
information is only useful to readers that have read at least the is essential to read at least the earlier sections of <xref
first few chapters of this part. linkend="extend"> (covering functions) before diving into the
material about server-side programming languages.
</para> </para>
</partintro> </partintro>
&extend; &extend;
&rules;
&trigger; &trigger;
&rules;
&xplang; &xplang;
&plsql; &plsql;
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/rules.sgml,v 1.36 2004/11/15 06:32:14 neilc Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/rules.sgml,v 1.37 2004/12/30 03:13:56 tgl Exp $ -->
<Chapter Id="rules"> <Chapter Id="rules">
<Title>The Rule System</Title> <Title>The Rule System</Title>
...@@ -142,7 +142,7 @@ ...@@ -142,7 +142,7 @@
<Para> <Para>
For <command>INSERT</command>, <command>UPDATE</command>, and For <command>INSERT</command>, <command>UPDATE</command>, and
<command>DELETE</command> commands, the result relation is the table <command>DELETE</command> commands, the result relation is the table
(or view!) where the changes take effect. (or view!) where the changes are to take effect.
</Para> </Para>
</ListItem> </ListItem>
</VarListEntry> </VarListEntry>
...@@ -322,7 +322,7 @@ CREATE RULE "_RETURN" AS ON SELECT TO myview DO INSTEAD ...@@ -322,7 +322,7 @@ CREATE RULE "_RETURN" AS ON SELECT TO myview DO INSTEAD
Currently, there can be only one action in an <literal>ON SELECT</> rule, and it must Currently, there can be only one action in an <literal>ON SELECT</> rule, and it must
be an unconditional <command>SELECT</> action that is <literal>INSTEAD</>. This restriction was be an unconditional <command>SELECT</> action that is <literal>INSTEAD</>. This restriction was
required to make rules safe enough to open them for ordinary users, and required to make rules safe enough to open them for ordinary users, and
it restricts <literal>ON SELECT</> rules to real view rules. it restricts <literal>ON SELECT</> rules to act like views.
</Para> </Para>
<Para> <Para>
...@@ -1875,14 +1875,15 @@ GRANT SELECT ON phone_number TO secretary; ...@@ -1875,14 +1875,15 @@ GRANT SELECT ON phone_number TO secretary;
</Para> </Para>
<Para> <Para>
For the things that can be implemented by both, For the things that can be implemented by both, which is best
it depends on the usage of the database, which is the best. depends on the usage of the database.
A trigger is fired for any affected row once. A rule manipulates A trigger is fired for any affected row once. A rule manipulates
the query tree or generates an additional one. So if many the query or generates an additional query. So if many
rows are affected in one statement, a rule issuing one extra rows are affected in one statement, a rule issuing one extra
command would usually do a better job than a trigger that is command is likely to be faster than a trigger that is
called for every single row and must execute its operations called for every single row and must execute its operations
many times. many times. However, the trigger approach is conceptually far
simpler than the rule approach, and is easier for novices to get right.
</Para> </Para>
<Para> <Para>
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/trigger.sgml,v 1.38 2004/12/13 18:05:09 petere Exp $ $PostgreSQL: pgsql/doc/src/sgml/trigger.sgml,v 1.39 2004/12/30 03:13:56 tgl Exp $
--> -->
<chapter id="triggers"> <chapter id="triggers">
...@@ -58,6 +58,15 @@ $PostgreSQL: pgsql/doc/src/sgml/trigger.sgml,v 1.38 2004/12/13 18:05:09 petere E ...@@ -58,6 +58,15 @@ $PostgreSQL: pgsql/doc/src/sgml/trigger.sgml,v 1.38 2004/12/13 18:05:09 petere E
respectively. respectively.
</para> </para>
<para>
Statement-level <quote>before</> triggers naturally fire before the
statement starts to do anything, while statement-level <quote>after</>
triggers fire at the very end of the statement. Row-level <quote>before</>
triggers fire immediately before a particular row is operated on,
while row-level <quote>after</> triggers fire at the end of the statement
(but before any statement-level <quote>after</> triggers).
</para>
<para> <para>
Trigger functions invoked by per-statement triggers should always Trigger functions invoked by per-statement triggers should always
return <symbol>NULL</symbol>. Trigger functions invoked by per-row return <symbol>NULL</symbol>. Trigger functions invoked by per-row
...@@ -110,6 +119,21 @@ $PostgreSQL: pgsql/doc/src/sgml/trigger.sgml,v 1.38 2004/12/13 18:05:09 petere E ...@@ -110,6 +119,21 @@ $PostgreSQL: pgsql/doc/src/sgml/trigger.sgml,v 1.38 2004/12/13 18:05:09 petere E
triggers are not fired. triggers are not fired.
</para> </para>
<para>
Typically, row before triggers are used for checking or
modifying the data that will be inserted or updated. For example,
a before trigger might be used to insert the current time into a
timestamp column, or to check that two elements of the row are
consistent. Row after triggers are most sensibly
used to propagate the updates to other tables, or make consistency
checks against other tables. The reason for this division of labor is
that an after trigger can be certain it is seeing the final value of the
row, while a before trigger cannot; there might be other before triggers
firing after it. If you have no specific reason to make a trigger before
or after, the before case is more efficient, since the information about
the operation doesn't have to be saved until end of statement.
</para>
<para> <para>
If a trigger function executes SQL commands then these If a trigger function executes SQL commands then these
commands may fire triggers again. This is known as cascading commands may fire triggers again. This is known as cascading
...@@ -140,6 +164,20 @@ $PostgreSQL: pgsql/doc/src/sgml/trigger.sgml,v 1.38 2004/12/13 18:05:09 petere E ...@@ -140,6 +164,20 @@ $PostgreSQL: pgsql/doc/src/sgml/trigger.sgml,v 1.38 2004/12/13 18:05:09 petere E
trigger. trigger.
</para> </para>
<para>
Each programming language that supports triggers has its own method
for making the trigger input data available to the trigger function.
This input data includes the type of trigger event (e.g.,
<command>INSERT</command> or <command>UPDATE</command>) as well as any
arguments that were listed in <command>CREATE TRIGGER</>.
For a row-level trigger, the input data also includes the
<varname>NEW</varname> row for <command>INSERT</command> and
<command>UPDATE</command> triggers, and/or the <varname>OLD</varname> row
for <command>UPDATE</command> and <command>DELETE</command> triggers.
Statement-level triggers do not currently have any way to examine the
individual row(s) modified by the statement.
</para>
</sect1> </sect1>
<sect1 id="trigger-datachanges"> <sect1 id="trigger-datachanges">
...@@ -373,7 +411,7 @@ typedef struct TriggerData ...@@ -373,7 +411,7 @@ typedef struct TriggerData
the row being inserted, updated, or deleted. If this trigger the row being inserted, updated, or deleted. If this trigger
was fired for an <command>INSERT</command> or was fired for an <command>INSERT</command> or
<command>DELETE</command> then this is what you should return <command>DELETE</command> then this is what you should return
to from the function if you don't want to replace the row with from the function if you don't want to replace the row with
a different one (in the case of <command>INSERT</command>) or a different one (in the case of <command>INSERT</command>) or
skip the operation. skip the operation.
</para> </para>
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.90 2004/12/13 18:05:09 petere Exp $ $PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.91 2004/12/30 03:13:56 tgl Exp $
--> -->
<sect1 id="xfunc"> <sect1 id="xfunc">
...@@ -24,7 +24,7 @@ $PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.90 2004/12/13 18:05:09 petere Exp ...@@ -24,7 +24,7 @@ $PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.90 2004/12/13 18:05:09 petere Exp
<listitem> <listitem>
<para> <para>
procedural language functions (functions written in, for procedural language functions (functions written in, for
example, <application>PL/Tcl</> or <application>PL/pgSQL</>) example, <application>PL/pgSQL</> or <application>PL/Tcl</>)
(<xref linkend="xfunc-pl">) (<xref linkend="xfunc-pl">)
</para> </para>
</listitem> </listitem>
...@@ -46,7 +46,8 @@ $PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.90 2004/12/13 18:05:09 petere Exp ...@@ -46,7 +46,8 @@ $PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.90 2004/12/13 18:05:09 petere Exp
of function can take base types, composite types, or of function can take base types, composite types, or
combinations of these as arguments (parameters). In addition, combinations of these as arguments (parameters). In addition,
every kind of function can return a base type or every kind of function can return a base type or
a composite type. a composite type. Functions may also be defined to return
sets of base or composite values.
</para> </para>
<para> <para>
...@@ -64,7 +65,8 @@ $PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.90 2004/12/13 18:05:09 petere Exp ...@@ -64,7 +65,8 @@ $PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.90 2004/12/13 18:05:09 petere Exp
<para> <para>
Throughout this chapter, it can be useful to look at the reference Throughout this chapter, it can be useful to look at the reference
page of the <xref linkend="sql-createfunction"> command to page of the <xref linkend="sql-createfunction"
endterm="sql-createfunction-title"> command to
understand the examples better. Some examples from this chapter understand the examples better. Some examples from this chapter
can be found in <filename>funcs.sql</filename> and can be found in <filename>funcs.sql</filename> and
<filename>funcs.c</filename> in the <filename>src/tutorial</> <filename>funcs.c</filename> in the <filename>src/tutorial</>
...@@ -141,7 +143,7 @@ CREATE FUNCTION one() RETURNS integer AS $$ ...@@ -141,7 +143,7 @@ CREATE FUNCTION one() RETURNS integer AS $$
SELECT 1 AS result; SELECT 1 AS result;
$$ LANGUAGE SQL; $$ LANGUAGE SQL;
-- Alternative syntax: -- Alternative syntax for string literal:
CREATE FUNCTION one() RETURNS integer AS ' CREATE FUNCTION one() RETURNS integer AS '
SELECT 1 AS result; SELECT 1 AS result;
' LANGUAGE SQL; ' LANGUAGE SQL;
...@@ -356,15 +358,9 @@ ERROR: function declared to return emp returns varchar instead of text at colum ...@@ -356,15 +358,9 @@ ERROR: function declared to return emp returns varchar instead of text at colum
</para> </para>
<para> <para>
A function that returns a row (composite type) can be used as a table When you call a function that returns a row (composite type) in a
function, as described below. It can also be called in the context SQL expression, you might want only one field (attribute) from its
of an SQL expression, but only when you result. You can do that with syntax like this:
extract a single attribute out of the row or pass the entire row into
another function that accepts the same composite type.
</para>
<para>
This is an example of extracting an attribute out of a row type:
<screen> <screen>
SELECT (new_emp()).name; SELECT (new_emp()).name;
...@@ -374,11 +370,14 @@ SELECT (new_emp()).name; ...@@ -374,11 +370,14 @@ SELECT (new_emp()).name;
None None
</screen> </screen>
We need the extra parentheses to keep the parser from getting confused: The extra parentheses are needed to keep the parser from getting
confused. If you try to do it without them, you get something like this:
<screen> <screen>
SELECT new_emp().name; SELECT new_emp().name;
ERROR: syntax error at or near "." at character 17 ERROR: syntax error at or near "." at character 17
LINE 1: SELECT new_emp().name;
^
</screen> </screen>
</para> </para>
...@@ -412,9 +411,8 @@ SELECT name(emp) AS youngster ...@@ -412,9 +411,8 @@ SELECT name(emp) AS youngster
</para> </para>
<para> <para>
The other way to use a function returning a row result is to declare a Another way to use a function returning a row result is to pass the
second function accepting a row type argument and pass the result to another function that accepts the correct row type as input:
result of the first function to it:
<screen> <screen>
CREATE FUNCTION getname(emp) RETURNS text AS $$ CREATE FUNCTION getname(emp) RETURNS text AS $$
...@@ -428,6 +426,11 @@ SELECT getname(new_emp()); ...@@ -428,6 +426,11 @@ SELECT getname(new_emp());
(1 row) (1 row)
</screen> </screen>
</para> </para>
<para>
Another way to use a function that returns a composite type is to
call it as a table function, as described below.
</para>
</sect2> </sect2>
<sect2> <sect2>
...@@ -469,7 +472,7 @@ SELECT *, upper(fooname) FROM getfoo(1) AS t1; ...@@ -469,7 +472,7 @@ SELECT *, upper(fooname) FROM getfoo(1) AS t1;
<para> <para>
Note that we only got one row out of the function. This is because Note that we only got one row out of the function. This is because
we did not use <literal>SETOF</>. This is described in the next section. we did not use <literal>SETOF</>. That is described in the next section.
</para> </para>
</sect2> </sect2>
...@@ -598,7 +601,7 @@ ERROR: could not determine "anyarray"/"anyelement" type because input has type ...@@ -598,7 +601,7 @@ ERROR: could not determine "anyarray"/"anyelement" type because input has type
</para> </para>
<para> <para>
It is permitted to have polymorphic arguments with a deterministic It is permitted to have polymorphic arguments with a fixed
return type, but the converse is not. For example: return type, but the converse is not. For example:
<screen> <screen>
CREATE FUNCTION is_greater(anyelement, anyelement) RETURNS boolean AS $$ CREATE FUNCTION is_greater(anyelement, anyelement) RETURNS boolean AS $$
...@@ -621,6 +624,201 @@ DETAIL: A function returning "anyarray" or "anyelement" must have at least one ...@@ -621,6 +624,201 @@ DETAIL: A function returning "anyarray" or "anyelement" must have at least one
</sect2> </sect2>
</sect1> </sect1>
<sect1 id="xfunc-overload">
<title>Function Overloading</title>
<indexterm zone="xfunc-overload">
<primary>overloading</primary>
<secondary>functions</secondary>
</indexterm>
<para>
More than one function may be defined with the same SQL name, so long
as the arguments they take are different. In other words,
function names can be <firstterm>overloaded</firstterm>. When a
query is executed, the server will determine which function to
call from the data types and the number of the provided arguments.
Overloading can also be used to simulate functions with a variable
number of arguments, up to a finite maximum number.
</para>
<para>
When creating a family of overloaded functions, one should be
careful not to create ambiguities. For instance, given the
functions
<programlisting>
CREATE FUNCTION test(int, real) RETURNS ...
CREATE FUNCTION test(smallint, double precision) RETURNS ...
</programlisting>
it is not immediately clear which function would be called with
some trivial input like <literal>test(1, 1.5)</literal>. The
currently implemented resolution rules are described in
<xref linkend="typeconv">, but it is unwise to design a system that subtly
relies on this behavior.
</para>
<para>
A function that takes a single argument of a composite type should
generally not have the same name as any attribute (field) of that type.
Recall that <literal>attribute(table)</literal> is considered equivalent
to <literal>table.attribute</literal>. In the case that there is an
ambiguity between a function on a composite type and an attribute of
the composite type, the attribute will always be used. It is possible
to override that choice by schema-qualifying the function name
(that is, <literal>schema.func(table)</literal>) but it's better to
avoid the problem by not choosing conflicting names.
</para>
<para>
When overloading C-language functions, there is an additional
constraint: The C name of each function in the family of
overloaded functions must be different from the C names of all
other functions, either internal or dynamically loaded. If this
rule is violated, the behavior is not portable. You might get a
run-time linker error, or one of the functions will get called
(usually the internal one). The alternative form of the
<literal>AS</> clause for the SQL <command>CREATE
FUNCTION</command> command decouples the SQL function name from
the function name in the C source code. For instance,
<programlisting>
CREATE FUNCTION test(int) RETURNS int
AS '<replaceable>filename</>', 'test_1arg'
LANGUAGE C;
CREATE FUNCTION test(int, int) RETURNS int
AS '<replaceable>filename</>', 'test_2arg'
LANGUAGE C;
</programlisting>
The names of the C functions here reflect one of many possible conventions.
</para>
</sect1>
<sect1 id="xfunc-volatility">
<title>Function Volatility Categories</title>
<indexterm zone="xfunc-volatility">
<primary>volatility</primary>
<secondary>functions</secondary>
</indexterm>
<para>
Every function has a <firstterm>volatility</> classification, with
the possibilities being <literal>VOLATILE</>, <literal>STABLE</>, or
<literal>IMMUTABLE</>. <literal>VOLATILE</> is the default if the
<command>CREATE FUNCTION</command> command does not specify a category.
The volatility category is a promise to the optimizer about the behavior
of the function:
<itemizedlist>
<listitem>
<para>
A <literal>VOLATILE</> function can do anything, including modifying
the database. It can return different results on successive calls with
the same arguments. The optimizer makes no assumptions about the
behavior of such functions. A query using a volatile function will
re-evaluate the function at every row where its value is needed.
</para>
</listitem>
<listitem>
<para>
A <literal>STABLE</> function cannot modify the database and is
guaranteed to return the same results given the same arguments
for all calls within a single surrounding query. This category
allows the optimizer to optimize away multiple calls of the function
within a single query. In particular, it is safe to use an expression
containing such a function in an index scan condition. (Since an
index scan will evaluate the comparison value only once, not once at
each row, it is not valid to use a <literal>VOLATILE</> function in
an index scan condition.)
</para>
</listitem>
<listitem>
<para>
An <literal>IMMUTABLE</> function cannot modify the database and is
guaranteed to return the same results given the same arguments forever.
This category allows the optimizer to pre-evaluate the function when
a query calls it with constant arguments. For example, a query like
<literal>SELECT ... WHERE x = 2 + 2</> can be simplified on sight to
<literal>SELECT ... WHERE x = 4</>, because the function underlying
the integer addition operator is marked <literal>IMMUTABLE</>.
</para>
</listitem>
</itemizedlist>
</para>
<para>
For best optimization results, you should label your functions with the
strictest volatility category that is valid for them.
</para>
<para>
Any function with side-effects <emphasis>must</> be labeled
<literal>VOLATILE</>, so that calls to it cannot be optimized away.
Even a function with no side-effects needs to be labeled
<literal>VOLATILE</> if its value can change within a single query;
some examples are <literal>random()</>, <literal>currval()</>,
<literal>timeofday()</>.
</para>
<para>
There is relatively little difference between <literal>STABLE</> and
<literal>IMMUTABLE</> categories when considering simple interactive
queries that are planned and immediately executed: it doesn't matter
a lot whether a function is executed once during planning or once during
query execution startup. But there is a big difference if the plan is
saved and reused later. Labeling a function <literal>IMMUTABLE</> when
it really isn't may allow it to be prematurely folded to a constant during
planning, resulting in a stale value being re-used during subsequent uses
of the plan. This is a hazard when using prepared statements or when
using function languages that cache plans (such as
<application>PL/pgSQL</>).
</para>
<para>
Because of the snapshotting behavior of MVCC (see <xref linkend="mvcc">)
a function containing only <command>SELECT</> commands can safely be
marked <literal>STABLE</>, even if it selects from tables that might be
undergoing modifications by concurrent queries.
<productname>PostgreSQL</productname> will execute a <literal>STABLE</>
function using the snapshot established for the calling query, and so it
will see a fixed view of the database throughout that query.
Also note
that the <function>current_timestamp</> family of functions qualify
as stable, since their values do not change within a transaction.
</para>
<para>
The same snapshotting behavior is used for <command>SELECT</> commands
within <literal>IMMUTABLE</> functions. It is generally unwise to select
from database tables within an <literal>IMMUTABLE</> function at all,
since the immutability will be broken if the table contents ever change.
However, <productname>PostgreSQL</productname> does not enforce that you
do not do that.
</para>
<para>
A common error is to label a function <literal>IMMUTABLE</> when its
results depend on a configuration parameter. For example, a function
that manipulates timestamps might well have results that depend on the
<xref linkend="guc-timezone"> setting. For safety, such functions should
be labeled <literal>STABLE</> instead.
</para>
<note>
<para>
Before <productname>PostgreSQL</productname> release 8.0, the requirement
that <literal>STABLE</> and <literal>IMMUTABLE</> functions cannot modify
the database was not enforced by the system. Release 8.0 enforces it
by requiring SQL functions and procedural language functions of these
categories to contain no SQL commands other than <command>SELECT</>.
(This is not a completely bulletproof test, since such functions could
still call <literal>VOLATILE</> functions that modify the database.
If you do that, you will find that the <literal>STABLE</> or
<literal>IMMUTABLE</> function does not notice the database changes
applied by the called function.)
</para>
</note>
</sect1>
<sect1 id="xfunc-pl"> <sect1 id="xfunc-pl">
<title>Procedural Language Functions</title> <title>Procedural Language Functions</title>
...@@ -1618,7 +1816,7 @@ concat_text(PG_FUNCTION_ARGS) ...@@ -1618,7 +1816,7 @@ concat_text(PG_FUNCTION_ARGS)
&dfunc; &dfunc;
<sect2 id="xfunc-c-pgxs"> <sect2 id="xfunc-c-pgxs">
<title>Extension build infrastructure</title> <title>Extension Building Infrastructure</title>
<indexterm zone="xfunc-c-pgxs"> <indexterm zone="xfunc-c-pgxs">
<primary>pgxs</primary> <primary>pgxs</primary>
...@@ -1868,14 +2066,14 @@ c_overpaid(PG_FUNCTION_ARGS) ...@@ -1868,14 +2066,14 @@ c_overpaid(PG_FUNCTION_ARGS)
HeapTupleHeader t = PG_GETARG_HEAPTUPLEHEADER(0); HeapTupleHeader t = PG_GETARG_HEAPTUPLEHEADER(0);
int32 limit = PG_GETARG_INT32(1); int32 limit = PG_GETARG_INT32(1);
bool isnull; bool isnull;
int32 salary; Datum salary;
salary = DatumGetInt32(GetAttributeByName(t, "salary", &amp;isnull)); salary = GetAttributeByName(t, "salary", &amp;isnull);
if (isnull) if (isnull)
PG_RETURN_BOOL(false); PG_RETURN_BOOL(false);
/* Alternatively, we might prefer to do PG_RETURN_NULL() for null salary. */ /* Alternatively, we might prefer to do PG_RETURN_NULL() for null salary. */
PG_RETURN_BOOL(salary &gt; limit); PG_RETURN_BOOL(DatumGetInt32(salary) &gt; limit);
} }
</programlisting> </programlisting>
</para> </para>
...@@ -1890,7 +2088,10 @@ c_overpaid(PG_FUNCTION_ARGS) ...@@ -1890,7 +2088,10 @@ c_overpaid(PG_FUNCTION_ARGS)
return parameter that tells whether the attribute return parameter that tells whether the attribute
is null. <function>GetAttributeByName</function> returns a <type>Datum</type> is null. <function>GetAttributeByName</function> returns a <type>Datum</type>
value that you can convert to the proper data type by using the value that you can convert to the proper data type by using the
appropriate <function>DatumGet<replaceable>XXX</replaceable>()</function> macro. appropriate <function>DatumGet<replaceable>XXX</replaceable>()</function>
macro. Note that the return value is meaningless if the null flag is
set; always check the null flag before trying to do anything with the
result.
</para> </para>
<para> <para>
...@@ -2393,196 +2594,6 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray ...@@ -2393,196 +2594,6 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray
</sect2> </sect2>
</sect1> </sect1>
<sect1 id="xfunc-overload">
<title>Function Overloading</title>
<indexterm zone="xfunc-overload">
<primary>overloading</primary>
<secondary>functions</secondary>
</indexterm>
<para>
More than one function may be defined with the same SQL name, so long
as the arguments they take are different. In other words,
function names can be <firstterm>overloaded</firstterm>. When a
query is executed, the server will determine which function to
call from the data types and the number of the provided arguments.
Overloading can also be used to simulate functions with a variable
number of arguments, up to a finite maximum number.
</para>
<para>
When creating a family of overloaded functions, one should be
careful not to create ambiguities. For instance, given the
functions
<programlisting>
CREATE FUNCTION test(int, real) RETURNS ...
CREATE FUNCTION test(smallint, double precision) RETURNS ...
</programlisting>
it is not immediately clear which function would be called with
some trivial input like <literal>test(1, 1.5)</literal>. The
currently implemented resolution rules are described in
<xref linkend="typeconv">, but it is unwise to design a system that subtly
relies on this behavior.
</para>
<para>
A function that takes a single argument of a composite type should
generally not have the same name as any attribute (field) of that type.
Recall that <literal>attribute(table)</literal> is considered equivalent
to <literal>table.attribute</literal>. In the case that there is an
ambiguity between a function on a composite type and an attribute of
the composite type, the attribute will always be used. It is possible
to override that choice by schema-qualifying the function name
(that is, <literal>schema.func(table)</literal>) but it's better to
avoid the problem by not choosing conflicting names.
</para>
<para>
When overloading C-language functions, there is an additional
constraint: The C name of each function in the family of
overloaded functions must be different from the C names of all
other functions, either internal or dynamically loaded. If this
rule is violated, the behavior is not portable. You might get a
run-time linker error, or one of the functions will get called
(usually the internal one). The alternative form of the
<literal>AS</> clause for the SQL <command>CREATE
FUNCTION</command> command decouples the SQL function name from
the function name in the C source code. For instance,
<programlisting>
CREATE FUNCTION test(int) RETURNS int
AS '<replaceable>filename</>', 'test_1arg'
LANGUAGE C;
CREATE FUNCTION test(int, int) RETURNS int
AS '<replaceable>filename</>', 'test_2arg'
LANGUAGE C;
</programlisting>
The names of the C functions here reflect one of many possible conventions.
</para>
</sect1>
<sect1 id="xfunc-volatility">
<title>Function Volatility Categories</title>
<indexterm zone="xfunc-volatility">
<primary>volatility</primary>
<secondary>functions</secondary>
</indexterm>
<para>
Every function has a <firstterm>volatility</> classification, with
the possibilities being <literal>VOLATILE</>, <literal>STABLE</>, or
<literal>IMMUTABLE</>. <literal>VOLATILE</> is the default if the
<command>CREATE FUNCTION</command> command does not specify a category.
The volatility category is a promise to the optimizer about the behavior
of the function:
<itemizedlist>
<listitem>
<para>
A <literal>VOLATILE</> function can do anything, including modifying
the database. It can return different results on successive calls with
the same arguments. The optimizer makes no assumptions about the
behavior of such functions. A query using a volatile function will
re-evaluate the function at every row where its value is needed.
</para>
</listitem>
<listitem>
<para>
A <literal>STABLE</> function cannot modify the database and is
guaranteed to return the same results given the same arguments
for all calls within a single surrounding query. This category
allows the optimizer to optimize away multiple calls of the function
within a single query. In particular, it is safe to use an expression
containing such a function in an index scan condition. (Since an
index scan will evaluate the comparison value only once, not once at
each row, it is not valid to use a <literal>VOLATILE</> function in
an index scan condition.)
</para>
</listitem>
<listitem>
<para>
An <literal>IMMUTABLE</> function cannot modify the database and is
guaranteed to return the same results given the same arguments forever.
This category allows the optimizer to pre-evaluate the function when
a query calls it with constant arguments. For example, a query like
<literal>SELECT ... WHERE x = 2 + 2</> can be simplified on sight to
<literal>SELECT ... WHERE x = 4</>, because the function underlying
the integer addition operator is marked <literal>IMMUTABLE</>.
</para>
</listitem>
</itemizedlist>
</para>
<para>
For best optimization results, you should label your functions with the
strictest volatility category that is valid for them.
</para>
<para>
Any function with side-effects <emphasis>must</> be labeled
<literal>VOLATILE</>, so that calls to it cannot be optimized away.
Even a function with no side-effects needs to be labeled
<literal>VOLATILE</> if its value can change within a single query;
some examples are <literal>random()</>, <literal>currval()</>,
<literal>timeofday()</>.
</para>
<para>
There is relatively little difference between <literal>STABLE</> and
<literal>IMMUTABLE</> categories when considering simple interactive
queries that are planned and immediately executed: it doesn't matter
a lot whether a function is executed once during planning or once during
query execution startup. But there is a big difference if the plan is
saved and reused later. Labeling a function <literal>IMMUTABLE</> when
it really isn't may allow it to be prematurely folded to a constant during
planning, resulting in a stale value being re-used during subsequent uses
of the plan. This is a hazard when using prepared statements or when
using function languages that cache plans (such as
<application>PL/pgSQL</>).
</para>
<para>
Because of the snapshotting behavior of MVCC (see <xref linkend="mvcc">)
a function containing only <command>SELECT</> commands can safely be
marked <literal>STABLE</>, even if it selects from tables that might be
undergoing modifications by concurrent queries.
<productname>PostgreSQL</productname> will execute a <literal>STABLE</>
function using the snapshot established for the calling query, and so it
will see a fixed view of the database throughout that query.
Also note
that the <function>current_timestamp</> family of functions qualify
as stable, since their values do not change within a transaction.
</para>
<para>
The same snapshotting behavior is used for <command>SELECT</> commands
within <literal>IMMUTABLE</> functions. It is generally unwise to select
from database tables within an <literal>IMMUTABLE</> function at all,
since the immutability will be broken if the table contents ever change.
However, <productname>PostgreSQL</productname> does not enforce that you
do not do that.
</para>
<para>
A common error is to label a function <literal>IMMUTABLE</> when its
results depend on a configuration parameter. For example, a function
that manipulates timestamps might well have results that depend on the
<xref linkend="guc-timezone"> setting. For safety, such functions should
be labeled <literal>STABLE</> instead.
</para>
<note>
<para>
Before <productname>PostgreSQL</productname> release 8.0, the requirement
that <literal>STABLE</> and <literal>IMMUTABLE</> functions cannot modify
the database was not enforced by the system. Release 8.0 enforces it
by requiring SQL functions and procedural language functions of these
categories to contain no SQL commands other than <command>SELECT</>.
</para>
</note>
</sect1>
<!-- Keep this comment at the end of the file <!-- Keep this comment at the end of the file
Local variables: Local variables:
mode:sgml mode:sgml
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/xplang.sgml,v 1.26 2003/11/29 19:51:38 pgsql Exp $ $PostgreSQL: pgsql/doc/src/sgml/xplang.sgml,v 1.27 2004/12/30 03:13:56 tgl Exp $
--> -->
<chapter id="xplang"> <chapter id="xplang">
...@@ -29,10 +29,16 @@ $PostgreSQL: pgsql/doc/src/sgml/xplang.sgml,v 1.26 2003/11/29 19:51:38 pgsql Exp ...@@ -29,10 +29,16 @@ $PostgreSQL: pgsql/doc/src/sgml/xplang.sgml,v 1.26 2003/11/29 19:51:38 pgsql Exp
<para> <para>
Writing a handler for a new procedural language is described in Writing a handler for a new procedural language is described in
<xref linkend="plhandler">. Several procedural languages are <xref linkend="plhandler">. Several procedural languages are
available in the standard <productname>PostgreSQL</productname> available in the core <productname>PostgreSQL</productname>
distribution, which can serve as examples. distribution, which can serve as examples.
</para> </para>
<para>
There are additional procedural languages available that are not
included in the core distribution. <xref linkend="external-projects">
has information about finding them.
</para>
<sect1 id="xplang-install"> <sect1 id="xplang-install">
<title>Installing Procedural Languages</title> <title>Installing Procedural Languages</title>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment