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

Commit49ed392

Browse files
committed
While doing the final setrefs.c pass over a plan tree, try to match up
non-Var sort/group expressions using ressortgroupref labels instead ofdepending entirely on equal()-ity of the upper node's tlist expressionsto the lower node's. This avoids emitting the wrong outputs in caseswhere there are textually identical volatile sort/group expressions,as for exampleselect distinct random(),random() from generate_series(1,10);Per report from Andrew Gierth.Backpatch to 8.4. Arguably this is wrong all the way back, but the only knowncase where there's an observable problem is when using hash aggregation toimplement DISTINCT, which is new as of 8.4. So for the moment I'll refrainfrom backpatching further.
1 parent66363e8 commit49ed392

File tree

1 file changed

+67
-5
lines changed

1 file changed

+67
-5
lines changed

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

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/optimizer/plan/setrefs.c,v 1.154 2009/10/26 02:26:34 tgl Exp $
12+
* $PostgreSQL: pgsql/src/backend/optimizer/plan/setrefs.c,v 1.155 2009/11/16 18:04:40 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -101,6 +101,10 @@ static Var *search_indexed_tlist_for_var(Var *var,
101101
staticVar*search_indexed_tlist_for_non_var(Node*node,
102102
indexed_tlist*itlist,
103103
Indexnewvarno);
104+
staticVar*search_indexed_tlist_for_sortgroupref(Node*node,
105+
Indexsortgroupref,
106+
indexed_tlist*itlist,
107+
Indexnewvarno);
104108
staticList*fix_join_expr(PlannerGlobal*glob,
105109
List*clauses,
106110
indexed_tlist*outer_itlist,
@@ -1197,10 +1201,25 @@ set_upper_references(PlannerGlobal *glob, Plan *plan, int rtoffset)
11971201
TargetEntry*tle= (TargetEntry*)lfirst(l);
11981202
Node*newexpr;
11991203

1200-
newexpr=fix_upper_expr(glob,
1201-
(Node*)tle->expr,
1202-
subplan_itlist,
1203-
rtoffset);
1204+
/* If it's a non-Var sort/group item, first try to match by sortref */
1205+
if (tle->ressortgroupref!=0&& !IsA(tle->expr,Var))
1206+
{
1207+
newexpr= (Node*)
1208+
search_indexed_tlist_for_sortgroupref((Node*)tle->expr,
1209+
tle->ressortgroupref,
1210+
subplan_itlist,
1211+
OUTER);
1212+
if (!newexpr)
1213+
newexpr=fix_upper_expr(glob,
1214+
(Node*)tle->expr,
1215+
subplan_itlist,
1216+
rtoffset);
1217+
}
1218+
else
1219+
newexpr=fix_upper_expr(glob,
1220+
(Node*)tle->expr,
1221+
subplan_itlist,
1222+
rtoffset);
12041223
tle=flatCopyTargetEntry(tle);
12051224
tle->expr= (Expr*)newexpr;
12061225
output_targetlist=lappend(output_targetlist,tle);
@@ -1444,6 +1463,49 @@ search_indexed_tlist_for_non_var(Node *node,
14441463
returnNULL;/* no match */
14451464
}
14461465

1466+
/*
1467+
* search_indexed_tlist_for_sortgroupref --- find a sort/group expression
1468+
*(which is assumed not to be just a Var)
1469+
*
1470+
* If a match is found, return a Var constructed to reference the tlist item.
1471+
* If no match, return NULL.
1472+
*
1473+
* This is needed to ensure that we select the right subplan TLE in cases
1474+
* where there are multiple textually-equal()-but-volatile sort expressions.
1475+
* And it's also faster than search_indexed_tlist_for_non_var.
1476+
*/
1477+
staticVar*
1478+
search_indexed_tlist_for_sortgroupref(Node*node,
1479+
Indexsortgroupref,
1480+
indexed_tlist*itlist,
1481+
Indexnewvarno)
1482+
{
1483+
ListCell*lc;
1484+
1485+
foreach(lc,itlist->tlist)
1486+
{
1487+
TargetEntry*tle= (TargetEntry*)lfirst(lc);
1488+
1489+
/* The equal() check should be redundant, but let's be paranoid */
1490+
if (tle->ressortgroupref==sortgroupref&&
1491+
equal(node,tle->expr))
1492+
{
1493+
/* Found a matching subplan output expression */
1494+
Var*newvar;
1495+
1496+
newvar=makeVar(newvarno,
1497+
tle->resno,
1498+
exprType((Node*)tle->expr),
1499+
exprTypmod((Node*)tle->expr),
1500+
0);
1501+
newvar->varnoold=0;/* wasn't ever a plain Var */
1502+
newvar->varoattno=0;
1503+
returnnewvar;
1504+
}
1505+
}
1506+
returnNULL;/* no match */
1507+
}
1508+
14471509
/*
14481510
* fix_join_expr
14491511
* Create a new set of targetlist entries or join qual clauses by

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp