partition_key_collation.diff
text/x-patch
Filename: partition_key_collation.diff
Type: text/x-patch
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/optimizer/plan/planner.c | 25 | 3 |
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 948afd90..bf96c0ce 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -7998,6 +7998,10 @@ create_partitionwise_grouping_paths(PlannerInfo *root,
*
* Returns true, if all the partition keys of the given relation are part of
* the GROUP BY clauses, false otherwise.
+ * NB: partition key's collation is stored at part_scheme->partcollation.
+ * When comparing GROUP BY clauses with partition keys, we need check
+ * collation of part_scheme->partcollation, not the collation of input_rel->partexprs,
+ * since these two maybe different.
*/
static bool
group_by_has_partkey(RelOptInfo *input_rel,
@@ -8007,6 +8011,8 @@ group_by_has_partkey(RelOptInfo *input_rel,
List *groupexprs = get_sortgrouplist_exprs(groupClause, targetList);
int cnt = 0;
int partnatts;
+ Oid groupcoll = InvalidOid;
+ Oid partcoll = InvalidOid;
/* Input relation should be partitioned. */
Assert(input_rel->part_scheme);
@@ -8023,15 +8029,31 @@ group_by_has_partkey(RelOptInfo *input_rel,
ListCell *lc;
bool found = false;
+ partcoll = input_rel->part_scheme->partcollation[cnt];
foreach(lc, partexprs)
{
+ ListCell *lg;
Expr *partexpr = lfirst(lc);
- if (list_member(groupexprs, partexpr))
+ foreach(lg, groupexprs)
{
- found = true;
- break;
+ Expr *groupexpr = lfirst(lg);
+ groupcoll = exprCollation((Node *) groupexpr);
+
+ if (partcoll == groupcoll)
+ {
+ if (IsA(groupexpr, RelabelType))
+ groupexpr = ((RelabelType *) groupexpr)->arg;
+
+ if (equal(groupexpr, partexpr))
+ {
+ found = true;
+ break;
+ }
+ }
}
+ if (found)
+ break;
}
/*