*
  * 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.
+ * bound are the same in most common cases, and we only store one of them (the
+ * upper bound).
  *
  * In the case of list partitioning, the indexes array stores one entry for
  * every datum, which is the index of the partition that accepts a given datum.
  * partition_rbound_cmp
  *
  * Return for two range bounds whether the 1st one (specified in datum1,
- * content1, and lower1) is <=, =, >= the bound specified in *b2
+ * content1, and lower1) is <, =, or > the bound specified in *b2.
+ *
+ * Note that if the values of the two range bounds compare equal, then we take
+ * into account whether they are upper or lower bounds, and an upper bound is
+ * considered to be smaller than a lower bound. This is important to the way
+ * that RelationBuildPartitionDesc() builds the PartitionBoundInfoData
+ * structure, which only stores the upper bound of a common boundary between
+ * two contiguous partitions.
  */
 static int32
 partition_rbound_cmp(PartitionKey key,
        for (i = 0; i < key->partnatts; i++)
        {
                /*
-                * First, handle cases involving infinity, which don't require
-                * invoking the comparison proc.
+                * First, handle cases where the column is unbounded, which should not
+                * invoke the comparison procedure, and should not consider any later
+                * columns.
                 */
-               if (content1[i] != RANGE_DATUM_FINITE &&
+               if (content1[i] != RANGE_DATUM_FINITE ||
                        content2[i] != RANGE_DATUM_FINITE)
-
+               {
                        /*
-                        * Both are infinity, so they are equal unless one is negative
-                        * infinity and other positive (or vice versa)
+                        * If the bound values are equal, fall through and compare whether
+                        * they are upper or lower bounds.
                         */
-                       return content1[i] == content2[i] ? 0
-                               : (content1[i] < content2[i] ? -1 : 1);
-               else if (content1[i] != RANGE_DATUM_FINITE)
-                       return content1[i] == RANGE_DATUM_NEG_INF ? -1 : 1;
-               else if (content2[i] != RANGE_DATUM_FINITE)
-                       return content2[i] == RANGE_DATUM_NEG_INF ? 1 : -1;
+                       if (content1[i] == content2[i])
+                               break;
+
+                       /* Otherwise, one bound is definitely larger than the other */
+                       if (content1[i] == RANGE_DATUM_NEG_INF)
+                               return -1;
+                       else if (content1[i] == RANGE_DATUM_POS_INF)
+                               return 1;
+                       else if (content2[i] == RANGE_DATUM_NEG_INF)
+                               return 1;
+                       else if (content2[i] == RANGE_DATUM_POS_INF)
+                               return -1;
+               }
 
                cmpval = DatumGetInt32(FunctionCall2Coll(&key->partsupfunc[i],
                                                                                                 key->partcollation[i],