fix_generate_setop_child_grouplist.patch
application/octet-stream
Filename: fix_generate_setop_child_grouplist.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/backend/optimizer/plan/planner.c | 21 | 1 |
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;
}