confusion,
particularly with old client software that may assume that type names
beginning with underscores always represent arrays.
</para>
<para>
Before <productname>PostgreSQL</productname> version 8.2, the shell-type
creation syntax
<literal>CREATE TYPE <replaceable>name</replaceable></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 might 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> version 16 and later,
it is desirable for base types' input functions to
return <quote>soft</quote> errors using the
new <function>errsave()</function>/<function>ereturn()</function>
mechanism, rather than throwing <function>ereport()</function>
exceptions as in previous versions.
See <filename>src/backend/utils/fmgr/README</filename> for more
information.
</para>
</refsect1>
<refsect1>
<title>Examples</title>
<para>
This example creates a composite type and uses it in
a function definition:
<programlisting>
CREATE TYPE compfoo AS (f1 int, f2 text);
CREATE FUNCTION getfoo() RETURNS SETOF compfoo AS $$
SELECT fooid, fooname FROM foo
$$ LANGUAGE SQL;
</programlisting>
</para>
<para>
This example creates an enumerated type and uses it in
a table definition:
<programlisting>
CREATE TYPE bug_status AS ENUM ('new', 'open', 'closed');
CREATE TABLE bug (
id serial,
description text,
status bug_status
);
</programlisting>
</para>
<para>
This example creates a range type:
<programlisting>
CREATE TYPE float8_range AS RANGE (subtype = float8, subtype_diff = float8mi);
</programlisting>
</para>
<para>
This example creates the base data type <type>box</type> and then uses the
type in a table definition: