Can't ri_KeysEqual() consider two nulls as equal?

Lists: pgsql-hackers
From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Stephan Szabo <sszabo(at)megazone(dot)bigpanda(dot)com>
Cc: pgsql-hackers(at)postgreSQL(dot)org
Subject: Can't ri_KeysEqual() consider two nulls as equal?
Date: 2007-04-17 21:16:27
Message-ID: 13541.1176844587@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

A recent discussion led me to the idea that FK triggers are fired
unnecessarily during an UPDATE if the foreign-key column(s) contain
any NULLs, because ri_KeysEqual() treats two nulls as unequal,
and therefore we conclude the row has changed when it has not.
I claim that both ri_KeysEqual() and ri_OneKeyEqual() could consider
two nulls to be equal. Furthermore it seems like ri_AllKeysUnequal()
should do so too; the case can't arise at the moment because the sole
caller already knows that one of the key sets contains no nulls, but
if this weren't so, the optimization would be actively wrong if we
concluded that two nulls were unequal.

Comments?

Also, I am wondering to what extent the ri_KeysEqual() calls in
ri_triggers.c are redundant, given that commands/trigger.c now has
the smarts to not even queue the trigger when those cases apply.

regards, tom lane


From: "Simon Riggs" <simon(at)2ndquadrant(dot)com>
To: "Tom Lane" <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: "Stephan Szabo" <sszabo(at)megazone(dot)bigpanda(dot)com>, <pgsql-hackers(at)postgreSQL(dot)org>
Subject: Re: Can't ri_KeysEqual() consider two nulls as equal?
Date: 2007-04-17 21:24:30
Message-ID: 1176845071.3635.548.camel@silverbirch.site
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On Tue, 2007-04-17 at 17:16 -0400, Tom Lane wrote:
> A recent discussion led me to the idea that FK triggers are fired
> unnecessarily during an UPDATE if the foreign-key column(s) contain
> any NULLs, because ri_KeysEqual() treats two nulls as unequal,
> and therefore we conclude the row has changed when it has not.

FK trigger *can be optimised away* is true. No need to have a discussion
about whether NULL == NULL, but the critical test is: if I overwrote it,
would you be able to tell? The answer is No, so away it goes.

> I claim that both ri_KeysEqual() and ri_OneKeyEqual() could consider
> two nulls to be equal. Furthermore it seems like ri_AllKeysUnequal()
> should do so too; the case can't arise at the moment because the sole
> caller already knows that one of the key sets contains no nulls, but
> if this weren't so, the optimization would be actively wrong if we
> concluded that two nulls were unequal.
>
> Comments?
>
> Also, I am wondering to what extent the ri_KeysEqual() calls in
> ri_triggers.c are redundant, given that commands/trigger.c now has
> the smarts to not even queue the trigger when those cases apply.

Would be good to document that behaviour in ri_triggers.c - I was
completely misled when I looked at the code a while back. Probably more
than one thing can go.

--
Simon Riggs
EnterpriseDB http://www.enterprisedb.com


From: Stephan Szabo <sszabo(at)megazone(dot)bigpanda(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: pgsql-hackers(at)postgreSQL(dot)org
Subject: Re: Can't ri_KeysEqual() consider two nulls as equal?
Date: 2007-04-17 23:27:06
Message-ID: 20070417155335.G38365@megazone.bigpanda.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On Tue, 17 Apr 2007, Tom Lane wrote:

> A recent discussion led me to the idea that FK triggers are fired
> unnecessarily during an UPDATE if the foreign-key column(s) contain
> any NULLs, because ri_KeysEqual() treats two nulls as unequal,
> and therefore we conclude the row has changed when it has not.
> I claim that both ri_KeysEqual() and ri_OneKeyEqual() could consider
> two nulls to be equal.

For ri_KeysEqual, I think so, since we actually aren't testing equality as
much as difference between the rows that might invalidate the constraint.
And, it does seem like with the code in trigger.c that the other checks in
the _upd functions in ri_triggers.c are redundant, but I'm vaguely afraid
I've forgotten something.

For ri_OneKeyEqual, I think like ri_AllKeysUnequal we know that the old
row doesn't have NULLs in the places it's currently called (although I
don't think this is commented). It seems like it should stay consistent
with ri_KeysEqual and that not putting the foo = NULL or foo = DEFAULT
seems better for the current calling cases besides.

> Furthermore it seems like ri_AllKeysUnequal() should do so too; the case
> can't arise at the moment because the sole caller already knows that one
> of the key sets contains no nulls, but if this weren't so, the
> optimization would be actively wrong if we concluded that two nulls were
> unequal.

Hmm, probably so, although at least this does appear to be commented at
the calling site to mention that it's depending on the fact that there are
no NULLs.


From: Richard Huxton <dev(at)archonet(dot)com>
To: Simon Riggs <simon(at)2ndquadrant(dot)com>
Cc: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Stephan Szabo <sszabo(at)megazone(dot)bigpanda(dot)com>, pgsql-hackers(at)postgreSQL(dot)org
Subject: Re: Can't ri_KeysEqual() consider two nulls as equal?
Date: 2007-04-18 08:11:57
Message-ID: 4625D2CD.1030200@archonet.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Simon Riggs wrote:
> On Tue, 2007-04-17 at 17:16 -0400, Tom Lane wrote:
>> A recent discussion led me to the idea that FK triggers are fired
>> unnecessarily during an UPDATE if the foreign-key column(s) contain
>> any NULLs, because ri_KeysEqual() treats two nulls as unequal,
>> and therefore we conclude the row has changed when it has not.
>
> FK trigger *can be optimised away* is true. No need to have a discussion
> about whether NULL == NULL, but the critical test is: if I overwrote it,
> would you be able to tell? The answer is No, so away it goes.

The test should perhaps be named "unchanged" rather than "equal".

--
Richard Huxton
Archonet Ltd


From: Stephan Szabo <sszabo(at)megazone(dot)bigpanda(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: pgsql-hackers(at)postgreSQL(dot)org
Subject: Re: Can't ri_KeysEqual() consider two nulls as equal?
Date: 2007-04-18 14:51:48
Message-ID: 20070418075029.E83588@megazone.bigpanda.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On Tue, 17 Apr 2007, Tom Lane wrote:

> A recent discussion led me to the idea that FK triggers are fired
> unnecessarily during an UPDATE if the foreign-key column(s) contain
> any NULLs, because ri_KeysEqual() treats two nulls as unequal,
> and therefore we conclude the row has changed when it has not.
> I claim that both ri_KeysEqual() and ri_OneKeyEqual() could consider
> two nulls to be equal. Furthermore it seems like ri_AllKeysUnequal()
> should do so too; the case can't arise at the moment because the sole
> caller already knows that one of the key sets contains no nulls, but
> if this weren't so, the optimization would be actively wrong if we
> concluded that two nulls were unequal.

Do you have any suggestions for alternate names? Keeping them using Equal
seems to be dangerous since people would likely expect it to act like
normal equality (with nulls being different).


From: David Fetter <david(at)fetter(dot)org>
To: Stephan Szabo <sszabo(at)megazone(dot)bigpanda(dot)com>
Cc: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, pgsql-hackers(at)postgreSQL(dot)org
Subject: Re: Can't ri_KeysEqual() consider two nulls as equal?
Date: 2007-04-18 18:22:51
Message-ID: 20070418182251.GF25896@fetter.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On Wed, Apr 18, 2007 at 07:51:48AM -0700, Stephan Szabo wrote:
> On Tue, 17 Apr 2007, Tom Lane wrote:
>
> > A recent discussion led me to the idea that FK triggers are fired
> > unnecessarily during an UPDATE if the foreign-key column(s)
> > contain any NULLs, because ri_KeysEqual() treats two nulls as
> > unequal, and therefore we conclude the row has changed when it has
> > not. I claim that both ri_KeysEqual() and ri_OneKeyEqual() could
> > consider two nulls to be equal. Furthermore it seems like
> > ri_AllKeysUnequal() should do so too; the case can't arise at the
> > moment because the sole caller already knows that one of the key
> > sets contains no nulls, but if this weren't so, the optimization
> > would be actively wrong if we concluded that two nulls were
> > unequal.
>
> Do you have any suggestions for alternate names? Keeping them using
> Equal seems to be dangerous since people would likely expect it to
> act like normal equality (with nulls being different).

How about NotDistinct as in SQL's IS NOT DISTINCT FROM ?

Cheers,
D
--
David Fetter <david(at)fetter(dot)org> http://fetter.org/
phone: +1 415 235 3778 AIM: dfetter666
Skype: davidfetter

Remember to vote!
Consider donating to PostgreSQL: http://www.postgresql.org/about/donate


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Stephan Szabo <sszabo(at)megazone(dot)bigpanda(dot)com>
Cc: pgsql-hackers(at)postgresql(dot)org
Subject: Re: Can't ri_KeysEqual() consider two nulls as equal?
Date: 2007-04-18 18:23:04
Message-ID: 6214.1176920584@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Stephan Szabo <sszabo(at)megazone(dot)bigpanda(dot)com> writes:
> On Tue, 17 Apr 2007, Tom Lane wrote:
>> I claim that both ri_KeysEqual() and ri_OneKeyEqual() could consider
>> two nulls to be equal.

> Do you have any suggestions for alternate names? Keeping them using Equal
> seems to be dangerous since people would likely expect it to act like
> normal equality (with nulls being different).

I think Richard's suggestion of KeysUnchanged would work fine.

regards, tom lane