From 20a524d50895be0fb79659e1cbf9bc7c4f7173f6 Mon Sep 17 00:00:00 2001 From: amit Date: Fri, 9 Feb 2018 09:58:50 +0900 Subject: [PATCH v47 1/4] Add partsupfunc to PartitionSchemeData partsupfunc is merely a cache of the value in PartitionKey to avoid having to fetch it from the relcache at arbitrary points within the planner. It's needed to compare a matched operator clause's constant argument against partition bounds when performing partition pruning. --- src/backend/optimizer/util/plancat.c | 24 ++++++++++++++++++++++-- src/include/nodes/relation.h | 4 ++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 8a6baa7bea..b46b33d4f7 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -1881,7 +1881,8 @@ find_partition_scheme(PlannerInfo *root, Relation relation) { PartitionKey partkey = RelationGetPartitionKey(relation); ListCell *lc; - int partnatts; + int partnatts, + i; PartitionScheme part_scheme; /* A partitioned table should have a partition key. */ @@ -1899,7 +1900,7 @@ find_partition_scheme(PlannerInfo *root, Relation relation) partnatts != part_scheme->partnatts) continue; - /* Match the partition key types. */ + /* Match partition key type properties. */ if (memcmp(partkey->partopfamily, part_scheme->partopfamily, sizeof(Oid) * partnatts) != 0 || memcmp(partkey->partopcintype, part_scheme->partopcintype, @@ -1917,6 +1918,19 @@ find_partition_scheme(PlannerInfo *root, Relation relation) Assert(memcmp(partkey->parttypbyval, part_scheme->parttypbyval, sizeof(bool) * partnatts) == 0); + /* + * If partopfamily and partopcintype matched, must have the same + * partition comparison functions. Note that we cannot reliably + * Assert the equality of function structs themselves for they might + * be different across PartitionKey's, so just Assert for the function + * OIDs. + */ +#ifdef USE_ASSERT_CHECKING + for (i = 0; i < partkey->partnatts; i++) + Assert(partkey->partsupfunc[i].fn_oid == + part_scheme->partsupfunc[i].fn_oid); +#endif + /* Found matching partition scheme. */ return part_scheme; } @@ -1951,6 +1965,12 @@ find_partition_scheme(PlannerInfo *root, Relation relation) memcpy(part_scheme->parttypbyval, partkey->parttypbyval, sizeof(bool) * partnatts); + part_scheme->partsupfunc = (FmgrInfo *) + palloc(sizeof(FmgrInfo) * partnatts); + for (i = 0; i < partnatts; i++) + fmgr_info_copy(&part_scheme->partsupfunc[i], &partkey->partsupfunc[i], + CurrentMemoryContext); + /* Add the partitioning scheme to PlannerInfo. */ root->part_schemes = lappend(root->part_schemes, part_scheme); diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index a2dde70de5..83b03b41e4 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/relation.h @@ -15,6 +15,7 @@ #define RELATION_H #include "access/sdir.h" +#include "fmgr.h" #include "lib/stringinfo.h" #include "nodes/params.h" #include "nodes/parsenodes.h" @@ -356,6 +357,9 @@ typedef struct PartitionSchemeData /* Cached information about partition key data types. */ int16 *parttyplen; bool *parttypbyval; + + /* Cached information about partition comparison functions. */ + FmgrInfo *partsupfunc; } PartitionSchemeData; typedef struct PartitionSchemeData *PartitionScheme; -- 2.11.0