is this a bug?

Started by Jeff Davisalmost 16 years ago5 messages
#1Jeff Davis
pgsql@j-davis.com

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

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Jeff Davis (#1)
Re: is this a bug?

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

#3Jeff Davis
pgsql@j-davis.com
In reply to: Tom Lane (#2)
Re: is this a bug?

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

#4David E. Wheeler
david@kineticode.com
In reply to: Tom Lane (#2)
Re: is this a bug?

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

#5Tom Lane
tgl@sss.pgh.pa.us
In reply to: David E. Wheeler (#4)
Re: is this a bug?

"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