1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-26 23:43:30 +03:00

Add null test to partition constraint for default range partitions.

Non-default range partitions have a constraint which include null
tests, and both default and non-default list partitions also have a
constraint which includes null tests, but for some reason this was
missed for default range partitions.  This could cause the partition
constraint to evaluate to false for rows that were (correctly) routed
to that partition by insert tuple routing, which could in turn
cause constraint exclusion to prune the default partition in cases
where it should not.

Amit Langote, reviewed by Kyotaro Horiguchi

Discussion: http://postgr.es/m/ba7aaeb1-4399-220e-70b4-62eade1522d0@lab.ntt.co.jp
This commit is contained in:
Robert Haas
2017-11-28 10:51:01 -05:00
parent 487a0c1518
commit 7b88d63a91
4 changed files with 56 additions and 25 deletions

View File

@@ -2134,12 +2134,29 @@ get_qual_for_range(Relation parent, PartitionBoundSpec *spec,
if (or_expr_args != NIL)
{
/* OR all the non-default partition constraints; then negate it */
result = lappend(result,
list_length(or_expr_args) > 1
? makeBoolExpr(OR_EXPR, or_expr_args, -1)
: linitial(or_expr_args));
result = list_make1(makeBoolExpr(NOT_EXPR, result, -1));
Expr *other_parts_constr;
/*
* Combine the constraints obtained for non-default partitions
* using OR. As requested, each of the OR's args doesn't include
* the NOT NULL test for partition keys (which is to avoid its
* useless repetition). Add the same now.
*/
other_parts_constr =
makeBoolExpr(AND_EXPR,
lappend(get_range_nulltest(key),
list_length(or_expr_args) > 1
? makeBoolExpr(OR_EXPR, or_expr_args,
-1)
: linitial(or_expr_args)),
-1);
/*
* Finally, the default partition contains everything *NOT*
* contained in the non-default partitions.
*/
result = list_make1(makeBoolExpr(NOT_EXPR,
list_make1(other_parts_constr), -1));
}
return result;