Commit 1b506c96 authored by Peter Eisentraut's avatar Peter Eisentraut

updates

parent d6942607
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.36 2001/09/13 15:55:23 petere Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.37 2001/09/15 19:56:59 petere Exp $
--> -->
<chapter id="xfunc"> <chapter id="xfunc">
<title id="xfunc-title">Extending <acronym>SQL</acronym>: Functions</title> <title id="xfunc-title">Extending <acronym>SQL</acronym>: Functions</title>
<sect1 id="xfunc-intro">
<title>Introduction</title>
<comment>
Historically, functions were perhaps considered a tool for creating
types. Today, few people build their own types but many write
their own functions. This introduction ought to be changed to
reflect this.
</comment>
<para> <para>
As it turns out, part of defining a new type is the As it turns out, part of defining a new type is the
definition of functions that describe its behavior. definition of functions that describe its behavior.
...@@ -16,8 +26,8 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.36 2001/09/13 15:55:23 peter ...@@ -16,8 +26,8 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.36 2001/09/13 15:55:23 peter
</para> </para>
<para> <para>
<productname>Postgres</productname> <acronym>SQL</acronym> <productname>PostgreSQL</productname> provides four kinds of
provides three types of functions: functions:
<itemizedlist> <itemizedlist>
<listitem> <listitem>
...@@ -29,7 +39,12 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.36 2001/09/13 15:55:23 peter ...@@ -29,7 +39,12 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.36 2001/09/13 15:55:23 peter
<listitem> <listitem>
<para> <para>
procedural language procedural language
functions (functions written in, for example, PL/Tcl or PL/pgSQL) functions (functions written in, for example, <application>PL/Tcl</> or <application>PL/pgSQL</>)
</para>
</listitem>
<listitem>
<para>
internal functions
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
...@@ -38,7 +53,9 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.36 2001/09/13 15:55:23 peter ...@@ -38,7 +53,9 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.36 2001/09/13 15:55:23 peter
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
</para>
<para>
Every kind Every kind
of function can take a base type, a composite type or of function can take a base type, a composite type or
some combination as arguments (parameters). In addition, some combination as arguments (parameters). In addition,
...@@ -46,34 +63,37 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.36 2001/09/13 15:55:23 peter ...@@ -46,34 +63,37 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.36 2001/09/13 15:55:23 peter
a composite type. It's easiest to define <acronym>SQL</acronym> a composite type. It's easiest to define <acronym>SQL</acronym>
functions, so we'll start with those. Examples in this section functions, so we'll start with those. Examples in this section
can also be found in <filename>funcs.sql</filename> can also be found in <filename>funcs.sql</filename>
and <filename>funcs.c</filename>. and <filename>funcs.c</filename> in the tutorial directory.
</para> </para>
</sect1>
<sect1 id="xfunc-sql"> <sect1 id="xfunc-sql">
<title>Query Language (<acronym>SQL</acronym>) Functions</title> <title>Query Language (<acronym>SQL</acronym>) Functions</title>
<para> <para>
SQL functions execute an arbitrary list of SQL queries, returning SQL functions execute an arbitrary list of SQL statements, returning
the results of the last query in the list. SQL functions in general the results of the last query in the list. SQL functions in general
return sets. If their returntype is not specified as a return sets. If their returntype is not specified as a
<literal>setof</literal>, <literal>SETOF</literal>,
then an arbitrary element of the last query's result will be returned. then an arbitrary element of the last query's result will be returned.
</para> </para>
<para> <para>
The body of a SQL function following AS The body of an SQL function should be a list of one or more SQL
should be a list of queries separated by semicolons and statements separated by semicolons. Note that because the syntax
bracketed within single-quote marks. Note that quote marks used in of the <command>CREATE FUNCTION</command> requires the body of the
the queries must be escaped, by preceding them with a backslash. function to be enclosed in single quotes, single quote marks used
in the body of the function must be escaped, by writing two single
quotes where one is desired.
</para> </para>
<para> <para>
Arguments to the SQL function may be referenced in the queries using Arguments to the SQL function may be referenced in the function
a $n syntax: $1 refers to the first argument, $2 to the second, and so body using the syntax <literal>$<replaceable>n</></>: $1 refers to
on. If an argument is complex, then a <firstterm>dot</firstterm> the first argument, $2 to the second, and so on. If an argument
notation (e.g. <literal>$1.emp</literal>) may be is of a composite type, then the <quote>dot notation</quote>,
used to access attributes of the argument or e.g., <literal>$1.emp</literal>, may be used to access attributes
to invoke functions. of the argument or to invoke functions.
</para> </para>
<sect2> <sect2>
...@@ -83,34 +103,34 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.36 2001/09/13 15:55:23 peter ...@@ -83,34 +103,34 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.36 2001/09/13 15:55:23 peter
To illustrate a simple SQL function, consider the following, To illustrate a simple SQL function, consider the following,
which might be used to debit a bank account: which might be used to debit a bank account:
<programlisting> <programlisting>
CREATE FUNCTION tp1 (int4, float8) CREATE FUNCTION tp1 (integer, double precision) RETURNS integer AS '
RETURNS int4 UPDATE bank
AS 'UPDATE bank
SET balance = bank.balance - $2 SET balance = bank.balance - $2
WHERE bank.acctountno = $1; WHERE bank.acctountno = $1;
SELECT 1;' SELECT 1;
LANGUAGE 'sql'; ' LANGUAGE SQL;
</programlisting> </programlisting>
A user could execute this function to debit account 17 by $100.00 as A user could execute this function to debit account 17 by $100.00 as
follows: follows:
<programlisting> <programlisting>
SELECT tp1( 17,100.0); SELECT tp1(17, 100.0);
</programlisting> </programlisting>
</para> </para>
<para> <para>
The following more interesting example takes a single argument of type The following more interesting example takes a single argument of
EMP, and retrieves multiple results: type <type>EMP</type>, which is really a table that contains data
about employees, and retrieves multiple results:
<programlisting>
CREATE FUNCTION hobbies (EMP) RETURNS SETOF hobbies <programlisting>
AS 'SELECT hobbies.* FROM hobbies CREATE FUNCTION hobbies (EMP) RETURNS SETOF hobbies AS '
WHERE $1.name = hobbies.person' SELECT hobbies.* FROM hobbies
LANGUAGE 'sql'; WHERE $1.name = hobbies.person
</programlisting> ' LANGUAGE SQL;
</programlisting>
</para> </para>
</sect2> </sect2>
...@@ -119,49 +139,49 @@ CREATE FUNCTION hobbies (EMP) RETURNS SETOF hobbies ...@@ -119,49 +139,49 @@ CREATE FUNCTION hobbies (EMP) RETURNS SETOF hobbies
<para> <para>
The simplest possible <acronym>SQL</acronym> function has no arguments and The simplest possible <acronym>SQL</acronym> function has no arguments and
simply returns a base type, such as <literal>int4</literal>: simply returns a base type, such as <type>integer</type>:
<programlisting> <programlisting>
CREATE FUNCTION one() CREATE FUNCTION one() RETURNS integer AS '
RETURNS int4 SELECT 1 as RESULT;
AS 'SELECT 1 as RESULT;' ' LANGUAGE SQL;
LANGUAGE 'sql';
SELECT one() AS answer; SELECT one() AS answer;
</programlisting>
+-------+ <screen>
|answer | answer
+-------+ --------
|1 | 1
+-------+ </screen>
</programlisting>
</para> </para>
<para> <para>
Notice that we defined a column name for the function's result Notice that we defined a column alias within the function body for the result of the function
(with the name RESULT), but this column name is not visible (with the name <literal>RESULT</>), but this column alias is not visible
outside the function. Hence, the result is labelled answer outside the function. Hence, the result is labelled <literal>answer</>
instead of one. instead of <literal>one</>.
</para> </para>
<para> <para>
It's almost as easy to define <acronym>SQL</acronym> functions It is almost as easy to define <acronym>SQL</acronym> functions
that take base types as arguments. In the example below, notice that take base types as arguments. In the example below, notice
how we refer to the arguments within the function as $1 how we refer to the arguments within the function as <literal>$1</>
and $2: and <literal>$2</>:
<programlisting> <programlisting>
CREATE FUNCTION add_em(int4, int4) CREATE FUNCTION add_em(integer, integer) RETURNS integer AS '
RETURNS int4 SELECT $1 + $2;
AS 'SELECT $1 + $2;' ' LANGUAGE SQL;
LANGUAGE 'sql';
SELECT add_em(1, 2) AS answer; SELECT add_em(1, 2) AS answer;
</programlisting>
+-------+ <screen>
|answer | answer
+-------+ --------
|3 | 3
+-------+ </screen>
</programlisting>
</para> </para>
</sect2> </sect2>
...@@ -170,39 +190,38 @@ SELECT add_em(1, 2) AS answer; ...@@ -170,39 +190,38 @@ SELECT add_em(1, 2) AS answer;
<para> <para>
When specifying functions with arguments of composite When specifying functions with arguments of composite
types (such as EMP), we must not only specify which types (such as <type>EMP</type>), we must not only specify which
argument we want (as we did above with $1 and $2) but argument we want (as we did above with <literal>$1</> and <literal>$2</literal>) but
also the attributes of that argument. For example, also the attributes of that argument. For example,
take the function double_salary that computes what your take the function <function>double_salary</function> that computes what your
salary would be if it were doubled: salary would be if it were doubled:
<programlisting> <programlisting>
CREATE FUNCTION double_salary(EMP) CREATE FUNCTION double_salary(EMP) RETURNS integer AS '
RETURNS int4 SELECT $1.salary * 2 AS salary;
AS 'SELECT $1.salary * 2 AS salary;' ' LANGUAGE SQL;
LANGUAGE 'sql';
SELECT name, double_salary(EMP) AS dream SELECT name, double_salary(EMP) AS dream
FROM EMP FROM EMP
WHERE EMP.cubicle ~= point '(2,1)'; WHERE EMP.cubicle ~= point '(2,1)';
</programlisting>
<screen>
+-----+-------+ name | dream
|name | dream | ------+-------
+-----+-------+ Sam | 2400
|Sam | 2400 | </screen>
+-----+-------+
</programlisting>
</para> </para>
<para> <para>
Notice the use of the syntax $1.salary. Notice the use of the syntax <literal>$1.salary</literal>.
Before launching into the subject of functions that Before launching into the subject of functions that
return composite types, we must first introduce the return composite types, we must first introduce the
function notation for projecting attributes. The simple way function notation for projecting attributes. The simple way
to explain this is that we can usually use the to explain this is that we can usually use the
notations attribute(table) and table.attribute interchangably: notations <literal>attribute(table)</> and <literal>table.attribute</> interchangably:
<programlisting> <programlisting>
-- --
-- this is the same as: -- this is the same as:
-- SELECT EMP.name AS youngster FROM EMP WHERE EMP.age &lt; 30 -- SELECT EMP.name AS youngster FROM EMP WHERE EMP.age &lt; 30
...@@ -210,32 +229,33 @@ SELECT name, double_salary(EMP) AS dream ...@@ -210,32 +229,33 @@ SELECT name, double_salary(EMP) AS dream
SELECT name(EMP) AS youngster SELECT name(EMP) AS youngster
FROM EMP FROM EMP
WHERE age(EMP) &lt; 30; WHERE age(EMP) &lt; 30;
</programlisting>
+----------+ <screen>
|youngster | youngster
+----------+ -----------
|Sam | Sam
+----------+ </screen>
</programlisting>
</para> </para>
<para> <para>
As we shall see, however, this is not always the case. As we shall see, however, this is not always the case.
This function notation is important when we want to use This function notation is important when we want to use
a function that returns a single row. We do this a function that returns a single row. We do this
by assembling the entire row within the function, by assembling the entire row within the function,
attribute by attribute. This is an example of a function attribute by attribute. This is an example of a function
that returns a single EMP row: that returns a single <type>EMP</type> row:
<programlisting> <programlisting>
CREATE FUNCTION new_emp() CREATE FUNCTION new_emp() RETURNS EMP AS '
RETURNS EMP SELECT text ''None'' AS name,
AS 'SELECT text ''None'' AS name,
1000 AS salary, 1000 AS salary,
25 AS age, 25 AS age,
point ''(2,2)'' AS cubicle' point ''(2,2)'' AS cubicle;
LANGUAGE 'sql'; ' LANGUAGE SQL;
</programlisting> </programlisting>
</para> </para>
<para> <para>
In this case we have specified each of the attributes In this case we have specified each of the attributes
with a constant value, but any computation or expression with a constant value, but any computation or expression
...@@ -247,19 +267,19 @@ CREATE FUNCTION new_emp() ...@@ -247,19 +267,19 @@ CREATE FUNCTION new_emp()
<listitem> <listitem>
<para> <para>
The target list order must be exactly the same as The target list order must be exactly the same as
that in which the attributes appear in the CREATE that in which the attributes appear in the <command>CREATE
TABLE statement that defined the composite type. TABLE</command> statement that defined the table underlying the composite type.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
You must typecast the expressions to match the You must typecast the expressions to match the
composite type's definition, or you will get errors like this: definition of the composite type, or you will get errors like this:
<programlisting> <screen>
<computeroutput> <computeroutput>
ERROR: function declared to return emp returns varchar instead of text at column 1 ERROR: function declared to return emp returns varchar instead of text at column 1
</computeroutput> </computeroutput>
</programlisting> </screen>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
...@@ -269,15 +289,15 @@ ERROR: function declared to return emp returns varchar instead of text at colum ...@@ -269,15 +289,15 @@ ERROR: function declared to return emp returns varchar instead of text at colum
project an attribute out of the row or pass the project an attribute out of the row or pass the
entire row into another function. entire row into another function.
<programlisting> <programlisting>
SELECT name(new_emp()) AS nobody; SELECT name(new_emp()) AS nobody;
</programlisting>
+-------+ <screen>
|nobody | nobody
+-------+ --------
|None | None
+-------+ </screen>
</programlisting>
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
...@@ -288,40 +308,39 @@ SELECT name(new_emp()) AS nobody; ...@@ -288,40 +308,39 @@ SELECT name(new_emp()) AS nobody;
the other (dot) syntax for projection when combined the other (dot) syntax for projection when combined
with function calls. with function calls.
<programlisting> <screen>
SELECT new_emp().name AS nobody; SELECT new_emp().name AS nobody;
NOTICE:parser: syntax error at or near "." NOTICE:parser: syntax error at or near "."
</programlisting> </screen>
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
</para> </para>
<para> <para>
Any collection of commands in the <acronym>SQL</acronym> query Any collection of commands in the <acronym>SQL</acronym>
language can be packaged together and defined as a function. language can be packaged together and defined as a function.
The commands can include updates (i.e., The commands can include data modification (i.e.,
<command>INSERT</command>, <command>UPDATE</command>, and <command>INSERT</command>, <command>UPDATE</command>, and
<command>DELETE</command>) as well <command>DELETE</command>) as well
as <command>SELECT</command> queries. However, the final command as <command>SELECT</command> queries. However, the final command
must be a <command>SELECT</command> that returns whatever is must be a <command>SELECT</command> that returns whatever is
specified as the function's returntype. specified as the function's return type.
<programlisting> <programlisting>
CREATE FUNCTION clean_EMP () CREATE FUNCTION clean_EMP () RETURNS integer AS '
RETURNS int4 DELETE FROM EMP
AS 'DELETE FROM EMP
WHERE EMP.salary &lt;= 0; WHERE EMP.salary &lt;= 0;
SELECT 1 AS ignore_this;' SELECT 1 AS ignore_this;
LANGUAGE 'sql'; ' LANGUAGE SQL;
SELECT clean_EMP(); SELECT clean_EMP();
</programlisting>
+--+ <screen>
|x | x
+--+ ---
|1 | 1
+--+ </screen>
</programlisting>
</para> </para>
</sect2> </sect2>
</sect1> </sect1>
...@@ -330,18 +349,19 @@ SELECT clean_EMP(); ...@@ -330,18 +349,19 @@ SELECT clean_EMP();
<title>Procedural Language Functions</title> <title>Procedural Language Functions</title>
<para> <para>
Procedural languages aren't built into Postgres. They are offered Procedural languages aren't built into the <productname>PostgreSQL</productname> server; they are offered
by loadable modules. Please refer to the documentation for the by loadable modules. Please refer to the documentation of the
PL in question for details about the syntax and how the AS procedural language in question for details about the syntax and how the function body
clause is interpreted by the PL handler. is interpreted for each language.
</para> </para>
<para> <para>
There are currently four procedural languages available in the There are currently four procedural languages available in the
standard <productname>PostgreSQL</productname> distribution: standard <productname>PostgreSQL</productname> distribution:
PL/pgSQL, PL/Tcl, PL/Perl, and PL/Python. Other languages can be <application>PL/pgSQL</application>, <application>PL/Tcl</application>,
<application>PL/Perl</application>, and <application>PL/Python</application>. Other languages can be
defined by users. Refer to <xref linkend="xplang"> for more defined by users. Refer to <xref linkend="xplang"> for more
information. information. The basics of developing a new procedural language are covered in <xref linkend="xfunc-plhandler">.
</para> </para>
</sect1> </sect1>
...@@ -350,22 +370,39 @@ SELECT clean_EMP(); ...@@ -350,22 +370,39 @@ SELECT clean_EMP();
<para> <para>
Internal functions are functions written in C that have been statically Internal functions are functions written in C that have been statically
linked into the <productname>Postgres</productname> backend linked into the <productname>PostgreSQL</productname> server.
process. The AS The <quote>body</quote> of the function definition
clause gives the C-language name of the function, which need not be the specifies the C-language name of the function, which need not be the
same as the name being declared for SQL use. same as the name being declared for SQL use.
(For reasons of backwards compatibility, an empty AS (For reasons of backwards compatibility, an empty body
string is accepted as meaning that the C-language function name is the is accepted as meaning that the C-language function name is the
same as the SQL name.) Normally, all internal functions present in the same as the SQL name.)
backend are declared as SQL functions during database initialization,
but a user could use <command>CREATE FUNCTION</command>
to create additional alias names for an internal function.
</para> </para>
<para> <para>
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.
Internal functions are declared in <command>CREATE FUNCTION</command> Internal functions are declared in <command>CREATE FUNCTION</command>
with language name <literal>internal</literal>. 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>.)
</para> </para>
<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>
</sect1> </sect1>
<sect1 id="xfunc-c"> <sect1 id="xfunc-c">
...@@ -495,23 +532,26 @@ SELECT clean_EMP(); ...@@ -495,23 +532,26 @@ SELECT clean_EMP();
<title>Base Types in C-Language Functions</title> <title>Base Types in C-Language Functions</title>
<para> <para>
The following table gives the C type required for parameters in the C <xref linkend="xfunc-c-type-table"> gives the C type required for
functions that will be loaded into Postgres. The <quote>Defined In</quote> parameters in the C functions that will be loaded into Postgres.
column gives the actual header file (in the The <quote>Defined In</quote> column gives the header file that
<filename>.../src/backend/</filename> needs to be included to get the type definition. (The actual
directory) that the equivalent C type is defined. Note that you should definition may be in a different file that is included by the
always include <filename>postgres.h</filename> first, and that in turn listed file. It is recommended that users stick to the defined
includes <filename>c.h</filename>. interface.) Note that you should always include
<filename>postgres.h</filename> first in any source file, because
<table tocentry="1"> it declares a number of things that you will need anyway.
</para>
<table tocentry="1" id="xfunc-c-type-table">
<title>Equivalent C Types <title>Equivalent C Types
for Built-In <productname>Postgres</productname> Types</title> for Built-In <productname>PostgreSQL</productname> Types</title>
<titleabbrev>Equivalent C Types</titleabbrev> <titleabbrev>Equivalent C Types</titleabbrev>
<tgroup cols="3"> <tgroup cols="3">
<thead> <thead>
<row> <row>
<entry> <entry>
Built-In Type SQL Type
</entry> </entry>
<entry> <entry>
C Type C Type
...@@ -523,134 +563,158 @@ SELECT clean_EMP(); ...@@ -523,134 +563,158 @@ SELECT clean_EMP();
</thead> </thead>
<tbody> <tbody>
<row> <row>
<entry>abstime</entry> <entry><type>abstime</type></entry>
<entry>AbsoluteTime</entry> <entry><type>AbsoluteTime</type></entry>
<entry>utils/nabstime.h</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>
<entry><filename>utils/geo-decls.h</filename></entry>
</row>
<row>
<entry><type>bytea</type></entry>
<entry><type>bytea*</type></entry>
<entry><filename>postgres.h</filename></entry>
</row> </row>
<row> <row>
<entry>bool</entry> <entry><type>"char"</type></entry>
<entry>bool</entry> <entry><type>char</type></entry>
<entry>include/c.h</entry> <entry>(compiler built-in)</entry>
</row> </row>
<row> <row>
<entry>box</entry> <entry><type>character</type></entry>
<entry>(BOX *)</entry> <entry><type>BpChar*</type></entry>
<entry>utils/geo-decls.h</entry> <entry><filename>postgres.h</filename></entry>
</row> </row>
<row> <row>
<entry>bytea</entry> <entry><type>cid</type></entry>
<entry>(bytea *)</entry> <entry><type>CommandId</type></entry>
<entry>include/postgres.h</entry> <entry><filename>postgres.h</filename></entry>
</row> </row>
<row> <row>
<entry>"char"</entry> <entry><type>date</type></entry>
<entry>char</entry> <entry><type>DateADT</type></entry>
<entry>N/A</entry> <entry><filename>utils/date.h</filename></entry>
</row> </row>
<row> <row>
<entry>cid</entry> <entry><type>smallint</type> (<type>int2</type>)</entry>
<entry>CID</entry> <entry><type>int2</type> or <type>int16</type></entry>
<entry>include/postgres.h</entry> <entry><filename>postgres.h</filename></entry>
</row> </row>
<row> <row>
<entry>datetime</entry> <entry><type>int2vector</type></entry>
<entry>(DateTime *)</entry> <entry><type>int2vector*</type></entry>
<entry>include/c.h or include/postgres.h</entry> <entry><filename>postgres.h</filename></entry>
</row> </row>
<row> <row>
<entry>int2</entry> <entry><type>integer</type> (<type>int4</type>)</entry>
<entry>int2 or int16</entry> <entry><type>int4</type> or <type>int32</type></entry>
<entry>include/postgres.h</entry> <entry><filename>postgres.h</filename></entry>
</row> </row>
<row> <row>
<entry>int2vector</entry> <entry><type>real</type> (<type>float4</type>)</entry>
<entry>(int2vector *)</entry> <entry><type>float4*</type></entry>
<entry>include/postgres.h</entry> <entry><filename>postgres.h</filename></entry>
</row> </row>
<row> <row>
<entry>int4</entry> <entry><type>double precision</type> (<type>float8</type>)</entry>
<entry>int4 or int32</entry> <entry><type>float8*</type></entry>
<entry>include/postgres.h</entry> <entry><filename>postgres.h</filename></entry>
</row> </row>
<row> <row>
<entry>float4</entry> <entry><type>interval</type></entry>
<entry>(float4 *)</entry> <entry><type>Interval*</type></entry>
<entry>include/c.h or include/postgres.h</entry> <entry><filename>utils/timestamp.h</filename></entry>
</row> </row>
<row> <row>
<entry>float8</entry> <entry><type>lseg</type></entry>
<entry>(float8 *)</entry> <entry><type>LSEG*</type></entry>
<entry>include/c.h or include/postgres.h</entry> <entry><filename>utils/geo-decls.h</filename></entry>
</row> </row>
<row> <row>
<entry>lseg</entry> <entry><type>name</type></entry>
<entry>(LSEG *)</entry> <entry><type>Name</type></entry>
<entry>include/geo-decls.h</entry> <entry><filename>postgres.h</filename></entry>
</row> </row>
<row> <row>
<entry>name</entry> <entry><type>oid</type></entry>
<entry>(Name)</entry> <entry><type>Oid</type></entry>
<entry>include/postgres.h</entry> <entry><filename>postgres.h</filename></entry>
</row> </row>
<row> <row>
<entry>oid</entry> <entry><type>oidvector</type></entry>
<entry>oid</entry> <entry><type>oidvector*</type></entry>
<entry>include/postgres.h</entry> <entry><filename>postgres.h</filename></entry>
</row> </row>
<row> <row>
<entry>oidvector</entry> <entry><type>path</type></entry>
<entry>(oidvector *)</entry> <entry><type>PATH*</type></entry>
<entry>include/postgres.h</entry> <entry><filename>utils/geo-decls.h</filename></entry>
</row> </row>
<row> <row>
<entry>path</entry> <entry><type>point</type></entry>
<entry>(PATH *)</entry> <entry><type>POINT*</type></entry>
<entry>utils/geo-decls.h</entry> <entry><filename>utils/geo-decls.h</filename></entry>
</row> </row>
<row> <row>
<entry>point</entry> <entry><type>regproc</type></entry>
<entry>(POINT *)</entry> <entry><type>regproc</type></entry>
<entry>utils/geo-decls.h</entry> <entry><filename>postgres.h</filename></entry>
</row> </row>
<row> <row>
<entry>regproc</entry> <entry><type>reltime</type></entry>
<entry>regproc or REGPROC</entry> <entry><type>RelativeTime</type></entry>
<entry>include/postgres.h</entry> <entry><filename>utils/nabstime.h</filename></entry>
</row> </row>
<row> <row>
<entry>reltime</entry> <entry><type>text</type></entry>
<entry>RelativeTime</entry> <entry><type>text*</type></entry>
<entry>utils/nabstime.h</entry> <entry><filename>postgres.h</filename></entry>
</row> </row>
<row> <row>
<entry>text</entry> <entry><type>tid</type></entry>
<entry>(text *)</entry> <entry><type>ItemPointer</type></entry>
<entry>include/postgres.h</entry> <entry><filename>storage/itemptr.h</filename></entry>
</row> </row>
<row> <row>
<entry>tid</entry> <entry><type>time</type></entry>
<entry>ItemPointer</entry> <entry><type>TimeADT</type></entry>
<entry>storage/itemptr.h</entry> <entry><filename>utils/date.h</filename></entry>
</row> </row>
<row> <row>
<entry>timespan</entry> <entry><type>time with time zone</type></entry>
<entry>(TimeSpan *)</entry> <entry><type>TimeTzADT</type></entry>
<entry>include/c.h or include/postgres.h</entry> <entry><filename>utils/date.h</filename></entry>
</row> </row>
<row> <row>
<entry>tinterval</entry> <entry><type>timestamp</type></entry>
<entry>TimeInterval</entry> <entry><type>Timestamp*</type></entry>
<entry>utils/nabstime.h</entry> <entry><filename>utils/timestamp.h</filename></entry>
</row> </row>
<row> <row>
<entry>xid</entry> <entry><type>tinterval</type></entry>
<entry>(XID *)</entry> <entry><type>TimeInterval</type></entry>
<entry>include/postgres.h</entry> <entry><filename>utils/nabstime.h</filename></entry>
</row>
<row>
<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>
</row> </row>
</tbody> </tbody>
</tgroup> </tgroup>
</table> </table>
</para>
<para> <para>
Internally, <productname>Postgres</productname> regards a Internally, <productname>Postgres</productname> regards a
...@@ -683,28 +747,31 @@ SELECT clean_EMP(); ...@@ -683,28 +747,31 @@ SELECT clean_EMP();
<para> <para>
By-value types can only be 1, 2 or 4 bytes in length By-value types can only be 1, 2 or 4 bytes in length
(also 8 bytes, if sizeof(Datum) is 8 on your machine). (also 8 bytes, if <literal>sizeof(Datum)</literal> is 8 on your machine).
You should be careful You should be careful
to define your types such that they will be the same to define your types such that they will be the same
size (in bytes) on all architectures. For example, the size (in bytes) on all architectures. For example, the
<literal>long</literal> type is dangerous because it <literal>long</literal> type is dangerous because it
is 4 bytes on some machines and 8 bytes on others, whereas is 4 bytes on some machines and 8 bytes on others, whereas
<literal>int</literal> type is 4 bytes on most <type>int</type> type is 4 bytes on most
Unix machines (though not on most Unix machines. A reasonable implementation of
personal computers). A reasonable implementation of the <type>int4</type> type on Unix
the <literal>int4</literal> type on Unix
machines might be: machines might be:
<programlisting> <programlisting>
/* 4-byte integer, passed by value */ /* 4-byte integer, passed by value */
typedef int int4; typedef int int4;
</programlisting> </programlisting>
<productname>PostgreSQL</productname> automatically figures
things out so that the integer types really have the size they
advertise.
</para> </para>
<para> <para>
On the other hand, fixed-length types of any size may On the other hand, fixed-length types of any size may
be passed by-reference. For example, here is a sample be passed by-reference. For example, here is a sample
implementation of a <productname>Postgres</productname> type: implementation of a <productname>PostgreSQL</productname> type:
<programlisting> <programlisting>
/* 16-byte structure, passed by reference */ /* 16-byte structure, passed by reference */
...@@ -1252,7 +1319,6 @@ LANGUAGE 'c'; ...@@ -1252,7 +1319,6 @@ LANGUAGE 'c';
to include <filename>postgres.h</filename> <emphasis>first</>, to include <filename>postgres.h</filename> <emphasis>first</>,
before any other system or user header files. before any other system or user header files.
Including <filename>postgres.h</filename> will also include Including <filename>postgres.h</filename> will also include
<filename>c.h</filename>,
<filename>elog.h</filename> and <filename>palloc.h</filename> <filename>elog.h</filename> and <filename>palloc.h</filename>
for you. for you.
</para> </para>
...@@ -1291,71 +1357,66 @@ LANGUAGE 'c'; ...@@ -1291,71 +1357,66 @@ LANGUAGE 'c';
<title>Function Overloading</title> <title>Function Overloading</title>
<para> <para>
More than one function may be defined with the same name, so long as More than one function may be defined with the same name, so long
the arguments they take are different. In other words, function names as the arguments they take are different. In other words,
can be <firstterm>overloaded</firstterm>. 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>
A function may also have the same name as an attribute. In the case 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 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. an attribute of the complex type, the attribute will always be used.
</para> </para>
<sect2> <para>
<title>Name Space Conflicts</title> When creating a family of overloaded functions, one should be
careful not to create ambiguities. For instance, given the
<para> functions
As of <productname>Postgres</productname> 7.0, the alternative <programlisting>
form of the AS clause for the SQL CREATE FUNCTION test(int, real) RETURNS ...
<command>CREATE FUNCTION</command> command CREATE FUNCTION test(smallint, double precision) RETURNS ...
decouples the SQL function name from the function name in the C </programlisting>
source code. This is now the preferred technique to accomplish it is not immediately clear which function would be called with
function overloading. some trivial input like <literal>test(1, 1.5)</literal>. The
</para> currently implemented resolution rules are described in the
<citetitle>User's Guide</citetitle>, but it is unwise to design a
<sect3> system that subtly relies on this behavior.
<title>Pre-7.0</title> </para>
<para>
For functions written in C, the SQL name declared in
<command>CREATE FUNCTION</command>
must be exactly the same as the actual name of the function in the
C code (hence it must be a legal C function name).
</para>
<para>
There is a subtle implication of this restriction: while the
dynamic loading routines in most operating systems are more than
happy to allow you to load any number of shared libraries that
contain conflicting (identically-named) function names, they may
in fact botch the load in interesting ways. For example, if you
define a dynamically-loaded function that happens to have the
same name as a function built into Postgres, the DEC OSF/1 dynamic
loader causes Postgres to call the function within itself rather than
allowing Postgres to call your function. Hence, if you want your
function to be used on different architectures, we recommend that
you do not overload C function names.
</para>
<para> <para>
There is a clever trick to get around the problem just described. When overloading C language functions, there is an additional
Since there is no problem overloading SQL functions, you can constraint: The C name of each function in the family of
define a set of C functions with different names and then define overloaded functions must be different from the C names of all
a set of identically-named SQL function wrappers that take the other functions, either internal or dynamically loaded. If this
appropriate argument types and call the matching C function. rule is violated, the behavior is not portable. You might get a
</para> 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>
<para> <para>
Another solution is not to use dynamic loading, but to link your Prior to <productname>PostgreSQL</productname> 7.0, this
functions into the backend statically and declare them as INTERNAL alternative syntax did not exist. There is a trick to get around
functions. Then, the functions must all have distinct C names but the problem, by defining a set of C functions with different names
they can be declared with the same SQL names (as long as their and then define a set of identically-named SQL function wrappers
argument types differ, of course). This way avoids the overhead of that take the appropriate argument types and call the matching C
an SQL wrapper function, at the cost of more effort to prepare a function.
custom backend executable. (This option is only available in version </para>
6.5 and later, since prior versions required internal functions to
have the same name in SQL as in the C code.)
</para>
</sect3>
</sect2>
</sect1> </sect1>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment