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

Commit07c741e

Browse files
committed
Fix oversight in planning of GROUP queries: when an expression is used
as both a GROUP BY item and an output expression, the top-level Groupnode should just copy up the evaluated expression value from its input,rather than re-evaluating the expression. Aside from any performancebenefit this might offer, this avoids a crash when there is a sub-SELECTin said expression.
1 parent4cb0950 commit07c741e

File tree

4 files changed

+67
-12
lines changed

4 files changed

+67
-12
lines changed

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

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.68 2000/10/26 21:36:09 tgl Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.69 2001/01/09 03:48:51 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
1616
#include<sys/types.h>
1717

1818
#include"postgres.h"
1919

20+
#include"nodes/makefuncs.h"
2021
#include"nodes/nodeFuncs.h"
2122
#include"optimizer/clauses.h"
2223
#include"optimizer/planmain.h"
@@ -270,22 +271,75 @@ set_join_references(Join *join)
270271
* to refer to the tuples returned by its lefttree subplan.
271272
*
272273
* This is used for single-input plan types like Agg, Group, Result.
274+
*
275+
* In most cases, we have to match up individual Vars in the tlist and
276+
* qual expressions with elements of the subplan's tlist (which was
277+
* generated by flatten_tlist() from these selfsame expressions, so it
278+
* should have all the required variables). There is an important exception,
279+
* however: a GROUP BY expression that is also an output expression will
280+
* have been pushed into the subplan tlist unflattened. We want to detect
281+
* this case and reference the subplan output directly. Therefore, check
282+
* for equality of the whole tlist expression to any subplan element before
283+
* we resort to picking the expression apart for individual Vars.
273284
*/
274285
staticvoid
275286
set_uppernode_references(Plan*plan,Indexsubvarno)
276287
{
277288
Plan*subplan=plan->lefttree;
278-
List*subplanTargetList;
289+
List*subplanTargetList,
290+
*outputTargetList,
291+
*l;
279292

280293
if (subplan!=NULL)
281294
subplanTargetList=subplan->targetlist;
282295
else
283296
subplanTargetList=NIL;
284297

285-
plan->targetlist= (List*)
286-
replace_vars_with_subplan_refs((Node*)plan->targetlist,
287-
subvarno,
288-
subplanTargetList);
298+
outputTargetList=NIL;
299+
foreach (l,plan->targetlist)
300+
{
301+
TargetEntry*tle= (TargetEntry*)lfirst(l);
302+
TargetEntry*subplantle;
303+
Node*newexpr;
304+
305+
subplantle=tlistentry_member(tle->expr,subplanTargetList);
306+
if (subplantle)
307+
{
308+
/* Found a matching subplan output expression */
309+
Resdom*resdom=subplantle->resdom;
310+
Var*newvar;
311+
312+
newvar=makeVar(subvarno,
313+
resdom->resno,
314+
resdom->restype,
315+
resdom->restypmod,
316+
0);
317+
/* If we're just copying a simple Var, copy up original info */
318+
if (subplantle->expr&&IsA(subplantle->expr,Var))
319+
{
320+
Var*subvar= (Var*)subplantle->expr;
321+
322+
newvar->varnoold=subvar->varnoold;
323+
newvar->varoattno=subvar->varoattno;
324+
}
325+
else
326+
{
327+
newvar->varnoold=0;
328+
newvar->varoattno=0;
329+
}
330+
newexpr= (Node*)newvar;
331+
}
332+
else
333+
{
334+
/* No matching expression, so replace individual Vars */
335+
newexpr=replace_vars_with_subplan_refs(tle->expr,
336+
subvarno,
337+
subplanTargetList);
338+
}
339+
outputTargetList=lappend(outputTargetList,
340+
makeTargetEntry(tle->resdom,newexpr));
341+
}
342+
plan->targetlist=outputTargetList;
289343

290344
plan->qual= (List*)
291345
replace_vars_with_subplan_refs((Node*)plan->qual,

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

Lines changed: 3 additions & 2 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-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.46 2000/11/21 00:17:59 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.47 2001/01/09 03:48:51 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -125,6 +125,7 @@ make_subplan(SubLink *slink)
125125
{
126126
SubPlan*node=makeNode(SubPlan);
127127
Query*subquery= (Query*) (slink->subselect);
128+
Oidresult_type=exprType((Node*)slink);
128129
doubletuple_fraction;
129130
Plan*plan;
130131
List*lst;
@@ -368,7 +369,7 @@ make_subplan(SubLink *slink)
368369
/*
369370
* Make expression of SUBPLAN type
370371
*/
371-
expr->typeOid=BOOLOID;/* bogus, but we don't really care */
372+
expr->typeOid=result_type;
372373
expr->opType=SUBPLAN_EXPR;
373374
expr->oper= (Node*)node;
374375

‎src/backend/optimizer/util/tlist.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/tlist.c,v 1.47 2000/08/08 15:41:53 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/tlist.c,v 1.48 2001/01/09 03:48:50 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -18,7 +18,6 @@
1818
#include"optimizer/tlist.h"
1919
#include"optimizer/var.h"
2020

21-
staticTargetEntry*tlistentry_member(Node*node,List*targetlist);
2221

2322
/*****************************************************************************
2423
*---------- RELATION node target list routines ----------
@@ -29,7 +28,7 @@ static TargetEntry *tlistentry_member(Node *node, List *targetlist);
2928
* Finds the (first) member of the given tlist whose expression is
3029
* equal() to the given expression.Result is NULL if no such member.
3130
*/
32-
staticTargetEntry*
31+
TargetEntry*
3332
tlistentry_member(Node*node,List*targetlist)
3433
{
3534
List*temp;

‎src/include/optimizer/tlist.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: tlist.h,v 1.26 2000/06/08 22:37:51 momjian Exp $
10+
* $Id: tlist.h,v 1.27 2001/01/09 03:48:50 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -16,6 +16,7 @@
1616

1717
#include"nodes/relation.h"
1818

19+
externTargetEntry*tlistentry_member(Node*node,List*targetlist);
1920
externResdom*tlist_member(Node*node,List*targetlist);
2021

2122
externvoidadd_var_to_tlist(RelOptInfo*rel,Var*var);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp