ClickHouse / ClickHouse/ClickHouse
User Defined Types (aka type aliases): draft, discussion
- Dominant language
- C++
- Stars
- 49.9k
- Forks
- 9k
- Avg merge
- 21h 32m
- Merged PRs (30d)
- 515
Description
User defined type is determined by:
- its name;
- underlying type for in-memory representation and binary serialization;
- expressions to convert from/to String;
- default expression;
- constraints on internal representation;
- constraints on input string;
- function overloads;
**Details**
1. User defined type can map to parametrized type with fixed parameters:
```
CREATE TYPE Point2D AS Tuple(Float64, Float64)
```
It can also be parametrized itself. Then parameters can be substituted to the parameters of the underlying type:
```
CREATE TYPE Point2D(T) AS Tuple(T, T)
```
```
CREATE TYPE DecimalPoint2D(N, M) AS Tuple(Decimal(N, M), Decimal(N, M))
```
It can map to a simple type as well.
2. Expressions to convert from/to String can be composed from SQL functions.
It's in question how it's better to specify these expressions:
- as expressions with predefined argument name (`value`, `string`), e.g. `OUTPUT IPv4NumToString(value)`
- as lambda functions, e.g. `OUTPUT x -> IPv4NumToString(x)`
If we choose the first variant, we can write constraints on binary or string representations in uniform way, e.g. `CONSTRAINT isValidUTF8(value)` (in this example, `value` is the internal representation).
3. There are multiple possible options to specify which functions will be available:
- we can enable all existing functions that work on underlying type to also work on aliased type; but in some cases it can be undesired;
- we can provide custom overloads for some functions (e.g. `length AS lengthUTF8(value)`) or define some functions with custom names (e.g. `area AS (value.x1 - value.x2) * (value.y1 - value.y2)`);
- it can be desired for some functions to work automatically by converting some of arguments from String, e.g. `equals(T, String)`
It is uncrear how to define all these options.
**Examples**
These examples are probably impractical, just to illustrate the idea:
```
CREATE TYPE IPv4 AS UInt32
INPUT IPv4StringToNum(string)
OUTPUT IPv4NumToString(value)
DEFAULT IPv4StringToNum('127.0.0.1')
```
```
CREATE TYPE UTF8String AS String
CONSTRAINT isValidUTF8(value)
FUNCTION length: value -> lengthUTF8(value)
FUNCTION substring: value, n, m -> substringUTF8(value, n, m)
```
**References**
https://www.postgresql.org/docs/9.5/sql-createtype.html
It's not required to do anything similar. But we need to look what is offered by other DBMS.
Contributor guide
Assessment
This issue has not been assessed yet.