Documentation updates to reflect TOAST and new-style fmgr.

This commit is contained in:
Tom Lane 2000-08-24 23:36:29 +00:00
parent 481487b964
commit 0813fcbc08
7 changed files with 474 additions and 177 deletions

View File

@ -130,10 +130,12 @@ UPDATE sal_emp SET pay_by_quarter[1:2] = '{27000,27000}'
</Para>
<Para>
It is not currently possible to resize an array value except by
complete replacement; for example, we couldn't change a four-
element array value to a five-element value with a single
assignment to array[5].
An array can be enlarged by assigning to an element adjacent to
those already present, or by assigning to a slice that is adjacent
to or overlaps the data already present. Currently, this is only
allowed for one-dimensional arrays, not multidimensional arrays.
For example, if an array value currently has 4 elements, it will
have five elements after an update that assigns to array[5].
</Para>
<Para>

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.33 2000/08/23 05:59:01 thomas Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.34 2000/08/24 23:36:28 tgl Exp $
-->
<chapter id="datatype">
@ -42,7 +42,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.33 2000/08/23 05:59:01 th
<thead>
<row>
<entry><productname>Postgres</productname> Type</entry>
<entry><acronym>SQL92</acronym> or <acronym>SQL3</acronym> Type</entry>
<entry><acronym>SQL92</acronym> or <acronym>SQL99</acronym> Type</entry>
<entry>Description</entry>
</row>
</thead>
@ -80,7 +80,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.33 2000/08/23 05:59:01 th
<row>
<entry>decimal</entry>
<entry>decimal(p,s)</entry>
<entry>exact numeric for p <= 9, s = 0</entry>
<entry>exact numeric with selectable precision</entry>
</row>
<row>
<entry>float4</entry>
@ -135,7 +135,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.33 2000/08/23 05:59:01 th
<row>
<entry>numeric</entry>
<entry>numeric(p,s)</entry>
<entry>exact numeric for p == 9, s = 0</entry>
<entry>exact numeric with selectable precision</entry>
</row>
<row>
<entry>path</entry>
@ -157,6 +157,11 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.33 2000/08/23 05:59:01 th
<entry></entry>
<entry>unique id for indexing and cross-reference</entry>
</row>
<row>
<entry>text</entry>
<entry></entry>
<entry>variable-length character string</entry>
</row>
<row>
<entry>time</entry>
<entry>time [ without time zone ]</entry>
@ -234,7 +239,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.33 2000/08/23 05:59:01 th
<para>
<productname>Postgres</productname> has features at the forefront of
<acronym>ORDBMS</acronym> development. In addition to
<acronym>SQL3</acronym> conformance, substantial portions
<acronym>SQL99</acronym> conformance, substantial portions
of <acronym>SQL92</acronym> are also supported.
Although we strive for <acronym>SQL92</acronym> compliance,
there are some aspects of the standard
@ -275,7 +280,8 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.33 2000/08/23 05:59:01 th
<title>Numeric Types</title>
<para>
Numeric types consist of two- and four-byte integers, four- and eight-byte
Numeric types consist of two-, four-, and eight-byte integers,
four- and eight-byte
floating point numbers and fixed-precision decimals.
</para>
@ -297,7 +303,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.33 2000/08/23 05:59:01 th
<entry>decimal</entry>
<entry>variable</entry>
<entry>User-specified precision</entry>
<entry>~8000 digits</entry>
<entry>no limit</entry>
</row>
<row>
<entry>float4</entry>
@ -327,7 +333,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.33 2000/08/23 05:59:01 th
<entry>int8</entry>
<entry>8 bytes</entry>
<entry>Very large range fixed-precision</entry>
<entry>+/- &gt; 18 decimal places</entry>
<entry>~18 decimal places</entry>
</row>
<row>
<entry>numeric</entry>
@ -354,7 +360,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.33 2000/08/23 05:59:01 th
<para>
The <type>int8</type> type may not be available on all platforms since
it relies on compiler support for this.
it relies on compiler support for eight-byte integers.
</para>
<sect2>
@ -483,7 +489,7 @@ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (<replaceabl
</thead>
<tbody>
<row>
<entry>char</entry>
<entry>"char"</entry>
<entry>1 byte</entry>
<entry><acronym>SQL92</acronym>-compatible</entry>
<entry>Single character</entry>
@ -502,7 +508,7 @@ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (<replaceabl
</row>
<row>
<entry>varchar(n)</entry>
<entry>(4+n) bytes</entry>
<entry>(4+x) bytes</entry>
<entry><acronym>SQL92</acronym>-compatible</entry>
<entry>Variable-length with limit</entry>
</row>
@ -1359,10 +1365,10 @@ January 8 04:05:06 1999 PST
<para>
<productname>Postgres</productname> supports <type>bool</type> as
the <acronym>SQL3</acronym> boolean type.
the <acronym>SQL99</acronym> boolean type.
<type>bool</type> can have one of only two states: 'true' or 'false'.
A third state, 'unknown', is not
implemented and is not suggested in <acronym>SQL3</acronym>;
implemented and is not suggested in <acronym>SQL99</acronym>;
<acronym>NULL</acronym> is an
effective substitute. <type>bool</type> can be used in any boolean expression,
and boolean expressions

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.15 2000/07/22 04:30:27 momjian Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.16 2000/08/24 23:36:29 tgl Exp $
Postgres documentation
-->
@ -31,7 +31,7 @@ CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceab
CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceable class="parameter">ftype</replaceable> [, ...] ] )
RETURNS <replaceable class="parameter">rtype</replaceable>
AS <replaceable class="parameter">obj_file</replaceable> , <replaceable class="parameter">link_symbol</replaceable>
LANGUAGE 'C'
LANGUAGE 'langname'
[ WITH ( <replaceable class="parameter">attribute</replaceable> [, ...] ) ]
</synopsis>
@ -57,11 +57,11 @@ CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceab
<term><replaceable class="parameter">ftype</replaceable></term>
<listitem>
<para>
The data type of function arguments.
The data type(s) of the function's arguments, if any.
The input types may be base or complex types, or
<firstterm>opaque</firstterm>.
<literal>opaque</literal> indicates that the function
accepts arguments of an invalid type such as <type>char *</type>.
accepts arguments of a non-SQL type such as <type>char *</type>.
</para>
</listitem>
</varlistentry>
@ -84,14 +84,7 @@ CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceab
<listitem>
<para>
An optional piece of information about the function, used for
optimization. The only attribute currently supported is
<literal>iscachable</literal>.
<literal>iscachable</literal> indicates that the function always
returns the same result when given the same input values (i.e.,
it does not do database lookups or otherwise use information not
directly present in its parameter list). The optimizer uses
<literal>iscachable</literal> to know whether it is safe to
pre-evaluate a call of the function.
optimization. See below for details.
</para>
</listitem>
</varlistentry>
@ -115,8 +108,8 @@ CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceab
function. The string <replaceable
class="parameter">obj_file</replaceable> is the name of the file
containing the dynamically loadable object, and <replaceable
class="parameter">link_symbol</replaceable>, is the object's link
symbol which is the same as the name of the function in the C
class="parameter">link_symbol</replaceable> is the object's link
symbol, that is the name of the function in the C
language source code.
</para>
</listitem>
@ -125,8 +118,9 @@ CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceab
<term><replaceable class="parameter">langname</replaceable></term>
<listitem>
<para>
may be '<literal>C</literal>', '<literal>sql</literal>',
'<literal>internal</literal>'
may be '<literal>sql</literal>',
'<literal>C</literal>', '<literal>newC</literal>',
'<literal>internal</literal>', '<literal>newinternal</literal>',
or '<replaceable class="parameter">plname</replaceable>',
where '<replaceable class="parameter">plname</replaceable>'
is the name of a created procedural language. See
@ -175,11 +169,57 @@ CREATE
<command>CREATE FUNCTION</command> allows a
<productname>Postgres</productname> user
to register a function
with a database. Subsequently, this user is considered the
with the database. Subsequently, this user is considered the
owner of the function.
</para>
<refsect2 id="R2-SQL-CREATEFUNCTION-3">
<refsect2info>
<date>2000-08-24</date>
</refsect2info>
<title>
Function Attributes
</title>
<para>
The following items may appear in the WITH clause:
<variablelist>
<varlistentry>
<literal>iscachable</literal>
<listitem>
<para>
<literal>iscachable</literal> indicates that the function always
returns the same result when given the same argument values (i.e.,
it does not do database lookups or otherwise use information not
directly present in its parameter list). The optimizer uses
<literal>iscachable</literal> to know whether it is safe to
pre-evaluate a call of the function.
</para>
</listitem>
</varlistentry>
<varlistentry>
<literal>isstrict</literal>
<listitem>
<para>
<literal>isstrict</literal> indicates that the function always
returns NULL whenever any of its arguments are NULL. If this
attribute is specified, the function is not executed when there
are NULL arguments; instead a NULL result is assumed automatically.
When <literal>isstrict</literal> is not specified, the function will
be called for NULL inputs. It is then the function author's
responsibility to check for NULLs if necessary and respond
appropriately.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect2>
<refsect2 id="R2-SQL-CREATEFUNCTION-4">
<refsect2info>
<date>2000-03-25</date>
</refsect2info>
@ -200,26 +240,25 @@ CREATE
to remove user-defined functions.
</para>
<para>
<productname>Postgres</productname> allows function "overloading";
that is, the same name can be used for several different functions
so long as they have distinct argument types. This facility must
be used with caution for <literal>internal</literal> and
C-language functions, however.
</para>
<para>
The full <acronym>SQL92</acronym> type syntax is allowed for
input arguments and return value. However, some details of the
type specification (e.g. the precision field for
<type>numeric</type> types) are the responsibility of the
underlying function implementation and are silently swallowed
(e.g. not recognized or
(i.e., not recognized or
enforced) by the <command>CREATE FUNCTION</command> command.
</para>
<para>
Two <literal>internal</literal>
<productname>Postgres</productname> allows function "overloading";
that is, the same name can be used for several different functions
so long as they have distinct argument types. This facility must
be used with caution for internal and C-language functions, however.
</para>
<para>
Two <literal>internal</literal> or <literal>newinternal</literal>
functions cannot have the same C name without causing
errors at link time. To get around that, give them different C names
(for example, use the argument types as part of the C names), then
@ -229,18 +268,14 @@ CREATE
</para>
<para>
When overloading SQL functions with C-language functions, give
each C-language instance of the function a distinct name, and use
Similarly, when overloading SQL function names with multiple C-language
functions, give
each C-language instance of the function a distinct name, then use
the alternative form of the <command>AS</command> clause in the
<command>CREATE FUNCTION</command> syntax to ensure that
overloaded SQL functions names are resolved to the correct
dynamically linked objects.
<command>CREATE FUNCTION</command> syntax to select the appropriate
C-language implementation of each overloaded SQL function.
</para>
<para>
A C function cannot return a set of values.
</para>
</refsect2>
</refsect1>
@ -291,7 +326,7 @@ CREATE TABLE product (
function is implemented by a dynamically loaded object that was
compiled from C source. For <productname>Postgres</productname> to
find a type conversion function automatically, the sql function has
to have the same name as the return type, and overloading is
to have the same name as the return type, and so overloading is
unavoidable. The function name is overloaded by using the second
form of the <command>AS</command> clause in the SQL definition:
</para>
@ -324,7 +359,7 @@ Point * complex_to_point (Complex *z)
Compatibility
</title>
<refsect2 id="R2-SQL-CREATEFUNCTION-4">
<refsect2 id="R2-SQL-CREATEFUNCTION-5">
<refsect2info>
<date>2000-03-25</date>
</refsect2info>
@ -338,7 +373,7 @@ Point * complex_to_point (Complex *z)
</para>
</refsect2>
<refsect2 id="R2-SQL-CREATEFUNCTION-5">
<refsect2 id="R2-SQL-CREATEFUNCTION-6">
<refsect2info>
<date>2000-03-25</date>
</refsect2info>

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_language.sgml,v 1.10 2000/05/29 01:59:06 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_language.sgml,v 1.11 2000/08/24 23:36:29 tgl Exp $
Postgres documentation
-->
@ -48,8 +48,7 @@ CREATE [ TRUSTED ] PROCEDURAL LANGUAGE '<replaceable class="parameter">langname<
this keyword is omitted when registering the language,
only users with the <productname>Postgres</productname>
superuser privilege can use
this language to create new functions
(like the 'C' language).
this language to create new functions.
</para>
</listitem>
</varlistentry>
@ -222,6 +221,11 @@ ERROR: PL handler function <replaceable class="parameter">funcname</replaceable
must be careful that <literal>flinfo-&gt;fn_extra</literal> is made to
point at memory that will live at least until the end of the current
query, since an FmgrInfo data structure could be kept that long.
One way to do this is to allocate the extra data in the memory context
specified by <literal>flinfo-&gt;fn_mcxt</literal>; such data will
normally have the same lifespan as the FmgrInfo 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>
@ -262,20 +266,21 @@ ERROR: PL handler function <replaceable class="parameter">funcname</replaceable
lanplcallfoid | oid |
lancompiler | text |
lanname | lanispl | lanpltrusted | lanplcallfoid | lancompiler
----------+---------+--------------+---------------+-------------
internal | f | f | 0 | n/a
C | f | f | 0 | /bin/cc
sql | f | f | 0 | postgres
lanname | lanispl | lanpltrusted | lanplcallfoid | lancompiler
-------------+---------+--------------+---------------+-------------
internal | f | f | 0 | n/a
newinternal | f | f | 0 | n/a
C | f | f | 0 | /bin/cc
newC | f | f | 0 | /bin/cc
sql | f | f | 0 | postgres
</computeroutput>
</programlisting>
</para>
<para>
Since the call handler for a procedural language must be
registered with <productname>Postgres</productname> in the 'C' language,
it inherits
all the capabilities and restrictions of 'C' functions.
The call handler for a procedural language must normally be written
in C and registered as 'newinternal' or 'newC' language, depending
on whether it is linked into the backend or dynamically loaded.
</para>
<para>

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_table.sgml,v 1.33 2000/07/22 04:30:27 momjian Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_table.sgml,v 1.34 2000/08/24 23:36:29 tgl Exp $
Postgres documentation
-->
@ -248,11 +248,9 @@ ERROR: DEFAULT: type mismatched
<para>
The new table is created as a heap with no initial data.
A table can have no more than 1600 columns (realistically,
this is limited by the fact that tuple sizes must
be less than 8192 bytes), but this limit may be configured
lower at some sites. A table cannot have the same name as
a system catalog table.
A table can have no more than 1600 columns (in practice, the
effective limit is lower because of tuple-length constraints).
A table cannot have the same name as a system catalog table.
</para>
</refsect1>

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_type.sgml,v 1.12 2000/03/27 17:14:42 thomas Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_type.sgml,v 1.13 2000/08/24 23:36:29 tgl Exp $
Postgres documentation
-->
@ -24,11 +24,16 @@ Postgres documentation
</refsynopsisdivinfo>
<synopsis>
CREATE TYPE <replaceable class="parameter">typename</replaceable> ( INPUT = <replaceable class="parameter">input_function</replaceable>, OUTPUT = <replaceable class="parameter">output_function</replaceable>
, INTERNALLENGTH = { <replaceable class="parameter">internallength</replaceable> | VARIABLE } [ , EXTERNALLENGTH = { <replaceable class="parameter">externallength</replaceable> | VARIABLE } ]
, INTERNALLENGTH = { <replaceable
class="parameter">internallength</replaceable> | VARIABLE }
[ , EXTERNALLENGTH = { <replaceable class="parameter">externallength</replaceable> | VARIABLE } ]
[ , DEFAULT = "<replaceable class="parameter">default</replaceable>" ]
[ , ELEMENT = <replaceable class="parameter">element</replaceable> ] [ , DELIMITER = <replaceable class="parameter">delimiter</replaceable> ]
[ , SEND = <replaceable class="parameter">send_function</replaceable> ] [ , RECEIVE = <replaceable class="parameter">receive_function</replaceable> ]
[ , PASSEDBYVALUE ] )
[ , PASSEDBYVALUE ]
[ , ALIGNMENT = <replaceable class="parameter">alignment</replaceable> ]
[ , STORAGE = <replaceable class="parameter">storage</replaceable> ]
)
</synopsis>
<refsect2 id="R2-SQL-CREATETYPE-1">
@ -64,7 +69,7 @@ CREATE TYPE <replaceable class="parameter">typename</replaceable> ( INPUT = <rep
<term><replaceable class="parameter">externallength</replaceable></term>
<listitem>
<para>
A literal value, which specifies the external length of
A literal value, which specifies the external (displayed) length of
the new type.
</para>
</listitem>
@ -86,7 +91,8 @@ CREATE TYPE <replaceable class="parameter">typename</replaceable> ( INPUT = <rep
<term><replaceable class="parameter">output_function</replaceable></term>
<listitem>
<para>
The name of a function, created by CREATE FUNCTION, which
The name of a function, created by
<command>CREATE FUNCTION</command>, which
converts data from its internal form to a form suitable
for display.
</para>
@ -107,7 +113,7 @@ CREATE TYPE <replaceable class="parameter">typename</replaceable> ( INPUT = <rep
<term><replaceable class="parameter">delimiter</replaceable></term>
<listitem>
<para>
The delimiter character for the array.
The delimiter character for the array elements.
</para>
</listitem>
</varlistentry>
@ -116,8 +122,8 @@ CREATE TYPE <replaceable class="parameter">typename</replaceable> ( INPUT = <rep
<term><replaceable class="parameter">default</replaceable></term>
<listitem>
<para>
The default text to be displayed to indicate "data
not present"
The default value for the datatype. Usually this is omitted,
so that the default is NULL.
</para>
</listitem>
</varlistentry>
@ -141,6 +147,29 @@ CREATE TYPE <replaceable class="parameter">typename</replaceable> ( INPUT = <rep
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">alignment</replaceable></term>
<listitem>
<para>
Storage alignment requirement of the datatype. If specified, must
be '<literal>int4</literal>' or '<literal>double</literal>';
the default is '<literal>int4</literal>'.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">storage</replaceable></term>
<listitem>
<para>
Storage technique for the datatype. If specified, must
be '<literal>plain</literal>', '<literal>external</literal>',
'<literal>extended</literal>', or '<literal>main</literal>';
the default is '<literal>plain</literal>'.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect2>
@ -267,6 +296,24 @@ CREATE
more than four bytes.
</para>
<para>
The <replaceable class="parameter">storage</replaceable> keyword
allows selection of TOAST storage method for variable-length datatypes
(only <literal>plain</literal> is allowed for fixed-length types).
<literal>plain</literal> disables TOAST for the datatype: it will always
be stored in-line and not compressed.
<literal>extended</literal> is full TOAST capability: the system will
first try to compress a long data value, and will move the value out of
the main table row if it's still too long.
<literal>external</literal> allows the value to be moved out of the main
table, but the system will not try to compress it.
<literal>main</literal> allows compression, but discourages moving the
value out of the main table. (Data items with this storage method may
still be moved out of the main table if there is no other way to make
a row fit, but they will be kept in the main table preferentially over
<literal>extended</literal> and <literal>external</literal> items.)
</para>
<para>
For new base types, a user can define operators, functions
and aggregates using the appropriate facilities described
@ -283,17 +330,6 @@ CREATE
</para>
</refsect2>
<refsect2>
<title>Large Object Types</title>
<para>
A "regular" Postgres type can only be 8192 bytes in
length. If you need a larger type you must create a Large
Object type. The interface for these types is discussed
at length in the
<citetitle>PostgreSQL Programmer's Guide</citetitle>.
The length of all large object types is always VARIABLE.
</para>
</refsect2>
</refsect1>
<refsect1>

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.18 2000/08/21 17:22:36 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.19 2000/08/24 23:36:28 tgl Exp $
-->
<chapter id="xfunc">
@ -64,10 +64,9 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.18 2000/08/21 17:22:36 tgl E
<para>
The body of a SQL function following AS
should be a list of queries separated by whitespace characters and
bracketed within quotation marks. Note that quotation marks used in
the queries must be escaped, by preceding them with two
backslashes.
should be a list of queries separated by semicolons and
bracketed within single-quote marks. Note that quote marks used in
the queries must be escaped, by preceding them with a backslash.
</para>
<para>
@ -100,7 +99,7 @@ LANGUAGE 'sql';
follows:
<programlisting>
select (x = TP1( 17,100.0));
select TP1( 17,100.0);
</programlisting>
</para>
@ -109,7 +108,7 @@ select (x = TP1( 17,100.0));
EMP, and retrieves multiple results:
<programlisting>
select function hobbies (EMP) returns set of HOBBIES
create function hobbies (EMP) returns setof HOBBIES
as 'select HOBBIES.* from HOBBIES
where $1.name = HOBBIES.person'
language 'sql';
@ -140,10 +139,9 @@ SELECT one() AS answer;
</programlisting>
</para>
<para>
Notice that we defined a target list for the function
(with the name RESULT), but the target list of the
query that invoked the function overrode the function's
target list. Hence, the result is labelled answer
Notice that we defined a column name for the function's result
(with the name RESULT), but this column name is not visible
outside the function. Hence, the result is labelled answer
instead of one.
</para>
<para>
@ -204,7 +202,7 @@ WHERE EMP.cubicle ~= '(2,1)'::point;
return composite types, we must first introduce the
function notation for projecting attributes. The simple way
to explain this is that we can usually use the
notation attribute(class) and class.attribute interchangably:
notations attribute(class) and class.attribute interchangably:
<programlisting>
--
@ -252,17 +250,16 @@ LANGUAGE 'sql';
<para>
The target list order must be exactly the same as
that in which the attributes appear in the CREATE
TABLE statement (or when you execute a .* query).
TABLE statement that defined the composite type.
</para>
</listitem>
<listitem>
<para>
You must typecast the expressions (using ::) very carefully
or you will see the following error:
You must typecast the expressions (using ::) to match the
composite type's definition, or you will get errors like this:
<programlisting>
<computeroutput>
NOTICE::function declared to return type EMP does not retrieve (EMP.*)
ERROR: function declared to return emp returns varchar instead of text at column 1
</computeroutput>
</programlisting>
</para>
@ -366,6 +363,16 @@ SELECT clean_EMP();
but a user could use <command>CREATE FUNCTION</command>
to create additional alias names for an internal function.
</para>
<para>
Internal functions are declared in <command>CREATE FUNCTION</command>
with language name <literal>internal</literal> or
<literal>newinternal</literal>, depending on whether they follow the
old (pre-7.1) or new (7.1 and later) function call conventions.
The details of the call conventions are the same as for
<literal>C</literal> and <literal>newC</literal> functions respectively;
see the next section for details.
</para>
</sect1>
<sect1>
@ -373,50 +380,59 @@ SELECT clean_EMP();
<para>
Functions written in C can be compiled into dynamically loadable
objects, and used to implement user-defined SQL functions. The
first time the user defined function is called inside the backend,
the dynamic loader loads the function's object code into memory,
and links the function with the running
<productname>Postgres</productname> executable. The SQL syntax
for <command>CREATE FUNCTION</command>
links the SQL function
to the C source function in one of two ways. If the SQL function
has the same name as the C source function the first form of the
statement is used. The string argument in the AS clause is the
full pathname of the file that contains the dynamically loadable
compiled object. If the name of the C function is different from the
desired name of the SQL function, then the second form is used. In this
form the AS clause takes two string arguments, the first is the
full pathname of the dynamically loadable object file, and the
second is the link symbol that the dynamic loader should search
for. This link symbol is just the function name in the C source
code.
objects (also called shared libraries), and used to implement user-defined
SQL functions. The first time a user-defined function in a particular
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>
for a user-defined function must therefore specify two pieces of
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.
<note>
<para>
After it is used for the first time, a dynamically loaded, user
After it is used for the first time, a dynamically loaded user
function is retained in memory, and future calls to the function
only incur the small overhead of a symbol table lookup.
in the same session will only incur the small overhead of a symbol table
lookup.
</para>
</note>
</para>
<para>
The string which specifies the object file (the string in the AS
The string which specifies the object file (the first string in the AS
clause) should be the <emphasis>full path</emphasis> of the object
code file for the function, bracketed by quotation marks. If a
link symbol is used in the AS clause, the link symbol should also be
link symbol is given in the AS clause, the link symbol should also be
bracketed by single quotation marks, and should be exactly the
same as the name of the function in the C source code. On Unix systems
the command <command>nm</command> will print all of the link
symbols in a dynamically loadable object.
(<productname>Postgres</productname> will not compile a function
automatically; it must be compiled before it is used in a CREATE
FUNCTION command. See below for additional information.)
<note>
<para>
<productname>Postgres</productname> will not compile a function
automatically; it must be compiled before it is used in a CREATE
FUNCTION command. See below for additional information.
</para>
</note>
</para>
<para>
Two different calling conventions are currently used for C functions.
The "old style" (pre-<productname>Postgres</productname>-7.1) method
is selected by writing language name '<literal>C</literal>' in the
<command>CREATE FUNCTION</command> command, while the "new style"
(7.1 and later) method is selecting by writing language name
'<literal>newC</literal>'. Old-style functions are now deprecated
because of portability problems and lack of functionality, but they
are still supported for compatibility reasons.
</para>
<sect2>
<title>C Language Functions on Base Types</title>
<title>Base Types in C-Language Functions</title>
<para>
The following table gives the C type required for parameters in the C
@ -484,7 +500,7 @@ SELECT clean_EMP();
</row>
<row>
<entry>int2</entry>
<entry>int2</entry>
<entry>int2 or int16</entry>
<entry>include/postgres.h</entry>
</row>
<row>
@ -494,7 +510,7 @@ SELECT clean_EMP();
</row>
<row>
<entry>int4</entry>
<entry>int4</entry>
<entry>int4 or int32</entry>
<entry>include/postgres.h</entry>
</row>
<row>
@ -654,6 +670,12 @@ typedef struct
<para>
Only pointers to such types can be used when passing
them in and out of <productname>Postgres</productname> functions.
To return a value of such a type, allocate the right amount of
memory with <literal>palloc()</literal>, fill in the allocated memory,
and return a pointer to it.
</para>
<para>
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
@ -694,8 +716,24 @@ memmove(destination-&gt;data, buffer, 40);
<para>
Now that we've gone over all of the possible structures
for base types, we can show some examples of real functions.
Suppose <filename>funcs.c</filename> look like:
for base types, we can show some examples of real functions.
</para>
</sect2>
<sect2>
<title>Old-style Calling Conventions for C-Language Functions</title>
<para>
We present the "old style" calling convention first --- although
this approach is now deprecated, it's easier to get a handle on
initially. In the "old style" method, the arguments and result
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:
<programlisting>
#include &lt;string.h&gt;
@ -706,13 +744,23 @@ memmove(destination-&gt;data, buffer, 40);
int
add_one(int arg)
{
return(arg + 1);
return arg + 1;
}
/* By Reference, Fixed Length */
float8 *
add_one_float8(float8 *arg)
{
float8 *result = (float8 *) palloc(sizeof(float8));
*result = *arg + 1.0;
return result;
}
Point *
makepoint(Point *pointx, Point *pointy )
makepoint(Point *pointx, Point *pointy)
{
Point *new_point = (Point *) palloc(sizeof(Point));
@ -731,15 +779,14 @@ copytext(text *t)
* VARSIZE is the total size of the struct in bytes.
*/
text *new_t = (text *) palloc(VARSIZE(t));
memset(new_t, 0, VARSIZE(t));
VARSIZE(new_t) = 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 */
VARSIZE(t)-VARHDRSZ); /* how many bytes */
return(new_t);
VARSIZE(t)-VARHDRSZ); /* how many bytes */
return new_t;
}
text *
@ -749,40 +796,197 @@ concat_text(text *arg1, text *arg2)
text *new_text = (text *) palloc(new_text_size);
memset((void *) new_text, 0, new_text_size);
VARSIZE(new_text) = new_text_size;
VARATT_SIZEP(new_text) = new_text_size;
strncpy(VARDATA(new_text), VARDATA(arg1), VARSIZE(arg1)-VARHDRSZ);
strncat(VARDATA(new_text), VARDATA(arg2), VARSIZE(arg2)-VARHDRSZ);
return (new_text);
return new_text;
}
</programlisting>
</para>
<para>
On <acronym>OSF/1</acronym> we would type:
Supposing that the above code has been prepared in file
<filename>funcs.c</filename> and compiled into a shared object,
we could define the functions to <productname>Postgres</productname>
with commands like this:
<programlisting>
CREATE FUNCTION add_one(int4) RETURNS int4
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs.so' LANGUAGE 'c';
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs.so' LANGUAGE 'c'
WITH (isStrict);
-- note overloading of SQL function name add_one()
CREATE FUNCTION add_one(float8) RETURNS float8
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs.so',
'add_one_float8'
LANGUAGE 'c' WITH (isStrict);
CREATE FUNCTION makepoint(point, point) RETURNS point
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs.so' LANGUAGE 'c';
CREATE FUNCTION concat_text(text, text) RETURNS text
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs.so' LANGUAGE 'c';
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs.so' LANGUAGE 'c'
WITH (isStrict);
CREATE FUNCTION copytext(text) RETURNS text
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs.so' LANGUAGE 'c';
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs.so' LANGUAGE 'c'
WITH (isStrict);
CREATE FUNCTION concat_text(text, text) RETURNS text
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs.so' LANGUAGE 'c'
WITH (isStrict);
</programlisting>
</para>
<para>
On other systems, we might have to make the filename
end in .sl (to indicate that it's a shared library).
Here <replaceable>PGROOT</replaceable> stands for the full path to
the <productname>Postgres</productname> source tree. Note that
depending on your system, the filename for a shared object might
not end in <literal>.so</literal>, but in <literal>.sl</literal>
or something else; adapt accordingly.
</para>
<para>
Notice that we have specified the functions as "strict", meaning that
the system should automatically assume a NULL result if any input
value is NULL. By doing this, we avoid having to check for NULL inputs
in the function code. Without this, we'd have to check for NULLs
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>
Although this old-style calling convention is simple to use,
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
in any way other than making the function strict. The new-style
convention, presented next, overcomes these objections.
</para>
</sect2>
<sect2>
<title>C Language Functions on Composite Types</title>
<title>New-style Calling Conventions for C-Language Functions</title>
<para>
The new-style calling convention relies on macros to suppress most
of the complexity of passing arguments and results. The C declaration
of a new-style function is always
<programlisting>
Datum funcname(PG_FUNCTION_ARGS)
</programlisting>
Each actual argument is fetched using a PG_GETARG_xxx() macro that
corresponds to the argument's datatype, and the result is returned
using a PG_RETURN_xxx() macro for the return type.
</para>
<para>
Here we show the same functions as above, coded in new style:
<programlisting>
#include &lt;string.h&gt;
#include "postgres.h"
#include "fmgr.h"
/* By Value */
Datum
add_one(PG_FUNCTION_ARGS)
{
int32 arg = PG_GETARG_INT32(0);
PG_RETURN_INT32(arg + 1);
}
/* By Reference, Fixed Length */
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);
}
Datum
makepoint(PG_FUNCTION_ARGS)
{
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 */
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 */
VARSIZE(t)-VARHDRSZ); /* how many bytes */
PG_RETURN_TEXT_P(new_t);
}
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);
memset((void *) new_text, 0, new_text_size);
VARATT_SIZEP(new_text) = new_text_size;
strncpy(VARDATA(new_text), VARDATA(arg1), VARSIZE(arg1)-VARHDRSZ);
strncat(VARDATA(new_text), VARDATA(arg2), VARSIZE(arg2)-VARHDRSZ);
PG_RETURN_TEXT_P(new_text);
}
</programlisting>
</para>
<para>
The <command>CREATE FUNCTION</command> commands are the same as
for the old-style equivalents, except that the language is specified
as '<literal>newC</literal>' not '<literal>C</literal>'.
</para>
<para>
At first glance, the new-style coding conventions may appear to be
just pointless obscurantism. However, they do offer a number of
improvements, because the macros can hide unnecessary detail.
An example is that in coding add_one_float8, we no longer need to
be aware that float8 is a pass-by-reference type. Another example
is that the GETARG macros for variable-length types hide the need
to deal with fetching "toasted" (compressed or out-of-line) values.
The old-style copytext and concat_text functions shown above are
actually wrong in the presence of toasted values, because they don't
call pg_detoast_datum() on their inputs.
</para>
<para>
The new-style function call conventions also make it possible to
test for NULL inputs to a non-strict function, return a NULL result
(from either strict or non-strict functions), return "set" results,
and implement trigger functions and procedural-language call handlers.
For more details see <filename>src/backend/utils/fmgr/README</filename>.
</para>
</sect2>
<sect2>
<title>Composite Types in C-Language Functions</title>
<para>
Composite types do not have a fixed layout like C
@ -811,14 +1015,33 @@ CREATE FUNCTION copytext(text) RETURNS text
bool
c_overpaid(TupleTableSlot *t, /* the current instance of EMP */
int4 limit)
int32 limit)
{
bool isnull = false;
int4 salary;
salary = (int4) GetAttributeByName(t, "salary", &amp;isnull);
bool isnull;
int32 salary;
salary = DatumGetInt32(GetAttributeByName(t, "salary", &amp;isnull));
if (isnull)
return (false);
return(salary &gt; limit);
return salary &gt; limit;
}
/* In new-style coding, the above would look like this: */
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", &amp;isnull));
if (isnull)
PG_RETURN_BOOL(false);
/* Alternatively, we might prefer to do PG_RETURN_NULL() for null salary */
PG_RETURN_BOOL(salary &gt; limit);
}
</programlisting>
</para>
@ -827,20 +1050,12 @@ c_overpaid(TupleTableSlot *t, /* the current instance of EMP */
<function>GetAttributeByName</function> is the
<productname>Postgres</productname> system function that
returns attributes out of the current instance. It has
three arguments: the argument of type TUPLE passed into
three arguments: the argument of type TupleTableSlot* passed into
the function, the name of the desired attribute, and a
return parameter that describes whether the attribute
is null. <function>GetAttributeByName</function> will
align data properly so you can cast its return value to
the desired type. For example, if you have an attribute
name which is of the type name, the <function>GetAttributeByName</function>
call would look like:
<programlisting>
char *str;
...
str = (char *) GetAttributeByName(t, "name", &amp;isnull)
</programlisting>
return parameter that tells whether the attribute
is null. <function>GetAttributeByName</function> returns a Datum
value that you can convert to the proper datatype by using the
appropriate DatumGetXXX() macro.
</para>
<para>