Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit ffe12d1

Browse files
author
Richard Guo
committed
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
1 parent d32d146 commit ffe12d1

File tree

3 files changed

+47
-0
lines changed

3 files changed

+47
-0
lines changed

src/backend/optimizer/plan/subselect.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1539,6 +1539,8 @@ convert_EXISTS_sublink_to_join(PlannerInfo *root, SubLink *sublink,
15391539
static bool
15401540
simplify_EXISTS_query(PlannerInfo *root, Query *query)
15411541
{
1542+
ListCell *lc;
1543+
15421544
/*
15431545
* We don't try to simplify at all if the query uses set operations,
15441546
* aggregates, grouping sets, SRFs, modifying CTEs, HAVING, OFFSET, or FOR
@@ -1607,6 +1609,28 @@ simplify_EXISTS_query(PlannerInfo *root, Query *query)
16071609
query->sortClause = NIL;
16081610
query->hasDistinctOn = false;
16091611

1612+
/*
1613+
* Since we have thrown away the GROUP BY clauses, we'd better remove the
1614+
* RTE_GROUP RTE and clear the hasGroupRTE flag.
1615+
*/
1616+
foreach(lc, query->rtable)
1617+
{
1618+
RangeTblEntry *rte = lfirst_node(RangeTblEntry, lc);
1619+
1620+
/*
1621+
* Remove the RTE_GROUP RTE and clear the hasGroupRTE flag. (Since
1622+
* we'll exit the foreach loop immediately, we don't bother with
1623+
* foreach_delete_current.)
1624+
*/
1625+
if (rte->rtekind == RTE_GROUP)
1626+
{
1627+
Assert(query->hasGroupRTE);
1628+
query->rtable = list_delete_cell(query->rtable, lc);
1629+
query->hasGroupRTE = false;
1630+
break;
1631+
}
1632+
}
1633+
16101634
return true;
16111635
}
16121636

src/test/regress/expected/join.out

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3182,6 +3182,21 @@ where b.unique2 is null;
31823182
-> Index Only Scan using tenk1_unique2 on tenk1 b
31833183
(5 rows)
31843184

3185+
--
3186+
-- regression test for bogus RTE_GROUP entries
3187+
--
3188+
explain (costs off)
3189+
select a.* from tenk1 a
3190+
where exists (select 1 from tenk1 b where a.unique1 = b.unique2 group by b.unique1);
3191+
QUERY PLAN
3192+
------------------------------------------------------------
3193+
Hash Semi Join
3194+
Hash Cond: (a.unique1 = b.unique2)
3195+
-> Seq Scan on tenk1 a
3196+
-> Hash
3197+
-> Index Only Scan using tenk1_unique2 on tenk1 b
3198+
(5 rows)
3199+
31853200
--
31863201
-- regression test for proper handling of outer joins within antijoins
31873202
--

src/test/regress/sql/join.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,14 @@ explain (costs off)
818818
select a.* from tenk1 a left join tenk1 b on a.unique1 = b.unique2
819819
where b.unique2 is null;
820820

821+
--
822+
-- regression test for bogus RTE_GROUP entries
823+
--
824+
825+
explain (costs off)
826+
select a.* from tenk1 a
827+
where exists (select 1 from tenk1 b where a.unique1 = b.unique2 group by b.unique1);
828+
821829
--
822830
-- regression test for proper handling of outer joins within antijoins
823831
--

0 commit comments

Comments
 (0)