diff options
| author | Tom Lane <tgl@sss.pgh.pa.us> | 2003-01-15 19:35:48 +0000 |
|---|---|---|
| committer | Tom Lane <tgl@sss.pgh.pa.us> | 2003-01-15 19:35:48 +0000 |
| commit | de97072e3c88e104a55b0d5c67477f1b0097c003 (patch) | |
| tree | b4b0a243ce6d38ae6aa5cde1e3ef140e229a1615 /src/backend/optimizer/path/costsize.c | |
| parent | 0eed62f34d95d5c7ae7e0931cfe632f4c8373ec0 (diff) | |
| download | postgresql-de97072e3c88e104a55b0d5c67477f1b0097c003.tar.gz | |
Allow merge and hash joins to occur on arbitrary expressions (anything not
containing a volatile function), rather than only on 'Var = Var' clauses
as before. This makes it practical to do flatten_join_alias_vars at the
start of planning, which in turn eliminates a bunch of klugery inside the
planner to deal with alias vars. As a free side effect, we now detect
implied equality of non-Var expressions; for example in
SELECT ... WHERE a.x = b.y and b.y = 42
we will deduce a.x = 42 and use that as a restriction qual on a. Also,
we can remove the restriction introduced 12/5/02 to prevent pullup of
subqueries whose targetlists contain sublinks.
Still TODO: make statistical estimation routines in selfuncs.c and costsize.c
smarter about expressions that are more complex than plain Vars. The need
for this is considerably greater now that we have to be able to estimate
the suitability of merge and hash join techniques on such expressions.
Diffstat (limited to 'src/backend/optimizer/path/costsize.c')
| -rw-r--r-- | src/backend/optimizer/path/costsize.c | 25 |
1 files changed, 10 insertions, 15 deletions
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index 1d736b34b9..efd80dff1e 100644 --- a/src/backend/optimizer/path/costsize.c +++ b/src/backend/optimizer/path/costsize.c @@ -42,7 +42,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.99 2003/01/12 22:35:29 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.100 2003/01/15 19:35:39 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -752,7 +752,6 @@ cost_mergejoin(Path *path, Query *root, Cost cpu_per_tuple; QualCost restrict_qual_cost; RestrictInfo *firstclause; - Var *leftvar; double outer_rows, inner_rows; double ntuples; @@ -779,9 +778,7 @@ cost_mergejoin(Path *path, Query *root, &firstclause->left_mergescansel, &firstclause->right_mergescansel); - leftvar = get_leftop(firstclause->clause); - Assert(IsA(leftvar, Var)); - if (VARISRELMEMBER(leftvar->varno, outer_path->parent)) + if (is_subseti(firstclause->left_relids, outer_path->parent->relids)) { /* left side of clause is outer */ outerscansel = firstclause->left_mergescansel; @@ -935,14 +932,9 @@ cost_hashjoin(Path *path, Query *root, foreach(hcl, hashclauses) { RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(hcl); - Var *left, - *right; Selectivity thisbucketsize; Assert(IsA(restrictinfo, RestrictInfo)); - /* these must be OK, since check_hashjoinable accepted the clause */ - left = get_leftop(restrictinfo->clause); - right = get_rightop(restrictinfo->clause); /* * First we have to figure out which side of the hashjoin clause is the @@ -952,27 +944,30 @@ cost_hashjoin(Path *path, Query *root, * a large query, we cache the bucketsize estimate in the RestrictInfo * node to avoid repeated lookups of statistics. */ - if (VARISRELMEMBER(right->varno, inner_path->parent)) + if (is_subseti(restrictinfo->right_relids, inner_path->parent->relids)) { /* righthand side is inner */ thisbucketsize = restrictinfo->right_bucketsize; if (thisbucketsize < 0) { /* not cached yet */ - thisbucketsize = estimate_hash_bucketsize(root, right, + thisbucketsize = estimate_hash_bucketsize(root, + (Var *) get_rightop(restrictinfo->clause), virtualbuckets); restrictinfo->right_bucketsize = thisbucketsize; } } else { - Assert(VARISRELMEMBER(left->varno, inner_path->parent)); + Assert(is_subseti(restrictinfo->left_relids, + inner_path->parent->relids)); /* lefthand side is inner */ thisbucketsize = restrictinfo->left_bucketsize; if (thisbucketsize < 0) { /* not cached yet */ - thisbucketsize = estimate_hash_bucketsize(root, left, + thisbucketsize = estimate_hash_bucketsize(root, + (Var *) get_leftop(restrictinfo->clause), virtualbuckets); restrictinfo->left_bucketsize = thisbucketsize; } @@ -1088,7 +1083,7 @@ estimate_hash_bucketsize(Query *root, Var *var, int nbuckets) * Lookup info about var's relation and attribute; if none available, * return default estimate. */ - if (!IsA(var, Var)) + if (var == NULL || !IsA(var, Var)) return 0.1; relid = getrelid(var->varno, root->rtable); |
