Commit 0813fcbc authored by Tom Lane's avatar Tom Lane

Documentation updates to reflect TOAST and new-style fmgr.

parent 481487b9
...@@ -130,10 +130,12 @@ UPDATE sal_emp SET pay_by_quarter[1:2] = '{27000,27000}' ...@@ -130,10 +130,12 @@ UPDATE sal_emp SET pay_by_quarter[1:2] = '{27000,27000}'
</Para> </Para>
<Para> <Para>
It is not currently possible to resize an array value except by An array can be enlarged by assigning to an element adjacent to
complete replacement; for example, we couldn't change a four- those already present, or by assigning to a slice that is adjacent
element array value to a five-element value with a single to or overlaps the data already present. Currently, this is only
assignment to array[5]. 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>
<Para> <Para>
......
<!-- <!--
$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"> <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 ...@@ -42,7 +42,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.33 2000/08/23 05:59:01 th
<thead> <thead>
<row> <row>
<entry><productname>Postgres</productname> Type</entry> <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> <entry>Description</entry>
</row> </row>
</thead> </thead>
...@@ -80,7 +80,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.33 2000/08/23 05:59:01 th ...@@ -80,7 +80,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.33 2000/08/23 05:59:01 th
<row> <row>
<entry>decimal</entry> <entry>decimal</entry>
<entry>decimal(p,s)</entry> <entry>decimal(p,s)</entry>
<entry>exact numeric for p <= 9, s = 0</entry> <entry>exact numeric with selectable precision</entry>
</row> </row>
<row> <row>
<entry>float4</entry> <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 ...@@ -135,7 +135,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.33 2000/08/23 05:59:01 th
<row> <row>
<entry>numeric</entry> <entry>numeric</entry>
<entry>numeric(p,s)</entry> <entry>numeric(p,s)</entry>
<entry>exact numeric for p == 9, s = 0</entry> <entry>exact numeric with selectable precision</entry>
</row> </row>
<row> <row>
<entry>path</entry> <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 ...@@ -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></entry>
<entry>unique id for indexing and cross-reference</entry> <entry>unique id for indexing and cross-reference</entry>
</row> </row>
<row>
<entry>text</entry>
<entry></entry>
<entry>variable-length character string</entry>
</row>
<row> <row>
<entry>time</entry> <entry>time</entry>
<entry>time [ without time zone ]</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 ...@@ -234,7 +239,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.33 2000/08/23 05:59:01 th
<para> <para>
<productname>Postgres</productname> has features at the forefront of <productname>Postgres</productname> has features at the forefront of
<acronym>ORDBMS</acronym> development. In addition to <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. of <acronym>SQL92</acronym> are also supported.
Although we strive for <acronym>SQL92</acronym> compliance, Although we strive for <acronym>SQL92</acronym> compliance,
there are some aspects of the standard 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 ...@@ -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> <title>Numeric Types</title>
<para> <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. floating point numbers and fixed-precision decimals.
</para> </para>
...@@ -297,7 +303,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.33 2000/08/23 05:59:01 th ...@@ -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>decimal</entry>
<entry>variable</entry> <entry>variable</entry>
<entry>User-specified precision</entry> <entry>User-specified precision</entry>
<entry>~8000 digits</entry> <entry>no limit</entry>
</row> </row>
<row> <row>
<entry>float4</entry> <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 ...@@ -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>int8</entry>
<entry>8 bytes</entry> <entry>8 bytes</entry>
<entry>Very large range fixed-precision</entry> <entry>Very large range fixed-precision</entry>
<entry>+/- &gt; 18 decimal places</entry> <entry>~18 decimal places</entry>
</row> </row>
<row> <row>
<entry>numeric</entry> <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 ...@@ -354,7 +360,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.33 2000/08/23 05:59:01 th
<para> <para>
The <type>int8</type> type may not be available on all platforms since 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> </para>
<sect2> <sect2>
...@@ -483,7 +489,7 @@ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (<replaceabl ...@@ -483,7 +489,7 @@ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (<replaceabl
</thead> </thead>
<tbody> <tbody>
<row> <row>
<entry>char</entry> <entry>"char"</entry>
<entry>1 byte</entry> <entry>1 byte</entry>
<entry><acronym>SQL92</acronym>-compatible</entry> <entry><acronym>SQL92</acronym>-compatible</entry>
<entry>Single character</entry> <entry>Single character</entry>
...@@ -502,7 +508,7 @@ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (<replaceabl ...@@ -502,7 +508,7 @@ CREATE TABLE <replaceable class="parameter">tablename</replaceable> (<replaceabl
</row> </row>
<row> <row>
<entry>varchar(n)</entry> <entry>varchar(n)</entry>
<entry>(4+n) bytes</entry> <entry>(4+x) bytes</entry>
<entry><acronym>SQL92</acronym>-compatible</entry> <entry><acronym>SQL92</acronym>-compatible</entry>
<entry>Variable-length with limit</entry> <entry>Variable-length with limit</entry>
</row> </row>
...@@ -1359,10 +1365,10 @@ January 8 04:05:06 1999 PST ...@@ -1359,10 +1365,10 @@ January 8 04:05:06 1999 PST
<para> <para>
<productname>Postgres</productname> supports <type>bool</type> as <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'. <type>bool</type> can have one of only two states: 'true' or 'false'.
A third state, 'unknown', is not 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 <acronym>NULL</acronym> is an
effective substitute. <type>bool</type> can be used in any boolean expression, effective substitute. <type>bool</type> can be used in any boolean expression,
and boolean expressions and boolean expressions
......
<!-- <!--
$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 Postgres documentation
--> -->
...@@ -31,7 +31,7 @@ CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceab ...@@ -31,7 +31,7 @@ CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceab
CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceable class="parameter">ftype</replaceable> [, ...] ] ) CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceable class="parameter">ftype</replaceable> [, ...] ] )
RETURNS <replaceable class="parameter">rtype</replaceable> RETURNS <replaceable class="parameter">rtype</replaceable>
AS <replaceable class="parameter">obj_file</replaceable> , <replaceable class="parameter">link_symbol</replaceable> AS <replaceable class="parameter">obj_file</replaceable> , <replaceable class="parameter">link_symbol</replaceable>
LANGUAGE 'C' LANGUAGE 'langname'
[ WITH ( <replaceable class="parameter">attribute</replaceable> [, ...] ) ] [ WITH ( <replaceable class="parameter">attribute</replaceable> [, ...] ) ]
</synopsis> </synopsis>
...@@ -57,11 +57,11 @@ CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceab ...@@ -57,11 +57,11 @@ CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceab
<term><replaceable class="parameter">ftype</replaceable></term> <term><replaceable class="parameter">ftype</replaceable></term>
<listitem> <listitem>
<para> <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 The input types may be base or complex types, or
<firstterm>opaque</firstterm>. <firstterm>opaque</firstterm>.
<literal>opaque</literal> indicates that the function <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> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -84,14 +84,7 @@ CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceab ...@@ -84,14 +84,7 @@ CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceab
<listitem> <listitem>
<para> <para>
An optional piece of information about the function, used for An optional piece of information about the function, used for
optimization. The only attribute currently supported is optimization. See below for details.
<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.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -115,8 +108,8 @@ CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceab ...@@ -115,8 +108,8 @@ CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceab
function. The string <replaceable function. The string <replaceable
class="parameter">obj_file</replaceable> is the name of the file class="parameter">obj_file</replaceable> is the name of the file
containing the dynamically loadable object, and <replaceable containing the dynamically loadable object, and <replaceable
class="parameter">link_symbol</replaceable>, is the object's link class="parameter">link_symbol</replaceable> is the object's link
symbol which is the same as the name of the function in the C symbol, that is the name of the function in the C
language source code. language source code.
</para> </para>
</listitem> </listitem>
...@@ -125,8 +118,9 @@ CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceab ...@@ -125,8 +118,9 @@ CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceab
<term><replaceable class="parameter">langname</replaceable></term> <term><replaceable class="parameter">langname</replaceable></term>
<listitem> <listitem>
<para> <para>
may be '<literal>C</literal>', '<literal>sql</literal>', may be '<literal>sql</literal>',
'<literal>internal</literal>' '<literal>C</literal>', '<literal>newC</literal>',
'<literal>internal</literal>', '<literal>newinternal</literal>',
or '<replaceable class="parameter">plname</replaceable>', or '<replaceable class="parameter">plname</replaceable>',
where '<replaceable class="parameter">plname</replaceable>' where '<replaceable class="parameter">plname</replaceable>'
is the name of a created procedural language. See is the name of a created procedural language. See
...@@ -175,11 +169,57 @@ CREATE ...@@ -175,11 +169,57 @@ CREATE
<command>CREATE FUNCTION</command> allows a <command>CREATE FUNCTION</command> allows a
<productname>Postgres</productname> user <productname>Postgres</productname> user
to register a function 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. owner of the function.
</para> </para>
<refsect2 id="R2-SQL-CREATEFUNCTION-3"> <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> <refsect2info>
<date>2000-03-25</date> <date>2000-03-25</date>
</refsect2info> </refsect2info>
...@@ -200,26 +240,25 @@ CREATE ...@@ -200,26 +240,25 @@ CREATE
to remove user-defined functions. to remove user-defined functions.
</para> </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> <para>
The full <acronym>SQL92</acronym> type syntax is allowed for The full <acronym>SQL92</acronym> type syntax is allowed for
input arguments and return value. However, some details of the input arguments and return value. However, some details of the
type specification (e.g. the precision field for type specification (e.g. the precision field for
<type>numeric</type> types) are the responsibility of the <type>numeric</type> types) are the responsibility of the
underlying function implementation and are silently swallowed 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. enforced) by the <command>CREATE FUNCTION</command> command.
</para> </para>
<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 functions cannot have the same C name without causing
errors at link time. To get around that, give them different C names 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 (for example, use the argument types as part of the C names), then
...@@ -229,18 +268,14 @@ CREATE ...@@ -229,18 +268,14 @@ CREATE
</para> </para>
<para> <para>
When overloading SQL functions with C-language functions, give Similarly, when overloading SQL function names with multiple C-language
each C-language instance of the function a distinct name, and use 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 the alternative form of the <command>AS</command> clause in the
<command>CREATE FUNCTION</command> syntax to ensure that <command>CREATE FUNCTION</command> syntax to select the appropriate
overloaded SQL functions names are resolved to the correct C-language implementation of each overloaded SQL function.
dynamically linked objects.
</para> </para>
<para>
A C function cannot return a set of values.
</para>
</refsect2> </refsect2>
</refsect1> </refsect1>
...@@ -291,7 +326,7 @@ CREATE TABLE product ( ...@@ -291,7 +326,7 @@ CREATE TABLE product (
function is implemented by a dynamically loaded object that was function is implemented by a dynamically loaded object that was
compiled from C source. For <productname>Postgres</productname> to compiled from C source. For <productname>Postgres</productname> to
find a type conversion function automatically, the sql function has 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 unavoidable. The function name is overloaded by using the second
form of the <command>AS</command> clause in the SQL definition: form of the <command>AS</command> clause in the SQL definition:
</para> </para>
...@@ -324,7 +359,7 @@ Point * complex_to_point (Complex *z) ...@@ -324,7 +359,7 @@ Point * complex_to_point (Complex *z)
Compatibility Compatibility
</title> </title>
<refsect2 id="R2-SQL-CREATEFUNCTION-4"> <refsect2 id="R2-SQL-CREATEFUNCTION-5">
<refsect2info> <refsect2info>
<date>2000-03-25</date> <date>2000-03-25</date>
</refsect2info> </refsect2info>
...@@ -338,7 +373,7 @@ Point * complex_to_point (Complex *z) ...@@ -338,7 +373,7 @@ Point * complex_to_point (Complex *z)
</para> </para>
</refsect2> </refsect2>
<refsect2 id="R2-SQL-CREATEFUNCTION-5"> <refsect2 id="R2-SQL-CREATEFUNCTION-6">
<refsect2info> <refsect2info>
<date>2000-03-25</date> <date>2000-03-25</date>
</refsect2info> </refsect2info>
......
<!-- <!--
$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 Postgres documentation
--> -->
...@@ -48,8 +48,7 @@ CREATE [ TRUSTED ] PROCEDURAL LANGUAGE '<replaceable class="parameter">langname< ...@@ -48,8 +48,7 @@ CREATE [ TRUSTED ] PROCEDURAL LANGUAGE '<replaceable class="parameter">langname<
this keyword is omitted when registering the language, this keyword is omitted when registering the language,
only users with the <productname>Postgres</productname> only users with the <productname>Postgres</productname>
superuser privilege can use superuser privilege can use
this language to create new functions this language to create new functions.
(like the 'C' language).
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -222,6 +221,11 @@ ERROR: PL handler function <replaceable class="parameter">funcname</replaceable ...@@ -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 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 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. 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>
<para> <para>
...@@ -262,20 +266,21 @@ ERROR: PL handler function <replaceable class="parameter">funcname</replaceable ...@@ -262,20 +266,21 @@ ERROR: PL handler function <replaceable class="parameter">funcname</replaceable
lanplcallfoid | oid | lanplcallfoid | oid |
lancompiler | text | lancompiler | text |
lanname | lanispl | lanpltrusted | lanplcallfoid | lancompiler lanname | lanispl | lanpltrusted | lanplcallfoid | lancompiler
----------+---------+--------------+---------------+------------- -------------+---------+--------------+---------------+-------------
internal | f | f | 0 | n/a internal | f | f | 0 | n/a
C | f | f | 0 | /bin/cc newinternal | f | f | 0 | n/a
sql | f | f | 0 | postgres C | f | f | 0 | /bin/cc
newC | f | f | 0 | /bin/cc
sql | f | f | 0 | postgres
</computeroutput> </computeroutput>
</programlisting> </programlisting>
</para> </para>
<para> <para>
Since the call handler for a procedural language must be The call handler for a procedural language must normally be written
registered with <productname>Postgres</productname> in the 'C' language, in C and registered as 'newinternal' or 'newC' language, depending
it inherits on whether it is linked into the backend or dynamically loaded.
all the capabilities and restrictions of 'C' functions.
</para> </para>
<para> <para>
......
<!-- <!--
$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 Postgres documentation
--> -->
...@@ -248,11 +248,9 @@ ERROR: DEFAULT: type mismatched ...@@ -248,11 +248,9 @@ ERROR: DEFAULT: type mismatched
<para> <para>
The new table is created as a heap with no initial data. The new table is created as a heap with no initial data.
A table can have no more than 1600 columns (realistically, A table can have no more than 1600 columns (in practice, the
this is limited by the fact that tuple sizes must effective limit is lower because of tuple-length constraints).
be less than 8192 bytes), but this limit may be configured A table cannot have the same name as a system catalog table.
lower at some sites. A table cannot have the same name as
a system catalog table.
</para> </para>
</refsect1> </refsect1>
......
<!-- <!--
$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 Postgres documentation
--> -->
...@@ -24,11 +24,16 @@ Postgres documentation ...@@ -24,11 +24,16 @@ Postgres documentation
</refsynopsisdivinfo> </refsynopsisdivinfo>
<synopsis> <synopsis>
CREATE TYPE <replaceable class="parameter">typename</replaceable> ( INPUT = <replaceable class="parameter">input_function</replaceable>, OUTPUT = <replaceable class="parameter">output_function</replaceable> 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>" ] [ , DEFAULT = "<replaceable class="parameter">default</replaceable>" ]
[ , ELEMENT = <replaceable class="parameter">element</replaceable> ] [ , DELIMITER = <replaceable class="parameter">delimiter</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> ] [ , 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> </synopsis>
<refsect2 id="R2-SQL-CREATETYPE-1"> <refsect2 id="R2-SQL-CREATETYPE-1">
...@@ -64,7 +69,7 @@ CREATE TYPE <replaceable class="parameter">typename</replaceable> ( INPUT = <rep ...@@ -64,7 +69,7 @@ CREATE TYPE <replaceable class="parameter">typename</replaceable> ( INPUT = <rep
<term><replaceable class="parameter">externallength</replaceable></term> <term><replaceable class="parameter">externallength</replaceable></term>
<listitem> <listitem>
<para> <para>
A literal value, which specifies the external length of A literal value, which specifies the external (displayed) length of
the new type. the new type.
</para> </para>
</listitem> </listitem>
...@@ -86,7 +91,8 @@ CREATE TYPE <replaceable class="parameter">typename</replaceable> ( INPUT = <rep ...@@ -86,7 +91,8 @@ CREATE TYPE <replaceable class="parameter">typename</replaceable> ( INPUT = <rep
<term><replaceable class="parameter">output_function</replaceable></term> <term><replaceable class="parameter">output_function</replaceable></term>
<listitem> <listitem>
<para> <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 converts data from its internal form to a form suitable
for display. for display.
</para> </para>
...@@ -107,7 +113,7 @@ CREATE TYPE <replaceable class="parameter">typename</replaceable> ( INPUT = <rep ...@@ -107,7 +113,7 @@ CREATE TYPE <replaceable class="parameter">typename</replaceable> ( INPUT = <rep
<term><replaceable class="parameter">delimiter</replaceable></term> <term><replaceable class="parameter">delimiter</replaceable></term>
<listitem> <listitem>
<para> <para>
The delimiter character for the array. The delimiter character for the array elements.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -116,8 +122,8 @@ CREATE TYPE <replaceable class="parameter">typename</replaceable> ( INPUT = <rep ...@@ -116,8 +122,8 @@ CREATE TYPE <replaceable class="parameter">typename</replaceable> ( INPUT = <rep
<term><replaceable class="parameter">default</replaceable></term> <term><replaceable class="parameter">default</replaceable></term>
<listitem> <listitem>
<para> <para>
The default text to be displayed to indicate "data The default value for the datatype. Usually this is omitted,
not present" so that the default is NULL.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -141,6 +147,29 @@ CREATE TYPE <replaceable class="parameter">typename</replaceable> ( INPUT = <rep ...@@ -141,6 +147,29 @@ CREATE TYPE <replaceable class="parameter">typename</replaceable> ( INPUT = <rep
</para> </para>
</listitem> </listitem>
</varlistentry> </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> </variablelist>
</para> </para>
</refsect2> </refsect2>
...@@ -267,6 +296,24 @@ CREATE ...@@ -267,6 +296,24 @@ CREATE
more than four bytes. more than four bytes.
</para> </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> <para>
For new base types, a user can define operators, functions For new base types, a user can define operators, functions
and aggregates using the appropriate facilities described and aggregates using the appropriate facilities described
...@@ -283,17 +330,6 @@ CREATE ...@@ -283,17 +330,6 @@ CREATE
</para> </para>
</refsect2> </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>
<refsect1> <refsect1>
......
<!-- <!--
$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"> <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 ...@@ -64,10 +64,9 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.18 2000/08/21 17:22:36 tgl E
<para> <para>
The body of a SQL function following AS The body of a SQL function following AS
should be a list of queries separated by whitespace characters and should be a list of queries separated by semicolons and
bracketed within quotation marks. Note that quotation marks used in bracketed within single-quote marks. Note that quote marks used in
the queries must be escaped, by preceding them with two the queries must be escaped, by preceding them with a backslash.
backslashes.
</para> </para>
<para> <para>
...@@ -100,7 +99,7 @@ LANGUAGE 'sql'; ...@@ -100,7 +99,7 @@ LANGUAGE 'sql';
follows: follows:
<programlisting> <programlisting>
select (x = TP1( 17,100.0)); select TP1( 17,100.0);
</programlisting> </programlisting>
</para> </para>
...@@ -109,7 +108,7 @@ select (x = TP1( 17,100.0)); ...@@ -109,7 +108,7 @@ select (x = TP1( 17,100.0));
EMP, and retrieves multiple results: EMP, and retrieves multiple results:
<programlisting> <programlisting>
select function hobbies (EMP) returns set of HOBBIES create function hobbies (EMP) returns setof HOBBIES
as 'select HOBBIES.* from HOBBIES as 'select HOBBIES.* from HOBBIES
where $1.name = HOBBIES.person' where $1.name = HOBBIES.person'
language 'sql'; language 'sql';
...@@ -140,10 +139,9 @@ SELECT one() AS answer; ...@@ -140,10 +139,9 @@ SELECT one() AS answer;
</programlisting> </programlisting>
</para> </para>
<para> <para>
Notice that we defined a target list for the function Notice that we defined a column name for the function's result
(with the name RESULT), but the target list of the (with the name RESULT), but this column name is not visible
query that invoked the function overrode the function's outside the function. Hence, the result is labelled answer
target list. Hence, the result is labelled answer
instead of one. instead of one.
</para> </para>
<para> <para>
...@@ -204,7 +202,7 @@ WHERE EMP.cubicle ~= '(2,1)'::point; ...@@ -204,7 +202,7 @@ WHERE EMP.cubicle ~= '(2,1)'::point;
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
notation attribute(class) and class.attribute interchangably: notations attribute(class) and class.attribute interchangably:
<programlisting> <programlisting>
-- --
...@@ -252,17 +250,16 @@ LANGUAGE 'sql'; ...@@ -252,17 +250,16 @@ LANGUAGE 'sql';
<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 CREATE
TABLE statement (or when you execute a .* query). TABLE statement that defined the composite type.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
You must typecast the expressions (using ::) very carefully You must typecast the expressions (using ::) to match the
or you will see the following error: composite type's definition, or you will get errors like this:
<programlisting> <programlisting>
<computeroutput> <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> </computeroutput>
</programlisting> </programlisting>
</para> </para>
...@@ -366,6 +363,16 @@ SELECT clean_EMP(); ...@@ -366,6 +363,16 @@ SELECT clean_EMP();
but a user could use <command>CREATE FUNCTION</command> but a user could use <command>CREATE FUNCTION</command>
to create additional alias names for an internal function. to create additional alias names for an internal function.
</para> </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>
<sect1> <sect1>
...@@ -373,50 +380,59 @@ SELECT clean_EMP(); ...@@ -373,50 +380,59 @@ SELECT clean_EMP();
<para> <para>
Functions written in C can be compiled into dynamically loadable Functions written in C can be compiled into dynamically loadable
objects, and used to implement user-defined SQL functions. The objects (also called shared libraries), and used to implement user-defined
first time the user defined function is called inside the backend, SQL functions. The first time a user-defined function in a particular
the dynamic loader loads the function's object code into memory, loadable object file is called in a backend session,
and links the function with the running the dynamic loader loads that object file into memory so that the
<productname>Postgres</productname> executable. The SQL syntax function can be called. The <command>CREATE FUNCTION</command>
for <command>CREATE FUNCTION</command> for a user-defined function must therefore specify two pieces of
links the SQL function information for the function: the name of the loadable
to the C source function in one of two ways. If the SQL function object file, and the C name (link symbol) of the specific function to call
has the same name as the C source function the first form of the within that object file. If the C name is not explicitly specified then
statement is used. The string argument in the AS clause is the it is assumed to be the same as the SQL function name.
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.
<note> <note>
<para> <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 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> </para>
</note> </note>
</para> </para>
<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 clause) should be the <emphasis>full path</emphasis> of the object
code file for the function, bracketed by quotation marks. If a 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 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 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 the command <command>nm</command> will print all of the link
symbols in a dynamically loadable object. 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 <note>
FUNCTION command. See below for additional information.) <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> </para>
<sect2> <sect2>
<title>C Language Functions on Base Types</title> <title>Base Types in C-Language Functions</title>
<para> <para>
The following table gives the C type required for parameters in the C The following table gives the C type required for parameters in the C
...@@ -484,7 +500,7 @@ SELECT clean_EMP(); ...@@ -484,7 +500,7 @@ SELECT clean_EMP();
</row> </row>
<row> <row>
<entry>int2</entry> <entry>int2</entry>
<entry>int2</entry> <entry>int2 or int16</entry>
<entry>include/postgres.h</entry> <entry>include/postgres.h</entry>
</row> </row>
<row> <row>
...@@ -494,7 +510,7 @@ SELECT clean_EMP(); ...@@ -494,7 +510,7 @@ SELECT clean_EMP();
</row> </row>
<row> <row>
<entry>int4</entry> <entry>int4</entry>
<entry>int4</entry> <entry>int4 or int32</entry>
<entry>include/postgres.h</entry> <entry>include/postgres.h</entry>
</row> </row>
<row> <row>
...@@ -654,6 +670,12 @@ typedef struct ...@@ -654,6 +670,12 @@ typedef struct
<para> <para>
Only pointers to such types can be used when passing Only pointers to such types can be used when passing
them in and out of <productname>Postgres</productname> functions. 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 Finally, all variable-length types must also be passed
by reference. All variable-length types must begin by reference. All variable-length types must begin
with a length field of exactly 4 bytes, and all data to with a length field of exactly 4 bytes, and all data to
...@@ -694,8 +716,24 @@ memmove(destination-&gt;data, buffer, 40); ...@@ -694,8 +716,24 @@ memmove(destination-&gt;data, buffer, 40);
<para> <para>
Now that we've gone over all of the possible structures Now that we've gone over all of the possible structures
for base types, we can show some examples of real functions. for base types, we can show some examples of real functions.
Suppose <filename>funcs.c</filename> look like: </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> <programlisting>
#include &lt;string.h&gt; #include &lt;string.h&gt;
...@@ -706,13 +744,23 @@ memmove(destination-&gt;data, buffer, 40); ...@@ -706,13 +744,23 @@ memmove(destination-&gt;data, buffer, 40);
int int
add_one(int arg) add_one(int arg)
{ {
return(arg + 1); return arg + 1;
} }
/* By Reference, Fixed Length */ /* By Reference, Fixed Length */
float8 *
add_one_float8(float8 *arg)
{
float8 *result = (float8 *) palloc(sizeof(float8));
*result = *arg + 1.0;
return result;
}
Point * Point *
makepoint(Point *pointx, Point *pointy ) makepoint(Point *pointx, Point *pointy)
{ {
Point *new_point = (Point *) palloc(sizeof(Point)); Point *new_point = (Point *) palloc(sizeof(Point));
...@@ -731,15 +779,14 @@ copytext(text *t) ...@@ -731,15 +779,14 @@ copytext(text *t)
* VARSIZE is the total size of the struct in bytes. * VARSIZE is the total size of the struct in bytes.
*/ */
text *new_t = (text *) palloc(VARSIZE(t)); text *new_t = (text *) palloc(VARSIZE(t));
memset(new_t, 0, VARSIZE(t)); VARATT_SIZEP(new_t) = VARSIZE(t);
VARSIZE(new_t) = VARSIZE(t);
/* /*
* VARDATA is a pointer to the data region of the struct. * VARDATA is a pointer to the data region of the struct.
*/ */
memcpy((void *) VARDATA(new_t), /* destination */ memcpy((void *) VARDATA(new_t), /* destination */
(void *) VARDATA(t), /* source */ (void *) VARDATA(t), /* source */
VARSIZE(t)-VARHDRSZ); /* how many bytes */ VARSIZE(t)-VARHDRSZ); /* how many bytes */
return(new_t); return new_t;
} }
text * text *
...@@ -749,40 +796,197 @@ concat_text(text *arg1, text *arg2) ...@@ -749,40 +796,197 @@ concat_text(text *arg1, text *arg2)
text *new_text = (text *) palloc(new_text_size); text *new_text = (text *) palloc(new_text_size);
memset((void *) new_text, 0, 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); strncpy(VARDATA(new_text), VARDATA(arg1), VARSIZE(arg1)-VARHDRSZ);
strncat(VARDATA(new_text), VARDATA(arg2), VARSIZE(arg2)-VARHDRSZ); strncat(VARDATA(new_text), VARDATA(arg2), VARSIZE(arg2)-VARHDRSZ);
return (new_text); return new_text;
} }
</programlisting> </programlisting>
</para> </para>
<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> <programlisting>
CREATE FUNCTION add_one(int4) RETURNS int4 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);
CREATE FUNCTION makepoint(point, point) RETURNS point -- note overloading of SQL function name add_one()
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs.so' LANGUAGE 'c'; CREATE FUNCTION add_one(float8) RETURNS float8
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs.so',
'add_one_float8'
LANGUAGE 'c' WITH (isStrict);
CREATE FUNCTION concat_text(text, text) RETURNS text CREATE FUNCTION makepoint(point, point) RETURNS point
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 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> </programlisting>
</para> </para>
<para> <para>
On other systems, we might have to make the filename Here <replaceable>PGROOT</replaceable> stands for the full path to
end in .sl (to indicate that it's a shared library). 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> </para>
</sect2> </sect2>
<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> <para>
Composite types do not have a fixed layout like C Composite types do not have a fixed layout like C
...@@ -811,14 +1015,33 @@ CREATE FUNCTION copytext(text) RETURNS text ...@@ -811,14 +1015,33 @@ CREATE FUNCTION copytext(text) RETURNS text
bool bool
c_overpaid(TupleTableSlot *t, /* the current instance of EMP */ c_overpaid(TupleTableSlot *t, /* the current instance of EMP */
int4 limit) int32 limit)
{ {
bool isnull = false; bool isnull;
int4 salary; int32 salary;
salary = (int4) GetAttributeByName(t, "salary", &amp;isnull);
salary = DatumGetInt32(GetAttributeByName(t, "salary", &amp;isnull));
if (isnull) if (isnull)
return (false); 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> </programlisting>
</para> </para>
...@@ -827,20 +1050,12 @@ c_overpaid(TupleTableSlot *t, /* the current instance of EMP */ ...@@ -827,20 +1050,12 @@ c_overpaid(TupleTableSlot *t, /* the current instance of EMP */
<function>GetAttributeByName</function> is the <function>GetAttributeByName</function> is the
<productname>Postgres</productname> system function that <productname>Postgres</productname> system function that
returns attributes out of the current instance. It has 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 the function, the name of the desired attribute, and a
return parameter that describes whether the attribute return parameter that tells whether the attribute
is null. <function>GetAttributeByName</function> will is null. <function>GetAttributeByName</function> returns a Datum
align data properly so you can cast its return value to value that you can convert to the proper datatype by using the
the desired type. For example, if you have an attribute appropriate DatumGetXXX() macro.
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>
</para> </para>
<para> <para>
......
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