ignore_contradictory_where_clauses_at_partprune_step.patch

application/octet-stream

Filename: ignore_contradictory_where_clauses_at_partprune_step.patch
Type: application/octet-stream
Part: 0
Message: RE: Problem with default partition pruning

Patch

Format: unified
File+
src/backend/partitioning/partprune.c 24 19
diff --git a/src/backend/partitioning/partprune.c b/src/backend/partitioning/partprune.c
index 5cd740a..c45cd48 100644
--- a/src/backend/partitioning/partprune.c
+++ b/src/backend/partitioning/partprune.c
@@ -850,32 +850,13 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context,
 						 * an arg.  To indicate that to the pruning code, we
 						 * must construct a dummy PartitionPruneStepCombine
 						 * whose source_stepids is set to an empty List.
-						 * However, if we can prove using constraint exclusion
-						 * that the clause refutes the table's partition
-						 * constraint (if it's sub-partitioned), we need not
-						 * bother with that.  That is, we effectively ignore
-						 * this OR arm.
 						 */
-						List	   *partconstr = rel->partition_qual;
 						PartitionPruneStep *orstep;
 
 						/* Just ignore this argument. */
 						if (arg_contradictory)
 							continue;
 
-						if (partconstr)
-						{
-							partconstr = (List *)
-								expression_planner((Expr *) partconstr);
-							if (rel->relid != 1)
-								ChangeVarNodes((Node *) partconstr, 1,
-											   rel->relid, 0);
-							if (predicate_refuted_by(partconstr,
-													 list_make1(arg),
-													 false))
-								continue;
-						}
-
 						orstep = gen_prune_step_combine(context, NIL,
 														PARTPRUNE_COMBINE_UNION);
 						arg_stepids = lappend_int(arg_stepids, orstep->step_id);
@@ -951,6 +932,7 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context,
 			bool		clause_is_not_null = false;
 			PartClauseInfo *pc = NULL;
 			List	   *clause_steps = NIL;
+			List	   *partconstr = rel->partition_qual;
 
 			switch (match_clause_to_partition_key(rel, context,
 												  clause, partkey, i,
@@ -961,6 +943,29 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context,
 					Assert(pc != NULL);
 
 					/*
+					 * If this clause can be proved false for this partition,
+					 * given its partition constraint, we can ignore it, 
+					 * that is not try to pass it to the pruning code.  
+					 * We should do that especially to avoid pruning code 
+					 * wrongly failing to prune the default partition.
+					 */
+					if (partconstr)
+					{
+						partconstr = (List *)
+							expression_planner((Expr *) partconstr);
+						if (rel->relid != 1)
+							ChangeVarNodes((Node *) partconstr, 1,
+										   rel->relid, 0);
+						if (predicate_refuted_by(partconstr,
+												 list_make1(clause),
+												 false))
+						{
+							*contradictory = true;
+							return NIL;
+						}
+					}
+					
+					/*
 					 * Since we only allow strict operators, check for any
 					 * contradicting IS NULL.
 					 */