category, as this
could cause surprising changes in behavior.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">default</replaceable></term>
<listitem>
<para>
The default value for the data type. If this is omitted, the
default is null.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">element</replaceable></term>
<listitem>
<para>
The type being created is an array; this specifies the type of
the array elements.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">delimiter</replaceable></term>
<listitem>
<para>
The delimiter character to be used between values in arrays made
of this type.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">collatable</replaceable></term>
<listitem>
<para>
True if this type's operations can use collation information.
The default is false.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="sql-createtype-notes">
<title>Notes</title>
<para>
Because there are no restrictions on use of a data type once it's been
created, creating a base type or range type is tantamount to granting
public execute permission on the functions mentioned in the type definition.
This is usually
not an issue for the sorts of functions that are useful in a type
definition. But you might want to think twice before designing a type
in a way that would require <quote>secret</quote> information to be used
while converting it to or from external form.
</para>
<para>
Before <productname>PostgreSQL</productname> version 8.3, the name of
a generated array type was always exactly the element type's name with one
underscore character (<literal>_</literal>) prepended. (Type names were
therefore restricted in length to one fewer character than other names.)
While this is still usually the case, the array type name may vary from
this in case of maximum-length names or collisions with user type names
that begin with underscore. Writing code that depends on this convention
is therefore deprecated. Instead, use
<structname>pg_type</structname>.<structfield>typarray</structfield> to locate the array type
associated with a given type.
</para>
<para>
It may be advisable to avoid using type and table names that begin with
underscore. While the server will change generated array type names to
avoid collisions with user-given names, there is still risk of 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