diff options
author | Richard Guo <rguo@postgresql.org> | 2024-10-25 09:52:34 +0900 |
---|---|---|
committer | Richard Guo <rguo@postgresql.org> | 2024-10-25 09:52:34 +0900 |
commit | ffe12d1d22e73d7bcda1f0ee9af33d04fab199b2 (patch) | |
tree | 6c3d75e8cd6531fde2be443996e116300ef21643 /src/backend/optimizer/plan/subselect.c | |
parent | d32d1463995c036853eeb9ec99cc367ffc7794ae (diff) | |
download | postgresql-ffe12d1d22e73d7bcda1f0ee9af33d04fab199b2.tar.gz postgresql-ffe12d1d22e73d7bcda1f0ee9af33d04fab199b2.zip |
Remove the RTE_GROUP RTE if we drop the groupClause
For an EXISTS subquery, the only thing that matters is whether it
returns zero or more than zero rows. Therefore, we remove certain SQL
features that won't affect that, among them the GROUP BY clauses.
After we drop the groupClause, we'd better remove the RTE_GROUP RTE
and clear the hasGroupRTE flag, as they depend on the groupClause.
Failing to do so could result in a bogus RTE_GROUP entry in the parent
query, leading to an assertion failure on the hasGroupRTE flag.
Reported-by: David Rowley
Author: Richard Guo
Discussion: https://postgr.es/m/CAApHDvp2_yht8uPLyWO-kVGWZhYvx5zjGfSrg4fBQ9fsC13V0g@mail.gmail.com
Diffstat (limited to 'src/backend/optimizer/plan/subselect.c')
-rw-r--r-- | src/backend/optimizer/plan/subselect.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c index 6d003cc8e5c..09d5f0f571b 100644 --- a/src/backend/optimizer/plan/subselect.c +++ b/src/backend/optimizer/plan/subselect.c @@ -1539,6 +1539,8 @@ convert_EXISTS_sublink_to_join(PlannerInfo *root, SubLink *sublink, 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 @@ -1607,6 +1609,28 @@ simplify_EXISTS_query(PlannerInfo *root, Query *query) query->sortClause = NIL; 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. + */ + foreach(lc, query->rtable) + { + 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) + { + Assert(query->hasGroupRTE); + query->rtable = list_delete_cell(query->rtable, lc); + query->hasGroupRTE = false; + break; + } + } + return true; } |