Range, Multiranges and composite data types
The RANGE data type represents a contiguous intervals of values; it is defined by its lower and upper bound.
//It's compatible with previous postgreSQL data types
create table lista(
id serial primary key,
user_id int,
raggio int4range //int8range, numrange, daterange, tsrange, tstzrange
)
insert into lista(raggio) values ('[12, 44]');
insert into lista(raggio8) values ('[12, 44]');
insert into lista(raggionum) values ('[12.12 , 44]'); //num for decimals
insert into lista(raggiodata) values ('[2021-01-12, 2021-01-15]');
insert into lista(raggiots) values ('[2021-01-12 12:12:12, 2021-01-15 15:15:15]');
insert into lista(raggiotstz)values('[2021-01-12 12:12:12+02,2021-01-15 15:15:15+02]')By default, PostgreSQL ranges follow the [inclusive, exclusive) bounds format.
The lower() and upper() range functions retrieve their respective bounds. We can define infinite bounds using the 'infinity' string (compatible with tsrange, tstzrange, daterange, and numrange in both constructors and literals), NULL (in range constructors), or an empty bound (in range literals).
Arrays and ranges are both collections of data types, but they use different operators. Array operators like ANY or EXISTS operate on a series of values, while a range represents a single contiguous interval.
Range operations include:
The not-extend-to-the-left/right operators (&> and &<) return true depending on the starting and ending bound between two ranges.
The << and >> operators return true if the first range lies strictly at the left or right of the second. It compares the first range upper()/lower() with its opposite bound in the second
The adjacency operator (-|-) checks the boundary points between 2 ranges. It returns true if there is no gap or overlap between the bounds.
We can process math operations using:
The ranges sum (+), subtaction (-) and intersections (*) operations
The sum operator (+) returns a single range from multiple overlapping and contigous ranges.
Ranges are considered 'contiguous' based on their data type. For discrete data types, contiguity means there are no skipped units between their bounds, while continuous data types require its ranges to share the same boundary point, defined by their precision.
The subtract operation (-) returns the difference between two ranges. It returns error if the second range is contained within the first.
The intersection operator (*) returns a single range of values shared by the two input ranges.
Multirange data type syntax and operations
The multirange data type, introduced in PostgreSQL 14, allows for the representation of multiple non-contiguous ranges in a single value. It normalizes any overlapping or adjacent ranges within it and orders them by their lower bound.
We can apply range opration on multiranges:
The containment operator (@>) returns true if every value within the second element is completely contained by at least one range in the first multirange.
The overlap operator (&&) returns true if any range overlaps between the second and first value.
The strict-left operator (<<) returns true if all ranges in the first multirange lie entirely to the left of all ranges in the second.
The adjacent operator (-|-) returns true if any range in the first multirange is adjacent to any range in the second.
The addition operator (+) returns a new normalized multirange value.
The subtraction operation (-) returns a multirange containing parts of the first multirange that do not overlap with any ranges in the second.
The intersection operation (*) returns a multirange containing parts of the first multirange that do overlap with any ranges in the second.
Multirange on table column
The upper()/lower() function provides the upper/lower bound among all ranges within a multirange value.
The range_agg() function aggregates individual range values from multiple rows into a single multirange.
PostgreSQL composite custom data types
PostgreSQL data types include composite, enum, range and base.
The composite data type defines an object-like structure with multiple user-defined fields and their paired data type. Type casting during INSERT validates and adapts the data to the composite fields. If casting is not used, PostgreSQL validates each field individually and produces an error if the data does not match the field definitions.
We can SELECT a single composite value column by specifying its name within parentheses (). By default, SQL interprets dot notation (.) as extracting columns; the parentheses force SQL to evaluate the value as a composite, enabling direct access to its individual fields in your SELECT query.
We update a composite data type column by returning a new composite value that includes the appended element.
Collatation on composite fields and UNNEST FROM rules
We can define the collatable sorting rules for text-based fields within the composite data type.
We use the UNNEST function to access composite values from a table's array column. It returns each array element as a row in a new set. We then alias this set of composite values and their fields.
The FROM clause specifies the data sources in a query. It automatically performs a CROSS JOIN with the rows returned by the expressions, making the data available in the SELECT.
Composite data type arguments on PostgreSQL functions
A SQL function can accept a custom data type as its argument, allowing us to access and manipulate its fields during each invocation.
A composite data type shares its structure with a table, as both are ordered collections of named attributes with assigned data types.
Every CREATE TABLE statement implicitly defines a corresponding composite data type, which serves as the row structure for the instances stored in the table. The table provides persistent storage for this data, managed by its composite row type.
We can use a table's implicit composite data type as a custom argument in SQL functions, passing specific instances of users%ROWTYPE directly from a SELECT query.
Instead of passing a query result as a SQL function argument, we can process the query within a PL/pgSQL DO block.
The declared variable data type %ROWTYPE will hold the row structure of the instances returned by the SELECT ... INTO query. It contains the implicit composite value of the table row, allowing us to directly access and manipulate its fields.
Last updated