rendered paste bodyconstraints=# create table sessions (
loginName varchar(255) not null references users (loginname),
started_at timestamp not null,
ended_at timestamp,
check (ended_at is null or ended_at >= started_at),
sessionId bigint primary key);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "sessions_pkey" for table "sessions"
CREATE TABLE
constraints=# create unique index one_active_session on sessions (loginname) where ended_at is null;
CREATE INDEX
constraints=# insert into sessions (loginname, started_at, sessionid) values ('bob', now(), 1);
INSERT 0 1
constraints=# select * from sessions;
loginname | started_at | ended_at | sessionid
-----------+----------------------------+----------+-----------
bob | 2007-07-30 20:54:53.084682 | | 1
(1 row)
constraints=# insert into sessions (loginname, started_at, sessionid) values ('bob', now(), 2);
ERROR: duplicate key violates unique constraint "one_active_session"
constraints=# select * from sessions;
loginname | started_at | ended_at | sessionid
-----------+----------------------------+----------+-----------
bob | 2007-07-30 20:54:53.084682 | | 1
(1 row)
constraints=# update sessions set ended_at = now ()where sessionid=1;
UPDATE 1
constraints=# select * from sessions;
loginname | started_at | ended_at | sessionid
-----------+----------------------------+----------------------------+-----------
bob | 2007-07-30 20:54:53.084682 | 2007-07-30 21:02:41.031571 | 1
(1 row)
constraints=# insert into sessions (loginname, started_at, sessionid) values ('bob', now(), 2);
INSERT 0 1
constraints=# select * from sessions; loginname | started_at | ended_at | sessionid
-----------+----------------------------+----------------------------+-----------
bob | 2007-07-30 20:54:53.084682 | 2007-07-30 21:02:41.031571 | 1
bob | 2007-07-30 21:02:45.952053 | | 2
(2 rows)