Re: BUG #4085: No implicit cast after coalesce

Lists: pgsql-bugs
From: "Jeff Dwyer" <jdwyer(at)patientslikeme(dot)com>
To: pgsql-bugs(at)postgresql(dot)org
Subject: BUG #4085: No implicit cast after coalesce
Date: 2008-04-02 21:04:22
Message-ID: 200804022104.m32L4MtG077191@wwwmaster.postgresql.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs


The following bug has been logged online:

Bug reference: 4085
Logged by: Jeff Dwyer
Email address: jdwyer(at)patientslikeme(dot)com
PostgreSQL version: 8.3.1
Operating system: Mac OS X
Description: No implicit cast after coalesce
Details:

This works fine:
select 1 where current_date between '1900-3-3' and '1900-2-2';
This doesn't:
select 1 where current_date between coalesce(null,current_date) and
coalesce(null, '1900-1-2');

This fix works:
select 1 where current_date between coalesce(null,current_date) and
coalesce(null, date('1900-1-2'));

This seems like a bug to me. Why should an explicit cast be necessary after
a coalesce? This broke code that worked in 8.1.

Thanks,
-Jeff


From: Peter Eisentraut <peter_e(at)gmx(dot)net>
To: pgsql-bugs(at)postgresql(dot)org
Cc: "Jeff Dwyer" <jdwyer(at)patientslikeme(dot)com>
Subject: Re: BUG #4085: No implicit cast after coalesce
Date: 2008-04-02 22:24:17
Message-ID: 200804030024.18263.peter_e@gmx.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs

Jeff Dwyer wrote:
> This works fine:
> select 1 where current_date between '1900-3-3' and '1900-2-2';
> This doesn't:
> select 1 where current_date between coalesce(null,current_date) and
> coalesce(null, '1900-1-2');
>
> This fix works:
> select 1 where current_date between coalesce(null,current_date) and
> coalesce(null, date('1900-1-2'));
>
>
> This seems like a bug to me. Why should an explicit cast be necessary after
> a coalesce?

Because coalesce(null, '1900-1-2') has no other type information attached, so
it would have picked text by default as result type, and that then clashes
with the result type of coalesce(null,current_date), which can be derived to
be date. This is a robustness improvement: 8.2 and earlier would silently
accept coalesce(null, 'abc') and apply text-semantics comparison.


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Peter Eisentraut <peter_e(at)gmx(dot)net>
Cc: pgsql-bugs(at)postgresql(dot)org, "Jeff Dwyer" <jdwyer(at)patientslikeme(dot)com>
Subject: Re: BUG #4085: No implicit cast after coalesce
Date: 2008-04-02 23:15:56
Message-ID: 18140.1207178156@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs

Peter Eisentraut <peter_e(at)gmx(dot)net> writes:
> Jeff Dwyer wrote:
>> This seems like a bug to me. Why should an explicit cast be necessary after
>> a coalesce?

> Because coalesce(null, '1900-1-2') has no other type information attached, so
> it would have picked text by default as result type, and that then clashes
> with the result type of coalesce(null,current_date), which can be derived to
> be date. This is a robustness improvement: 8.2 and earlier would silently
> accept coalesce(null, 'abc') and apply text-semantics comparison.

Yes. The query "worked" in pre-8.3 only for rather small values of
"work": if you had been using a non-ISO datestyle the comparisons would
in fact have come out wrong. Also, it being a textual rather than date
comparison, any index on the date column being compared to wouldn't have
been used.

regards, tom lane


From: Jeff Dwyer <jdwyer(at)patientslikeme(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Peter Eisentraut <peter_e(at)gmx(dot)net>, pgsql-bugs(at)postgresql(dot)org
Subject: Re: BUG #4085: No implicit cast after coalesce
Date: 2008-04-03 13:15:17
Message-ID: 095B69F3-3E11-4458-95FB-487FE3B62EC8@patientslikeme.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs

OK, worksforme. I guess I still find it odd, but I much prefer
explicitness & robustness to small values of 'work'.

Thanks for the prompt response.

-Jeff

On Apr 2, 2008, at 7:15 PM, Tom Lane wrote:

> Peter Eisentraut <peter_e(at)gmx(dot)net> writes:
>> Jeff Dwyer wrote:
>>> This seems like a bug to me. Why should an explicit cast be
>>> necessary after
>>> a coalesce?
>
>> Because coalesce(null, '1900-1-2') has no other type information
>> attached, so
>> it would have picked text by default as result type, and that then
>> clashes
>> with the result type of coalesce(null,current_date), which can be
>> derived to
>> be date. This is a robustness improvement: 8.2 and earlier would
>> silently
>> accept coalesce(null, 'abc') and apply text-semantics comparison.
>
> Yes. The query "worked" in pre-8.3 only for rather small values of
> "work": if you had been using a non-ISO datestyle the comparisons
> would
> in fact have come out wrong. Also, it being a textual rather than
> date
> comparison, any index on the date column being compared to wouldn't
> have
> been used.
>
> regards, tom lane


From: Sam Mason <sam(at)samason(dot)me(dot)uk>
To: pgsql-bugs(at)postgresql(dot)org
Subject: Re: BUG #4085: No implicit cast after coalesce
Date: 2008-04-03 18:57:20
Message-ID: 20080403185720.GL6870@frubble.xen.chris-lamb.co.uk
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-bugs

On Thu, Apr 03, 2008 at 12:24:17AM +0200, Peter Eisentraut wrote:
> Jeff Dwyer wrote:
> > This works fine:
> > select 1 where current_date between '1900-3-3' and '1900-2-2';
> > This doesn't:
> > select 1 where current_date between coalesce(null,current_date) and
> > coalesce(null, '1900-1-2');
> >
> > This fix works:
> > select 1 where current_date between coalesce(null,current_date) and
> > coalesce(null, date('1900-1-2'));
> >
> > This seems like a bug to me. Why should an explicit cast be necessary after
> > a coalesce?
>
> Because coalesce(null, '1900-1-2') has no other type information attached, so
> it would have picked text by default as result type, and that then clashes
> with the result type of coalesce(null,current_date), which can be derived to
> be date. This is a robustness improvement: 8.2 and earlier would silently
> accept coalesce(null, 'abc') and apply text-semantics comparison.

The types look as though they could be interpreted unambiguously and
correctly very easily. Parametric polymorphism and some basic type
inference would easily be able to resolve this. BETWEEN would have
the following type (very informally presented; lower case characters
stand for type variables, Titlecase for type names, UPPERCASE for
identifiers!):

Boolean (t BETWEEN t AND t)

i.e. when BETWEEN is called all the types must be the same. COALESCE is
also parametrised over a single type:

t COALESCE(t,t)

NULLs could be encoded in the type system in many ways as long it had a
polymorphic type. The type system should realise that "current_date"
is of type Date and because NULL is polymorphic the COALESCEs would
unify, both returning values of type Date, which would in turn unify
with the BETWEEN operator resulting in a value of BOOLEAN type, which is
exactly what the WHERE clause expects.

This sort of type inference has been known (and extensively studied)
for about 50 years now, it always surprises me how little it's known
outside the functional programming community (ML and Haskell being the
old guard). Apparently, according to the fountain of wisdom that is
Wikipedia, It's finally starting to break into very mainstream languages
like the next versions of VB9 and C#3.

Moving an existing implementation over to a new type system is an
entirely non-trivial matter though!

Sam