diff options
| author | Tom Lane <tgl@sss.pgh.pa.us> | 2008-08-14 18:48:00 +0000 |
|---|---|---|
| committer | Tom Lane <tgl@sss.pgh.pa.us> | 2008-08-14 18:48:00 +0000 |
| commit | e006a24ad152b3faec748afe8c1ff0829699b2e6 (patch) | |
| tree | d00e01d25270b4b04aac3c723b9e440a56d8a085 /src/backend/optimizer/plan/createplan.c | |
| parent | ef1c807c25b47960aa86cd185fb74371e88d0cbf (diff) | |
Implement SEMI and ANTI joins in the planner and executor. (Semijoins replace
the old JOIN_IN code, but antijoins are new functionality.) Teach the planner
to convert appropriate EXISTS and NOT EXISTS subqueries into semi and anti
joins respectively. Also, LEFT JOINs with suitable upper-level IS NULL
filters are recognized as being anti joins. Unify the InClauseInfo and
OuterJoinInfo infrastructure into "SpecialJoinInfo". With that change,
it becomes possible to associate a SpecialJoinInfo with every join attempt,
which permits some cleanup of join selectivity estimation. That needs to be
taken much further than this patch does, but the next step is to change the
API for oprjoin selectivity functions, which seems like material for a
separate patch. So for the moment the output size estimates for semi and
especially anti joins are quite bogus.
Diffstat (limited to 'src/backend/optimizer/plan/createplan.c')
| -rw-r--r-- | src/backend/optimizer/plan/createplan.c | 30 |
1 files changed, 5 insertions, 25 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 0c200e05795..ea85fe016e4 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.244 2008/08/07 19:35:02 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.245 2008/08/14 18:47:59 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -595,8 +595,8 @@ create_unique_plan(PlannerInfo *root, UniquePath *best_path) { Plan *plan; Plan *subplan; - List *uniq_exprs; List *in_operators; + List *uniq_exprs; List *newtlist; int nextresno; bool newitems; @@ -611,7 +611,7 @@ create_unique_plan(PlannerInfo *root, UniquePath *best_path) if (best_path->umethod == UNIQUE_PATH_NOOP) return subplan; - /*---------- + /* * As constructed, the subplan has a "flat" tlist containing just the * Vars needed here and at upper levels. The values we are supposed * to unique-ify may be expressions in these variables. We have to @@ -626,29 +626,9 @@ create_unique_plan(PlannerInfo *root, UniquePath *best_path) * Therefore newtlist starts from build_relation_tlist() not just a * copy of the subplan's tlist; and we don't install it into the subplan * unless we are sorting or stuff has to be added. - * - * To find the correct list of values to unique-ify, we look in the - * information saved for IN expressions. If this code is ever used in - * other scenarios, some other way of finding what to unique-ify will - * be needed. The IN clause's operators are needed too, since they - * determine what the meaning of "unique" is in this context. - *---------- */ - uniq_exprs = NIL; /* just to keep compiler quiet */ - in_operators = NIL; - foreach(l, root->in_info_list) - { - InClauseInfo *ininfo = (InClauseInfo *) lfirst(l); - - if (bms_equal(ininfo->righthand, best_path->path.parent->relids)) - { - uniq_exprs = ininfo->sub_targetlist; - in_operators = ininfo->in_operators; - break; - } - } - if (l == NULL) /* fell out of loop? */ - elog(ERROR, "could not find UniquePath in in_info_list"); + in_operators = best_path->in_operators; + uniq_exprs = best_path->uniq_exprs; /* initialize modified subplan tlist as just the "required" vars */ newtlist = build_relation_tlist(best_path->path.parent); |
