From: | Amit Langote <Langote_Amit_f8(at)lab(dot)ntt(dot)co(dot)jp> |
---|---|
To: | Kyotaro HORIGUCHI <horiguchi(dot)kyotaro(at)lab(dot)ntt(dot)co(dot)jp>, robertmhaas(at)gmail(dot)com |
Cc: | pgsql-hackers(at)postgresql(dot)org |
Subject: | Re: default range partition and constraint exclusion |
Date: | 2017-11-28 11:44:47 |
Message-ID: | 72dc9717-6ba2-dc41-ee92-462248977321@lab.ntt.co.jp |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
Horiguchi-san, thanks for the clarifying comment.
On 2017/11/27 18:04, Kyotaro HORIGUCHI wrote:
> At Fri, 24 Nov 2017 10:49:07 -0500, Robert Haas wrote
>> OK, so I am still confused about whether the constraint is wrong or
>> the constraint exclusion logic is wrong. One of them, at least, has
>> to be wrong, and we have to fix whichever one is wrong. Fixing broken
>> constraint exclusion logic by hacking up the constraint, or conversely
>> fixing a broken constraint by hacking up the constraint exclusion
>> logic, wouldn't be right.
>>
>> I think my last email was confused: I thought that the (2, null) tuple
>> was ending up in mc2p2, but it's really ending up in mc2p_default,
>> whose constraint currently looks like this:
>>
>> NOT (
>> ((a < 1) OR ((a = 1) AND (b < 1)))
>> OR
>> ((a > 1) OR ((a = 1) AND (b >= 1)))
>> )
>>
>> Now where exactly is constraint exclusion going wrong here? a = 2
>> refutes a < 1 and a = 1, which means that (a < 1) OR ((a = 1) AND (b <
>> 1)) must be false and that (a = 1) AND (b >= 1) must also be false.
>> But (a > 1) could be either true or null, which means (a > 1) OR ((a =
>
> a > 1 is true when a = 2, so the second term is true?
Yes.
>> 1) AND (b >= 1)) can be true or null, which means the whole thing can
>> be false or null, which means that it is not refuted by a = 2. It
>
> Then the whole thing is false.
Yes, too.
>> should be possible to dig down in there step by step and figure out
>> where the wheels are coming off -- have you tried to do that?
>
> | select NOT (
> | ((a < 1) OR ((a = 1) AND (b < 1)))
> | OR
> | ((a > 1) OR ((a = 1) AND (b >= 1)))
> | )
> | from (values (2::int, null::int)) as t(a, b);
> | ?column?
> | ----------
> | f
>
> The problem here I think is that get_qual_for_range() for default
> partition returns an inconsistent qual with what partition
> get_partition_for_tuple chooses for keys containing nulls. It
> chooses default partition if any of the key values is null,
> without referring the constraint expression.
Right.
> The current behavior is apparently odd.
>
> | select pg_get_partition_constraintdef('mc2p2'::regclass);
> | pg_get_partition_constraintdef
> | ----------------------------------------------------------------------------
> | ((a IS NOT NULL) AND (b IS NOT NULL) AND ((a > 1) OR ((a = 1) AND (b >= 1))))
>
>
> | select pg_get_partition_constraintdef('mc2p_default'::regclass);
> | pg_get_partition_constraintdef
> |
> | ---------------------------------------------------------------------------
> | (NOT (((a < 1) OR ((a = 1) AND (b < 1))) OR ((a > 1) OR ((a = 1) AND (b >= 1)))))
>
>
> | insert into mc2p2 values (2);
> | ERROR: new row for relation "mc2p2" violates partition constraint
> | DETAIL: Failing row contains (2, null).
>
> This is the correct behavior.
Yes, a non-default range partition does not accept nulls in any of the
partition keys.
> | insert into mc2p_default values (2);
> | ERROR: new row for relation "mc2p_default" violates partition constraint
> | DETAIL: Failing row contains (2, null).
>
> This is the correct behavior in terms of constraint, but
> incorrect in terms of partition routing.
>
> But interestingly, the following *works*, in a way contradicting
> to the constraint.
>
> | insert into mc2p values (2);
> | INSERT 0 1
> |
> | select * from mc2p_default;
> | a | b
> | ---+---
> | 2 |
> | (1 row)
That is, the default partition's constraint, as currently generated, is wrong.
> After applying the patch upthread, get_qual_for_range() returns
> the consistent qual and "insert into mc2p_default values (2)" is
> accepted correctly and everything become consistent.
Thanks for testing.
Thanks,
Amit
From | Date | Subject | |
---|---|---|---|
Next Message | Jan Michálek | 2017-11-28 12:20:51 | Re: [HACKERS] Other formats in pset like markdown, rst, mediawiki |
Previous Message | Kyotaro HORIGUCHI | 2017-11-28 11:39:15 | Re: [HACKERS] path toward faster partition pruning |