I would like to create check constraint on the HSTORE field that contains data in a following format:
{
1 => 2020-03-01, 2 => 2020-03-07, etc, etc, etc,
}
Where key is always a positive digit and value is a date.
Problem here that I want to extract keys ( by akeys), and then somehow get the biggest key and compare it with number_of_episodes(positive integer).
But it says that I can’t use arrays in check constraint.
Question is -is it possible to extract somehow biggest key from HSTORE as an integer and use it in check constraint afterwards?
Thank you.
alter table archives_seasonmodel
add constraint test
check (max((unnest(akeys(episodes))) <= number_of_episodes ))
This doesn’t work.
This works for me in PostgreSQL 10:
# create table tvseries
(number_of_episodes int,
episodes hstore,
check (number_of_episodes >= all (akeys(episodes)::int[]))
);
CREATE TABLE
# insert into tvseries values (2, '1=>"a", 2=>"b"');
INSERT 0 1
# insert into tvseries values (1, '1=>"a", 2=>"b"');
ERROR: new row for relation "tvseries" violates check constraint "tvseries_check"
DETAIL: Failing row contains (1, "1"=>"a", "2"=>"b").
# insert into tvseries values (2, '1=>"a"');
INSERT 0 1
# select * from tvseries;
number_of_episodes | episodes
--------------------+--------------------
2 | "1"=>"a", "2"=>"b"
2 | "1"=>"a"
(2 rows)
This answer outlines a couple ways you can go about this. The first is to use the intarray extension and it's sort_desc function, but I think the better approach here is to use a custom function.
testdb=# create extension hstore;
CREATE EXTENSION
testdb=# create table tt0(h hstore, max_n bigint);
CREATE TABLE
testdb=# CREATE OR REPLACE FUNCTION array_greatest(anyarray)
RETURNS anyelement LANGUAGE SQL AS $$
SELECT max(x) FROM unnest($1) as x;
$$;
CREATE FUNCTION
testdb=# alter table tt0 add check((array_greatest(akeys(h)::integer[]))<=max_n);
ALTER TABLE
testdb=# insert into tt0 select hstore(ARRAY[['1','asdf'],['3','fdsa']]), 2;
ERROR: new row for relation "tt0" violates check constraint "tt0_check"
DETAIL: Failing row contains ("1"=>"asdf", "3"=>"fdsa", 2).
testdb=# insert into tt0 select hstore(ARRAY[['1','asdf'],['2','fdsa']]), 2;
INSERT 0 1
testdb=# select * from tt0
testdb-# ;
h | max_n
--------------------------+-------
"1"=>"asdf", "2"=>"fdsa" | 2
(1 row)
testdb=# \d tt0
Table "public.tt0"
Column | Type | Collation | Nullable | Default
--------+--------+-----------+----------+---------
h | hstore | | |
max_n | bigint | | |
Check constraints:
"tt0_check" CHECK (array_greatest(akeys(h)::integer[]) <= max_n)