From 7a9d903deb0475b4f8b0742fbe904a7cf0ce69c1 Mon Sep 17 00:00:00 2001
From: Ashutosh Bapat <ashutosh.bapat@enterprisedb.com>
Date: Thu, 6 Jul 2017 14:15:22 +0530
Subject: [PATCH 10/11] Modify bound comparision functions to accept members
 of PartitionKey

Functions partition_bound_cmp(), partition_rbound_cmp() and
partition_rbound_datum_cmp() are required to merge partition bounds
from joining relations. While doing so, we do not have access to the
PartitionKey of either relations. So, modify these functions to accept
only required members of PartitionKey so that the functions can be
reused for merging bounds.

Ashutosh Bapat.
---
 src/backend/catalog/partition.c |   76 ++++++++++++++++++++++-----------------
 1 file changed, 44 insertions(+), 32 deletions(-)

diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c
index 96a64ce..d42e1b5 100644
--- a/src/backend/catalog/partition.c
+++ b/src/backend/catalog/partition.c
@@ -126,15 +126,17 @@ static List *generate_partition_qual(Relation rel);
 
 static PartitionRangeBound *make_one_range_bound(PartitionKey key, int index,
 					 List *datums, bool lower);
-static int32 partition_rbound_cmp(PartitionKey key,
-					 Datum *datums1, PartitionRangeDatumKind *kind1,
-					 bool lower1, PartitionRangeBound *b2);
-static int32 partition_rbound_datum_cmp(PartitionKey key,
-						   Datum *rb_datums, PartitionRangeDatumKind *rb_kind,
+static int32 partition_rbound_cmp(int partnatts, FmgrInfo *partsupfunc,
+					 Oid *partcollation, Datum *datums1,
+					 PartitionRangeDatumKind *kind1, bool lower1,
+					 PartitionRangeBound *b2);
+static int32 partition_rbound_datum_cmp(int partnatts, FmgrInfo *partsupfunc,
+						   Oid *partcollation, Datum *rb_datums,
+						   PartitionRangeDatumKind *rb_kind,
 						   Datum *tuple_datums);
 
-static int32 partition_bound_cmp(PartitionKey key,
-					PartitionBoundInfo boundinfo,
+static int32 partition_bound_cmp(int partnatts, FmgrInfo *partsupfunc,
+					Oid *partcollation, PartitionBoundInfo boundinfo,
 					int offset, void *probe, bool probe_is_bound);
 static int partition_bound_bsearch(PartitionKey key,
 						PartitionBoundInfo boundinfo,
@@ -719,8 +721,9 @@ check_new_partition_bound(char *relname, Relation parent,
 				 * First check if the resulting range would be empty with
 				 * specified lower and upper bounds
 				 */
-				if (partition_rbound_cmp(key, lower->datums, lower->kind, true,
-										 upper) >= 0)
+				if (partition_rbound_cmp(key->partnatts, key->partsupfunc,
+										 key->partcollation, lower->datums,
+										 lower->kind, true, upper) >= 0)
 				{
 					ereport(ERROR,
 							(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
@@ -771,9 +774,11 @@ check_new_partition_bound(char *relname, Relation parent,
 						{
 							int32		cmpval;
 
-							cmpval = partition_bound_cmp(key, boundinfo,
-														 offset + 1, upper,
-														 true);
+							cmpval = partition_bound_cmp(key->partnatts,
+														 key->partsupfunc,
+														 key->partcollation,
+														 boundinfo, offset + 1,
+														 upper, true);
 							if (cmpval < 0)
 							{
 								/*
@@ -2138,7 +2143,9 @@ qsort_partition_rbound_cmp(const void *a, const void *b, void *arg)
 	PartitionRangeBound *b2 = (*(PartitionRangeBound *const *) b);
 	PartitionKey key = (PartitionKey) arg;
 
-	return partition_rbound_cmp(key, b1->datums, b1->kind, b1->lower, b2);
+	return partition_rbound_cmp(key->partnatts, key->partsupfunc,
+								key->partcollation, b1->datums, b1->kind,
+								b1->lower, b2);
 }
 
 /*
@@ -2155,7 +2162,7 @@ qsort_partition_rbound_cmp(const void *a, const void *b, void *arg)
  * two contiguous partitions.
  */
 static int32
-partition_rbound_cmp(PartitionKey key,
+partition_rbound_cmp(int partnatts, FmgrInfo *partsupfunc, Oid *partcollation,
 					 Datum *datums1, PartitionRangeDatumKind *kind1,
 					 bool lower1, PartitionRangeBound *b2)
 {
@@ -2165,7 +2172,7 @@ partition_rbound_cmp(PartitionKey key,
 	PartitionRangeDatumKind *kind2 = b2->kind;
 	bool		lower2 = b2->lower;
 
-	for (i = 0; i < key->partnatts; i++)
+	for (i = 0; i < partnatts; i++)
 	{
 		/*
 		 * First, handle cases where the column is unbounded, which should not
@@ -2186,8 +2193,8 @@ partition_rbound_cmp(PartitionKey key,
 			 */
 			break;
 
-		cmpval = DatumGetInt32(FunctionCall2Coll(&key->partsupfunc[i],
-												 key->partcollation[i],
+		cmpval = DatumGetInt32(FunctionCall2Coll(&partsupfunc[i],
+												 partcollation[i],
 												 datums1[i],
 												 datums2[i]));
 		if (cmpval != 0)
@@ -2213,22 +2220,23 @@ partition_rbound_cmp(PartitionKey key,
  * is <, =, or > partition key of tuple (tuple_datums)
  */
 static int32
-partition_rbound_datum_cmp(PartitionKey key,
-						   Datum *rb_datums, PartitionRangeDatumKind *rb_kind,
+partition_rbound_datum_cmp(int partnatts, FmgrInfo *partsupfunc,
+						   Oid *partcollation, Datum *rb_datums,
+						   PartitionRangeDatumKind *rb_kind,
 						   Datum *tuple_datums)
 {
 	int			i;
 	int32		cmpval = -1;
 
-	for (i = 0; i < key->partnatts; i++)
+	for (i = 0; i < partnatts; i++)
 	{
 		if (rb_kind[i] == PARTITION_RANGE_DATUM_MINVALUE)
 			return -1;
 		else if (rb_kind[i] == PARTITION_RANGE_DATUM_MAXVALUE)
 			return 1;
 
-		cmpval = DatumGetInt32(FunctionCall2Coll(&key->partsupfunc[i],
-												 key->partcollation[i],
+		cmpval = DatumGetInt32(FunctionCall2Coll(&partsupfunc[i],
+												 partcollation[i],
 												 rb_datums[i],
 												 tuple_datums[i]));
 		if (cmpval != 0)
@@ -2245,17 +2253,18 @@ partition_rbound_datum_cmp(PartitionKey key,
  * specified in *probe.
  */
 static int32
-partition_bound_cmp(PartitionKey key, PartitionBoundInfo boundinfo,
-					int offset, void *probe, bool probe_is_bound)
+partition_bound_cmp(int partnatts, FmgrInfo *partsupfunc, Oid *partcollation,
+					PartitionBoundInfo boundinfo, int offset, void *probe,
+					bool probe_is_bound)
 {
 	Datum	   *bound_datums = boundinfo->datums[offset];
 	int32		cmpval = -1;
 
-	switch (key->strategy)
+	switch (boundinfo->strategy)
 	{
 		case PARTITION_STRATEGY_LIST:
-			cmpval = DatumGetInt32(FunctionCall2Coll(&key->partsupfunc[0],
-													 key->partcollation[0],
+			cmpval = DatumGetInt32(FunctionCall2Coll(&partsupfunc[0],
+													 partcollation[0],
 													 bound_datums[0],
 													 *(Datum *) probe));
 			break;
@@ -2273,12 +2282,14 @@ partition_bound_cmp(PartitionKey key, PartitionBoundInfo boundinfo,
 					 */
 					bool		lower = boundinfo->indexes[offset] < 0;
 
-					cmpval = partition_rbound_cmp(key,
-												  bound_datums, kind, lower,
+					cmpval = partition_rbound_cmp(partnatts, partsupfunc,
+												  partcollation, bound_datums,
+												  kind, lower,
 												  (PartitionRangeBound *) probe);
 				}
 				else
-					cmpval = partition_rbound_datum_cmp(key,
+					cmpval = partition_rbound_datum_cmp(partnatts, partsupfunc,
+														partcollation,
 														bound_datums, kind,
 														(Datum *) probe);
 				break;
@@ -2286,7 +2297,7 @@ partition_bound_cmp(PartitionKey key, PartitionBoundInfo boundinfo,
 
 		default:
 			elog(ERROR, "unexpected partition strategy: %d",
-				 (int) key->strategy);
+				 (int) boundinfo->strategy);
 	}
 
 	return cmpval;
@@ -2320,7 +2331,8 @@ partition_bound_bsearch(PartitionKey key, PartitionBoundInfo boundinfo,
 		int32		cmpval;
 
 		mid = (lo + hi + 1) / 2;
-		cmpval = partition_bound_cmp(key, boundinfo, mid, probe,
+		cmpval = partition_bound_cmp(key->partnatts, key->partsupfunc,
+									 key->partcollation, boundinfo, mid, probe,
 									 probe_is_bound);
 		if (cmpval <= 0)
 		{
-- 
1.7.9.5

