Обсуждение: Re: doverlaps() returns null
On May 20, 1:39 pm, "Andrus" <kobrule...@hot.ee> wrote:
> I need to check when two date intervals overlap.
> Some date interval values may be null.
>
> I created the following function but
>
> select doverlaps( null, null, null, null);
>
> returns null.
>
> How to fix this so that null values are allowed in parameters ?
>
> Andrus.
>
> -- returns true when date interval $1 .. $2 overlaps with $3 .. $4
> -- null values are allowed in parameters.
> CREATE OR REPLACE FUNCTION public.doverlaps(date,
> date, date, date, out bool) immutable AS
> $_$
> SELECT coalesce($1, timestamp '-infinity'::date) <=coalesce($4, timestamp
> 'infinity'::date) AND
> coalesce($2, timestamp 'infinity'::date)>=coalesce($3, timestamp
> '-infinity'::date);
> $_$ language sql;
You cannot cast +/- infinity timestamp to date, but you can cast date
to timestamp.
And what's wrong with OVERLAPS? e.g. :
CREATE OR REPLACE FUNCTION
PUBLIC.DOVERLAPS
(DATE, DATE, DATE, DATE, OUT BOOL)
IMMUTABLE AS
$_$
SELECT
(COALESCE($1::TIMESTAMP, TIMESTAMP '-INFINITY')
, COALESCE($2::TIMESTAMP, TIMESTAMP 'INFINITY')
)
OVERLAPS(
COALESCE($3::TIMESTAMP, TIMESTAMP '-INFINITY')
, COALESCE($4::TIMESTAMP, TIMESTAMP 'INFINITY'));
$_$ LANGUAGE SQL;
t=# SELECT doverlaps( NULL, NULL, NULL, NULL);
doverlaps
-----------
t
On May 21, 4:49 am, "Andrus" <kobrule...@hot.ee> wrote: > I'm using this for emplyment, vacation, illness etc. period calculation. > OVERLAPS produces invalid result in this case for DATE as discussed in other > thread. > > select doverlaps(date '2007-01-01',date '2007-01-02',date '2007-01-02',date > '2007-01-04'); > > returns FALSE > > When first period end and second period start dates are the the same, > doverlaps() must return TRUE. > > Andrus. OR $2 = $3
> You cannot cast +/- infinity timestamp to date
Thank you.
All my dates are in nearest centuries. So I fixed this by creating function
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;
is this best solution ?
> , but you can cast date to timestamp.
> And what's wrong with OVERLAPS? e.g. :
>
> CREATE OR REPLACE FUNCTION
> PUBLIC.DOVERLAPS
> (DATE, DATE, DATE, DATE, OUT BOOL)
> IMMUTABLE AS
> $_$
> SELECT
> (COALESCE($1::TIMESTAMP, TIMESTAMP '-INFINITY')
> , COALESCE($2::TIMESTAMP, TIMESTAMP 'INFINITY')
> )
> OVERLAPS(
> COALESCE($3::TIMESTAMP, TIMESTAMP '-INFINITY')
> , COALESCE($4::TIMESTAMP, TIMESTAMP 'INFINITY'));
> $_$ LANGUAGE SQL;
>
> t=# SELECT doverlaps( NULL, NULL, NULL, NULL);
> doverlaps
> -----------
> t
I'm using this for emplyment, vacation, illness etc. period calculation.
OVERLAPS produces invalid result in this case for DATE as discussed in other
thread.
select doverlaps(date '2007-01-01',date '2007-01-02',date '2007-01-02',date
'2007-01-04');
returns FALSE
When first period end and second period start dates are the the same,
doverlaps() must return TRUE.
Andrus.