diff options
author | Bruce Momjian <bruce@momjian.us> | 2000-04-12 17:17:23 +0000 |
---|---|---|
committer | Bruce Momjian <bruce@momjian.us> | 2000-04-12 17:17:23 +0000 |
commit | 52f77df613cea1803ce86321c37229626d9f213c (patch) | |
tree | bd9ac9f667f295cb65f4c448a5bb5a062d656b27 /src/backend/optimizer/path/joinpath.c | |
parent | db4518729d85da83eafdacbcebaeb12618517595 (diff) | |
download | postgresql-52f77df613cea1803ce86321c37229626d9f213c.tar.gz postgresql-52f77df613cea1803ce86321c37229626d9f213c.zip |
Ye-old pgindent run. Same 4-space tabs.
Diffstat (limited to 'src/backend/optimizer/path/joinpath.c')
-rw-r--r-- | src/backend/optimizer/path/joinpath.c | 184 |
1 files changed, 98 insertions, 86 deletions
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c index 92614374968..64e9443ab18 100644 --- a/src/backend/optimizer/path/joinpath.c +++ b/src/backend/optimizer/path/joinpath.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.53 2000/02/18 23:47:19 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.54 2000/04/12 17:15:19 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -28,25 +28,27 @@ #include "utils/lsyscache.h" static void sort_inner_and_outer(Query *root, RelOptInfo *joinrel, - RelOptInfo *outerrel, RelOptInfo *innerrel, - List *restrictlist, List *mergeclause_list); + RelOptInfo *outerrel, RelOptInfo *innerrel, + List *restrictlist, List *mergeclause_list); static void match_unsorted_outer(Query *root, RelOptInfo *joinrel, - RelOptInfo *outerrel, RelOptInfo *innerrel, - List *restrictlist, List *mergeclause_list); + RelOptInfo *outerrel, RelOptInfo *innerrel, + List *restrictlist, List *mergeclause_list); + #ifdef NOT_USED static void match_unsorted_inner(Query *root, RelOptInfo *joinrel, - RelOptInfo *outerrel, RelOptInfo *innerrel, - List *restrictlist, List *mergeclause_list); + RelOptInfo *outerrel, RelOptInfo *innerrel, + List *restrictlist, List *mergeclause_list); + #endif static void hash_inner_and_outer(Query *root, RelOptInfo *joinrel, - RelOptInfo *outerrel, RelOptInfo *innerrel, - List *restrictlist); + RelOptInfo *outerrel, RelOptInfo *innerrel, + List *restrictlist); static Path *best_innerjoin(List *join_paths, List *outer_relid); static Selectivity estimate_disbursion(Query *root, Var *var); static List *select_mergejoin_clauses(RelOptInfo *joinrel, - RelOptInfo *outerrel, - RelOptInfo *innerrel, - List *restrictlist); + RelOptInfo *outerrel, + RelOptInfo *innerrel, + List *restrictlist); /* @@ -79,32 +81,33 @@ add_paths_to_joinrel(Query *root, restrictlist); /* - * 1. Consider mergejoin paths where both relations must be - * explicitly sorted. + * 1. Consider mergejoin paths where both relations must be explicitly + * sorted. */ sort_inner_and_outer(root, joinrel, outerrel, innerrel, restrictlist, mergeclause_list); /* - * 2. Consider paths where the outer relation need not be - * explicitly sorted. This includes both nestloops and - * mergejoins where the outer path is already ordered. + * 2. Consider paths where the outer relation need not be explicitly + * sorted. This includes both nestloops and mergejoins where the outer + * path is already ordered. */ match_unsorted_outer(root, joinrel, outerrel, innerrel, restrictlist, mergeclause_list); #ifdef NOT_USED + /* - * 3. Consider paths where the inner relation need not be - * explicitly sorted. This includes mergejoins only - * (nestloops were already built in match_unsorted_outer). + * 3. Consider paths where the inner relation need not be explicitly + * sorted. This includes mergejoins only (nestloops were already + * built in match_unsorted_outer). * - * Diked out as redundant 2/13/2000 -- tgl. There isn't any - * really significant difference between the inner and outer - * side of a mergejoin, so match_unsorted_inner creates no paths - * that aren't equivalent to those made by match_unsorted_outer - * when add_paths_to_joinrel() is invoked with the two rels given - * in the other order. + * Diked out as redundant 2/13/2000 -- tgl. There isn't any really + * significant difference between the inner and outer side of a + * mergejoin, so match_unsorted_inner creates no paths that aren't + * equivalent to those made by match_unsorted_outer when + * add_paths_to_joinrel() is invoked with the two rels given in the + * other order. */ match_unsorted_inner(root, joinrel, outerrel, innerrel, restrictlist, mergeclause_list); @@ -144,31 +147,31 @@ sort_inner_and_outer(Query *root, /* * Each possible ordering of the available mergejoin clauses will - * generate a differently-sorted result path at essentially the - * same cost. We have no basis for choosing one over another at - * this level of joining, but some sort orders may be more useful - * than others for higher-level mergejoins. Generating a path here - * for *every* permutation of mergejoin clauses doesn't seem like - * a winning strategy, however; the cost in planning time is too high. + * generate a differently-sorted result path at essentially the same + * cost. We have no basis for choosing one over another at this level + * of joining, but some sort orders may be more useful than others for + * higher-level mergejoins. Generating a path here for *every* + * permutation of mergejoin clauses doesn't seem like a winning + * strategy, however; the cost in planning time is too high. * * For now, we generate one path for each mergejoin clause, listing that - * clause first and the rest in random order. This should allow at least - * a one-clause mergejoin without re-sorting against any other possible - * mergejoin partner path. But if we've not guessed the right ordering - * of secondary clauses, we may end up evaluating clauses as qpquals when - * they could have been done as mergeclauses. We need to figure out a - * better way. (Two possible approaches: look at all the relevant index - * relations to suggest plausible sort orders, or make just one output - * path and somehow mark it as having a sort-order that can be rearranged - * freely.) + * clause first and the rest in random order. This should allow at + * least a one-clause mergejoin without re-sorting against any other + * possible mergejoin partner path. But if we've not guessed the + * right ordering of secondary clauses, we may end up evaluating + * clauses as qpquals when they could have been done as mergeclauses. + * We need to figure out a better way. (Two possible approaches: look + * at all the relevant index relations to suggest plausible sort + * orders, or make just one output path and somehow mark it as having + * a sort-order that can be rearranged freely.) */ foreach(i, mergeclause_list) { - RestrictInfo *restrictinfo = lfirst(i); - List *curclause_list; - List *outerkeys; - List *innerkeys; - List *merge_pathkeys; + RestrictInfo *restrictinfo = lfirst(i); + List *curclause_list; + List *outerkeys; + List *innerkeys; + List *merge_pathkeys; /* Make a mergeclause list with this guy first. */ if (i != mergeclause_list) @@ -176,13 +179,14 @@ sort_inner_and_outer(Query *root, lremove(restrictinfo, listCopy(mergeclause_list))); else - curclause_list = mergeclause_list; /* no work at first one... */ + curclause_list = mergeclause_list; /* no work at first one... */ - /* Build sort pathkeys for both sides. + /* + * Build sort pathkeys for both sides. * - * Note: it's possible that the cheapest paths will already be - * sorted properly. create_mergejoin_path will detect that case - * and suppress an explicit sort step, so we needn't do so here. + * Note: it's possible that the cheapest paths will already be sorted + * properly. create_mergejoin_path will detect that case and + * suppress an explicit sort step, so we needn't do so here. */ outerkeys = make_pathkeys_for_mergeclauses(root, curclause_list, @@ -198,8 +202,8 @@ sort_inner_and_outer(Query *root, /* * And now we can make the path. We only consider the cheapest- * total-cost input paths, since we are assuming here that a sort - * is required. We will consider cheapest-startup-cost input paths - * later, and only if they don't need a sort. + * is required. We will consider cheapest-startup-cost input + * paths later, and only if they don't need a sort. */ add_path(joinrel, (Path *) create_mergejoin_path(joinrel, @@ -225,7 +229,7 @@ sort_inner_and_outer(Query *root, * inner path, one on the cheapest-startup-cost inner path (if different), * and one on the best inner-indexscan path (if any). * - * We also consider mergejoins if mergejoin clauses are available. We have + * We also consider mergejoins if mergejoin clauses are available. We have * two ways to generate the inner path for a mergejoin: sort the cheapest * inner path, or use an inner path that is already suitably ordered for the * merge. If we have several mergeclauses, it could be that there is no inner @@ -255,8 +259,8 @@ match_unsorted_outer(Query *root, List *i; /* - * Get the best innerjoin indexpath (if any) for this outer rel. - * It's the same for all outer paths. + * Get the best innerjoin indexpath (if any) for this outer rel. It's + * the same for all outer paths. */ bestinnerjoin = best_innerjoin(innerrel->innerjoin, outerrel->relids); @@ -274,8 +278,8 @@ match_unsorted_outer(Query *root, /* * The result will have this sort order (even if it is implemented - * as a nestloop, and even if some of the mergeclauses are implemented - * by qpquals rather than as true mergeclauses): + * as a nestloop, and even if some of the mergeclauses are + * implemented by qpquals rather than as true mergeclauses): */ merge_pathkeys = build_join_pathkeys(outerpath->pathkeys, joinrel->targetlist, @@ -318,11 +322,12 @@ match_unsorted_outer(Query *root, /* Compute the required ordering of the inner path */ innersortkeys = make_pathkeys_for_mergeclauses(root, mergeclauses, - innerrel->targetlist); + innerrel->targetlist); /* - * Generate a mergejoin on the basis of sorting the cheapest inner. - * Since a sort will be needed, only cheapest total cost matters. + * Generate a mergejoin on the basis of sorting the cheapest + * inner. Since a sort will be needed, only cheapest total cost + * matters. */ add_path(joinrel, (Path *) create_mergejoin_path(joinrel, @@ -335,11 +340,11 @@ match_unsorted_outer(Query *root, innersortkeys)); /* - * Look for presorted inner paths that satisfy the mergeclause list - * or any truncation thereof. Here, we consider both cheap startup - * cost and cheap total cost. + * Look for presorted inner paths that satisfy the mergeclause + * list or any truncation thereof. Here, we consider both cheap + * startup cost and cheap total cost. */ - trialsortkeys = listCopy(innersortkeys); /* modifiable copy */ + trialsortkeys = listCopy(innersortkeys); /* modifiable copy */ cheapest_startup_inner = NULL; cheapest_total_inner = NULL; num_mergeclauses = length(mergeclauses); @@ -349,8 +354,9 @@ match_unsorted_outer(Query *root, Path *innerpath; List *newclauses = NIL; - /* Look for an inner path ordered well enough to merge with - * the first 'clausecnt' mergeclauses. NB: trialsortkeys list + /* + * Look for an inner path ordered well enough to merge with + * the first 'clausecnt' mergeclauses. NB: trialsortkeys list * is modified destructively, which is why we made a copy... */ trialsortkeys = ltruncate(clausecnt, trialsortkeys); @@ -391,14 +397,16 @@ match_unsorted_outer(Query *root, /* Found a cheap (or even-cheaper) sorted path */ if (innerpath != cheapest_total_inner) { - /* Avoid rebuilding clause list if we already made one; - * saves memory in big join trees... + + /* + * Avoid rebuilding clause list if we already made + * one; saves memory in big join trees... */ if (newclauses == NIL) { if (clausecnt < num_mergeclauses) newclauses = ltruncate(clausecnt, - listCopy(mergeclauses)); + listCopy(mergeclauses)); else newclauses = mergeclauses; } @@ -461,11 +469,12 @@ match_unsorted_inner(Query *root, /* Compute the required ordering of the outer path */ outersortkeys = make_pathkeys_for_mergeclauses(root, mergeclauses, - outerrel->targetlist); + outerrel->targetlist); /* - * Generate a mergejoin on the basis of sorting the cheapest outer. - * Since a sort will be needed, only cheapest total cost matters. + * Generate a mergejoin on the basis of sorting the cheapest + * outer. Since a sort will be needed, only cheapest total cost + * matters. */ merge_pathkeys = build_join_pathkeys(outersortkeys, joinrel->targetlist, @@ -479,10 +488,11 @@ match_unsorted_inner(Query *root, mergeclauses, outersortkeys, NIL)); + /* * Now generate mergejoins based on already-sufficiently-ordered - * outer paths. There's likely to be some redundancy here with paths - * already generated by merge_unsorted_outer ... but since + * outer paths. There's likely to be some redundancy here with + * paths already generated by merge_unsorted_outer ... but since * merge_unsorted_outer doesn't consider all permutations of the * mergeclause list, it may fail to notice that this particular * innerpath could have been used with this outerpath. @@ -491,7 +501,8 @@ match_unsorted_inner(Query *root, outersortkeys, TOTAL_COST); if (totalouterpath == NULL) - continue; /* there won't be a startup-cost path either */ + continue; /* there won't be a startup-cost path + * either */ merge_pathkeys = build_join_pathkeys(totalouterpath->pathkeys, joinrel->targetlist, @@ -552,8 +563,8 @@ hash_inner_and_outer(Query *root, List *i; /* - * Scan the join's restrictinfo list to find hashjoinable clauses - * that are usable with this pair of sub-relations. Since we currently + * Scan the join's restrictinfo list to find hashjoinable clauses that + * are usable with this pair of sub-relations. Since we currently * accept only var-op-var clauses as hashjoinable, we need only check * the membership of the vars to determine whether a particular clause * can be used with this pair of sub-relations. This code would need @@ -568,7 +579,7 @@ hash_inner_and_outer(Query *root, *right, *inner; List *hashclauses; - Selectivity innerdisbursion; + Selectivity innerdisbursion; if (restrictinfo->hashjoinoperator == InvalidOid) continue; /* not hashjoinable */ @@ -595,9 +606,9 @@ hash_inner_and_outer(Query *root, innerdisbursion = estimate_disbursion(root, inner); /* - * We consider both the cheapest-total-cost and cheapest-startup-cost - * outer paths. There's no need to consider any but the cheapest- - * total-cost inner path, however. + * We consider both the cheapest-total-cost and + * cheapest-startup-cost outer paths. There's no need to consider + * any but the cheapest- total-cost inner path, however. */ add_path(joinrel, (Path *) create_hashjoin_path(joinrel, @@ -644,7 +655,8 @@ best_innerjoin(List *join_paths, Relids outer_relids) Assert(IsA(path, IndexPath)); - /* path->joinrelids is the set of base rels that must be part of + /* + * path->joinrelids is the set of base rels that must be part of * outer_relids in order to use this inner path, because those * rels are used in the index join quals of this inner path. */ @@ -661,7 +673,7 @@ best_innerjoin(List *join_paths, Relids outer_relids) * * We use a default of 0.1 if we can't figure out anything better. * This will typically discourage use of a hash rather strongly, - * if the inner relation is large. We do not want to hash unless + * if the inner relation is large. We do not want to hash unless * we know that the inner rel is well-dispersed (or the alternatives * seem much worse). */ @@ -670,7 +682,7 @@ estimate_disbursion(Query *root, Var *var) { Oid relid; - if (! IsA(var, Var)) + if (!IsA(var, Var)) return 0.1; relid = getrelid(var->varno, root->rtable); @@ -690,7 +702,7 @@ estimate_disbursion(Query *root, Var *var) * Since we currently allow only plain Vars as the left and right sides * of mergejoin clauses, this test is relatively simple. This routine * would need to be upgraded to support more-complex expressions - * as sides of mergejoins. In theory, we could allow arbitrarily complex + * as sides of mergejoins. In theory, we could allow arbitrarily complex * expressions in mergejoins, so long as one side uses only vars from one * sub-relation and the other side uses only vars from the other. */ |