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

Commite6ae3b5

Browse files
committed
Add a concept of "placeholder" variables to the planner. These are variables
that represent some expression that we desire to compute below the top levelof the plan, and then let that value "bubble up" as though it were a plainVar (ie, a column value).The immediate application is to allow sub-selects to be flattened even whenthey are below an outer join and have non-nullable output expressions.Formerly we couldn't flatten because such an expression wouldn't properlygo to NULL when evaluated above the outer join. Now, we wrap it in aPlaceHolderVar and arrange for the actual evaluation to occur below the outerjoin. When the resulting Var bubbles up through the join, it will be set toNULL if necessary, yielding the correct results. This fixes a plannerlimitation that's existed since 7.1.In future we might want to use this mechanism to re-introduce some form ofHellerstein's "expensive functions" optimization, ie place the evaluation ofan expensive function at the most suitable point in the plan tree.
1 parent831abae commite6ae3b5

28 files changed

+1134
-225
lines changed

‎src/backend/nodes/copyfuncs.c

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Portions Copyright (c) 1994, Regents of the University of California
1616
*
1717
* IDENTIFICATION
18-
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.408 2008/10/07 19:27:04 tgl Exp $
18+
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.409 2008/10/21 20:42:52 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -1592,6 +1592,22 @@ _copyFlattenedSubLink(FlattenedSubLink *from)
15921592
returnnewnode;
15931593
}
15941594

1595+
/*
1596+
* _copyPlaceHolderVar
1597+
*/
1598+
staticPlaceHolderVar*
1599+
_copyPlaceHolderVar(PlaceHolderVar*from)
1600+
{
1601+
PlaceHolderVar*newnode=makeNode(PlaceHolderVar);
1602+
1603+
COPY_NODE_FIELD(phexpr);
1604+
COPY_BITMAPSET_FIELD(phrels);
1605+
COPY_SCALAR_FIELD(phid);
1606+
COPY_SCALAR_FIELD(phlevelsup);
1607+
1608+
returnnewnode;
1609+
}
1610+
15951611
/*
15961612
* _copySpecialJoinInfo
15971613
*/
@@ -1631,6 +1647,23 @@ _copyAppendRelInfo(AppendRelInfo *from)
16311647
returnnewnode;
16321648
}
16331649

1650+
/*
1651+
* _copyPlaceHolderInfo
1652+
*/
1653+
staticPlaceHolderInfo*
1654+
_copyPlaceHolderInfo(PlaceHolderInfo*from)
1655+
{
1656+
PlaceHolderInfo*newnode=makeNode(PlaceHolderInfo);
1657+
1658+
COPY_SCALAR_FIELD(phid);
1659+
COPY_NODE_FIELD(ph_var);
1660+
COPY_BITMAPSET_FIELD(ph_eval_at);
1661+
COPY_BITMAPSET_FIELD(ph_needed);
1662+
COPY_SCALAR_FIELD(ph_width);
1663+
1664+
returnnewnode;
1665+
}
1666+
16341667
/* ****************************************************************
16351668
*parsenodes.h copy functions
16361669
* ****************************************************************
@@ -3438,12 +3471,18 @@ copyObject(void *from)
34383471
caseT_FlattenedSubLink:
34393472
retval=_copyFlattenedSubLink(from);
34403473
break;
3474+
caseT_PlaceHolderVar:
3475+
retval=_copyPlaceHolderVar(from);
3476+
break;
34413477
caseT_SpecialJoinInfo:
34423478
retval=_copySpecialJoinInfo(from);
34433479
break;
34443480
caseT_AppendRelInfo:
34453481
retval=_copyAppendRelInfo(from);
34463482
break;
3483+
caseT_PlaceHolderInfo:
3484+
retval=_copyPlaceHolderInfo(from);
3485+
break;
34473486

34483487
/*
34493488
* VALUE NODES

‎src/backend/nodes/equalfuncs.c

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
* Portions Copyright (c) 1994, Regents of the University of California
2323
*
2424
* IDENTIFICATION
25-
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.333 2008/10/06 17:39:26 tgl Exp $
25+
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.334 2008/10/21 20:42:52 tgl Exp $
2626
*
2727
*-------------------------------------------------------------------------
2828
*/
@@ -763,6 +763,27 @@ _equalFlattenedSubLink(FlattenedSubLink *a, FlattenedSubLink *b)
763763
return true;
764764
}
765765

