diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c
index 0d9c774..57ea4a7 100644
--- a/src/backend/catalog/partition.c
+++ b/src/backend/catalog/partition.c
@@ -291,8 +291,8 @@ PG_FUNCTION_INFO_V1(satisfies_hash_partition);
 
 static Bitmapset *get_partitions_from_clauses_recurse(Relation relation,
 								int rt_index, List *clauses);
-static Bitmapset *get_partitions_from_ne_clauses(Relation relation,
-								List *ne_clauses);
+static Bitmapset *get_partitions_excluded_by(Relation relation,
+						   List *ne_clauses);
 static Bitmapset *get_partitions_from_or_clause_args(Relation relation,
 								int rt_index, List *or_clause_args);
 static bool classify_partition_bounding_keys(Relation relation, List *clauses,
@@ -1787,15 +1787,10 @@ get_partitions_from_clauses_recurse(Relation relation, int rt_index,
 	{
 		Bitmapset *ne_clause_parts;
 
-		ne_clause_parts = get_partitions_from_ne_clauses(relation, ne_clauses);
+		ne_clause_parts = get_partitions_excluded_by(relation, ne_clauses);
 
-		/*
-		 * Clauses in ne_clauses are in conjunction with the clauses that
-		 * selected the partitions contained in result, so combine the
-		 * partitions thus selected with those in result using set
-		 * intersection.
-		 */
-		result = bms_int_members(result, ne_clause_parts);
+		/* Remove any matched partitions */
+		result = bms_del_members(result, ne_clause_parts);
 		bms_free(ne_clause_parts);
 	}
 
@@ -1825,151 +1820,105 @@ get_partitions_from_clauses_recurse(Relation relation, int rt_index,
 		(0 == DatumGetInt32(FunctionCall2Coll(&partkey->partsupfunc[0],\
 											  partkey->partcollation[0],\
 											  (d1), (d2))))
-/*
- * Check if d is equal to some member of darray where equality is determined
- * by the partitioning comparison function.
- */
-static bool
-datum_in_array(PartitionKey partkey, Datum d, Datum *darray, int n)
-{
-	int		i;
-
-	if (darray == NULL || n == 0)
-		return false;
-
-	for (i = 0; i < n; i++)
-		if (partkey_datums_equal(d, darray[i]))
-			return true;
-
-	return false;
-}
-
-/*
- * count_partition_datums
- *
- * Returns the number of non-null datums allowed by a non-default list
- * partition with given index.
- */
-static int
-count_partition_datums(Relation rel, int index)
-{
-	PartitionBoundInfo boundinfo = RelationGetPartitionDesc(rel)->boundinfo;
-	int		i,
-			result = 0;
-
-	Assert(index != boundinfo->default_index);
-
-	/*
-	 * The answer is as many as the count of occurrence of the value index
-	 * in boundinfo->indexes[].
-	 */
-	for (i = 0; i < boundinfo->ndatums; i++)
-		if (index == boundinfo->indexes[i])
-			result += 1;
-
-	return result;
-}
 
 /*
- * get_partitions_from_ne_clauses
+ * get_partitions_excluded_by
  *
- * Return partitions of relation that satisfy all <> operator clauses in
- * ne_clauses.  Only ever called if relation is a list partitioned table.
+ * Returns a Bitmapset of partition indexes of any partition that can safely
+ * be removed due to 'ne_clauses' containing not-equal clauses for all
+ * possible values that the partition can contain.
  */
 static Bitmapset *
-get_partitions_from_ne_clauses(Relation relation, List *ne_clauses)
+get_partitions_excluded_by(Relation relation, List *ne_clauses)
 {
-	ListCell   *lc;
-	Bitmapset  *result,
-			   *excluded_parts;
-	PartitionKey partkey = RelationGetPartitionKey(relation);
-	PartitionDesc partdesc = RelationGetPartitionDesc(relation);
+	ListCell	   *lc;
+	Bitmapset	   *excluded_parts = NULL;
+	Bitmapset	   *foundoffsets = NULL;
+	PartitionKey	partkey = RelationGetPartitionKey(relation);
+	PartitionDesc	partdesc = RelationGetPartitionDesc(relation);
 	PartitionBoundInfo boundinfo = partdesc->boundinfo;
-	Datum  *exclude_datums;
-	int	   *count_excluded,
-			n_exclude_datums,
-			i;
+	PartitionBoundCmpArg arg;
+	int			   *datums_in_part;
+	int			   *datums_found;
+	int				i;
 
 	Assert(partkey->strategy == PARTITION_STRATEGY_LIST);
+	Assert(partkey->partnatts == 1);
 
-	/*
-	 * How this works:
-	 *
-	 * For each constant expression, we look up the partition that would
-	 * contain its value and mark the same as excluded partition.  After
-	 * doing the same for all clauses we'll have set of partitions that
-	 * are excluded.  For each excluded partition, check if there exist
-	 * values that it allows but are not specified in the clauses, if so
-	 * the partition won't actually be excluded.
-	 */
+	memset(&arg, 0, sizeof(arg));
 
-	/* De-duplicate constant values. */
-	exclude_datums = (Datum *) palloc0(list_length(ne_clauses) *
-									   sizeof(Datum));
-	n_exclude_datums = 0;
+	/* build a Bitmapset to record the offsets of all datums found */
 	foreach(lc, ne_clauses)
 	{
-		PartClause *pc = lfirst(lc);
+		PartClause *pc = (PartClause *) lfirst(lc);
 		Datum	datum;
 
-		if (partkey_datum_from_expr(partkey, 0, pc->constarg, &datum) &&
-			!datum_in_array(partkey, datum, exclude_datums, n_exclude_datums))
-			exclude_datums[n_exclude_datums++] = datum;
+		if (partkey_datum_from_expr(partkey, 0, pc->constarg, &datum))
+		{
+			int		offset;
+			bool	is_equal;
+
+			arg.datums = &datum;
+			arg.ndatums = 1;
+			offset = partition_bound_bsearch(partkey, boundinfo, &arg,
+											 &is_equal);
+
+			if (offset >= 0 && is_equal && boundinfo->indexes[offset] >= 0)
+				foundoffsets = bms_add_member(foundoffsets, offset);
+		}
 	}
 
+	/* No partitions can be excluded if we found no valid offsets above */
+	if (bms_is_empty(foundoffsets))
+		return NULL;
+
 	/*
-	 * For each value, if it's found in boundinfo, increment the count of its
-	 * partition as excluded due to that value.
+	 * Since each list partition can have multiple values in the IN clause, we
+	 * must ensure that we got all values in that clause before we can
+	 * eliminate the entire partition.
+	 *
+	 * We'll need two arrays for this, one to count the number of unique
+	 * datums we found, and another to record the number of datums permitted
+	 * in each partition.  Once we've counted all this, we can eliminate any
+	 * partition where the number of datums found match the number of datums
+	 * allowed in the partition.
 	 */
-	count_excluded = (int *) palloc0(partdesc->nparts * sizeof(int));
-	for (i = 0; i < n_exclude_datums; i++)
-	{
-		int		offset,
-				excluded_part;
-		bool	is_equal;
-		PartitionBoundCmpArg arg;
-		Datum   argdatums[] = {exclude_datums[i]};
-
-		memset(&arg, 0, sizeof(arg));
-		arg.datums = argdatums;
-		arg.ndatums = 1;
-		offset = partition_bound_bsearch(partkey, boundinfo, &arg, &is_equal);
-		if (offset >= 0 && is_equal && boundinfo->indexes[offset] >= 0)
-		{
-			excluded_part = boundinfo->indexes[offset];
-			count_excluded[excluded_part]++;
-		}
-	}
+	datums_in_part = (int *) palloc0(sizeof(int) * partdesc->nparts);
+	datums_found = (int *) palloc0(sizeof(int) * partdesc->nparts);
 
-	excluded_parts = NULL;
+	i = -1;
+	while ((i = bms_next_member(foundoffsets, i)) >= 0)
+		datums_found[boundinfo->indexes[i]]++;
+
+	/* Now, in a single pass of the partitions, count the datums it permits */
+	for (i = 0; i < boundinfo->ndatums; i++)
+		datums_in_part[boundinfo->indexes[i]]++;
+
+	/*
+	 * Compare the counts, eliminate any partition that we found clause for
+	 * all possible values. We must be careful here not to include any default
+	 * partition.  In this case both arrays will contain zero, so we can just
+	 * simply ensure we only eliminate when we found at least 1 datum.
+	 */
 	for (i = 0; i < partdesc->nparts; i++)
 	{
-		/*
-		 * If all datums of this partition appeared in ne_clauses, exclude
-		 * this partition.
-		 */
-		if (count_excluded[i] > 0 &&
-			count_excluded[i] == count_partition_datums(relation, i))
+		if (datums_found[i] >= datums_in_part[i] && datums_found[i] > 0)
 			excluded_parts = bms_add_member(excluded_parts, i);
 	}
 
 	/*
-	 * Also, exclude the "null-only" partition, because strict clauses in
-	 * ne_clauses will not select any rows from it.
+	 * Because the above clauses are strict, we can also exclude the NULL
+	 * partition providing it does not also allow non-NULL values.
 	 */
 	if (partition_bound_accepts_nulls(boundinfo) &&
-		count_partition_datums(relation, boundinfo->null_index) == 0)
+		datums_in_part[boundinfo->null_index] == 0)
 		excluded_parts = bms_add_member(excluded_parts,
 										boundinfo->null_index);
 
-	pfree(count_excluded);
-	pfree(exclude_datums);
-
-	result = bms_add_range(NULL, 0, partdesc->nparts - 1);
-	result = bms_del_members(result, excluded_parts);
-	bms_free(excluded_parts);
+	pfree(datums_in_part);
+	pfree(datums_found);
 
-	return result;
+	return excluded_parts;
 }
 
 /*
@@ -2251,7 +2200,7 @@ classify_partition_bounding_keys(Relation relation, List *clauses,
 				/*
 				 * We don't turn a <> operator clause into a key right away.
 				 * Instead, the caller will hand over such clauses to
-				 * get_partitions_from_ne_clauses().
+				 * get_partitions_excluded_by().
 				 */
 				if (is_ne_listp)
 					*ne_clauses = lappend(*ne_clauses, pc);
