diff options
-rw-r--r-- | doc/src/sgml/datatype.sgml | 54 | ||||
-rw-r--r-- | doc/src/sgml/extend.sgml | 79 | ||||
-rw-r--r-- | doc/src/sgml/ref/alter_domain.sgml | 12 | ||||
-rw-r--r-- | doc/src/sgml/rowtypes.sgml | 13 |
4 files changed, 124 insertions, 34 deletions
diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml index 6a15f9030c9..b397e188583 100644 --- a/doc/src/sgml/datatype.sgml +++ b/doc/src/sgml/datatype.sgml @@ -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> diff --git a/doc/src/sgml/extend.sgml b/doc/src/sgml/extend.sgml index c1bd03ad4c9..e8190108754 100644 --- a/doc/src/sgml/extend.sgml +++ b/doc/src/sgml/extend.sgml @@ -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> diff --git a/doc/src/sgml/ref/alter_domain.sgml b/doc/src/sgml/ref/alter_domain.sgml index 26e95aefcfd..9cd044de540 100644 --- a/doc/src/sgml/ref/alter_domain.sgml +++ b/doc/src/sgml/ref/alter_domain.sgml @@ -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> diff --git a/doc/src/sgml/rowtypes.sgml b/doc/src/sgml/rowtypes.sgml index bc2fc9b8850..7e436a46065 100644 --- a/doc/src/sgml/rowtypes.sgml +++ b/doc/src/sgml/rowtypes.sgml @@ -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> |