diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c
index bb6cddc35e..a38c87bcc1 100644
--- a/src/backend/partitioning/partbounds.c
+++ b/src/backend/partitioning/partbounds.c
@@ -103,7 +103,8 @@ static PartitionBoundInfo create_list_bounds(PartitionBoundSpec **boundspecs,
 											 int nparts, PartitionKey key, int **mapping);
 static PartitionBoundInfo create_range_bounds(PartitionBoundSpec **boundspecs,
 											  int nparts, PartitionKey key, int **mapping);
-static PartitionBoundInfo merge_list_bounds(FmgrInfo *partsupfunc,
+static PartitionBoundInfo merge_list_bounds(int partnatts,
+											FmgrInfo *partsupfunc,
 											Oid *collations,
 											RelOptInfo *outer_rel,
 											RelOptInfo *inner_rel,
@@ -222,6 +223,9 @@ static int32 partition_rbound_cmp(int partnatts, FmgrInfo *partsupfunc,
 								  Oid *partcollation, Datum *datums1,
 								  PartitionRangeDatumKind *kind1, bool lower1,
 								  PartitionRangeBound *b2);
+static int32 partition_lbound_datum_cmp(FmgrInfo *partsupfunc, Oid *partcollation,
+						   int nvalues, Datum *lb_datums, bool *lb_isnulls,
+						   Datum *values, bool *isnulls);
 static int	partition_range_bsearch(int partnatts, FmgrInfo *partsupfunc,
 									Oid *partcollation,
 									PartitionBoundInfo boundinfo,
@@ -1111,7 +1115,8 @@ partition_bounds_merge(int partnatts,
 			return NULL;
 
 		case PARTITION_STRATEGY_LIST:
-			return merge_list_bounds(partsupfunc,
+			return merge_list_bounds(partnatts,
+									 partsupfunc,
 									 partcollation,
 									 outer_rel,
 									 inner_rel,
@@ -1155,7 +1160,8 @@ partition_bounds_merge(int partnatts,
  * join can't handle.
  */
 static PartitionBoundInfo
-merge_list_bounds(FmgrInfo *partsupfunc, Oid *partcollation,
+merge_list_bounds(int partnatts,
+				  FmgrInfo *partsupfunc, Oid *partcollation,
 				  RelOptInfo *outer_rel, RelOptInfo *inner_rel,
 				  JoinType jointype,
 				  List **outer_parts, List **inner_parts)
@@ -1221,7 +1227,6 @@ merge_list_bounds(FmgrInfo *partsupfunc, Oid *partcollation,
 		bool	   *outer_isnull;
 		bool	   *inner_isnull;
 		bool	   *merged_isnull = NULL;
-		bool 		is_all_match = false;
 
 		if (outer_bi->isnulls && outer_pos < outer_bi->ndatums)
 			outer_isnull = outer_bi->isnulls[outer_pos];
@@ -1298,14 +1303,15 @@ merge_list_bounds(FmgrInfo *partsupfunc, Oid *partcollation,
 		{
 			Assert(outer_datums != NULL && inner_datums != NULL);
 			//TODO: handle multi-column case
-			cmpval = partition_lbound_datum_cmp(partsupfunc, partcollation, 1,  //TODO: get attr count
+			cmpval = partition_lbound_datum_cmp(partsupfunc, partcollation,
+												partnatts,
 												outer_datums,
 												outer_isnull,
 												inner_datums,
-												inner_isnull, &is_all_match);
+												inner_isnull);
 		}
 
-		if (is_all_match)
+		if (cmpval == 0)
 		{
 			/* Two list values match exactly. */
 			Assert(outer_pos < outer_bi->ndatums);
@@ -3634,32 +3640,33 @@ partition_hbound_cmp(int modulus1, int remainder1, int modulus2, int remainder2)
 /*
  * partition_lbound_datum_cmp
  *
- * This function compares the list bound values of all the partition key
- * columns. Returns the value of 'cmpval' if the first bound value does
- * not match, otherwise returns zero. If it successfully compares the bound
- * values for all the partition key, then it sets is_all_match to TRUE.
+ * Return whether list bound value (given by lb_datums and lb_isnulls) is
+ * <, =, or > partition key of a tuple (specified in values and isnulls).
+ *
+ * nvalues gives the number of values provided in the 'values' and 'isnulls'
+ * array.   partsupfunc and partcollation, both arrays of nvalues elements,
+ * give the comparison functions and the collations to be used when comparing.
  */
-int32
+static int32
 partition_lbound_datum_cmp(FmgrInfo *partsupfunc, Oid *partcollation,
 						   int nvalues, Datum *lb_datums, bool *lb_isnulls,
-						   Datum *values, bool *isnulls, bool *is_all_match)
+						   Datum *values, bool *isnulls)
 {
-	int		i = 0;
-	int32	cmpval = 0;
+	int		i;
+	int32	cmpval;
 
 	for (i = 0; i < nvalues; i++)
 	{
-		bool isnull = false;
-
-		if (isnulls)
-			isnull = isnulls[i];
-
-		if (lb_isnulls[i] && isnull)
-			cmpval = 0;
-		else if (lb_isnulls[i])
-			cmpval = 1;
-		else if (isnull)
-			cmpval = -1;
+		/* This always places NULLs after not-NULLs. */
+		if (lb_isnulls[i])
+		{
+			if (isnulls && isnulls[i])
+				cmpval = 0;		/* NULL "=" NULL */
+			else
+				cmpval = 1;		/* NULL ">" not-NULL */
+		}
+		else if (isnulls && isnulls[i])
+			cmpval = -1;		/* not-NULL "<" NULL */
 		else
 			cmpval = DatumGetInt32(FunctionCall2Coll(&partsupfunc[i],
 													 partcollation[i],
@@ -3669,13 +3676,7 @@ partition_lbound_datum_cmp(FmgrInfo *partsupfunc, Oid *partcollation,
 			break;
 	}
 
-	if (i == 0)
-		return cmpval;
-
-	if (i == nvalues && cmpval == 0)
-		*is_all_match = true;
-
-	return 0;
+	return cmpval;
 }
 
 /*
@@ -3700,76 +3701,17 @@ partition_list_bsearch(FmgrInfo *partsupfunc, Oid *partcollation,
 	while (lo < hi)
 	{
 		int32		cmpval;
-		bool		is_all_match = false;
 
 		mid = (lo + hi + 1) / 2;
 		cmpval = partition_lbound_datum_cmp(partsupfunc, partcollation,
-											nvalues, boundinfo->datums[mid],
-											boundinfo->isnulls[mid], values,
-											isnulls, &is_all_match);
-
-		if (is_all_match)
-		{
-			*is_equal = true;
-			return mid;
-		}
-
-		if (cmpval == 0)
-		{
-			/*
-			 * Once we find the matching for the first column but if it does not
-			 * match for the any of the other columns, then the binary search
-			 * will not work in all the cases. We should traverse just below
-			 * and above the mid index until we find the match or we reach the
-			 * first mismatch.
-			 */
-			int32	off = mid;
-			while (off >= 1)
-			{
-				cmpval = partition_lbound_datum_cmp(partsupfunc, partcollation,
-													nvalues, boundinfo->datums[off - 1],
-													boundinfo->isnulls[off - 1], values,
-													isnulls, &is_all_match);
-
-				if (is_all_match)
-				{
-					/* Found the matching bound. Return the offset. */
-					*is_equal = true;
-					return (off - 1);
-				}
-
-				if (cmpval != 0)
-					break;
-
-				off--;
-			}
-
-			off = mid;
-			while (off < boundinfo->ndatums - 1)
-			{
-				cmpval = partition_lbound_datum_cmp(partsupfunc, partcollation,
-													nvalues, boundinfo->datums[off + 1],
-													boundinfo->isnulls[off + 1], values,
-													isnulls, &is_all_match);
-
-				if (is_all_match)
-				{
-					/* Found the matching bound. Return the offset. */
-					*is_equal = true;
-					return (off + 1);
-				}
-
-				if (cmpval != 0)
-					break;
-
-				off++;
-			}
-		}
-
+											nvalues,
+											boundinfo->datums[mid],
+											boundinfo->isnulls[mid],
+											values, isnulls);
 		if (cmpval <= 0)
 		{
 			lo = mid;
-			*is_equal = (cmpval == 0 && is_all_match);
+			*is_equal = (cmpval == 0);
 			if (*is_equal)
 				break;
 		}
@@ -3935,23 +3877,17 @@ qsort_partition_hbound_cmp(const void *a, const void *b)
 static int32
 qsort_partition_list_value_cmp(const void *a, const void *b, void *arg)
 {
-	Datum	   *val1 = (*(PartitionListValue *const *) a)->values;
-	Datum	   *val2 = (*(PartitionListValue *const *) b)->values;
-	bool	   *null1 = (*(PartitionListValue *const *) a)->isnulls;
-	bool	   *null2 = (*(PartitionListValue *const *) b)->isnulls;
-
+	Datum	   *vals1 = (*(PartitionListValue *const *) a)->values;
+	Datum	   *vals2 = (*(PartitionListValue *const *) b)->values;
+	bool	   *isnull1 = (*(PartitionListValue *const *) a)->isnulls;
+	bool	   *isnull2 = (*(PartitionListValue *const *) b)->isnulls;
 	PartitionKey key = (PartitionKey) arg;
 
-	if (null1[0] && null2[0])
-		return 0;
-	else if (null1[0])
-		return 1;
-	else if (null2[0])
-		return -1;
-	else
-		return DatumGetInt32(FunctionCall2Coll(&key->partsupfunc[0],
-											   key->partcollation[0],
-											   val1[0], val2[0]));
+	return partition_lbound_datum_cmp(key->partsupfunc,
+									  key->partcollation,
+									  key->partnatts,
+									  vals1, isnull1,
+									  vals2, isnull2);
 }
 
 /*
diff --git a/src/include/partitioning/partbounds.h b/src/include/partitioning/partbounds.h
index a4b301bfa1..f46ad3ad23 100644
--- a/src/include/partitioning/partbounds.h
+++ b/src/include/partitioning/partbounds.h
@@ -24,9 +24,6 @@ struct RelOptInfo;				/* avoid including pathnodes.h here */
  * descriptor, but may also be used to represent a virtual partitioned
  * table such as a partitioned joinrel within the planner.
  *
- * A list partition datum that is known to be NULL is never put into the
- * datums array. Instead, it is tracked using the null_index field.
- *
  * In the case of range partitioning, ndatums will typically be far less than
  * 2 * nparts, because a partition's upper bound and the next partition's lower
  * bound are the same in most common cases, and we only store one of them (the
@@ -38,6 +35,10 @@ struct RelOptInfo;				/* avoid including pathnodes.h here */
  * of datum-tuples with 2 datums, modulus and remainder, corresponding to a
  * given partition.
  *
+ * isnulls is an array of boolean-tuples with key->partnatts booleans values
+ * each.  Currently only used for list partitioning, it stores whether a
+ * given partition key accepts NULL as value.
+ *
  * The datums in datums array are arranged in increasing order as defined by
  * functions qsort_partition_rbound_cmp(), qsort_partition_list_value_cmp() and
  * qsort_partition_hbound_cmp() for range, list and hash partitioned tables
@@ -126,9 +127,4 @@ extern int	partition_range_datum_bsearch(FmgrInfo *partsupfunc,
 										  int nvalues, Datum *values, bool *is_equal);
 extern int	partition_hash_bsearch(PartitionBoundInfo boundinfo,
 								   int modulus, int remainder);
-extern int32 partition_lbound_datum_cmp(FmgrInfo *partsupfunc,
-										Oid *partcollation,
-										int nvalues, Datum *lb_datums,
-										bool *lb_isnulls, Datum *values,
-										bool *isnulls, bool *is_all_match);
 #endif							/* PARTBOUNDS_H */
diff --git a/src/test/regress/expected/insert.out b/src/test/regress/expected/insert.out
index 174f8c2d19..8e704d3928 100644
--- a/src/test/regress/expected/insert.out
+++ b/src/test/regress/expected/insert.out
@@ -846,20 +846,20 @@ insert into mclparted values (1, null, null);
 ERROR:  no partition of relation "mclparted" found for row
 DETAIL:  Partition key of the failing row contains (a, b, c) = (1, null, null).
 -- check rows
-select tableoid::regclass::text, * from mclparted order by 1;
+select tableoid::regclass::text, * from mclparted order by 1, 2, 3, 4;
    tableoid   | a | b | c 
 --------------+---+---+---
  mclparted_p1 | 1 | a | 1
+ mclparted_p2 | 1 | a | 2
  mclparted_p2 | 1 | b | 1
  mclparted_p2 | 2 | a | 1
- mclparted_p2 | 1 | a | 2
  mclparted_p3 | 3 | c | 3
+ mclparted_p3 | 4 | d | 4
  mclparted_p3 | 5 | e | 5
  mclparted_p3 | 6 |   | 6
- mclparted_p3 | 4 | d | 4
- mclparted_p4 |   | a | 1
- mclparted_p4 | 1 |   | 1
  mclparted_p4 | 1 | a |  
+ mclparted_p4 | 1 |   | 1
+ mclparted_p4 |   | a | 1
  mclparted_p5 |   |   |  
 (12 rows)
 
diff --git a/src/test/regress/sql/insert.sql b/src/test/regress/sql/insert.sql
index 76e0d004a1..2bfc55c66a 100644
--- a/src/test/regress/sql/insert.sql
+++ b/src/test/regress/sql/insert.sql
@@ -573,7 +573,7 @@ insert into mclparted values (1, 'a', 10);
 insert into mclparted values (1, null, null);
 
 -- check rows
-select tableoid::regclass::text, * from mclparted order by 1;
+select tableoid::regclass::text, * from mclparted order by 1, 2, 3, 4;
 
 -- cleanup
 drop table mclparted;
