diff options
Diffstat (limited to 'src/backend/optimizer/path/joinpath.c')
-rw-r--r-- | src/backend/optimizer/path/joinpath.c | 342 |
1 files changed, 120 insertions, 222 deletions
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c index dabef3c3c7f..ba78252b8f9 100644 --- a/src/backend/optimizer/path/joinpath.c +++ b/src/backend/optimizer/path/joinpath.c @@ -30,21 +30,13 @@ set_join_pathlist_hook_type set_join_pathlist_hook = NULL; static void sort_inner_and_outer(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outerrel, RelOptInfo *innerrel, - List *restrictlist, List *mergeclause_list, - JoinType jointype, SpecialJoinInfo *sjinfo, - Relids param_source_rels, Relids extra_lateral_rels); + JoinType jointype, JoinPathExtraData *extra); static void match_unsorted_outer(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outerrel, RelOptInfo *innerrel, - List *restrictlist, List *mergeclause_list, - JoinType jointype, SpecialJoinInfo *sjinfo, - SemiAntiJoinFactors *semifactors, - Relids param_source_rels, Relids extra_lateral_rels); + JoinType jointype, JoinPathExtraData *extra); static void hash_inner_and_outer(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outerrel, RelOptInfo *innerrel, - List *restrictlist, - JoinType jointype, SpecialJoinInfo *sjinfo, - SemiAntiJoinFactors *semifactors, - Relids param_source_rels, Relids extra_lateral_rels); + JoinType jointype, JoinPathExtraData *extra); static List *select_mergejoin_clauses(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outerrel, @@ -86,13 +78,16 @@ add_paths_to_joinrel(PlannerInfo *root, SpecialJoinInfo *sjinfo, List *restrictlist) { - List *mergeclause_list = NIL; + JoinPathExtraData extra; bool mergejoin_allowed = true; - SemiAntiJoinFactors semifactors; - Relids param_source_rels = NULL; - Relids extra_lateral_rels = NULL; ListCell *lc; + extra.restrictlist = restrictlist; + extra.mergeclause_list = NIL; + extra.sjinfo = sjinfo; + extra.param_source_rels = NULL; + extra.extra_lateral_rels = NULL; + /* * Find potential mergejoin clauses. We can skip this if we are not * interested in doing a mergejoin. However, mergejoin may be our only @@ -100,13 +95,13 @@ add_paths_to_joinrel(PlannerInfo *root, * it's a full join. */ if (enable_mergejoin || jointype == JOIN_FULL) - mergeclause_list = select_mergejoin_clauses(root, - joinrel, - outerrel, - innerrel, - restrictlist, - jointype, - &mergejoin_allowed); + extra.mergeclause_list = select_mergejoin_clauses(root, + joinrel, + outerrel, + innerrel, + restrictlist, + jointype, + &mergejoin_allowed); /* * If it's SEMI or ANTI join, compute correction factors for cost @@ -115,7 +110,7 @@ add_paths_to_joinrel(PlannerInfo *root, if (jointype == JOIN_SEMI || jointype == JOIN_ANTI) compute_semi_anti_join_factors(root, outerrel, innerrel, jointype, sjinfo, restrictlist, - &semifactors); + &extra.semifactors); /* * Decide whether it's sensible to generate parameterized paths for this @@ -142,16 +137,16 @@ add_paths_to_joinrel(PlannerInfo *root, */ if (bms_overlap(joinrel->relids, sjinfo->min_righthand) && !bms_overlap(joinrel->relids, sjinfo->min_lefthand)) - param_source_rels = bms_join(param_source_rels, - bms_difference(root->all_baserels, + extra.param_source_rels = bms_join(extra.param_source_rels, + bms_difference(root->all_baserels, sjinfo->min_righthand)); /* full joins constrain both sides symmetrically */ if (sjinfo->jointype == JOIN_FULL && bms_overlap(joinrel->relids, sjinfo->min_lefthand) && !bms_overlap(joinrel->relids, sjinfo->min_righthand)) - param_source_rels = bms_join(param_source_rels, - bms_difference(root->all_baserels, + extra.param_source_rels = bms_join(extra.param_source_rels, + bms_difference(root->all_baserels, sjinfo->min_lefthand)); } @@ -168,9 +163,9 @@ add_paths_to_joinrel(PlannerInfo *root, LateralJoinInfo *ljinfo = (LateralJoinInfo *) lfirst(lc); if (bms_is_subset(ljinfo->lateral_rhs, joinrel->relids)) - param_source_rels = bms_join(param_source_rels, - bms_difference(ljinfo->lateral_lhs, - joinrel->relids)); + extra.param_source_rels = bms_join(extra.param_source_rels, + bms_difference(ljinfo->lateral_lhs, + joinrel->relids)); } /* @@ -195,8 +190,8 @@ add_paths_to_joinrel(PlannerInfo *root, !bms_is_subset(phinfo->ph_eval_at, innerrel->relids)) { /* Yes, remember its lateral rels */ - extra_lateral_rels = bms_add_members(extra_lateral_rels, - phinfo->ph_lateral); + extra.extra_lateral_rels = bms_add_members(extra.extra_lateral_rels, + phinfo->ph_lateral); } } @@ -206,9 +201,10 @@ add_paths_to_joinrel(PlannerInfo *root, * it to required_outer below, while preserving the property that * required_outer is exactly NULL if empty.) */ - extra_lateral_rels = bms_del_members(extra_lateral_rels, joinrel->relids); - if (bms_is_empty(extra_lateral_rels)) - extra_lateral_rels = NULL; + extra.extra_lateral_rels = bms_del_members(extra.extra_lateral_rels, + joinrel->relids); + if (bms_is_empty(extra.extra_lateral_rels)) + extra.extra_lateral_rels = NULL; /* * 1. Consider mergejoin paths where both relations must be explicitly @@ -216,9 +212,7 @@ add_paths_to_joinrel(PlannerInfo *root, */ if (mergejoin_allowed) sort_inner_and_outer(root, joinrel, outerrel, innerrel, - restrictlist, mergeclause_list, jointype, - sjinfo, - param_source_rels, extra_lateral_rels); + jointype, &extra); /* * 2. Consider paths where the outer relation need not be explicitly @@ -229,9 +223,7 @@ add_paths_to_joinrel(PlannerInfo *root, */ if (mergejoin_allowed) match_unsorted_outer(root, joinrel, outerrel, innerrel, - restrictlist, mergeclause_list, jointype, - sjinfo, &semifactors, - param_source_rels, extra_lateral_rels); + jointype, &extra); #ifdef NOT_USED @@ -248,9 +240,7 @@ add_paths_to_joinrel(PlannerInfo *root, */ if (mergejoin_allowed) match_unsorted_inner(root, joinrel, outerrel, innerrel, - restrictlist, mergeclause_list, jointype, - sjinfo, &semifactors, - param_source_rels, extra_lateral_rels); + jointype, &extra); #endif /* @@ -260,30 +250,24 @@ add_paths_to_joinrel(PlannerInfo *root, */ if (enable_hashjoin || jointype == JOIN_FULL) hash_inner_and_outer(root, joinrel, outerrel, innerrel, - restrictlist, jointype, - sjinfo, &semifactors, - param_source_rels, extra_lateral_rels); + jointype, &extra); /* - * 5. If both inner and outer relations are managed by the same FDW, - * give it a chance to push down joins. + * 5. If inner and outer relations are foreign tables (or joins) belonging + * to the same server, give the FDW a chance to push down joins. */ if (joinrel->fdwroutine && joinrel->fdwroutine->GetForeignJoinPaths) joinrel->fdwroutine->GetForeignJoinPaths(root, joinrel, outerrel, innerrel, - restrictlist, jointype, sjinfo, - &semifactors, - param_source_rels, - extra_lateral_rels); + jointype, &extra); + /* * 6. Finally, give extensions a chance to manipulate the path list. */ if (set_join_pathlist_hook) set_join_pathlist_hook(root, joinrel, outerrel, innerrel, - restrictlist, jointype, - sjinfo, &semifactors, - param_source_rels, extra_lateral_rels); + jointype, &extra); } /* @@ -294,15 +278,11 @@ add_paths_to_joinrel(PlannerInfo *root, static void try_nestloop_path(PlannerInfo *root, RelOptInfo *joinrel, - JoinType jointype, - SpecialJoinInfo *sjinfo, - SemiAntiJoinFactors *semifactors, - Relids param_source_rels, - Relids extra_lateral_rels, Path *outer_path, Path *inner_path, - List *restrict_clauses, - List *pathkeys) + List *pathkeys, + JoinType jointype, + JoinPathExtraData *extra) { Relids required_outer; JoinCostWorkspace workspace; @@ -314,7 +294,7 @@ try_nestloop_path(PlannerInfo *root, required_outer = calc_nestloop_required_outer(outer_path, inner_path); if (required_outer && - !bms_overlap(required_outer, param_source_rels)) + !bms_overlap(required_outer, extra->param_source_rels)) { /* * We override the param_source_rels heuristic to accept nestloop @@ -345,7 +325,7 @@ try_nestloop_path(PlannerInfo *root, * Independently of that, add parameterization needed for any * PlaceHolderVars that need to be computed at the join. */ - required_outer = bms_add_members(required_outer, extra_lateral_rels); + required_outer = bms_add_members(required_outer, extra->extra_lateral_rels); /* * Do a precheck to quickly eliminate obviously-inferior paths. We @@ -358,7 +338,7 @@ try_nestloop_path(PlannerInfo *root, */ initial_cost_nestloop(root, &workspace, jointype, outer_path, inner_path, - sjinfo, semifactors); + extra->sjinfo, &extra->semifactors); if (add_path_precheck(joinrel, workspace.startup_cost, workspace.total_cost, @@ -369,11 +349,11 @@ try_nestloop_path(PlannerInfo *root, joinrel, jointype, &workspace, - sjinfo, - semifactors, + extra->sjinfo, + &extra->semifactors, outer_path, inner_path, - restrict_clauses, + extra->restrictlist, pathkeys, required_outer)); } @@ -392,17 +372,14 @@ try_nestloop_path(PlannerInfo *root, static void try_mergejoin_path(PlannerInfo *root, RelOptInfo *joinrel, - JoinType jointype, - SpecialJoinInfo *sjinfo, - Relids param_source_rels, - Relids extra_lateral_rels, Path *outer_path, Path *inner_path, - List *restrict_clauses, List *pathkeys, List *mergeclauses, List *outersortkeys, - List *innersortkeys) + List *innersortkeys, + JoinType jointype, + JoinPathExtraData *extra) { Relids required_outer; JoinCostWorkspace workspace; @@ -414,7 +391,7 @@ try_mergejoin_path(PlannerInfo *root, required_outer = calc_non_nestloop_required_outer(outer_path, inner_path); if (required_outer && - !bms_overlap(required_outer, param_source_rels)) + !bms_overlap(required_outer, extra->param_source_rels)) { /* Waste no memory when we reject a path here */ bms_free(required_outer); @@ -425,7 +402,7 @@ try_mergejoin_path(PlannerInfo *root, * Independently of that, add parameterization needed for any * PlaceHolderVars that need to be computed at the join. */ - required_outer = bms_add_members(required_outer, extra_lateral_rels); + required_outer = bms_add_members(required_outer, extra->extra_lateral_rels); /* * If the given paths are already well enough ordered, we can skip doing @@ -444,7 +421,7 @@ try_mergejoin_path(PlannerInfo *root, initial_cost_mergejoin(root, &workspace, jointype, mergeclauses, outer_path, inner_path, outersortkeys, innersortkeys, - sjinfo); + extra->sjinfo); if (add_path_precheck(joinrel, workspace.startup_cost, workspace.total_cost, @@ -455,10 +432,10 @@ try_mergejoin_path(PlannerInfo *root, joinrel, jointype, &workspace, - sjinfo, + extra->sjinfo, outer_path, inner_path, - restrict_clauses, + extra->restrictlist, pathkeys, required_outer, mergeclauses, @@ -480,15 +457,11 @@ try_mergejoin_path(PlannerInfo *root, static void try_hashjoin_path(PlannerInfo *root, RelOptInfo *joinrel, - JoinType jointype, - SpecialJoinInfo *sjinfo, - SemiAntiJoinFactors *semifactors, - Relids param_source_rels, - Relids extra_lateral_rels, Path *outer_path, Path *inner_path, - List *restrict_clauses, - List *hashclauses) + List *hashclauses, + JoinType jointype, + JoinPathExtraData *extra) { Relids required_outer; JoinCostWorkspace workspace; @@ -500,7 +473,7 @@ try_hashjoin_path(PlannerInfo *root, required_outer = calc_non_nestloop_required_outer(outer_path, inner_path); if (required_outer && - !bms_overlap(required_outer, param_source_rels)) + !bms_overlap(required_outer, extra->param_source_rels)) { /* Waste no memory when we reject a path here */ bms_free(required_outer); @@ -511,7 +484,7 @@ try_hashjoin_path(PlannerInfo *root, * Independently of that, add parameterization needed for any * PlaceHolderVars that need to be computed at the join. */ - required_outer = bms_add_members(required_outer, extra_lateral_rels); + required_outer = bms_add_members(required_outer, extra->extra_lateral_rels); /* * See comments in try_nestloop_path(). Also note that hashjoin paths @@ -519,7 +492,7 @@ try_hashjoin_path(PlannerInfo *root, */ initial_cost_hashjoin(root, &workspace, jointype, hashclauses, outer_path, inner_path, - sjinfo, semifactors); + extra->sjinfo, &extra->semifactors); if (add_path_precheck(joinrel, workspace.startup_cost, workspace.total_cost, @@ -530,11 +503,11 @@ try_hashjoin_path(PlannerInfo *root, joinrel, jointype, &workspace, - sjinfo, - semifactors, + extra->sjinfo, + &extra->semifactors, outer_path, inner_path, - restrict_clauses, + extra->restrictlist, required_outer, hashclauses)); } @@ -584,26 +557,16 @@ clause_sides_match_join(RestrictInfo *rinfo, RelOptInfo *outerrel, * 'joinrel' is the join relation * 'outerrel' is the outer join relation * 'innerrel' is the inner join relation - * 'restrictlist' contains all of the RestrictInfo nodes for restriction - * clauses that apply to this join - * 'mergeclause_list' is a list of RestrictInfo nodes for available - * mergejoin clauses in this join * 'jointype' is the type of join to do - * 'sjinfo' is extra info about the join for selectivity estimation - * 'param_source_rels' are OK targets for parameterization of result paths - * 'extra_lateral_rels' are additional parameterization for result paths + * 'extra' contains additional input values */ static void sort_inner_and_outer(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outerrel, RelOptInfo *innerrel, - List *restrictlist, - List *mergeclause_list, JoinType jointype, - SpecialJoinInfo *sjinfo, - Relids param_source_rels, - Relids extra_lateral_rels) + JoinPathExtraData *extra) { Path *outer_path; Path *inner_path; @@ -643,14 +606,14 @@ sort_inner_and_outer(PlannerInfo *root, if (jointype == JOIN_UNIQUE_OUTER) { outer_path = (Path *) create_unique_path(root, outerrel, - outer_path, sjinfo); + outer_path, extra->sjinfo); Assert(outer_path); jointype = JOIN_INNER; } else if (jointype == JOIN_UNIQUE_INNER) { inner_path = (Path *) create_unique_path(root, innerrel, - inner_path, sjinfo); + inner_path, extra->sjinfo); Assert(inner_path); jointype = JOIN_INNER; } @@ -684,7 +647,7 @@ sort_inner_and_outer(PlannerInfo *root, * exactly as-is as well as making variants. */ all_pathkeys = select_outer_pathkeys_for_merge(root, - mergeclause_list, + extra->mergeclause_list, joinrel); foreach(l, all_pathkeys) @@ -707,10 +670,10 @@ sort_inner_and_outer(PlannerInfo *root, cur_mergeclauses = find_mergeclauses_for_pathkeys(root, outerkeys, true, - mergeclause_list); + extra->mergeclause_list); /* Should have used them all... */ - Assert(list_length(cur_mergeclauses) == list_length(mergeclause_list)); + Assert(list_length(cur_mergeclauses) == list_length(extra->mergeclause_list)); /* Build sort pathkeys for the inner side */ innerkeys = make_inner_pathkeys_for_merge(root, @@ -730,17 +693,14 @@ sort_inner_and_outer(PlannerInfo *root, */ try_mergejoin_path(root, joinrel, - jointype, - sjinfo, - param_source_rels, - extra_lateral_rels, outer_path, inner_path, - restrictlist, merge_pathkeys, cur_mergeclauses, outerkeys, - innerkeys); + innerkeys, + jointype, + extra); } } @@ -771,28 +731,16 @@ sort_inner_and_outer(PlannerInfo *root, * 'joinrel' is the join relation * 'outerrel' is the outer join relation * 'innerrel' is the inner join relation - * 'restrictlist' contains all of the RestrictInfo nodes for restriction - * clauses that apply to this join - * 'mergeclause_list' is a list of RestrictInfo nodes for available - * mergejoin clauses in this join * 'jointype' is the type of join to do - * 'sjinfo' is extra info about the join for selectivity estimation - * 'semifactors' contains valid data if jointype is SEMI or ANTI - * 'param_source_rels' are OK targets for parameterization of result paths - * 'extra_lateral_rels' are additional parameterization for result paths + * 'extra' contains additional input values */ static void match_unsorted_outer(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outerrel, RelOptInfo *innerrel, - List *restrictlist, - List *mergeclause_list, JoinType jointype, - SpecialJoinInfo *sjinfo, - SemiAntiJoinFactors *semifactors, - Relids param_source_rels, - Relids extra_lateral_rels) + JoinPathExtraData *extra) { JoinType save_jointype = jointype; bool nestjoinOK; @@ -854,7 +802,7 @@ match_unsorted_outer(PlannerInfo *root, if (inner_cheapest_total == NULL) return; inner_cheapest_total = (Path *) - create_unique_path(root, innerrel, inner_cheapest_total, sjinfo); + create_unique_path(root, innerrel, inner_cheapest_total, extra->sjinfo); Assert(inner_cheapest_total); } else if (nestjoinOK) @@ -898,7 +846,7 @@ match_unsorted_outer(PlannerInfo *root, if (outerpath != outerrel->cheapest_total_path) continue; outerpath = (Path *) create_unique_path(root, outerrel, - outerpath, sjinfo); + outerpath, extra->sjinfo); Assert(outerpath); } @@ -918,15 +866,11 @@ match_unsorted_outer(PlannerInfo *root, */ try_nestloop_path(root, joinrel, - jointype, - sjinfo, - semifactors, - param_source_rels, - extra_lateral_rels, outerpath, inner_cheapest_total, - restrictlist, - merge_pathkeys); + merge_pathkeys, + jointype, + extra); } else if (nestjoinOK) { @@ -944,30 +888,22 @@ match_unsorted_outer(PlannerInfo *root, try_nestloop_path(root, joinrel, - jointype, - sjinfo, - semifactors, - param_source_rels, - extra_lateral_rels, outerpath, innerpath, - restrictlist, - merge_pathkeys); + merge_pathkeys, + jointype, + extra); } /* Also consider materialized form of the cheapest inner path */ if (matpath != NULL) try_nestloop_path(root, joinrel, - jointype, - sjinfo, - semifactors, - param_source_rels, - extra_lateral_rels, outerpath, matpath, - restrictlist, - merge_pathkeys); + merge_pathkeys, + jointype, + extra); } /* Can't do anything else if outer path needs to be unique'd */ @@ -982,7 +918,7 @@ match_unsorted_outer(PlannerInfo *root, mergeclauses = find_mergeclauses_for_pathkeys(root, outerpath->pathkeys, true, - mergeclause_list); + extra->mergeclause_list); /* * Done with this outer path if no chance for a mergejoin. @@ -1000,7 +936,7 @@ match_unsorted_outer(PlannerInfo *root, else continue; } - if (useallclauses && list_length(mergeclauses) != list_length(mergeclause_list)) + if (useallclauses && list_length(mergeclauses) != list_length(extra->mergeclause_list)) continue; /* Compute the required ordering of the inner path */ @@ -1016,17 +952,14 @@ match_unsorted_outer(PlannerInfo *root, */ try_mergejoin_path(root, joinrel, - jointype, - sjinfo, - param_source_rels, - extra_lateral_rels, outerpath, inner_cheapest_total, - restrictlist, merge_pathkeys, mergeclauses, NIL, - innersortkeys); + innersortkeys, + jointype, + extra); /* Can't do anything else if inner path needs to be unique'd */ if (save_jointype == JOIN_UNIQUE_INNER) @@ -1115,17 +1048,14 @@ match_unsorted_outer(PlannerInfo *root, newclauses = mergeclauses; try_mergejoin_path(root, joinrel, - jointype, - sjinfo, - param_source_rels, - extra_lateral_rels, outerpath, innerpath, - restrictlist, merge_pathkeys, newclauses, NIL, - NIL); + NIL, + jointype, + extra); cheapest_total_inner = innerpath; } /* Same on the basis of cheapest startup cost ... */ @@ -1161,17 +1091,14 @@ match_unsorted_outer(PlannerInfo *root, } try_mergejoin_path(root, joinrel, - jointype, - sjinfo, - param_source_rels, - extra_lateral_rels, outerpath, innerpath, - restrictlist, merge_pathkeys, newclauses, NIL, - NIL); + NIL, + jointype, + extra); } cheapest_startup_inner = innerpath; } @@ -1193,25 +1120,16 @@ match_unsorted_outer(PlannerInfo *root, * 'joinrel' is the join relation * 'outerrel' is the outer join relation * 'innerrel' is the inner join relation - * 'restrictlist' contains all of the RestrictInfo nodes for restriction - * clauses that apply to this join * 'jointype' is the type of join to do - * 'sjinfo' is extra info about the join for selectivity estimation - * 'semifactors' contains valid data if jointype is SEMI or ANTI - * 'param_source_rels' are OK targets for parameterization of result paths - * 'extra_lateral_rels' are additional parameterization for result paths + * 'extra' contains additional input values */ static void hash_inner_and_outer(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outerrel, RelOptInfo *innerrel, - List *restrictlist, JoinType jointype, - SpecialJoinInfo *sjinfo, - SemiAntiJoinFactors *semifactors, - Relids param_source_rels, - Relids extra_lateral_rels) + JoinPathExtraData *extra) { bool isouterjoin = IS_OUTER_JOIN(jointype); List *hashclauses; @@ -1225,7 +1143,7 @@ hash_inner_and_outer(PlannerInfo *root, * usable with this pair of sub-relations. */ hashclauses = NIL; - foreach(l, restrictlist) + foreach(l, extra->restrictlist) { RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(l); @@ -1276,53 +1194,41 @@ hash_inner_and_outer(PlannerInfo *root, { cheapest_total_outer = (Path *) create_unique_path(root, outerrel, - cheapest_total_outer, sjinfo); + cheapest_total_outer, extra->sjinfo); Assert(cheapest_total_outer); jointype = JOIN_INNER; try_hashjoin_path(root, joinrel, - jointype, - sjinfo, - semifactors, - param_source_rels, - extra_lateral_rels, cheapest_total_outer, cheapest_total_inner, - restrictlist, - hashclauses); + hashclauses, + jointype, + extra); /* no possibility of cheap startup here */ } else if (jointype == JOIN_UNIQUE_INNER) { cheapest_total_inner = (Path *) create_unique_path(root, innerrel, - cheapest_total_inner, sjinfo); + cheapest_total_inner, extra->sjinfo); Assert(cheapest_total_inner); jointype = JOIN_INNER; try_hashjoin_path(root, joinrel, - jointype, - sjinfo, - semifactors, - param_source_rels, - extra_lateral_rels, cheapest_total_outer, cheapest_total_inner, - restrictlist, - hashclauses); + hashclauses, + jointype, + extra); if (cheapest_startup_outer != NULL && cheapest_startup_outer != cheapest_total_outer) try_hashjoin_path(root, joinrel, - jointype, - sjinfo, - semifactors, - param_source_rels, - extra_lateral_rels, cheapest_startup_outer, cheapest_total_inner, - restrictlist, - hashclauses); + hashclauses, + jointype, + extra); } else { @@ -1339,15 +1245,11 @@ hash_inner_and_outer(PlannerInfo *root, if (cheapest_startup_outer != NULL) try_hashjoin_path(root, joinrel, - jointype, - sjinfo, - semifactors, - param_source_rels, - extra_lateral_rels, cheapest_startup_outer, cheapest_total_inner, - restrictlist, - hashclauses); + hashclauses, + jointype, + extra); foreach(lc1, outerrel->cheapest_parameterized_paths) { @@ -1377,15 +1279,11 @@ hash_inner_and_outer(PlannerInfo *root, try_hashjoin_path(root, joinrel, - jointype, - sjinfo, - semifactors, - param_source_rels, - extra_lateral_rels, outerpath, innerpath, - restrictlist, - hashclauses); + hashclauses, + jointype, + extra); } } } |