From 55ce468f608c27617ed0fe32a6874667266bdea4 Mon Sep 17 00:00:00 2001
From: amit <amitlangote09@gmail.com>
Date: Mon, 26 Dec 2016 17:44:14 +0900
Subject: [PATCH 6/8] Avoid tuple coversion in common partitioning cases

Currently, the tuple conversion is performed after a tuple is routed,
even if the attributes of a target leaf partition map one-to-one with
those of the root table, which is wasteful.  Avoid that by making
convert_tuples_by_name() return a NULL map for such cases.

Reported by: n/a
Patch by: Amit Langote
Reports: n/a
---
 src/backend/access/common/tupconvert.c | 8 ++++++--
 src/backend/catalog/partition.c        | 5 ++---
 src/backend/commands/analyze.c         | 1 +
 src/backend/executor/execMain.c        | 1 +
 src/backend/executor/execQual.c        | 2 +-
 src/include/access/tupconvert.h        | 1 +
 6 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/src/backend/access/common/tupconvert.c b/src/backend/access/common/tupconvert.c
index b17ceafa6e..bbbd271e1f 100644
--- a/src/backend/access/common/tupconvert.c
+++ b/src/backend/access/common/tupconvert.c
@@ -202,6 +202,7 @@ convert_tuples_by_position(TupleDesc indesc,
 TupleConversionMap *
 convert_tuples_by_name(TupleDesc indesc,
 					   TupleDesc outdesc,
+					   bool consider_typeid,
 					   const char *msg)
 {
 	TupleConversionMap *map;
@@ -216,11 +217,14 @@ convert_tuples_by_name(TupleDesc indesc,
 	/*
 	 * Check to see if the map is one-to-one and the tuple types are the same.
 	 * (We check the latter because if they're not, we want to do conversion
-	 * to inject the right OID into the tuple datum.)
+	 * to inject the right OID into the tuple datum.  In the partitioning
+	 * case (!consider_typeid), tdhasoids must always match between indesc
+	 * and outdesc, so we need not require tdtypeid's to be the same.)
 	 */
 	if (indesc->natts == outdesc->natts &&
-		indesc->tdtypeid == outdesc->tdtypeid)
+		(!consider_typeid || indesc->tdtypeid == outdesc->tdtypeid))
 	{
+		Assert(!consider_typeid && indesc->tdhasoid == outdesc->tdhasoid);
 		same = true;
 		for (i = 0; i < n; i++)
 		{
diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c
index 5ca57f44fb..75ec746cb4 100644
--- a/src/backend/catalog/partition.c
+++ b/src/backend/catalog/partition.c
@@ -1084,7 +1084,7 @@ RelationGetPartitionDispatchInfo(Relation rel, int lockmode,
 			 */
 			pd[i]->tupslot = MakeSingleTupleTableSlot(tupdesc);
 			pd[i]->tupmap = convert_tuples_by_name(RelationGetDescr(parent),
-												   tupdesc,
+												   tupdesc, false,
 								gettext_noop("could not convert row type"));
 		}
 		else
@@ -1694,12 +1694,11 @@ get_partition_for_tuple(PartitionDispatch *pd,
 			return -1;
 		}
 
-		if (myslot != NULL)
+		if (myslot != NULL && map != NULL)
 		{
 			HeapTuple	tuple = ExecFetchSlotTuple(slot);
 
 			ExecClearTuple(myslot);
-			Assert(map != NULL);
 			tuple = do_convert_tuple(tuple, map);
 			ExecStoreTuple(tuple, myslot, InvalidBuffer, true);
 			slot = myslot;
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index e3e1a53072..31bec9f961 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -1419,6 +1419,7 @@ acquire_inherited_sample_rows(Relation onerel, int elevel,
 
 					map = convert_tuples_by_name(RelationGetDescr(childrel),
 												 RelationGetDescr(onerel),
+												 true,
 								 gettext_noop("could not convert row type"));
 					if (map != NULL)
 					{
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 04c026f3f8..b14cc98caf 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -3201,6 +3201,7 @@ ExecSetupPartitionTupleRouting(Relation rel,
 		 * partition from the parent's type to the partition's.
 		 */
 		(*tup_conv_maps)[i] = convert_tuples_by_name(tupDesc, part_tupdesc,
+													 false,
 								 gettext_noop("could not convert row type"));
 
 		InitResultRelInfo(leaf_part_rri,
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c
index eed7e95c75..5f637006d1 100644
--- a/src/backend/executor/execQual.c
+++ b/src/backend/executor/execQual.c
@@ -2920,7 +2920,7 @@ ExecEvalConvertRowtype(ConvertRowtypeExprState *cstate,
 
 		/* prepare map from old to new attribute numbers */
 		cstate->map = convert_tuples_by_name(cstate->indesc,
-											 cstate->outdesc,
+											 cstate->outdesc, true,
 								 gettext_noop("could not convert row type"));
 		cstate->initialized = true;
 
diff --git a/src/include/access/tupconvert.h b/src/include/access/tupconvert.h
index e86cfd56c8..231fe872d7 100644
--- a/src/include/access/tupconvert.h
+++ b/src/include/access/tupconvert.h
@@ -36,6 +36,7 @@ extern TupleConversionMap *convert_tuples_by_position(TupleDesc indesc,
 
 extern TupleConversionMap *convert_tuples_by_name(TupleDesc indesc,
 					   TupleDesc outdesc,
+					   bool consider_typeid,
 					   const char *msg);
 
 extern AttrNumber *convert_tuples_by_name_map(TupleDesc indesc,
-- 
2.11.0

