rows by
comparing an <type>xml</type> column against a search value. XML
values should therefore typically be accompanied by a separate key
field such as an ID. An alternative solution for comparing XML
values is to convert them to character strings first, but note
that character string comparison has little to do with a useful
XML comparison method.
</para>
<para>
Since there are no comparison operators for the <type>xml</type>
data type, it is not possible to create an index directly on a
column of this type. If speedy searches in XML data are desired,
possible workarounds include casting the expression to a
character string type and indexing that, or indexing an XPath
expression. Of course, the actual query would have to be adjusted
to search by the indexed expression.
</para>
<para>
The text-search functionality in PostgreSQL can also be used to speed
up full-document searches of XML data. The necessary
preprocessing support is, however, not yet available in the PostgreSQL
distribution.
</para>
</sect2>
</sect1>
&json;
&array;
&rowtypes;
&rangetypes;
<sect1 id="domains">
<title>Domain Types</title>
<indexterm zone="domains">
<primary>domain</primary>
</indexterm>
<indexterm zone="domains">
<primary>data type</primary>
<secondary>domain</secondary>
</indexterm>
<para>
A <firstterm>domain</firstterm> is a user-defined data type that is
based on another <firstterm>underlying type</firstterm>. Optionally,
it can have constraints that restrict its valid values to a subset of
what the underlying type would allow. Otherwise it behaves like the
underlying type — for example, any operator or function that
can be applied to the underlying type will work on the domain type.
The underlying type can be any built-in or user-defined base type,
enum type, array type, composite type, range type, or another domain.
</para>
<para>
For example, we could create a domain over integers that accepts only
positive integers:
<programlisting>
CREATE DOMAIN posint AS integer CHECK (VALUE > 0);
CREATE TABLE mytable (id posint);
INSERT INTO mytable VALUES(1); -- works
INSERT INTO mytable VALUES(-1); -- fails
</programlisting>
</para>
<para>
When an operator or function of the underlying type is applied to a
domain value, the domain is automatically down-cast to the underlying
type. Thus, for example, the result of <literal>mytable.id - 1</literal>
is considered to be of type <type>integer</type> not <type>posint</type>.
We could write <literal>(mytable.id - 1)::posint</literal> to cast the
result back to <type>posint</type>, causing the domain's constraints
to be rechecked. In this case, that would result in an error if the
expression had been applied to an <structfield>id</structfield> value of
1. Assigning a value of the underlying type to a field or variable of
the domain type is allowed without writing an explicit cast, but the
domain's constraints will be checked.
</para>
<para>
For additional information see <xref linkend="sql-createdomain"/>.
</para>
</sect1>
<sect1 id="datatype-oid">
<title>Object Identifier Types</title>
<indexterm zone="datatype-oid">
<primary>object identifier</primary>
<secondary>data type</secondary>
</indexterm>
<indexterm zone="datatype-oid">
<primary>oid</primary>
</indexterm>
<indexterm zone="datatype-oid">
<primary>regclass</primary>
</indexterm>
<indexterm zone="datatype-oid">
<primary>regcollation</primary>
</indexterm>
<indexterm zone="datatype-oid">
<primary>regconfig</primary>
</indexterm>
<indexterm zone="datatype-oid">
<primary>regdictionary</primary>
</indexterm>
<indexterm zone="datatype-oid">
<primary>regnamespace</primary>
</indexterm>
<indexterm zone="datatype-oid">