diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml index 6a15f9030c..b397e18858 100644 --- a/doc/src/sgml/datatype.sgml +++ b/doc/src/sgml/datatype.sgml @@ -4359,6 +4359,60 @@ SET xmloption TO { DOCUMENT | CONTENT }; &rangetypes; + + Domain Types + + + domain + + + + data type + domain + + + + A domain is a user-defined data type that is + based on another underlying type. 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.) + + + + For example, we could create a domain over integers that accepts only + positive integers: + +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 + + + + + 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 mytable.id - 1 + is considered to be of type integer not posint. + We could write (mytable.id - 1)::posint to cast the + result back to posint, 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 id 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. + + + + For additional information see . + + + Object Identifier Types diff --git a/doc/src/sgml/extend.sgml b/doc/src/sgml/extend.sgml index c1bd03ad4c..e819010875 100644 --- a/doc/src/sgml/extend.sgml +++ b/doc/src/sgml/extend.sgml @@ -106,31 +106,60 @@ composite + + container type + + + + data type + container + + - PostgreSQL data types are divided into base - types, composite types, domains, and pseudo-types. + PostgreSQL data types can be divided into base + types, container types, domains, and pseudo-types. Base Types - Base types are those, like int4, that are + Base types are those, like integer, that are implemented below the level of the SQL language (typically in a low-level language such as C). They generally correspond to what are often known as abstract data types. PostgreSQL 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 . + + + + Enumerated (enum) types can be considered as a subcategory of base + types. The main difference is that they can be created using + just SQL commands, without any low-level programming. + Refer to for more information. - Composite Types + Container Types + + + PostgreSQL has three kinds + of container types, which are types that contain multiple + values of other types. These are arrays, composites, and ranges. + + + + 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 for more + information. + Composite types, or row types, are created whenever the user @@ -139,9 +168,15 @@ define a stand-alone 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 SQL queries. Refer to - for more information on composite types. + record of field values. Refer to + for more information. + + + + 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 + for more information. @@ -149,16 +184,12 @@ Domains - 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. - - - - Domains can be created using the SQL command - . - 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 SQL command . + Refer to for more information. @@ -167,8 +198,8 @@ There are a few pseudo-types 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. lists the existing @@ -188,7 +219,7 @@ - type + data type polymorphic diff --git a/doc/src/sgml/ref/alter_domain.sgml b/doc/src/sgml/ref/alter_domain.sgml index 26e95aefcf..9cd044de54 100644 --- a/doc/src/sgml/ref/alter_domain.sgml +++ b/doc/src/sgml/ref/alter_domain.sgml @@ -199,7 +199,7 @@ ALTER DOMAIN name - NOT VALID + NOT VALID Do not verify existing column data for constraint validity. @@ -274,11 +274,11 @@ ALTER DOMAIN name Currently, ALTER DOMAIN ADD CONSTRAINT, ALTER - DOMAIN VALIDATE CONSTRAINT, and ALTER DOMAIN SET NOT NULL - 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, and ALTER DOMAIN SET NOT + NULL 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. diff --git a/doc/src/sgml/rowtypes.sgml b/doc/src/sgml/rowtypes.sgml index bc2fc9b885..7e436a4606 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: -SELECT (m).* FROM (SELECT myfunc(x) AS m FROM some_table OFFSET 0) ss; +SELECT m.* FROM some_table, LATERAL myfunc(x) AS m; - The OFFSET 0 clause keeps the optimizer - from flattening the sub-select to arrive at the form with - multiple calls of myfunc(). + Placing the function in + a LATERAL FROM item keeps it from + being invoked more than once per row. m.* is still + expanded into m.a, m.b, m.c, but now those variables + are just references to the output of the FROM item. + (The LATERAL keyword is optional here, but we show it + to clarify that the function is getting x + from some_table.)