mirror of
https://github.com/postgres/postgres.git
synced 2025-07-14 08:21:07 +03:00
Pgindent run for 8.0.
This commit is contained in:
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.120 2004/08/29 04:12:33 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.121 2004/08/29 05:06:43 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -58,9 +58,9 @@ static void compare_tlist_datatypes(List *tlist, List *colTypes,
|
||||
static bool qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual,
|
||||
bool *differentTypes);
|
||||
static void subquery_push_qual(Query *subquery, List *rtable,
|
||||
Index rti, Node *qual);
|
||||
Index rti, Node *qual);
|
||||
static void recurse_push_qual(Node *setOp, Query *topquery,
|
||||
List *rtable, Index rti, Node *qual);
|
||||
List *rtable, Index rti, Node *qual);
|
||||
|
||||
|
||||
/*
|
||||
@ -102,7 +102,7 @@ make_one_rel(Query *root)
|
||||
static void
|
||||
set_base_rel_pathlists(Query *root)
|
||||
{
|
||||
ListCell *l;
|
||||
ListCell *l;
|
||||
|
||||
foreach(l, root->base_rel_list)
|
||||
{
|
||||
@ -156,9 +156,9 @@ set_plain_rel_pathlist(Query *root, RelOptInfo *rel, RangeTblEntry *rte)
|
||||
check_partial_indexes(root, rel);
|
||||
|
||||
/*
|
||||
* Check to see if we can extract any restriction conditions from
|
||||
* join quals that are OR-of-AND structures. If so, add them to the
|
||||
* rel's restriction list, and recompute the size estimates.
|
||||
* Check to see if we can extract any restriction conditions from join
|
||||
* quals that are OR-of-AND structures. If so, add them to the rel's
|
||||
* restriction list, and recompute the size estimates.
|
||||
*/
|
||||
if (create_or_index_quals(root, rel))
|
||||
set_baserel_size_estimates(root, rel);
|
||||
@ -303,7 +303,7 @@ set_inherited_rel_pathlist(Query *root, RelOptInfo *rel,
|
||||
Var *parentvar = (Var *) lfirst(parentvars);
|
||||
Var *childvar = (Var *) lfirst(childvars);
|
||||
|
||||
if (IsA(parentvar, Var) && IsA(childvar, Var))
|
||||
if (IsA(parentvar, Var) &&IsA(childvar, Var))
|
||||
{
|
||||
int pndx = parentvar->varattno - rel->min_attr;
|
||||
int cndx = childvar->varattno - childrel->min_attr;
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/clausesel.c,v 1.69 2004/08/29 04:12:33 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/clausesel.c,v 1.70 2004/08/29 05:06:43 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -128,7 +128,7 @@ clauselist_selectivity(Query *root,
|
||||
/*
|
||||
* See if it looks like a restriction clause with a pseudoconstant
|
||||
* on one side. (Anything more complicated than that might not
|
||||
* behave in the simple way we are expecting.) Most of the tests
|
||||
* behave in the simple way we are expecting.) Most of the tests
|
||||
* here can be done more efficiently with rinfo than without.
|
||||
*/
|
||||
if (is_opclause(clause) && list_length(((OpExpr *) clause)->args) == 2)
|
||||
@ -141,10 +141,10 @@ clauselist_selectivity(Query *root,
|
||||
{
|
||||
ok = (bms_membership(rinfo->clause_relids) == BMS_SINGLETON) &&
|
||||
(is_pseudo_constant_clause_relids(lsecond(expr->args),
|
||||
rinfo->right_relids) ||
|
||||
rinfo->right_relids) ||
|
||||
(varonleft = false,
|
||||
is_pseudo_constant_clause_relids(linitial(expr->args),
|
||||
rinfo->left_relids)));
|
||||
is_pseudo_constant_clause_relids(linitial(expr->args),
|
||||
rinfo->left_relids)));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -158,9 +158,8 @@ clauselist_selectivity(Query *root,
|
||||
{
|
||||
/*
|
||||
* If it's not a "<" or ">" operator, just merge the
|
||||
* selectivity in generically. But if it's the
|
||||
* right oprrest, add the clause to rqlist for later
|
||||
* processing.
|
||||
* selectivity in generically. But if it's the right
|
||||
* oprrest, add the clause to rqlist for later processing.
|
||||
*/
|
||||
switch (get_oprrest(expr->opno))
|
||||
{
|
||||
@ -409,16 +408,17 @@ clause_selectivity(Query *root,
|
||||
rinfo = (RestrictInfo *) clause;
|
||||
|
||||
/*
|
||||
* If possible, cache the result of the selectivity calculation for
|
||||
* the clause. We can cache if varRelid is zero or the clause
|
||||
* contains only vars of that relid --- otherwise varRelid will affect
|
||||
* the result, so mustn't cache. We also have to be careful about
|
||||
* the jointype. It's OK to cache when jointype is JOIN_INNER or
|
||||
* one of the outer join types (any given outer-join clause should
|
||||
* always be examined with the same jointype, so result won't change).
|
||||
* It's not OK to cache when jointype is one of the special types
|
||||
* associated with IN processing, because the same clause may be
|
||||
* examined with different jointypes and the result should vary.
|
||||
* If possible, cache the result of the selectivity calculation
|
||||
* for the clause. We can cache if varRelid is zero or the clause
|
||||
* contains only vars of that relid --- otherwise varRelid will
|
||||
* affect the result, so mustn't cache. We also have to be
|
||||
* careful about the jointype. It's OK to cache when jointype is
|
||||
* JOIN_INNER or one of the outer join types (any given outer-join
|
||||
* clause should always be examined with the same jointype, so
|
||||
* result won't change). It's not OK to cache when jointype is one
|
||||
* of the special types associated with IN processing, because the
|
||||
* same clause may be examined with different jointypes and the
|
||||
* result should vary.
|
||||
*/
|
||||
if (varRelid == 0 ||
|
||||
bms_is_subset_singleton(rinfo->clause_relids, varRelid))
|
||||
@ -481,7 +481,7 @@ clause_selectivity(Query *root,
|
||||
s1 = restriction_selectivity(root,
|
||||
BooleanEqualOperator,
|
||||
list_make2(var,
|
||||
makeBoolConst(true,
|
||||
makeBoolConst(true,
|
||||
false)),
|
||||
varRelid);
|
||||
}
|
||||
@ -495,7 +495,7 @@ clause_selectivity(Query *root,
|
||||
else if (IsA(clause, Param))
|
||||
{
|
||||
/* see if we can replace the Param */
|
||||
Node *subst = estimate_expression_value(clause);
|
||||
Node *subst = estimate_expression_value(clause);
|
||||
|
||||
if (IsA(subst, Const))
|
||||
{
|
||||
@ -527,8 +527,8 @@ clause_selectivity(Query *root,
|
||||
else if (or_clause(clause))
|
||||
{
|
||||
/*
|
||||
* Selectivities for an OR clause are computed as s1+s2 - s1*s2
|
||||
* to account for the probable overlap of selected tuple sets.
|
||||
* Selectivities for an OR clause are computed as s1+s2 - s1*s2 to
|
||||
* account for the probable overlap of selected tuple sets.
|
||||
*
|
||||
* XXX is this too conservative?
|
||||
*/
|
||||
@ -563,7 +563,8 @@ clause_selectivity(Query *root,
|
||||
{
|
||||
/*
|
||||
* Otherwise, it's a join if there's more than one relation
|
||||
* used. We can optimize this calculation if an rinfo was passed.
|
||||
* used. We can optimize this calculation if an rinfo was
|
||||
* passed.
|
||||
*/
|
||||
if (rinfo)
|
||||
is_join_clause = (bms_membership(rinfo->clause_relids) ==
|
||||
|
@ -49,7 +49,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.133 2004/08/29 04:12:33 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.134 2004/08/29 05:06:43 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -746,10 +746,10 @@ cost_nestloop(NestPath *path, Query *root)
|
||||
Selectivity joininfactor;
|
||||
|
||||
/*
|
||||
* If inner path is an indexscan, be sure to use its estimated output row
|
||||
* count, which may be lower than the restriction-clause-only row count of
|
||||
* its parent. (We don't include this case in the PATH_ROWS macro because
|
||||
* it applies *only* to a nestloop's inner relation.)
|
||||
* If inner path is an indexscan, be sure to use its estimated output
|
||||
* row count, which may be lower than the restriction-clause-only row
|
||||
* count of its parent. (We don't include this case in the PATH_ROWS
|
||||
* macro because it applies *only* to a nestloop's inner relation.)
|
||||
*/
|
||||
if (IsA(inner_path, IndexPath))
|
||||
inner_path_rows = ((IndexPath *) inner_path)->rows;
|
||||
@ -761,8 +761,8 @@ cost_nestloop(NestPath *path, Query *root)
|
||||
* If we're doing JOIN_IN then we will stop scanning inner tuples for
|
||||
* an outer tuple as soon as we have one match. Account for the
|
||||
* effects of this by scaling down the cost estimates in proportion to
|
||||
* the JOIN_IN selectivity. (This assumes that all the quals
|
||||
* attached to the join are IN quals, which should be true.)
|
||||
* the JOIN_IN selectivity. (This assumes that all the quals attached
|
||||
* to the join are IN quals, which should be true.)
|
||||
*/
|
||||
joininfactor = join_in_selectivity(path, root);
|
||||
|
||||
@ -922,7 +922,7 @@ cost_mergejoin(MergePath *path, Query *root)
|
||||
if (mergeclauses)
|
||||
{
|
||||
firstclause = (RestrictInfo *) linitial(mergeclauses);
|
||||
if (firstclause->left_mergescansel < 0) /* not computed yet? */
|
||||
if (firstclause->left_mergescansel < 0) /* not computed yet? */
|
||||
mergejoinscansel(root, (Node *) firstclause->clause,
|
||||
&firstclause->left_mergescansel,
|
||||
&firstclause->right_mergescansel);
|
||||
@ -1159,7 +1159,7 @@ cost_hashjoin(HashPath *path, Query *root)
|
||||
/* not cached yet */
|
||||
thisbucketsize =
|
||||
estimate_hash_bucketsize(root,
|
||||
get_rightop(restrictinfo->clause),
|
||||
get_rightop(restrictinfo->clause),
|
||||
virtualbuckets);
|
||||
restrictinfo->right_bucketsize = thisbucketsize;
|
||||
}
|
||||
@ -1175,7 +1175,7 @@ cost_hashjoin(HashPath *path, Query *root)
|
||||
/* not cached yet */
|
||||
thisbucketsize =
|
||||
estimate_hash_bucketsize(root,
|
||||
get_leftop(restrictinfo->clause),
|
||||
get_leftop(restrictinfo->clause),
|
||||
virtualbuckets);
|
||||
restrictinfo->left_bucketsize = thisbucketsize;
|
||||
}
|
||||
@ -1617,11 +1617,12 @@ join_in_selectivity(JoinPath *path, Query *root)
|
||||
return 1.0;
|
||||
|
||||
/*
|
||||
* Return 1.0 if the inner side is already known unique. The case where
|
||||
* the inner path is already a UniquePath probably cannot happen in
|
||||
* current usage, but check it anyway for completeness. The interesting
|
||||
* case is where we've determined the inner relation itself is unique,
|
||||
* which we can check by looking at the rows estimate for its UniquePath.
|
||||
* Return 1.0 if the inner side is already known unique. The case
|
||||
* where the inner path is already a UniquePath probably cannot happen
|
||||
* in current usage, but check it anyway for completeness. The
|
||||
* interesting case is where we've determined the inner relation
|
||||
* itself is unique, which we can check by looking at the rows
|
||||
* estimate for its UniquePath.
|
||||
*/
|
||||
if (IsA(path->innerjoinpath, UniquePath))
|
||||
return 1.0;
|
||||
@ -1633,11 +1634,11 @@ join_in_selectivity(JoinPath *path, Query *root)
|
||||
return 1.0;
|
||||
|
||||
/*
|
||||
* Compute same result set_joinrel_size_estimates would compute
|
||||
* for JOIN_INNER. Note that we use the input rels' absolute size
|
||||
* estimates, not PATH_ROWS() which might be less; if we used PATH_ROWS()
|
||||
* we'd be double-counting the effects of any join clauses used in
|
||||
* input scans.
|
||||
* Compute same result set_joinrel_size_estimates would compute for
|
||||
* JOIN_INNER. Note that we use the input rels' absolute size
|
||||
* estimates, not PATH_ROWS() which might be less; if we used
|
||||
* PATH_ROWS() we'd be double-counting the effects of any join clauses
|
||||
* used in input scans.
|
||||
*/
|
||||
selec = clauselist_selectivity(root,
|
||||
path->joinrestrictinfo,
|
||||
|
@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.163 2004/08/29 04:12:33 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.164 2004/08/29 05:06:43 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -57,11 +57,11 @@ static List *group_clauses_by_indexkey_for_join(Query *root,
|
||||
Relids outer_relids,
|
||||
JoinType jointype, bool isouterjoin);
|
||||
static bool match_clause_to_indexcol(RelOptInfo *rel, IndexOptInfo *index,
|
||||
int indexcol, Oid opclass,
|
||||
RestrictInfo *rinfo);
|
||||
int indexcol, Oid opclass,
|
||||
RestrictInfo *rinfo);
|
||||
static bool match_join_clause_to_indexcol(RelOptInfo *rel, IndexOptInfo *index,
|
||||
int indexcol, Oid opclass,
|
||||
RestrictInfo *rinfo);
|
||||
int indexcol, Oid opclass,
|
||||
RestrictInfo *rinfo);
|
||||
static Oid indexable_operator(Expr *clause, Oid opclass,
|
||||
bool indexkey_on_left);
|
||||
static bool pred_test(List *predicate_list, List *restrictinfo_list);
|
||||
@ -137,8 +137,8 @@ create_index_paths(Query *root, RelOptInfo *rel)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* 1. Match the index against non-OR restriction clauses.
|
||||
* (OR clauses will be considered later by orindxpath.c.)
|
||||
* 1. Match the index against non-OR restriction clauses. (OR
|
||||
* clauses will be considered later by orindxpath.c.)
|
||||
*/
|
||||
restrictclauses = group_clauses_by_indexkey(rel, index);
|
||||
|
||||
@ -312,12 +312,12 @@ group_clauses_by_indexkey_for_join(Query *root,
|
||||
ListCell *l;
|
||||
|
||||
/*
|
||||
* We can always use plain restriction clauses for the rel. We scan
|
||||
* these first because we want them first in the clausegroup list
|
||||
* for the convenience of remove_redundant_join_clauses, which can
|
||||
* never remove non-join clauses and hence won't be able to get rid
|
||||
* of a non-join clause if it appears after a join clause it is
|
||||
* redundant with.
|
||||
* We can always use plain restriction clauses for the rel. We
|
||||
* scan these first because we want them first in the clausegroup
|
||||
* list for the convenience of remove_redundant_join_clauses,
|
||||
* which can never remove non-join clauses and hence won't be able
|
||||
* to get rid of a non-join clause if it appears after a join
|
||||
* clause it is redundant with.
|
||||
*/
|
||||
foreach(l, rel->baserestrictinfo)
|
||||
{
|
||||
@ -374,8 +374,8 @@ group_clauses_by_indexkey_for_join(Query *root,
|
||||
}
|
||||
|
||||
/*
|
||||
* If we found clauses in more than one list, we may now have clauses
|
||||
* that are known redundant. Get rid of 'em.
|
||||
* If we found clauses in more than one list, we may now have
|
||||
* clauses that are known redundant. Get rid of 'em.
|
||||
*/
|
||||
if (numsources > 1)
|
||||
{
|
||||
@ -416,7 +416,7 @@ group_clauses_by_indexkey_for_join(Query *root,
|
||||
* top-level restriction clauses of the relation. Furthermore, we demand
|
||||
* that at least one such use be made, otherwise we fail and return NIL.
|
||||
* (Any path we made without such a use would be redundant with non-OR
|
||||
* indexscans. Compare also group_clauses_by_indexkey_for_join.)
|
||||
* indexscans. Compare also group_clauses_by_indexkey_for_join.)
|
||||
*
|
||||
* XXX When we generate an indexqual list that uses both the OR subclause
|
||||
* and top-level restriction clauses, we end up with a slightly inefficient
|
||||
@ -473,8 +473,8 @@ group_clauses_by_indexkey_for_or(RelOptInfo *rel,
|
||||
* If we found no clauses for this indexkey in the OR subclause
|
||||
* itself, try looking in the rel's top-level restriction list.
|
||||
*
|
||||
* XXX should we always search the top-level list? Slower but
|
||||
* could sometimes yield a better plan.
|
||||
* XXX should we always search the top-level list? Slower but could
|
||||
* sometimes yield a better plan.
|
||||
*/
|
||||
if (clausegroup == NIL)
|
||||
{
|
||||
@ -910,7 +910,7 @@ pred_test_recurse_pred(Expr *predicate, Node *clause)
|
||||
*
|
||||
* The strategy numbers defined by btree indexes (see access/skey.h) are:
|
||||
* (1) < (2) <= (3) = (4) >= (5) >
|
||||
* and in addition we use (6) to represent <>. <> is not a btree-indexable
|
||||
* and in addition we use (6) to represent <>. <> is not a btree-indexable
|
||||
* operator, but we assume here that if the equality operator of a btree
|
||||
* opclass has a negator operator, the negator behaves as <> for the opclass.
|
||||
*
|
||||
@ -943,14 +943,14 @@ static const StrategyNumber
|
||||
/*
|
||||
* The target operator:
|
||||
*
|
||||
* LT LE EQ GE GT NE
|
||||
* LT LE EQ GE GT NE
|
||||
*/
|
||||
{BTGE, BTGE, 0, 0, 0, BTGE}, /* LT */
|
||||
{BTGT, BTGE, 0, 0, 0, BTGT}, /* LE */
|
||||
{BTGE, BTGE, 0, 0, 0, BTGE}, /* LT */
|
||||
{BTGT, BTGE, 0, 0, 0, BTGT}, /* LE */
|
||||
{BTGT, BTGE, BTEQ, BTLE, BTLT, BTNE}, /* EQ */
|
||||
{ 0, 0, 0, BTLE, BTLT, BTLT}, /* GE */
|
||||
{ 0, 0, 0, BTLE, BTLE, BTLE}, /* GT */
|
||||
{ 0, 0, 0, 0, 0, BTEQ} /* NE */
|
||||
{0, 0, 0, BTLE, BTLT, BTLT}, /* GE */
|
||||
{0, 0, 0, BTLE, BTLE, BTLE}, /* GT */
|
||||
{0, 0, 0, 0, 0, BTEQ} /* NE */
|
||||
};
|
||||
|
||||
|
||||
@ -963,21 +963,21 @@ static const StrategyNumber
|
||||
* implies another:
|
||||
*
|
||||
* A simple and general way is to see if they are equal(); this works for any
|
||||
* kind of expression. (Actually, there is an implied assumption that the
|
||||
* kind of expression. (Actually, there is an implied assumption that the
|
||||
* functions in the expression are immutable, ie dependent only on their input
|
||||
* arguments --- but this was checked for the predicate by CheckPredicate().)
|
||||
*
|
||||
* When the predicate is of the form "foo IS NOT NULL", we can conclude that
|
||||
* the predicate is implied if the clause is a strict operator or function
|
||||
* that has "foo" as an input. In this case the clause must yield NULL when
|
||||
* that has "foo" as an input. In this case the clause must yield NULL when
|
||||
* "foo" is NULL, which we can take as equivalent to FALSE because we know
|
||||
* we are within an AND/OR subtree of a WHERE clause. (Again, "foo" is
|
||||
* already known immutable, so the clause will certainly always fail.)
|
||||
*
|
||||
* Our other way works only for binary boolean opclauses of the form
|
||||
* "foo op constant", where "foo" is the same in both clauses. The operators
|
||||
* "foo op constant", where "foo" is the same in both clauses. The operators
|
||||
* and constants can be different but the operators must be in the same btree
|
||||
* operator class. We use the above operator implication table to be able to
|
||||
* operator class. We use the above operator implication table to be able to
|
||||
* derive implications between nonidentical clauses. (Note: "foo" is known
|
||||
* immutable, and constants are surely immutable, but we have to check that
|
||||
* the operators are too. As of 8.0 it's possible for opclasses to contain
|
||||
@ -1028,7 +1028,7 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
|
||||
if (predicate && IsA(predicate, NullTest) &&
|
||||
((NullTest *) predicate)->nulltesttype == IS_NOT_NULL)
|
||||
{
|
||||
Expr *nonnullarg = ((NullTest *) predicate)->arg;
|
||||
Expr *nonnullarg = ((NullTest *) predicate)->arg;
|
||||
|
||||
if (is_opclause(clause) &&
|
||||
list_member(((OpExpr *) clause)->args, nonnullarg) &&
|
||||
@ -1044,8 +1044,8 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
|
||||
/*
|
||||
* Can't do anything more unless they are both binary opclauses with a
|
||||
* Const on one side, and identical subexpressions on the other sides.
|
||||
* Note we don't have to think about binary relabeling of the Const node,
|
||||
* since that would have been folded right into the Const.
|
||||
* Note we don't have to think about binary relabeling of the Const
|
||||
* node, since that would have been folded right into the Const.
|
||||
*
|
||||
* If either Const is null, we also fail right away; this assumes that
|
||||
* the test operator will always be strict.
|
||||
@ -1097,9 +1097,9 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Check for matching subexpressions on the non-Const sides. We used to
|
||||
* only allow a simple Var, but it's about as easy to allow any
|
||||
* expression. Remember we already know that the pred expression does
|
||||
* Check for matching subexpressions on the non-Const sides. We used
|
||||
* to only allow a simple Var, but it's about as easy to allow any
|
||||
* expression. Remember we already know that the pred expression does
|
||||
* not contain any non-immutable functions, so identical expressions
|
||||
* should yield identical results.
|
||||
*/
|
||||
@ -1107,9 +1107,8 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Okay, get the operators in the two clauses we're comparing.
|
||||
* Commute them if needed so that we can assume the variables are
|
||||
* on the left.
|
||||
* Okay, get the operators in the two clauses we're comparing. Commute
|
||||
* them if needed so that we can assume the variables are on the left.
|
||||
*/
|
||||
pred_op = ((OpExpr *) predicate)->opno;
|
||||
if (!pred_var_on_left)
|
||||
@ -1132,16 +1131,16 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
|
||||
*
|
||||
* We must find a btree opclass that contains both operators, else the
|
||||
* implication can't be determined. Also, the pred_op has to be of
|
||||
* default subtype (implying left and right input datatypes are the same);
|
||||
* otherwise it's unsafe to put the pred_const on the left side of the
|
||||
* test. Also, the opclass must contain a suitable test operator
|
||||
* matching the clause_const's type (which we take to mean that it has
|
||||
* the same subtype as the original clause_operator).
|
||||
* default subtype (implying left and right input datatypes are the
|
||||
* same); otherwise it's unsafe to put the pred_const on the left side
|
||||
* of the test. Also, the opclass must contain a suitable test
|
||||
* operator matching the clause_const's type (which we take to mean
|
||||
* that it has the same subtype as the original clause_operator).
|
||||
*
|
||||
* If there are multiple matching opclasses, assume we can use any one to
|
||||
* determine the logical relationship of the two operators and the correct
|
||||
* corresponding test operator. This should work for any logically
|
||||
* consistent opclasses.
|
||||
* determine the logical relationship of the two operators and the
|
||||
* correct corresponding test operator. This should work for any
|
||||
* logically consistent opclasses.
|
||||
*/
|
||||
catlist = SearchSysCacheList(AMOPOPID, 1,
|
||||
ObjectIdGetDatum(pred_op),
|
||||
@ -1160,7 +1159,7 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
|
||||
pred_op_negated = true;
|
||||
ReleaseSysCacheList(catlist);
|
||||
catlist = SearchSysCacheList(AMOPOPID, 1,
|
||||
ObjectIdGetDatum(pred_op_negator),
|
||||
ObjectIdGetDatum(pred_op_negator),
|
||||
0, 0, 0);
|
||||
}
|
||||
}
|
||||
@ -1197,8 +1196,8 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
|
||||
}
|
||||
|
||||
/*
|
||||
* From the same opclass, find a strategy number for the clause_op,
|
||||
* if possible
|
||||
* From the same opclass, find a strategy number for the
|
||||
* clause_op, if possible
|
||||
*/
|
||||
clause_tuple = SearchSysCache(AMOPOPID,
|
||||
ObjectIdGetDatum(clause_op),
|
||||
@ -1217,7 +1216,7 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
|
||||
else if (OidIsValid(clause_op_negator))
|
||||
{
|
||||
clause_tuple = SearchSysCache(AMOPOPID,
|
||||
ObjectIdGetDatum(clause_op_negator),
|
||||
ObjectIdGetDatum(clause_op_negator),
|
||||
ObjectIdGetDatum(opclass_id),
|
||||
0, 0);
|
||||
if (HeapTupleIsValid(clause_tuple))
|
||||
@ -1272,8 +1271,8 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
|
||||
/*
|
||||
* Last check: test_op must be immutable.
|
||||
*
|
||||
* Note that we require only the test_op to be immutable, not
|
||||
* the original clause_op. (pred_op must be immutable, else it
|
||||
* Note that we require only the test_op to be immutable, not the
|
||||
* original clause_op. (pred_op must be immutable, else it
|
||||
* would not be allowed in an index predicate.) Essentially
|
||||
* we are assuming that the opclass is consistent even if it
|
||||
* contains operators that are merely stable.
|
||||
@ -1314,7 +1313,7 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
|
||||
|
||||
/* And execute it. */
|
||||
test_result = ExecEvalExprSwitchContext(test_exprstate,
|
||||
GetPerTupleExprContext(estate),
|
||||
GetPerTupleExprContext(estate),
|
||||
&isNull, NULL);
|
||||
|
||||
/* Get back to outer memory context */
|
||||
@ -1667,9 +1666,7 @@ flatten_clausegroups_list(List *clausegroups)
|
||||
ListCell *l;
|
||||
|
||||
foreach(l, clausegroups)
|
||||
{
|
||||
allclauses = list_concat(allclauses, list_copy((List *) lfirst(l)));
|
||||
}
|
||||
return allclauses;
|
||||
}
|
||||
|
||||
@ -1692,7 +1689,7 @@ make_expr_from_indexclauses(List *indexclauses)
|
||||
|
||||
foreach(orlist, indexclauses)
|
||||
{
|
||||
List *andlist = (List *) lfirst(orlist);
|
||||
List *andlist = (List *) lfirst(orlist);
|
||||
|
||||
/* Strip RestrictInfos */
|
||||
andlist = get_actual_clauses(andlist);
|
||||
@ -1994,7 +1991,7 @@ match_special_index_operator(Expr *clause, Oid opclass,
|
||||
* (The latter is not depended on by any part of the planner, so far as I can
|
||||
* tell; but some parts of the executor do assume that the indxqual list
|
||||
* ultimately delivered to the executor is so ordered. One such place is
|
||||
* _bt_preprocess_keys() in the btree support. Perhaps that ought to be fixed
|
||||
* _bt_preprocess_keys() in the btree support. Perhaps that ought to be fixed
|
||||
* someday --- tgl 7/00)
|
||||
*/
|
||||
List *
|
||||
@ -2019,7 +2016,7 @@ expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups)
|
||||
|
||||
resultquals = list_concat(resultquals,
|
||||
expand_indexqual_condition(rinfo,
|
||||
curClass));
|
||||
curClass));
|
||||
}
|
||||
|
||||
clausegroup_item = lnext(clausegroup_item);
|
||||
@ -2040,6 +2037,7 @@ static List *
|
||||
expand_indexqual_condition(RestrictInfo *rinfo, Oid opclass)
|
||||
{
|
||||
Expr *clause = rinfo->clause;
|
||||
|
||||
/* we know these will succeed */
|
||||
Node *leftop = get_leftop(clause);
|
||||
Node *rightop = get_rightop(clause);
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinpath.c,v 1.89 2004/08/29 04:12:33 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinpath.c,v 1.90 2004/08/29 05:06:43 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -254,7 +254,7 @@ sort_inner_and_outer(Query *root,
|
||||
|
||||
/* Forget it if can't use all the clauses in right/full join */
|
||||
if (useallclauses &&
|
||||
list_length(cur_mergeclauses) != list_length(mergeclause_list))
|
||||
list_length(cur_mergeclauses) != list_length(mergeclause_list))
|
||||
continue;
|
||||
|
||||
/*
|
||||
@ -492,8 +492,8 @@ match_unsorted_outer(Query *root,
|
||||
/*
|
||||
* Done with this outer path if no chance for a mergejoin.
|
||||
*
|
||||
* Special corner case: for "x FULL JOIN y ON true", there will be
|
||||
* no join clauses at all. Ordinarily we'd generate a clauseless
|
||||
* Special corner case: for "x FULL JOIN y ON true", there will be no
|
||||
* join clauses at all. Ordinarily we'd generate a clauseless
|
||||
* nestloop path, but since mergejoin is our only join type that
|
||||
* supports FULL JOIN, it's necessary to generate a clauseless
|
||||
* mergejoin path instead.
|
||||
@ -506,7 +506,7 @@ match_unsorted_outer(Query *root,
|
||||
if (mergeclauses == NIL)
|
||||
{
|
||||
if (jointype == JOIN_FULL && restrictlist == NIL)
|
||||
/* okay to try for mergejoin */ ;
|
||||
/* okay to try for mergejoin */ ;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.70 2004/08/29 04:12:33 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.71 2004/08/29 05:06:43 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -70,7 +70,8 @@ make_rels_by_joins(Query *root, int level, List **joinrels)
|
||||
other_rels = lnext(r); /* only consider remaining initial
|
||||
* rels */
|
||||
else
|
||||
other_rels = list_head(joinrels[1]); /* consider all initial rels */
|
||||
other_rels = list_head(joinrels[1]); /* consider all initial
|
||||
* rels */
|
||||
|
||||
if (old_rel->joininfo != NIL)
|
||||
{
|
||||
@ -84,12 +85,14 @@ make_rels_by_joins(Query *root, int level, List **joinrels)
|
||||
new_rels = make_rels_by_clause_joins(root,
|
||||
old_rel,
|
||||
other_rels);
|
||||
|
||||
/*
|
||||
* An exception occurs when there is a clauseless join inside an
|
||||
* IN (sub-SELECT) construct. Here, the members of the subselect
|
||||
* all have join clauses (against the stuff outside the IN), but
|
||||
* they *must* be joined to each other before we can make use of
|
||||
* those join clauses. So do the clauseless join bit.
|
||||
* An exception occurs when there is a clauseless join inside
|
||||
* an IN (sub-SELECT) construct. Here, the members of the
|
||||
* subselect all have join clauses (against the stuff outside
|
||||
* the IN), but they *must* be joined to each other before we
|
||||
* can make use of those join clauses. So do the clauseless
|
||||
* join bit.
|
||||
*
|
||||
* See also the last-ditch case below.
|
||||
*/
|
||||
@ -223,8 +226,8 @@ make_rels_by_joins(Query *root, int level, List **joinrels)
|
||||
other_rels = lnext(r); /* only consider remaining initial
|
||||
* rels */
|
||||
else
|
||||
other_rels = list_head(joinrels[1]); /* consider all initial
|
||||
* rels */
|
||||
other_rels = list_head(joinrels[1]); /* consider all initial
|
||||
* rels */
|
||||
|
||||
new_rels = make_rels_by_clauseless_joins(root,
|
||||
old_rel,
|
||||
@ -241,11 +244,11 @@ make_rels_by_joins(Query *root, int level, List **joinrels)
|
||||
|
||||
/*----------
|
||||
* When IN clauses are involved, there may be no legal way to make
|
||||
* an N-way join for some values of N. For example consider
|
||||
* an N-way join for some values of N. For example consider
|
||||
*
|
||||
* SELECT ... FROM t1 WHERE
|
||||
* x IN (SELECT ... FROM t2,t3 WHERE ...) AND
|
||||
* y IN (SELECT ... FROM t4,t5 WHERE ...)
|
||||
* x IN (SELECT ... FROM t2,t3 WHERE ...) AND
|
||||
* y IN (SELECT ... FROM t4,t5 WHERE ...)
|
||||
*
|
||||
* We will flatten this query to a 5-way join problem, but there are
|
||||
* no 4-way joins that make_join_rel() will consider legal. We have
|
||||
@ -486,8 +489,8 @@ make_join_rel(Query *root, RelOptInfo *rel1, RelOptInfo *rel2,
|
||||
|
||||
/*
|
||||
* This IN clause is not relevant unless its RHS overlaps the
|
||||
* proposed join. (Check this first as a fast path for dismissing
|
||||
* most irrelevant INs quickly.)
|
||||
* proposed join. (Check this first as a fast path for
|
||||
* dismissing most irrelevant INs quickly.)
|
||||
*/
|
||||
if (!bms_overlap(ininfo->righthand, joinrelids))
|
||||
continue;
|
||||
@ -516,8 +519,9 @@ make_join_rel(Query *root, RelOptInfo *rel1, RelOptInfo *rel2,
|
||||
* some other rel(s).
|
||||
*
|
||||
* If we already joined IN's RHS to any other rels in either
|
||||
* input path, then this join is not constrained (the necessary
|
||||
* work was done at the lower level where that join occurred).
|
||||
* input path, then this join is not constrained (the
|
||||
* necessary work was done at the lower level where that join
|
||||
* occurred).
|
||||
*/
|
||||
if (bms_is_subset(ininfo->righthand, rel1->relids) &&
|
||||
!bms_equal(ininfo->righthand, rel1->relids))
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/orindxpath.c,v 1.61 2004/08/29 04:12:33 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/orindxpath.c,v 1.62 2004/08/29 05:06:43 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
|
||||
static IndexPath *best_or_subclause_indexes(Query *root, RelOptInfo *rel,
|
||||
List *subclauses);
|
||||
List *subclauses);
|
||||
static bool best_or_subclause_index(Query *root,
|
||||
RelOptInfo *rel,
|
||||
Expr *subclause,
|
||||
@ -55,7 +55,7 @@ static bool best_or_subclause_index(Query *root,
|
||||
*
|
||||
* The added quals are partially redundant with the original OR, and therefore
|
||||
* will cause the size of the joinrel to be underestimated when it is finally
|
||||
* formed. (This would be true of a full transformation to CNF as well; the
|
||||
* formed. (This would be true of a full transformation to CNF as well; the
|
||||
* fault is not really in the transformation, but in clauselist_selectivity's
|
||||
* inability to recognize redundant conditions.) To minimize the collateral
|
||||
* damage, we want to minimize the number of quals added. Therefore we do
|
||||
@ -70,7 +70,7 @@ static bool best_or_subclause_index(Query *root,
|
||||
* it is finally formed. This is a MAJOR HACK: it depends on the fact
|
||||
* that clause selectivities are cached and on the fact that the same
|
||||
* RestrictInfo node will appear in every joininfo list that might be used
|
||||
* when the joinrel is formed. And it probably isn't right in cases where
|
||||
* when the joinrel is formed. And it probably isn't right in cases where
|
||||
* the size estimation is nonlinear (i.e., outer and IN joins). But it
|
||||
* beats not doing anything.
|
||||
*
|
||||
@ -103,9 +103,9 @@ create_or_index_quals(Query *root, RelOptInfo *rel)
|
||||
ListCell *i;
|
||||
|
||||
/*
|
||||
* We use the best_or_subclause_indexes() machinery to locate the
|
||||
* best combination of restriction subclauses. Note we must ignore
|
||||
* any joinclauses that are not marked valid_everywhere, because they
|
||||
* We use the best_or_subclause_indexes() machinery to locate the best
|
||||
* combination of restriction subclauses. Note we must ignore any
|
||||
* joinclauses that are not marked valid_everywhere, because they
|
||||
* cannot be pushed down due to outer-join rules.
|
||||
*/
|
||||
foreach(i, rel->joininfo)
|
||||
@ -124,12 +124,12 @@ create_or_index_quals(Query *root, RelOptInfo *rel)
|
||||
|
||||
pathnode = best_or_subclause_indexes(root,
|
||||
rel,
|
||||
((BoolExpr *) rinfo->orclause)->args);
|
||||
((BoolExpr *) rinfo->orclause)->args);
|
||||
|
||||
if (pathnode)
|
||||
{
|
||||
if (bestpath == NULL ||
|
||||
pathnode->path.total_cost < bestpath->path.total_cost)
|
||||
pathnode->path.total_cost < bestpath->path.total_cost)
|
||||
{
|
||||
bestpath = pathnode;
|
||||
bestrinfo = rinfo;
|
||||
@ -144,8 +144,8 @@ create_or_index_quals(Query *root, RelOptInfo *rel)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Convert the indexclauses structure to a RestrictInfo tree,
|
||||
* and add it to the rel's restriction list.
|
||||
* Convert the indexclauses structure to a RestrictInfo tree, and add
|
||||
* it to the rel's restriction list.
|
||||
*/
|
||||
newrinfos = make_restrictinfo_from_indexclauses(bestpath->indexclauses,
|
||||
true, true);
|
||||
@ -157,9 +157,9 @@ create_or_index_quals(Query *root, RelOptInfo *rel)
|
||||
* Adjust the original OR clause's cached selectivity to compensate
|
||||
* for the selectivity of the added (but redundant) lower-level qual.
|
||||
* This should result in the join rel getting approximately the same
|
||||
* rows estimate as it would have gotten without all these shenanigans.
|
||||
* (XXX major hack alert ... this depends on the assumption that the
|
||||
* selectivity will stay cached ...)
|
||||
* rows estimate as it would have gotten without all these
|
||||
* shenanigans. (XXX major hack alert ... this depends on the
|
||||
* assumption that the selectivity will stay cached ...)
|
||||
*/
|
||||
or_selec = clause_selectivity(root, (Node *) or_rinfo,
|
||||
0, JOIN_INNER);
|
||||
@ -193,8 +193,8 @@ create_or_index_paths(Query *root, RelOptInfo *rel)
|
||||
ListCell *l;
|
||||
|
||||
/*
|
||||
* Check each restriction clause to see if it is an OR clause, and if so,
|
||||
* try to make a path using it.
|
||||
* Check each restriction clause to see if it is an OR clause, and if
|
||||
* so, try to make a path using it.
|
||||
*/
|
||||
foreach(l, rel->baserestrictinfo)
|
||||
{
|
||||
@ -206,7 +206,7 @@ create_or_index_paths(Query *root, RelOptInfo *rel)
|
||||
|
||||
pathnode = best_or_subclause_indexes(root,
|
||||
rel,
|
||||
((BoolExpr *) rinfo->orclause)->args);
|
||||
((BoolExpr *) rinfo->orclause)->args);
|
||||
|
||||
if (pathnode)
|
||||
add_path(rel, (Path *) pathnode);
|
||||
@ -264,20 +264,21 @@ best_or_subclause_indexes(Query *root,
|
||||
if (!best_or_subclause_index(root, rel, subclause,
|
||||
&best_indexinfo,
|
||||
&best_indexclauses, &best_indexquals,
|
||||
&best_startup_cost, &best_total_cost))
|
||||
&best_startup_cost, &best_total_cost))
|
||||
return NULL; /* failed to match this subclause */
|
||||
|
||||
infos = lappend(infos, best_indexinfo);
|
||||
clauses = lappend(clauses, best_indexclauses);
|
||||
quals = lappend(quals, best_indexquals);
|
||||
|
||||
/*
|
||||
* Path startup_cost is the startup cost for the first index scan only;
|
||||
* startup costs for later scans will be paid later on, so they just
|
||||
* get reflected in total_cost.
|
||||
* Path startup_cost is the startup cost for the first index scan
|
||||
* only; startup costs for later scans will be paid later on, so
|
||||
* they just get reflected in total_cost.
|
||||
*
|
||||
* Total cost is sum of the per-scan costs.
|
||||
*/
|
||||
if (slist == list_head(subclauses)) /* first scan? */
|
||||
if (slist == list_head(subclauses)) /* first scan? */
|
||||
path_startup_cost = best_startup_cost;
|
||||
path_total_cost += best_total_cost;
|
||||
}
|
||||
@ -292,8 +293,8 @@ best_or_subclause_indexes(Query *root,
|
||||
|
||||
/*
|
||||
* This is an IndexScan, but the overall result will consist of tuples
|
||||
* extracted in multiple passes (one for each subclause of the OR),
|
||||
* so the result cannot be claimed to have any particular ordering.
|
||||
* extracted in multiple passes (one for each subclause of the OR), so
|
||||
* the result cannot be claimed to have any particular ordering.
|
||||
*/
|
||||
pathnode->path.pathkeys = NIL;
|
||||
|
||||
@ -339,7 +340,7 @@ best_or_subclause_index(Query *root,
|
||||
RelOptInfo *rel,
|
||||
Expr *subclause,
|
||||
IndexOptInfo **retIndexInfo, /* return value */
|
||||
List **retIndexClauses, /* return value */
|
||||
List **retIndexClauses, /* return value */
|
||||
List **retIndexQuals, /* return value */
|
||||
Cost *retStartupCost, /* return value */
|
||||
Cost *retTotalCost) /* return value */
|
||||
|
@ -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.61 2004/08/29 04:12:33 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.62 2004/08/29 05:06:43 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -48,10 +48,11 @@ makePathKeyItem(Node *key, Oid sortop, bool checkType)
|
||||
|
||||
/*
|
||||
* Some callers pass expressions that are not necessarily of the same
|
||||
* type as the sort operator expects as input (for example when dealing
|
||||
* with an index that uses binary-compatible operators). We must relabel
|
||||
* these with the correct type so that the key expressions will be seen
|
||||
* as equal() to expressions that have been correctly labeled.
|
||||
* type as the sort operator expects as input (for example when
|
||||
* dealing with an index that uses binary-compatible operators). We
|
||||
* must relabel these with the correct type so that the key
|
||||
* expressions will be seen as equal() to expressions that have been
|
||||
* correctly labeled.
|
||||
*/
|
||||
if (checkType)
|
||||
{
|
||||
|
Reference in New Issue
Block a user