Identity Type¶
How often do you run into a case like this?
```sql
create table users
(
id serial primary key
);
create table orders
(
id serial primary key,
user_id int not null references users (id)
);
select *
from users
inner join orders on orders.id = users.id
--- Why is this not getting the right results? \o/
--- ooooh... it should have been `on orders.user_id = users.id`
In a simple case, it is usually easy to spot the problem. However, real operational queries tend to get a lot more complicated, with a lot of visual noise in them, and spotting subtle errors is hard.
omni_id solves exacly this problem by introduce custom types that are comparable to themselves but not
other types (at least, not without explicit casting).
create table users
(
id user_id primary key default user_id_nextval()
);
create table orders
(
id order_id primary key default order_id_nextval(),
user_id user_id not null references users (id)
);
select *
from users
inner join orders on orders.id = users.id
-- ERROR: operator does not exist: order_id = user_id
-- ^^^ this just saved us precious time
Usage¶
This extension defines a single function identity_type. In its most primitive form, it will just take a name of a new
type
and will create a bigint-backed type:
create extension omni_id;
-- CREATE EXTENSION
select identity_type('user_id');
-- identity_type
-- ---------------
-- user_id
You can also select a different base integer type (smallint, int) and a few sequence-related options.
| Parameter | Type | Description |
|---|---|---|
| type | regtype | Base type. bigint by default. int and smallint permitted, as well as their aliases, and uuid |
| sequence | text | Sequence name. Equal to <type>_seq by default |
| create_sequence | boolean | Should sequence be created? True by default. Meaningless for uuid base type. |
| increment | bigint | Sequence increment. Default set to 1 |
| minvalue | bigint | Minimum value a sequence can generate. Default set to 1 |
| maxvalue | bigint | Maximum value a sequence can generate. Default set to the maximum of the underlying type |
| cache | bigint | Enables sequence numbers to be preallocated and stored in memory for faster access |
| cycle | boolean | Wrap around when the maxvalue or minvalue has been reached by an ascending or descending sequence respectively |
| constructor | text | Name of the constructor function |
| create_constructor | boolean | Should constructor be created? True by default |
| operator_schema | boolean | Schema to create operators in. public by default |
| nextval | regproc | If not null, use this function (no arguments, returning base type) to make <type>_nextval() |
identity_type will also create helper functions for the sequence: <type>_nextval(), <type>_currval()
and <type>_setval(<type>, bool)
Constructor¶
When it is necessary to construct an identity type value, one can use a constructor function like this: