0006-Tweak-default-range-partition-s-constraint-a-little-v11.patch

text/plain

Filename: 0006-Tweak-default-range-partition-s-constraint-a-little-v11.patch
Type: text/plain
Part: 5
Message: Re: path toward faster partition pruning

Patch

Format: format-patch
Series: patch v11-0006
Subject: Tweak default range partition's constraint a little
File+
src/backend/catalog/partition.c 23 6
src/test/regress/expected/update.out 1 1
From 473dc4917eccb402b570961c92754ea342d9445d Mon Sep 17 00:00:00 2001
From: amit <amitlangote09@gmail.com>
Date: Tue, 31 Oct 2017 16:26:55 +0900
Subject: [PATCH 6/7] Tweak default range partition's constraint a little

When using as a predicate, it's useful for it explicitly say that
the default range partition might contain nulls, because non-default
range partitions can't.
---
 src/backend/catalog/partition.c      | 29 +++++++++++++++++++++++------
 src/test/regress/expected/update.out |  2 +-
 2 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c
index a2068ae422..fb973ef20c 100644
--- a/src/backend/catalog/partition.c
+++ b/src/backend/catalog/partition.c
@@ -2934,12 +2934,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;
diff --git a/src/test/regress/expected/update.out b/src/test/regress/expected/update.out
index cef70b1a1e..40217bdf9c 100644
--- a/src/test/regress/expected/update.out
+++ b/src/test/regress/expected/update.out
@@ -227,7 +227,7 @@ create table part_def partition of range_parted default;
  a      | text    |           |          |         | extended |              | 
  b      | integer |           |          |         | plain    |              | 
 Partition of: range_parted DEFAULT
-Partition constraint: (NOT (((a = 'a'::text) AND (b >= 1) AND (b < 10)) OR ((a = 'a'::text) AND (b >= 10) AND (b < 20)) OR ((a = 'b'::text) AND (b >= 1) AND (b < 10)) OR ((a = 'b'::text) AND (b >= 10) AND (b < 20))))
+Partition constraint: (NOT ((a IS NOT NULL) AND (b IS NOT NULL) AND (((a = 'a'::text) AND (b >= 1) AND (b < 10)) OR ((a = 'a'::text) AND (b >= 10) AND (b < 20)) OR ((a = 'b'::text) AND (b >= 1) AND (b < 10)) OR ((a = 'b'::text) AND (b >= 10) AND (b < 20)))))
 
 insert into range_parted values ('c', 9);
 -- ok
-- 
2.11.0