diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index e92e108b6b..29e55725cb 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -8077,7 +8077,11 @@ group_by_has_partkey(RelOptInfo *input_rel, * child query's targetlist entries may already have a tleSortGroupRef * assigned for other purposes, such as GROUP BYs. Here we keep the * SortGroupClause list in the same order as 'op' groupClauses and just adjust - * the tleSortGroupRef to reference the TargetEntry's 'ressortgroupref'. + * the tleSortGroupRef to reference the TargetEntry's 'ressortgroupref'. If + * any of the columns in the targetlist don't match to the setop's colTypes + * or if there is no sort operator for the setop's groupClauses then we return + * an empty list. This may leave some TLEs with unreferenced ressortgroupref + * markings, but that's harmless. */ static List * generate_setop_child_grouplist(SetOperationStmt *op, List *targetlist) @@ -8085,12 +8089,15 @@ generate_setop_child_grouplist(SetOperationStmt *op, List *targetlist) List *grouplist = copyObject(op->groupClauses); ListCell *lg; ListCell *lt; + ListCell *ct; lg = list_head(grouplist); + ct = list_head(op->colTypes); foreach(lt, targetlist) { TargetEntry *tle = (TargetEntry *) lfirst(lt); SortGroupClause *sgc; + Oid coltype; /* resjunk columns could have sortgrouprefs. Leave these alone */ if (tle->resjunk) @@ -8099,11 +8106,24 @@ generate_setop_child_grouplist(SetOperationStmt *op, List *targetlist) /* we expect every non-resjunk target to have a SortGroupClause */ Assert(lg != NULL); sgc = (SortGroupClause *) lfirst(lg); + + if (!OidIsValid(sgc->sortop)) + return NIL; + + coltype = lfirst_oid(ct); + + if (coltype != exprType((Node *) tle->expr)) + return NIL; + lg = lnext(grouplist, lg); + ct = lnext(op->colTypes, ct); /* assign a tleSortGroupRef, or reuse the existing one */ sgc->tleSortGroupRef = assignSortGroupRef(tle, targetlist); } + Assert(lg == NULL); + Assert(ct == NULL); + return grouplist; }