mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-03-07 19:47:50 +08:00
Editorial work on xfunc chapter --- better explanations about SQL
functions handling composite types and sets, various minor cleanups.
This commit is contained in:
parent
b93939a6a7
commit
62651c0176
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/dfunc.sgml,v 1.14 2001/05/19 09:01:10 petere Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/dfunc.sgml,v 1.15 2001/10/26 19:58:12 tgl Exp $
|
||||
-->
|
||||
|
||||
<sect2 id="dfunc">
|
||||
@ -7,9 +7,9 @@ $Header: /cvsroot/pgsql/doc/src/sgml/dfunc.sgml,v 1.14 2001/05/19 09:01:10 peter
|
||||
|
||||
<para>
|
||||
Before you are able to use your
|
||||
<productname>PostgreSQL</productname> extension function written in
|
||||
C they need to be compiled and linked in a special way in order to
|
||||
allow it to be dynamically loaded as needed by the server. To be
|
||||
<productname>PostgreSQL</productname> extension functions written in
|
||||
C, they must be compiled and linked in a special way to produce a file
|
||||
that can be dynamically loaded by the server. To be
|
||||
precise, a <firstterm>shared library</firstterm> needs to be created.
|
||||
</para>
|
||||
|
||||
@ -31,7 +31,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/dfunc.sgml,v 1.14 2001/05/19 09:01:10 peter
|
||||
be created as <firstterm>position-independent code</firstterm>
|
||||
(<acronym>PIC</acronym>), which conceptually means that they can be
|
||||
placed at an arbitrary location in memory when they are loaded by the
|
||||
executable. (Object files intended for executables are not compiled
|
||||
executable. (Object files intended for executables are usually not compiled
|
||||
that way.) The command to link a shared library contains special
|
||||
flags to distinguish it from linking an executable. --- At least
|
||||
this is the theory. On some systems the practice is much uglier.
|
||||
@ -263,16 +263,14 @@ gcc -shared -o foo.so foo.o
|
||||
The resulting shared library file can then be loaded into
|
||||
<productname>Postgres</productname>. When specifying the file name
|
||||
to the <command>CREATE FUNCTION</command> command, one must give it
|
||||
the name of the shared library file (ending in
|
||||
<filename>.so</filename>) rather than the intermediate object file.
|
||||
|
||||
<note>
|
||||
<para>
|
||||
Actually, <productname>Postgres</productname> does not care what
|
||||
you name the file as long as it is a shared library file.
|
||||
</para>
|
||||
</note>
|
||||
the name of the shared library file, not the intermediate object file.
|
||||
Note that the system's standard shared-library extension (usually
|
||||
<literal>.so</literal> or <literal>.sl</literal>) can be omitted from
|
||||
the <command>CREATE FUNCTION</command> command, and normally should
|
||||
be omitted for best portability.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Refer back to <xref linkend="xfunc-c-dynload"> about where the
|
||||
server expects to find the shared library files.
|
||||
</para>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/load.sgml,v 1.9 2001/09/03 12:57:50 petere Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/load.sgml,v 1.10 2001/10/26 19:58:12 tgl Exp $
|
||||
-->
|
||||
|
||||
<refentry id="SQL-LOAD">
|
||||
@ -10,7 +10,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/ref/load.sgml,v 1.9 2001/09/03 12:57:50 pet
|
||||
|
||||
<refnamediv>
|
||||
<refname>LOAD</refname>
|
||||
<refpurpose>load or reload a shared object file</refpurpose>
|
||||
<refpurpose>load or reload a shared library file</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv>
|
||||
@ -23,13 +23,22 @@ LOAD '<replaceable class="PARAMETER">filename</replaceable>'
|
||||
<title>Description</title>
|
||||
|
||||
<para>
|
||||
Loads a shared object file into the PostgreSQL backend's address
|
||||
Loads a shared library file into the PostgreSQL backend's address
|
||||
space. If the file had been loaded previously, it is first
|
||||
unloaded. This command is primarily useful to unload and reload a
|
||||
shared object file if it has been changed. To make use of the
|
||||
shared object, a function needs to be declared using the <xref
|
||||
shared library file that has been changed since the backend first
|
||||
loaded it. To make use of the
|
||||
shared library, function(s) in it need to be declared using the <xref
|
||||
linkend="sql-createfunction"> command.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The filename is specified in the same way as for shared library
|
||||
names in <xref linkend="sql-createfunction">; in particular, one
|
||||
may rely on a search path and automatic addition of the system's standard
|
||||
shared library filename extension. See the
|
||||
<citetitle>Programmer's Guide</citetitle> for more detail.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1 id="sql-load-compat">
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.38 2001/09/16 16:11:09 petere Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.39 2001/10/26 19:58:12 tgl Exp $
|
||||
-->
|
||||
|
||||
<chapter id="xfunc">
|
||||
@ -72,19 +72,30 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.38 2001/09/16 16:11:09 peter
|
||||
|
||||
<para>
|
||||
SQL functions execute an arbitrary list of SQL statements, returning
|
||||
the results of the last query in the list. SQL functions in general
|
||||
return sets. If their returntype is not specified as a
|
||||
<literal>SETOF</literal>,
|
||||
then an arbitrary element of the last query's result will be returned.
|
||||
the results of the last query in the list. In the simple (non-set)
|
||||
case, the first row of the last query's result will be returned.
|
||||
(Bear in mind that <quote>the first row</quote> is not well-defined
|
||||
unless you use <literal>ORDER BY</>.) If the last query happens
|
||||
to return no rows at all, NULL will be returned.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Alternatively, an SQL function may be declared to return a set,
|
||||
by specifying the function's return type
|
||||
as <literal>SETOF</literal> <replaceable>sometype</>. In this case
|
||||
all rows of the last query's result are returned. Further details
|
||||
appear below.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The body of an SQL function should be a list of one or more SQL
|
||||
statements separated by semicolons. Note that because the syntax
|
||||
of the <command>CREATE FUNCTION</command> requires the body of the
|
||||
function to be enclosed in single quotes, single quote marks used
|
||||
of the <command>CREATE FUNCTION</command> command requires the body of the
|
||||
function to be enclosed in single quotes, single quote marks
|
||||
(<literal>'</>) used
|
||||
in the body of the function must be escaped, by writing two single
|
||||
quotes where one is desired.
|
||||
quotes (<literal>''</>) or a backslash (<literal>\'</>) where each
|
||||
quote is desired.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -93,7 +104,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.38 2001/09/16 16:11:09 peter
|
||||
the first argument, $2 to the second, and so on. If an argument
|
||||
is of a composite type, then the <quote>dot notation</quote>,
|
||||
e.g., <literal>$1.emp</literal>, may be used to access attributes
|
||||
of the argument or to invoke functions.
|
||||
of the argument.
|
||||
</para>
|
||||
|
||||
<sect2>
|
||||
@ -104,11 +115,11 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.38 2001/09/16 16:11:09 peter
|
||||
which might be used to debit a bank account:
|
||||
|
||||
<programlisting>
|
||||
CREATE FUNCTION tp1 (integer, double precision) RETURNS integer AS '
|
||||
CREATE FUNCTION tp1 (integer, numeric) RETURNS integer AS '
|
||||
UPDATE bank
|
||||
SET balance = bank.balance - $2
|
||||
WHERE bank.acctountno = $1;
|
||||
SELECT 1;
|
||||
SET balance = balance - $2
|
||||
WHERE accountno = $1;
|
||||
SELECT 1;
|
||||
' LANGUAGE SQL;
|
||||
</programlisting>
|
||||
|
||||
@ -121,16 +132,47 @@ SELECT tp1(17, 100.0);
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The following more interesting example takes a single argument of
|
||||
type <type>EMP</type>, which is really a table that contains data
|
||||
about employees, and retrieves multiple results:
|
||||
In practice one would probably like a more useful result from the
|
||||
function than a constant <quote>1</>, so a more likely definition
|
||||
is
|
||||
|
||||
<programlisting>
|
||||
CREATE FUNCTION hobbies (EMP) RETURNS SETOF hobbies AS '
|
||||
SELECT hobbies.* FROM hobbies
|
||||
WHERE $1.name = hobbies.person
|
||||
CREATE FUNCTION tp1 (integer, numeric) RETURNS numeric AS '
|
||||
UPDATE bank
|
||||
SET balance = balance - $2
|
||||
WHERE accountno = $1;
|
||||
SELECT balance FROM bank WHERE accountno = $1;
|
||||
' LANGUAGE SQL;
|
||||
</programlisting>
|
||||
|
||||
which adjusts the balance and returns the new balance.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Any collection of commands in the <acronym>SQL</acronym>
|
||||
language can be packaged together and defined as a function.
|
||||
The commands can include data modification (i.e.,
|
||||
<command>INSERT</command>, <command>UPDATE</command>, and
|
||||
<command>DELETE</command>) as well
|
||||
as <command>SELECT</command> queries. However, the final command
|
||||
must be a <command>SELECT</command> that returns whatever is
|
||||
specified as the function's return type.
|
||||
|
||||
<programlisting>
|
||||
CREATE FUNCTION clean_EMP () RETURNS integer AS '
|
||||
DELETE FROM EMP
|
||||
WHERE EMP.salary <= 0;
|
||||
SELECT 1 AS ignore_this;
|
||||
' LANGUAGE SQL;
|
||||
|
||||
SELECT clean_EMP();
|
||||
</programlisting>
|
||||
|
||||
<screen>
|
||||
x
|
||||
---
|
||||
1
|
||||
</screen>
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
@ -146,21 +188,21 @@ CREATE FUNCTION one() RETURNS integer AS '
|
||||
SELECT 1 as RESULT;
|
||||
' LANGUAGE SQL;
|
||||
|
||||
SELECT one() AS answer;
|
||||
SELECT one();
|
||||
</programlisting>
|
||||
|
||||
<screen>
|
||||
answer
|
||||
--------
|
||||
1
|
||||
one
|
||||
-----
|
||||
1
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Notice that we defined a column alias within the function body for the result of the function
|
||||
(with the name <literal>RESULT</>), but this column alias is not visible
|
||||
outside the function. Hence, the result is labelled <literal>answer</>
|
||||
instead of <literal>one</>.
|
||||
outside the function. Hence, the result is labelled <literal>one</>
|
||||
instead of <literal>RESULT</>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -190,10 +232,12 @@ SELECT add_em(1, 2) AS answer;
|
||||
|
||||
<para>
|
||||
When specifying functions with arguments of composite
|
||||
types (such as <type>EMP</type>), we must not only specify which
|
||||
types, we must not only specify which
|
||||
argument we want (as we did above with <literal>$1</> and <literal>$2</literal>) but
|
||||
also the attributes of that argument. For example,
|
||||
take the function <function>double_salary</function> that computes what your
|
||||
also the attributes of that argument. For example, suppose that
|
||||
<type>EMP</type> is a table containing employee data, and therefore
|
||||
also the name of the composite type of each row of the table. Here
|
||||
is a function <function>double_salary</function> that computes what your
|
||||
salary would be if it were doubled:
|
||||
|
||||
<programlisting>
|
||||
@ -214,12 +258,83 @@ SELECT name, double_salary(EMP) AS dream
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Notice the use of the syntax <literal>$1.salary</literal>.
|
||||
Before launching into the subject of functions that
|
||||
return composite types, we must first introduce the
|
||||
Notice the use of the syntax <literal>$1.salary</literal>
|
||||
to select one field of the argument row value. Also notice
|
||||
how the calling SELECT command uses a table name to denote
|
||||
the entire current row of that table as a composite value.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
It is also possible to build a function that returns a composite type.
|
||||
(However, as we'll see below, there are some
|
||||
unfortunate restrictions on how the function may be used.)
|
||||
This is an example of a function
|
||||
that returns a single <type>EMP</type> row:
|
||||
|
||||
<programlisting>
|
||||
CREATE FUNCTION new_emp() RETURNS EMP AS '
|
||||
SELECT text ''None'' AS name,
|
||||
1000 AS salary,
|
||||
25 AS age,
|
||||
point ''(2,2)'' AS cubicle;
|
||||
' LANGUAGE SQL;
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In this case we have specified each of the attributes
|
||||
with a constant value, but any computation or expression
|
||||
could have been substituted for these constants.
|
||||
Note two important things about defining the function:
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
The target list order must be exactly the same as
|
||||
that in which the columns appear in the table associated
|
||||
with the composite type.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
You must typecast the expressions to match the
|
||||
definition of the composite type, or you will get errors like this:
|
||||
<screen>
|
||||
<computeroutput>
|
||||
ERROR: function declared to return emp returns varchar instead of text at column 1
|
||||
</computeroutput>
|
||||
</screen>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In the present release of <productname>PostgreSQL</productname>
|
||||
there are some unpleasant restrictions on how functions returning
|
||||
composite types can be used. Briefly, when calling a function that
|
||||
returns a row, we cannot retrieve the entire row. We must either
|
||||
project a single attribute out of the row or pass the entire row into
|
||||
another function. (Trying to display the entire row value will yield
|
||||
a meaningless number.) For example,
|
||||
|
||||
<programlisting>
|
||||
SELECT name(new_emp());
|
||||
</programlisting>
|
||||
|
||||
<screen>
|
||||
name
|
||||
------
|
||||
None
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This example makes use of the
|
||||
function notation for projecting attributes. The simple way
|
||||
to explain this is that we can usually use the
|
||||
notations <literal>attribute(table)</> and <literal>table.attribute</> interchangably:
|
||||
notations <literal>attribute(table)</> and <literal>table.attribute</>
|
||||
interchangeably:
|
||||
|
||||
<programlisting>
|
||||
--
|
||||
@ -239,108 +354,96 @@ SELECT name(EMP) AS youngster
|
||||
</para>
|
||||
|
||||
<para>
|
||||
As we shall see, however, this is not always the case.
|
||||
This function notation is important when we want to use
|
||||
a function that returns a single row. We do this
|
||||
by assembling the entire row within the function,
|
||||
attribute by attribute. This is an example of a function
|
||||
that returns a single <type>EMP</type> row:
|
||||
|
||||
<programlisting>
|
||||
CREATE FUNCTION new_emp() RETURNS EMP AS '
|
||||
SELECT text ''None'' AS name,
|
||||
1000 AS salary,
|
||||
25 AS age,
|
||||
point ''(2,2)'' AS cubicle;
|
||||
' LANGUAGE SQL;
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In this case we have specified each of the attributes
|
||||
with a constant value, but any computation or expression
|
||||
could have been substituted for these constants.
|
||||
Defining a function like this can be tricky. Some of
|
||||
the more important caveats are as follows:
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
The target list order must be exactly the same as
|
||||
that in which the attributes appear in the <command>CREATE
|
||||
TABLE</command> statement that defined the table underlying the composite type.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
You must typecast the expressions to match the
|
||||
definition of the composite type, or you will get errors like this:
|
||||
<screen>
|
||||
<computeroutput>
|
||||
ERROR: function declared to return emp returns varchar instead of text at column 1
|
||||
</computeroutput>
|
||||
</screen>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
When calling a function that returns a row, we
|
||||
cannot retrieve the entire row. We must either
|
||||
project an attribute out of the row or pass the
|
||||
entire row into another function.
|
||||
|
||||
<programlisting>
|
||||
SELECT name(new_emp()) AS nobody;
|
||||
</programlisting>
|
||||
|
||||
<screen>
|
||||
nobody
|
||||
--------
|
||||
None
|
||||
</screen>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The reason why, in general, we must use the function
|
||||
syntax for projecting attributes of function return
|
||||
values is that the parser just doesn't understand
|
||||
the other (dot) syntax for projection when combined
|
||||
the dot syntax for projection when combined
|
||||
with function calls.
|
||||
|
||||
<screen>
|
||||
SELECT new_emp().name AS nobody;
|
||||
NOTICE:parser: syntax error at or near "."
|
||||
ERROR: parser: parse error at or near "."
|
||||
</screen>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Any collection of commands in the <acronym>SQL</acronym>
|
||||
language can be packaged together and defined as a function.
|
||||
The commands can include data modification (i.e.,
|
||||
<command>INSERT</command>, <command>UPDATE</command>, and
|
||||
<command>DELETE</command>) as well
|
||||
as <command>SELECT</command> queries. However, the final command
|
||||
must be a <command>SELECT</command> that returns whatever is
|
||||
specified as the function's return type.
|
||||
Another way to use a function returning a row result is to declare a
|
||||
second function accepting a rowtype parameter, and pass the function
|
||||
result to it:
|
||||
|
||||
<programlisting>
|
||||
CREATE FUNCTION clean_EMP () RETURNS integer AS '
|
||||
DELETE FROM EMP
|
||||
WHERE EMP.salary <= 0;
|
||||
SELECT 1 AS ignore_this;
|
||||
' LANGUAGE SQL;
|
||||
|
||||
SELECT clean_EMP();
|
||||
CREATE FUNCTION getname(emp) RETURNS text AS
|
||||
'SELECT $1.name;'
|
||||
LANGUAGE SQL;
|
||||
</programlisting>
|
||||
|
||||
<screen>
|
||||
x
|
||||
---
|
||||
1
|
||||
SELECT getname(new_emp());
|
||||
getname
|
||||
---------
|
||||
None
|
||||
(1 row)
|
||||
</screen>
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title><acronym>SQL</acronym> Functions Returning Sets</title>
|
||||
|
||||
<para>
|
||||
As previously mentioned, an SQL function may be declared as
|
||||
returning <literal>SETOF</literal> <replaceable>sometype</>.
|
||||
In this case the function's final SELECT query is executed to
|
||||
completion, and each row it outputs is returned as an element
|
||||
of the set.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Functions returning sets may only be called in the target list
|
||||
of a SELECT query. For each row that the SELECT generates by itself,
|
||||
the function returning set is invoked, and an output row is generated
|
||||
for each element of the function's result set. An example:
|
||||
|
||||
<programlisting>
|
||||
CREATE FUNCTION listchildren(text) RETURNS SETOF text AS
|
||||
'SELECT name FROM nodes WHERE parent = $1'
|
||||
LANGUAGE SQL;
|
||||
</programlisting>
|
||||
|
||||
<screen>
|
||||
SELECT * FROM nodes;
|
||||
name | parent
|
||||
-----------+--------
|
||||
Top |
|
||||
Child1 | Top
|
||||
Child2 | Top
|
||||
Child3 | Top
|
||||
SubChild1 | Child1
|
||||
SubChild2 | Child1
|
||||
(6 rows)
|
||||
|
||||
SELECT listchildren('Top');
|
||||
listchildren
|
||||
--------------
|
||||
Child1
|
||||
Child2
|
||||
Child3
|
||||
(3 rows)
|
||||
|
||||
SELECT name, listchildren(name) FROM nodes;
|
||||
name | listchildren
|
||||
--------+--------------
|
||||
Top | Child1
|
||||
Top | Child2
|
||||
Top | Child3
|
||||
Child1 | SubChild1
|
||||
Child1 | SubChild2
|
||||
(5 rows)
|
||||
</screen>
|
||||
|
||||
Notice that no output row appears for Child2, Child3, etc.
|
||||
This happens because listchildren() returns an empty set
|
||||
for those inputs, so no output rows are generated.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
@ -412,8 +515,12 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision
|
||||
User-defined functions can be written in C (or a language that can
|
||||
be made compatible with C, such as C++). Such functions are
|
||||
compiled into dynamically loadable objects (also called shared
|
||||
libraries) and are loaded by the server on demand. This
|
||||
distinguishes them from internal functions.
|
||||
libraries) and are loaded by the server on demand. The dynamic
|
||||
loading feature is what distinguishes <quote>C language</> functions
|
||||
from <quote>internal</> functions --- the actual coding conventions
|
||||
are essentially the same for both. (Hence, the standard internal
|
||||
function library is a rich source of coding examples for user-defined
|
||||
C functions.)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -440,15 +547,6 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision
|
||||
object file, and the C name (link symbol) of the specific function to call
|
||||
within that object file. If the C name is not explicitly specified then
|
||||
it is assumed to be the same as the SQL function name.
|
||||
|
||||
<note>
|
||||
<para>
|
||||
After it is used for the first time, a dynamically loaded user
|
||||
function is retained in memory, and future calls to the function
|
||||
in the same session will only incur the small overhead of a symbol table
|
||||
lookup.
|
||||
</para>
|
||||
</note>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@ -459,22 +557,22 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
If the name is an absolute file name, the given file is loaded.
|
||||
If the name is an absolute path, the given file is loaded.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
If the name starts with the string <literal>$libdir</literal>,
|
||||
that part is replaced by the PostgreSQL package library directory,
|
||||
which is determined at build time.
|
||||
that part is replaced by the PostgreSQL package library directory
|
||||
name, which is determined at build time.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
If the name does not contain a directory part, the file is
|
||||
searched the path specified by the configuration variable
|
||||
searched for in the path specified by the configuration variable
|
||||
<varname>dynamic_library_path</varname>.
|
||||
</para>
|
||||
</listitem>
|
||||
@ -506,12 +604,33 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision
|
||||
</note>
|
||||
|
||||
<para>
|
||||
In any case, the file name that is specified in the
|
||||
In any case, the file name that is given in the
|
||||
<command>CREATE FUNCTION</command> command is recorded literally
|
||||
in the system catalogs, so if the file needs to be loaded again
|
||||
the same procedure is applied.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
<application>PostgreSQL</application> will not compile a C function
|
||||
automatically. The object file must be compiled before it is referenced
|
||||
in a <command>CREATE
|
||||
FUNCTION</> command. See <xref linkend="dfunc"> for additional
|
||||
information.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
After it is used for the first time, a dynamically loaded object
|
||||
file is retained in memory. Future calls in the same session to the
|
||||
function(s) in that file will only incur the small overhead of a symbol
|
||||
table lookup. If you need to force a reload of an object file, for
|
||||
example after recompiling it, use the <command>LOAD</> command or
|
||||
begin a fresh session.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<para>
|
||||
It is recommended to locate shared libraries either relative to
|
||||
<literal>$libdir</literal> or through the dynamic library path.
|
||||
@ -523,11 +642,15 @@ CREATE FUNCTION square_root(double precision) RETURNS double precision
|
||||
|
||||
<note>
|
||||
<para>
|
||||
<application>PostgreSQL</application> will not compile a function
|
||||
automatically; it must be compiled before it is used in a CREATE
|
||||
FUNCTION command. See <xref linkend="dfunc"> for additional information.
|
||||
Before <application>PostgreSQL</application> release 7.2, only exact
|
||||
absolute paths to object files could be specified in <command>CREATE
|
||||
FUNCTION</>. This approach is now deprecated since it makes the
|
||||
function definition unnecessarily unportable. It's best to specify
|
||||
just the shared library name with no path nor extension, and let
|
||||
the search mechanism provide that information instead.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
@ -931,39 +1054,42 @@ concat_text(text *arg1, text *arg2)
|
||||
|
||||
<programlisting>
|
||||
CREATE FUNCTION add_one(int4) RETURNS int4
|
||||
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs.so' LANGUAGE 'c'
|
||||
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs' LANGUAGE 'c'
|
||||
WITH (isStrict);
|
||||
|
||||
-- note overloading of SQL function name add_one()
|
||||
CREATE FUNCTION add_one(float8) RETURNS float8
|
||||
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs.so',
|
||||
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs',
|
||||
'add_one_float8'
|
||||
LANGUAGE 'c' WITH (isStrict);
|
||||
|
||||
CREATE FUNCTION makepoint(point, point) RETURNS point
|
||||
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs.so' LANGUAGE 'c'
|
||||
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs' LANGUAGE 'c'
|
||||
WITH (isStrict);
|
||||
|
||||
CREATE FUNCTION copytext(text) RETURNS text
|
||||
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs.so' LANGUAGE 'c'
|
||||
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs' LANGUAGE 'c'
|
||||
WITH (isStrict);
|
||||
|
||||
CREATE FUNCTION concat_text(text, text) RETURNS text
|
||||
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs.so' LANGUAGE 'c'
|
||||
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs' LANGUAGE 'c'
|
||||
WITH (isStrict);
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Here <replaceable>PGROOT</replaceable> stands for the full path to
|
||||
the <productname>Postgres</productname> source tree. Note that
|
||||
depending on your system, the filename for a shared object might
|
||||
not end in <literal>.so</literal>, but in <literal>.sl</literal>
|
||||
or something else; adapt accordingly.
|
||||
the <productname>Postgres</productname> source tree. (Better style would
|
||||
be to use just <literal>'funcs'</> in the <literal>AS</> clause,
|
||||
after having added <replaceable>PGROOT</replaceable><literal>/tutorial</>
|
||||
to the search path. In any case, we may omit the system-specific
|
||||
extension for a shared library, commonly <literal>.so</literal> or
|
||||
<literal>.sl</literal>.)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Notice that we have specified the functions as <quote>strict</quote>, meaning that
|
||||
Notice that we have specified the functions as <quote>strict</quote>,
|
||||
meaning that
|
||||
the system should automatically assume a NULL result if any input
|
||||
value is NULL. By doing this, we avoid having to check for NULL inputs
|
||||
in the function code. Without this, we'd have to check for NULLs
|
||||
@ -998,8 +1124,8 @@ PG_FUNCTION_INFO_V1(funcname);
|
||||
</programlisting>
|
||||
must appear in the same source file (conventionally it's written
|
||||
just before the function itself). This macro call is not needed
|
||||
for <literal>internal</>-language functions, since Postgres currently assumes
|
||||
all internal functions are version-1. However, it is
|
||||
for <literal>internal</>-language functions, since Postgres currently
|
||||
assumes all internal functions are version-1. However, it is
|
||||
<emphasis>required</emphasis> for dynamically-loaded functions.
|
||||
</para>
|
||||
|
||||
@ -1131,7 +1257,10 @@ concat_text(PG_FUNCTION_ARGS)
|
||||
this is only necessary in functions not declared <quote>strict</>).
|
||||
As with the
|
||||
<function>PG_GETARG_<replaceable>xxx</replaceable>()</function> macros,
|
||||
the input arguments are counted beginning at zero.
|
||||
the input arguments are counted beginning at zero. Note that one
|
||||
should refrain from executing
|
||||
<function>PG_GETARG_<replaceable>xxx</replaceable>()</function> until
|
||||
one has verified that the argument isn't NULL.
|
||||
To return a NULL result, execute <function>PG_RETURN_NULL()</function>;
|
||||
this works in both strict and non-strict functions.
|
||||
</para>
|
||||
@ -1229,7 +1358,7 @@ c_overpaid(PG_FUNCTION_ARGS)
|
||||
<programlisting>
|
||||
CREATE FUNCTION c_overpaid(emp, int4)
|
||||
RETURNS bool
|
||||
AS '<replaceable>PGROOT</replaceable>/tutorial/obj/funcs.so'
|
||||
AS '<replaceable>PGROOT</replaceable>/tutorial/obj/funcs'
|
||||
LANGUAGE 'c';
|
||||
</programlisting>
|
||||
</para>
|
||||
@ -1238,6 +1367,7 @@ LANGUAGE 'c';
|
||||
While there are ways to construct new rows or modify
|
||||
existing rows from within a C function, these
|
||||
are far too complex to discuss in this manual.
|
||||
Consult the backend source code for examples.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
@ -1359,7 +1489,7 @@ LANGUAGE 'c';
|
||||
<title>Function Overloading</title>
|
||||
|
||||
<para>
|
||||
More than one function may be defined with the same name, so long
|
||||
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
|
||||
@ -1428,9 +1558,9 @@ CREATE FUNCTION test(int, int) RETURNS int
|
||||
<para>
|
||||
All calls to functions that are written in a language other than
|
||||
the current <quote>version 1</quote> interface for compiled
|
||||
languages, in particular in user-defined procedural languages, but
|
||||
also functions written in SQL or the version 0 compiled language
|
||||
interface, go through a <firstterm>call handler</firstterm>
|
||||
languages (this includes functions in user-defined procedural languages,
|
||||
functions written in SQL, and functions using the version 0 compiled
|
||||
language interface), go through a <firstterm>call handler</firstterm>
|
||||
function for the specific language. It is the responsibility of
|
||||
the call handler to execute the function in a meaningful way, such
|
||||
as by interpreting the supplied source text. This section
|
||||
@ -1580,7 +1710,7 @@ plsample_call_handler(PG_FUNCTION_ARGS)
|
||||
language:
|
||||
<programlisting>
|
||||
CREATE FUNCTION plsample_call_handler () RETURNS opaque
|
||||
AS '/usr/local/pgsql/lib/plsample.so'
|
||||
AS '/usr/local/pgsql/lib/plsample'
|
||||
LANGUAGE C;
|
||||
CREATE LANGUAGE plsample
|
||||
HANDLER plsample_call_handler;
|
||||
|
Loading…
Reference in New Issue
Block a user