Thread: is this a bug?

is this a bug?

From
Jeff Davis
Date:
create type y as (c char, n int); select ('a', NULL)::y = ('a', NULL)::y; -- TRUE  select ('a', NULL) = ('a', NULL);
--NULL
 

I would expect those to evaluate to the same thing.

Regards,Jeff Davis



Re: is this a bug?

From
Tom Lane
Date:
Jeff Davis <pgsql@j-davis.com> writes:
>   create type y as (c char, n int);
>   select ('a', NULL)::y = ('a', NULL)::y; -- TRUE 
>   select ('a', NULL) = ('a', NULL); -- NULL

> I would expect those to evaluate to the same thing.

The latter gets simplified to ('a' = 'a') AND (NULL = NULL).
The former doesn't --- it goes through record_eq, which treats
two nulls as equal.

The reason record_eq does that is that we have to have a total ordering
in order for record types to be indexable or sortable.

The former might be closer to the spec's expectations but I'm not
totally sure about it.
        regards, tom lane


Re: is this a bug?

From
Jeff Davis
Date:
On Sun, 2010-01-17 at 18:47 -0500, Tom Lane wrote:
> The former might be closer to the spec's expectations but I'm not
> totally sure about it.

I suppose that people using NULLs should expect the unexpected ;)

I don't have strong feelings about it, I just wanted to raise the issue.

Regards,Jeff Davis



Re: is this a bug?

From
"David E. Wheeler"
Date:
On Jan 17, 2010, at 3:47 PM, Tom Lane wrote:

>>  create type y as (c char, n int);
>>  select ('a', NULL)::y = ('a', NULL)::y; -- TRUE 
>>  select ('a', NULL) = ('a', NULL); -- NULL
> 
>> I would expect those to evaluate to the same thing.
> 
> The latter gets simplified to ('a' = 'a') AND (NULL = NULL).
> The former doesn't --- it goes through record_eq, which treats
> two nulls as equal.

Shouldn't this go through record_eq, then?

try=# select row('a', NULL) = row('a', NULL);?column? 
----------[null]

Best,

David


Re: is this a bug?

From
Tom Lane
Date:
"David E. Wheeler" <david@kineticode.com> writes:
> On Jan 17, 2010, at 3:47 PM, Tom Lane wrote:
>>> create type y as (c char, n int);
>>> select ('a', NULL)::y = ('a', NULL)::y; -- TRUE 
>>> select ('a', NULL) = ('a', NULL); -- NULL

>> The latter gets simplified to ('a' = 'a') AND (NULL = NULL).
>> The former doesn't --- it goes through record_eq, which treats
>> two nulls as equal.

> Shouldn't this go through record_eq, then?
> try=# select row('a', NULL) = row('a', NULL);

No, the ROW keyword is just noise.  It's the cast that is preventing the
expansion.  We could possibly change things so that it got expanded out
even with the cast, but on the whole I'm not sure that would be an
improvement.  It doesn't make things consistent, it just shifts the
boundary of inconsistency ...
        regards, tom lane