Skip to content

Instantly share code, notes, and snippets.

@monacoremo
Created January 9, 2020 19:50
Show Gist options
  • Save monacoremo/3995ed6b29a98639a0ac1a6111b45aa5 to your computer and use it in GitHub Desktop.
Save monacoremo/3995ed6b29a98639a0ac1a6111b45aa5 to your computer and use it in GitHub Desktop.
Sum types / ADTs in Postgres
/* Experiment on how to represent sum types in Postgres.
In this example, we try to represent the following sum type:
type Animal
= Dog { name : String, age : Integer }
| Bird { song : String }
*/
create type animal_type
as enum
( 'dog'
, 'bird'
);
create table animals
( animal_id serial primary key
, animal_type animal_type not null
, dog_name text
check ((animal_type = 'dog') = (dog_name is not null))
, dog_age integer
check ((animal_type = 'dog') = (dog_age is not null))
, bird_song text
check ((animal_type = 'bird') = (bird_song is not null))
);
insert into animals(animal_type, bird_song) values ('bird', 'lalala');
insert into animals(animal_type, dog_name, dog_age) values ('dog', 'rex', 7);
/* The following examples would fail the check constraints:
Value from another constructor:
insert into animals(animal_type, bird_song, dog_name)
values ('bird', 'lalala', 'rex');
Not all fields set for the constructor:
insert into animals(animal_type, dog_name) values ('dog', 'rex');
*/
select * from animals;
@erebe
Copy link

erebe commented Oct 26, 2022

Thanks :)
didn't know that check ((animal_type = 'dog') = (dog_name is not null)) was possible

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment