From: | Jeff Davis <pgsql(at)j-davis(dot)com> |
---|---|
To: | Mathieu De Zutter <mathieu(at)dezutter(dot)org> |
Cc: | pgsql-general(at)postgresql(dot)org |
Subject: | Re: Constraint exclusion issue |
Date: | 2010-01-17 21:43:59 |
Message-ID: | 1263764639.4235.153.camel@jdavis |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
On Sun, 2010-01-17 at 21:48 +0100, Mathieu De Zutter wrote:
> Can you explain this then:
> OK: select * from parent where (c,n) = ('b',0);
> NOT OK: select * from parent where (c,n)::y = ('b',0)::y;
Once you pass (c,n) into the cast, you get out something new that's
neither c nor n. It's as if you said "n1 + n2 = 5 + 3".
You are able to recognize that a record type is special, because you can
get the original components even after the transformation (unlike +,
which is irreversible). That allows you to transform the predicate
"(c,n)::y = ('b',0)::y" into an equivalent** form "c = 'b' AND n = 0",
which makes the contradiction with the CHECK constraint apparent.
The optimizer isn't that smart though. You're following a chain of
reasoning, and usually optimizers only go so far, because that can get
expensive, quickly.
** That's actually not really equivalent in the general case, anyway,
because of NULLs. "('a', NULL)::y = ('a', NULL)::y" is TRUE, but "'a' =
'a' AND NULL = NULL" is NULL. Interestingly, "('a', NULL) = ('a', NULL)"
is NULL as well (which might be a bug). So there isn't some nice
canonical form for "record = record" that will solve all of these
problems, which makes the optimization problem a lot harder.
Regards,
Jeff Davis
From | Date | Subject | |
---|---|---|---|
Next Message | Thomas Kellerer | 2010-01-17 22:37:52 | Re: Data Generators |
Previous Message | Mathieu De Zutter | 2010-01-17 20:48:15 | Re: Constraint exclusion issue |