Обсуждение: Best way to prevent overlapping dates

Поиск
Список
Период
Сортировка

Best way to prevent overlapping dates

От
"Andrus"
Дата:
I need to disable rows with overlapping dates in 8.1+
I created the following trigger procedure for this.

Is this best way ?
Will it prevent overlapping rows in all cases ?

Andrus.

create table puhkus (reanr serial primary key,   palgus date, plopp date);

CREATE OR REPLACE FUNCTION puhkus_sequenced_pkey() RETURNS trigger AS $$

DECLARE
   OverlappingRow INTEGER;

BEGIN
  SELECT reanr
  INTO OverlappingRow
FROM puhkus
WHERE puhkus.reanr<>NEW.reanr AND doverlaps( puhkus.palgus, puhkus.plopp,
NEW.palgus, NEW.plopp );

IF found THEN
  RAISE EXCEPTION 'Changed row % overlaps with existing row %', NEW.reanr,
OverLappingRow ;
  END IF;
RETURN NEW;
END;

$$ LANGUAGE plpgsql;

CREATE TRIGGER puhkus_sequenced_trigger BEFORE INSERT OR UPDATE ON puhkus
    FOR EACH ROW EXECUTE PROCEDURE puhkus_sequenced_pkey();

CREATE OR REPLACE FUNCTION public.doverlaps(date,
        date, date, date, out bool) IMMUTABLE AS
$_$
SELECT coalesce($1, date '0001-01-01')<=coalesce($4, date '9999-12-31') AND
     coalesce($2, date '9999-12-31')>=coalesce($3, date '0001-01-01' );
$_$ language sql;

CREATE OR REPLACE FUNCTION PUBLIC.GOMONTH(DATE, INTEGER, OUT DATE) IMMUTABLE
AS
$_$
SELECT ($1 + ($2 * '1 MONTH'::INTERVAL))::DATE;
$_$ LANGUAGE SQL;



I also tried code from SNODGRASS book
"Developing Time-Oriented Database Applications" but this causes error.

create table puhkus (palgus date, plopp date);

alter table puhkus add check
(NOT EXISTS ( SELECT *
FROM puhkus AS I1
WHERE 1 < (SELECT COUNT(*)
FROM puhkus AS I2
WHERE doverlaps(i1.palgus, i1.plopp, i2.palgus, i2.plopp)
) ));

but got error

ERROR: cannot use subquery in check constraint


Re: Best way to prevent overlapping dates

От
Michael Glaesemann
Дата:
On May 25, 2007, at 3:22 , Andrus wrote:

> CREATE TRIGGER puhkus_sequenced_trigger BEFORE INSERT OR UPDATE ON
> puhkus
>    FOR EACH ROW EXECUTE PROCEDURE puhkus_sequenced_pkey();

You can also use CREATE CONSTRAINT TRIGGER, which allows you to have
deferrable constraints. This is useful if statements within a
transaction may temporarily put the database in a state where it
violates the constraint: the constraint will be called at the end of
the transaction to make sure integrity is maintained.

http://www.postgresql.org/docs/8.2/interactive/sql-createconstraint.html

> create table puhkus (palgus date, plopp date);
>
> alter table puhkus add check
> (NOT EXISTS ( SELECT *
> FROM puhkus AS I1
> WHERE 1 < (SELECT COUNT(*)
> FROM puhkus AS I2
> WHERE doverlaps(i1.palgus, i1.plopp, i2.palgus, i2.plopp)
> ) ));
>
> but got error
>
> ERROR: cannot use subquery in check constraint

Right. As the error says, subqueries in CHECK constraints is not
implemented in PostgreSQL.


Michael Glaesemann
grzm seespotcode net



Re: Best way to prevent overlapping dates

От
Jeff Davis
Дата:
On Tue, 2007-05-29 at 10:59 -0500, Michael Glaesemann wrote:
> On May 25, 2007, at 3:22 , Andrus wrote:
>
> > CREATE TRIGGER puhkus_sequenced_trigger BEFORE INSERT OR UPDATE ON
> > puhkus
> >    FOR EACH ROW EXECUTE PROCEDURE puhkus_sequenced_pkey();
>
> You can also use CREATE CONSTRAINT TRIGGER, which allows you to have
> deferrable constraints. This is useful if statements within a
> transaction may temporarily put the database in a state where it
> violates the constraint: the constraint will be called at the end of
> the transaction to make sure integrity is maintained.
>
> http://www.postgresql.org/docs/8.2/interactive/sql-createconstraint.html
>

The docs say:

"CREATE CONSTRAINT TRIGGER is used within CREATE TABLE/ALTER TABLE and
by pg_dump to create the special triggers for referential integrity. It
is not intended for general use."

Is there harm in using constraint triggers outside of pg_dump? It seems
like deferrable constraints would be useful for many applications, but
the docs imply that it's a bad idea.

Regards,
    Jeff Davis

PS: Nice to meet you at PGCon. Hope you enjoyed it as much as I did!


Re: Best way to prevent overlapping dates

От
Tom Lane
Дата:
Jeff Davis <pgsql@j-davis.com> writes:
> Is there harm in using constraint triggers outside of pg_dump? It seems
> like deferrable constraints would be useful for many applications, but
> the docs imply that it's a bad idea.

It's un-deprecated as of 8.3.

            regards, tom lane

Re: Best way to prevent overlapping dates

От
Michael Glaesemann
Дата:
On May 29, 2007, at 12:41 , Jeff Davis wrote:

> "CREATE CONSTRAINT TRIGGER is used within CREATE TABLE/ALTER TABLE and
> by pg_dump to create the special triggers for referential
> integrity. It
> is not intended for general use."
>
> Is there harm in using constraint triggers outside of pg_dump? It
> seems
> like deferrable constraints would be useful for many applications, but
> the docs imply that it's a bad idea.

It's a PostgreSQL extension, so it's nonstandard, but my
understanding is that it's safe to use and there are no current plans
to make it go away. As long as you understand what you're doing, I
don't know of any problems with using CREATE CONSTRAINT TRIGGER. I've
asked similar questions in the past, so you might want to check the
archives.

Michael Glaesemann
grzm seespotcode net


> PS: Nice to meet you at PGCon. Hope you enjoyed it as much as I did!

It was good to meet you too, Jeff! Hope to see you at the next
gathering :)