From 5a2376376b49aeff814d2b1e473394b2377a6370 Mon Sep 17 00:00:00 2001 From: amit Date: Fri, 9 Feb 2018 09:58:50 +0900 Subject: [PATCH v33 1/3] Add partcollation and partsupfunc to PartitionSchemeData Partitioning-specific collation denoted by partcollation may be different from the collation of the partition key's type. When performing partitioning-specific optimizations within the planner, such as when determining which partitions to prune based on a given operator clause, we must use that collation. Also, two logically identical partition schemes must have the same partcollation. 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 | 15 ++++++++++++++- src/include/nodes/relation.h | 19 ++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 60f21711f4..fdcbc2f513 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -1886,12 +1886,16 @@ find_partition_scheme(PlannerInfo *root, Relation relation) partnatts != part_scheme->partnatts) continue; - /* Match the partition key types. */ + /* + * Match the partition key types and partitioning-specific collations. + */ if (memcmp(partkey->partopfamily, part_scheme->partopfamily, sizeof(Oid) * partnatts) != 0 || memcmp(partkey->partopcintype, part_scheme->partopcintype, sizeof(Oid) * partnatts) != 0 || memcmp(partkey->parttypcoll, part_scheme->parttypcoll, + sizeof(Oid) * partnatts) != 0 || + memcmp(partkey->partcollation, part_scheme->partcollation, sizeof(Oid) * partnatts) != 0) continue; @@ -1930,6 +1934,10 @@ find_partition_scheme(PlannerInfo *root, Relation relation) memcpy(part_scheme->parttypcoll, partkey->parttypcoll, sizeof(Oid) * partnatts); + part_scheme->partcollation = (Oid *) palloc(sizeof(Oid) * partnatts); + memcpy(part_scheme->partcollation, partkey->partcollation, + sizeof(Oid) * partnatts); + part_scheme->parttyplen = (int16 *) palloc(sizeof(int16) * partnatts); memcpy(part_scheme->parttyplen, partkey->parttyplen, sizeof(int16) * partnatts); @@ -1938,6 +1946,11 @@ find_partition_scheme(PlannerInfo *root, Relation relation) memcpy(part_scheme->parttypbyval, partkey->parttypbyval, sizeof(bool) * partnatts); + part_scheme->partsupfunc = (FmgrInfo *) + palloc(sizeof(FmgrInfo) * partnatts); + memcpy(part_scheme->partsupfunc, partkey->partsupfunc, + sizeof(FmgrInfo) * partnatts); + /* 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 b1c63173c2..0d918b5643 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" @@ -349,11 +350,27 @@ typedef struct PartitionSchemeData int16 partnatts; /* number of partition attributes */ Oid *partopfamily; /* OIDs of operator families */ Oid *partopcintype; /* OIDs of opclass declared input data types */ - Oid *parttypcoll; /* OIDs of collations of partition keys. */ + + /* + * We store both the collation implied by the partition key's type and the + * one specified for partitioning. Values in the former are used as + * varcollid in the Vars corresponding to simple column partition keys so + * as to make them match corresponding Vars appearing elsewhere in the + * query tree. Whereas, the latter is used when actually comparing values + * against partition bounds datums, such as, when doing partition pruning. + */ + Oid *parttypcoll; + Oid *partcollation; /* Cached information about partition key data types. */ int16 *parttyplen; bool *parttypbyval; + + /* + * Cached array of partitioning comparison functions' fmgr structs. We + * don't compare these when trying to match two partition schemes. + */ + FmgrInfo *partsupfunc; } PartitionSchemeData; typedef struct PartitionSchemeData *PartitionScheme; -- 2.11.0