5454 * Portions Copyright (c) 1994, Regents of the University of California
5555 *
5656 * IDENTIFICATION
57- * $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.203 2009/01/01 17: 23:43 momjian Exp $
57+ * $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.204 2009/02/06 23:43:23 tgl Exp $
5858 *
5959 *-------------------------------------------------------------------------
6060 */
@@ -120,7 +120,7 @@ static MergeScanSelCache *cached_scansel(PlannerInfo *root,
120120PathKey * pathkey );
121121static bool cost_qual_eval_walker (Node * node ,cost_qual_eval_context * context );
122122static double approx_tuple_count (PlannerInfo * root ,JoinPath * path ,
123- List * quals , SpecialJoinInfo * sjinfo );
123+ List * quals );
124124static void set_rel_width (PlannerInfo * root ,RelOptInfo * rel );
125125static double relation_byte_size (double tuples ,int width );
126126static double page_size (double tuples ,int width );
@@ -1507,11 +1507,9 @@ cost_mergejoin(MergePath *path, PlannerInfo *root, SpecialJoinInfo *sjinfo)
15071507
15081508/*
15091509 * Get approx # tuples passing the mergequals. We use approx_tuple_count
1510- * here for speed --- in most cases, any errors won't affect the result
1511- * much.
1510+ * here because we need an estimate done with JOIN_INNER semantics.
15121511 */
1513- mergejointuples = approx_tuple_count (root ,& path -> jpath ,
1514- mergeclauses ,sjinfo );
1512+ mergejointuples = approx_tuple_count (root ,& path -> jpath ,mergeclauses );
15151513
15161514/*
15171515 * When there are equal merge keys in the outer relation, the mergejoin
@@ -1539,16 +1537,10 @@ cost_mergejoin(MergePath *path, PlannerInfo *root, SpecialJoinInfo *sjinfo)
15391537 * when we should not.Can we do better without expensive selectivity
15401538 * computations?
15411539 *
1542- * For SEMI and ANTI joins, only one inner tuple need be rescanned for
1543- * each group of same-keyed outer tuples (assuming that all joinquals
1544- * are merge quals). This makes the effect small enough to ignore,
1545- * so we just set rescannedtuples = 0. Likewise, the whole issue is
1546- * moot if we are working from a unique-ified outer input.
1540+ * The whole issue is moot if we are working from a unique-ified outer
1541+ * input.
15471542 */
1548- if (sjinfo -> jointype == JOIN_SEMI ||
1549- sjinfo -> jointype == JOIN_ANTI )
1550- rescannedtuples = 0 ;
1551- else if (IsA (outer_path ,UniquePath ))
1543+ if (IsA (outer_path ,UniquePath ))
15521544rescannedtuples = 0 ;
15531545else
15541546{
@@ -1847,11 +1839,9 @@ cost_hashjoin(HashPath *path, PlannerInfo *root, SpecialJoinInfo *sjinfo)
18471839
18481840/*
18491841 * Get approx # tuples passing the hashquals. We use approx_tuple_count
1850- * here for speed --- in most cases, any errors won't affect the result
1851- * much.
1842+ * here because we need an estimate done with JOIN_INNER semantics.
18521843 */
1853- hashjointuples = approx_tuple_count (root ,& path -> jpath ,
1854- hashclauses ,sjinfo );
1844+ hashjointuples = approx_tuple_count (root ,& path -> jpath ,hashclauses );
18551845
18561846/* cost of source data */
18571847startup_cost += outer_path -> startup_cost ;
@@ -2324,6 +2314,11 @@ cost_qual_eval_walker(Node *node, cost_qual_eval_context *context)
23242314 * The quals can be either an implicitly-ANDed list of boolean expressions,
23252315 * or a list of RestrictInfo nodes (typically the latter).
23262316 *
2317+ * We intentionally compute the selectivity under JOIN_INNER rules, even
2318+ * if it's some type of outer join. This is appropriate because we are
2319+ * trying to figure out how many tuples pass the initial merge or hash
2320+ * join step.
2321+ *
23272322 * This is quick-and-dirty because we bypass clauselist_selectivity, and
23282323 * simply multiply the independent clause selectivities together. Now
23292324 * clauselist_selectivity often can't do any better than that anyhow, but
@@ -2336,31 +2331,40 @@ cost_qual_eval_walker(Node *node, cost_qual_eval_context *context)
23362331 * seems OK to live with the approximation.
23372332 */
23382333static double
2339- approx_tuple_count (PlannerInfo * root ,JoinPath * path ,
2340- List * quals ,SpecialJoinInfo * sjinfo )
2334+ approx_tuple_count (PlannerInfo * root ,JoinPath * path ,List * quals )
23412335{
23422336double tuples ;
23432337double outer_tuples = path -> outerjoinpath -> parent -> rows ;
23442338double inner_tuples = path -> innerjoinpath -> parent -> rows ;
2339+ SpecialJoinInfo sjinfo ;
23452340Selectivity selec = 1.0 ;
23462341ListCell * l ;
23472342
2343+ /*
2344+ * Make up a SpecialJoinInfo for JOIN_INNER semantics.
2345+ */
2346+ sjinfo .type = T_SpecialJoinInfo ;
2347+ sjinfo .min_lefthand = path -> outerjoinpath -> parent -> relids ;
2348+ sjinfo .min_righthand = path -> innerjoinpath -> parent -> relids ;
2349+ sjinfo .syn_lefthand = path -> outerjoinpath -> parent -> relids ;
2350+ sjinfo .syn_righthand = path -> innerjoinpath -> parent -> relids ;
2351+ sjinfo .jointype = JOIN_INNER ;
2352+ /* we don't bother trying to make the remaining fields valid */
2353+ sjinfo .lhs_strict = false;
2354+ sjinfo .delay_upper_joins = false;
2355+ sjinfo .join_quals = NIL ;
2356+
23482357/* Get the approximate selectivity */
23492358foreach (l ,quals )
23502359{
23512360Node * qual = (Node * )lfirst (l );
23522361
23532362/* Note that clause_selectivity will be able to cache its result */
2354- selec *=clause_selectivity (root ,qual ,0 ,sjinfo -> jointype , sjinfo );
2363+ selec *=clause_selectivity (root ,qual ,0 ,JOIN_INNER , & sjinfo );
23552364}
23562365
2357- /* Apply it correctly using the input relation sizes */
2358- if (sjinfo -> jointype == JOIN_SEMI )
2359- tuples = selec * outer_tuples ;
2360- else if (sjinfo -> jointype == JOIN_ANTI )
2361- tuples = (1.0 - selec )* outer_tuples ;
2362- else
2363- tuples = selec * outer_tuples * inner_tuples ;
2366+ /* Apply it to the input relation sizes */
2367+ tuples = selec * outer_tuples * inner_tuples ;
23642368
23652369return clamp_row_est (tuples );
23662370}