Chapter 2. Set and Span Types

Table of Contents

Input and Output
Constructors
Conversions
Accessors
Transformations
Spatial Reference System
Set Operations
Bounding Box Operations
Topological Operations
Position Operations
Distance Operations
Comparisons
Aggregations
Indexing

MobilityDB provides set, span, and span set types for representing set of values another type, which is called the base type. Set types are akin to array types in PostgreSQL restricted to one dimension, but enforce the constraint that sets do not have duplicates. Span and span set types in MobilityDB correspond to the range and multirange types in PostgreSQL but have additional constraints. In particular, span types in MobilityDB are of fixed length and do not allow empty spans and infinite bounds. While span types provide similar functionality to range types, they enable increasing performance. In particular, the overhead of processing variable-length types is removed and, in addition, pointer arithmetics and binary search can be used.

The base types used for constructing set, span, and span set types are the types integer, bigint, float, text, date, and timestamptz (timestamp with time zone) provided by PostgreSQL, the types geometry and geography provided by PostGIS, and the type npoint (network point) provided by MobilityDB (see Chapter 11, Temporal Network Points). MobilityDB provides the following set and span types:

We present next the functions and operators for set and span types. These functions and operators are polymorphic, that is, their arguments may be of several types, and the result type may depend on the type of the arguments. To express this in the signature of the functions and operators, we use the following notation:

As an example, the signature of the contains operator (@>) is as follows:

{set,spans} @> {set,spans,base} → boolean

Notice that the signature above is an abridged version of the more precise signature below

set @> {set,base} → boolean
spans @> {spans,base} → boolean

since sets and spans cannot be mixed in operations and thus, for instance, we cannot ask wether a span contains a set. In the following, for conciseness, we use the abridged style of signatures above. Furthermore, the time part of the timestamps is omitted in most examples. Recall that in that case PostgreSQL assumes the time 00:00:00.

In what follows, since span and span set types have similar functions and operators, when we speak about span types we mean both span and span set types, unless we explicitly refer to unit span types and span set types to distinguish them.

Input and Output

MobilityDB generalizes Open Geospatial Consortium's (OGC) Well-Known Text (WKT) and Well-Known Binary (WKB) input and output format for all its types. In this way, applications can exchange data between them using a standardized exchange format. The WKT format is human-readable while the WKB format is more compact and more efficient than the WKT format. The WKB format can be output either as a binary string or as a character string encoded in hexadecimal ASCII.

The set types represent an ordered set of distinct values. A set must contain at least one element. Examples of set values are as follows:

SELECT tstzset '{2001-01-01 08:00:00, 2001-01-03 09:30:00}';
-- Singleton set
SELECT textset '{"highway"}';
-- Erroneous set: unordered elements
SELECT floatset '{3.5, 1.2}';
-- Erroneous set: duplicate elements
SELECT geomset '{"Point(1 1)", "Point(1 1)"}';

Notice that the elements of the sets textset, geomset, geogset, and npointset must be enclosed between double quotes. Notice also that geometries and geographies follow the order defined in PostGIS.

A value of a unit span type has two bounds, the lower bound and the upper bound, which are values of the underlying base type. For example, a value of the tstzspan type has two bounds, which are timestamptz values. The bounds can be inclusive or exclusive. An inclusive bound means that the boundary instant is included in the span, while an exclusive bound means that the boundary instant is not included in the span. In the text form of a span value, inclusive and exclusive lower bounds are represented, respectively, by “[” and “(”. Likewise, inclusive and exclusive upper bounds are represented, respectively, by “]” and “)”. In a span value, the lower bound must be less than or equal to the upper bound. A span value with equal and inclusive bounds is called an instantaneous span and corresponds to a base type value. Examples of span values are as follows:

SELECT intspan '[1, 3)';
SELECT floatspan '[1.5, 3.5]';
SELECT tstzspan '[2001-01-01 08:00:00, 2001-01-03 09:30:00)';
-- Instant spans
SELECT intspan '[1, 1]';
SELECT floatspan '[1.5, 1.5]';
SELECT tstzspan '[2001-01-01 08:00:00, 2001-01-01 08:00:00]';
-- Erroneous span: invalid bounds
SELECT tstzspan '[2001-01-01 08:10:00, 2001-01-01 08:00:00]';
-- Erroneous span: empty span
SELECT tstzspan '[2001-01-01 08:00:00, 2001-01-01 08:00:00)';

Values of intspan, bigintspan, and datespan are converted into normal form so that equivalent values have identical representations. In the canonical representation of these types, the lower bound is inclusive and the upper bound is exclusive as shown in the following examples:

SELECT intspan '[1, 1]';
-- [1, 2)
SELECT bigintspan '(1, 3]';
--[2, 4)
SELECT datespan '[2001-01-01, 2001-01-03]';
-- [2001-01-01, 2001-01-04)

A value of a span set type represents an ordered set of disjoint span values. A span set value must contain at least one element, in which case it corresponds to a single span value. Examples of span set values are as follows:

SELECT floatspanset '{[8.1, 8.5],[9.2, 9.4]}';
-- Singleton spanset
SELECT tstzspanset '{[2001-01-01 08:00:00, 2001-01-01 08:10:00]}';
-- Erroneous spanset: unordered elements
SELECT intspanset '{[3,4],[1,2]}';
-- Erroneous spanset: overlapping elements
SELECT tstzspanset '{[2001-01-01 08:00:00, 2001-01-01 08:10:00],
  [2001-01-01 08:05:00, 2001-01-01 08:15:00]}';

Values of the span set types are converted into normal form so that equivalent values have identical representations. For this, consecutive adjacent span values are merged when possible. Examples of transformation into normal form are as follows:

SELECT intspanset '{[1,2],[3,4]}';
-- {[1, 5)}
SELECT floatspanset '{[1.5,2.5],(2.5,4.5]}';
-- {[1.5, 4.5]}
SELECT tstzspanset '{[2001-01-01 08:00:00, 2001-01-01 08:10:00),
  [2001-01-01 08:10:00, 2001-01-01 08:10:00], (2001-01-01 08:10:00, 2001-01-01 08:20:00]}';
-- {[2001-01-01 08:00:00+00,2001-01-01 08:20:00+00]}

We give next the functions for input and output of set and span types in Well-Known Text and Well-Known Binary format. The default output format of all set and span types is the Well-Known Text format. The function asText given next enables to determine the output of floating point values.

  • Return the Well-Known Text (WKT) representation

    asText({floatset,floatspans},maxdecdigits=15) → text

    The maxdecdigits argument can be used to set the maximum number of decimal places in the output of floating point values (default 15).

    SELECT asText(floatset '{1.123456789,2.123456789}', 3);
    -- {1.123, 2.123}
    SELECT asText(floatspanset '{[1.55,2.55],[4,5]}',0);
    -- {[2, 3], [4, 5]}
    
  • Return the Well-Known Binary (WKB) representation

    asBinary({set,spans},endian text='') → bytea

    The result is encoded using either the little-endian (NDR) or the big-endian (XDR) encoding. If no encoding is specified, then the encoding of the machine is used.

    SELECT asBinary(dateset '{2001-01-01, 2001-01-03}');
    -- \x01050001020000006e01000070010000
    SELECT asBinary(intspan '[1, 3)');
    -- \x011300010100000003000000
    SELECT asBinary(floatspanset '{[1, 2], [4, 5]}', 'XDR');
    -- \x00000e00000002033ff000000000000040000000000000000340100000000000004014000000000000
    
  • Return the Hexadecimal Well-Known Binary (HexWKB) representation as text

    asHexWKB({set,spans},endian text='') → text

    The result is encoded using either the little-endian (NDR) or the big-endian (XDR) encoding. If no encoding is specified, then the encoding of the machine is used.

    SELECT asHexWKB(dateset '{2001-01-01, 2001-01-03}');
    -- 01050001020000006E01000070010000
    SELECT asHexWKB(intspan '[1, 3)');
    -- 011300010100000003000000
    SELECT asHexWKB(floatspanset '{[1, 2], [4, 5]}', 'XDR');
    -- 00000E00000002033FF000000000000040000000000000000340100000000000004014000000000000
    
  • Input from a Well-Known Binary (WKB) representation

    settypeFromBinary(bytea) → set

    spantypeFromBinary(bytea) → span

    spansettypeFromBinary(bytea) → spanset

    There is one function per set or span (set) type, the name of the function has as prefix the name of the type

    SELECT datesetFromBinary('\x01050001020000006e01000070010000');
    -- {2001-01-01, 2001-01-03}
    SELECT intspanFromBinary('\x011300010100000003000000');
    -- [1, 3)
    SELECT floatspansetFromBinary(
      '\x00000e00000002033ff000000000000040000000000000000340100000000000004014000000000000');
    -- {[1, 2], [4, 5]}
    
  • Input from an Hexadecimal Well-Known Binary (HexWKB) representation

    settypeFromHexWKB(text) → set

    spantypeFromHexWKB(text) → span

    spansettypeFromHexWKB(text) → spanset

    There is one function per set or span (set) type, the name of the function has as prefix the name of the type.

    SELECT datesetFromHexWKB('01050001020000006E01000070010000');
    -- {2001-01-01, 2001-01-03}
    SELECT intspanFromHexWKB('011300010100000003000000');
    -- [1, 3)
    SELECT floatspanFromHexWKB('01060001000000000000F83F0000000000000440');
    -- [1.5, 2.5)
    SELECT floatspansetFromHexWKB(
      '00000E00000002033FF000000000000040000000000000000340100000000000004014000000000000');
    -- {[1, 2], [4, 5]}