Documentation updates to reflect TOAST and new-style fmgr.
This commit is contained in:
parent
481487b964
commit
0813fcbc08
@ -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>
|
||||
|
@ -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>+/- > 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
|
||||
|
@ -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>
|
||||
|
@ -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->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->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>
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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->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 <string.h>
|
||||
@ -706,13 +744,23 @@ memmove(destination->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 <string.h>
|
||||
#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", &isnull);
|
||||
bool isnull;
|
||||
int32 salary;
|
||||
|
||||
salary = DatumGetInt32(GetAttributeByName(t, "salary", &isnull));
|
||||
if (isnull)
|
||||
return (false);
|
||||
return(salary > limit);
|
||||
return salary > 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", &isnull));
|
||||
if (isnull)
|
||||
PG_RETURN_BOOL(false);
|
||||
/* Alternatively, we might prefer to do PG_RETURN_NULL() for null salary */
|
||||
|
||||
PG_RETURN_BOOL(salary > 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", &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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user