diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c
index d96d4f9947b..1093cb5044c 100644
--- a/src/backend/executor/execPartition.c
+++ b/src/backend/executor/execPartition.c
@@ -1680,7 +1680,7 @@ get_partition_for_tuple(PartitionDispatch pd, const Datum *values, const bool *i
 				if (range_partkey_has_null)
 					break;
 
-				if (partdesc->last_found_count >= PARTITION_CACHED_FIND_THRESHOLD)
+				if (partdesc->last_found_count >= PARTITION_CACHED_FIND_THRESHOLD && false /* temporary disable */)
 				{
 					int			last_datum_offset = partdesc->last_found_datum_index;
 					Datum	   *lastDatums = boundinfo->datums[last_datum_offset];
diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c
index f867d1b75a5..5b6099c7b3b 100644
--- a/src/backend/partitioning/partbounds.c
+++ b/src/backend/partitioning/partbounds.c
@@ -224,7 +224,8 @@ static int32 partition_rbound_cmp(int partnatts, FmgrInfo *partsupfunc,
 static int	partition_range_bsearch(int partnatts, FmgrInfo *partsupfunc,
 									Oid *partcollation,
 									PartitionBoundInfo boundinfo,
-									PartitionRangeBound *probe, int32 *cmpval);
+									PartitionRangeBound *lower,
+									PartitionRangeBound *upper);
 static Expr *make_partition_op_expr(PartitionKey key, int keynum,
 									uint16 strategy, Expr *arg1, Expr *arg2);
 static Oid	get_partition_operator(PartitionKey key, int col,
@@ -677,8 +678,7 @@ create_range_bounds(PartitionBoundSpec **boundspecs, int nparts,
 {
 	PartitionBoundInfo boundinfo;
 	PartitionRangeBound **rbounds = NULL;
-	PartitionRangeBound **all_bounds,
-			   *prev;
+	PartitionRangeBound **all_bounds;
 	int			i,
 				k,
 				partnatts;
@@ -728,61 +728,12 @@ create_range_bounds(PartitionBoundSpec **boundspecs, int nparts,
 	Assert(ndatums == nparts * 2 ||
 		   (default_index != -1 && ndatums == (nparts - 1) * 2));
 
-	/* Sort all the bounds in ascending order */
-	qsort_arg(all_bounds, ndatums,
-			  sizeof(PartitionRangeBound *),
-			  qsort_partition_rbound_cmp,
-			  key);
-
-	/* Save distinct bounds from all_bounds into rbounds. */
 	rbounds = (PartitionRangeBound **)
 		palloc(ndatums * sizeof(PartitionRangeBound *));
 	k = 0;
-	prev = NULL;
 	for (i = 0; i < ndatums; i++)
 	{
-		PartitionRangeBound *cur = all_bounds[i];
-		bool		is_distinct = false;
-		int			j;
-
-		/* Is the current bound distinct from the previous one? */
-		for (j = 0; j < key->partnatts; j++)
-		{
-			Datum		cmpval;
-
-			if (prev == NULL || cur->kind[j] != prev->kind[j])
-			{
-				is_distinct = true;
-				break;
-			}
-
-			/*
-			 * If the bounds are both MINVALUE or MAXVALUE, stop now and treat
-			 * them as equal, since any values after this point must be
-			 * ignored.
-			 */
-			if (cur->kind[j] != PARTITION_RANGE_DATUM_VALUE)
-				break;
-
-			cmpval = FunctionCall2Coll(&key->partsupfunc[j],
-									   key->partcollation[j],
-									   cur->datums[j],
-									   prev->datums[j]);
-			if (DatumGetInt32(cmpval) != 0)
-			{
-				is_distinct = true;
-				break;
-			}
-		}
-
-		/*
-		 * Only if the bound is distinct save it into a temporary array, i.e,
-		 * rbounds which is later copied into boundinfo datums array.
-		 */
-		if (is_distinct)
 			rbounds[k++] = all_bounds[i];
-
-		prev = cur;
 	}
 
 	pfree(all_bounds);
@@ -3127,6 +3078,7 @@ check_new_partition_bound(char *relname, Relation parent,
 
 				if (partdesc->nparts > 0)
 				{
+					/* if key->partnatts == 1 or ? boundinfo->ndatums */
 					int			offset;
 
 					Assert(boundinfo &&
@@ -3152,68 +3104,10 @@ check_new_partition_bound(char *relname, Relation parent,
 					offset = partition_range_bsearch(key->partnatts,
 													 key->partsupfunc,
 													 key->partcollation,
-													 boundinfo, lower,
-													 &cmpval);
+													 boundinfo, lower, upper);
 
-					if (boundinfo->indexes[offset + 1] < 0)
-					{
-						/*
-						 * Check that the new partition will fit in the gap.
-						 * For it to fit, the new upper bound must be less
-						 * than or equal to the lower bound of the next
-						 * partition, if there is one.
-						 */
-						if (offset + 1 < boundinfo->ndatums)
-						{
-							Datum	   *datums;
-							PartitionRangeDatumKind *kind;
-							bool		is_lower;
-
-							datums = boundinfo->datums[offset + 1];
-							kind = boundinfo->kind[offset + 1];
-							is_lower = (boundinfo->indexes[offset + 1] == -1);
-
-							cmpval = partition_rbound_cmp(key->partnatts,
-														  key->partsupfunc,
-														  key->partcollation,
-														  datums, kind,
-														  is_lower, upper);
-							if (cmpval < 0)
-							{
-								/*
-								 * Point to problematic key in the upper
-								 * datums list.
-								 */
-								PartitionRangeDatum *datum =
-									list_nth(spec->upperdatums, abs(cmpval) - 1);
-
-								/*
-								 * The new partition overlaps with the
-								 * existing partition between offset + 1 and
-								 * offset + 2.
-								 */
-								overlap = true;
-								overlap_location = datum->location;
-								with = boundinfo->indexes[offset + 2];
-							}
-						}
-					}
-					else
-					{
-						/*
-						 * The new partition overlaps with the existing
-						 * partition between offset and offset + 1.
-						 */
-						PartitionRangeDatum *datum;
-
-						/*
-						 * Point to problematic key in the lower datums list;
-						 * if we have equality, point to the first one.
-						 */
-						datum = cmpval == 0 ? linitial(spec->lowerdatums) :
-							list_nth(spec->lowerdatums, abs(cmpval) - 1);
+					if (offset > -1) {
 						overlap = true;
-						overlap_location = datum->location;
 						with = boundinfo->indexes[offset + 1];
 					}
 				}
@@ -3646,34 +3540,133 @@ static int
 partition_range_bsearch(int partnatts, FmgrInfo *partsupfunc,
 						Oid *partcollation,
 						PartitionBoundInfo boundinfo,
-						PartitionRangeBound *probe, int32 *cmpval)
+						PartitionRangeBound *lower,
+						PartitionRangeBound *upper)
 {
-	int			lo,
-				hi,
-				mid;
+	int offset = -1;
+	int d, partattr;
+	int32 cmpval1, cmpval2;
 
-	lo = -1;
-	hi = boundinfo->ndatums - 1;
-	while (lo < hi)
+	Datum *lower_datums, *upper_datums;
+
+	fprintf(stdout,"Func : partition_range_bsearch : \n");
+	fprintf(stdout,"\n# Partition by range (relevant for 2D partition key, for Python script) : \n");
+
+	/* New the partition by range */
+	partattr = 0;
+	fprintf(stdout,"range((");
+	while (partattr < partnatts) {
+		fprintf(stdout, "%lu, ", lower->datums[partattr]);
+		partattr++;
+	}
+	fprintf(stdout,"), ");
+
+	partattr = 0;
+	fprintf(stdout,"(");
+	while (partattr < partnatts) {
+		fprintf(stdout, "%lu, ", upper->datums[partattr]);
+		partattr++;
+	}
+	fprintf(stdout,"), 'new', facecolor='black', edgecolor='yellow')\n");
+
+	/* Existing the partition by range */
+	d = 0;
+	while ( d < boundinfo->ndatums - 1 )
 	{
-		mid = (lo + hi + 1) / 2;
-		*cmpval = partition_rbound_cmp(partnatts, partsupfunc,
-									   partcollation,
-									   boundinfo->datums[mid],
-									   boundinfo->kind[mid],
-									   (boundinfo->indexes[mid] == -1),
-									   probe);
-		if (*cmpval <= 0)
+		if ( boundinfo->indexes[d] == -1 && boundinfo->indexes[d+1] > -1 )
 		{
-			lo = mid;
-			if (*cmpval == 0)
-				break;
+			lower_datums = boundinfo->datums[d];
+			upper_datums = boundinfo->datums[d+1];
+
+			partattr = 0;
+			fprintf(stdout,"range((");
+			while (partattr < partnatts) {
+				fprintf(stdout, "%lu, ", lower_datums[partattr]);
+				partattr++;
+			}
+			fprintf(stdout,"), ");
+
+			partattr = 0;
+			fprintf(stdout,"(");
+			while (partattr < partnatts) {
+				fprintf(stdout, "%lu, ", upper_datums[partattr]);
+				partattr++;
+			}
+			fprintf(stdout,"),'p-%d')\n", boundinfo->indexes[d+1]);
+
+			d+=2;
 		}
 		else
-			hi = mid - 1;
+			d++;
 	}
+	fprintf(stdout,"\n");
+	fflush(stdout);
 
-	return lo;
+	/* Search algorithm */
+	d = 0;
+	while ( d < boundinfo->ndatums )
+	{
+		if ( (boundinfo->indexes[d] == -1) && (boundinfo->indexes[d+1] > -1) )
+		{
+			lower_datums = boundinfo->datums[d];
+			upper_datums = boundinfo->datums[d+1];
+
+			partattr = 0;
+			while (partattr < partnatts)
+			{
+				cmpval1 = DatumGetInt32(FunctionCall2Coll(&partsupfunc[partattr], partcollation[partattr],
+														 upper_datums[partattr], lower->datums[partattr]));
+
+				cmpval2 = DatumGetInt32(FunctionCall2Coll(&partsupfunc[partattr], partcollation[partattr],
+														 upper->datums[partattr], lower_datums[partattr]));
+
+				/* Step of the search algorithm */
+				/* datums_lower[partattr], datums_upper[partattr] ;
+				 * probe->datums[partattr], upper->datums[partattr];
+				 * a,a'; b,b' -> a_k' < b_k OR b_k' < a_k
+				 */
+				fprintf(stdout, "Range : Exists( %lu, %lu), New( %lu, %lu)\n",
+					lower_datums[partattr], upper_datums[partattr],
+					lower->datums[partattr], upper->datums[partattr]);
+				fprintf(stdout, "Condition: 1) %lu < %lu : result = %d or 2) %lu < %lu : result = %d; attr = %d; ",
+					upper_datums[partattr], lower->datums[partattr], cmpval1,
+					upper->datums[partattr], lower_datums[partattr], cmpval2,
+					partattr);
+
+				if ( cmpval1 < 1 || cmpval2 < 1 )
+				{
+					/* The partition range passed the check - there are no intersections
+					 * with the new partition range.
+					 * Then exit the loop with the value partnatts++
+					 */
+					partattr = partnatts;
+					fprintf(stdout, "[CHECK OK].");
+				}
+
+				partattr++;
+				fprintf(stdout,"\n");
+				fflush(stdout);
+			}
+
+			if (partattr == partnatts)
+			{
+				/* This condition means that in the while loop for all <partattr>,
+				 * there is an intersection of ranges across all partition key value.
+				 * Therefore, we can skip further partition range checks.
+				 */
+				offset = d;
+				d = boundinfo->ndatums + 3;
+			}
+			d+=2;
+		}
+		else
+			d++;
+	}
+
+	fprintf(stdout,"New the partition by range : %s.\n", (d == boundinfo->ndatums + 3) ? "ERROR" : "OK" );
+	fflush(stdout);
+
+	return offset;
 }
 
 /*
@@ -3689,36 +3682,103 @@ partition_range_datum_bsearch(FmgrInfo *partsupfunc, Oid *partcollation,
 							  PartitionBoundInfo boundinfo,
 							  int nvalues, const Datum *values, bool *is_equal)
 {
-	int			lo,
-				hi,
-				mid;
+	int offset = -1;
+	int d, partattr;
+	int32 cmpval1, cmpval2;
+
+	Datum *lower_datums, *upper_datums;
+	fprintf(stdout,"Func : partition_range_datum_bsearch : nvalues = %d\n", nvalues);
+	fprintf(stdout,"\n# Partition by range (relevant for 2D partition key, for Python script) : \n");
+
+	/* New the partition key */
+	partattr = 0;
+	fprintf(stdout,"key((");
+	while (partattr < nvalues) {
+		fprintf(stdout, "%lu, ", values[partattr]);
+		partattr++;
+	}
+	fprintf(stdout,"), 0.3)\n");
 
-	lo = -1;
-	hi = boundinfo->ndatums - 1;
-	while (lo < hi)
+	/* Existing the partition by range */
+	d = 0;
+	while ( d < boundinfo->ndatums - 1 )
 	{
-		int32		cmpval;
+		if ( boundinfo->indexes[d] == -1 && boundinfo->indexes[d+1] > -1 )
+		{
+			lower_datums = boundinfo->datums[d];
+			upper_datums = boundinfo->datums[d+1];
+
+			partattr = 0;
+			fprintf(stdout,"range((");
+			while (partattr < nvalues) {
+				fprintf(stdout, "%lu, ", lower_datums[partattr]);
+				partattr++;
+			}
+			fprintf(stdout,"), ");
 
-		mid = (lo + hi + 1) / 2;
-		cmpval = partition_rbound_datum_cmp(partsupfunc,
-											partcollation,
-											boundinfo->datums[mid],
-											boundinfo->kind[mid],
-											values,
-											nvalues);
-		if (cmpval <= 0)
+			partattr = 0;
+			fprintf(stdout,"(");
+			while (partattr < nvalues) {
+				fprintf(stdout, "%lu, ", upper_datums[partattr]);
+				partattr++;
+			}
+			fprintf(stdout,"),'p-%d')\n", boundinfo->indexes[d+1]);
+
+			d+=2;
+		}
+		else
+			d++;
+	}
+	fprintf(stdout,"\n");
+	fflush(stdout);
+
+	/* Search algorithm */
+	d = 0;
+	while ( d < boundinfo->ndatums )
+	{
+		if ( (boundinfo->indexes[d] == -1) && (boundinfo->indexes[d+1] > -1) )
 		{
-			lo = mid;
-			*is_equal = (cmpval == 0);
+			lower_datums = boundinfo->datums[d];
+			upper_datums = boundinfo->datums[d+1];
 
-			if (*is_equal)
-				break;
+			partattr = 0;
+			while (partattr < nvalues)
+			{
+				cmpval1 = DatumGetInt32(FunctionCall2Coll(&partsupfunc[partattr], partcollation[partattr],
+														 lower_datums[partattr], values[partattr]));
+
+				cmpval2 = DatumGetInt32(FunctionCall2Coll(&partsupfunc[partattr], partcollation[partattr],
+														 values[partattr], upper_datums[partattr]));
+
+				/* Step of the search algorithm */
+				fprintf(stdout, "Range : Exists(%lu, %lu), Key(%lu)\n",  lower_datums[partattr], upper_datums[partattr], values[partattr]);
+
+				if ( !(cmpval1 < 1 && cmpval2 < 1) )
+				{
+					partattr = nvalues;
+					fprintf(stdout, "[KEY OUT RANGE].");
+				}
+
+				partattr++;
+				fprintf(stdout,"\n");
+				fflush(stdout);
+			}
+
+			if (partattr == nvalues)
+			{
+				offset = d;
+				d = boundinfo->ndatums + 3;
+			}
+			d+=2;
 		}
 		else
-			hi = mid - 1;
+			d++;
 	}
 
-	return lo;
+	fprintf(stdout,"New partition key : %s.\n", (d == boundinfo->ndatums + 3) ? "OK" : "ERROR" );
+	fflush(stdout);
+
+	return offset;
 }
 
 /*
diff --git a/src/backend/partitioning/partdesc.c b/src/backend/partitioning/partdesc.c
index c3d275f8726..77ef116172c 100644
--- a/src/backend/partitioning/partdesc.c
+++ b/src/backend/partitioning/partdesc.c
@@ -71,7 +71,7 @@ PartitionDesc
 RelationGetPartitionDesc(Relation rel, bool omit_detached)
 {
 	Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
-
+	return RelationBuildPartitionDesc(rel, omit_detached);
 	/*
 	 * If relcache has a partition descriptor, use that.  However, we can only
 	 * do so when we are asked to include all partitions including detached;
@@ -307,9 +307,30 @@ retry:
 	 * Create PartitionBoundInfo and mapping, working in the caller's context.
 	 * This could fail, but we haven't done any damage if so.
 	 */
-	if (nparts > 0)
+	if (nparts > 0) {
 		boundinfo = partition_bounds_create(boundspecs, nparts, key, &mapping);
 
+		int d = 0, partattr;
+
+		fprintf(stdout,"BoundInfo : \n");
+		while ( d < boundinfo->ndatums )
+		{
+			/*cur_datum = boundinfo->datums[d];*/
+			fprintf(stdout,"Index = %d, Range (",boundinfo->indexes[d]);
+
+			partattr = 0;
+			while (partattr < key->partnatts)
+			{
+				fprintf(stdout," %lu, ", boundinfo->datums[d][partattr]);
+				partattr++;
+			}
+			fprintf(stdout,");\n");
+			fflush(stdout);
+
+			d++;
+		}
+	}
+
 	/*
 	 * Now build the actual relcache partition descriptor, copying all the
 	 * data into a new, small context.  As per above comment, we don't make
