📄 joinpath.c
字号:
PathOrder *outerpath_ordering = NULL; foreach(i, outerpath_list) { List *clauses = NIL; List *matchedJoinKeys = NIL; List *matchedJoinClauses = NIL; MergeInfo *xmergeinfo = NULL; outerpath = (Path *) lfirst(i); outerpath_ordering = outerpath->pathorder; if (outerpath_ordering) xmergeinfo = match_order_mergeinfo(outerpath_ordering, mergeinfo_list); if (xmergeinfo) clauses = xmergeinfo->jmethod.clauses; if (clauses) { List *jmkeys = xmergeinfo->jmethod.jmkeys; order_joinkeys_by_pathkeys(outerpath->pathkeys, jmkeys, clauses, OUTER, &matchedJoinKeys, &matchedJoinClauses); merge_pathkeys = new_join_pathkeys(outerpath->pathkeys, joinrel->targetlist, clauses); } else merge_pathkeys = outerpath->pathkeys; if (best_innerjoin && path_is_cheaper(best_innerjoin, cheapest_inner)) nestinnerpath = best_innerjoin; else nestinnerpath = cheapest_inner; paths = lcons(create_nestloop_path(joinrel, outerrel, outerpath, nestinnerpath, merge_pathkeys), NIL); if (clauses && matchedJoinKeys) { bool path_is_cheaper_than_sort; List *varkeys = NIL; Path *mergeinnerpath = get_cheapest_path_for_joinkeys( matchedJoinKeys, outerpath_ordering, innerrel->pathlist, INNER); /* Should we use the mergeinner, or sort the cheapest inner? */ path_is_cheaper_than_sort = (bool) (mergeinnerpath && (mergeinnerpath->path_cost < (cheapest_inner->path_cost + cost_sort(matchedJoinKeys, innerrel->size, innerrel->width)))); if (!path_is_cheaper_than_sort) { varkeys = make_pathkeys_from_joinkeys(matchedJoinKeys, innerrel->targetlist, INNER); } /* * Keep track of the cost of the outer path used with this * ordered inner path for later processing in * (match_unsorted_inner), since it isn't a sort and thus * wouldn't otherwise be considered. */ if (path_is_cheaper_than_sort) mergeinnerpath->outerjoincost = outerpath->path_cost; else mergeinnerpath = cheapest_inner; temp_node = lcons(create_mergejoin_path(joinrel, outerrel->size, innerrel->size, outerrel->width, innerrel->width, outerpath, mergeinnerpath, merge_pathkeys, xmergeinfo->m_ordering, matchedJoinClauses, NIL, varkeys), paths); } else temp_node = paths; jp_list = nconc(jp_list, temp_node); } return jp_list;}/* * match_unsorted_inner * Find the cheapest ordered join path for a given(ordered, unsorted) * inner join path. * * Scans through each path available on an inner join relation and tries * matching its ordering keys against those of mergejoin clauses. * If 1. an appropriately_ordered inner path and matching mergeclause are * found, and * 2. sorting the cheapest outer path is cheaper than using an ordered * but unsorted outer path(as was considered in * (match_unsorted_outer)), then this merge path is considered. * * 'joinrel' is the join result relation * 'outerrel' is the outer join relation * 'innerrel' is the inner join relation * 'innerpath_list' is the list of possible inner join paths * 'mergeinfo_list' is a list of nodes containing info on mergejoinable * clauses * * Returns a list of possible merge paths. */static List *match_unsorted_inner(RelOptInfo *joinrel, RelOptInfo *outerrel, RelOptInfo *innerrel, List *innerpath_list, List *mergeinfo_list){ List *mp_list = NIL; List *i; foreach(i, innerpath_list) { Path *innerpath = (Path *) lfirst(i); PathOrder *innerpath_ordering = innerpath->pathorder; MergeInfo *xmergeinfo = (MergeInfo *) NULL; List *clauses = NIL; List *matchedJoinKeys = NIL; List *matchedJoinClauses = NIL; if (innerpath_ordering) xmergeinfo = match_order_mergeinfo(innerpath_ordering, mergeinfo_list); if (xmergeinfo) clauses = ((JoinMethod *) xmergeinfo)->clauses; if (clauses) { List *jmkeys = xmergeinfo->jmethod.jmkeys; order_joinkeys_by_pathkeys(innerpath->pathkeys, jmkeys, clauses, INNER, &matchedJoinKeys, &matchedJoinClauses); } /* * (match_unsorted_outer) if it is applicable. 'OuterJoinCost was * set above in */ if (clauses && matchedJoinKeys) { Cost temp1; temp1 = outerrel->cheapestpath->path_cost + cost_sort(matchedJoinKeys, outerrel->size, outerrel->width); if (innerpath->outerjoincost <= 0 /* unset? */ || innerpath->outerjoincost > temp1) { List *outerkeys = make_pathkeys_from_joinkeys(matchedJoinKeys, outerrel->targetlist, OUTER); List *merge_pathkeys = new_join_pathkeys(outerkeys, joinrel->targetlist, clauses); mp_list = lappend(mp_list, create_mergejoin_path(joinrel, outerrel->size, innerrel->size, outerrel->width, innerrel->width, (Path *) outerrel->cheapestpath, innerpath, merge_pathkeys, xmergeinfo->m_ordering, matchedJoinClauses, outerkeys, NIL)); } } } return mp_list;}/* * hash_inner_and_outer-- XXX HASH * Create hashjoin join paths by explicitly hashing both the outer and * inner join relations on each available hash op. * * 'joinrel' is the join relation * 'outerrel' is the outer join relation * 'innerrel' is the inner join relation * 'hashinfo_list' is a list of nodes containing info on(hashjoinable) * clauses for joining the relations * * Returns a list of hashjoin paths. */static List *hash_inner_and_outer(RelOptInfo *joinrel, RelOptInfo *outerrel, RelOptInfo *innerrel, List *hashinfo_list){ List *hjoin_list = NIL; List *i; foreach(i, hashinfo_list) { HashInfo *xhashinfo = (HashInfo *) lfirst(i); List *outerkeys; List *innerkeys; List *hash_pathkeys; HashPath *temp_node; outerkeys = make_pathkeys_from_joinkeys( ((JoinMethod *) xhashinfo)->jmkeys, outerrel->targetlist, OUTER); innerkeys = make_pathkeys_from_joinkeys( ((JoinMethod *) xhashinfo)->jmkeys, innerrel->targetlist, INNER); /* * We cannot assume that the output of the hashjoin appears in any * particular order, so it should have NIL pathkeys. */#ifdef NOT_USED hash_pathkeys = new_join_pathkeys(outerkeys, joinrel->targetlist, ((JoinMethod *) xhashinfo)->clauses);#else hash_pathkeys = NIL;#endif temp_node = create_hashjoin_path(joinrel, outerrel->size, innerrel->size, outerrel->width, innerrel->width, (Path *) outerrel->cheapestpath, (Path *) innerrel->cheapestpath, hash_pathkeys, xhashinfo->hashop, ((JoinMethod *) xhashinfo)->clauses, outerkeys, innerkeys); hjoin_list = lappend(hjoin_list, temp_node); } return hjoin_list;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -