Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit20a3ddb

Browse files
committed
Fix the handling of sub-SELECTs appearing in the arguments of an outer-level
aggregate function. By definition, such a sub-SELECT cannot reference anyvariables of query levels between itself and the aggregate's semantic level(else the aggregate would've been assigned to that lower level instead).So the correct, most efficient implementation is to treat the sub-SELECT asbeing a sub-select of that outer query level, not the level the aggregatesyntactically appears in. Not doing so also confuses the heck out of ourparameter-passing logic, as illustrated in bug report from Daniel Grace.Fortunately, we were already copying the whole Aggref expression up to theouter query level, so all that's needed is to delay SS_process_sublinksprocessing of the sub-SELECT until control returns to the outer level.This has been broken since we introduced spec-compliant treatment ofouter aggregates in 7.4; so patch all the way back.
1 parent245316e commit20a3ddb

File tree

3 files changed

+48
-3
lines changed

3 files changed

+48
-3
lines changed

‎src/backend/optimizer/plan/subselect.c

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.148 2009/04/05 19:59:40 tgl Exp $
10+
* $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.149 2009/04/25 16:44:56 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -437,13 +437,24 @@ build_subplan(PlannerInfo *root, Plan *plan, List *rtable,
437437

438438
if (pitem->abslevel==root->query_level)
439439
{
440-
splan->parParam=lappend_int(splan->parParam,paramid);
440+
Node*arg;
441+
441442
/*
442443
* The Var or Aggref has already been adjusted to have the correct
443444
* varlevelsup or agglevelsup.We probably don't even need to
444445
* copy it again, but be safe.
445446
*/
446-
splan->args=lappend(splan->args,copyObject(pitem->item));
447+
arg=copyObject(pitem->item);
448+
449+
/*
450+
* If it's an Aggref, its arguments might contain SubLinks,
451+
* which have not yet been processed. Do that now.
452+
*/
453+
if (IsA(arg,Aggref))
454+
arg=SS_process_sublinks(root,arg, false);
455+
456+
splan->parParam=lappend_int(splan->parParam,paramid);
457+
splan->args=lappend(splan->args,arg);
447458
}
448459
}
449460
bms_free(tmpset);
@@ -1531,6 +1542,12 @@ convert_EXISTS_to_ANY(PlannerInfo *root, Query *subselect,
15311542
* so after expanding its sublinks to subplans. And we don't want any steps
15321543
* in between, else those steps would never get applied to the aggregate
15331544
* argument expressions, either in the parent or the child level.
1545+
*
1546+
* Another fairly tricky thing going on here is the handling of SubLinks in
1547+
* the arguments of uplevel aggregates. Those are not touched inside the
1548+
* intermediate query level, either. Instead, SS_process_sublinks recurses
1549+
* on them after copying the Aggref expression into the parent plan level
1550+
* (this is actually taken care of in build_subplan).
15341551
*/
15351552
Node*
15361553
SS_replace_correlation_vars(PlannerInfo*root,Node*expr)
@@ -1607,6 +1624,18 @@ process_sublinks_mutator(Node *node, process_sublinks_context *context)
16071624
context->isTopQual);
16081625
}
16091626

1627+
/*
1628+
* Don't recurse into the arguments of an outer aggregate here.
1629+
* Any SubLinks in the arguments have to be dealt with at the outer
1630+
* query level; they'll be handled when build_subplan collects the
1631+
* Aggref into the arguments to be passed down to the current subplan.
1632+
*/
1633+
if (IsA(node,Aggref))
1634+
{
1635+
if (((Aggref*)node)->agglevelsup>0)
1636+
returnnode;
1637+
}
1638+
16101639
/*
16111640
* We should never see a SubPlan expression in the input (since this is
16121641
* the very routine that creates 'em to begin with). We shouldn't find

‎src/test/regress/expected/aggregates.out

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,16 @@ having exists (select 1 from onek b
295295
ERROR: aggregates not allowed in WHERE clause
296296
LINE 4: where sum(distinct a.four + b.four) = b.four)...
297297
^
298+
-- Test handling of sublinks within outer-level aggregates.
299+
-- Per bug report from Daniel Grace.
300+
select
301+
(select max((select i.unique2 from tenk1 i where i.unique1 = o.unique1)))
302+
from tenk1 o;
303+
?column?
304+
----------
305+
9999
306+
(1 row)
307+
298308
--
299309
-- test for bitwise integer aggregates
300310
--

‎src/test/regress/sql/aggregates.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,12 @@ group by ten
8080
having exists (select1from onek b
8181
wheresum(distincta.four+b.four)=b.four);
8282

83+
-- Test handling of sublinks within outer-level aggregates.
84+
-- Per bug report from Daniel Grace.
85+
select
86+
(selectmax((selecti.unique2from tenk1 iwherei.unique1=o.unique1)))
87+
from tenk1 o;
88+
8389
--
8490
-- test for bitwise integer aggregates
8591
--

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp