Commit b5956a2f authored by Tom Lane's avatar Tom Lane

Detect case where an outer join can be reduced to a plain inner join

because there are WHERE clauses that will reject the null-extended rows.
Per suggestion from Brandon Craig Rhodes, 19-Nov-02.
parent 43785a43
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.145 2003/02/09 00:30:39 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.146 2003/02/09 23:57:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -144,6 +144,7 @@ subquery_planner(Query *parse, double tuple_fraction)
{
List *saved_initplan = PlannerInitPlan;
int saved_planid = PlannerPlanId;
bool hasOuterJoins;
Plan *plan;
List *newHaving;
List *lst;
......@@ -172,10 +173,12 @@ subquery_planner(Query *parse, double tuple_fraction)
/*
* Detect whether any rangetable entries are RTE_JOIN kind; if not,
* we can avoid the expense of doing flatten_join_alias_vars().
* we can avoid the expense of doing flatten_join_alias_vars(). Also
* check for outer joins --- if none, we can skip reduce_outer_joins().
* This must be done after we have done pull_up_subqueries, of course.
*/
parse->hasJoinRTEs = false;
hasOuterJoins = false;
foreach(lst, parse->rtable)
{
RangeTblEntry *rte = (RangeTblEntry *) lfirst(lst);
......@@ -183,9 +186,14 @@ subquery_planner(Query *parse, double tuple_fraction)
if (rte->rtekind == RTE_JOIN)
{
parse->hasJoinRTEs = true;
if (IS_OUTER_JOIN(rte->jointype))
{
hasOuterJoins = true;
/* Can quit scanning once we find an outer join */
break;
}
}
}
/*
* Do expression preprocessing on targetlist and quals.
......@@ -244,15 +252,23 @@ subquery_planner(Query *parse, double tuple_fraction)
}
parse->havingQual = (Node *) newHaving;
/*
* If we have any outer joins, try to reduce them to plain inner joins.
* This step is most easily done after we've done expression preprocessing.
*/
if (hasOuterJoins)
reduce_outer_joins(parse);
/*
* See if we can simplify the jointree; opportunities for this may come
* from having pulled up subqueries, or from flattening explicit JOIN
* syntax. We must do this after flattening JOIN alias variables, since
* eliminating explicit JOIN nodes from the jointree will cause
* get_relids_for_join() to fail.
* get_relids_for_join() to fail. But it should happen after
* reduce_outer_joins, anyway.
*/
parse->jointree = (FromExpr *)
preprocess_jointree(parse, (Node *) parse->jointree);
simplify_jointree(parse, (Node *) parse->jointree);
/*
* Do the main planning. If we have an inherited target relation,
......
This diff is collapsed.
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: prep.h,v 1.36 2003/02/08 20:20:55 tgl Exp $
* $Id: prep.h,v 1.37 2003/02/09 23:57:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -28,7 +28,8 @@ extern int join_collapse_limit;
extern Node *pull_up_IN_clauses(Query *parse, Node *node);
extern Node *pull_up_subqueries(Query *parse, Node *jtnode,
bool below_outer_join);
extern Node *preprocess_jointree(Query *parse, Node *jtnode);
extern void reduce_outer_joins(Query *parse);
extern Node *simplify_jointree(Query *parse, Node *jtnode);
extern Relids get_relids_in_jointree(Node *jtnode);
extern Relids get_relids_for_join(Query *parse, int joinrelid);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment