diff options
Diffstat (limited to 'src/backend/optimizer/path/clausesel.c')
-rw-r--r-- | src/backend/optimizer/path/clausesel.c | 131 |
1 files changed, 77 insertions, 54 deletions
diff --git a/src/backend/optimizer/path/clausesel.c b/src/backend/optimizer/path/clausesel.c index 985155edf92..d430059a1e0 100644 --- a/src/backend/optimizer/path/clausesel.c +++ b/src/backend/optimizer/path/clausesel.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/clausesel.c,v 1.33 2000/03/23 23:35:47 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/clausesel.c,v 1.34 2000/04/12 17:15:19 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -28,17 +28,18 @@ * Data structure for accumulating info about possible range-query * clause pairs in clauselist_selectivity. */ -typedef struct RangeQueryClause { - struct RangeQueryClause *next; /* next in linked list */ +typedef struct RangeQueryClause +{ + struct RangeQueryClause *next; /* next in linked list */ Node *var; /* The common variable of the clauses */ bool have_lobound; /* found a low-bound clause yet? */ bool have_hibound; /* found a high-bound clause yet? */ - Selectivity lobound; /* Selectivity of a var > something clause */ - Selectivity hibound; /* Selectivity of a var < something clause */ + Selectivity lobound; /* Selectivity of a var > something clause */ + Selectivity hibound; /* Selectivity of a var < something clause */ } RangeQueryClause; static void addRangeClause(RangeQueryClause **rqlist, Node *clause, - int flag, bool isLTsel, Selectivity s2); + int flag, bool isLTsel, Selectivity s2); /**************************************************************************** @@ -59,7 +60,7 @@ restrictlist_selectivity(Query *root, int varRelid) { List *clauselist = get_actual_clauses(restrictinfo_list); - Selectivity result; + Selectivity result; result = clauselist_selectivity(root, clauselist, varRelid); freeList(clauselist); @@ -75,7 +76,7 @@ restrictlist_selectivity(Query *root, * See clause_selectivity() for the meaning of the varRelid parameter. * * Our basic approach is to take the product of the selectivities of the - * subclauses. However, that's only right if the subclauses have independent + * subclauses. However, that's only right if the subclauses have independent * probabilities, and in reality they are often NOT independent. So, * we want to be smarter where we can. @@ -92,7 +93,7 @@ restrictlist_selectivity(Query *root, * see that hisel is the fraction of the range below the high bound, while * losel is the fraction above the low bound; so hisel can be interpreted * directly as a 0..1 value but we need to convert losel to 1-losel before - * interpreting it as a value. Then the available range is 1-losel to hisel.) + * interpreting it as a value. Then the available range is 1-losel to hisel.) * If the calculation yields zero or negative, however, we chicken out and * use the default interpretation; that probably means that one or both * selectivities is a default estimate rather than an actual range value. @@ -104,9 +105,9 @@ clauselist_selectivity(Query *root, List *clauses, int varRelid) { - Selectivity s1 = 1.0; - RangeQueryClause *rqlist = NULL; - List *clist; + Selectivity s1 = 1.0; + RangeQueryClause *rqlist = NULL; + List *clist; /* * Initial scan over clauses. Anything that doesn't look like a @@ -116,13 +117,13 @@ clauselist_selectivity(Query *root, foreach(clist, clauses) { Node *clause = (Node *) lfirst(clist); - Selectivity s2; + Selectivity s2; /* - * See if it looks like a restriction clause with a constant. - * (If it's not a constant we can't really trust the selectivity!) - * NB: for consistency of results, this fragment of code had - * better match what clause_selectivity() would do. + * See if it looks like a restriction clause with a constant. (If + * it's not a constant we can't really trust the selectivity!) NB: + * for consistency of results, this fragment of code had better + * match what clause_selectivity() would do. */ if (varRelid != 0 || NumRelids(clause) == 1) { @@ -147,11 +148,12 @@ clauselist_selectivity(Query *root, root->rtable), attno, constval, flag); + /* - * If we reach here, we have computed the same result - * that clause_selectivity would, so we can just use s2 - * if it's the wrong oprrest. But if it's the right - * oprrest, add the clause to rqlist for later processing. + * If we reach here, we have computed the same result that + * clause_selectivity would, so we can just use s2 if it's + * the wrong oprrest. But if it's the right oprrest, add + * the clause to rqlist for later processing. */ switch (oprrest) { @@ -166,7 +168,7 @@ clauselist_selectivity(Query *root, s1 = s1 * s2; break; } - continue; /* drop to loop bottom */ + continue; /* drop to loop bottom */ } } /* Not the right form, so treat it generically. */ @@ -179,12 +181,12 @@ clauselist_selectivity(Query *root, */ while (rqlist != NULL) { - RangeQueryClause *rqnext; + RangeQueryClause *rqnext; if (rqlist->have_lobound && rqlist->have_hibound) { /* Successfully matched a pair of range clauses */ - Selectivity s2 = rqlist->hibound + rqlist->lobound - 1.0; + Selectivity s2 = rqlist->hibound + rqlist->lobound - 1.0; /* * A zero or slightly negative s2 should be converted into a @@ -199,14 +201,20 @@ clauselist_selectivity(Query *root, { if (s2 < -0.01) { - /* No data available --- use a default estimate that + + /* + * No data available --- use a default estimate that * is small, but not real small. */ s2 = 0.01; } else { - /* It's just roundoff error; use a small positive value */ + + /* + * It's just roundoff error; use a small positive + * value + */ s2 = 1.0e-10; } } @@ -239,15 +247,15 @@ static void addRangeClause(RangeQueryClause **rqlist, Node *clause, int flag, bool isLTsel, Selectivity s2) { - RangeQueryClause *rqelem; - Node *var; - bool is_lobound; + RangeQueryClause *rqelem; + Node *var; + bool is_lobound; /* get_relattval sets flag&SEL_RIGHT if the var is on the LEFT. */ if (flag & SEL_RIGHT) { var = (Node *) get_leftop((Expr *) clause); - is_lobound = ! isLTsel; /* x < something is high bound */ + is_lobound = !isLTsel; /* x < something is high bound */ } else { @@ -257,23 +265,27 @@ addRangeClause(RangeQueryClause **rqlist, Node *clause, for (rqelem = *rqlist; rqelem; rqelem = rqelem->next) { - /* We use full equal() here because the "var" might be a function + + /* + * We use full equal() here because the "var" might be a function * of one or more attributes of the same relation... */ - if (! equal(var, rqelem->var)) + if (!equal(var, rqelem->var)) continue; /* Found the right group to put this clause in */ if (is_lobound) { - if (! rqelem->have_lobound) + if (!rqelem->have_lobound) { rqelem->have_lobound = true; rqelem->lobound = s2; } else { - /* We have found two similar clauses, such as - * x < y AND x < z. Keep only the more restrictive one. + + /* + * We have found two similar clauses, such as x < y AND x + * < z. Keep only the more restrictive one. */ if (rqelem->lobound > s2) rqelem->lobound = s2; @@ -281,15 +293,17 @@ addRangeClause(RangeQueryClause **rqlist, Node *clause, } else { - if (! rqelem->have_hibound) + if (!rqelem->have_hibound) { rqelem->have_hibound = true; rqelem->hibound = s2; } else { - /* We have found two similar clauses, such as - * x > y AND x > z. Keep only the more restrictive one. + + /* + * We have found two similar clauses, such as x > y AND x + * > z. Keep only the more restrictive one. */ if (rqelem->hibound > s2) rqelem->hibound = s2; @@ -331,7 +345,7 @@ addRangeClause(RangeQueryClause **rqlist, Node *clause, * nestloop join's inner relation --- varRelid should then be the ID of the * inner relation. * - * When varRelid is 0, all variables are treated as variables. This + * When varRelid is 0, all variables are treated as variables. This * is appropriate for ordinary join clauses and restriction clauses. */ Selectivity @@ -339,12 +353,13 @@ clause_selectivity(Query *root, Node *clause, int varRelid) { - Selectivity s1 = 1.0; /* default for any unhandled clause type */ + Selectivity s1 = 1.0; /* default for any unhandled clause type */ if (clause == NULL) return s1; if (IsA(clause, Var)) { + /* * we have a bool Var. This is exactly equivalent to the clause: * reln.attribute = 't' so we compute the selectivity as if that @@ -352,7 +367,7 @@ clause_selectivity(Query *root, * didn't want to have to do system cache look ups to find out all * of that info. */ - Index varno = ((Var *) clause)->varno; + Index varno = ((Var *) clause)->varno; if (varRelid == 0 || varRelid == (int) varno) s1 = restriction_selectivity(F_EQSEL, @@ -377,7 +392,7 @@ clause_selectivity(Query *root, { /* inverse of the selectivity of the underlying clause */ s1 = 1.0 - clause_selectivity(root, - (Node*) get_notclausearg((Expr*) clause), + (Node *) get_notclausearg((Expr *) clause), varRelid); } else if (and_clause(clause)) @@ -389,18 +404,21 @@ 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. - * XXX is this too conservative? + * to account for the probable overlap of selected tuple sets. XXX + * is this too conservative? */ - List *arg; + List *arg; + s1 = 0.0; foreach(arg, ((Expr *) clause)->args) { - Selectivity s2 = clause_selectivity(root, + Selectivity s2 = clause_selectivity(root, (Node *) lfirst(arg), varRelid); + s1 = s1 + s2 - s1 * s2; } } @@ -411,17 +429,20 @@ clause_selectivity(Query *root, if (varRelid != 0) { + /* - * If we are considering a nestloop join then all clauses - * are restriction clauses, since we are only interested in - * the one relation. + * If we are considering a nestloop join then all clauses are + * restriction clauses, since we are only interested in the + * one relation. */ is_join_clause = false; } else { + /* - * Otherwise, it's a join if there's more than one relation used. + * Otherwise, it's a join if there's more than one relation + * used. */ is_join_clause = (NumRelids(clause) > 1); } @@ -432,8 +453,8 @@ clause_selectivity(Query *root, RegProcedure oprjoin = get_oprjoin(opno); /* - * if the oprjoin procedure is missing for whatever reason, use a - * selectivity of 0.5 + * if the oprjoin procedure is missing for whatever reason, + * use a selectivity of 0.5 */ if (!oprjoin) s1 = (Selectivity) 0.5; @@ -460,8 +481,8 @@ clause_selectivity(Query *root, RegProcedure oprrest = get_oprrest(opno); /* - * if the oprrest procedure is missing for whatever reason, use a - * selectivity of 0.5 + * if the oprrest procedure is missing for whatever reason, + * use a selectivity of 0.5 */ if (!oprrest) s1 = (Selectivity) 0.5; @@ -484,6 +505,7 @@ clause_selectivity(Query *root, } else if (is_funcclause(clause)) { + /* * This is not an operator, so we guess at the selectivity. THIS * IS A HACK TO GET V4 OUT THE DOOR. FUNCS SHOULD BE ABLE TO HAVE @@ -493,6 +515,7 @@ clause_selectivity(Query *root, } else if (is_subplan(clause)) { + /* * Just for the moment! FIX ME! - vadim 02/04/98 */ |