1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-27 12:41:57 +03:00

Add a bunch of pseudo-types to replace the behavior formerly associated

with OPAQUE, as per recent pghackers discussion.  I still want to do some
more work on the 'cstring' pseudo-type, but I'm going to commit the bulk
of the changes now before the tree starts shifting under me ...
This commit is contained in:
Tom Lane
2002-08-22 00:01:51 +00:00
parent 606c9b9d4f
commit b663f3443b
126 changed files with 2005 additions and 1205 deletions

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.99 2002/08/19 19:33:33 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.100 2002/08/22 00:01:40 tgl Exp $
-->
<chapter id="datatype">
@ -3099,6 +3099,146 @@ SELECT SUBSTRING(b FROM 1 FOR 2) FROM test;
</sect1>
<sect1 id="datatype-pseudo">
<title>Pseudo-Types</title>
<indexterm zone="datatype-pseudo">
<primary>record</primary>
</indexterm>
<indexterm zone="datatype-pseudo">
<primary>any</primary>
</indexterm>
<indexterm zone="datatype-pseudo">
<primary>anyarray</primary>
</indexterm>
<indexterm zone="datatype-pseudo">
<primary>void</primary>
</indexterm>
<indexterm zone="datatype-pseudo">
<primary>trigger</primary>
</indexterm>
<indexterm zone="datatype-pseudo">
<primary>language_handler</primary>
</indexterm>
<indexterm zone="datatype-pseudo">
<primary>cstring</primary>
</indexterm>
<indexterm zone="datatype-pseudo">
<primary>internal</primary>
</indexterm>
<indexterm zone="datatype-pseudo">
<primary>opaque</primary>
</indexterm>
<para>
The <productname>PostgreSQL</productname> type system contains a number
of special-purpose entries that are collectively called
<firstterm>pseudo-types</>. A pseudo-type cannot be used as a column
datatype, but it can be used to declare a function's argument or result
type. Each of the available pseudo-types is useful in situations where
a function's behavior does not correspond to simply taking or returning
a value of a specific SQL datatype.
</para>
<para>
<table tocentry="1">
<title>Pseudo-Types</title>
<tgroup cols="2">
<thead>
<row>
<entry>Type name</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><type>record</></entry>
<entry>Identifies a function returning an unspecified tuple type</entry>
</row>
<row>
<entry><type>any</></entry>
<entry>Indicates that a function accepts any input datatype whatever</entry>
</row>
<row>
<entry><type>anyarray</></entry>
<entry>Indicates that a function accepts any array datatype</entry>
</row>
<row>
<entry><type>void</></entry>
<entry>Indicates that a function returns no value</entry>
</row>
<row>
<entry><type>trigger</></entry>
<entry>A trigger function is declared to return <type>trigger</></entry>
</row>
<row>
<entry><type>language_handler</></entry>
<entry>A procedural language call handler is declared to return <type>language_handler</></entry>
</row>
<row>
<entry><type>cstring</></entry>
<entry>Indicates a function takes or returns a null-terminated C string</entry>
</row>
<row>
<entry><type>internal</></entry>
<entry>Indicates that a function accepts or returns a server-internal
data type</entry>
</row>
<row>
<entry><type>opaque</></entry>
<entry>An obsolete type name that formerly served all the above purposes</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
Functions coded in C (whether built-in or dynamically loaded) may be
declared to take or return any of these pseudo datatypes. It is up to
the function author to ensure that the function will behave safely
when a pseudo-type is used as an argument type.
</para>
<para>
Functions coded in procedural languages may use pseudo-types only as
allowed by their implementation languages. At present the procedural
languages all forbid use of a pseudo-type as argument type, and allow
only <type>void</> as a result type (plus <type>trigger</> when the
function is used as a trigger).
</para>
<para>
The <type>internal</> pseudo-type is used to declare functions that are
meant only to be called internally by the database system, and not by
direct invocation in a SQL query. If a function has at least one
<type>internal</>-type argument then it cannot be called from SQL.
To preserve the type safety of this restriction it is important to
follow this coding rule: do not create any function that is declared
to return <type>internal</> unless it has at least one <type>internal</>
argument.
</para>
</sect1>
&array;
</chapter>

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/indexcost.sgml,v 2.11 2002/03/22 19:20:10 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/indexcost.sgml,v 2.12 2002/08/22 00:01:40 tgl Exp $
-->
<chapter id="indexcost">
@ -261,15 +261,8 @@ amcostestimate (Query *root,
<para>
By convention, the <literal>pg_proc</literal> entry for an
<literal>amcostestimate</literal> function should show
<programlisting>
prorettype = 0
pronargs = 8
proargtypes = 0 0 0 0 0 0 0 0
</programlisting>
We use zero ("opaque") for all the arguments since none of them have types
that are known in pg_type.
eight arguments all declared as <type>internal</> (since none of them have
types that are known to SQL), and the return type is <type>void</>.
</para>
</chapter>

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/plpgsql.sgml,v 1.2 2002/08/20 05:28:23 momjian Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/plpgsql.sgml,v 1.3 2002/08/22 00:01:40 tgl Exp $
-->
<chapter id="plpgsql">
@ -1865,7 +1865,7 @@ RAISE EXCEPTION ''Inexistent ID --> %'',user_id;
<application>PL/pgSQL</application> can be used to define trigger
procedures. A trigger procedure is created with the <command>CREATE
FUNCTION</command> command as a function with no arguments and a return
type of <type>OPAQUE</type>. Note that the function must be declared
type of <type>TRIGGER</type>. Note that the function must be declared
with no arguments even if it expects to receive arguments specified
in <command>CREATE TRIGGER</> --- trigger arguments are passed via
<varname>TG_ARGV</>, as described below.
@ -2022,7 +2022,7 @@ CREATE TABLE emp (
last_user text
);
CREATE FUNCTION emp_stamp () RETURNS OPAQUE AS '
CREATE FUNCTION emp_stamp () RETURNS TRIGGER AS '
BEGIN
-- Check that empname and salary are given
IF NEW.empname ISNULL THEN

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.20 2002/03/22 19:20:21 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.21 2002/08/22 00:01:40 tgl Exp $
-->
<chapter id="pltcl">
@ -472,7 +472,7 @@ SELECT 'doesn''t' AS ret
Trigger procedures can be written in PL/Tcl. As is customary in
<productname>PostgreSQL</productname>, a procedure that's to be called
as a trigger must be declared as a function with no arguments
and a return type of <literal>opaque</>.
and a return type of <literal>trigger</>.
</para>
<para>
The information from the trigger manager is passed to the procedure body
@ -597,7 +597,7 @@ SELECT 'doesn''t' AS ret
incremented on every update operation:
<programlisting>
CREATE FUNCTION trigfunc_modcount() RETURNS OPAQUE AS '
CREATE FUNCTION trigfunc_modcount() RETURNS TRIGGER AS '
switch $TG_op {
INSERT {
set NEW($1) 0

View File

@ -1,4 +1,4 @@
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/ref/create_conversion.sgml,v 1.2 2002/07/22 13:00:00 ishii Exp $ -->
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/ref/create_conversion.sgml,v 1.3 2002/08/22 00:01:40 tgl Exp $ -->
<refentry id="SQL-CREATECONVERSION">
<refmeta>
@ -108,10 +108,10 @@ CREATE [DEFAULT] CONVERSION <replaceable>conversion_name</replaceable>
conv_proc(
INTEGER, -- source encoding id
INTEGER, -- destination encoding id
OPAQUE, -- source string (null terminated C string)
OPAQUE, -- destination string (null terminated C string)
CSTRING, -- source string (null terminated C string)
CSTRING, -- destination string (null terminated C string)
INTEGER -- source string length
) returns INTEGER; -- dummy. returns nothing, actually.
) returns VOID;
</programlisting>
</para>
</listitem>

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.41 2002/07/24 19:11:07 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.42 2002/08/22 00:01:40 tgl Exp $
-->
<refentry id="SQL-CREATEFUNCTION">
@ -67,16 +67,17 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
<listitem>
<para>
The data type(s) of the function's arguments, if any. The
input types may be base or complex types,
<literal>opaque</literal>, or the same as the type of an
existing column. <literal>Opaque</literal> indicates
that the function accepts arguments of a non-SQL type such as
<type>char *</type>.
The type of a column is indicated using <replaceable
input types may be base, complex, or domain types,
or the same as the type of an existing column.
The type of a column is referenced by writing <replaceable
class="parameter">tablename</replaceable>.<replaceable
class="parameter">columnname</replaceable><literal>%TYPE</literal>;
using this can sometimes help make a function independent from
changes to the definition of a table.
Depending on the implementation language it may also be allowed
to specify <quote>pseudo-types</> such as <type>cstring</>.
Pseudo-types indicate that the actual argument type is either
incompletely specified, or outside the set of ordinary SQL datatypes.
</para>
</listitem>
</varlistentry>
@ -87,15 +88,13 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable>
<listitem>
<para>
The return data type. The return type may be specified as a
base type, complex type, <literal>setof</literal> type,
<literal>opaque</literal>, or the same as the type of an
base, complex, or domain type, or the same as the type of an
existing column.
Depending on the implementation language it may also be allowed
to specify <quote>pseudo-types</> such as <type>cstring</>.
The <literal>setof</literal>
modifier indicates that the function will return a set of
items, rather than a single item. Functions with a declared
return type of <literal>opaque</literal> do not return a value.
These cannot be called directly; trigger functions make use of
this feature.
items, rather than a single item.
</para>
</listitem>
</varlistentry>

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_language.sgml,v 1.26 2002/07/24 19:11:07 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_language.sgml,v 1.27 2002/08/22 00:01:40 tgl Exp $
PostgreSQL documentation
-->
@ -108,8 +108,8 @@ CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE <replaceable class="parameter">langna
language such as C with version 1 call convention and
registered with <productname>PostgreSQL</productname> as a
function taking no arguments and returning the
<type>opaque</type> type, a placeholder for unspecified or
undefined types.
<type>language_handler</type> type, a placeholder type that is
simply used to identify the function as a call handler.
</para>
</listitem>
</varlistentry>
@ -122,11 +122,13 @@ CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE <replaceable class="parameter">langna
<replaceable class="parameter">valfunction</replaceable> is the
name of a previously registered function that will be called
when a new function in the language is created, to validate the
new function. The validator function must take one argument of
type <type>oid</type>, which will be the OID of the
to-be-created function, and can have any return type. If no
new function.
If no
validator function is specified, then a new function will not
be checked when it is created.
The validator function must take one argument of
type <type>oid</type>, which will be the OID of the
to-be-created function, and will typically return <type>void</>.
</para>
<para>
@ -251,7 +253,7 @@ ERROR: PL handler function <replaceable class="parameter">funcname</replaceable
The following two commands executed in sequence will register a new
procedural language and the associated call handler.
<programlisting>
CREATE FUNCTION plsample_call_handler () RETURNS opaque
CREATE FUNCTION plsample_call_handler () RETURNS language_handler
AS '$libdir/plsample'
LANGUAGE C;
CREATE LANGUAGE plsample

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_opclass.sgml,v 1.1 2002/07/29 22:14:10 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_opclass.sgml,v 1.2 2002/08/22 00:01:40 tgl Exp $
PostgreSQL documentation
-->
@ -260,13 +260,13 @@ CREATE OPERATOR CLASS gist__int_ops
OPERATOR 7 @,
OPERATOR 8 ~,
OPERATOR 20 @@ (_int4, query_int),
FUNCTION 1 g_int_consistent (opaque, _int4, int4),
FUNCTION 2 g_int_union (bytea, opaque),
FUNCTION 3 g_int_compress (opaque),
FUNCTION 4 g_int_decompress (opaque),
FUNCTION 5 g_int_penalty (opaque, opaque, opaque),
FUNCTION 6 g_int_picksplit (opaque, opaque),
FUNCTION 7 g_int_same (_int4, _int4, opaque);
FUNCTION 1 g_int_consistent (internal, _int4, int4),
FUNCTION 2 g_int_union (bytea, internal),
FUNCTION 3 g_int_compress (internal),
FUNCTION 4 g_int_decompress (internal),
FUNCTION 5 g_int_penalty (internal, internal, internal),
FUNCTION 6 g_int_picksplit (internal, internal),
FUNCTION 7 g_int_same (_int4, _int4, internal);
</programlisting>
<para>

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_trigger.sgml,v 1.26 2002/05/18 15:44:47 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_trigger.sgml,v 1.27 2002/08/22 00:01:40 tgl Exp $
PostgreSQL documentation
-->
@ -66,7 +66,7 @@ CREATE TRIGGER <replaceable class="PARAMETER">name</replaceable> { BEFORE | AFTE
<listitem>
<para>
A user-supplied function that is declared as taking no arguments
and returning type <literal>opaque</>.
and returning type <literal>trigger</>.
</para>
</listitem>
</varlistentry>
@ -167,6 +167,14 @@ CREATE TRIGGER
<literal>TRIGGER</literal> privilege on the table.
</para>
<para>
In <productname>PostgreSQL</productname> versions before 7.3, it was
necessary to declare trigger functions as returning the placeholder
type <type>opaque</>, rather than <type>trigger</>. This is still
supported, but is deprecated because it is obscure and causes loss of
type safety.
</para>
<para>
As of the current release, <literal>STATEMENT</literal> triggers are not implemented.
</para>

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_type.sgml,v 1.31 2002/08/15 16:36:00 momjian Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_type.sgml,v 1.32 2002/08/22 00:01:40 tgl Exp $
PostgreSQL documentation
-->
@ -226,22 +226,47 @@ CREATE TYPE
operators and functions defined for the type. Naturally,
<replaceable class="parameter">output_function</replaceable>
performs the reverse transformation. The input function may be
declared as taking one argument of type <type>opaque</type>,
declared as taking one argument of type <type>cstring</type>,
or as taking three arguments of types
<type>opaque</type>, <type>OID</type>, <type>int4</type>.
<type>cstring</type>, <type>OID</type>, <type>int4</type>.
(The first argument is the input text as a C string, the second
argument is the element type in case this is an array type,
and the third is the typmod of the destination column, if known.)
It should return a value of the datatype itself.
The output function may be
declared as taking one argument of type <type>opaque</type>,
or as taking two arguments of types
<type>opaque</type>, <type>OID</type>.
(The first argument is actually of the data type itself, but since the
output function must be declared first, it's easier to declare it as
accepting type <type>opaque</type>. The second argument is again
the array element type for array types.)
declared as taking one argument of the new datatype, or as taking
two arguments of which the second is type <type>OID</type>.
(The second argument is again the array element type for array types.)
The output function should return type <type>cstring</type>.
</para>
<para>
You should at this point be wondering how the input and output functions
can be declared to have results or inputs of the new type, when they have
to be created before the new type can be created. The answer is that the
input function must be created first, then the output function, then the
datatype.
<productname>PostgreSQL</productname> will first see the name of the new
datatype as the return type of the input function. It will create a
<quote>shell</> type, which is simply a placeholder entry in
<literal>pg_type</>, and link the input function definition to the shell
type. Similarly the output function will be linked to the (now already
existing) shell type. Finally, <command>CREATE TYPE</> replaces the
shell entry with a complete type definition, and the new type can be used.
</para>
<note>
<para>
In <productname>PostgreSQL</productname> versions before 7.3, it was
customary to avoid creating a shell type by replacing the functions'
forward references to the type name with the placeholder pseudo-type
<type>OPAQUE</>. The <type>cstring</> inputs and
results also had to be declared as <type>OPAQUE</> before 7.3.
Use of <type>OPAQUE</> for this purpose is still supported, but it is
deprecated because it causes loss of type safety.
</para>
</note>
<para>
New base data types can be fixed length, in which case
<replaceable class="parameter">internallength</replaceable> is a

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.149 2002/08/20 17:54:44 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.150 2002/08/22 00:01:40 tgl Exp $
-->
<appendix id="release">
@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without
worries about funny characters.
-->
<literallayout><![CDATA[
Type OPAQUE is now deprecated in favor of pseudo-types cstring, trigger, etc
Files larger than 2 GB are now supported (if supported by the operating system)
SERIAL no longer implies UNIQUE; specify explicitly if index is wanted
pg_dump -n and -N options have been removed. The new behavior is like -n but knows about key words.

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/trigger.sgml,v 1.23 2002/04/19 16:36:08 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/trigger.sgml,v 1.24 2002/08/22 00:01:40 tgl Exp $
-->
<chapter id="triggers">
@ -26,7 +26,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/trigger.sgml,v 1.23 2002/04/19 16:36:08 tgl
<para>
The trigger function must be defined before the trigger itself can be
created. The trigger function must be declared as a
function taking no arguments and returning type <literal>opaque</>.
function taking no arguments and returning type <literal>trigger</>.
(The trigger function receives its input through a TriggerData
structure, not in the form of ordinary function arguments.)
If the function is written in C, it must use the <quote>version 1</>
@ -536,7 +536,7 @@ trigf(PG_FUNCTION_ARGS)
Now, compile and create the trigger function:
<programlisting>
CREATE FUNCTION trigf () RETURNS OPAQUE AS
CREATE FUNCTION trigf () RETURNS TRIGGER AS
'...path_to_so' LANGUAGE 'C';
CREATE TABLE ttest (x int4);

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.54 2002/07/30 16:20:03 momjian Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.55 2002/08/22 00:01:40 tgl Exp $
-->
<chapter id="xfunc">
@ -2071,12 +2071,9 @@ SELECT * FROM vw_getfoo;
<quote>normal</quote> function, which must be written in a
compiled language such as C and registered with
<productname>PostgreSQL</productname> as taking no arguments and
returning the <type>opaque</type> type, a placeholder for
unspecified or undefined types. This prevents the call handler
from being called directly as a function from queries. (However,
arguments may be supplied in the actual call to the handler when a
function in the language offered by the handler is to be
executed.)
returning the <type>language_handler</type> type.
This special pseudo-type identifies the handler as a call handler
and prevents it from being called directly in queries.
</para>
<note>
@ -2203,7 +2200,7 @@ plsample_call_handler(PG_FUNCTION_ARGS)
The following commands then register the sample procedural
language:
<programlisting>
CREATE FUNCTION plsample_call_handler () RETURNS opaque
CREATE FUNCTION plsample_call_handler () RETURNS language_handler
AS '/usr/local/pgsql/lib/plsample'
LANGUAGE C;
CREATE LANGUAGE plsample

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/xplang.sgml,v 1.17 2002/01/07 02:29:14 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/xplang.sgml,v 1.18 2002/08/22 00:01:40 tgl Exp $
-->
<chapter id="xplang">
@ -82,10 +82,10 @@ createlang plpgsql template1
The handler must be declared with the command
<synopsis>
CREATE FUNCTION <replaceable>handler_function_name</replaceable> ()
RETURNS OPAQUE AS
RETURNS LANGUAGE_HANDLER AS
'<replaceable>path-to-shared-object</replaceable>' LANGUAGE C;
</synopsis>
The special return type of <type>OPAQUE</type> tells
The special return type of <type>LANGUAGE_HANDLER</type> tells
the database that this function does not return one of
the defined <acronym>SQL</acronym> data types and is not directly usable
in <acronym>SQL</acronym> statements.
@ -140,7 +140,7 @@ CREATE <optional>TRUSTED</optional> <optional>PROCEDURAL</optional> LANGUAGE <re
shared object for the <application>PL/pgSQL</application> language's call handler function.
<programlisting>
CREATE FUNCTION plpgsql_call_handler () RETURNS OPAQUE AS
CREATE FUNCTION plpgsql_call_handler () RETURNS LANGUAGE_HANDLER AS
'$libdir/plpgsql' LANGUAGE C;
</programlisting>
</para>

View File

@ -128,13 +128,13 @@ complex_out(Complex *complex)
<function>complex_out</function> before creating the type:
<programlisting>
CREATE FUNCTION complex_in(opaque)
CREATE FUNCTION complex_in(cstring)
RETURNS complex
AS '<replaceable>PGROOT</replaceable>/tutorial/complex'
LANGUAGE C;
CREATE FUNCTION complex_out(opaque)
RETURNS opaque
CREATE FUNCTION complex_out(complex)
RETURNS cstring
AS '<replaceable>PGROOT</replaceable>/tutorial/complex'
LANGUAGE C;
</programlisting>
@ -149,6 +149,10 @@ CREATE TYPE complex (
output = complex_out
);
</programlisting>
Notice that the declarations of the input and output functions must
reference the not-yet-defined type. This is allowed, but will draw
warning messages that may be ignored.
</para>
<para>