diff options
Diffstat (limited to 'src/backend/optimizer/plan/planner.c')
-rw-r--r-- | src/backend/optimizer/plan/planner.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index b68d532d31a..2d8b008607a 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -2533,7 +2533,8 @@ choose_hashed_distinct(PlannerInfo *root, * 'groupColIdx' receives an array of column numbers for the GROUP BY * expressions (if there are any) in the subplan's target list. * 'need_tlist_eval' is set true if we really need to evaluate the - * result tlist. + * returned tlist as-is. (Note: locate_grouping_columns assumes + * that if this is FALSE, all grouping columns are simple Vars.) * * The result is the targetlist to be passed to the subplan. */ @@ -2634,6 +2635,7 @@ make_subplanTargetList(PlannerInfo *root, * This is only needed if we don't use the sub_tlist chosen by * make_subplanTargetList. We have to forget the column indexes found * by that routine and re-locate the grouping exprs in the real sub_tlist. + * We assume the grouping exprs are just Vars (see make_subplanTargetList). */ static void locate_grouping_columns(PlannerInfo *root, @@ -2657,11 +2659,24 @@ locate_grouping_columns(PlannerInfo *root, foreach(gl, root->parse->groupClause) { SortGroupClause *grpcl = (SortGroupClause *) lfirst(gl); - Node *groupexpr = get_sortgroupclause_expr(grpcl, tlist); - TargetEntry *te = tlist_member(groupexpr, sub_tlist); + Var *groupexpr = (Var *) get_sortgroupclause_expr(grpcl, tlist); + TargetEntry *te; + /* + * The grouping column returned by create_plan might not have the same + * typmod as the original Var. (This can happen in cases where a + * set-returning function has been inlined, so that we now have more + * knowledge about what it returns than we did when the original Var + * was created.) So we can't use tlist_member() to search the tlist; + * instead use tlist_member_match_var. For safety, still check that + * the vartype matches. + */ + if (!(groupexpr && IsA(groupexpr, Var))) + elog(ERROR, "grouping column is not a Var as expected"); + te = tlist_member_match_var(groupexpr, sub_tlist); if (!te) elog(ERROR, "failed to locate grouping columns"); + Assert(((Var *) te->expr)->vartype == groupexpr->vartype); groupColIdx[keyno++] = te->resno; } } |