Skip to content

Commit 6a81ba1

Browse files
committed
Make setrefs.c match by ressortgroupref even for plain Vars.
Previously, we skipped using search_indexed_tlist_for_sortgroupref() if the tlist expression being sought in the child plan node was merely a Var. This is purely an optimization, based on the theory that search_indexed_tlist_for_var() is faster, and one copy of a Var should be as good as another. However, the GROUPING SETS patch broke the latter assumption: grouping columns containing the "same" Var can sometimes have different outputs, as shown in the test case added here. So do it the hard way whenever a ressortgroupref marking exists. (If this seems like a bottleneck, we could imagine building a tlist index data structure for ressortgroupref values, as we do for Vars. But I'll let that idea go until there's some evidence it's worthwhile.) Back-patch to 9.6. The problem also exists in 9.5 where GROUPING SETS came in, but this patch is insufficient to resolve the problem in 9.5: there is some obscure dependency on the upper-planner-pathification work that happened in 9.6. Given that this is such a weird corner case, and no end users have complained about it, it doesn't seem worth the work to develop a fix for 9.5. Patch by me, per a report from Heikki Linnakangas. (This does not fix Heikki's original complaint, just the follow-on one.) Discussion: https://postgr.es/m/aefc657e-edb2-64d5-6df1-a0828f6e9104@iki.fi
1 parent a9d4625 commit 6a81ba1

File tree

3 files changed

+42
-3
lines changed

3 files changed

+42
-3
lines changed

src/backend/optimizer/plan/setrefs.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1746,8 +1746,8 @@ set_upper_references(PlannerInfo *root, Plan *plan, int rtoffset)
17461746
TargetEntry *tle = (TargetEntry *) lfirst(l);
17471747
Node *newexpr;
17481748

1749-
/* If it's a non-Var sort/group item, first try to match by sortref */
1750-
if (tle->ressortgroupref != 0 && !IsA(tle->expr, Var))
1749+
/* If it's a sort/group item, first try to match by sortref */
1750+
if (tle->ressortgroupref != 0)
17511751
{
17521752
newexpr = (Node *)
17531753
search_indexed_tlist_for_sortgroupref(tle->expr,
@@ -2108,7 +2108,6 @@ search_indexed_tlist_for_non_var(Expr *node,
21082108

21092109
/*
21102110
* search_indexed_tlist_for_sortgroupref --- find a sort/group expression
2111-
* (which is assumed not to be just a Var)
21122111
*
21132112
* If a match is found, return a Var constructed to reference the tlist item.
21142113
* If no match, return NULL.

src/test/regress/expected/groupingsets.out

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,35 @@ select a, d, grouping(a,b,c)
360360
2 | 2 | 2
361361
(4 rows)
362362

363+
-- check that distinct grouping columns are kept separate
364+
-- even if they are equal()
365+
explain (costs off)
366+
select g as alias1, g as alias2
367+
from generate_series(1,3) g
368+
group by alias1, rollup(alias2);
369+
QUERY PLAN
370+
------------------------------------------------
371+
GroupAggregate
372+
Group Key: g, g
373+
Group Key: g
374+
-> Sort
375+
Sort Key: g
376+
-> Function Scan on generate_series g
377+
(6 rows)
378+
379+
select g as alias1, g as alias2
380+
from generate_series(1,3) g
381+
group by alias1, rollup(alias2);
382+
alias1 | alias2
383+
--------+--------
384+
1 | 1
385+
1 |
386+
2 | 2
387+
2 |
388+
3 | 3
389+
3 |
390+
(6 rows)
391+
363392
-- simple rescan tests
364393
select a, b, sum(v.x)
365394
from (values (1),(2)) v(x), gstest_data(v.x)

src/test/regress/sql/groupingsets.sql

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,17 @@ select a, d, grouping(a,b,c)
141141
from gstest3
142142
group by grouping sets ((a,b), (a,c));
143143

144+
-- check that distinct grouping columns are kept separate
145+
-- even if they are equal()
146+
explain (costs off)
147+
select g as alias1, g as alias2
148+
from generate_series(1,3) g
149+
group by alias1, rollup(alias2);
150+
151+
select g as alias1, g as alias2
152+
from generate_series(1,3) g
153+
group by alias1, rollup(alias2);
154+
144155
-- simple rescan tests
145156

146157
select a, b, sum(v.x)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy