提交 96d92667 编写于 作者: S Shreedhar Hardikar 提交者: Chris Hajas

Fix wrong results for aggs containing a correlated subquery

This commit handles a missed case in the previous commit: "Fix
algebrization of subqueries in queries with complex GROUP BYs".

The logic inside RunExtractAggregatesMutator's Var case was intended to
fix top-level Vars inside subqueries in the targetlist, but also
incorrectly fixed top-level Vars in subqueries inside of aggregates.
上级 4ba11535
......@@ -808,12 +808,42 @@ CQueryMutators::RunExtractAggregatesMutator
{
// If Var references the top level query inside an Aggref that also
// references top level query, the Aggref is moved to the derived query
// (see comments in Aggref if-case above). Thus, these Vars reference
// (see comments in Aggref if-case above). Thus, these Var references
// are brought up to the top-query level.
// e.g:
// explain select (select sum(foo.a) from jazz) from foo group by a, b;
// is transformed into
// select (select fnew.sum_t from jazz)
// from (select foo.a, foo.b, sum(foo.a) sum_t
// from foo group by foo.a, foo.b) fnew;
//
// Note the foo.a var which is in sum() in a subquery must now become a
// var referencing the current query level.
var->varlevelsup = 0;
return (Node *) var;
}
// Skip vars inside Aggrefs, since they have already been fixed when they
// were moved into the derived query in ConvertToDerivedTable(), and thus,
// the relative varno, varattno & varlevelsup should still be valid.
// e.g:
// SELECT foo.b+1, avg(( SELECT bar.f FROM bar
// WHERE bar.d = foo.b)) AS t
// FROM foo GROUP BY foo.b;
// is transformed into
// SELECT fnew.b+1, fnew.avg_t
// FROM (SELECT foo.b,`avg(( SELECT bar.f FROM bar
// WHERE bar.d = foo.b)) AS t
// FROM foo) fnew;
//
// Note the foo.b outerref in subquery inside the avg() aggregation.
// Because it is inside the aggregation, it was pushed down along with
// the aggregate function, and thus does not need to be fixed.
if (context->m_is_mutating_agg_arg)
{
return (Node *) var;
}
// For other top-level references, correct their varno & varattno, since
// they now must refer to the target list of the derived query - whose
// target list may be different from the original query.
......
......@@ -374,7 +374,7 @@ select
(select max((select i.unique2 from tenk1 i where i.unique1 = o.unique1)))
from tenk1 o;
INFO: GPORCA failed to produce a plan, falling back to planner
DETAIL: Query-to-DXL Translation: No attribute entry found due to incorrect normalization of query
DETAIL: Query-to-DXL Translation: No variable entry found due to incorrect normalization of query
max
------
9999
......@@ -1453,7 +1453,7 @@ select
filter (where o.unique1 < 10))
from tenk1 o; -- outer query is aggregation query
INFO: GPORCA failed to produce a plan, falling back to planner
DETAIL: Query-to-DXL Translation: No attribute entry found due to incorrect normalization of query
DETAIL: Feature not supported: Aggregate functions with FILTER
max
------
9998
......@@ -1925,7 +1925,7 @@ select
filter (where o.unique1 < 10))
from tenk1 o; -- outer query is aggregation query
INFO: GPORCA failed to produce a plan, falling back to planner
DETAIL: Query-to-DXL Translation: No attribute entry found due to incorrect normalization of query
DETAIL: Feature not supported: Aggregate functions with FILTER
max
------
9998
......
......@@ -8762,9 +8762,37 @@ select max(b), (select foo.a * count(bar.e) from bar), (with cte as (select e, m
select b + (a+1) from foo group by b, a+1;
?column?
----------
7
3
5
3
7
(3 rows)
-- subselects inside aggs
SELECT foo.b+1, avg (( SELECT bar.f FROM bar WHERE bar.d = foo.b)) AS t FROM foo GROUP BY foo.b;
?column? | t
----------+------------------------
3 | 2.0000000000000000
4 | 3.0000000000000000
2 | 1.00000000000000000000
(3 rows)
SELECT foo.b+1, sum( 1 + (SELECT bar.f FROM bar WHERE bar.d = ANY (SELECT jazz.g FROM jazz WHERE jazz.h = foo.b))) AS t FROM foo GROUP BY foo.b;
ERROR: correlated subquery with skip-level correlations is not supported
select foo.b+1, sum((with cte as (select * from jazz) select 1 from cte where cte.h = foo.b)) as t FROM foo GROUP BY foo.b;
?column? | t
----------+---
3 | 1
4 |
2 |
(3 rows)
-- ctes inside aggs
select foo.b+1, sum((with cte as (select * from jazz) select 1 from cte cte1, cte cte2 where cte1.h = foo.b)) as t FROM foo GROUP BY foo.b;
?column? | t
----------+---
3 | 1
4 |
2 |
(3 rows)
drop table foo, bar, jazz;
......
......@@ -8793,6 +8793,42 @@ select b + (a+1) from foo group by b, a+1;
7
(3 rows)
-- subselects inside aggs
SELECT foo.b+1, avg (( SELECT bar.f FROM bar WHERE bar.d = foo.b)) AS t FROM foo GROUP BY foo.b;
?column? | t
----------+------------------------
2 | 1.00000000000000000000
3 | 2.0000000000000000
4 | 3.0000000000000000
(3 rows)
SELECT foo.b+1, sum( 1 + (SELECT bar.f FROM bar WHERE bar.d = ANY (SELECT jazz.g FROM jazz WHERE jazz.h = foo.b))) AS t FROM foo GROUP BY foo.b;
?column? | t
----------+---
2 |
3 | 3
4 |
(3 rows)
select foo.b+1, sum((with cte as (select * from jazz) select 1 from cte where cte.h = foo.b)) as t FROM foo GROUP BY foo.b;
?column? | t
----------+---
2 |
3 | 1
4 |
(3 rows)
-- ctes inside aggs
select foo.b+1, sum((with cte as (select * from jazz) select 1 from cte cte1, cte cte2 where cte1.h = foo.b)) as t FROM foo GROUP BY foo.b;
INFO: GPORCA failed to produce a plan, falling back to planner
DETAIL: No plan has been computed for required properties
?column? | t
----------+---
3 | 1
4 |
2 |
(3 rows)
drop table foo, bar, jazz;
create table orca.t77(C952 text) WITH (compresstype=zlib,compresslevel=2,appendonly=true,blocksize=393216,checksum=true);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c952' as the Greenplum Database data distribution key for this table.
......
......@@ -727,6 +727,16 @@ select max(b), (select foo.a * count(bar.e) from bar), (with cte as (select e, m
-- complex expression in group by & targetlist
select b + (a+1) from foo group by b, a+1;
-- subselects inside aggs
SELECT foo.b+1, avg (( SELECT bar.f FROM bar WHERE bar.d = foo.b)) AS t FROM foo GROUP BY foo.b;
SELECT foo.b+1, sum( 1 + (SELECT bar.f FROM bar WHERE bar.d = ANY (SELECT jazz.g FROM jazz WHERE jazz.h = foo.b))) AS t FROM foo GROUP BY foo.b;
select foo.b+1, sum((with cte as (select * from jazz) select 1 from cte where cte.h = foo.b)) as t FROM foo GROUP BY foo.b;
-- ctes inside aggs
select foo.b+1, sum((with cte as (select * from jazz) select 1 from cte cte1, cte cte2 where cte1.h = foo.b)) as t FROM foo GROUP BY foo.b;
drop table foo, bar, jazz;
create table orca.t77(C952 text) WITH (compresstype=zlib,compresslevel=2,appendonly=true,blocksize=393216,checksum=true);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册