Documentation improvements around domain types.
I was a bit surprised to find that domains were almost completely unmentioned in the main SGML documentation, outside of the reference pages for CREATE/ALTER/DROP DOMAIN. In particular, noplace was it mentioned that we don't support domains over composite, making it hard to document the planned fix for that. Hence, add a section about domains to chapter 8 (Data Types). Also, modernize the type system overview in section 37.2; it had never heard of range types, and insisted on calling arrays base types, which seems a bit odd from a user's perspective; furthermore it didn't fit well with the fact that we now support arrays over types other than base types. It seems appropriate to use the term "container types" to describe all of arrays, composites, and ranges, so let's do that. Also a few other minor improvements, notably improve an example query in rowtypes.sgml by using a LATERAL function instead of an ad-hoc OFFSET 0 clause. In part this is mop-up for commit c12d570fa, which missed updating 37.2 to reflect the fact that it added arrays of domains. We could possibly back-patch this without that claim, but I don't feel a strong need to.
This commit is contained in:
parent
8df4ce1eac
commit
a32c0923b4
@ -4359,6 +4359,60 @@ SET xmloption TO { DOCUMENT | CONTENT };
|
||||
|
||||
&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 or range type, or another domain. (Currently, domains
|
||||
over composite types are not implemented.)
|
||||
</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>
|
||||
|
||||
|
@ -106,31 +106,60 @@
|
||||
<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 are divided into base
|
||||
types, composite types, domains, and pseudo-types.
|
||||
<productname>PostgreSQL</productname> data types can be divided into base
|
||||
types, container types, domains, and pseudo-types.
|
||||
</para>
|
||||
|
||||
<sect2>
|
||||
<title>Base Types</title>
|
||||
|
||||
<para>
|
||||
Base types are those, like <type>int4</type>, that are
|
||||
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. Base types are further subdivided into scalar and array
|
||||
types. For each scalar type, a corresponding array type is
|
||||
automatically created that can hold variable-size arrays of that
|
||||
scalar type.
|
||||
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>
|
||||
<title>Composite Types</title>
|
||||
<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
|
||||
@ -139,9 +168,15 @@
|
||||
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. The user can access the component fields
|
||||
from <acronym>SQL</acronym> queries. Refer to <xref linkend="rowtypes">
|
||||
for more information on composite types.
|
||||
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>
|
||||
|
||||
@ -149,16 +184,12 @@
|
||||
<title>Domains</title>
|
||||
|
||||
<para>
|
||||
A domain is based on a particular base type and for many purposes
|
||||
is interchangeable with its base type. However, a domain can
|
||||
have constraints that restrict its valid values to a subset of
|
||||
what the underlying base type would allow.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Domains can be created using the <acronym>SQL</acronym> command
|
||||
<xref linkend="sql-createdomain">.
|
||||
Their creation and use is not discussed in this chapter.
|
||||
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 linkend="sql-createdomain">.
|
||||
Refer to <xref linkend="domains"> for more information.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
@ -167,8 +198,8 @@
|
||||
|
||||
<para>
|
||||
There are a few <quote>pseudo-types</quote> for special purposes.
|
||||
Pseudo-types cannot appear as columns of tables or attributes of
|
||||
composite types, but they can be used to declare the argument and
|
||||
Pseudo-types cannot appear as columns of tables or components of
|
||||
container types, but they can be used to declare the argument and
|
||||
result types of functions. This provides a mechanism within the
|
||||
type system to identify special classes of functions. <xref
|
||||
linkend="datatype-pseudotypes-table"> lists the existing
|
||||
@ -188,7 +219,7 @@
|
||||
</indexterm>
|
||||
|
||||
<indexterm zone="extend-types-polymorphic">
|
||||
<primary>type</primary>
|
||||
<primary>data type</primary>
|
||||
<secondary>polymorphic</secondary>
|
||||
</indexterm>
|
||||
|
||||
|
@ -199,7 +199,7 @@ ALTER DOMAIN <replaceable class="parameter">name</replaceable>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><replaceable class="parameter">NOT VALID</replaceable></term>
|
||||
<term><literal>NOT VALID</literal></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Do not verify existing column data for constraint validity.
|
||||
@ -274,11 +274,11 @@ ALTER DOMAIN <replaceable class="parameter">name</replaceable>
|
||||
|
||||
<para>
|
||||
Currently, <command>ALTER DOMAIN ADD CONSTRAINT</command>, <command>ALTER
|
||||
DOMAIN VALIDATE CONSTRAINT</command>, and <command>ALTER DOMAIN SET NOT NULL</command>
|
||||
will fail if the validated named domain or
|
||||
any derived domain is used within a composite-type column of any
|
||||
table in the database. They should eventually be improved to be
|
||||
able to verify the new constraint for such nested columns.
|
||||
DOMAIN VALIDATE CONSTRAINT</command>, and <command>ALTER DOMAIN SET NOT
|
||||
NULL</command> will fail if the named domain or any derived domain is used
|
||||
within a container-type column (a composite, array, or range column) in
|
||||
any table in the database. They should eventually be improved to be able
|
||||
to verify the new constraint for such nested values.
|
||||
</para>
|
||||
|
||||
</refsect1>
|
||||
|
@ -328,11 +328,16 @@ SELECT (myfunc(x)).a, (myfunc(x)).b, (myfunc(x)).c FROM some_table;
|
||||
with either syntax. If it's an expensive function you may wish to
|
||||
avoid that, which you can do with a query like:
|
||||
<programlisting>
|
||||
SELECT (m).* FROM (SELECT myfunc(x) AS m FROM some_table OFFSET 0) ss;
|
||||
SELECT m.* FROM some_table, LATERAL myfunc(x) AS m;
|
||||
</programlisting>
|
||||
The <literal>OFFSET 0</literal> clause keeps the optimizer
|
||||
from <quote>flattening</quote> the sub-select to arrive at the form with
|
||||
multiple calls of <function>myfunc()</function>.
|
||||
Placing the function in
|
||||
a <literal>LATERAL</literal> <literal>FROM</literal> item keeps it from
|
||||
being invoked more than once per row. <literal>m.*</literal> is still
|
||||
expanded into <literal>m.a, m.b, m.c</literal>, but now those variables
|
||||
are just references to the output of the <literal>FROM</literal> item.
|
||||
(The <literal>LATERAL</literal> keyword is optional here, but we show it
|
||||
to clarify that the function is getting <structfield>x</structfield>
|
||||
from <structname>some_table</structname>.)
|
||||
</para>
|
||||
</tip>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user