Range
A range type is a data type that represents the range of a value of an element type (called the subtype of a range). For example, the range of timestamp may be used to express a time range in which a conference room is reserved. In this case, the data type is tsrange (short for timestamp range), and timestamp is the subtype. The subtype must have an overall order so that the element value can be clearly specified within a range, before, or after.
Range types are useful because they can express multiple element values in a single range value and can clearly express concepts such as range overlapping. The time and date range used for scheduling is the best example, as the range of an instrument are also examples of range type.
Built-in Range
The following built-in ranges are available:
- int4range: integer range.
- int8range: bigint range.
- numrange: numeric range.
- tsrange: range of timestamp without the time zone.
- tstzrange: range of timestamp with the time zone
- daterange: date range.
In addition, you can define your own range types. For details, see CREATE TYPE.
Example
CREATE TABLE reservation (room int, during tsrange); INSERT INTO reservation VALUES (1108, '[2010-01-01 14:30, 2010-01-01 15:30)'); -- Inclusion SELECT int4range(10, 20) @> 3; -- Determine whether the two ranges overlap. SELECT numrange(11.1, 22.2) && numrange(20.0, 30.0); -- Upper bound extraction SELECT upper(int8range(15, 25)); -- Intersection set SELECT int4range(10, 20) * int4range(15, 25); -- Determine whether the range is empty. SELECT isempty(numrange(1, 5));
See the complete list of operators and functions on a range type in Range Functions and Operators.
Including and Excluding Bounds
Each non-empty range has two bounds, a lower bound and an upper bound. All values between the two bounds are included in the range. An inclusion bound means that the bound value itself is included in the range, while an exclusion bound means that the bound value is not included in the range.
In a textual form of a range, an inclusion lower bound is expressed as "[" and an exclusion lower bound is expressed as "(". Similarly, one including the upper bound is expressed as "]" and one excluding the upper bound is expressed as ")" (for details, see Range Input/Output).
The lower_inc and upper_inc functions test the upper and lower bounds of a range value, respectively.
Infinite (Unbounded) Range
When the lower bound of a range is unbounded, it means that all values less than the upper bound are included in the range, for example, (,3] meaning all values less than the upper bound 3 are included in the range. Similarly, when the upper bound of a range is unbounded, all values greater than the upper bound are included in the range. When both the upper and lower bounds are unbounded, all values of the element type are considered within the range. The missing bounds are automatically converted to exclusions, for example, [,] is converted to (,). You can think of these missing values as positive infinity or negative infinity, but they are special range type values and are considered to be positive and negative infinity values that go beyond any range element type.
Element types with the infinity values can be used as explicit bound values. For example, in the timestamp range, [today, infinity) does not include a special timestamp value infinity.
The lower_inf and upper_inf functions test the infinite upper and lower bounds of a range, respectively.
Range Input/Output
The input of a range value must follow one of the following formats:
(lower-bound, upper-bound) (lower-bound, upper-bound] [lower-bound, upper-bound) [lower-bound, upper-bound] Empty
Parentheses () or square brackets [] indicate whether the upper and lower bounds are excluded or included. Note that the last format is empty, which represents an empty range (a range that does not contain values).
The value of lower-bound can be a valid input string of the subtype or null, indicating that there is no lower bound. Similarly, upper-bound can be a valid input string of the subtype or null, indicating that there is no upper bound.
Each bound value can be referenced using the quotation marks("") character. This is necessary if the bounds value contains parentheses (), square brackets [], commas (,), quotation marks (""), or backslashes (\), because otherwise those characters will be considered part of the range syntax. To put the quotation mark or backslash in a referenced bound value, put a backslash in front of it (and a pair of double quotation marks in its quoted bound value represents one quotation mark character, which is similar to the single quotation mark rule in SQL character strings). In addition, you can avoid referencing and use backslash escapes to protect all data characters, otherwise they will be used as part of the return syntax. Also, if you want to write a bound value that is an empty string, write "", indicating infinite bounds.
Spaces are allowed before and after a range value, but any space between parentheses() or square brackets[] is used as part of the upper or lower bound value (depending on the element type, the space may or may not represent a value).
Example:
-- 3 is included, 7 is not included, and all values between 3 and 7 are included. SELECT '[3,7)'::int4range; -- Neither 3 nor 7 is included, but all values between them are included. SELECT '(3,7)'::int4range; -- Only value 4 is included. SELECT '[4,4]'::int4range; -- Exclude any value (and will be normalized to empty). SELECT '[4,4)'::int4range;
Constructing Range
Each range type has a constructor function with the same name. Using constructor functions is often more convenient than writing a range literal constant because it avoids extra references to bound values. Constructor functions accept two or three parameters. Two parameters form a range in the standard form, where the lower bound is included and the upper bound is excluded, and three parameters form a range according to the bound specified by the third parameter. The third parameter must be one of the following character strings: (), (], [], or []. For example:
-- The complete format is: lower bound, upper bound, and textual parameters indicating the inclusion/exclusion of bounds. SELECT numrange(1.0, 14.0, '(]'); -- If the third parameter is ignored, it is assumed to be '[)'. SELECT numrange(1.0, 14.0); -- Although '(]' is specified here, the value will be converted to the standard format when displayed, because int8range is a discrete range type (see below). SELECT int8range(1, 14, '(]'); -- Using NULL for a bound causes the range to be unbounded on that side. SELECT numrange(NULL, 2.2);
Discrete Range
A range element type has a well-defined "step" such as integer or date. In these types, if there is no valid value between two elements, they can be said to be adjacent. This is in contrast to a continuous range in which other element values can always be identified between two given values. For example, the numeric type range is continuous, and the timestamp range is also continuous. (Although timestamp has limited precision and can be considered as discrete in theory, it is better to consider it as continuous because the step is not normally considered.)
Another way to consider discrete range types is to have a clear "next" or "previous" value for each element value. With this idea in mind, you can switch between inclusion and exclusion expressions of a range bound by replacing it with the original given next or previous element value. For example, in an integer range type, [4,8] and (3,9) represent the same set of values, but not for numeric ranges.
A discrete range type should have a regularization function that knows the expected step size of the element type. The regularization function can convert the equivalents of the range type to the same expression, in particular consistent with the inclusion or exclusion bounds. If you do not specify a regularization function, ranges with different formats will always be considered as unequal, even if they actually express the same set of values.
The built-in range types int4range, int8range, and daterange use a regularized form that includes the lower bound and excludes the upper bound, that is, [). However, user-defined range types can use other conventions.
Index
GiST and SP-GiST indexes can be created for table columns of the range type. For example, to create a GiST index, run the following command:
CREATE INDEX reservation_idx ON reservation USING GIST (during);
A GiST or SP-GiST index can accelerate queries involving the following range operators: =, &&, <@, @>, <<, >>, -|-, &<, and &> (see Range Functions and Operators).
In addition, the B-tree and hash index can be created on table columns of the range type. For these index types, basically the only useful range operation is equivalence. Using the corresponding < and > operators, there is a B-tree sort oder for range value definitions, but that order is fairly arbitrary and is often less useful in the reality. The B-tree and hash support for range types is primarily designed to allow sorting and hashing within a query, rather than creating an index.
Feedback
Was this page helpful?
Provide feedbackThank you very much for your feedback. We will continue working to improve the documentation.See the reply and handling status in My Cloud VOC.
For any further questions, feel free to contact us through the chatbot.
Chatbot