Re: Struggling with EXCLUDE USING gist
От | Adrian Klaver |
---|---|
Тема | Re: Struggling with EXCLUDE USING gist |
Дата | |
Msg-id | a691e9f9-df2b-34f1-a1a2-3b15763cac06@aklaver.com обсуждение исходный текст |
Ответ на | Struggling with EXCLUDE USING gist (Laura Smith <n5d9xq3ti233xiyif2vp@protonmail.ch>) |
Ответы |
Re: Struggling with EXCLUDE USING gist
|
Список | pgsql-general |
On 6/4/21 9:47 AM, Laura Smith wrote: > All the examples I've seen around the internet make this sound so easy. > > But I seem to be missing some important step because all I'm getting are messages such as "DETAIL: Key (t_val, t_version)=(def,[-infinity,infinity)) conflicts with existing key (t_val, t_version)=(def, [-infinity,"2021-06-04 16:56:08.008122+01"))." That would be correct: select '[-infinity,infinity)'::tstzrange && '[-infinity,"2021-06-04 16:56:08.008122+01")'::tstzrange; ?column? ---------- t The ranges overlap so they fail the exclusion constraint. > > I'm on PostgresSQL 12.5 if it makes any difference. > > > It is my understanding that: > (a) Postgres functions are one big transaction and so what I'm trying to do in my function code should work (i.e. updatetstzrange before updating something that would normally conflict). > (b) That infinity takes precedence over a defined point in time. The error I'm receiving - shown above - seems to counterthat perception though ? > > > Simplified example: > > CREATE TABLE test ( > t_val text not null, > t_version text unique not null default gen_random_uuid() , > t_range tstzrange not null default tstzrange('-infinity','infinity'), > EXCLUDE USING gist (t_val WITH=, t_range WITH &&) DEFERRABLE INITIALLY DEFERRED > ); > > CREATE VIEW test_v AS select * from test where t_range @> now(); > > INSERT INTO test(t_val) values('abc'); > > CREATE FUNCTION create_or_update_test(p_val text) RETURNS bool AS $$ > DECLARE > v_version text; > v_range tstzrange; > BEGIN > -- N.B. Have coded it this way round (not insert first) because "ON CONFLICT does not support deferrable unique constraints/exclusionconstraints as arbiters" > SELECT t_version,t_range into v_version,v_range from test_v where t_val='abc'; > IF NOT FOUND THEN > INSERT INTO test(t_val) values(p_val) > END IF; > -- If range conflict, adjust old and set new > UPDATE test set t_range=tstzrange(lower(v_range),now(),'[)') where t_version=v_version; > INSERT INTO test(t_val) values(p_val); > RETURN FOUND; > END; > $$ language plpgsql; > > > -- Adrian Klaver adrian.klaver@aklaver.com
В списке pgsql-general по дате отправления: