10
10
*
11
11
*
12
12
* IDENTIFICATION
13
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.166 2004/01/07 18:56:26 neilc Exp $
13
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.167 2004/01/18 00:50:02 tgl Exp $
14
14
*
15
15
*-------------------------------------------------------------------------
16
16
*/
@@ -97,13 +97,13 @@ static HashJoin *make_hashjoin(List *tlist,
97
97
List * hashclauses ,
98
98
Plan * lefttree , Plan * righttree ,
99
99
JoinType jointype );
100
- static Hash * make_hash (List * tlist , Plan * lefttree );
100
+ static Hash * make_hash (Plan * lefttree );
101
101
static MergeJoin * make_mergejoin (List * tlist ,
102
102
List * joinclauses , List * otherclauses ,
103
103
List * mergeclauses ,
104
104
Plan * lefttree , Plan * righttree ,
105
105
JoinType jointype );
106
- static Sort * make_sort (Query * root , List * tlist , Plan * lefttree , int numCols ,
106
+ static Sort * make_sort (Query * root , Plan * lefttree , int numCols ,
107
107
AttrNumber * sortColIdx , Oid * sortOperators );
108
108
static Sort * make_sort_from_pathkeys (Query * root , Plan * lefttree ,
109
109
Relids relids , List * pathkeys );
@@ -492,7 +492,7 @@ create_material_plan(Query *root, MaterialPath *best_path)
492
492
/* We don't want any excess columns in the materialized tuples */
493
493
disuse_physical_tlist (subplan , best_path -> subpath );
494
494
495
- plan = make_material (subplan -> targetlist , subplan );
495
+ plan = make_material (subplan );
496
496
497
497
copy_path_costsize (& plan -> plan , (Path * ) best_path );
498
498
@@ -518,7 +518,6 @@ create_unique_plan(Query *root, UniquePath *best_path)
518
518
List * newtlist ;
519
519
int nextresno ;
520
520
bool newitems ;
521
- List * my_tlist ;
522
521
List * l ;
523
522
524
523
subplan = create_plan (root , best_path -> subpath );
@@ -596,11 +595,8 @@ create_unique_plan(Query *root, UniquePath *best_path)
596
595
/*
597
596
* If the top plan node can't do projections, we need to add a
598
597
* Result node to help it along.
599
- *
600
- * Currently, the only non-projection-capable plan type we can see
601
- * here is Append.
602
598
*/
603
- if (IsA (subplan , Append ))
599
+ if (! is_projection_capable_plan (subplan ))
604
600
subplan = (Plan * ) make_result (newtlist , NULL , subplan );
605
601
else
606
602
subplan -> targetlist = newtlist ;
@@ -610,17 +606,14 @@ create_unique_plan(Query *root, UniquePath *best_path)
610
606
if (best_path -> umethod == UNIQUE_PATH_NOOP )
611
607
return subplan ;
612
608
613
- /* Copy tlist again to make one we can put sorting labels on */
614
- my_tlist = copyObject (subplan -> targetlist );
615
-
616
609
if (best_path -> umethod == UNIQUE_PATH_HASH )
617
610
{
618
611
long numGroups ;
619
612
620
613
numGroups = (long ) Min (best_path -> rows , (double ) LONG_MAX );
621
614
622
615
plan = (Plan * ) make_agg (root ,
623
- my_tlist ,
616
+ copyObject ( subplan -> targetlist ) ,
624
617
NIL ,
625
618
AGG_HASHED ,
626
619
numGroupCols ,
@@ -637,15 +630,15 @@ create_unique_plan(Query *root, UniquePath *best_path)
637
630
{
638
631
TargetEntry * tle ;
639
632
640
- tle = get_tle_by_resno (my_tlist , groupColIdx [groupColPos ]);
633
+ tle = get_tle_by_resno (subplan -> targetlist ,
634
+ groupColIdx [groupColPos ]);
641
635
Assert (tle != NULL );
642
636
sortList = addTargetToSortList (NULL , tle ,
643
- sortList , my_tlist ,
637
+ sortList , subplan -> targetlist ,
644
638
SORTBY_ASC , NIL , false);
645
639
}
646
- plan = (Plan * ) make_sort_from_sortclauses (root , my_tlist ,
647
- subplan , sortList );
648
- plan = (Plan * ) make_unique (my_tlist , plan , sortList );
640
+ plan = (Plan * ) make_sort_from_sortclauses (root , sortList , subplan );
641
+ plan = (Plan * ) make_unique (plan , sortList );
649
642
}
650
643
651
644
/* Adjust output size estimate (other fields should be OK already) */
@@ -1145,8 +1138,7 @@ create_hashjoin_plan(Query *root,
1145
1138
/*
1146
1139
* Build the hash node and hash join node.
1147
1140
*/
1148
- hash_plan = make_hash (inner_plan -> targetlist ,
1149
- inner_plan );
1141
+ hash_plan = make_hash (inner_plan );
1150
1142
join_plan = make_hashjoin (tlist ,
1151
1143
joinclauses ,
1152
1144
otherclauses ,
@@ -1735,7 +1727,7 @@ make_hashjoin(List *tlist,
1735
1727
}
1736
1728
1737
1729
static Hash *
1738
- make_hash (List * tlist , Plan * lefttree )
1730
+ make_hash (Plan * lefttree )
1739
1731
{
1740
1732
Hash * node = makeNode (Hash );
1741
1733
Plan * plan = & node -> plan ;
@@ -1747,7 +1739,7 @@ make_hash(List *tlist, Plan *lefttree)
1747
1739
* input plan; this only affects EXPLAIN display not decisions.
1748
1740
*/
1749
1741
plan -> startup_cost = plan -> total_cost ;
1750
- plan -> targetlist = tlist ;
1742
+ plan -> targetlist = copyObject ( lefttree -> targetlist ) ;
1751
1743
plan -> qual = NIL ;
1752
1744
plan -> lefttree = lefttree ;
1753
1745
plan -> righttree = NULL ;
@@ -1785,7 +1777,7 @@ make_mergejoin(List *tlist,
1785
1777
* Caller must have built the sortColIdx and sortOperators arrays already.
1786
1778
*/
1787
1779
static Sort *
1788
- make_sort (Query * root , List * tlist , Plan * lefttree , int numCols ,
1780
+ make_sort (Query * root , Plan * lefttree , int numCols ,
1789
1781
AttrNumber * sortColIdx , Oid * sortOperators )
1790
1782
{
1791
1783
Sort * node = makeNode (Sort );
@@ -1799,7 +1791,7 @@ make_sort(Query *root, List *tlist, Plan *lefttree, int numCols,
1799
1791
lefttree -> plan_width );
1800
1792
plan -> startup_cost = sort_path .startup_cost ;
1801
1793
plan -> total_cost = sort_path .total_cost ;
1802
- plan -> targetlist = tlist ;
1794
+ plan -> targetlist = copyObject ( lefttree -> targetlist ) ;
1803
1795
plan -> qual = NIL ;
1804
1796
plan -> lefttree = lefttree ;
1805
1797
plan -> righttree = NULL ;
@@ -1862,7 +1854,6 @@ make_sort_from_pathkeys(Query *root, Plan *lefttree,
1862
1854
Relids relids , List * pathkeys )
1863
1855
{
1864
1856
List * tlist = lefttree -> targetlist ;
1865
- List * sort_tlist ;
1866
1857
List * i ;
1867
1858
int numsortkeys ;
1868
1859
AttrNumber * sortColIdx ;
@@ -1916,11 +1907,8 @@ make_sort_from_pathkeys(Query *root, Plan *lefttree,
1916
1907
1917
1908
/*
1918
1909
* Do we need to insert a Result node?
1919
- *
1920
- * Currently, the only non-projection-capable plan type we can
1921
- * see here is Append.
1922
1910
*/
1923
- if (IsA (lefttree , Append ))
1911
+ if (! is_projection_capable_plan (lefttree ))
1924
1912
{
1925
1913
tlist = copyObject (tlist );
1926
1914
lefttree = (Plan * ) make_result (tlist , NULL , lefttree );
@@ -1952,26 +1940,21 @@ make_sort_from_pathkeys(Query *root, Plan *lefttree,
1952
1940
1953
1941
Assert (numsortkeys > 0 );
1954
1942
1955
- /* Give Sort node its own copy of the tlist (still necessary?) */
1956
- sort_tlist = copyObject (tlist );
1957
-
1958
- return make_sort (root , sort_tlist , lefttree , numsortkeys ,
1943
+ return make_sort (root , lefttree , numsortkeys ,
1959
1944
sortColIdx , sortOperators );
1960
1945
}
1961
1946
1962
1947
/*
1963
1948
* make_sort_from_sortclauses
1964
1949
* Create sort plan to sort according to given sortclauses
1965
1950
*
1966
- * 'tlist' is the targetlist
1967
- * 'lefttree' is the node which yields input tuples
1968
1951
* 'sortcls' is a list of SortClauses
1952
+ * 'lefttree' is the node which yields input tuples
1969
1953
*/
1970
1954
Sort *
1971
- make_sort_from_sortclauses (Query * root , List * tlist ,
1972
- Plan * lefttree , List * sortcls )
1955
+ make_sort_from_sortclauses (Query * root , List * sortcls , Plan * lefttree )
1973
1956
{
1974
- List * sort_tlist ;
1957
+ List * sub_tlist = lefttree -> targetlist ;
1975
1958
List * i ;
1976
1959
int numsortkeys ;
1977
1960
AttrNumber * sortColIdx ;
@@ -1987,24 +1970,20 @@ make_sort_from_sortclauses(Query *root, List *tlist,
1987
1970
foreach (i , sortcls )
1988
1971
{
1989
1972
SortClause * sortcl = (SortClause * ) lfirst (i );
1990
- TargetEntry * tle = get_sortgroupclause_tle (sortcl , tlist );
1991
- Resdom * resdom = tle -> resdom ;
1973
+ TargetEntry * tle = get_sortgroupclause_tle (sortcl , sub_tlist );
1992
1974
1993
1975
/*
1994
1976
* Check for the possibility of duplicate order-by clauses --- the
1995
1977
* parser should have removed 'em, but no point in sorting
1996
1978
* redundantly.
1997
1979
*/
1998
- numsortkeys = add_sort_column (resdom -> resno , sortcl -> sortop ,
1980
+ numsortkeys = add_sort_column (tle -> resdom -> resno , sortcl -> sortop ,
1999
1981
numsortkeys , sortColIdx , sortOperators );
2000
1982
}
2001
1983
2002
1984
Assert (numsortkeys > 0 );
2003
1985
2004
- /* Give Sort node its own copy of the tlist (still necessary?) */
2005
- sort_tlist = copyObject (tlist );
2006
-
2007
- return make_sort (root , sort_tlist , lefttree , numsortkeys ,
1986
+ return make_sort (root , lefttree , numsortkeys ,
2008
1987
sortColIdx , sortOperators );
2009
1988
}
2010
1989
@@ -2028,7 +2007,6 @@ make_sort_from_groupcols(Query *root,
2028
2007
Plan * lefttree )
2029
2008
{
2030
2009
List * sub_tlist = lefttree -> targetlist ;
2031
- List * sort_tlist ;
2032
2010
int grpno = 0 ;
2033
2011
List * i ;
2034
2012
int numsortkeys ;
@@ -2046,35 +2024,31 @@ make_sort_from_groupcols(Query *root,
2046
2024
{
2047
2025
GroupClause * grpcl = (GroupClause * ) lfirst (i );
2048
2026
TargetEntry * tle = get_tle_by_resno (sub_tlist , grpColIdx [grpno ]);
2049
- Resdom * resdom = tle -> resdom ;
2050
2027
2051
2028
/*
2052
2029
* Check for the possibility of duplicate group-by clauses --- the
2053
2030
* parser should have removed 'em, but no point in sorting
2054
2031
* redundantly.
2055
2032
*/
2056
- numsortkeys = add_sort_column (resdom -> resno , grpcl -> sortop ,
2033
+ numsortkeys = add_sort_column (tle -> resdom -> resno , grpcl -> sortop ,
2057
2034
numsortkeys , sortColIdx , sortOperators );
2058
2035
grpno ++ ;
2059
2036
}
2060
2037
2061
2038
Assert (numsortkeys > 0 );
2062
2039
2063
- /* Give Sort node its own copy of the tlist (still necessary?) */
2064
- sort_tlist = copyObject (sub_tlist );
2065
-
2066
- return make_sort (root , sort_tlist , lefttree , numsortkeys ,
2040
+ return make_sort (root , lefttree , numsortkeys ,
2067
2041
sortColIdx , sortOperators );
2068
2042
}
2069
2043
2070
2044
Material *
2071
- make_material (List * tlist , Plan * lefttree )
2045
+ make_material (Plan * lefttree )
2072
2046
{
2073
2047
Material * node = makeNode (Material );
2074
2048
Plan * plan = & node -> plan ;
2075
2049
2076
2050
/* cost should be inserted by caller */
2077
- plan -> targetlist = tlist ;
2051
+ plan -> targetlist = copyObject ( lefttree -> targetlist ) ;
2078
2052
plan -> qual = NIL ;
2079
2053
plan -> lefttree = lefttree ;
2080
2054
plan -> righttree = NULL ;
@@ -2098,7 +2072,7 @@ materialize_finished_plan(Plan *subplan)
2098
2072
Plan * matplan ;
2099
2073
Path matpath ; /* dummy for result of cost_material */
2100
2074
2101
- matplan = (Plan * ) make_material (subplan -> targetlist , subplan );
2075
+ matplan = (Plan * ) make_material (subplan );
2102
2076
2103
2077
/* Set cost data */
2104
2078
cost_material (& matpath ,
@@ -2239,7 +2213,7 @@ make_group(Query *root,
2239
2213
* that should be considered by the Unique filter.
2240
2214
*/
2241
2215
Unique *
2242
- make_unique (List * tlist , Plan * lefttree , List * distinctList )
2216
+ make_unique (Plan * lefttree , List * distinctList )
2243
2217
{
2244
2218
Unique * node = makeNode (Unique );
2245
2219
Plan * plan = & node -> plan ;
@@ -2263,7 +2237,7 @@ make_unique(List *tlist, Plan *lefttree, List *distinctList)
2263
2237
* this if he has a better idea.
2264
2238
*/
2265
2239
2266
- plan -> targetlist = tlist ;
2240
+ plan -> targetlist = copyObject ( lefttree -> targetlist ) ;
2267
2241
plan -> qual = NIL ;
2268
2242
plan -> lefttree = lefttree ;
2269
2243
plan -> righttree = NULL ;
@@ -2278,7 +2252,7 @@ make_unique(List *tlist, Plan *lefttree, List *distinctList)
2278
2252
foreach (slitem , distinctList )
2279
2253
{
2280
2254
SortClause * sortcl = (SortClause * ) lfirst (slitem );
2281
- TargetEntry * tle = get_sortgroupclause_tle (sortcl , tlist );
2255
+ TargetEntry * tle = get_sortgroupclause_tle (sortcl , plan -> targetlist );
2282
2256
2283
2257
uniqColIdx [keyno ++ ] = tle -> resdom -> resno ;
2284
2258
}
@@ -2295,7 +2269,7 @@ make_unique(List *tlist, Plan *lefttree, List *distinctList)
2295
2269
*/
2296
2270
2297
2271
SetOp *
2298
- make_setop (SetOpCmd cmd , List * tlist , Plan * lefttree ,
2272
+ make_setop (SetOpCmd cmd , Plan * lefttree ,
2299
2273
List * distinctList , AttrNumber flagColIdx )
2300
2274
{
2301
2275
SetOp * node = makeNode (SetOp );
@@ -2321,7 +2295,7 @@ make_setop(SetOpCmd cmd, List *tlist, Plan *lefttree,
2321
2295
if (plan -> plan_rows < 1 )
2322
2296
plan -> plan_rows = 1 ;
2323
2297
2324
- plan -> targetlist = tlist ;
2298
+ plan -> targetlist = copyObject ( lefttree -> targetlist ) ;
2325
2299
plan -> qual = NIL ;
2326
2300
plan -> lefttree = lefttree ;
2327
2301
plan -> righttree = NULL ;
@@ -2336,7 +2310,7 @@ make_setop(SetOpCmd cmd, List *tlist, Plan *lefttree,
2336
2310
foreach (slitem , distinctList )
2337
2311
{
2338
2312
SortClause * sortcl = (SortClause * ) lfirst (slitem );
2339
- TargetEntry * tle = get_sortgroupclause_tle (sortcl , tlist );
2313
+ TargetEntry * tle = get_sortgroupclause_tle (sortcl , plan -> targetlist );
2340
2314
2341
2315
dupColIdx [keyno ++ ] = tle -> resdom -> resno ;
2342
2316
}
@@ -2350,8 +2324,7 @@ make_setop(SetOpCmd cmd, List *tlist, Plan *lefttree,
2350
2324
}
2351
2325
2352
2326
Limit *
2353
- make_limit (List * tlist , Plan * lefttree ,
2354
- Node * limitOffset , Node * limitCount )
2327
+ make_limit (Plan * lefttree , Node * limitOffset , Node * limitCount )
2355
2328
{
2356
2329
Limit * node = makeNode (Limit );
2357
2330
Plan * plan = & node -> plan ;
@@ -2401,7 +2374,7 @@ make_limit(List *tlist, Plan *lefttree,
2401
2374
}
2402
2375
}
2403
2376
2404
- plan -> targetlist = tlist ;
2377
+ plan -> targetlist = copyObject ( lefttree -> targetlist ) ;
2405
2378
plan -> qual = NIL ;
2406
2379
plan -> lefttree = lefttree ;
2407
2380
plan -> righttree = NULL ;
@@ -2448,3 +2421,27 @@ make_result(List *tlist,
2448
2421
2449
2422
return node ;
2450
2423
}
2424
+
2425
+ /*
2426
+ * is_projection_capable_plan
2427
+ * Check whether a given Plan node is able to do projection.
2428
+ */
2429
+ bool
2430
+ is_projection_capable_plan (Plan * plan )
2431
+ {
2432
+ /* Most plan types can project, so just list the ones that can't */
2433
+ switch (nodeTag (plan ))
2434
+ {
2435
+ case T_Hash :
2436
+ case T_Material :
2437
+ case T_Sort :
2438
+ case T_Unique :
2439
+ case T_SetOp :
2440
+ case T_Limit :
2441
+ case T_Append :
2442
+ return false;
2443
+ default :
2444
+ break ;
2445
+ }
2446
+ return true;
2447
+ }
0 commit comments