diff --git a/doc/src/sgml/rangetypes.sgml b/doc/src/sgml/rangetypes.sgml index 083560e9b2..87acca19ea 100644 --- a/doc/src/sgml/rangetypes.sgml +++ b/doc/src/sgml/rangetypes.sgml @@ -94,9 +94,9 @@ SELECT int4range(10, 20) * int4range(15, 25); SELECT isempty(numrange(1, 5)); - See - and for complete lists of - functions and operators on range types. + See + and for complete lists of + operators and functions on range types. @@ -230,6 +230,9 @@ select '(3,7)'::int4range; -- includes only the single point 4 select '[4,4]'::int4range; + +-- includes no points (and will be normalized to 'empty') +select '[4,4)'::int4range; @@ -277,7 +280,7 @@ SELECT numrange(NULL, 2.2); A discrete range is one whose element type has a well-defined step, such as INTEGER or DATE. - In these types two elements can be said to be adjacent, since there are + In these types two elements can be said to be adjacent, when there are no valid values between them. This contrasts with continuous ranges, where it's always (or almost always) possible to identify other element values between two given values. For example, a range over the @@ -301,18 +304,12 @@ SELECT numrange(NULL, 2.2); A discrete range type should have a canonicalization function that is aware of the desired step size for the element type. - The canonicalization function is charged with converting values of the - range type to have consistently inclusive or exclusive bounds. - The canonicalization function takes an input range value, and - must return an equivalent range value that may have a different - formatting. The canonical output for two values that are equivalent, like - [1, 7] and [1, 8), must be identical. - It doesn't matter which representation you choose to be the canonical one, - so long as two equivalent values with different formattings are always - mapped to the same value with the same formatting. If a canonicalization - function is not specified, then ranges with different formatting - will always be treated as unequal, even though they might represent the - same set of values. + The canonicalization function is charged with converting equivalent values + of the range type to have identical representations, in particular + consistently inclusive or exclusive bounds. + If a canonicalization function is not specified, then ranges with different + formatting will always be treated as unequal, even though they might + represent the same set of values in reality. @@ -331,28 +328,64 @@ SELECT numrange(NULL, 2.2); Users can define their own range types. The most common reason to do this is to use ranges over subtypes not provided among the built-in range types. - For example, to define a new range type of subtype DOUBLE - PRECISION: + For example, to define a new range type of subtype float8: -CREATE TYPE FLOATRANGE AS RANGE ( - SUBTYPE = DOUBLE PRECISION +CREATE TYPE floatrange AS RANGE ( + subtype = float8, + subtype_diff = float8mi ); SELECT '[1.234, 5.678]'::floatrange; - Because DOUBLE PRECISION has no meaningful + Because float8 has no meaningful step, we do not define a canonicalization - function. + function in this example. + + + + If the subtype is considered to have discrete rather than continuous + values, the CREATE TYPE command should specify a + canonical function. + The canonicalization function takes an input range value, and must return + an equivalent range value that may have different bounds and formatting. + The canonical output for two ranges that represent the same set of values, + for example the integer ranges [1, 7] and [1, + 8), must be identical. It doesn't matter which representation + you choose to be the canonical one, so long as two equivalent values with + different formattings are always mapped to the same value with the same + formatting. In addition to adjusting the inclusive/exclusive bounds + format, a canonicalization function might round off boundary values, in + case the desired step size is larger than what the subtype is capable of + storing. For instance, a range type over timestamp could be + defined to have a step size of an hour, in which case the canonicalization + function would need to round off bounds that weren't a multiple of an hour, + or perhaps throw an error instead. Defining your own range type also allows you to specify a different - operator class or collation to use, so as to change the sort ordering - that determines which values fall into a given range. You might also - choose to use a different canonicalization function, either to change - the displayed format or to modify the effective step size. + subtype B-tree operator class or collation to use, so as to change the sort + ordering that determines which values fall into a given range. + + + + In addition, any range type that is meant to be used with GiST indexes + should define a subtype difference, or subtype_diff, function. + (A GiST index will still work without subtype_diff, but it is + likely to be considerably less efficient than if a difference function is + provided.) The subtype difference function takes two input values of the + subtype, and returns their difference (i.e., X minus + Y) represented as a float8 value. In our example + above, the function that underlies the regular float8 minus + operator can be used; but for any other subtype, some type conversion would + be necessary. Some creative thought about how to represent differences as + numbers might be needed, too. To the greatest extent possible, the + subtype_diff function should agree with the sort ordering + implied by the selected operator class and collation; that is, its result + should be positive whenever its first argument is greater than its second + according to the sort ordering. @@ -366,18 +399,37 @@ SELECT '[1.234, 5.678]'::floatrange; range type - GiST index + indexes on - GiST indexes can be applied to columns of range types. For instance: + GiST indexes can be created for table columns of range types. + For instance: CREATE INDEX reservation_idx ON reservation USING gist (during); - This index may speed up queries - involving && - (overlaps), @> (contains), and other boolean - operators listed in . + A GiST index can accelerate queries involving these range operators: + =, + &&, + <@, + @>, + <<, + >>, + -|-, + &<, and + &> + (see for more information). + + + + In addition, B-tree and hash indexes can be created for table columns of + range types. For these index types, basically the only useful range + operation is equality. There is a B-tree sort ordering defined for range + values, with corresponding < and > operators, + but the ordering is rather arbitrary and not usually useful in the real + world. Range types' B-tree and hash support is primarily meant to + allow sorting and hashing internally in queries, rather than creation of + actual indexes. diff --git a/doc/src/sgml/ref/create_type.sgml b/doc/src/sgml/ref/create_type.sgml index 1bf8cd9546..3308ee72ea 100644 --- a/doc/src/sgml/ref/create_type.sgml +++ b/doc/src/sgml/ref/create_type.sgml @@ -128,9 +128,9 @@ CREATE TYPE name The range type's subtype can - be any type with an associated btree operator class (to determine the + be any type with an associated b-tree operator class (to determine the ordering of values for the range type). Normally the subtype's default - btree operator class is used to determine ordering; to use a non-default + b-tree operator class is used to determine ordering; to use a non-default opclass, specify its name with subtype_opclass. If the subtype is collatable, and you want to use a non-default collation in the range's @@ -141,16 +141,18 @@ CREATE TYPE name The optional canonical function must take one argument of the range type being defined, and - return a value of the same type. This is used to convert the range value - to a canonical form, when applicable. See - for more information. To define - the canonical function, - you must first create a shell type, which is a + return a value of the same type. This is used to convert range values + to a canonical form, when applicable. See for more information. Creating a + canonical function + is a bit tricky, since it must be defined before the range type can be + declared. To do this, you must first create a shell type, which is a placeholder type that has no properties except a name and an owner. This is done by issuing the command CREATE TYPE name, with no additional parameters. Then - the function can be declared, and finally the range type can be declared, - replacing the shell type entry with a valid range type. + the function can be declared using the shell type as argument and result, + and finally the range type can be declared using the same name. This + automatically replaces the shell type entry with a valid range type. @@ -160,11 +162,8 @@ CREATE TYPE name and return a double precision value representing the difference between the two given values. While this is optional, providing it allows much greater efficiency of GiST indexes on columns of - the range type. Note that the subtype_diff function should agree with - the sort ordering implied by the selected operator class and collation; - that is, its result should be positive whenever its first argument is - greater than its second according to the sort ordering. + the range type. See for more + information. @@ -541,7 +540,7 @@ CREATE TYPE name subtype_operator_class - The name of a btree operator class for the subtype. + The name of a b-tree operator class for the subtype.