2000-03-31 05:27:42 +02:00
|
|
|
<!--
|
2002-08-29 19:14:33 +02:00
|
|
|
$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.58 2002/08/29 17:14:32 tgl Exp $
|
2000-03-31 05:27:42 +02:00
|
|
|
-->
|
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<chapter id="xfunc">
|
|
|
|
<title id="xfunc-title">Extending <acronym>SQL</acronym>: Functions</title>
|
|
|
|
|
2001-11-12 20:19:39 +01:00
|
|
|
<indexterm zone="xfunc"><primary>function</></>
|
|
|
|
|
2001-09-15 21:56:59 +02:00
|
|
|
<sect1 id="xfunc-intro">
|
|
|
|
<title>Introduction</title>
|
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<para>
|
2001-09-15 21:56:59 +02:00
|
|
|
<productname>PostgreSQL</productname> provides four kinds of
|
|
|
|
functions:
|
1999-07-22 17:11:05 +02:00
|
|
|
|
|
|
|
<itemizedlist>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
query language functions
|
|
|
|
(functions written in <acronym>SQL</acronym>)
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
procedural language
|
2001-09-15 21:56:59 +02:00
|
|
|
functions (functions written in, for example, <application>PL/Tcl</> or <application>PL/pgSQL</>)
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
internal functions
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2001-05-19 11:01:10 +02:00
|
|
|
C language functions
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
</itemizedlist>
|
2001-09-15 21:56:59 +02:00
|
|
|
</para>
|
1999-07-22 17:11:05 +02:00
|
|
|
|
2001-09-15 21:56:59 +02:00
|
|
|
<para>
|
1999-07-22 17:11:05 +02:00
|
|
|
Every kind
|
2002-01-07 03:29:15 +01:00
|
|
|
of function can take a base type, a composite type, or
|
1999-07-22 17:11:05 +02:00
|
|
|
some combination as arguments (parameters). In addition,
|
|
|
|
every kind of function can return a base type or
|
|
|
|
a composite type. It's easiest to define <acronym>SQL</acronym>
|
|
|
|
functions, so we'll start with those. Examples in this section
|
|
|
|
can also be found in <filename>funcs.sql</filename>
|
2001-09-15 21:56:59 +02:00
|
|
|
and <filename>funcs.c</filename> in the tutorial directory.
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
2002-01-07 03:29:15 +01:00
|
|
|
|
|
|
|
<para>
|
|
|
|
Throughout this chapter, it can be useful to look at the reference
|
|
|
|
page of the <command>CREATE FUNCTION</command> command to
|
|
|
|
understand the examples better.
|
|
|
|
</para>
|
2001-09-15 21:56:59 +02:00
|
|
|
</sect1>
|
1999-07-22 17:11:05 +02:00
|
|
|
|
2000-09-29 22:21:34 +02:00
|
|
|
<sect1 id="xfunc-sql">
|
1999-07-22 17:11:05 +02:00
|
|
|
<title>Query Language (<acronym>SQL</acronym>) Functions</title>
|
|
|
|
|
2001-11-12 20:19:39 +01:00
|
|
|
<indexterm zone="xfunc-sql"><primary>function</><secondary>SQL</></>
|
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<para>
|
2001-09-15 21:56:59 +02:00
|
|
|
SQL functions execute an arbitrary list of SQL statements, returning
|
2001-11-01 05:07:29 +01:00
|
|
|
the result of the last query in the list, which must be a
|
|
|
|
<literal>SELECT</>.
|
|
|
|
In the simple (non-set)
|
2001-10-26 21:58:12 +02:00
|
|
|
case, the first row of the last query's result will be returned.
|
2002-03-22 20:20:45 +01:00
|
|
|
(Bear in mind that <quote>the first row</quote> of a multirow
|
2001-11-01 05:07:29 +01:00
|
|
|
result is not well-defined unless you use <literal>ORDER BY</>.)
|
|
|
|
If the last query happens
|
2001-10-26 21:58:12 +02:00
|
|
|
to return no rows at all, NULL will be returned.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2001-11-12 20:19:39 +01:00
|
|
|
<indexterm><primary>SETOF</><seealso>function</></>
|
2001-10-26 21:58:12 +02:00
|
|
|
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.
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2001-09-15 21:56:59 +02:00
|
|
|
The body of an SQL function should be a list of one or more SQL
|
|
|
|
statements separated by semicolons. Note that because the syntax
|
2001-10-26 21:58:12 +02:00
|
|
|
of the <command>CREATE FUNCTION</command> command requires the body of the
|
|
|
|
function to be enclosed in single quotes, single quote marks
|
|
|
|
(<literal>'</>) used
|
2001-09-15 21:56:59 +02:00
|
|
|
in the body of the function must be escaped, by writing two single
|
2001-10-26 21:58:12 +02:00
|
|
|
quotes (<literal>''</>) or a backslash (<literal>\'</>) where each
|
|
|
|
quote is desired.
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2001-09-15 21:56:59 +02:00
|
|
|
Arguments to the SQL function may be referenced in the function
|
|
|
|
body using the syntax <literal>$<replaceable>n</></>: $1 refers to
|
|
|
|
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
|
2001-10-26 21:58:12 +02:00
|
|
|
of the argument.
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<sect2>
|
|
|
|
<title>Examples</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
To illustrate a simple SQL function, consider the following,
|
|
|
|
which might be used to debit a bank account:
|
|
|
|
|
2001-09-15 21:56:59 +02:00
|
|
|
<programlisting>
|
2001-10-26 21:58:12 +02:00
|
|
|
CREATE FUNCTION tp1 (integer, numeric) RETURNS integer AS '
|
2001-09-15 21:56:59 +02:00
|
|
|
UPDATE bank
|
2001-10-26 21:58:12 +02:00
|
|
|
SET balance = balance - $2
|
|
|
|
WHERE accountno = $1;
|
|
|
|
SELECT 1;
|
2001-09-15 21:56:59 +02:00
|
|
|
' LANGUAGE SQL;
|
|
|
|
</programlisting>
|
1999-07-22 17:11:05 +02:00
|
|
|
|
|
|
|
A user could execute this function to debit account 17 by $100.00 as
|
|
|
|
follows:
|
|
|
|
|
2001-09-15 21:56:59 +02:00
|
|
|
<programlisting>
|
|
|
|
SELECT tp1(17, 100.0);
|
|
|
|
</programlisting>
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2001-10-26 21:58:12 +02:00
|
|
|
In practice one would probably like a more useful result from the
|
|
|
|
function than a constant <quote>1</>, so a more likely definition
|
|
|
|
is
|
2001-09-15 21:56:59 +02:00
|
|
|
|
|
|
|
<programlisting>
|
2001-10-26 21:58:12 +02:00
|
|
|
CREATE FUNCTION tp1 (integer, numeric) RETURNS numeric AS '
|
|
|
|
UPDATE bank
|
|
|
|
SET balance = balance - $2
|
|
|
|
WHERE accountno = $1;
|
|
|
|
SELECT balance FROM bank WHERE accountno = $1;
|
2001-09-15 21:56:59 +02:00
|
|
|
' LANGUAGE SQL;
|
|
|
|
</programlisting>
|
2001-10-26 21:58:12 +02:00
|
|
|
|
|
|
|
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
|
2002-08-23 18:41:38 +02:00
|
|
|
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 <type>void</>.
|
|
|
|
In that case it must not end with a <command>SELECT</command>.
|
|
|
|
For example:
|
2001-10-26 21:58:12 +02:00
|
|
|
|
|
|
|
<programlisting>
|
2002-08-23 18:41:38 +02:00
|
|
|
CREATE FUNCTION clean_EMP () RETURNS void AS '
|
2001-10-26 21:58:12 +02:00
|
|
|
DELETE FROM EMP
|
|
|
|
WHERE EMP.salary <= 0;
|
|
|
|
' LANGUAGE SQL;
|
|
|
|
|
|
|
|
SELECT clean_EMP();
|
|
|
|
</programlisting>
|
|
|
|
|
|
|
|
<screen>
|
2002-08-23 18:41:38 +02:00
|
|
|
clean_emp
|
|
|
|
-----------
|
|
|
|
|
|
|
|
(1 row)
|
2001-10-26 21:58:12 +02:00
|
|
|
</screen>
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
2002-06-20 18:57:00 +02:00
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
</sect2>
|
|
|
|
|
|
|
|
<sect2>
|
|
|
|
<title><acronym>SQL</acronym> Functions on Base Types</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The simplest possible <acronym>SQL</acronym> function has no arguments and
|
2001-09-15 21:56:59 +02:00
|
|
|
simply returns a base type, such as <type>integer</type>:
|
1998-03-01 09:16:16 +01:00
|
|
|
|
2001-09-15 21:56:59 +02:00
|
|
|
<programlisting>
|
|
|
|
CREATE FUNCTION one() RETURNS integer AS '
|
|
|
|
SELECT 1 as RESULT;
|
|
|
|
' LANGUAGE SQL;
|
1998-03-01 09:16:16 +01:00
|
|
|
|
2001-10-26 21:58:12 +02:00
|
|
|
SELECT one();
|
2001-09-15 21:56:59 +02:00
|
|
|
</programlisting>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
2001-09-15 21:56:59 +02:00
|
|
|
<screen>
|
2001-10-26 21:58:12 +02:00
|
|
|
one
|
|
|
|
-----
|
|
|
|
1
|
2001-09-15 21:56:59 +02:00
|
|
|
</screen>
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
2001-09-15 21:56:59 +02:00
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<para>
|
2001-09-15 21:56:59 +02:00
|
|
|
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
|
2002-01-20 23:19:57 +01:00
|
|
|
outside the function. Hence, the result is labeled <literal>one</>
|
2001-10-26 21:58:12 +02:00
|
|
|
instead of <literal>RESULT</>.
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
2001-09-15 21:56:59 +02:00
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<para>
|
2001-09-15 21:56:59 +02:00
|
|
|
It is almost as easy to define <acronym>SQL</acronym> functions
|
1999-03-14 16:24:15 +01:00
|
|
|
that take base types as arguments. In the example below, notice
|
2001-09-15 21:56:59 +02:00
|
|
|
how we refer to the arguments within the function as <literal>$1</>
|
|
|
|
and <literal>$2</>:
|
1999-07-22 17:11:05 +02:00
|
|
|
|
2001-09-15 21:56:59 +02:00
|
|
|
<programlisting>
|
|
|
|
CREATE FUNCTION add_em(integer, integer) RETURNS integer AS '
|
|
|
|
SELECT $1 + $2;
|
|
|
|
' LANGUAGE SQL;
|
1998-03-01 09:16:16 +01:00
|
|
|
|
2000-05-02 22:02:03 +02:00
|
|
|
SELECT add_em(1, 2) AS answer;
|
2001-09-15 21:56:59 +02:00
|
|
|
</programlisting>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
2001-09-15 21:56:59 +02:00
|
|
|
<screen>
|
|
|
|
answer
|
|
|
|
--------
|
|
|
|
3
|
|
|
|
</screen>
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
|
|
|
</sect2>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<sect2>
|
|
|
|
<title><acronym>SQL</acronym> Functions on Composite Types</title>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<para>
|
1998-03-01 09:16:16 +01:00
|
|
|
When specifying functions with arguments of composite
|
2001-10-26 21:58:12 +02:00
|
|
|
types, we must not only specify which
|
2001-09-15 21:56:59 +02:00
|
|
|
argument we want (as we did above with <literal>$1</> and <literal>$2</literal>) but
|
2001-10-26 21:58:12 +02:00
|
|
|
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
|
1999-07-22 17:11:05 +02:00
|
|
|
salary would be if it were doubled:
|
|
|
|
|
2001-09-15 21:56:59 +02:00
|
|
|
<programlisting>
|
|
|
|
CREATE FUNCTION double_salary(EMP) RETURNS integer AS '
|
|
|
|
SELECT $1.salary * 2 AS salary;
|
|
|
|
' LANGUAGE SQL;
|
2000-05-02 22:02:03 +02:00
|
|
|
|
|
|
|
SELECT name, double_salary(EMP) AS dream
|
2000-08-25 17:17:50 +02:00
|
|
|
FROM EMP
|
2001-01-20 21:59:29 +01:00
|
|
|
WHERE EMP.cubicle ~= point '(2,1)';
|
2001-09-15 21:56:59 +02:00
|
|
|
</programlisting>
|
2000-08-25 17:17:50 +02:00
|
|
|
|
2001-09-15 21:56:59 +02:00
|
|
|
<screen>
|
|
|
|
name | dream
|
|
|
|
------+-------
|
|
|
|
Sam | 2400
|
|
|
|
</screen>
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
2001-09-15 21:56:59 +02:00
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<para>
|
2001-10-26 21:58:12 +02:00
|
|
|
Notice the use of the syntax <literal>$1.salary</literal>
|
|
|
|
to select one field of the argument row value. Also notice
|
2002-01-07 03:29:15 +01:00
|
|
|
how the calling <command>SELECT</> command uses a table name to denote
|
2001-10-26 21:58:12 +02:00
|
|
|
the entire current row of that table as a composite value.
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
2001-09-15 21:56:59 +02:00
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<para>
|
2001-10-26 21:58:12 +02:00
|
|
|
It is also possible to build a function that returns a composite type.
|
|
|
|
This is an example of a function
|
2001-09-15 21:56:59 +02:00
|
|
|
that returns a single <type>EMP</type> row:
|
1999-07-22 17:11:05 +02:00
|
|
|
|
2001-09-15 21:56:59 +02:00
|
|
|
<programlisting>
|
|
|
|
CREATE FUNCTION new_emp() RETURNS EMP AS '
|
|
|
|
SELECT text ''None'' AS name,
|
2000-08-25 17:17:50 +02:00
|
|
|
1000 AS salary,
|
|
|
|
25 AS age,
|
2001-09-15 21:56:59 +02:00
|
|
|
point ''(2,2)'' AS cubicle;
|
|
|
|
' LANGUAGE SQL;
|
|
|
|
</programlisting>
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
2001-09-15 21:56:59 +02:00
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<para>
|
1998-03-01 09:16:16 +01:00
|
|
|
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.
|
2001-10-26 21:58:12 +02:00
|
|
|
Note two important things about defining the function:
|
1999-07-22 17:11:05 +02:00
|
|
|
|
|
|
|
<itemizedlist>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
The target list order must be exactly the same as
|
2001-10-26 21:58:12 +02:00
|
|
|
that in which the columns appear in the table associated
|
2002-03-21 17:02:16 +01:00
|
|
|
with the composite type. (Naming the columns, as we did above,
|
|
|
|
is irrelevant to the system.)
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2001-01-20 21:59:29 +01:00
|
|
|
You must typecast the expressions to match the
|
2001-09-15 21:56:59 +02:00
|
|
|
definition of the composite type, or you will get errors like this:
|
|
|
|
<screen>
|
|
|
|
<computeroutput>
|
2000-08-25 01:36:29 +02:00
|
|
|
ERROR: function declared to return emp returns varchar instead of text at column 1
|
2001-09-15 21:56:59 +02:00
|
|
|
</computeroutput>
|
|
|
|
</screen>
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
|
|
|
</listitem>
|
2001-10-26 21:58:12 +02:00
|
|
|
</itemizedlist>
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2002-08-29 02:17:06 +02:00
|
|
|
A function that returns a row (composite type) can be used as a table
|
|
|
|
function, as described below. It can also be called in the context
|
|
|
|
of an SQL expression, but only when you
|
2002-03-21 17:02:16 +01:00
|
|
|
extract a single attribute out of the row or pass the entire row into
|
2002-08-29 02:17:06 +02:00
|
|
|
another function that accepts the same composite type. (Trying to
|
|
|
|
display the entire row value will yield
|
2001-10-26 21:58:12 +02:00
|
|
|
a meaningless number.) For example,
|
1999-07-22 17:11:05 +02:00
|
|
|
|
2001-09-15 21:56:59 +02:00
|
|
|
<programlisting>
|
2002-03-21 17:02:16 +01:00
|
|
|
SELECT (new_emp()).name;
|
2001-09-15 21:56:59 +02:00
|
|
|
</programlisting>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
2001-09-15 21:56:59 +02:00
|
|
|
<screen>
|
2001-10-26 21:58:12 +02:00
|
|
|
name
|
|
|
|
------
|
2001-09-15 21:56:59 +02:00
|
|
|
None
|
2002-03-21 17:02:16 +01:00
|
|
|
</screen>
|
|
|
|
|
|
|
|
We need the extra parentheses to keep the parser from getting confused:
|
|
|
|
|
|
|
|
<screen>
|
|
|
|
SELECT new_emp().name;
|
|
|
|
ERROR: parser: parse error at or near "."
|
2001-09-15 21:56:59 +02:00
|
|
|
</screen>
|
2001-10-26 21:58:12 +02:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2002-08-29 02:17:06 +02:00
|
|
|
Another option is to use
|
|
|
|
functional notation for extracting an attribute. The simple way
|
2002-03-21 17:02:16 +01:00
|
|
|
to explain this is that we can use the
|
2001-10-26 21:58:12 +02:00
|
|
|
notations <literal>attribute(table)</> and <literal>table.attribute</>
|
|
|
|
interchangeably:
|
|
|
|
|
2002-03-21 17:02:16 +01:00
|
|
|
<programlisting>
|
|
|
|
SELECT name(new_emp());
|
|
|
|
</programlisting>
|
|
|
|
|
|
|
|
<screen>
|
|
|
|
name
|
|
|
|
------
|
|
|
|
None
|
|
|
|
</screen>
|
|
|
|
|
2001-10-26 21:58:12 +02:00
|
|
|
<programlisting>
|
|
|
|
--
|
|
|
|
-- this is the same as:
|
|
|
|
-- SELECT EMP.name AS youngster FROM EMP WHERE EMP.age < 30
|
|
|
|
--
|
|
|
|
SELECT name(EMP) AS youngster
|
|
|
|
FROM EMP
|
|
|
|
WHERE age(EMP) < 30;
|
|
|
|
</programlisting>
|
|
|
|
|
|
|
|
<screen>
|
|
|
|
youngster
|
|
|
|
-----------
|
|
|
|
Sam
|
|
|
|
</screen>
|
|
|
|
</para>
|
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<para>
|
2001-10-26 21:58:12 +02:00
|
|
|
Another way to use a function returning a row result is to declare a
|
2002-01-07 03:29:15 +01:00
|
|
|
second function accepting a row type parameter, and pass the function
|
2001-10-26 21:58:12 +02:00
|
|
|
result to it:
|
1999-07-22 17:11:05 +02:00
|
|
|
|
2001-09-15 21:56:59 +02:00
|
|
|
<programlisting>
|
2001-10-26 21:58:12 +02:00
|
|
|
CREATE FUNCTION getname(emp) RETURNS text AS
|
|
|
|
'SELECT $1.name;'
|
|
|
|
LANGUAGE SQL;
|
|
|
|
</programlisting>
|
2000-05-02 22:02:03 +02:00
|
|
|
|
2001-10-26 21:58:12 +02:00
|
|
|
<screen>
|
|
|
|
SELECT getname(new_emp());
|
|
|
|
getname
|
|
|
|
---------
|
|
|
|
None
|
|
|
|
(1 row)
|
|
|
|
</screen>
|
|
|
|
</para>
|
|
|
|
</sect2>
|
|
|
|
|
|
|
|
<sect2>
|
2002-08-29 02:17:06 +02:00
|
|
|
<title><acronym>SQL</acronym> Table Functions</title>
|
2002-06-20 18:57:00 +02:00
|
|
|
|
|
|
|
<para>
|
|
|
|
A table function is one that may be used in the <command>FROM</command>
|
2002-08-29 02:17:06 +02:00
|
|
|
clause of a query. All SQL language functions may be used in this manner,
|
|
|
|
but it is particularly useful for functions returning composite types.
|
2002-06-20 18:57:00 +02:00
|
|
|
If the function is defined to return a base type, the table function
|
2002-08-29 02:17:06 +02:00
|
|
|
produces a one-column table. If the function is defined to return
|
|
|
|
a composite type, the table function produces a column for each column
|
|
|
|
of the composite type.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Here is an example:
|
2002-06-20 18:57:00 +02:00
|
|
|
|
|
|
|
<programlisting>
|
2002-08-29 02:17:06 +02:00
|
|
|
CREATE TABLE foo (fooid int, foosubid int, fooname text);
|
2002-06-20 18:57:00 +02:00
|
|
|
INSERT INTO foo VALUES(1,1,'Joe');
|
|
|
|
INSERT INTO foo VALUES(1,2,'Ed');
|
|
|
|
INSERT INTO foo VALUES(2,1,'Mary');
|
2002-08-29 02:17:06 +02:00
|
|
|
|
|
|
|
CREATE FUNCTION getfoo(int) RETURNS foo AS '
|
|
|
|
SELECT * FROM foo WHERE fooid = $1;
|
|
|
|
' LANGUAGE SQL;
|
|
|
|
|
|
|
|
SELECT *, upper(fooname) FROM getfoo(1) AS t1;
|
|
|
|
</programlisting>
|
|
|
|
|
|
|
|
<screen>
|
|
|
|
fooid | foosubid | fooname | upper
|
|
|
|
-------+----------+---------+-------
|
|
|
|
1 | 1 | Joe | JOE
|
|
|
|
(2 rows)
|
|
|
|
</screen>
|
|
|
|
|
|
|
|
As the example shows, we can work with the columns of the function's
|
|
|
|
result just the same as if they were columns of a regular table.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Note that we only got one row out of the function. This is because
|
|
|
|
we did not say <literal>SETOF</>.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
</sect2>
|
|
|
|
|
|
|
|
<sect2>
|
|
|
|
<title><acronym>SQL</acronym> Functions Returning Sets</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
When an SQL function is declared as returning <literal>SETOF</literal>
|
|
|
|
<replaceable>sometype</>, the function's final
|
|
|
|
<command>SELECT</> query is executed to completion, and each row it
|
|
|
|
outputs is returned as an element of the set.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
This feature is normally used by calling the function as a table
|
|
|
|
function. In this case each row returned by the function becomes
|
|
|
|
a row of the table seen by the query. For example, assume that
|
|
|
|
table <literal>foo</> has the same contents as above, and we say:
|
|
|
|
|
|
|
|
<programlisting>
|
2002-06-20 18:57:00 +02:00
|
|
|
CREATE FUNCTION getfoo(int) RETURNS setof foo AS '
|
|
|
|
SELECT * FROM foo WHERE fooid = $1;
|
|
|
|
' LANGUAGE SQL;
|
2002-08-29 02:17:06 +02:00
|
|
|
|
2002-06-20 18:57:00 +02:00
|
|
|
SELECT * FROM getfoo(1) AS t1;
|
|
|
|
</programlisting>
|
|
|
|
|
|
|
|
<screen>
|
|
|
|
fooid | foosubid | fooname
|
|
|
|
-------+----------+---------
|
|
|
|
1 | 1 | Joe
|
|
|
|
1 | 2 | Ed
|
|
|
|
(2 rows)
|
|
|
|
</screen>
|
|
|
|
</para>
|
2001-10-26 21:58:12 +02:00
|
|
|
|
|
|
|
<para>
|
2002-08-29 02:17:06 +02:00
|
|
|
Currently, functions returning sets may also be called in the target list
|
2002-06-20 18:57:00 +02:00
|
|
|
of a <command>SELECT</> query. For each row that the <command>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. Note,
|
|
|
|
however, that this capability is deprecated and may be removed in future
|
|
|
|
releases. The following is an example function returning a set from the
|
|
|
|
target list:
|
2001-10-26 21:58:12 +02:00
|
|
|
|
|
|
|
<programlisting>
|
|
|
|
CREATE FUNCTION listchildren(text) RETURNS SETOF text AS
|
|
|
|
'SELECT name FROM nodes WHERE parent = $1'
|
|
|
|
LANGUAGE SQL;
|
2001-09-15 21:56:59 +02:00
|
|
|
</programlisting>
|
2000-05-02 22:02:03 +02:00
|
|
|
|
2001-09-15 21:56:59 +02:00
|
|
|
<screen>
|
2001-10-26 21:58:12 +02:00
|
|
|
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)
|
2001-09-15 21:56:59 +02:00
|
|
|
</screen>
|
2001-10-26 21:58:12 +02:00
|
|
|
|
2002-01-07 03:29:15 +01:00
|
|
|
In the last <command>SELECT</command>,
|
|
|
|
notice that no output row appears for <literal>Child2</>, <literal>Child3</>, etc.
|
|
|
|
This happens because <function>listchildren</function> returns an empty set
|
2001-10-26 21:58:12 +02:00
|
|
|
for those inputs, so no output rows are generated.
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
|
|
|
</sect2>
|
|
|
|
</sect1>
|
|
|
|
|
2000-09-29 22:21:34 +02:00
|
|
|
<sect1 id="xfunc-pl">
|
1999-07-22 17:11:05 +02:00
|
|
|
<title>Procedural Language Functions</title>
|
|
|
|
|
|
|
|
<para>
|
2001-09-15 21:56:59 +02:00
|
|
|
Procedural languages aren't built into the <productname>PostgreSQL</productname> server; they are offered
|
|
|
|
by loadable modules. Please refer to the documentation of the
|
|
|
|
procedural language in question for details about the syntax and how the function body
|
|
|
|
is interpreted for each language.
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<para>
|
2001-09-06 12:28:39 +02:00
|
|
|
There are currently four procedural languages available in the
|
|
|
|
standard <productname>PostgreSQL</productname> distribution:
|
2001-09-15 21:56:59 +02:00
|
|
|
<application>PL/pgSQL</application>, <application>PL/Tcl</application>,
|
|
|
|
<application>PL/Perl</application>, and <application>PL/Python</application>. Other languages can be
|
2001-09-06 12:28:39 +02:00
|
|
|
defined by users. Refer to <xref linkend="xplang"> for more
|
2001-09-15 21:56:59 +02:00
|
|
|
information. The basics of developing a new procedural language are covered in <xref linkend="xfunc-plhandler">.
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
|
|
|
</sect1>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
2000-09-29 22:21:34 +02:00
|
|
|
<sect1 id="xfunc-internal">
|
1999-07-22 17:11:05 +02:00
|
|
|
<title>Internal Functions</title>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
2001-11-12 20:19:39 +01:00
|
|
|
<indexterm zone="xfunc-internal"><primary>function</><secondary>internal</></>
|
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<para>
|
2000-12-22 19:57:50 +01:00
|
|
|
Internal functions are functions written in C that have been statically
|
2001-09-15 21:56:59 +02:00
|
|
|
linked into the <productname>PostgreSQL</productname> server.
|
|
|
|
The <quote>body</quote> of the function definition
|
|
|
|
specifies the C-language name of the function, which need not be the
|
1999-07-22 17:11:05 +02:00
|
|
|
same as the name being declared for SQL use.
|
2001-09-15 21:56:59 +02:00
|
|
|
(For reasons of backwards compatibility, an empty body
|
|
|
|
is accepted as meaning that the C-language function name is the
|
|
|
|
same as the SQL name.)
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
2000-08-25 01:36:29 +02:00
|
|
|
|
|
|
|
<para>
|
2001-09-15 21:56:59 +02:00
|
|
|
Normally, all internal functions present in the
|
|
|
|
backend are declared during the initialization of the database cluster (<command>initdb</command>),
|
|
|
|
but a user could use <command>CREATE FUNCTION</command>
|
|
|
|
to create additional alias names for an internal function.
|
2000-08-25 01:36:29 +02:00
|
|
|
Internal functions are declared in <command>CREATE FUNCTION</command>
|
2001-09-15 21:56:59 +02:00
|
|
|
with language name <literal>internal</literal>. For instance, to
|
|
|
|
create an alias for the <function>sqrt</function> function:
|
|
|
|
<programlisting>
|
|
|
|
CREATE FUNCTION square_root(double precision) RETURNS double precision
|
|
|
|
AS 'dsqrt'
|
|
|
|
LANGUAGE INTERNAL
|
|
|
|
WITH (isStrict);
|
|
|
|
</programlisting>
|
|
|
|
(Most internal functions expect to be declared <quote>strict</quote>.)
|
2000-08-25 01:36:29 +02:00
|
|
|
</para>
|
2001-09-15 21:56:59 +02:00
|
|
|
|
|
|
|
<note>
|
|
|
|
<para>
|
|
|
|
Not all <quote>predefined</quote> functions are
|
|
|
|
<quote>internal</quote> in the above sense. Some predefined
|
|
|
|
functions are written in SQL.
|
|
|
|
</para>
|
|
|
|
</note>
|
1999-07-22 17:11:05 +02:00
|
|
|
</sect1>
|
|
|
|
|
2000-09-29 22:21:34 +02:00
|
|
|
<sect1 id="xfunc-c">
|
2001-05-19 11:01:10 +02:00
|
|
|
<title>C Language Functions</title>
|
1999-07-22 17:11:05 +02:00
|
|
|
|
|
|
|
<para>
|
2001-05-19 11:01:10 +02:00
|
|
|
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
|
2001-10-26 21:58:12 +02:00
|
|
|
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.)
|
2001-05-19 11:01:10 +02:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Two different calling conventions are currently used for C functions.
|
2001-09-13 17:55:24 +02:00
|
|
|
The newer <quote>version 1</quote> calling convention is indicated by writing
|
2001-05-19 11:01:10 +02:00
|
|
|
a <literal>PG_FUNCTION_INFO_V1()</literal> macro call for the function,
|
|
|
|
as illustrated below. Lack of such a macro indicates an old-style
|
2001-09-13 17:55:24 +02:00
|
|
|
("version 0") function. The language name specified in <command>CREATE FUNCTION</command>
|
|
|
|
is <literal>C</literal> in either case. Old-style functions are now deprecated
|
2001-05-19 11:01:10 +02:00
|
|
|
because of portability problems and lack of functionality, but they
|
|
|
|
are still supported for compatibility reasons.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<sect2 id="xfunc-c-dynload">
|
|
|
|
<title>Dynamic Loading</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The first time a user-defined function in a particular
|
2000-08-25 01:36:29 +02:00
|
|
|
loadable object file is called in a backend session,
|
|
|
|
the dynamic loader loads that object file into memory so that the
|
|
|
|
function can be called. The <command>CREATE FUNCTION</command>
|
2001-05-19 11:01:10 +02:00
|
|
|
for a user-defined C function must therefore specify two pieces of
|
2000-08-25 01:36:29 +02:00
|
|
|
information for the function: the name of the loadable
|
|
|
|
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.
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2001-05-19 11:01:10 +02:00
|
|
|
The following algorithm is used to locate the shared object file
|
|
|
|
based on the name given in the <command>CREATE FUNCTION</command>
|
|
|
|
command:
|
|
|
|
|
|
|
|
<orderedlist>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2001-10-26 21:58:12 +02:00
|
|
|
If the name is an absolute path, the given file is loaded.
|
2001-05-19 11:01:10 +02:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
If the name starts with the string <literal>$libdir</literal>,
|
2001-11-21 07:09:45 +01:00
|
|
|
that part is replaced by the <productname>PostgreSQL</> package
|
|
|
|
library directory
|
2001-11-12 20:19:39 +01:00
|
|
|
name, which is determined at build time.<indexterm><primary>$libdir</></>
|
2001-05-19 11:01:10 +02:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
If the name does not contain a directory part, the file is
|
2001-10-26 21:58:12 +02:00
|
|
|
searched for in the path specified by the configuration variable
|
2001-11-12 20:19:39 +01:00
|
|
|
<varname>dynamic_library_path</varname>.<indexterm><primary>dynamic_library_path</></>
|
2001-05-19 11:01:10 +02:00
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
Otherwise (the file was not found in the path, or it contains a
|
|
|
|
non-absolute directory part), the dynamic loader will try to
|
|
|
|
take the name as given, which will most likely fail. (It is
|
|
|
|
unreliable to depend on the current working directory.)
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
</orderedlist>
|
|
|
|
|
|
|
|
If this sequence does not work, the platform-specific shared
|
|
|
|
library file name extension (often <filename>.so</filename>) is
|
|
|
|
appended to the given name and this sequence is tried again. If
|
|
|
|
that fails as well, the load will fail.
|
|
|
|
</para>
|
2000-08-25 01:36:29 +02:00
|
|
|
|
2001-05-19 11:01:10 +02:00
|
|
|
<note>
|
|
|
|
<para>
|
2002-01-07 03:29:15 +01:00
|
|
|
The user ID the <application>PostgreSQL</application> server runs
|
2001-05-19 11:01:10 +02:00
|
|
|
as must be able to traverse the path to the file you intend to
|
|
|
|
load. Making the file or a higher-level directory not readable
|
2002-03-22 20:20:45 +01:00
|
|
|
and/or not executable by the <systemitem>postgres</systemitem> user is a
|
2001-05-19 11:01:10 +02:00
|
|
|
common mistake.
|
|
|
|
</para>
|
|
|
|
</note>
|
|
|
|
|
|
|
|
<para>
|
2001-10-26 21:58:12 +02:00
|
|
|
In any case, the file name that is given in the
|
2001-05-19 11:01:10 +02:00
|
|
|
<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.
|
2000-08-25 01:36:29 +02:00
|
|
|
</para>
|
|
|
|
|
2001-10-26 21:58:12 +02:00
|
|
|
<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>
|
|
|
|
|
2000-08-25 01:36:29 +02:00
|
|
|
<para>
|
2001-05-19 11:01:10 +02:00
|
|
|
It is recommended to locate shared libraries either relative to
|
|
|
|
<literal>$libdir</literal> or through the dynamic library path.
|
|
|
|
This simplifies version upgrades if the new installation is at a
|
2001-09-16 18:11:11 +02:00
|
|
|
different location. The actual directory that
|
|
|
|
<literal>$libdir</literal> stands for can be found out with the
|
|
|
|
command <literal>pg_config --pkglibdir</literal>.
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
|
|
|
|
2001-05-19 11:01:10 +02:00
|
|
|
<note>
|
|
|
|
<para>
|
2001-10-26 21:58:12 +02:00
|
|
|
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.
|
2001-05-19 11:01:10 +02:00
|
|
|
</para>
|
|
|
|
</note>
|
2001-10-26 21:58:12 +02:00
|
|
|
|
2001-05-19 11:01:10 +02:00
|
|
|
</sect2>
|
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<sect2>
|
2000-08-25 01:36:29 +02:00
|
|
|
<title>Base Types in C-Language Functions</title>
|
1999-07-22 17:11:05 +02:00
|
|
|
|
|
|
|
<para>
|
2001-09-15 21:56:59 +02:00
|
|
|
<xref linkend="xfunc-c-type-table"> gives the C type required for
|
2001-11-21 07:09:45 +01:00
|
|
|
parameters in the C functions that will be loaded into
|
2002-01-07 03:29:15 +01:00
|
|
|
<productname>PostgreSQL</>.
|
2001-09-15 21:56:59 +02:00
|
|
|
The <quote>Defined In</quote> column gives the header file that
|
|
|
|
needs to be included to get the type definition. (The actual
|
|
|
|
definition may be in a different file that is included by the
|
|
|
|
listed file. It is recommended that users stick to the defined
|
|
|
|
interface.) Note that you should always include
|
|
|
|
<filename>postgres.h</filename> first in any source file, because
|
|
|
|
it declares a number of things that you will need anyway.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<table tocentry="1" id="xfunc-c-type-table">
|
1999-07-22 17:11:05 +02:00
|
|
|
<title>Equivalent C Types
|
2001-09-15 21:56:59 +02:00
|
|
|
for Built-In <productname>PostgreSQL</productname> Types</title>
|
1999-07-22 17:11:05 +02:00
|
|
|
<titleabbrev>Equivalent C Types</titleabbrev>
|
|
|
|
<tgroup cols="3">
|
|
|
|
<thead>
|
|
|
|
<row>
|
|
|
|
<entry>
|
2001-09-15 21:56:59 +02:00
|
|
|
SQL Type
|
1999-07-22 17:11:05 +02:00
|
|
|
</entry>
|
|
|
|
<entry>
|
|
|
|
C Type
|
|
|
|
</entry>
|
|
|
|
<entry>
|
|
|
|
Defined In
|
|
|
|
</entry>
|
|
|
|
</row>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
<row>
|
2001-09-15 21:56:59 +02:00
|
|
|
<entry><type>abstime</type></entry>
|
|
|
|
<entry><type>AbsoluteTime</type></entry>
|
|
|
|
<entry><filename>utils/nabstime.h</filename></entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry><type>boolean</type></entry>
|
|
|
|
<entry><type>bool</type></entry>
|
|
|
|
<entry><filename>postgres.h</filename> (maybe compiler built-in)</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry><type>box</type></entry>
|
|
|
|
<entry><type>BOX*</type></entry>
|
2001-11-18 22:28:00 +01:00
|
|
|
<entry><filename>utils/geo_decls.h</filename></entry>
|
2001-09-15 21:56:59 +02:00
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry><type>bytea</type></entry>
|
|
|
|
<entry><type>bytea*</type></entry>
|
|
|
|
<entry><filename>postgres.h</filename></entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry><type>"char"</type></entry>
|
|
|
|
<entry><type>char</type></entry>
|
|
|
|
<entry>(compiler built-in)</entry>
|
1999-07-22 17:11:05 +02:00
|
|
|
</row>
|
|
|
|
<row>
|
2001-09-15 21:56:59 +02:00
|
|
|
<entry><type>character</type></entry>
|
|
|
|
<entry><type>BpChar*</type></entry>
|
|
|
|
<entry><filename>postgres.h</filename></entry>
|
1999-07-22 17:11:05 +02:00
|
|
|
</row>
|
|
|
|
<row>
|
2001-09-15 21:56:59 +02:00
|
|
|
<entry><type>cid</type></entry>
|
|
|
|
<entry><type>CommandId</type></entry>
|
|
|
|
<entry><filename>postgres.h</filename></entry>
|
1999-07-22 17:11:05 +02:00
|
|
|
</row>
|
|
|
|
<row>
|
2001-09-15 21:56:59 +02:00
|
|
|
<entry><type>date</type></entry>
|
|
|
|
<entry><type>DateADT</type></entry>
|
|
|
|
<entry><filename>utils/date.h</filename></entry>
|
1999-07-22 17:11:05 +02:00
|
|
|
</row>
|
|
|
|
<row>
|
2001-09-15 21:56:59 +02:00
|
|
|
<entry><type>smallint</type> (<type>int2</type>)</entry>
|
|
|
|
<entry><type>int2</type> or <type>int16</type></entry>
|
|
|
|
<entry><filename>postgres.h</filename></entry>
|
1999-07-22 17:11:05 +02:00
|
|
|
</row>
|
|
|
|
<row>
|
2001-09-15 21:56:59 +02:00
|
|
|
<entry><type>int2vector</type></entry>
|
|
|
|
<entry><type>int2vector*</type></entry>
|
|
|
|
<entry><filename>postgres.h</filename></entry>
|
1999-07-22 17:11:05 +02:00
|
|
|
</row>
|
|
|
|
<row>
|
2001-09-15 21:56:59 +02:00
|
|
|
<entry><type>integer</type> (<type>int4</type>)</entry>
|
|
|
|
<entry><type>int4</type> or <type>int32</type></entry>
|
|
|
|
<entry><filename>postgres.h</filename></entry>
|
1999-07-22 17:11:05 +02:00
|
|
|
</row>
|
|
|
|
<row>
|
2001-09-15 21:56:59 +02:00
|
|
|
<entry><type>real</type> (<type>float4</type>)</entry>
|
|
|
|
<entry><type>float4*</type></entry>
|
|
|
|
<entry><filename>postgres.h</filename></entry>
|
1999-07-22 17:11:05 +02:00
|
|
|
</row>
|
|
|
|
<row>
|
2001-09-15 21:56:59 +02:00
|
|
|
<entry><type>double precision</type> (<type>float8</type>)</entry>
|
|
|
|
<entry><type>float8*</type></entry>
|
|
|
|
<entry><filename>postgres.h</filename></entry>
|
1999-07-22 17:11:05 +02:00
|
|
|
</row>
|
|
|
|
<row>
|
2001-09-15 21:56:59 +02:00
|
|
|
<entry><type>interval</type></entry>
|
|
|
|
<entry><type>Interval*</type></entry>
|
|
|
|
<entry><filename>utils/timestamp.h</filename></entry>
|
1999-07-22 17:11:05 +02:00
|
|
|
</row>
|
|
|
|
<row>
|
2001-09-15 21:56:59 +02:00
|
|
|
<entry><type>lseg</type></entry>
|
|
|
|
<entry><type>LSEG*</type></entry>
|
2001-11-18 22:28:00 +01:00
|
|
|
<entry><filename>utils/geo_decls.h</filename></entry>
|
1999-07-22 17:11:05 +02:00
|
|
|
</row>
|
|
|
|
<row>
|
2001-09-15 21:56:59 +02:00
|
|
|
<entry><type>name</type></entry>
|
|
|
|
<entry><type>Name</type></entry>
|
|
|
|
<entry><filename>postgres.h</filename></entry>
|
1999-07-22 17:11:05 +02:00
|
|
|
</row>
|
|
|
|
<row>
|
2001-09-15 21:56:59 +02:00
|
|
|
<entry><type>oid</type></entry>
|
|
|
|
<entry><type>Oid</type></entry>
|
|
|
|
<entry><filename>postgres.h</filename></entry>
|
1999-07-22 17:11:05 +02:00
|
|
|
</row>
|
|
|
|
<row>
|
2001-09-15 21:56:59 +02:00
|
|
|
<entry><type>oidvector</type></entry>
|
|
|
|
<entry><type>oidvector*</type></entry>
|
|
|
|
<entry><filename>postgres.h</filename></entry>
|
1999-07-22 17:11:05 +02:00
|
|
|
</row>
|
|
|
|
<row>
|
2001-09-15 21:56:59 +02:00
|
|
|
<entry><type>path</type></entry>
|
|
|
|
<entry><type>PATH*</type></entry>
|
2001-11-18 22:28:00 +01:00
|
|
|
<entry><filename>utils/geo_decls.h</filename></entry>
|
1999-07-22 17:11:05 +02:00
|
|
|
</row>
|
|
|
|
<row>
|
2001-09-15 21:56:59 +02:00
|
|
|
<entry><type>point</type></entry>
|
|
|
|
<entry><type>POINT*</type></entry>
|
2001-11-18 22:28:00 +01:00
|
|
|
<entry><filename>utils/geo_decls.h</filename></entry>
|
1999-07-22 17:11:05 +02:00
|
|
|
</row>
|
|
|
|
<row>
|
2001-09-15 21:56:59 +02:00
|
|
|
<entry><type>regproc</type></entry>
|
|
|
|
<entry><type>regproc</type></entry>
|
|
|
|
<entry><filename>postgres.h</filename></entry>
|
1999-07-22 17:11:05 +02:00
|
|
|
</row>
|
|
|
|
<row>
|
2001-09-15 21:56:59 +02:00
|
|
|
<entry><type>reltime</type></entry>
|
|
|
|
<entry><type>RelativeTime</type></entry>
|
|
|
|
<entry><filename>utils/nabstime.h</filename></entry>
|
1999-07-22 17:11:05 +02:00
|
|
|
</row>
|
|
|
|
<row>
|
2001-09-15 21:56:59 +02:00
|
|
|
<entry><type>text</type></entry>
|
|
|
|
<entry><type>text*</type></entry>
|
|
|
|
<entry><filename>postgres.h</filename></entry>
|
1999-07-22 17:11:05 +02:00
|
|
|
</row>
|
|
|
|
<row>
|
2001-09-15 21:56:59 +02:00
|
|
|
<entry><type>tid</type></entry>
|
|
|
|
<entry><type>ItemPointer</type></entry>
|
|
|
|
<entry><filename>storage/itemptr.h</filename></entry>
|
1999-07-22 17:11:05 +02:00
|
|
|
</row>
|
|
|
|
<row>
|
2001-09-15 21:56:59 +02:00
|
|
|
<entry><type>time</type></entry>
|
|
|
|
<entry><type>TimeADT</type></entry>
|
|
|
|
<entry><filename>utils/date.h</filename></entry>
|
1999-07-22 17:11:05 +02:00
|
|
|
</row>
|
|
|
|
<row>
|
2001-09-15 21:56:59 +02:00
|
|
|
<entry><type>time with time zone</type></entry>
|
|
|
|
<entry><type>TimeTzADT</type></entry>
|
|
|
|
<entry><filename>utils/date.h</filename></entry>
|
1999-07-22 17:11:05 +02:00
|
|
|
</row>
|
|
|
|
<row>
|
2001-09-15 21:56:59 +02:00
|
|
|
<entry><type>timestamp</type></entry>
|
|
|
|
<entry><type>Timestamp*</type></entry>
|
|
|
|
<entry><filename>utils/timestamp.h</filename></entry>
|
1999-07-22 17:11:05 +02:00
|
|
|
</row>
|
|
|
|
<row>
|
2001-09-15 21:56:59 +02:00
|
|
|
<entry><type>tinterval</type></entry>
|
|
|
|
<entry><type>TimeInterval</type></entry>
|
|
|
|
<entry><filename>utils/nabstime.h</filename></entry>
|
1999-07-22 17:11:05 +02:00
|
|
|
</row>
|
|
|
|
<row>
|
2001-09-15 21:56:59 +02:00
|
|
|
<entry><type>varchar</type></entry>
|
|
|
|
<entry><type>VarChar*</type></entry>
|
|
|
|
<entry><filename>postgres.h</filename></entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry><type>xid</type></entry>
|
|
|
|
<entry><type>TransactionId</type></entry>
|
|
|
|
<entry><filename>postgres.h</filename></entry>
|
1999-07-22 17:11:05 +02:00
|
|
|
</row>
|
|
|
|
</tbody>
|
|
|
|
</tgroup>
|
|
|
|
</table>
|
|
|
|
|
|
|
|
<para>
|
2001-11-21 07:09:45 +01:00
|
|
|
Internally, <productname>PostgreSQL</productname> regards a
|
2001-09-13 17:55:24 +02:00
|
|
|
base type as a <quote>blob of memory</quote>. The user-defined
|
1999-03-14 16:24:15 +01:00
|
|
|
functions that you define over a type in turn define the
|
2001-11-21 07:09:45 +01:00
|
|
|
way that <productname>PostgreSQL</productname> can operate
|
|
|
|
on it. That is, <productname>PostgreSQL</productname> will
|
1999-03-14 16:24:15 +01:00
|
|
|
only store and retrieve the data from disk and use your
|
|
|
|
user-defined functions to input, process, and output the data.
|
1998-03-01 09:16:16 +01:00
|
|
|
Base types can have one of three internal formats:
|
1999-07-22 17:11:05 +02:00
|
|
|
|
|
|
|
<itemizedlist>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
pass by value, fixed-length
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
pass by reference, fixed-length
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
pass by reference, variable-length
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
</itemizedlist>
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
1998-03-01 09:16:16 +01:00
|
|
|
By-value types can only be 1, 2 or 4 bytes in length
|
2001-09-15 21:56:59 +02:00
|
|
|
(also 8 bytes, if <literal>sizeof(Datum)</literal> is 8 on your machine).
|
2001-02-15 20:03:35 +01:00
|
|
|
You should be careful
|
1999-03-14 16:24:15 +01:00
|
|
|
to define your types such that they will be the same
|
|
|
|
size (in bytes) on all architectures. For example, the
|
1999-10-04 17:18:54 +02:00
|
|
|
<literal>long</literal> type is dangerous because it
|
1999-03-14 16:24:15 +01:00
|
|
|
is 4 bytes on some machines and 8 bytes on others, whereas
|
2001-09-15 21:56:59 +02:00
|
|
|
<type>int</type> type is 4 bytes on most
|
|
|
|
Unix machines. A reasonable implementation of
|
|
|
|
the <type>int4</type> type on Unix
|
1998-03-01 09:16:16 +01:00
|
|
|
machines might be:
|
|
|
|
|
2001-01-12 23:15:32 +01:00
|
|
|
<programlisting>
|
1999-07-22 17:11:05 +02:00
|
|
|
/* 4-byte integer, passed by value */
|
|
|
|
typedef int int4;
|
2001-01-12 23:15:32 +01:00
|
|
|
</programlisting>
|
2001-09-15 21:56:59 +02:00
|
|
|
|
|
|
|
<productname>PostgreSQL</productname> automatically figures
|
|
|
|
things out so that the integer types really have the size they
|
|
|
|
advertise.
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<para>
|
1998-03-01 09:16:16 +01:00
|
|
|
On the other hand, fixed-length types of any size may
|
|
|
|
be passed by-reference. For example, here is a sample
|
2001-09-15 21:56:59 +02:00
|
|
|
implementation of a <productname>PostgreSQL</productname> type:
|
1998-03-01 09:16:16 +01:00
|
|
|
|
2001-01-12 23:15:32 +01:00
|
|
|
<programlisting>
|
1999-07-22 17:11:05 +02:00
|
|
|
/* 16-byte structure, passed by reference */
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
double x, y;
|
|
|
|
} Point;
|
2001-01-12 23:15:32 +01:00
|
|
|
</programlisting>
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
1998-03-01 09:16:16 +01:00
|
|
|
Only pointers to such types can be used when passing
|
2001-11-21 07:09:45 +01:00
|
|
|
them in and out of <productname>PostgreSQL</productname> functions.
|
2000-08-25 01:36:29 +02:00
|
|
|
To return a value of such a type, allocate the right amount of
|
|
|
|
memory with <literal>palloc()</literal>, fill in the allocated memory,
|
2001-02-15 20:03:35 +01:00
|
|
|
and return a pointer to it. (Alternatively, you can return an input
|
|
|
|
value of the same type by returning its pointer. <emphasis>Never</>
|
|
|
|
modify the contents of a pass-by-reference input value, however.)
|
2000-08-25 01:36:29 +02:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
1998-03-01 09:16:16 +01:00
|
|
|
Finally, all variable-length types must also be passed
|
|
|
|
by reference. All variable-length types must begin
|
|
|
|
with a length field of exactly 4 bytes, and all data to
|
|
|
|
be stored within that type must be located in the memory
|
|
|
|
immediately following that length field. The
|
|
|
|
length field is the total length of the structure
|
|
|
|
(i.e., it includes the size of the length field
|
|
|
|
itself). We can define the text type as follows:
|
1999-07-22 17:11:05 +02:00
|
|
|
|
2001-01-12 23:15:32 +01:00
|
|
|
<programlisting>
|
1999-07-22 17:11:05 +02:00
|
|
|
typedef struct {
|
|
|
|
int4 length;
|
|
|
|
char data[1];
|
|
|
|
} text;
|
2001-01-12 23:15:32 +01:00
|
|
|
</programlisting>
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2001-11-14 23:14:22 +01:00
|
|
|
Obviously, the data field declared here is not long enough to hold
|
|
|
|
all possible strings. Since it's impossible to declare a variable-size
|
|
|
|
structure in <acronym>C</acronym>, we rely on the knowledge that the
|
|
|
|
<acronym>C</acronym> compiler won't range-check array subscripts. We
|
|
|
|
just allocate the necessary amount of space and then access the array as
|
|
|
|
if it were declared the right length. (If this isn't a familiar trick to
|
|
|
|
you, you may wish to spend some time with an introductory
|
|
|
|
<acronym>C</acronym> programming textbook before delving deeper into
|
2001-11-21 07:09:45 +01:00
|
|
|
<productname>PostgreSQL</productname> server programming.)
|
2001-11-14 23:14:22 +01:00
|
|
|
When manipulating
|
1999-03-14 16:24:15 +01:00
|
|
|
variable-length types, we must be careful to allocate
|
2001-11-14 23:14:22 +01:00
|
|
|
the correct amount of memory and set the length field correctly.
|
1999-03-14 16:24:15 +01:00
|
|
|
For example, if we wanted to store 40 bytes in a text
|
1998-03-01 09:16:16 +01:00
|
|
|
structure, we might use a code fragment like this:
|
|
|
|
|
2001-01-12 23:15:32 +01:00
|
|
|
<programlisting>
|
1999-07-22 17:11:05 +02:00
|
|
|
#include "postgres.h"
|
|
|
|
...
|
|
|
|
char buffer[40]; /* our source data */
|
|
|
|
...
|
|
|
|
text *destination = (text *) palloc(VARHDRSZ + 40);
|
|
|
|
destination->length = VARHDRSZ + 40;
|
2001-11-14 23:14:22 +01:00
|
|
|
memcpy(destination->data, buffer, 40);
|
1999-07-22 17:11:05 +02:00
|
|
|
...
|
2001-01-12 23:15:32 +01:00
|
|
|
</programlisting>
|
2001-11-14 23:14:22 +01:00
|
|
|
|
|
|
|
<literal>VARHDRSZ</> is the same as <literal>sizeof(int4)</>, but
|
|
|
|
it's considered good style to use the macro <literal>VARHDRSZ</>
|
|
|
|
to refer to the size of the overhead for a variable-length type.
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
1998-03-01 09:16:16 +01:00
|
|
|
Now that we've gone over all of the possible structures
|
2000-08-25 01:36:29 +02:00
|
|
|
for base types, we can show some examples of real functions.
|
|
|
|
</para>
|
|
|
|
</sect2>
|
|
|
|
|
|
|
|
<sect2>
|
2000-11-20 21:36:57 +01:00
|
|
|
<title>Version-0 Calling Conventions for C-Language Functions</title>
|
2000-08-25 01:36:29 +02:00
|
|
|
|
|
|
|
<para>
|
2001-01-12 23:15:32 +01:00
|
|
|
We present the <quote>old style</quote> calling convention first --- although
|
2000-08-25 01:36:29 +02:00
|
|
|
this approach is now deprecated, it's easier to get a handle on
|
2000-11-20 21:36:57 +01:00
|
|
|
initially. In the version-0 method, the arguments and result
|
2000-08-25 01:36:29 +02:00
|
|
|
of the C function are just declared in normal C style, but being
|
|
|
|
careful to use the C representation of each SQL data type as shown
|
|
|
|
above.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Here are some examples:
|
1999-07-22 17:11:05 +02:00
|
|
|
|
2001-01-12 23:15:32 +01:00
|
|
|
<programlisting>
|
2000-05-02 22:02:03 +02:00
|
|
|
#include "postgres.h"
|
2001-02-15 20:03:35 +01:00
|
|
|
#include <string.h>
|
1999-03-14 16:24:15 +01:00
|
|
|
|
2000-05-02 22:02:03 +02:00
|
|
|
/* By Value */
|
1999-03-14 16:24:15 +01:00
|
|
|
|
2000-05-02 22:02:03 +02:00
|
|
|
int
|
|
|
|
add_one(int arg)
|
|
|
|
{
|
2000-08-25 01:36:29 +02:00
|
|
|
return arg + 1;
|
2000-05-02 22:02:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* By Reference, Fixed Length */
|
|
|
|
|
2000-08-25 01:36:29 +02:00
|
|
|
float8 *
|
|
|
|
add_one_float8(float8 *arg)
|
|
|
|
{
|
|
|
|
float8 *result = (float8 *) palloc(sizeof(float8));
|
|
|
|
|
|
|
|
*result = *arg + 1.0;
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2000-05-02 22:02:03 +02:00
|
|
|
Point *
|
2000-08-25 01:36:29 +02:00
|
|
|
makepoint(Point *pointx, Point *pointy)
|
2000-05-02 22:02:03 +02:00
|
|
|
{
|
|
|
|
Point *new_point = (Point *) palloc(sizeof(Point));
|
|
|
|
|
|
|
|
new_point->x = pointx->x;
|
|
|
|
new_point->y = pointy->y;
|
|
|
|
|
|
|
|
return new_point;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* By Reference, Variable Length */
|
|
|
|
|
|
|
|
text *
|
|
|
|
copytext(text *t)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* VARSIZE is the total size of the struct in bytes.
|
|
|
|
*/
|
|
|
|
text *new_t = (text *) palloc(VARSIZE(t));
|
2000-08-25 01:36:29 +02:00
|
|
|
VARATT_SIZEP(new_t) = VARSIZE(t);
|
2000-05-02 22:02:03 +02:00
|
|
|
/*
|
|
|
|
* VARDATA is a pointer to the data region of the struct.
|
|
|
|
*/
|
|
|
|
memcpy((void *) VARDATA(new_t), /* destination */
|
|
|
|
(void *) VARDATA(t), /* source */
|
2000-08-25 01:36:29 +02:00
|
|
|
VARSIZE(t)-VARHDRSZ); /* how many bytes */
|
|
|
|
return new_t;
|
2000-05-02 22:02:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
text *
|
|
|
|
concat_text(text *arg1, text *arg2)
|
|
|
|
{
|
|
|
|
int32 new_text_size = VARSIZE(arg1) + VARSIZE(arg2) - VARHDRSZ;
|
|
|
|
text *new_text = (text *) palloc(new_text_size);
|
|
|
|
|
2000-08-25 01:36:29 +02:00
|
|
|
VARATT_SIZEP(new_text) = new_text_size;
|
2001-02-15 20:03:35 +01:00
|
|
|
memcpy(VARDATA(new_text), VARDATA(arg1), VARSIZE(arg1)-VARHDRSZ);
|
|
|
|
memcpy(VARDATA(new_text) + (VARSIZE(arg1)-VARHDRSZ),
|
|
|
|
VARDATA(arg2), VARSIZE(arg2)-VARHDRSZ);
|
2000-08-25 01:36:29 +02:00
|
|
|
return new_text;
|
2000-05-02 22:02:03 +02:00
|
|
|
}
|
2001-01-12 23:15:32 +01:00
|
|
|
</programlisting>
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<para>
|
2000-08-25 01:36:29 +02:00
|
|
|
Supposing that the above code has been prepared in file
|
|
|
|
<filename>funcs.c</filename> and compiled into a shared object,
|
2001-11-21 07:09:45 +01:00
|
|
|
we could define the functions to <productname>PostgreSQL</productname>
|
2000-08-25 01:36:29 +02:00
|
|
|
with commands like this:
|
1998-03-01 09:16:16 +01:00
|
|
|
|
2001-01-12 23:15:32 +01:00
|
|
|
<programlisting>
|
2000-05-02 22:02:03 +02:00
|
|
|
CREATE FUNCTION add_one(int4) RETURNS int4
|
2001-10-26 23:17:03 +02:00
|
|
|
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs' LANGUAGE C
|
2000-08-25 01:36:29 +02:00
|
|
|
WITH (isStrict);
|
2000-05-02 22:02:03 +02:00
|
|
|
|
2000-08-25 01:36:29 +02:00
|
|
|
-- note overloading of SQL function name add_one()
|
|
|
|
CREATE FUNCTION add_one(float8) RETURNS float8
|
2001-10-26 21:58:12 +02:00
|
|
|
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs',
|
2000-08-25 01:36:29 +02:00
|
|
|
'add_one_float8'
|
2001-10-26 23:17:03 +02:00
|
|
|
LANGUAGE C WITH (isStrict);
|
2000-05-02 22:02:03 +02:00
|
|
|
|
2000-08-25 01:36:29 +02:00
|
|
|
CREATE FUNCTION makepoint(point, point) RETURNS point
|
2001-10-26 23:17:03 +02:00
|
|
|
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs' LANGUAGE C
|
2000-08-25 01:36:29 +02:00
|
|
|
WITH (isStrict);
|
2000-05-02 22:02:03 +02:00
|
|
|
|
|
|
|
CREATE FUNCTION copytext(text) RETURNS text
|
2001-10-26 23:17:03 +02:00
|
|
|
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs' LANGUAGE C
|
2000-08-25 01:36:29 +02:00
|
|
|
WITH (isStrict);
|
|
|
|
|
|
|
|
CREATE FUNCTION concat_text(text, text) RETURNS text
|
2001-10-26 23:17:03 +02:00
|
|
|
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs' LANGUAGE C
|
2000-08-25 01:36:29 +02:00
|
|
|
WITH (isStrict);
|
2001-01-12 23:15:32 +01:00
|
|
|
</programlisting>
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<para>
|
2000-08-25 01:36:29 +02:00
|
|
|
Here <replaceable>PGROOT</replaceable> stands for the full path to
|
2001-11-21 07:09:45 +01:00
|
|
|
the <productname>PostgreSQL</productname> source tree. (Better style would
|
2001-10-26 21:58:12 +02:00
|
|
|
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>.)
|
2000-08-25 01:36:29 +02:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2001-10-26 21:58:12 +02:00
|
|
|
Notice that we have specified the functions as <quote>strict</quote>,
|
|
|
|
meaning that
|
2000-08-25 01:36:29 +02:00
|
|
|
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
|
|
|
|
explicitly, for example by checking for a null pointer for each
|
|
|
|
pass-by-reference argument. (For pass-by-value arguments, we don't
|
|
|
|
even have a way to check!)
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2000-11-20 21:36:57 +01:00
|
|
|
Although this calling convention is simple to use,
|
2000-08-25 01:36:29 +02:00
|
|
|
it is not very portable; on some architectures there are problems
|
|
|
|
with passing smaller-than-int data types this way. Also, there is
|
|
|
|
no simple way to return a NULL result, nor to cope with NULL arguments
|
2000-11-20 21:36:57 +01:00
|
|
|
in any way other than making the function strict. The version-1
|
2000-08-25 01:36:29 +02:00
|
|
|
convention, presented next, overcomes these objections.
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
|
|
|
</sect2>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<sect2>
|
2000-11-20 21:36:57 +01:00
|
|
|
<title>Version-1 Calling Conventions for C-Language Functions</title>
|
2000-08-25 01:36:29 +02:00
|
|
|
|
|
|
|
<para>
|
2000-11-20 21:36:57 +01:00
|
|
|
The version-1 calling convention relies on macros to suppress most
|
2000-08-25 01:36:29 +02:00
|
|
|
of the complexity of passing arguments and results. The C declaration
|
2000-11-20 21:36:57 +01:00
|
|
|
of a version-1 function is always
|
2001-01-12 23:15:32 +01:00
|
|
|
<programlisting>
|
|
|
|
Datum funcname(PG_FUNCTION_ARGS)
|
|
|
|
</programlisting>
|
2000-11-20 21:36:57 +01:00
|
|
|
In addition, the macro call
|
2001-01-12 23:15:32 +01:00
|
|
|
<programlisting>
|
|
|
|
PG_FUNCTION_INFO_V1(funcname);
|
|
|
|
</programlisting>
|
2000-11-20 21:36:57 +01:00
|
|
|
must appear in the same source file (conventionally it's written
|
|
|
|
just before the function itself). This macro call is not needed
|
2001-11-21 07:09:45 +01:00
|
|
|
for <literal>internal</>-language functions, since
|
|
|
|
<productname>PostgreSQL</> currently
|
2001-10-26 21:58:12 +02:00
|
|
|
assumes all internal functions are version-1. However, it is
|
2000-11-20 21:36:57 +01:00
|
|
|
<emphasis>required</emphasis> for dynamically-loaded functions.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2001-01-12 23:15:32 +01:00
|
|
|
In a version-1 function, each actual argument is fetched using a
|
|
|
|
<function>PG_GETARG_<replaceable>xxx</replaceable>()</function>
|
2002-03-22 20:20:45 +01:00
|
|
|
macro that corresponds to the argument's data type, and the result
|
2001-01-12 23:15:32 +01:00
|
|
|
is returned using a
|
2001-01-22 17:11:17 +01:00
|
|
|
<function>PG_RETURN_<replaceable>xxx</replaceable>()</function>
|
2001-01-12 23:15:32 +01:00
|
|
|
macro for the return type.
|
2000-08-25 01:36:29 +02:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2001-01-22 17:11:17 +01:00
|
|
|
Here we show the same functions as above, coded in version-1 style:
|
2000-08-25 01:36:29 +02:00
|
|
|
|
2001-01-12 23:15:32 +01:00
|
|
|
<programlisting>
|
2000-08-25 01:36:29 +02:00
|
|
|
#include "postgres.h"
|
2001-02-15 20:03:35 +01:00
|
|
|
#include <string.h>
|
2000-08-25 01:36:29 +02:00
|
|
|
#include "fmgr.h"
|
|
|
|
|
|
|
|
/* By Value */
|
2000-11-20 21:36:57 +01:00
|
|
|
|
|
|
|
PG_FUNCTION_INFO_V1(add_one);
|
2000-08-25 01:36:29 +02:00
|
|
|
|
|
|
|
Datum
|
|
|
|
add_one(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
int32 arg = PG_GETARG_INT32(0);
|
|
|
|
|
|
|
|
PG_RETURN_INT32(arg + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* By Reference, Fixed Length */
|
|
|
|
|
2000-11-20 21:36:57 +01:00
|
|
|
PG_FUNCTION_INFO_V1(add_one_float8);
|
|
|
|
|
2000-08-25 01:36:29 +02:00
|
|
|
Datum
|
|
|
|
add_one_float8(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
/* The macros for FLOAT8 hide its pass-by-reference nature */
|
|
|
|
float8 arg = PG_GETARG_FLOAT8(0);
|
|
|
|
|
|
|
|
PG_RETURN_FLOAT8(arg + 1.0);
|
|
|
|
}
|
|
|
|
|
2000-11-20 21:36:57 +01:00
|
|
|
PG_FUNCTION_INFO_V1(makepoint);
|
|
|
|
|
2000-08-25 01:36:29 +02:00
|
|
|
Datum
|
|
|
|
makepoint(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2001-01-22 17:11:17 +01:00
|
|
|
/* Here, the pass-by-reference nature of Point is not hidden */
|
2000-08-25 01:36:29 +02:00
|
|
|
Point *pointx = PG_GETARG_POINT_P(0);
|
|
|
|
Point *pointy = PG_GETARG_POINT_P(1);
|
|
|
|
Point *new_point = (Point *) palloc(sizeof(Point));
|
|
|
|
|
|
|
|
new_point->x = pointx->x;
|
|
|
|
new_point->y = pointy->y;
|
|
|
|
|
|
|
|
PG_RETURN_POINT_P(new_point);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* By Reference, Variable Length */
|
|
|
|
|
2000-11-20 21:36:57 +01:00
|
|
|
PG_FUNCTION_INFO_V1(copytext);
|
|
|
|
|
2000-08-25 01:36:29 +02:00
|
|
|
Datum
|
|
|
|
copytext(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
text *t = PG_GETARG_TEXT_P(0);
|
|
|
|
/*
|
|
|
|
* VARSIZE is the total size of the struct in bytes.
|
|
|
|
*/
|
|
|
|
text *new_t = (text *) palloc(VARSIZE(t));
|
|
|
|
VARATT_SIZEP(new_t) = VARSIZE(t);
|
|
|
|
/*
|
|
|
|
* VARDATA is a pointer to the data region of the struct.
|
|
|
|
*/
|
|
|
|
memcpy((void *) VARDATA(new_t), /* destination */
|
|
|
|
(void *) VARDATA(t), /* source */
|
2001-02-15 20:03:35 +01:00
|
|
|
VARSIZE(t)-VARHDRSZ); /* how many bytes */
|
2000-08-25 01:36:29 +02:00
|
|
|
PG_RETURN_TEXT_P(new_t);
|
|
|
|
}
|
|
|
|
|
2000-11-20 21:36:57 +01:00
|
|
|
PG_FUNCTION_INFO_V1(concat_text);
|
|
|
|
|
2000-08-25 01:36:29 +02:00
|
|
|
Datum
|
|
|
|
concat_text(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
text *arg1 = PG_GETARG_TEXT_P(0);
|
|
|
|
text *arg2 = PG_GETARG_TEXT_P(1);
|
|
|
|
int32 new_text_size = VARSIZE(arg1) + VARSIZE(arg2) - VARHDRSZ;
|
|
|
|
text *new_text = (text *) palloc(new_text_size);
|
|
|
|
|
|
|
|
VARATT_SIZEP(new_text) = new_text_size;
|
2001-02-15 20:03:35 +01:00
|
|
|
memcpy(VARDATA(new_text), VARDATA(arg1), VARSIZE(arg1)-VARHDRSZ);
|
|
|
|
memcpy(VARDATA(new_text) + (VARSIZE(arg1)-VARHDRSZ),
|
|
|
|
VARDATA(arg2), VARSIZE(arg2)-VARHDRSZ);
|
2000-08-25 01:36:29 +02:00
|
|
|
PG_RETURN_TEXT_P(new_text);
|
|
|
|
}
|
2001-01-12 23:15:32 +01:00
|
|
|
</programlisting>
|
2000-08-25 01:36:29 +02:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The <command>CREATE FUNCTION</command> commands are the same as
|
2001-01-22 17:11:17 +01:00
|
|
|
for the version-0 equivalents.
|
2000-08-25 01:36:29 +02:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2001-01-12 23:15:32 +01:00
|
|
|
At first glance, the version-1 coding conventions may appear to
|
|
|
|
be just pointless obscurantism. However, they do offer a number
|
|
|
|
of improvements, because the macros can hide unnecessary detail.
|
2002-01-07 03:29:15 +01:00
|
|
|
An example is that in coding <function>add_one_float8</>, we no longer need to
|
|
|
|
be aware that <type>float8</type> is a pass-by-reference type. Another
|
|
|
|
example is that the <literal>GETARG</> macros for variable-length types hide
|
2001-09-13 17:55:24 +02:00
|
|
|
the need to deal with fetching <quote>toasted</quote> (compressed or
|
2001-01-12 23:15:32 +01:00
|
|
|
out-of-line) values. The old-style <function>copytext</function>
|
|
|
|
and <function>concat_text</function> functions shown above are
|
|
|
|
actually wrong in the presence of toasted values, because they
|
|
|
|
don't call <function>pg_detoast_datum()</function> on their
|
|
|
|
inputs. (The handler for old-style dynamically-loaded functions
|
|
|
|
currently takes care of this detail, but it does so less
|
|
|
|
efficiently than is possible for a version-1 function.)
|
2000-08-25 01:36:29 +02:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2001-02-15 20:03:35 +01:00
|
|
|
One big improvement in version-1 functions is better handling of NULL
|
2002-01-07 03:29:15 +01:00
|
|
|
inputs and results. The macro <function>PG_ARGISNULL(<replaceable>n</>)</function>
|
2001-02-15 20:03:35 +01:00
|
|
|
allows a function to test whether each input is NULL (of course, doing
|
|
|
|
this is only necessary in functions not declared <quote>strict</>).
|
|
|
|
As with the
|
|
|
|
<function>PG_GETARG_<replaceable>xxx</replaceable>()</function> macros,
|
2001-10-26 21:58:12 +02:00
|
|
|
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.
|
2001-02-15 20:03:35 +01:00
|
|
|
To return a NULL result, execute <function>PG_RETURN_NULL()</function>;
|
2002-01-07 03:29:15 +01:00
|
|
|
this works in both strict and nonstrict functions.
|
2001-02-15 20:03:35 +01:00
|
|
|
</para>
|
|
|
|
|
2002-03-05 06:33:31 +01:00
|
|
|
<para>
|
|
|
|
Other options provided in the new-style interface are two
|
|
|
|
variants of the
|
|
|
|
<function>PG_GETARG_<replaceable>xxx</replaceable>()</function>
|
|
|
|
macros. The first of these,
|
|
|
|
<function>PG_GETARG_<replaceable>xxx</replaceable>_COPY()</function>
|
|
|
|
guarantees to return a copy of the specified parameter which is
|
|
|
|
safe for writing into. (The normal macros will sometimes return a
|
2002-08-29 02:17:06 +02:00
|
|
|
pointer to a value that is physically stored in a table, and so
|
|
|
|
must not be written to. Using the
|
2002-03-05 06:33:31 +01:00
|
|
|
<function>PG_GETARG_<replaceable>xxx</replaceable>_COPY()</function>
|
|
|
|
macros guarantees a writable result.)
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The second variant consists of the
|
|
|
|
<function>PG_GETARG_<replaceable>xxx</replaceable>_SLICE()</function>
|
|
|
|
macros which take three parameters. The first is the number of the
|
|
|
|
parameter (as above). The second and third are the offset and
|
|
|
|
length of the segment to be returned. Offsets are counted from
|
|
|
|
zero, and a negative length requests that the remainder of the
|
|
|
|
value be returned. These routines provide more efficient access to
|
|
|
|
parts of large values in the case where they have storage type
|
|
|
|
"external". (The storage type of a column can be specified using
|
2002-03-11 06:03:52 +01:00
|
|
|
<literal>ALTER TABLE <replaceable>tablename</replaceable> ALTER
|
2002-03-05 06:33:31 +01:00
|
|
|
COLUMN <replaceable>colname</replaceable> SET STORAGE
|
2002-03-11 06:03:52 +01:00
|
|
|
<replaceable>storagetype</replaceable></literal>. Storage type is one of
|
|
|
|
<literal>plain</>, <literal>external</>, <literal>extended</literal>,
|
|
|
|
or <literal>main</>.)
|
2002-03-05 06:33:31 +01:00
|
|
|
</para>
|
|
|
|
|
2001-02-15 20:03:35 +01:00
|
|
|
<para>
|
|
|
|
The version-1 function call conventions make it possible to
|
|
|
|
return <quote>set</quote> results and implement trigger functions and
|
2001-01-22 17:11:17 +01:00
|
|
|
procedural-language call handlers. Version-1 code is also more
|
|
|
|
portable than version-0, because it does not break ANSI C restrictions
|
|
|
|
on function call protocol. For more details see
|
2001-01-12 23:15:32 +01:00
|
|
|
<filename>src/backend/utils/fmgr/README</filename> in the source
|
|
|
|
distribution.
|
2000-08-25 01:36:29 +02:00
|
|
|
</para>
|
|
|
|
</sect2>
|
|
|
|
|
|
|
|
<sect2>
|
|
|
|
<title>Composite Types in C-Language Functions</title>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<para>
|
1998-03-01 09:16:16 +01:00
|
|
|
Composite types do not have a fixed layout like C
|
|
|
|
structures. Instances of a composite type may contain
|
|
|
|
null fields. In addition, composite types that are
|
|
|
|
part of an inheritance hierarchy may have different
|
|
|
|
fields than other members of the same inheritance hierarchy.
|
2001-11-21 07:09:45 +01:00
|
|
|
Therefore, <productname>PostgreSQL</productname> provides
|
1999-03-14 16:24:15 +01:00
|
|
|
a procedural interface for accessing fields of composite types
|
2001-11-21 07:09:45 +01:00
|
|
|
from C. As <productname>PostgreSQL</productname> processes
|
2001-01-14 00:58:55 +01:00
|
|
|
a set of rows, each row will be passed into your
|
1999-10-04 17:18:54 +02:00
|
|
|
function as an opaque structure of type <literal>TUPLE</literal>.
|
1998-03-01 09:16:16 +01:00
|
|
|
Suppose we want to write a function to answer the query
|
1999-07-22 17:11:05 +02:00
|
|
|
|
2001-01-12 23:15:32 +01:00
|
|
|
<programlisting>
|
|
|
|
SELECT name, c_overpaid(emp, 1500) AS overpaid
|
|
|
|
FROM emp
|
|
|
|
WHERE name = 'Bill' OR name = 'Sam';
|
|
|
|
</programlisting>
|
1999-07-22 17:11:05 +02:00
|
|
|
|
2002-01-07 03:29:15 +01:00
|
|
|
In the query above, we can define <function>c_overpaid</> as:
|
1998-03-01 09:16:16 +01:00
|
|
|
|
2001-01-12 23:15:32 +01:00
|
|
|
<programlisting>
|
2000-05-02 22:02:03 +02:00
|
|
|
#include "postgres.h"
|
|
|
|
#include "executor/executor.h" /* for GetAttributeByName() */
|
|
|
|
|
|
|
|
bool
|
2001-01-14 00:58:55 +01:00
|
|
|
c_overpaid(TupleTableSlot *t, /* the current row of EMP */
|
2000-08-25 01:36:29 +02:00
|
|
|
int32 limit)
|
2000-05-02 22:02:03 +02:00
|
|
|
{
|
2000-08-25 01:36:29 +02:00
|
|
|
bool isnull;
|
|
|
|
int32 salary;
|
|
|
|
|
|
|
|
salary = DatumGetInt32(GetAttributeByName(t, "salary", &isnull));
|
2000-05-02 22:02:03 +02:00
|
|
|
if (isnull)
|
|
|
|
return (false);
|
2000-08-25 01:36:29 +02:00
|
|
|
return salary > limit;
|
|
|
|
}
|
|
|
|
|
2000-11-20 21:36:57 +01:00
|
|
|
/* In version-1 coding, the above would look like this: */
|
|
|
|
|
|
|
|
PG_FUNCTION_INFO_V1(c_overpaid);
|
2000-08-25 01:36:29 +02:00
|
|
|
|
|
|
|
Datum
|
|
|
|
c_overpaid(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
TupleTableSlot *t = (TupleTableSlot *) PG_GETARG_POINTER(0);
|
|
|
|
int32 limit = PG_GETARG_INT32(1);
|
|
|
|
bool isnull;
|
|
|
|
int32 salary;
|
|
|
|
|
|
|
|
salary = DatumGetInt32(GetAttributeByName(t, "salary", &isnull));
|
|
|
|
if (isnull)
|
|
|
|
PG_RETURN_BOOL(false);
|
|
|
|
/* Alternatively, we might prefer to do PG_RETURN_NULL() for null salary */
|
|
|
|
|
|
|
|
PG_RETURN_BOOL(salary > limit);
|
2000-05-02 22:02:03 +02:00
|
|
|
}
|
2001-01-12 23:15:32 +01:00
|
|
|
</programlisting>
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<para>
|
1999-10-04 17:18:54 +02:00
|
|
|
<function>GetAttributeByName</function> is the
|
2001-11-21 07:09:45 +01:00
|
|
|
<productname>PostgreSQL</productname> system function that
|
2001-01-14 00:58:55 +01:00
|
|
|
returns attributes out of the current row. It has
|
2001-01-12 23:15:32 +01:00
|
|
|
three arguments: the argument of type <type>TupleTableSlot*</type> passed into
|
1998-03-01 09:16:16 +01:00
|
|
|
the function, the name of the desired attribute, and a
|
2000-08-25 01:36:29 +02:00
|
|
|
return parameter that tells whether the attribute
|
2002-01-07 03:29:15 +01:00
|
|
|
is null. <function>GetAttributeByName</function> returns a <type>Datum</type>
|
|
|
|
value that you can convert to the proper data type by using the
|
2001-01-12 23:15:32 +01:00
|
|
|
appropriate <function>DatumGet<replaceable>XXX</replaceable>()</function> macro.
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<para>
|
2002-01-07 03:29:15 +01:00
|
|
|
The following command lets <productname>PostgreSQL</productname>
|
2001-01-12 23:15:32 +01:00
|
|
|
know about the <function>c_overpaid</function> function:
|
1999-07-22 17:11:05 +02:00
|
|
|
|
2001-01-12 23:15:32 +01:00
|
|
|
<programlisting>
|
|
|
|
CREATE FUNCTION c_overpaid(emp, int4)
|
2000-05-20 13:24:37 +02:00
|
|
|
RETURNS bool
|
2001-10-26 23:17:03 +02:00
|
|
|
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs'
|
|
|
|
LANGUAGE C;
|
2002-07-18 06:47:17 +02:00
|
|
|
</programlisting>
|
|
|
|
</para>
|
|
|
|
</sect2>
|
|
|
|
|
|
|
|
<sect2>
|
|
|
|
<title>Table Function API</title>
|
|
|
|
|
|
|
|
<para>
|
2002-08-29 02:17:06 +02:00
|
|
|
The Table Function API assists in the creation of user-defined
|
|
|
|
C language table functions (<xref linkend="xfunc-tablefunctions">).
|
2002-07-18 06:47:17 +02:00
|
|
|
Table functions are functions that produce a set of rows, made up of
|
|
|
|
either base (scalar) data types, or composite (multi-column) data types.
|
|
|
|
The API is split into two main components: support for returning
|
|
|
|
composite data types, and support for returning multiple rows
|
|
|
|
(set returning functions or SRFs).
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The Table Function API relies on macros and functions to suppress most
|
2002-08-29 02:17:06 +02:00
|
|
|
of the complexity of building composite data types and returning multiple
|
|
|
|
results. A table function must follow the version-1 calling convention
|
|
|
|
described above. In addition, the source file must include:
|
2002-07-18 06:47:17 +02:00
|
|
|
<programlisting>
|
|
|
|
#include "funcapi.h"
|
|
|
|
</programlisting>
|
|
|
|
</para>
|
|
|
|
|
2002-08-29 02:17:06 +02:00
|
|
|
<sect3>
|
|
|
|
<title>Returning Tuples (Composite Types)</title>
|
|
|
|
|
2002-07-18 06:47:17 +02:00
|
|
|
<para>
|
|
|
|
The Table Function API support for returning composite data types
|
|
|
|
(or tuples) starts with the AttInMetadata struct. This struct holds
|
|
|
|
arrays of individual attribute information needed to create a tuple from
|
2002-08-29 02:17:06 +02:00
|
|
|
raw C strings. It also saves a pointer to the TupleDesc. The information
|
2002-07-18 06:47:17 +02:00
|
|
|
carried here is derived from the TupleDesc, but it is stored here to
|
2002-08-29 02:17:06 +02:00
|
|
|
avoid redundant CPU cycles on each call to a Table Function. In the
|
|
|
|
case of a function returning a set, the AttInMetadata struct should be
|
|
|
|
computed once during the first call and saved for re-use in later calls.
|
2002-07-18 06:47:17 +02:00
|
|
|
<programlisting>
|
2002-08-29 02:17:06 +02:00
|
|
|
typedef struct AttInMetadata
|
2002-07-18 06:47:17 +02:00
|
|
|
{
|
2002-08-29 02:17:06 +02:00
|
|
|
/* full TupleDesc */
|
|
|
|
TupleDesc tupdesc;
|
2002-07-18 06:47:17 +02:00
|
|
|
|
2002-08-29 02:17:06 +02:00
|
|
|
/* array of attribute type input function finfo */
|
|
|
|
FmgrInfo *attinfuncs;
|
2002-07-18 06:47:17 +02:00
|
|
|
|
2002-08-29 02:17:06 +02:00
|
|
|
/* array of attribute type typelem */
|
|
|
|
Oid *attelems;
|
2002-07-18 06:47:17 +02:00
|
|
|
|
2002-08-29 02:17:06 +02:00
|
|
|
/* array of attribute typmod */
|
|
|
|
int32 *atttypmods;
|
2002-07-18 06:47:17 +02:00
|
|
|
} AttInMetadata;
|
|
|
|
</programlisting>
|
|
|
|
To assist you in populating this struct, several functions and a macro
|
|
|
|
are available. Use
|
|
|
|
<programlisting>
|
2002-08-29 02:17:06 +02:00
|
|
|
TupleDesc RelationNameGetTupleDesc(const char *relname)
|
2002-07-18 06:47:17 +02:00
|
|
|
</programlisting>
|
2002-08-29 02:17:06 +02:00
|
|
|
to get a TupleDesc based on a specified relation, or
|
2002-07-18 06:47:17 +02:00
|
|
|
<programlisting>
|
|
|
|
TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases)
|
|
|
|
</programlisting>
|
2002-08-29 02:17:06 +02:00
|
|
|
to get a TupleDesc based on a type OID. This can be used to
|
|
|
|
get a TupleDesc for a base (scalar) or composite (relation) type. Then
|
2002-07-18 06:47:17 +02:00
|
|
|
<programlisting>
|
|
|
|
AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc)
|
|
|
|
</programlisting>
|
|
|
|
will return a pointer to an AttInMetadata struct, initialized based on
|
2002-08-29 02:17:06 +02:00
|
|
|
the given TupleDesc. AttInMetadata can be used in conjunction with
|
2002-07-18 06:47:17 +02:00
|
|
|
C strings to produce a properly formed tuple. The metadata is stored here
|
2002-08-29 02:17:06 +02:00
|
|
|
to avoid redundant work across multiple calls.
|
2002-07-18 06:47:17 +02:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2002-08-29 02:17:06 +02:00
|
|
|
To return a tuple you must create a tuple slot based on the
|
2002-07-18 06:47:17 +02:00
|
|
|
TupleDesc. You can use
|
|
|
|
<programlisting>
|
|
|
|
TupleTableSlot *TupleDescGetSlot(TupleDesc tupdesc)
|
|
|
|
</programlisting>
|
|
|
|
to initialize this tuple slot, or obtain one through other (user provided)
|
|
|
|
means. The tuple slot is needed to create a Datum for return by the
|
2002-08-29 02:17:06 +02:00
|
|
|
function. The same slot can (and should) be re-used on each call.
|
2002-07-18 06:47:17 +02:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2002-08-29 02:17:06 +02:00
|
|
|
After constructing an AttInMetadata structure,
|
2002-07-18 06:47:17 +02:00
|
|
|
<programlisting>
|
|
|
|
HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
|
|
|
|
</programlisting>
|
|
|
|
can be used to build a HeapTuple given user data in C string form.
|
|
|
|
"values" is an array of C strings, one for each attribute of the return
|
2002-08-29 02:17:06 +02:00
|
|
|
tuple. Each C string should be in the form expected by the input function
|
|
|
|
of the attribute data type. In order to return a NULL value for
|
2002-07-18 06:47:17 +02:00
|
|
|
one of the attributes, the corresponding pointer in the "values" array
|
2002-08-29 02:17:06 +02:00
|
|
|
should be set to NULL. This function will need to be called again
|
|
|
|
for each tuple you return.
|
2002-07-18 06:47:17 +02:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2002-08-29 02:17:06 +02:00
|
|
|
Building a tuple via TupleDescGetAttInMetadata and BuildTupleFromCStrings
|
|
|
|
is only convenient if your function naturally computes the values to
|
|
|
|
be returned as text strings. If your code naturally computes the
|
|
|
|
values as a set of Datums, you should instead use the underlying
|
|
|
|
heap_formtuple routine to convert the Datums directly into a tuple.
|
|
|
|
You will still need the TupleDesc and a TupleTableSlot, but not
|
|
|
|
AttInMetadata.
|
2002-07-30 18:20:03 +02:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2002-08-29 02:17:06 +02:00
|
|
|
Once you have built a tuple to return from your function, the tuple must
|
|
|
|
be converted into a Datum. Use
|
2002-07-18 06:47:17 +02:00
|
|
|
<programlisting>
|
|
|
|
TupleGetDatum(TupleTableSlot *slot, HeapTuple tuple)
|
|
|
|
</programlisting>
|
2002-08-29 02:17:06 +02:00
|
|
|
to get a Datum given a tuple and a slot. This Datum can be returned
|
|
|
|
directly if you intend to return just a single row, or it can be used
|
|
|
|
as the current return value in a set-returning function.
|
2002-07-18 06:47:17 +02:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2002-08-29 02:17:06 +02:00
|
|
|
An example appears below.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
</sect3>
|
|
|
|
|
|
|
|
<sect3>
|
|
|
|
<title>Returning Sets</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
A set-returning function (SRF) is normally called once for each item it
|
|
|
|
returns. The SRF must therefore save enough state to remember what it
|
|
|
|
was doing and return the next item on each call. The Table Function API
|
|
|
|
provides the FuncCallContext struct to help control this process.
|
|
|
|
<literal>fcinfo->flinfo->fn_extra</> is used to
|
|
|
|
hold a pointer to FuncCallContext across calls.
|
2002-07-18 06:47:17 +02:00
|
|
|
<programlisting>
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Number of times we've been called before.
|
|
|
|
*
|
|
|
|
* call_cntr is initialized to 0 for you by SRF_FIRSTCALL_INIT(), and
|
|
|
|
* incremented for you every time SRF_RETURN_NEXT() is called.
|
|
|
|
*/
|
|
|
|
uint32 call_cntr;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* OPTIONAL maximum number of calls
|
|
|
|
*
|
|
|
|
* max_calls is here for convenience ONLY and setting it is OPTIONAL.
|
|
|
|
* If not set, you must provide alternative means to know when the
|
|
|
|
* function is done.
|
|
|
|
*/
|
|
|
|
uint32 max_calls;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* OPTIONAL pointer to result slot
|
|
|
|
*
|
|
|
|
* slot is for use when returning tuples (i.e. composite data types)
|
|
|
|
* and is not needed when returning base (i.e. scalar) data types.
|
|
|
|
*/
|
|
|
|
TupleTableSlot *slot;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* OPTIONAL pointer to misc user provided context info
|
|
|
|
*
|
|
|
|
* user_fctx is for use as a pointer to your own struct to retain
|
|
|
|
* arbitrary context information between calls for your function.
|
|
|
|
*/
|
|
|
|
void *user_fctx;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* OPTIONAL pointer to struct containing arrays of attribute type input
|
|
|
|
* metainfo
|
|
|
|
*
|
|
|
|
* attinmeta is for use when returning tuples (i.e. composite data types)
|
|
|
|
* and is not needed when returning base (i.e. scalar) data types. It
|
|
|
|
* is ONLY needed if you intend to use BuildTupleFromCStrings() to create
|
|
|
|
* the return tuple.
|
|
|
|
*/
|
|
|
|
AttInMetadata *attinmeta;
|
|
|
|
|
|
|
|
/*
|
2002-08-29 19:14:33 +02:00
|
|
|
* memory context used for structures which must live for multiple calls
|
2002-07-18 06:47:17 +02:00
|
|
|
*
|
2002-08-29 19:14:33 +02:00
|
|
|
* multi_call_memory_ctx is set by SRF_FIRSTCALL_INIT() for you, and used
|
|
|
|
* by SRF_RETURN_DONE() for cleanup. It is the most appropriate memory
|
|
|
|
* context for any memory that is to be re-used across multiple calls
|
|
|
|
* of the SRF.
|
2002-07-18 06:47:17 +02:00
|
|
|
*/
|
2002-08-29 19:14:33 +02:00
|
|
|
MemoryContext multi_call_memory_ctx;
|
2002-07-18 06:47:17 +02:00
|
|
|
|
|
|
|
} FuncCallContext;
|
|
|
|
</programlisting>
|
2002-08-29 02:17:06 +02:00
|
|
|
An SRF uses several functions and macros that automatically manipulate
|
|
|
|
the FuncCallContext struct (and expect to find it via
|
|
|
|
<literal>fn_extra</>). Use
|
2002-07-18 06:47:17 +02:00
|
|
|
<programlisting>
|
|
|
|
SRF_IS_FIRSTCALL()
|
|
|
|
</programlisting>
|
2002-08-29 02:17:06 +02:00
|
|
|
to determine if your function is being called for the first or a
|
2002-07-18 06:47:17 +02:00
|
|
|
subsequent time. On the first call (only) use
|
|
|
|
<programlisting>
|
|
|
|
SRF_FIRSTCALL_INIT()
|
|
|
|
</programlisting>
|
|
|
|
to initialize the FuncCallContext struct. On every function call,
|
|
|
|
including the first, use
|
|
|
|
<programlisting>
|
|
|
|
SRF_PERCALL_SETUP()
|
|
|
|
</programlisting>
|
|
|
|
to properly set up for using the FuncCallContext struct and clearing
|
|
|
|
any previously returned data left over from the previous pass.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
If your function has data to return, use
|
|
|
|
<programlisting>
|
|
|
|
SRF_RETURN_NEXT(funcctx, result)
|
|
|
|
</programlisting>
|
2002-08-29 02:17:06 +02:00
|
|
|
to return it to the caller. (The <literal>result</>
|
|
|
|
must be a Datum, either a single value or a tuple prepared as described
|
|
|
|
earlier.) Finally, when your function is finished returning data, use
|
2002-07-18 06:47:17 +02:00
|
|
|
<programlisting>
|
|
|
|
SRF_RETURN_DONE(funcctx)
|
|
|
|
</programlisting>
|
|
|
|
to clean up and end the SRF.
|
|
|
|
</para>
|
|
|
|
|
2002-08-29 19:14:33 +02:00
|
|
|
<para>
|
|
|
|
The palloc memory context that is current when the SRF is called is
|
|
|
|
a transient context that will be cleared between calls. This means
|
|
|
|
that you do not need to be careful about pfree'ing everything
|
|
|
|
you palloc; it will go away anyway. However, if you want to allocate
|
|
|
|
any data structures to live across calls, you need to put them somewhere
|
|
|
|
else. The memory context referenced by
|
|
|
|
<structfield>multi_call_memory_ctx</> is a suitable location for any
|
|
|
|
data that needs to survive until the SRF is finished running. In most
|
|
|
|
cases, this means that you should switch into
|
|
|
|
<structfield>multi_call_memory_ctx</> while doing the first-call setup.
|
|
|
|
</para>
|
|
|
|
|
2002-07-18 06:47:17 +02:00
|
|
|
<para>
|
|
|
|
A complete pseudo-code example looks like the following:
|
|
|
|
<programlisting>
|
|
|
|
Datum
|
|
|
|
my_Set_Returning_Function(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2002-08-29 19:14:33 +02:00
|
|
|
FuncCallContext *funcctx;
|
|
|
|
Datum result;
|
|
|
|
MemoryContext oldcontext;
|
2002-08-29 02:17:06 +02:00
|
|
|
[user defined declarations]
|
|
|
|
|
|
|
|
if (SRF_IS_FIRSTCALL())
|
|
|
|
{
|
2002-08-29 19:14:33 +02:00
|
|
|
funcctx = SRF_FIRSTCALL_INIT();
|
|
|
|
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
|
2002-08-29 02:17:06 +02:00
|
|
|
/* one-time setup code appears here: */
|
|
|
|
[user defined code]
|
|
|
|
[if returning composite]
|
|
|
|
[build TupleDesc, and perhaps AttInMetadata]
|
|
|
|
[obtain slot]
|
|
|
|
funcctx->slot = slot;
|
|
|
|
[endif returning composite]
|
|
|
|
[user defined code]
|
2002-08-29 19:14:33 +02:00
|
|
|
MemoryContextSwitchTo(oldcontext);
|
2002-08-29 02:17:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* each-time setup code appears here: */
|
|
|
|
[user defined code]
|
|
|
|
funcctx = SRF_PERCALL_SETUP();
|
|
|
|
[user defined code]
|
|
|
|
|
|
|
|
/* this is just one way we might test whether we are done: */
|
|
|
|
if (funcctx->call_cntr < funcctx->max_calls)
|
|
|
|
{
|
|
|
|
/* here we want to return another item: */
|
|
|
|
[user defined code]
|
|
|
|
[obtain result Datum]
|
|
|
|
SRF_RETURN_NEXT(funcctx, result);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* here we are done returning items, and just need to clean up: */
|
|
|
|
[user defined code]
|
|
|
|
SRF_RETURN_DONE(funcctx);
|
|
|
|
}
|
2002-07-18 06:47:17 +02:00
|
|
|
}
|
|
|
|
</programlisting>
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2002-08-29 02:17:06 +02:00
|
|
|
A complete example of a simple SRF returning a composite type looks like:
|
2002-07-18 06:47:17 +02:00
|
|
|
<programlisting>
|
|
|
|
PG_FUNCTION_INFO_V1(testpassbyval);
|
|
|
|
Datum
|
|
|
|
testpassbyval(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2002-08-29 02:17:06 +02:00
|
|
|
FuncCallContext *funcctx;
|
|
|
|
int call_cntr;
|
|
|
|
int max_calls;
|
|
|
|
TupleDesc tupdesc;
|
|
|
|
TupleTableSlot *slot;
|
|
|
|
AttInMetadata *attinmeta;
|
|
|
|
|
|
|
|
/* stuff done only on the first call of the function */
|
|
|
|
if (SRF_IS_FIRSTCALL())
|
|
|
|
{
|
2002-08-29 19:14:33 +02:00
|
|
|
MemoryContext oldcontext;
|
|
|
|
|
2002-08-29 02:17:06 +02:00
|
|
|
/* create a function context for cross-call persistence */
|
2002-08-29 19:14:33 +02:00
|
|
|
funcctx = SRF_FIRSTCALL_INIT();
|
|
|
|
|
|
|
|
/* switch to memory context appropriate for multiple function calls */
|
|
|
|
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
|
2002-08-29 02:17:06 +02:00
|
|
|
|
|
|
|
/* total number of tuples to be returned */
|
|
|
|
funcctx->max_calls = PG_GETARG_UINT32(0);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Build a tuple description for a __testpassbyval tuple
|
|
|
|
*/
|
|
|
|
tupdesc = RelationNameGetTupleDesc("__testpassbyval");
|
|
|
|
|
|
|
|
/* allocate a slot for a tuple with this tupdesc */
|
|
|
|
slot = TupleDescGetSlot(tupdesc);
|
|
|
|
|
|
|
|
/* assign slot to function context */
|
|
|
|
funcctx->slot = slot;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Generate attribute metadata needed later to produce tuples from raw
|
|
|
|
* C strings
|
|
|
|
*/
|
|
|
|
attinmeta = TupleDescGetAttInMetadata(tupdesc);
|
|
|
|
funcctx->attinmeta = attinmeta;
|
2002-08-29 19:14:33 +02:00
|
|
|
|
|
|
|
MemoryContextSwitchTo(oldcontext);
|
2002-07-18 06:47:17 +02:00
|
|
|
}
|
|
|
|
|
2002-08-29 02:17:06 +02:00
|
|
|
/* stuff done on every call of the function */
|
|
|
|
funcctx = SRF_PERCALL_SETUP();
|
2002-07-18 06:47:17 +02:00
|
|
|
|
2002-08-29 02:17:06 +02:00
|
|
|
call_cntr = funcctx->call_cntr;
|
|
|
|
max_calls = funcctx->max_calls;
|
|
|
|
slot = funcctx->slot;
|
|
|
|
attinmeta = funcctx->attinmeta;
|
2002-07-18 06:47:17 +02:00
|
|
|
|
2002-08-29 02:17:06 +02:00
|
|
|
if (call_cntr < max_calls) /* do when there is more left to send */
|
|
|
|
{
|
|
|
|
char **values;
|
|
|
|
HeapTuple tuple;
|
|
|
|
Datum result;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Prepare a values array for storage in our slot.
|
|
|
|
* This should be an array of C strings which will
|
|
|
|
* be processed later by the appropriate "in" functions.
|
|
|
|
*/
|
|
|
|
values = (char **) palloc(3 * sizeof(char *));
|
|
|
|
values[0] = (char *) palloc(16 * sizeof(char));
|
|
|
|
values[1] = (char *) palloc(16 * sizeof(char));
|
|
|
|
values[2] = (char *) palloc(16 * sizeof(char));
|
|
|
|
|
|
|
|
snprintf(values[0], 16, "%d", 1 * PG_GETARG_INT32(1));
|
|
|
|
snprintf(values[1], 16, "%d", 2 * PG_GETARG_INT32(1));
|
|
|
|
snprintf(values[2], 16, "%d", 3 * PG_GETARG_INT32(1));
|
|
|
|
|
|
|
|
/* build a tuple */
|
|
|
|
tuple = BuildTupleFromCStrings(attinmeta, values);
|
|
|
|
|
|
|
|
/* make the tuple into a datum */
|
|
|
|
result = TupleGetDatum(slot, tuple);
|
|
|
|
|
2002-08-29 19:14:33 +02:00
|
|
|
/* Clean up (this is not actually necessary) */
|
2002-08-29 02:17:06 +02:00
|
|
|
pfree(values[0]);
|
|
|
|
pfree(values[1]);
|
|
|
|
pfree(values[2]);
|
|
|
|
pfree(values);
|
|
|
|
|
|
|
|
SRF_RETURN_NEXT(funcctx, result);
|
|
|
|
}
|
|
|
|
else /* do when there is no more left */
|
|
|
|
{
|
|
|
|
SRF_RETURN_DONE(funcctx);
|
|
|
|
}
|
2002-07-18 06:47:17 +02:00
|
|
|
}
|
|
|
|
</programlisting>
|
|
|
|
with supporting SQL code of
|
|
|
|
<programlisting>
|
2002-08-29 02:17:06 +02:00
|
|
|
CREATE TYPE __testpassbyval AS (f1 int4, f2 int4, f3 int4);
|
2002-07-18 06:47:17 +02:00
|
|
|
|
|
|
|
CREATE OR REPLACE FUNCTION testpassbyval(int4, int4) RETURNS setof __testpassbyval
|
|
|
|
AS 'MODULE_PATHNAME','testpassbyval' LANGUAGE 'c' IMMUTABLE STRICT;
|
2001-01-12 23:15:32 +01:00
|
|
|
</programlisting>
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<para>
|
2002-07-18 06:47:17 +02:00
|
|
|
See contrib/tablefunc for more examples of Table Functions.
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
2002-08-29 02:17:06 +02:00
|
|
|
|
|
|
|
</sect3>
|
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
</sect2>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<sect2>
|
|
|
|
<title>Writing Code</title>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<para>
|
1998-03-01 09:16:16 +01:00
|
|
|
We now turn to the more difficult task of writing
|
|
|
|
programming language functions. Be warned: this section
|
|
|
|
of the manual will not make you a programmer. You must
|
2001-01-12 23:15:32 +01:00
|
|
|
have a good understanding of <acronym>C</acronym>
|
1999-03-14 16:24:15 +01:00
|
|
|
(including the use of pointers and the malloc memory manager)
|
1999-07-22 17:11:05 +02:00
|
|
|
before trying to write <acronym>C</acronym> functions for
|
2001-11-21 07:09:45 +01:00
|
|
|
use with <productname>PostgreSQL</productname>. While it may
|
1999-03-14 16:24:15 +01:00
|
|
|
be possible to load functions written in languages other
|
2001-11-21 07:09:45 +01:00
|
|
|
than <acronym>C</acronym> into <productname>PostgreSQL</productname>,
|
1999-03-14 16:24:15 +01:00
|
|
|
this is often difficult (when it is possible at all)
|
1999-07-22 17:11:05 +02:00
|
|
|
because other languages, such as <acronym>FORTRAN</acronym>
|
|
|
|
and <acronym>Pascal</acronym> often do not follow the same
|
|
|
|
<firstterm>calling convention</firstterm>
|
|
|
|
as <acronym>C</acronym>. That is, other
|
1998-03-01 09:16:16 +01:00
|
|
|
languages do not pass argument and return values
|
|
|
|
between functions in the same way. For this reason, we
|
|
|
|
will assume that your programming language functions
|
1999-07-22 17:11:05 +02:00
|
|
|
are written in <acronym>C</acronym>.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The basic rules for building <acronym>C</acronym> functions
|
1999-03-14 16:24:15 +01:00
|
|
|
are as follows:
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<itemizedlist>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
2001-11-12 20:19:39 +01:00
|
|
|
Use <literal>pg_config --includedir-server</literal><indexterm><primary>pg_config</></> to find
|
2001-11-21 07:09:45 +01:00
|
|
|
out where the <productname>PostgreSQL</> server header files are installed on
|
2001-08-28 16:20:28 +02:00
|
|
|
your system (or the system that your users will be running
|
2001-11-21 07:09:45 +01:00
|
|
|
on). This option is new with <productname>PostgreSQL</> 7.2.
|
|
|
|
For <productname>PostgreSQL</>
|
2001-08-28 16:20:28 +02:00
|
|
|
7.1 you should use the option <option>--includedir</option>.
|
|
|
|
(<command>pg_config</command> will exit with a non-zero status
|
|
|
|
if it encounters an unknown option.) For releases prior to
|
|
|
|
7.1 you will have to guess, but since that was before the
|
|
|
|
current calling conventions were introduced, it is unlikely
|
|
|
|
that you want to support those releases.
|
2001-01-12 23:15:32 +01:00
|
|
|
</para>
|
|
|
|
</listitem>
|
1999-07-22 17:11:05 +02:00
|
|
|
|
2001-01-12 23:15:32 +01:00
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
When allocating memory, use the
|
2001-11-21 07:09:45 +01:00
|
|
|
<productname>PostgreSQL</productname> routines
|
2001-01-12 23:15:32 +01:00
|
|
|
<function>palloc</function> and <function>pfree</function>
|
|
|
|
instead of the corresponding <acronym>C</acronym> library
|
|
|
|
routines <function>malloc</function> and
|
|
|
|
<function>free</function>. The memory allocated by
|
|
|
|
<function>palloc</function> will be freed automatically at the
|
|
|
|
end of each transaction, preventing memory leaks.
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
|
|
|
</listitem>
|
2001-01-12 23:15:32 +01:00
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<listitem>
|
|
|
|
<para>
|
2001-01-12 23:15:32 +01:00
|
|
|
Always zero the bytes of your structures using
|
|
|
|
<function>memset</function> or <function>bzero</function>.
|
|
|
|
Several routines (such as the hash access method, hash join
|
|
|
|
and the sort algorithm) compute functions of the raw bits
|
|
|
|
contained in your structure. Even if you initialize all
|
|
|
|
fields of your structure, there may be several bytes of
|
|
|
|
alignment padding (holes in the structure) that may contain
|
|
|
|
garbage values.
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
|
|
|
</listitem>
|
2001-01-12 23:15:32 +01:00
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<listitem>
|
|
|
|
<para>
|
2001-11-21 07:09:45 +01:00
|
|
|
Most of the internal <productname>PostgreSQL</productname> types
|
2001-02-15 20:03:35 +01:00
|
|
|
are declared in <filename>postgres.h</filename>, while the function
|
2001-01-12 23:15:32 +01:00
|
|
|
manager interfaces (<symbol>PG_FUNCTION_ARGS</symbol>, etc.)
|
|
|
|
are in <filename>fmgr.h</filename>, so you will need to
|
2001-02-15 20:03:35 +01:00
|
|
|
include at least these two files. For portability reasons it's best
|
|
|
|
to include <filename>postgres.h</filename> <emphasis>first</>,
|
|
|
|
before any other system or user header files.
|
|
|
|
Including <filename>postgres.h</filename> will also include
|
2001-01-12 23:15:32 +01:00
|
|
|
<filename>elog.h</filename> and <filename>palloc.h</filename>
|
|
|
|
for you.
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
|
|
|
</listitem>
|
2001-01-12 23:15:32 +01:00
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<listitem>
|
|
|
|
<para>
|
2001-01-12 23:15:32 +01:00
|
|
|
Symbol names defined within object files must not conflict
|
|
|
|
with each other or with symbols defined in the
|
|
|
|
<productname>PostgreSQL</productname> server executable. You
|
|
|
|
will have to rename your functions or variables if you get
|
|
|
|
error messages to this effect.
|
1999-07-22 17:11:05 +02:00
|
|
|
</para>
|
|
|
|
</listitem>
|
2001-01-12 23:15:32 +01:00
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<listitem>
|
|
|
|
<para>
|
2001-01-20 21:59:29 +01:00
|
|
|
Compiling and linking your object code so that
|
1999-07-22 17:11:05 +02:00
|
|
|
it can be dynamically loaded into
|
2001-11-21 07:09:45 +01:00
|
|
|
<productname>PostgreSQL</productname>
|
1999-07-22 17:11:05 +02:00
|
|
|
always requires special flags.
|
2000-12-26 01:10:37 +01:00
|
|
|
See <xref linkend="dfunc">
|
1999-07-22 17:11:05 +02:00
|
|
|
for a detailed explanation of how to do it for
|
|
|
|
your particular operating system.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
</itemizedlist>
|
|
|
|
</para>
|
|
|
|
</sect2>
|
2001-01-12 23:15:32 +01:00
|
|
|
|
|
|
|
&dfunc;
|
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
</sect1>
|
|
|
|
|
2000-09-29 22:21:34 +02:00
|
|
|
<sect1 id="xfunc-overload">
|
1999-07-22 17:11:05 +02:00
|
|
|
<title>Function Overloading</title>
|
|
|
|
|
2001-11-12 20:19:39 +01:00
|
|
|
<indexterm zone="xfunc-overload"><primary>overloading</></>
|
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<para>
|
2001-10-26 21:58:12 +02:00
|
|
|
More than one function may be defined with the same SQL name, so long
|
2001-09-15 21:56:59 +02:00
|
|
|
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>
|
1999-07-22 17:11:05 +02:00
|
|
|
A function may also have the same name as an attribute. In the case
|
|
|
|
that there is an ambiguity between a function on a complex type and
|
|
|
|
an attribute of the complex type, the attribute will always be used.
|
|
|
|
</para>
|
|
|
|
|
2001-09-15 21:56:59 +02:00
|
|
|
<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 the
|
|
|
|
<citetitle>User's Guide</citetitle>, but it is unwise to design a
|
|
|
|
system that subtly relies on this behavior.
|
|
|
|
</para>
|
1999-07-22 17:11:05 +02:00
|
|
|
|
2001-09-15 21:56:59 +02:00
|
|
|
<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. E.g.,
|
|
|
|
<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>
|
1999-07-22 17:11:05 +02:00
|
|
|
|
2001-09-15 21:56:59 +02:00
|
|
|
<para>
|
|
|
|
Prior to <productname>PostgreSQL</productname> 7.0, this
|
|
|
|
alternative syntax did not exist. There is a trick to get around
|
|
|
|
the problem, by defining a set of C functions with different names
|
|
|
|
and then define a set of identically-named SQL function wrappers
|
|
|
|
that take the appropriate argument types and call the matching C
|
|
|
|
function.
|
|
|
|
</para>
|
1999-07-22 17:11:05 +02:00
|
|
|
</sect1>
|
2001-09-06 12:28:39 +02:00
|
|
|
|
2002-06-20 18:57:00 +02:00
|
|
|
<sect1 id="xfunc-tablefunctions">
|
|
|
|
<title>Table Functions</title>
|
|
|
|
|
|
|
|
<indexterm zone="xfunc-tablefunctions"><primary>function</></>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Table functions are functions that produce a set of rows, made up of
|
|
|
|
either base (scalar) data types, or composite (multi-column) data types.
|
|
|
|
They are used like a table, view, or subselect in the <literal>FROM</>
|
|
|
|
clause of a query. Columns returned by table functions may be included in
|
|
|
|
<literal>SELECT</>, <literal>JOIN</>, or <literal>WHERE</> clauses in the
|
|
|
|
same manner as a table, view, or subselect column.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
If a table function returns a base data type, the single result column
|
|
|
|
is named for the function. If the function returns a composite type, the
|
|
|
|
result columns get the same names as the individual attributes of the type.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
A table function may be aliased in the <literal>FROM</> clause, but it also
|
|
|
|
may be left unaliased. If a function is used in the FROM clause with no
|
|
|
|
alias, the function name is used as the relation name.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Table functions work wherever tables do in <literal>SELECT</> statements.
|
|
|
|
For example
|
|
|
|
<programlisting>
|
2002-08-29 02:17:06 +02:00
|
|
|
CREATE TABLE foo (fooid int, foosubid int, fooname text);
|
|
|
|
|
|
|
|
CREATE FUNCTION getfoo(int) RETURNS setof foo AS '
|
|
|
|
SELECT * FROM foo WHERE fooid = $1;
|
|
|
|
' LANGUAGE SQL;
|
|
|
|
|
2002-06-20 18:57:00 +02:00
|
|
|
SELECT * FROM getfoo(1) AS t1;
|
2002-08-29 02:17:06 +02:00
|
|
|
|
|
|
|
SELECT * FROM foo
|
|
|
|
WHERE foosubid in (select foosubid from getfoo(foo.fooid) z
|
|
|
|
where z.fooid = foo.fooid);
|
|
|
|
|
2002-06-20 18:57:00 +02:00
|
|
|
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo(1);
|
|
|
|
SELECT * FROM vw_getfoo;
|
|
|
|
</programlisting>
|
|
|
|
are all valid statements.
|
|
|
|
</para>
|
|
|
|
</sect1>
|
2001-09-06 12:28:39 +02:00
|
|
|
|
|
|
|
<sect1 id="xfunc-plhandler">
|
|
|
|
<title>Procedural Language Handlers</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
All calls to functions that are written in a language other than
|
|
|
|
the current <quote>version 1</quote> interface for compiled
|
2001-10-26 21:58:12 +02:00
|
|
|
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>
|
2001-09-06 12:28:39 +02:00
|
|
|
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
|
|
|
|
describes how a language call handler can be written. This is not
|
|
|
|
a common task, in fact, it has only been done a handful of times
|
|
|
|
in the history of <productname>PostgreSQL</productname>, but the
|
|
|
|
topic naturally belongs in this chapter, and the material might
|
|
|
|
give some insight into the extensible nature of the
|
|
|
|
<productname>PostgreSQL</productname> system.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The call handler for a procedural language is a
|
|
|
|
<quote>normal</quote> function, which must be written in a
|
|
|
|
compiled language such as C and registered with
|
|
|
|
<productname>PostgreSQL</productname> as taking no arguments and
|
2002-08-22 02:01:51 +02:00
|
|
|
returning the <type>language_handler</type> type.
|
|
|
|
This special pseudo-type identifies the handler as a call handler
|
|
|
|
and prevents it from being called directly in queries.
|
2001-09-06 12:28:39 +02:00
|
|
|
</para>
|
|
|
|
|
|
|
|
<note>
|
|
|
|
<para>
|
|
|
|
In <productname>PostgreSQL</productname> 7.1 and later, call
|
|
|
|
handlers must adhere to the <quote>version 1</quote> function
|
|
|
|
manager interface, not the old-style interface.
|
|
|
|
</para>
|
|
|
|
</note>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The call handler is called in the same way as any other function:
|
|
|
|
It receives a pointer to a
|
|
|
|
<structname>FunctionCallInfoData</structname> struct containing
|
|
|
|
argument values and information about the called function, and it
|
|
|
|
is expected to return a <type>Datum</type> result (and possibly
|
|
|
|
set the <structfield>isnull</structfield> field of the
|
|
|
|
<structname>FunctionCallInfoData</structname> struct, if it wishes
|
|
|
|
to return an SQL NULL result). The difference between a call
|
|
|
|
handler and an ordinary callee function is that the
|
|
|
|
<structfield>flinfo->fn_oid</structfield> field of the
|
|
|
|
<structname>FunctionCallInfoData</structname> struct will contain
|
|
|
|
the OID of the actual function to be called, not of the call
|
|
|
|
handler itself. The call handler must use this field to determine
|
|
|
|
which function to execute. Also, the passed argument list has
|
|
|
|
been set up according to the declaration of the target function,
|
|
|
|
not of the call handler.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
It's up to the call handler to fetch the
|
|
|
|
<classname>pg_proc</classname> entry and to analyze the argument
|
|
|
|
and return types of the called procedure. The AS clause from the
|
|
|
|
<command>CREATE FUNCTION</command> of the procedure will be found
|
|
|
|
in the <literal>prosrc</literal> attribute of the
|
|
|
|
<classname>pg_proc</classname> table entry. This may be the source
|
|
|
|
text in the procedural language itself (like for PL/Tcl), a
|
2001-09-10 23:58:47 +02:00
|
|
|
path name to a file, or anything else that tells the call handler
|
2001-09-06 12:28:39 +02:00
|
|
|
what to do in detail.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Often, the same function is called many times per SQL statement.
|
|
|
|
A call handler can avoid repeated lookups of information about the
|
|
|
|
called function by using the
|
|
|
|
<structfield>flinfo->fn_extra</structfield> field. This will
|
|
|
|
initially be NULL, but can be set by the call handler to point at
|
|
|
|
information about the PL function. On subsequent calls, if
|
|
|
|
<structfield>flinfo->fn_extra</structfield> is already non-NULL
|
|
|
|
then it can be used and the information lookup step skipped. The
|
|
|
|
call handler must be careful that
|
|
|
|
<structfield>flinfo->fn_extra</structfield> is made to point at
|
|
|
|
memory that will live at least until the end of the current query,
|
|
|
|
since an <structname>FmgrInfo</structname> data structure could be
|
|
|
|
kept that long. One way to do this is to allocate the extra data
|
|
|
|
in the memory context specified by
|
|
|
|
<structfield>flinfo->fn_mcxt</structfield>; such data will
|
|
|
|
normally have the same lifespan as the
|
|
|
|
<structname>FmgrInfo</structname> itself. But the handler could
|
|
|
|
also choose to use a longer-lived context so that it can cache
|
|
|
|
function definition information across queries.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
When a PL function is invoked as a trigger, no explicit arguments
|
|
|
|
are passed, but the
|
|
|
|
<structname>FunctionCallInfoData</structname>'s
|
|
|
|
<structfield>context</structfield> field points at a
|
|
|
|
<structname>TriggerData</structname> node, rather than being NULL
|
|
|
|
as it is in a plain function call. A language handler should
|
|
|
|
provide mechanisms for PL functions to get at the trigger
|
|
|
|
information.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
This is a template for a PL handler written in C:
|
|
|
|
<programlisting>
|
|
|
|
#include "postgres.h"
|
|
|
|
#include "executor/spi.h"
|
|
|
|
#include "commands/trigger.h"
|
|
|
|
#include "utils/elog.h"
|
|
|
|
#include "fmgr.h"
|
|
|
|
#include "access/heapam.h"
|
|
|
|
#include "utils/syscache.h"
|
|
|
|
#include "catalog/pg_proc.h"
|
|
|
|
#include "catalog/pg_type.h"
|
|
|
|
|
|
|
|
PG_FUNCTION_INFO_V1(plsample_call_handler);
|
|
|
|
|
|
|
|
Datum
|
|
|
|
plsample_call_handler(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
Datum retval;
|
|
|
|
|
|
|
|
if (CALLED_AS_TRIGGER(fcinfo))
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Called as a trigger procedure
|
|
|
|
*/
|
|
|
|
TriggerData *trigdata = (TriggerData *) fcinfo->context;
|
|
|
|
|
|
|
|
retval = ...
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/*
|
|
|
|
* Called as a function
|
|
|
|
*/
|
|
|
|
|
|
|
|
retval = ...
|
|
|
|
}
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
</programlisting>
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Only a few thousand lines of code have to be added instead of the
|
|
|
|
dots to complete the call handler. See <xref linkend="xfunc-c">
|
|
|
|
for information on how to compile it into a loadable module.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The following commands then register the sample procedural
|
|
|
|
language:
|
|
|
|
<programlisting>
|
2002-08-22 02:01:51 +02:00
|
|
|
CREATE FUNCTION plsample_call_handler () RETURNS language_handler
|
2001-10-26 21:58:12 +02:00
|
|
|
AS '/usr/local/pgsql/lib/plsample'
|
2001-09-06 12:28:39 +02:00
|
|
|
LANGUAGE C;
|
|
|
|
CREATE LANGUAGE plsample
|
|
|
|
HANDLER plsample_call_handler;
|
|
|
|
</programlisting>
|
|
|
|
</para>
|
|
|
|
</sect1>
|
1999-07-22 17:11:05 +02:00
|
|
|
</chapter>
|
1998-12-29 03:24:47 +01:00
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<!-- Keep this comment at the end of the file
|
|
|
|
Local variables:
|
2000-03-31 05:27:42 +02:00
|
|
|
mode:sgml
|
1999-07-22 17:11:05 +02:00
|
|
|
sgml-omittag:nil
|
|
|
|
sgml-shorttag:t
|
|
|
|
sgml-minimize-attributes:nil
|
|
|
|
sgml-always-quote-attributes:t
|
|
|
|
sgml-indent-step:1
|
|
|
|
sgml-indent-data:t
|
|
|
|
sgml-parent-document:nil
|
|
|
|
sgml-default-dtd-file:"./reference.ced"
|
|
|
|
sgml-exposed-tags:nil
|
2000-03-31 05:27:42 +02:00
|
|
|
sgml-local-catalogs:("/usr/lib/sgml/catalog")
|
1999-07-22 17:11:05 +02:00
|
|
|
sgml-local-ecat-files:nil
|
|
|
|
End:
|
|
|
|
-->
|