static bool
simplify_EXISTS_query(PlannerInfo *root, Query *query)
{
- ListCell *lc;
-
/*
* We don't try to simplify at all if the query uses set operations,
* aggregates, grouping sets, SRFs, modifying CTEs, HAVING, OFFSET, or FOR
query->hasDistinctOn = false;
/*
- * Since we have thrown away the GROUP BY clauses, we'd better remove the
- * RTE_GROUP RTE and clear the hasGroupRTE flag.
+ * Since we have thrown away the GROUP BY clauses, we'd better get rid of
+ * the RTE_GROUP RTE and clear the hasGroupRTE flag. To safely get rid of
+ * the RTE_GROUP RTE without shifting the index of any subsequent RTE in
+ * the rtable, we convert the RTE to be RTE_RESULT type in-place, and zero
+ * out RTE_GROUP-specific fields.
*/
- foreach(lc, query->rtable)
+ if (query->hasGroupRTE)
{
- RangeTblEntry *rte = lfirst_node(RangeTblEntry, lc);
-
- /*
- * Remove the RTE_GROUP RTE and clear the hasGroupRTE flag. (Since
- * we'll exit the foreach loop immediately, we don't bother with
- * foreach_delete_current.)
- */
- if (rte->rtekind == RTE_GROUP)
+ foreach_node(RangeTblEntry, rte, query->rtable)
{
- Assert(query->hasGroupRTE);
- query->rtable = list_delete_cell(query->rtable, lc);
- query->hasGroupRTE = false;
- break;
+ if (rte->rtekind == RTE_GROUP)
+ {
+ rte->rtekind = RTE_RESULT;
+ rte->groupexprs = NIL;
+
+ /* A query should only have one RTE_GROUP, so we can stop. */
+ break;
+ }
}
+
+ query->hasGroupRTE = false;
}
return true;