From 55ce468f608c27617ed0fe32a6874667266bdea4 Mon Sep 17 00:00:00 2001 From: amit 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