<quote>on the
fly</quote> makes <productname>PostgreSQL</productname> uniquely
suited for rapid prototyping of new applications and storage
structures.
</para>
</sect1>
<sect1 id="extend-type-system">
<title>The <productname>PostgreSQL</productname> Type System</title>
<indexterm zone="extend-type-system">
<primary>base type</primary>
</indexterm>
<indexterm zone="extend-type-system">
<primary>data type</primary>
<secondary>base</secondary>
</indexterm>
<indexterm zone="extend-type-system">
<primary>composite type</primary>
</indexterm>
<indexterm zone="extend-type-system">
<primary>data type</primary>
<secondary>composite</secondary>
</indexterm>
<indexterm zone="extend-type-system">
<primary>container type</primary>
</indexterm>
<indexterm zone="extend-type-system">
<primary>data type</primary>
<secondary>container</secondary>
</indexterm>
<para>
<productname>PostgreSQL</productname> data types can be divided into base
types, container types, domains, and pseudo-types.
</para>
<sect2 id="extend-type-system-base">
<title>Base Types</title>
<para>
Base types are those, like <type>integer</type>, that are
implemented below the level of the <acronym>SQL</acronym> language
(typically in a low-level language such as C). They generally
correspond to what are often known as abstract data types.
<productname>PostgreSQL</productname> can only operate on such
types through functions provided by the user and only understands
the behavior of such types to the extent that the user describes
them.
The built-in base types are described in <xref linkend="datatype"/>.
</para>
<para>
Enumerated (enum) types can be considered as a subcategory of base
types. The main difference is that they can be created using
just <acronym>SQL</acronym> commands, without any low-level programming.
Refer to <xref linkend="datatype-enum"/> for more information.
</para>
</sect2>
<sect2 id="extend-type-system-container">
<title>Container Types</title>
<para>
<productname>PostgreSQL</productname> has three kinds
of <quote>container</quote> types, which are types that contain multiple
values of other types. These are arrays, composites, and ranges.
</para>
<para>
Arrays can hold multiple values that are all of the same type. An array
type is automatically created for each base type, composite type, range
type, and domain type. But there are no arrays of arrays. So far as
the type system is concerned, multi-dimensional arrays are the same as
one-dimensional arrays. Refer to <xref linkend="arrays"/> for more
information.
</para>
<para>
Composite types, or row types, are created whenever the user
creates a table. It is also possible to use <xref
linkend="sql-createtype"/> to
define a <quote>stand-alone</quote> composite type with no associated
table. A composite type is simply a list of types with
associated field names. A value of a composite type is a row or
record of field values. Refer to <xref linkend="rowtypes"/>
for more information.
</para>
<para>
A range type can hold two values of the same type, which are the lower
and upper bounds of the range. Range types are user-created, although
a few built-in ones exist. Refer to <xref linkend="rangetypes"/>
for more information.
</para>
</sect2>
<sect2 id="extend-type-system-domains">
<title>Domains</title>
<para>
A domain is based on a particular underlying type and for many purposes
is interchangeable with its underlying type. However, a domain can have
constraints that restrict its valid values to a subset of what the
underlying type would allow. Domains are created using
the <acronym>SQL</acronym> command <xref