On Fri, Sep 24, 2010 at 3:22 PM, Tom Lane <t...@sss.pgh.pa.us> wrote:

> Eric McKeeth <eldi...@gmail.com> writes:
> > why would I get the following error, since the period() function is in
> fact
> > declared as immutable?
>
> > test=# ALTER TABLE test3 ADD exclude using
> > gist(period(effect_date::timestamptz, expire_date::timestamptz) with &&
> );
> > ERROR:  functions in index expression must be marked IMMUTABLE
>
> period() might be immutable, but those casts from date to timestamptz
> are not, because they depend on the TimeZone parameter.
>
>                        regards, tom lane
>


Thanks for pointing out what I was overlooking. After a bit of further
investigation and testing it seems like the period type I found isn't going
to work without modification for my constraint, so I ended up with the
following to get the semantics I need:

alter table test3 add exclude using gist(
    box(
        point(
            case when effect_date = '-Infinity'::date
            then '-Infinity'::double precision
            else date_part('epoch'::text, effect_date)
            end,
            1
        ),
        point(
            case when expire_date = 'Infinity'::date
            then 'Infinity'::double precision
            else date_part('epoch', expire_date) - 1
            end,
            1
        )
    )
    with &&
);

This is ugly, but it does seem to enforce the constraint I need, of
non-overlapping dates where sharing an endpoint is not considered an
overlap. The case blocks are because the date_part bit always returns 0 for
infinite dates, which seemed a bit counter-intuitive. Any suggestions on how
I could improve on it?

Reply via email to