1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-20 15:22:23 +03:00

Allow the syntax CREATE TYPE foo, with no parameters, to permit explicit

creation of a shell type.  This allows a less hacky way of dealing with
the mutual dependency between a datatype and its I/O functions: make a
shell type, then make the functions, then define the datatype fully.
We should fix pg_dump to handle things this way, but this commit just deals
with the backend.

Martijn van Oosterhout, with some corrections by Tom Lane.
This commit is contained in:
Tom Lane
2006-02-28 22:37:27 +00:00
parent 7f19339cca
commit 8e68d78390
12 changed files with 220 additions and 86 deletions

View File

@ -1,5 +1,5 @@
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/create_type.sgml,v 1.60 2006/01/13 18:06:45 tgl Exp $
$PostgreSQL: pgsql/doc/src/sgml/ref/create_type.sgml,v 1.61 2006/02/28 22:37:25 tgl Exp $
PostgreSQL documentation
-->
@ -37,6 +37,8 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> (
[ , ELEMENT = <replaceable class="parameter">element</replaceable> ]
[ , DELIMITER = <replaceable class="parameter">delimiter</replaceable> ]
)
CREATE TYPE <replaceable class="parameter">name</replaceable>
</synopsis>
</refsynopsisdiv>
@ -142,17 +144,16 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> (
<para>
You should at this point be wondering how the input and output functions
can be declared to have results or arguments 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 (and
the binary I/O functions if wanted), and finally the data type.
<productname>PostgreSQL</productname> will first see the name of the new
data type as the return type of the input function. It will create a
<quote>shell</> type, which is simply a placeholder entry in
the system catalog, and link the input function definition to the shell
type. Similarly the other functions 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.
can be declared to have results or arguments of the new type, when they
have to be created before the new type can be created. The answer is that
the type should first be defined as a <firstterm>shell type</>, which is a
placeholder type that has no properties except a name and an owner. This
is done by issuing the command <literal>CREATE TYPE
<replaceable>name</></literal>, with no additional parameters. Then the
I/O functions can be defined referencing the shell type. Finally,
<command>CREATE TYPE</> with a full definition replaces the shell entry
with a complete, valid type definition, after which the new type can be
used normally.
</para>
<para>
@ -457,17 +458,33 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> (
while converting it to or from external form.
</para>
<para>
Before <productname>PostgreSQL</productname> version 8.2, the syntax
<literal>CREATE TYPE <replaceable>name</></literal> did not exist.
The way to create a new base type was to create its input function first.
In this approach, <productname>PostgreSQL</productname> will first see
the name of the new data type as the return type of the input function.
The shell type is implicitly created in this situation, and then it
can be referenced in the definitions of the remaining I/O functions.
This approach still works, but is deprecated and may be disallowed in
some future release. Also, to avoid accidentally cluttering
the catalogs with shell types as a result of simple typos in function
definitions, a shell type will only be made this way when the input
function is written in C.
</para>
<para>
In <productname>PostgreSQL</productname> versions before 7.3, it
was customary to avoid creating a shell type by replacing the
was customary to avoid creating a shell type at all, by replacing the
functions' forward references to the type name with the placeholder
pseudotype <type>opaque</>. The <type>cstring</> arguments and
results also had to be declared as <type>opaque</> before 7.3. To
support loading of old dump files, <command>CREATE TYPE</> will
accept functions declared using <type>opaque</>, but it will issue
a notice and change the function's declaration to use the correct
accept I/O functions declared using <type>opaque</>, but it will issue
a notice and change the function declarations to use the correct
types.
</para>
</refsect1>
<refsect1>
@ -489,6 +506,11 @@ $$ LANGUAGE SQL;
This example creates the base data type <type>box</type> and then uses the
type in a table definition:
<programlisting>
CREATE TYPE box;
CREATE FUNCTION my_box_in_function(cstring) RETURNS box AS ... ;
CREATE FUNCTION my_box_out_function(box) RETURNS cstring AS ... ;
CREATE TYPE box (
INTERNALLENGTH = 16,
INPUT = my_box_in_function,

View File

@ -1,5 +1,5 @@
<!--
$PostgreSQL: pgsql/doc/src/sgml/xtypes.sgml,v 1.25 2005/01/10 00:04:38 tgl Exp $
$PostgreSQL: pgsql/doc/src/sgml/xtypes.sgml,v 1.26 2006/02/28 22:37:25 tgl Exp $
-->
<sect1 id="xtypes">
@ -168,8 +168,16 @@ complex_send(PG_FUNCTION_ARGS)
</para>
<para>
To define the <type>complex</type> type, we need to create the
user-defined I/O functions before creating the type:
Once we have written the I/O functions and compiled them into a shared
library, we can define the <type>complex</type> type in SQL.
First we declare it as a shell type:
<programlisting>
CREATE TYPE complex;
</programlisting>
This serves as a placeholder that allows us to reference the type while
defining its I/O functions. Now we can define the I/O functions:
<programlisting>
CREATE FUNCTION complex_in(cstring)
@ -192,15 +200,10 @@ CREATE FUNCTION complex_send(complex)
AS '<replaceable>filename</replaceable>'
LANGUAGE C IMMUTABLE STRICT;
</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. The input function must
appear first.
</para>
<para>
Finally, we can declare the data type:
Finally, we can provide the full definition of the data type:
<programlisting>
CREATE TYPE complex (
internallength = 16,