Skip to content

Commit 08f1e1f

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 74d2c0d commit 08f1e1f

File tree

3 files changed

+43
-4
lines changed

3 files changed

+43
-4
lines changed

src/backend/optimizer/plan/setrefs.c

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

1747-
/* If it's a non-Var sort/group item, first try to match by sortref */
1748-
if (tle->ressortgroupref != 0 && !IsA(tle->expr, Var))
1747+
/* If it's a sort/group item, first try to match by sortref */
1748+
if (tle->ressortgroupref != 0)
17491749
{
17501750
newexpr = (Node *)
17511751
search_indexed_tlist_for_sortgroupref(tle->expr,
@@ -2113,7 +2113,6 @@ search_indexed_tlist_for_non_var(Expr *node,
21132113

21142114
/*
21152115
* search_indexed_tlist_for_sortgroupref --- find a sort/group expression
2116-
* (which is assumed not to be just a Var)
21172116
*
21182117
* If a match is found, return a Var constructed to reference the tlist item.
21192118
* If no match, return NULL.
@@ -2644,7 +2643,7 @@ is_converted_whole_row_reference(Node *node)
26442643

26452644
if (IsA(convexpr->arg, Var))
26462645
{
2647-
Var *var = castNode(Var, convexpr->arg);
2646+
Var *var = castNode(Var, convexpr->arg);
26482647

26492648
if (var->varattno == 0)
26502649
return true;

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