summaryrefslogtreecommitdiff
path: root/src/include/nodes
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/nodes')
-rw-r--r--src/include/nodes/nodes.h3
-rw-r--r--src/include/nodes/primnodes.h9
-rw-r--r--src/include/nodes/relation.h47
3 files changed, 41 insertions, 18 deletions
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index e9ec4b8ad6..0d6a4871ac 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.178 2005/11/22 18:17:30 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.179 2005/12/20 02:30:36 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -186,6 +186,7 @@ typedef enum NodeTag
T_PathKeyItem,
T_RestrictInfo,
T_InnerIndexscanInfo,
+ T_OuterJoinInfo,
T_InClauseInfo,
/*
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index 1cdd64b26e..40fda441b9 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -10,7 +10,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.109 2005/10/15 02:49:45 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.110 2005/12/20 02:30:36 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -845,12 +845,7 @@ typedef struct TargetEntry
* or qualified join. Also, FromExpr nodes can appear to denote an
* ordinary cross-product join ("FROM foo, bar, baz WHERE ...").
* FromExpr is like a JoinExpr of jointype JOIN_INNER, except that it
- * may have any number of child nodes, not just two. Also, there is an
- * implementation-defined difference: the planner is allowed to join the
- * children of a FromExpr using whatever join order seems good to it.
- * At present, JoinExpr nodes are always joined in exactly the order
- * implied by the jointree structure (except the planner may choose to
- * swap inner and outer members of a join pair).
+ * may have any number of child nodes, not just two.
*
* NOTE: the top level of a Query's jointree is always a FromExpr.
* Even if the jointree contains no rels, there will be a FromExpr.
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h
index aa6217d031..1d490fc17b 100644
--- a/src/include/nodes/relation.h
+++ b/src/include/nodes/relation.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.121 2005/11/26 22:14:57 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.122 2005/12/20 02:30:36 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -97,6 +97,8 @@ typedef struct PlannerInfo
List *full_join_clauses; /* list of RestrictInfos for full
* outer join clauses */
+ List *oj_info_list; /* list of OuterJoinInfos */
+
List *in_info_list; /* list of InClauseInfos */
List *query_pathkeys; /* desired pathkeys for query_planner(), and
@@ -201,10 +203,6 @@ typedef struct PlannerInfo
* participates (only used for base rels)
* baserestrictcost - Estimated cost of evaluating the baserestrictinfo
* clauses at a single tuple (only used for base rels)
- * outerjoinset - For a base rel: if the rel appears within the nullable
- * side of an outer join, the set of all relids
- * participating in the highest such outer join; else NULL.
- * Otherwise, unused.
* joininfo - List of RestrictInfo nodes, containing info about each
* join clause in which this relation participates
* index_outer_relids - only used for base rels; set of outer relids
@@ -228,10 +226,6 @@ typedef struct PlannerInfo
* We store baserestrictcost in the RelOptInfo (for base relations) because
* we know we will need it at least once (to price the sequential scan)
* and may need it multiple times to price index scans.
- *
- * outerjoinset is used to ensure correct placement of WHERE clauses that
- * apply to outer-joined relations; we must not apply such WHERE clauses
- * until after the outer join is performed.
*----------
*/
typedef enum RelOptKind
@@ -277,7 +271,6 @@ typedef struct RelOptInfo
List *baserestrictinfo; /* RestrictInfo structures (if base
* rel) */
QualCost baserestrictcost; /* cost of evaluating the above */
- Relids outerjoinset; /* set of base relids */
List *joininfo; /* RestrictInfo structures for join clauses
* involving this rel */
@@ -831,6 +824,40 @@ typedef struct InnerIndexscanInfo
} InnerIndexscanInfo;
/*
+ * Outer join info.
+ *
+ * One-sided outer joins constrain the order of joining partially but not
+ * completely. We flatten such joins into the planner's top-level list of
+ * relations to join, but record information about each outer join in an
+ * OuterJoinInfo struct. These structs are kept in the PlannerInfo node's
+ * oj_info_list.
+ *
+ * min_lefthand and min_righthand are the sets of base relids that must be
+ * available on each side when performing the outer join. lhs_strict is
+ * true if the outer join's condition cannot succeed when the LHS variables
+ * are all NULL (this means that the outer join can commute with upper-level
+ * outer joins even if it appears in their RHS). We don't bother to set
+ * lhs_strict for FULL JOINs, however.
+ *
+ * It is not valid for either min_lefthand or min_righthand to be empty sets;
+ * if they were, this would break the logic that enforces join order.
+ *
+ * Note: OuterJoinInfo directly represents only LEFT JOIN and FULL JOIN;
+ * RIGHT JOIN is handled by switching the inputs to make it a LEFT JOIN.
+ * We make an OuterJoinInfo for FULL JOINs even though there is no flexibility
+ * of planning for them, because this simplifies make_join_rel()'s API.
+ */
+
+typedef struct OuterJoinInfo
+{
+ NodeTag type;
+ Relids min_lefthand; /* base relids in minimum LHS for join */
+ Relids min_righthand; /* base relids in minimum RHS for join */
+ bool is_full_join; /* it's a FULL OUTER JOIN */
+ bool lhs_strict; /* joinclause is strict for some LHS rel */
+} OuterJoinInfo;
+
+/*
* IN clause info.
*
* When we convert top-level IN quals into join operations, we must restrict