mirror of
https://github.com/postgres/postgres.git
synced 2025-07-14 08:21:07 +03:00
pgindent run for 9.0
This commit is contained in:
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.192 2010/01/02 16:57:46 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.193 2010/02/26 02:00:44 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -347,11 +347,11 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
|
||||
* can disregard this child.
|
||||
*
|
||||
* As of 8.4, the child rel's targetlist might contain non-Var
|
||||
* expressions, which means that substitution into the quals
|
||||
* could produce opportunities for const-simplification, and perhaps
|
||||
* even pseudoconstant quals. To deal with this, we strip the
|
||||
* RestrictInfo nodes, do the substitution, do const-simplification,
|
||||
* and then reconstitute the RestrictInfo layer.
|
||||
* expressions, which means that substitution into the quals could
|
||||
* produce opportunities for const-simplification, and perhaps even
|
||||
* pseudoconstant quals. To deal with this, we strip the RestrictInfo
|
||||
* nodes, do the substitution, do const-simplification, and then
|
||||
* reconstitute the RestrictInfo layer.
|
||||
*/
|
||||
childquals = get_all_actual_clauses(rel->baserestrictinfo);
|
||||
childquals = (List *) adjust_appendrel_attrs((Node *) childquals,
|
||||
|
@ -59,7 +59,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.215 2010/02/19 21:49:10 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.216 2010/02/26 02:00:44 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -635,11 +635,11 @@ cost_bitmap_heap_scan(Path *path, PlannerInfo *root, RelOptInfo *baserel,
|
||||
pages_fetched = ceil(pages_fetched);
|
||||
|
||||
/*
|
||||
* For small numbers of pages we should charge spc_random_page_cost apiece,
|
||||
* while if nearly all the table's pages are being read, it's more
|
||||
* appropriate to charge spc_seq_page_cost apiece. The effect is nonlinear,
|
||||
* too. For lack of a better idea, interpolate like this to determine the
|
||||
* cost per page.
|
||||
* For small numbers of pages we should charge spc_random_page_cost
|
||||
* apiece, while if nearly all the table's pages are being read, it's more
|
||||
* appropriate to charge spc_seq_page_cost apiece. The effect is
|
||||
* nonlinear, too. For lack of a better idea, interpolate like this to
|
||||
* determine the cost per page.
|
||||
*/
|
||||
if (pages_fetched >= 2.0)
|
||||
cost_per_page = spc_random_page_cost -
|
||||
@ -936,13 +936,13 @@ cost_functionscan(Path *path, PlannerInfo *root, RelOptInfo *baserel)
|
||||
*
|
||||
* Currently, nodeFunctionscan.c always executes the function to
|
||||
* completion before returning any rows, and caches the results in a
|
||||
* tuplestore. So the function eval cost is all startup cost, and
|
||||
* per-row costs are minimal.
|
||||
* tuplestore. So the function eval cost is all startup cost, and per-row
|
||||
* costs are minimal.
|
||||
*
|
||||
* XXX in principle we ought to charge tuplestore spill costs if the
|
||||
* number of rows is large. However, given how phony our rowcount
|
||||
* estimates for functions tend to be, there's not a lot of point
|
||||
* in that refinement right now.
|
||||
* estimates for functions tend to be, there's not a lot of point in that
|
||||
* refinement right now.
|
||||
*/
|
||||
cost_qual_eval_node(&exprcost, rte->funcexpr, root);
|
||||
|
||||
@ -1230,7 +1230,7 @@ cost_material(Path *path,
|
||||
* if it is exactly the same then there will be a cost tie between
|
||||
* nestloop with A outer, materialized B inner and nestloop with B outer,
|
||||
* materialized A inner. The extra cost ensures we'll prefer
|
||||
* materializing the smaller rel.) Note that this is normally a good deal
|
||||
* materializing the smaller rel.) Note that this is normally a good deal
|
||||
* less than cpu_tuple_cost; which is OK because a Material plan node
|
||||
* doesn't do qual-checking or projection, so it's got less overhead than
|
||||
* most plan nodes.
|
||||
@ -1526,9 +1526,10 @@ cost_nestloop(NestPath *path, PlannerInfo *root, SpecialJoinInfo *sjinfo)
|
||||
{
|
||||
run_cost += (outer_path_rows - outer_matched_rows) *
|
||||
inner_rescan_run_cost / inner_path_rows;
|
||||
|
||||
/*
|
||||
* We won't be evaluating any quals at all for these rows,
|
||||
* so don't add them to ntuples.
|
||||
* We won't be evaluating any quals at all for these rows, so
|
||||
* don't add them to ntuples.
|
||||
*/
|
||||
}
|
||||
else
|
||||
@ -1568,10 +1569,10 @@ cost_nestloop(NestPath *path, PlannerInfo *root, SpecialJoinInfo *sjinfo)
|
||||
* Unlike other costsize functions, this routine makes one actual decision:
|
||||
* whether we should materialize the inner path. We do that either because
|
||||
* the inner path can't support mark/restore, or because it's cheaper to
|
||||
* use an interposed Material node to handle mark/restore. When the decision
|
||||
* use an interposed Material node to handle mark/restore. When the decision
|
||||
* is cost-based it would be logically cleaner to build and cost two separate
|
||||
* paths with and without that flag set; but that would require repeating most
|
||||
* of the calculations here, which are not all that cheap. Since the choice
|
||||
* of the calculations here, which are not all that cheap. Since the choice
|
||||
* will not affect output pathkeys or startup cost, only total cost, there is
|
||||
* no possibility of wanting to keep both paths. So it seems best to make
|
||||
* the decision here and record it in the path's materialize_inner field.
|
||||
@ -1826,14 +1827,15 @@ cost_mergejoin(MergePath *path, PlannerInfo *root, SpecialJoinInfo *sjinfo)
|
||||
|
||||
/*
|
||||
* Decide whether we want to materialize the inner input to shield it from
|
||||
* mark/restore and performing re-fetches. Our cost model for regular
|
||||
* mark/restore and performing re-fetches. Our cost model for regular
|
||||
* re-fetches is that a re-fetch costs the same as an original fetch,
|
||||
* which is probably an overestimate; but on the other hand we ignore the
|
||||
* bookkeeping costs of mark/restore. Not clear if it's worth developing
|
||||
* a more refined model. So we just need to inflate the inner run cost
|
||||
* by rescanratio.
|
||||
* a more refined model. So we just need to inflate the inner run cost by
|
||||
* rescanratio.
|
||||
*/
|
||||
bare_inner_cost = inner_run_cost * rescanratio;
|
||||
|
||||
/*
|
||||
* When we interpose a Material node the re-fetch cost is assumed to be
|
||||
* just cpu_operator_cost per tuple, independently of the underlying
|
||||
@ -1842,7 +1844,7 @@ cost_mergejoin(MergePath *path, PlannerInfo *root, SpecialJoinInfo *sjinfo)
|
||||
* never spill to disk, since it only has to remember tuples back to the
|
||||
* last mark. (If there are a huge number of duplicates, our other cost
|
||||
* factors will make the path so expensive that it probably won't get
|
||||
* chosen anyway.) So we don't use cost_rescan here.
|
||||
* chosen anyway.) So we don't use cost_rescan here.
|
||||
*
|
||||
* Note: keep this estimate in sync with create_mergejoin_plan's labeling
|
||||
* of the generated Material node.
|
||||
@ -1853,6 +1855,7 @@ cost_mergejoin(MergePath *path, PlannerInfo *root, SpecialJoinInfo *sjinfo)
|
||||
/* Prefer materializing if it looks cheaper */
|
||||
if (mat_inner_cost < bare_inner_cost)
|
||||
path->materialize_inner = true;
|
||||
|
||||
/*
|
||||
* Even if materializing doesn't look cheaper, we *must* do it if the
|
||||
* inner path is to be used directly (without sorting) and it doesn't
|
||||
@ -1868,6 +1871,7 @@ cost_mergejoin(MergePath *path, PlannerInfo *root, SpecialJoinInfo *sjinfo)
|
||||
else if (innersortkeys == NIL &&
|
||||
!ExecSupportsMarkRestore(inner_path->pathtype))
|
||||
path->materialize_inner = true;
|
||||
|
||||
/*
|
||||
* Also, force materializing if the inner path is to be sorted and the
|
||||
* sort is expected to spill to disk. This is because the final merge
|
||||
@ -2323,10 +2327,10 @@ cost_subplan(PlannerInfo *root, SubPlan *subplan, Plan *plan)
|
||||
/*
|
||||
* cost_rescan
|
||||
* Given a finished Path, estimate the costs of rescanning it after
|
||||
* having done so the first time. For some Path types a rescan is
|
||||
* having done so the first time. For some Path types a rescan is
|
||||
* cheaper than an original scan (if no parameters change), and this
|
||||
* function embodies knowledge about that. The default is to return
|
||||
* the same costs stored in the Path. (Note that the cost estimates
|
||||
* the same costs stored in the Path. (Note that the cost estimates
|
||||
* actually stored in Paths are always for first scans.)
|
||||
*
|
||||
* This function is not currently intended to model effects such as rescans
|
||||
@ -2336,23 +2340,25 @@ cost_subplan(PlannerInfo *root, SubPlan *subplan, Plan *plan)
|
||||
*/
|
||||
static void
|
||||
cost_rescan(PlannerInfo *root, Path *path,
|
||||
Cost *rescan_startup_cost, /* output parameters */
|
||||
Cost *rescan_startup_cost, /* output parameters */
|
||||
Cost *rescan_total_cost)
|
||||
{
|
||||
switch (path->pathtype)
|
||||
{
|
||||
case T_FunctionScan:
|
||||
|
||||
/*
|
||||
* Currently, nodeFunctionscan.c always executes the function
|
||||
* to completion before returning any rows, and caches the
|
||||
* results in a tuplestore. So the function eval cost is
|
||||
* all startup cost and isn't paid over again on rescans.
|
||||
* However, all run costs will be paid over again.
|
||||
* Currently, nodeFunctionscan.c always executes the function to
|
||||
* completion before returning any rows, and caches the results in
|
||||
* a tuplestore. So the function eval cost is all startup cost
|
||||
* and isn't paid over again on rescans. However, all run costs
|
||||
* will be paid over again.
|
||||
*/
|
||||
*rescan_startup_cost = 0;
|
||||
*rescan_total_cost = path->total_cost - path->startup_cost;
|
||||
break;
|
||||
case T_HashJoin:
|
||||
|
||||
/*
|
||||
* Assume that all of the startup cost represents hash table
|
||||
* building, which we won't have to do over.
|
||||
@ -2365,14 +2371,14 @@ cost_rescan(PlannerInfo *root, Path *path,
|
||||
{
|
||||
/*
|
||||
* These plan types materialize their final result in a
|
||||
* tuplestore or tuplesort object. So the rescan cost is only
|
||||
* tuplestore or tuplesort object. So the rescan cost is only
|
||||
* cpu_tuple_cost per tuple, unless the result is large enough
|
||||
* to spill to disk.
|
||||
*/
|
||||
Cost run_cost = cpu_tuple_cost * path->parent->rows;
|
||||
double nbytes = relation_byte_size(path->parent->rows,
|
||||
path->parent->width);
|
||||
long work_mem_bytes = work_mem * 1024L;
|
||||
Cost run_cost = cpu_tuple_cost * path->parent->rows;
|
||||
double nbytes = relation_byte_size(path->parent->rows,
|
||||
path->parent->width);
|
||||
long work_mem_bytes = work_mem * 1024L;
|
||||
|
||||
if (nbytes > work_mem_bytes)
|
||||
{
|
||||
@ -2389,17 +2395,17 @@ cost_rescan(PlannerInfo *root, Path *path,
|
||||
case T_Sort:
|
||||
{
|
||||
/*
|
||||
* These plan types not only materialize their results, but
|
||||
* do not implement qual filtering or projection. So they
|
||||
* are even cheaper to rescan than the ones above. We charge
|
||||
* only cpu_operator_cost per tuple. (Note: keep that in
|
||||
* sync with the run_cost charge in cost_sort, and also see
|
||||
* comments in cost_material before you change it.)
|
||||
* These plan types not only materialize their results, but do
|
||||
* not implement qual filtering or projection. So they are
|
||||
* even cheaper to rescan than the ones above. We charge only
|
||||
* cpu_operator_cost per tuple. (Note: keep that in sync with
|
||||
* the run_cost charge in cost_sort, and also see comments in
|
||||
* cost_material before you change it.)
|
||||
*/
|
||||
Cost run_cost = cpu_operator_cost * path->parent->rows;
|
||||
double nbytes = relation_byte_size(path->parent->rows,
|
||||
path->parent->width);
|
||||
long work_mem_bytes = work_mem * 1024L;
|
||||
Cost run_cost = cpu_operator_cost * path->parent->rows;
|
||||
double nbytes = relation_byte_size(path->parent->rows,
|
||||
path->parent->width);
|
||||
long work_mem_bytes = work_mem * 1024L;
|
||||
|
||||
if (nbytes > work_mem_bytes)
|
||||
{
|
||||
@ -3212,8 +3218,8 @@ set_rel_width(PlannerInfo *root, RelOptInfo *rel)
|
||||
{
|
||||
/*
|
||||
* We could be looking at an expression pulled up from a subquery,
|
||||
* or a ROW() representing a whole-row child Var, etc. Do what
|
||||
* we can using the expression type information.
|
||||
* or a ROW() representing a whole-row child Var, etc. Do what we
|
||||
* can using the expression type information.
|
||||
*/
|
||||
int32 item_width;
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/equivclass.c,v 1.22 2010/01/02 16:57:46 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/equivclass.c,v 1.23 2010/02/26 02:00:44 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -115,14 +115,13 @@ process_equivalence(PlannerInfo *root, RestrictInfo *restrictinfo,
|
||||
item2_relids = restrictinfo->right_relids;
|
||||
|
||||
/*
|
||||
* Reject clauses of the form X=X. These are not as redundant as they
|
||||
* Reject clauses of the form X=X. These are not as redundant as they
|
||||
* might seem at first glance: assuming the operator is strict, this is
|
||||
* really an expensive way to write X IS NOT NULL. So we must not risk
|
||||
* just losing the clause, which would be possible if there is already
|
||||
* a single-element EquivalenceClass containing X. The case is not
|
||||
* common enough to be worth contorting the EC machinery for, so just
|
||||
* reject the clause and let it be processed as a normal restriction
|
||||
* clause.
|
||||
* really an expensive way to write X IS NOT NULL. So we must not risk
|
||||
* just losing the clause, which would be possible if there is already a
|
||||
* single-element EquivalenceClass containing X. The case is not common
|
||||
* enough to be worth contorting the EC machinery for, so just reject the
|
||||
* clause and let it be processed as a normal restriction clause.
|
||||
*/
|
||||
if (equal(item1, item2))
|
||||
return false; /* X=X is not a useful equivalence */
|
||||
@ -367,7 +366,7 @@ add_eq_member(EquivalenceClass *ec, Expr *expr, Relids relids,
|
||||
* EquivalenceClass for it.
|
||||
*
|
||||
* sortref is the SortGroupRef of the originating SortGroupClause, if any,
|
||||
* or zero if not. (It should never be zero if the expression is volatile!)
|
||||
* or zero if not. (It should never be zero if the expression is volatile!)
|
||||
*
|
||||
* This can be used safely both before and after EquivalenceClass merging;
|
||||
* since it never causes merging it does not invalidate any existing ECs
|
||||
@ -448,7 +447,7 @@ get_eclass_for_sort_expr(PlannerInfo *root,
|
||||
newec->ec_sortref = sortref;
|
||||
newec->ec_merged = NULL;
|
||||
|
||||
if (newec->ec_has_volatile && sortref == 0) /* should not happen */
|
||||
if (newec->ec_has_volatile && sortref == 0) /* should not happen */
|
||||
elog(ERROR, "volatile EquivalenceClass has no sortref");
|
||||
|
||||
newem = add_eq_member(newec, expr, pull_varnos((Node *) expr),
|
||||
|
@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.245 2010/01/02 16:57:46 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.246 2010/02/26 02:00:44 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1944,8 +1944,8 @@ relation_has_unique_index_for(PlannerInfo *root, RelOptInfo *rel,
|
||||
/* Examine each index of the relation ... */
|
||||
foreach(ic, rel->indexlist)
|
||||
{
|
||||
IndexOptInfo *ind = (IndexOptInfo *) lfirst(ic);
|
||||
int c;
|
||||
IndexOptInfo *ind = (IndexOptInfo *) lfirst(ic);
|
||||
int c;
|
||||
|
||||
/*
|
||||
* If the index is not unique or if it's a partial index that doesn't
|
||||
@ -1964,13 +1964,13 @@ relation_has_unique_index_for(PlannerInfo *root, RelOptInfo *rel,
|
||||
|
||||
foreach(lc, restrictlist)
|
||||
{
|
||||
RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
|
||||
Node *rexpr;
|
||||
RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
|
||||
Node *rexpr;
|
||||
|
||||
/*
|
||||
* The condition's equality operator must be a member of the
|
||||
* index opfamily, else it is not asserting the right kind
|
||||
* of equality behavior for this index. We check this first
|
||||
* index opfamily, else it is not asserting the right kind of
|
||||
* equality behavior for this index. We check this first
|
||||
* since it's probably cheaper than match_index_to_operand().
|
||||
*/
|
||||
if (!list_member_oid(rinfo->mergeopfamilies, ind->opfamily[c]))
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinpath.c,v 1.129 2010/01/05 23:25:36 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinpath.c,v 1.130 2010/02/26 02:00:44 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -161,7 +161,7 @@ add_paths_to_joinrel(PlannerInfo *root,
|
||||
* We already know that the clause is a binary opclause referencing only the
|
||||
* rels in the current join. The point here is to check whether it has the
|
||||
* form "outerrel_expr op innerrel_expr" or "innerrel_expr op outerrel_expr",
|
||||
* rather than mixing outer and inner vars on either side. If it matches,
|
||||
* rather than mixing outer and inner vars on either side. If it matches,
|
||||
* we set the transient flag outer_is_left to identify which side is which.
|
||||
*/
|
||||
static inline bool
|
||||
@ -212,7 +212,7 @@ join_is_removable(PlannerInfo *root,
|
||||
|
||||
/*
|
||||
* Currently, we only know how to remove left joins to a baserel with
|
||||
* unique indexes. We can check most of these criteria pretty trivially
|
||||
* unique indexes. We can check most of these criteria pretty trivially
|
||||
* to avoid doing useless extra work. But checking whether any of the
|
||||
* indexes are unique would require iterating over the indexlist, so for
|
||||
* now we just make sure there are indexes of some sort or other. If none
|
||||
@ -225,13 +225,12 @@ join_is_removable(PlannerInfo *root,
|
||||
return false;
|
||||
|
||||
/*
|
||||
* We can't remove the join if any inner-rel attributes are used above
|
||||
* the join.
|
||||
* We can't remove the join if any inner-rel attributes are used above the
|
||||
* join.
|
||||
*
|
||||
* Note that this test only detects use of inner-rel attributes in
|
||||
* higher join conditions and the target list. There might be such
|
||||
* attributes in pushed-down conditions at this join, too. We check
|
||||
* that case below.
|
||||
* Note that this test only detects use of inner-rel attributes in higher
|
||||
* join conditions and the target list. There might be such attributes in
|
||||
* pushed-down conditions at this join, too. We check that case below.
|
||||
*
|
||||
* As a micro-optimization, it seems better to start with max_attr and
|
||||
* count down rather than starting with min_attr and counting up, on the
|
||||
@ -249,9 +248,9 @@ join_is_removable(PlannerInfo *root,
|
||||
/*
|
||||
* Search for mergejoinable clauses that constrain the inner rel against
|
||||
* either the outer rel or a pseudoconstant. If an operator is
|
||||
* mergejoinable then it behaves like equality for some btree opclass,
|
||||
* so it's what we want. The mergejoinability test also eliminates
|
||||
* clauses containing volatile functions, which we couldn't depend on.
|
||||
* mergejoinable then it behaves like equality for some btree opclass, so
|
||||
* it's what we want. The mergejoinability test also eliminates clauses
|
||||
* containing volatile functions, which we couldn't depend on.
|
||||
*/
|
||||
foreach(l, restrictlist)
|
||||
{
|
||||
@ -259,10 +258,10 @@ join_is_removable(PlannerInfo *root,
|
||||
|
||||
/*
|
||||
* If we find a pushed-down clause, it must have come from above the
|
||||
* outer join and it must contain references to the inner rel. (If
|
||||
* it had only outer-rel variables, it'd have been pushed down into
|
||||
* the outer rel.) Therefore, we can conclude that join removal
|
||||
* is unsafe without any examination of the clause contents.
|
||||
* outer join and it must contain references to the inner rel. (If it
|
||||
* had only outer-rel variables, it'd have been pushed down into the
|
||||
* outer rel.) Therefore, we can conclude that join removal is unsafe
|
||||
* without any examination of the clause contents.
|
||||
*/
|
||||
if (restrictinfo->is_pushed_down)
|
||||
return false;
|
||||
@ -289,15 +288,15 @@ join_is_removable(PlannerInfo *root,
|
||||
|
||||
/*
|
||||
* Note: can_join won't be set for a restriction clause, but
|
||||
* mergeopfamilies will be if it has a mergejoinable operator
|
||||
* and doesn't contain volatile functions.
|
||||
* mergeopfamilies will be if it has a mergejoinable operator and
|
||||
* doesn't contain volatile functions.
|
||||
*/
|
||||
if (restrictinfo->mergeopfamilies == NIL)
|
||||
continue; /* not mergejoinable */
|
||||
|
||||
/*
|
||||
* The clause certainly doesn't refer to anything but the given
|
||||
* rel. If either side is pseudoconstant then we can use it.
|
||||
* The clause certainly doesn't refer to anything but the given rel.
|
||||
* If either side is pseudoconstant then we can use it.
|
||||
*/
|
||||
if (bms_is_empty(restrictinfo->left_relids))
|
||||
{
|
||||
@ -340,13 +339,13 @@ generate_outer_only(PlannerInfo *root, RelOptInfo *joinrel,
|
||||
/*
|
||||
* For the moment, replicate all of the outerrel's paths as join paths.
|
||||
* Some of them might not really be interesting above the join, if they
|
||||
* have sort orderings that have no real use except to do a mergejoin
|
||||
* for the join we've just found we don't need. But distinguishing that
|
||||
* case probably isn't worth the extra code it would take.
|
||||
* have sort orderings that have no real use except to do a mergejoin for
|
||||
* the join we've just found we don't need. But distinguishing that case
|
||||
* probably isn't worth the extra code it would take.
|
||||
*/
|
||||
foreach(lc, outerrel->pathlist)
|
||||
{
|
||||
Path *outerpath = (Path *) lfirst(lc);
|
||||
Path *outerpath = (Path *) lfirst(lc);
|
||||
|
||||
add_path(joinrel, (Path *)
|
||||
create_noop_path(root, joinrel, outerpath));
|
||||
@ -1189,8 +1188,8 @@ select_mergejoin_clauses(PlannerInfo *root,
|
||||
restrictinfo->mergeopfamilies == NIL)
|
||||
{
|
||||
/*
|
||||
* The executor can handle extra joinquals that are constants,
|
||||
* but not anything else, when doing right/full merge join. (The
|
||||
* The executor can handle extra joinquals that are constants, but
|
||||
* not anything else, when doing right/full merge join. (The
|
||||
* reason to support constants is so we can do FULL JOIN ON
|
||||
* FALSE.)
|
||||
*/
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.104 2010/01/02 16:57:47 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.105 2010/02/26 02:00:45 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -373,10 +373,10 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
|
||||
continue;
|
||||
|
||||
/*
|
||||
* If it's a semijoin and we already joined the RHS to any other
|
||||
* rels within either input, then we must have unique-ified the RHS
|
||||
* at that point (see below). Therefore the semijoin is no longer
|
||||
* relevant in this join path.
|
||||
* If it's a semijoin and we already joined the RHS to any other rels
|
||||
* within either input, then we must have unique-ified the RHS at that
|
||||
* point (see below). Therefore the semijoin is no longer relevant in
|
||||
* this join path.
|
||||
*/
|
||||
if (sjinfo->jointype == JOIN_SEMI)
|
||||
{
|
||||
@ -495,9 +495,9 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
|
||||
}
|
||||
|
||||
/*
|
||||
* Fail if violated some SJ's RHS and didn't match to another SJ.
|
||||
* However, "matching" to a semijoin we are implementing by
|
||||
* unique-ification doesn't count (think: it's really an inner join).
|
||||
* Fail if violated some SJ's RHS and didn't match to another SJ. However,
|
||||
* "matching" to a semijoin we are implementing by unique-ification
|
||||
* doesn't count (think: it's really an inner join).
|
||||
*/
|
||||
if (!is_valid_inner &&
|
||||
(match_sjinfo == NULL || unique_ified))
|
||||
|
@ -11,7 +11,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.100 2010/01/02 16:57:47 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.101 2010/02/26 02:00:45 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -637,12 +637,12 @@ convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel,
|
||||
0);
|
||||
|
||||
/*
|
||||
* Note: it might look funny to be setting sortref = 0 for
|
||||
* a reference to a volatile sub_eclass. However, the
|
||||
* expression is *not* volatile in the outer query: it's
|
||||
* just a Var referencing whatever the subquery emitted.
|
||||
* (IOW, the outer query isn't going to re-execute the
|
||||
* volatile expression itself.) So this is okay.
|
||||
* Note: it might look funny to be setting sortref = 0 for a
|
||||
* reference to a volatile sub_eclass. However, the
|
||||
* expression is *not* volatile in the outer query: it's just
|
||||
* a Var referencing whatever the subquery emitted. (IOW, the
|
||||
* outer query isn't going to re-execute the volatile
|
||||
* expression itself.) So this is okay.
|
||||
*/
|
||||
outer_ec =
|
||||
get_eclass_for_sort_expr(root,
|
||||
@ -1000,7 +1000,7 @@ find_mergeclauses_for_pathkeys(PlannerInfo *root,
|
||||
* It's possible that multiple matching clauses might have different
|
||||
* ECs on the other side, in which case the order we put them into our
|
||||
* result makes a difference in the pathkeys required for the other
|
||||
* input path. However this routine hasn't got any info about which
|
||||
* input path. However this routine hasn't got any info about which
|
||||
* order would be best, so we don't worry about that.
|
||||
*
|
||||
* It's also possible that the selected mergejoin clauses produce
|
||||
|
Reference in New Issue
Block a user