766+
staticbool
767+
_equalPlaceHolderVar(PlaceHolderVar*a,PlaceHolderVar*b)
768+
{
769+
/*
770+
* We intentionally do not compare phexpr. Two PlaceHolderVars with the
771+
* same ID and levelsup should be considered equal even if the contained
772+
* expressions have managed to mutate to different states. One way in
773+
* which that can happen is that initplan sublinks would get replaced by
774+
* differently-numbered Params when sublink folding is done. (The end
775+
* result of such a situation would be some unreferenced initplans, which
776+
* is annoying but not really a problem.)
777+
*
778+
* COMPARE_NODE_FIELD(phexpr);
779+
*/
780+
COMPARE_BITMAPSET_FIELD(phrels);
781+
COMPARE_SCALAR_FIELD(phid);
782+
COMPARE_SCALAR_FIELD(phlevelsup);
783+
784+
return true;
785+
}
786+
766787
staticbool
767788
_equalSpecialJoinInfo(SpecialJoinInfo*a,SpecialJoinInfo*b)
768789
{
@@ -792,6 +813,18 @@ _equalAppendRelInfo(AppendRelInfo *a, AppendRelInfo *b)
792813
return true;
793814
}
794815

816+
staticbool
817+
_equalPlaceHolderInfo(PlaceHolderInfo*a,PlaceHolderInfo*b)
818+
{
819+
COMPARE_SCALAR_FIELD(phid);
820+
COMPARE_NODE_FIELD(ph_var);
821+
COMPARE_BITMAPSET_FIELD(ph_eval_at);
822+
COMPARE_BITMAPSET_FIELD(ph_needed);
823+
COMPARE_SCALAR_FIELD(ph_width);
824+
825+
return true;
826+
}
827+
795828

796829
/*
797830
* Stuff from parsenodes.h
@@ -2289,12 +2322,19 @@ equal(void *a, void *b)
22892322
caseT_FlattenedSubLink:
22902323
retval=_equalFlattenedSubLink(a,b);
22912324
break;
2325+
caseT_PlaceHolderVar:
2326+
retval=_equalPlaceHolderVar(a,b);
2327+
break;
22922328
caseT_SpecialJoinInfo:
22932329
retval=_equalSpecialJoinInfo(a,b);
22942330
break;
22952331
caseT_AppendRelInfo:
22962332
retval=_equalAppendRelInfo(a,b);
22972333
break;
2334+
caseT_PlaceHolderInfo:
2335+
retval=_equalPlaceHolderInfo(a,b);
2336+
break;
2337+
22982338
caseT_List:
22992339
caseT_IntList:
23002340
caseT_OidList:

‎src/backend/nodes/nodeFuncs.c

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/nodes/nodeFuncs.c,v 1.34 2008/10/06 17:39:26 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/nodes/nodeFuncs.c,v 1.35 2008/10/21 20:42:52 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -220,6 +220,9 @@ exprType(Node *expr)
220220
caseT_CurrentOfExpr:
221221
type=BOOLOID;
222222
break;
223+
caseT_PlaceHolderVar:
224+
type=exprType((Node*) ((PlaceHolderVar*)expr)->phexpr);
225+
break;
223226
default:
224227
elog(ERROR,"unrecognized node type: %d", (int)nodeTag(expr));
225228
type=InvalidOid;/* keep compiler quiet */
@@ -420,6 +423,8 @@ exprTypmod(Node *expr)
420423
return ((CoerceToDomainValue*)expr)->typeMod;
421424
caseT_SetToDefault:
422425
return ((SetToDefault*)expr)->typeMod;
426+
caseT_PlaceHolderVar:
427+
returnexprTypmod((Node*) ((PlaceHolderVar*)expr)->phexpr);
423428
default:
424429
break;
425430
}
@@ -876,6 +881,10 @@ exprLocation(Node *expr)
876881
caseT_CommonTableExpr:
877882
loc= ((CommonTableExpr*)expr)->location;
878883
break;
884+
caseT_PlaceHolderVar:
885+
/* just use argument's location */
886+
loc=exprLocation((Node*) ((PlaceHolderVar*)expr)->phexpr);
887+
break;
879888
default:
880889
/* for any other node type it's just unknown... */
881890
loc=-1;
@@ -1272,11 +1281,12 @@ expression_tree_walker(Node *node,
12721281
{
12731282
FlattenedSubLink*fslink= (FlattenedSubLink*)node;
12741283

1275-
if (expression_tree_walker((Node*)fslink->quals,
1276-
walker,context))
1284+
if (walker(fslink->quals,context))
12771285
return true;
12781286
}
12791287
break;
1288+
caseT_PlaceHolderVar:
1289+
returnwalker(((PlaceHolderVar*)node)->phexpr,context);
12801290
caseT_AppendRelInfo:
12811291
{
12821292
AppendRelInfo*appinfo= (AppendRelInfo*)node;
@@ -1286,6 +1296,8 @@ expression_tree_walker(Node *node,
12861296
return true;
12871297
}
12881298
break;
1299+
caseT_PlaceHolderInfo:
1300+
returnwalker(((PlaceHolderInfo*)node)->ph_var,context);
12891301
default:
12901302
elog(ERROR,"unrecognized node type: %d",
12911303
(int)nodeTag(node));
@@ -1918,6 +1930,17 @@ expression_tree_mutator(Node *node,
19181930
return (Node*)newnode;
19191931
}
19201932
break;
1933+
caseT_PlaceHolderVar:
1934+
{
1935+
PlaceHolderVar*phv= (PlaceHolderVar*)node;
1936+
PlaceHolderVar*newnode;
1937+
1938+
FLATCOPY(newnode,phv,PlaceHolderVar);
1939+
MUTATE(newnode->phexpr,phv->phexpr,Expr*);
1940+
/* Assume we need not copy the relids bitmapset */
1941+
return (Node*)newnode;
1942+
}
1943+
break;
19211944
caseT_AppendRelInfo:
19221945
{
19231946
AppendRelInfo*appinfo= (AppendRelInfo*)node;
@@ -1928,6 +1951,17 @@ expression_tree_mutator(Node *node,
19281951
return (Node*)newnode;
19291952
}
19301953
break;
1954+
caseT_PlaceHolderInfo:
1955+
{
1956+
PlaceHolderInfo*phinfo= (PlaceHolderInfo*)node;
1957+
PlaceHolderInfo*newnode;
1958+
1959+
FLATCOPY(newnode,phinfo,PlaceHolderInfo);
1960+
MUTATE(newnode->ph_var,phinfo->ph_var,PlaceHolderVar*);
1961+
/* Assume we need not copy the relids bitmapsets */
1962+
return (Node*)newnode;
1963+
}
1964+
break;
19311965
default:
19321966
elog(ERROR,"unrecognized node type: %d",
19331967
(int)nodeTag(node));

‎src/backend/nodes/outfuncs.c

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.342 2008/10/07 19:27:04 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.343 2008/10/21 20:42:52 tgl Exp $
1212
*
1313
* NOTES
1414
* Every node type that can appear in stored rules' parsetrees *must*
@@ -1412,6 +1412,8 @@ _outPlannerGlobal(StringInfo str, PlannerGlobal *node)
14121412
WRITE_NODE_FIELD(finalrtable);
14131413
WRITE_NODE_FIELD(relationOids);
14141414
WRITE_NODE_FIELD(invalItems);
1415+
WRITE_UINT_FIELD(lastPHId);
1416+
WRITE_BOOL_FIELD(transientPlan);
14151417
}
14161418

14171419
staticvoid
@@ -1435,6 +1437,7 @@ _outPlannerInfo(StringInfo str, PlannerInfo *node)
14351437
WRITE_NODE_FIELD(full_join_clauses);
14361438
WRITE_NODE_FIELD(join_info_list);
14371439
WRITE_NODE_FIELD(append_rel_list);
1440+
WRITE_NODE_FIELD(placeholder_list);
14381441
WRITE_NODE_FIELD(query_pathkeys);
14391442
WRITE_NODE_FIELD(group_pathkeys);
14401443
WRITE_NODE_FIELD(distinct_pathkeys);
@@ -1590,6 +1593,17 @@ _outFlattenedSubLink(StringInfo str, FlattenedSubLink *node)
15901593
WRITE_NODE_FIELD(quals);
15911594
}
15921595

1596+
staticvoid
1597+
_outPlaceHolderVar(StringInfostr,PlaceHolderVar*node)
1598+
{
1599+
WRITE_NODE_TYPE("PLACEHOLDERVAR");
1600+
1601+
WRITE_NODE_FIELD(phexpr);
1602+
WRITE_BITMAPSET_FIELD(phrels);
1603+
WRITE_UINT_FIELD(phid);
1604+
WRITE_UINT_FIELD(phlevelsup);
1605+
}
1606+
15931607
staticvoid
15941608
_outSpecialJoinInfo(StringInfostr,SpecialJoinInfo*node)
15951609
{
@@ -1619,6 +1633,18 @@ _outAppendRelInfo(StringInfo str, AppendRelInfo *node)
16191633
WRITE_OID_FIELD(parent_reloid);
16201634
}
16211635

1636+
staticvoid
1637+
_outPlaceHolderInfo(StringInfostr,PlaceHolderInfo*node)
1638+
{
1639+
WRITE_NODE_TYPE("PLACEHOLDERINFO");
1640+
1641+
WRITE_UINT_FIELD(phid);
1642+
WRITE_NODE_FIELD(ph_var);
1643+
WRITE_BITMAPSET_FIELD(ph_eval_at);
1644+
WRITE_BITMAPSET_FIELD(ph_needed);
1645+
WRITE_INT_FIELD(ph_width);
1646+
}
1647+
16221648
staticvoid
16231649
_outPlannerParamItem(StringInfostr,PlannerParamItem*node)
16241650
{
@@ -2539,12 +2565,18 @@ _outNode(StringInfo str, void *obj)
25392565
caseT_FlattenedSubLink:
25402566
_outFlattenedSubLink(str,obj);
25412567
break;
2568+
caseT_PlaceHolderVar:
2569+
_outPlaceHolderVar(str,obj);
2570+
break;
25422571
caseT_SpecialJoinInfo:
25432572
_outSpecialJoinInfo(str,obj);
25442573
break;
25452574
caseT_AppendRelInfo:
25462575
_outAppendRelInfo(str,obj);
25472576
break;
2577+
caseT_PlaceHolderInfo:
2578+
_outPlaceHolderInfo(str,obj);
2579+
break;
25482580
caseT_PlannerParamItem:
25492581
_outPlannerParamItem(str,obj);
25502582
break;

‎src/backend/optimizer/path/allpaths.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.174 2008/10/04 21:56:53 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.175 2008/10/21 20:42:52 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -423,6 +423,10 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
423423
Var*parentvar= (Var*)lfirst(parentvars);
424424
Var*childvar= (Var*)lfirst(childvars);
425425

426+
/*
427+
* Accumulate per-column estimates too. Whole-row Vars and
428+
* PlaceHolderVars can be ignored here.
429+
*/
426430
if (IsA(parentvar,Var)&&
427431
IsA(childvar,Var))
428432
{
@@ -1105,12 +1109,25 @@ qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual,
11051109
* Examine all Vars used in clause; since it's a restriction clause, all
11061110
* such Vars must refer to subselect output columns.
11071111
*/
1108-
vars=pull_var_clause(qual,false);
1112+
vars=pull_var_clause(qual,true);
11091113
foreach(vl,vars)
11101114
{
11111115
Var*var= (Var*)lfirst(vl);
11121116
TargetEntry*tle;
11131117

1118+
/*
1119+
* XXX Punt if we find any PlaceHolderVars in the restriction clause.
1120+
* It's not clear whether a PHV could safely be pushed down, and even
1121+
* less clear whether such a situation could arise in any cases of
1122+
* practical interest anyway. So for the moment, just refuse to push
1123+
* down.
1124+
*/
1125+
if (!IsA(var,Var))
1126+
{
1127+
safe= false;
1128+
break;
1129+
}
1130+
11141131
Assert(var->varno==rti);
11151132

11161133
/* Check point 2 */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp