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

Commit655d2d7

Browse files
committed
parameterized append paths
1 parent713f55c commit655d2d7

File tree

1 file changed

+115
-0
lines changed

1 file changed

+115
-0
lines changed

‎pg_pathman.c

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ static void generate_mergeappend_paths(PlannerInfo *root, RelOptInfo *rel,
9999
List*all_child_pathkeys,
100100
PathKey*pathkeyAsc,
101101
PathKey*pathkeyDesc);
102+
staticPath*get_cheapest_parameterized_child_path(PlannerInfo*root,RelOptInfo*rel,Relidsrequired_outer);
102103

103104

104105
/*
@@ -1616,6 +1617,49 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
16161617
generate_mergeappend_paths(root,rel,live_childrels,
16171618
all_child_pathkeys,pathkeyAsc,
16181619
pathkeyDesc);
1620+
1621+
/*
1622+
* Build Append paths for each parameterization seen among the child rels.
1623+
* (This may look pretty expensive, but in most cases of practical
1624+
* interest, the child rels will expose mostly the same parameterizations,
1625+
* so that not that many cases actually get considered here.)
1626+
*
1627+
* The Append node itself cannot enforce quals, so all qual checking must
1628+
* be done in the child paths. This means that to have a parameterized
1629+
* Append path, we must have the exact same parameterization for each
1630+
* child path; otherwise some children might be failing to check the
1631+
* moved-down quals. To make them match up, we can try to increase the
1632+
* parameterization of lesser-parameterized paths.
1633+
*/
1634+
foreach(l,all_child_outers)
1635+
{
1636+
Relidsrequired_outer= (Relids)lfirst(l);
1637+
ListCell*lcr;
1638+
1639+
/* Select the child paths for an Append with this parameterization */
1640+
subpaths=NIL;
1641+
subpaths_valid= true;
1642+
foreach(lcr,live_childrels)
1643+
{
1644+
RelOptInfo*childrel= (RelOptInfo*)lfirst(lcr);
1645+
Path*subpath;
1646+
1647+
subpath=get_cheapest_parameterized_child_path(root,
1648+
childrel,
1649+
required_outer);
1650+
if (subpath==NULL)
1651+
{
1652+
/* failed to make a suitable path for this child */
1653+
subpaths_valid= false;
1654+
break;
1655+
}
1656+
subpaths=accumulate_append_subpath(subpaths,subpath);
1657+
}
1658+
1659+
if (subpaths_valid)
1660+
add_path(rel, (Path*)
1661+
create_append_path(rel,subpaths,required_outer));
1662+
}
16191663
}
16201664

16211665
staticList*
@@ -1624,7 +1668,78 @@ accumulate_append_subpath(List *subpaths, Path *path)
16241668
returnlappend(subpaths,path);
16251669
}
16261670

1671+
/*
1672+
* get_cheapest_parameterized_child_path
1673+
*Get cheapest path for this relation that has exactly the requested
1674+
*parameterization.
1675+
*
1676+
* Returns NULL if unable to create such a path.
1677+
*/
1678+
staticPath*
1679+
get_cheapest_parameterized_child_path(PlannerInfo*root,RelOptInfo*rel,
1680+
Relidsrequired_outer)
1681+
{
1682+
Path*cheapest;
1683+
ListCell*lc;
1684+
1685+
/*
1686+
* Look up the cheapest existing path with no more than the needed
1687+
* parameterization. If it has exactly the needed parameterization, we're
1688+
* done.
1689+
*/
1690+
cheapest=get_cheapest_path_for_pathkeys(rel->pathlist,
1691+
NIL,
1692+
required_outer,
1693+
TOTAL_COST);
1694+
Assert(cheapest!=NULL);
1695+
if (bms_equal(PATH_REQ_OUTER(cheapest),required_outer))
1696+
returncheapest;
16271697

1698+
/*
1699+
* Otherwise, we can "reparameterize" an existing path to match the given
1700+
* parameterization, which effectively means pushing down additional
1701+
* joinquals to be checked within the path's scan. However, some existing
1702+
* paths might check the available joinquals already while others don't;
1703+
* therefore, it's not clear which existing path will be cheapest after
1704+
* reparameterization. We have to go through them all and find out.
1705+
*/
1706+
cheapest=NULL;
1707+
foreach(lc,rel->pathlist)
1708+
{
1709+
Path*path= (Path*)lfirst(lc);
1710+
1711+
/* Can't use it if it needs more than requested parameterization */
1712+
if (!bms_is_subset(PATH_REQ_OUTER(path),required_outer))
1713+
continue;
1714+
1715+
/*
1716+
* Reparameterization can only increase the path's cost, so if it's
1717+
* already more expensive than the current cheapest, forget it.
1718+
*/
1719+
if (cheapest!=NULL&&
1720+
compare_path_costs(cheapest,path,TOTAL_COST) <=0)
1721+
continue;
1722+
1723+
/* Reparameterize if needed, then recheck cost */
1724+
if (!bms_equal(PATH_REQ_OUTER(path),required_outer))
1725+
{
1726+
path=reparameterize_path(root,path,required_outer,1.0);
1727+
if (path==NULL)
1728+
continue;/* failed to reparameterize this one */
1729+
Assert(bms_equal(PATH_REQ_OUTER(path),required_outer));
1730+
1731+
if (cheapest!=NULL&&
1732+
compare_path_costs(cheapest,path,TOTAL_COST) <=0)
1733+
continue;
1734+
}
1735+
1736+
/* We have a new best path */
1737+
cheapest=path;
1738+
}
1739+
1740+
/* Return the best path, or NULL if we found no suitable candidate */
1741+
returncheapest;
1742+
}
16281743

16291744

16301745
//---------------------------------------------------------------

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp