summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorTom Lane2007-01-20 20:45:41 +0000
committerTom Lane2007-01-20 20:45:41 +0000
commitf41803bb39bc2949db200116a609fd242d0ec221 (patch)
tree2c81bcf712ab8b46133c2f50bbee34b2b3ea7129 /src/include
parent2b7334d4877ba445003f96b0bb7eed4e7078a39b (diff)
Refactor planner's pathkeys data structure to create a separate, explicit
representation of equivalence classes of variables. This is an extensive rewrite, but it brings a number of benefits: * planner no longer fails in the presence of "incomplete" operator families that don't offer operators for every possible combination of datatypes. * avoid generating and then discarding redundant equality clauses. * remove bogus assumption that derived equalities always use operators named "=". * mergejoins can work with a variety of sort orders (e.g., descending) now, instead of tying each mergejoinable operator to exactly one sort order. * better recognition of redundant sort columns. * can make use of equalities appearing underneath an outer join.
Diffstat (limited to 'src/include')
-rw-r--r--src/include/nodes/nodes.h6
-rw-r--r--src/include/nodes/relation.h197
-rw-r--r--src/include/optimizer/joininfo.h5
-rw-r--r--src/include/optimizer/pathnode.h5
-rw-r--r--src/include/optimizer/paths.h59
-rw-r--r--src/include/optimizer/planmain.h22
-rw-r--r--src/include/optimizer/restrictinfo.h8
-rw-r--r--src/include/utils/lsyscache.h5
8 files changed, 218 insertions, 89 deletions
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index be151ac9f30..d3e84bdf69a 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.191 2007/01/05 22:19:55 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.192 2007/01/20 20:45:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -190,7 +190,9 @@ typedef enum NodeTag
T_ResultPath,
T_MaterialPath,
T_UniquePath,
- T_PathKeyItem,
+ T_EquivalenceClass,
+ T_EquivalenceMember,
+ T_PathKey,
T_RestrictInfo,
T_InnerIndexscanInfo,
T_OuterJoinInfo,
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h
index f7900377398..a83a20d21b5 100644
--- a/src/include/nodes/relation.h
+++ b/src/include/nodes/relation.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.132 2007/01/10 18:06:04 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.133 2007/01/20 20:45:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -69,7 +69,7 @@ typedef struct PlannerInfo
* does not correspond to a base relation, such as a join RTE or an
* unreferenced view RTE; or if the RelOptInfo hasn't been made yet.
*/
- struct RelOptInfo **simple_rel_array; /* All 1-relation RelOptInfos */
+ struct RelOptInfo **simple_rel_array; /* All 1-rel RelOptInfos */
int simple_rel_array_size; /* allocated size of array */
/*
@@ -84,18 +84,20 @@ typedef struct PlannerInfo
List *join_rel_list; /* list of join-relation RelOptInfos */
struct HTAB *join_rel_hash; /* optional hashtable for join relations */
- List *equi_key_list; /* list of lists of equijoined PathKeyItems */
+ List *eq_classes; /* list of active EquivalenceClasses */
- List *left_join_clauses; /* list of RestrictInfos for outer
- * join clauses w/nonnullable var on
- * left */
+ List *canon_pathkeys; /* list of "canonical" PathKeys */
- List *right_join_clauses; /* list of RestrictInfos for outer
- * join clauses w/nonnullable var on
- * right */
+ List *left_join_clauses; /* list of RestrictInfos for
+ * mergejoinable outer join clauses
+ * w/nonnullable var on left */
- List *full_join_clauses; /* list of RestrictInfos for full
- * outer join clauses */
+ List *right_join_clauses; /* list of RestrictInfos for
+ * mergejoinable outer join clauses
+ * w/nonnullable var on right */
+
+ List *full_join_clauses; /* list of RestrictInfos for
+ * mergejoinable full join clauses */
List *oj_info_list; /* list of OuterJoinInfos */
@@ -109,6 +111,8 @@ typedef struct PlannerInfo
List *group_pathkeys; /* groupClause pathkeys, if any */
List *sort_pathkeys; /* sortClause pathkeys, if any */
+ MemoryContext planner_cxt; /* context holding PlannerInfo */
+
double total_table_pages; /* # of pages in all tables of query */
double tuple_fraction; /* tuple_fraction passed to query_planner */
@@ -209,7 +213,10 @@ typedef struct PlannerInfo
* baserestrictcost - Estimated cost of evaluating the baserestrictinfo
* clauses at a single tuple (only used for base rels)
* joininfo - List of RestrictInfo nodes, containing info about each
- * join clause in which this relation participates
+ * join clause in which this relation participates (but
+ * note this excludes clauses that might be derivable from
+ * EquivalenceClasses)
+ * has_eclass_joins - flag that EquivalenceClass joins are possible
* index_outer_relids - only used for base rels; set of outer relids
* that participate in indexable joinclauses for this rel
* index_inner_paths - only used for base rels; list of InnerIndexscanInfo
@@ -278,6 +285,7 @@ typedef struct RelOptInfo
QualCost baserestrictcost; /* cost of evaluating the above */
List *joininfo; /* RestrictInfo structures for join clauses
* involving this rel */
+ bool has_eclass_joins; /* T means joininfo is incomplete */
/* cached info about inner indexscan paths for relation: */
Relids index_outer_relids; /* other relids in indexable join
@@ -349,31 +357,106 @@ typedef struct IndexOptInfo
/*
+ * EquivalenceClasses
+ *
+ * Whenever we can determine that a mergejoinable equality clause A = B is
+ * not delayed by any outer join, we create an EquivalenceClass containing
+ * the expressions A and B to record this knowledge. If we later find another
+ * equivalence B = C, we add C to the existing EquivalenceClass; this may
+ * require merging two existing EquivalenceClasses. At the end of the qual
+ * distribution process, we have sets of values that are known all transitively
+ * equal to each other, where "equal" is according to the rules of the btree
+ * operator family(s) shown in ec_opfamilies. (We restrict an EC to contain
+ * only equalities whose operators belong to the same set of opfamilies. This
+ * could probably be relaxed, but for now it's not worth the trouble, since
+ * nearly all equality operators belong to only one btree opclass anyway.)
+ *
+ * We also use EquivalenceClasses as the base structure for PathKeys, letting
+ * us represent knowledge about different sort orderings being equivalent.
+ * Since every PathKey must reference an EquivalenceClass, we will end up
+ * with single-member EquivalenceClasses whenever a sort key expression has
+ * not been equivalenced to anything else. It is also possible that such an
+ * EquivalenceClass will contain a volatile expression ("ORDER BY random()"),
+ * which is a case that can't arise otherwise since clauses containing
+ * volatile functions are never considered mergejoinable. We mark such
+ * EquivalenceClasses specially to prevent them from being merged with
+ * ordinary EquivalenceClasses.
+ *
+ * We allow equality clauses appearing below the nullable side of an outer join
+ * to form EquivalenceClasses, but these have a slightly different meaning:
+ * the included values might be all NULL rather than all the same non-null
+ * values. See src/backend/optimizer/README for more on that point.
+ *
+ * NB: if ec_merged isn't NULL, this class has been merged into another, and
+ * should be ignored in favor of using the pointed-to class.
+ */
+typedef struct EquivalenceClass
+{
+ NodeTag type;
+
+ List *ec_opfamilies; /* btree operator family OIDs */
+ List *ec_members; /* list of EquivalenceMembers */
+ List *ec_sources; /* list of generating RestrictInfos */
+ Relids ec_relids; /* all relids appearing in ec_members */
+ bool ec_has_const; /* any pseudoconstants in ec_members? */
+ bool ec_has_volatile; /* the (sole) member is a volatile expr */
+ bool ec_below_outer_join; /* equivalence applies below an OJ */
+ bool ec_broken; /* failed to generate needed clauses? */
+ struct EquivalenceClass *ec_merged; /* set if merged into another EC */
+} EquivalenceClass;
+
+/*
+ * EquivalenceMember - one member expression of an EquivalenceClass
+ *
+ * em_is_child signifies that this element was built by transposing a member
+ * for an inheritance parent relation to represent the corresponding expression
+ * on an inheritance child. The element should be ignored for all purposes
+ * except constructing inner-indexscan paths for the child relation. (Other
+ * types of join are driven from transposed joininfo-list entries.) Note
+ * that the EC's ec_relids field does NOT include the child relation.
+ *
+ * em_datatype is usually the same as exprType(em_expr), but can be
+ * different when dealing with a binary-compatible opfamily; in particular
+ * anyarray_ops would never work without this. Use em_datatype when
+ * looking up a specific btree operator to work with this expression.
+ */
+typedef struct EquivalenceMember
+{
+ NodeTag type;
+
+ Expr *em_expr; /* the expression represented */
+ Relids em_relids; /* all relids appearing in em_expr */
+ bool em_is_const; /* expression is pseudoconstant? */
+ bool em_is_child; /* derived version for a child relation? */
+ Oid em_datatype; /* the "nominal type" used by the opfamily */
+} EquivalenceMember;
+
+/*
* PathKeys
*
- * The sort ordering of a path is represented by a list of sublists of
- * PathKeyItem nodes. An empty list implies no known ordering. Otherwise
- * the first sublist represents the primary sort key, the second the
- * first secondary sort key, etc. Each sublist contains one or more
- * PathKeyItem nodes, each of which can be taken as the attribute that
- * appears at that sort position. (See optimizer/README for more
- * information.)
+ * The sort ordering of a path is represented by a list of PathKey nodes.
+ * An empty list implies no known ordering. Otherwise the first item
+ * represents the primary sort key, the second the first secondary sort key,
+ * etc. The value being sorted is represented by linking to an
+ * EquivalenceClass containing that value and including pk_opfamily among its
+ * ec_opfamilies. This is a convenient method because it makes it trivial
+ * to detect equivalent and closely-related orderings. (See optimizer/README
+ * for more information.)
+ *
+ * Note: pk_strategy is either BTLessStrategyNumber (for ASC) or
+ * BTGreaterStrategyNumber (for DESC). We assume that all ordering-capable
+ * index types will use btree-compatible strategy numbers.
*/
-typedef struct PathKeyItem
+typedef struct PathKey
{
NodeTag type;
- Node *key; /* the item that is ordered */
- Oid sortop; /* the ordering operator ('<' op) */
- bool nulls_first; /* do NULLs come before normal values? */
-
- /*
- * key typically points to a Var node, ie a relation attribute, but it can
- * also point to an arbitrary expression representing the value indexed by
- * an index expression.
- */
-} PathKeyItem;
+ EquivalenceClass *pk_eclass; /* the value that is ordered */
+ Oid pk_opfamily; /* btree opfamily defining the ordering */
+ int pk_strategy; /* sort direction (ASC or DESC) */
+ bool pk_nulls_first; /* do NULLs come before normal values? */
+} PathKey;
/*
* Type "Path" is used as-is for sequential-scan paths. For other
@@ -398,7 +481,7 @@ typedef struct Path
Cost total_cost; /* total cost (assuming all tuples fetched) */
List *pathkeys; /* sort ordering of path's output */
- /* pathkeys is a List of Lists of PathKeyItem nodes; see above */
+ /* pathkeys is a List of PathKey nodes; see above */
} Path;
/*----------
@@ -618,11 +701,7 @@ typedef JoinPath NestPath;
* A mergejoin path has these fields.
*
* path_mergeclauses lists the clauses (in the form of RestrictInfos)
- * that will be used in the merge. The parallel arrays path_mergeFamilies,
- * path_mergeStrategies, and path_mergeNullsFirst specify the merge semantics
- * for each clause (i.e., define the relevant sort ordering for each clause).
- * (XXX is this the most reasonable path-time representation? It's at least
- * partially redundant with the pathkeys of the input paths.)
+ * that will be used in the merge.
*
* Note that the mergeclauses are a subset of the parent relation's
* restriction-clause list. Any join clauses that are not mergejoinable
@@ -639,10 +718,6 @@ typedef struct MergePath
{
JoinPath jpath;
List *path_mergeclauses; /* join clauses to be used for merge */
- /* these are arrays, but have the same length as the mergeclauses list: */
- Oid *path_mergeFamilies; /* per-clause OIDs of opfamilies */
- int *path_mergeStrategies; /* per-clause ordering (ASC or DESC) */
- bool *path_mergeNullsFirst; /* per-clause nulls ordering */
List *outersortkeys; /* keys for explicit sort, if any */
List *innersortkeys; /* keys for explicit sort, if any */
} MergePath;
@@ -696,6 +771,15 @@ typedef struct HashPath
* sequence we use. So, these clauses cannot be associated directly with
* the join RelOptInfo, but must be kept track of on a per-join-path basis.
*
+ * RestrictInfos that represent equivalence conditions (i.e., mergejoinable
+ * equalities that are not outerjoin-delayed) are handled a bit differently.
+ * Initially we attach them to the EquivalenceClasses that are derived from
+ * them. When we construct a scan or join path, we look through all the
+ * EquivalenceClasses and generate derived RestrictInfos representing the
+ * minimal set of conditions that need to be checked for this particular scan
+ * or join to enforce that all members of each EquivalenceClass are in fact
+ * equal in all rows emitted by the scan or join.
+ *
* When dealing with outer joins we have to be very careful about pushing qual
* clauses up and down the tree. An outer join's own JOIN/ON conditions must
* be evaluated exactly at that join node, and any quals appearing in WHERE or
@@ -728,9 +812,9 @@ typedef struct HashPath
*
* In general, the referenced clause might be arbitrarily complex. The
* kinds of clauses we can handle as indexscan quals, mergejoin clauses,
- * or hashjoin clauses are fairly limited --- the code for each kind of
- * path is responsible for identifying the restrict clauses it can use
- * and ignoring the rest. Clauses not implemented by an indexscan,
+ * or hashjoin clauses are limited (e.g., no volatile functions). The code
+ * for each kind of path is responsible for identifying the restrict clauses
+ * it can use and ignoring the rest. Clauses not implemented by an indexscan,
* mergejoin, or hashjoin will be placed in the plan qual or joinqual field
* of the finished Plan node, where they will be enforced by general-purpose
* qual-expression-evaluation code. (But we are still entitled to count
@@ -758,6 +842,12 @@ typedef struct HashPath
* estimates. Note that a pseudoconstant clause can never be an indexqual
* or merge or hash join clause, so it's of no interest to large parts of
* the planner.
+ *
+ * When join clauses are generated from EquivalenceClasses, there may be
+ * several equally valid ways to enforce join equivalence, of which we need
+ * apply only one. We mark clauses of this kind by setting parent_ec to
+ * point to the generating EquivalenceClass. Multiple clauses with the same
+ * parent_ec in the same join are redundant.
*/
typedef struct RestrictInfo
@@ -787,23 +877,22 @@ typedef struct RestrictInfo
/* This field is NULL unless clause is an OR clause: */
Expr *orclause; /* modified clause with RestrictInfos */
+ /* This field is NULL unless clause is potentially redundant: */
+ EquivalenceClass *parent_ec; /* generating EquivalenceClass */
+
/* cache space for cost and selectivity */
QualCost eval_cost; /* eval cost of clause; -1 if not yet set */
Selectivity this_selec; /* selectivity; -1 if not yet set */
- /* valid if clause is mergejoinable, else InvalidOid: */
- Oid mergejoinoperator; /* copy of clause operator */
- Oid left_sortop; /* leftside sortop needed for mergejoin */
- Oid right_sortop; /* rightside sortop needed for mergejoin */
- Oid mergeopfamily; /* btree opfamily relating these ops */
+ /* valid if clause is mergejoinable, else NIL */
+ List *mergeopfamilies; /* opfamilies containing clause operator */
- /* cache space for mergeclause processing; NIL if not yet set */
- List *left_pathkey; /* canonical pathkey for left side */
- List *right_pathkey; /* canonical pathkey for right side */
+ /* cache space for mergeclause processing; NULL if not yet set */
+ EquivalenceClass *left_ec; /* EquivalenceClass containing lefthand */
+ EquivalenceClass *right_ec; /* EquivalenceClass containing righthand */
- /* cache space for mergeclause processing; -1 if not yet set */
- Selectivity left_mergescansel; /* fraction of left side to scan */
- Selectivity right_mergescansel; /* fraction of right side to scan */
+ /* transient workspace for use while considering a specific join path */
+ bool outer_is_left; /* T = outer var on left, F = on right */
/* valid if clause is hashjoinable, else InvalidOid: */
Oid hashjoinoperator; /* copy of clause operator */
diff --git a/src/include/optimizer/joininfo.h b/src/include/optimizer/joininfo.h
index d491a368eb6..f7c4bc07d39 100644
--- a/src/include/optimizer/joininfo.h
+++ b/src/include/optimizer/joininfo.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/optimizer/joininfo.h,v 1.33 2007/01/05 22:19:56 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/optimizer/joininfo.h,v 1.34 2007/01/20 20:45:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,8 +23,5 @@ extern bool have_relevant_joinclause(PlannerInfo *root,
extern void add_join_clause_to_rels(PlannerInfo *root,
RestrictInfo *restrictinfo,
Relids join_relids);
-extern void remove_join_clause_from_rels(PlannerInfo *root,
- RestrictInfo *restrictinfo,
- Relids join_relids);
#endif /* JOININFO_H */
diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h
index fd5c78372ec..98a73ebc4ee 100644
--- a/src/include/optimizer/pathnode.h
+++ b/src/include/optimizer/pathnode.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/optimizer/pathnode.h,v 1.75 2007/01/10 18:06:04 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/optimizer/pathnode.h,v 1.76 2007/01/20 20:45:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -71,9 +71,6 @@ extern MergePath *create_mergejoin_path(PlannerInfo *root,
List *restrict_clauses,
List *pathkeys,
List *mergeclauses,
- Oid *mergefamilies,
- int *mergestrategies,
- bool *mergenullsfirst,
List *outersortkeys,
List *innersortkeys);
diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h
index 14baf430a06..7e7eb15469e 100644
--- a/src/include/optimizer/paths.h
+++ b/src/include/optimizer/paths.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/optimizer/paths.h,v 1.94 2007/01/05 22:19:56 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/optimizer/paths.h,v 1.95 2007/01/20 20:45:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -52,6 +52,9 @@ extern List *group_clauses_by_indexkey(IndexOptInfo *index,
Relids outer_relids,
SaOpControl saop_control,
bool *found_clause);
+extern bool eclass_matches_any_index(EquivalenceClass *ec,
+ EquivalenceMember *em,
+ RelOptInfo *rel);
extern bool match_index_to_operand(Node *operand, int indexcol,
IndexOptInfo *index);
extern List *expand_indexqual_conditions(IndexOptInfo *index,
@@ -90,6 +93,37 @@ extern RelOptInfo *make_join_rel(PlannerInfo *root,
RelOptInfo *rel1, RelOptInfo *rel2);
/*
+ * equivclass.c
+ * routines for managing EquivalenceClasses
+ */
+extern bool process_equivalence(PlannerInfo *root, RestrictInfo *restrictinfo,
+ bool below_outer_join);
+extern void reconsider_outer_join_clauses(PlannerInfo *root);
+extern EquivalenceClass *get_eclass_for_sort_expr(PlannerInfo *root,
+ Expr *expr,
+ Oid expr_datatype,
+ List *opfamilies);
+extern void generate_base_implied_equalities(PlannerInfo *root);
+extern List *generate_join_implied_equalities(PlannerInfo *root,
+ RelOptInfo *joinrel,
+ RelOptInfo *outer_rel,
+ RelOptInfo *inner_rel);
+extern bool exprs_known_equal(PlannerInfo *root, Node *item1, Node *item2);
+extern void add_child_rel_equivalences(PlannerInfo *root,
+ AppendRelInfo *appinfo,
+ RelOptInfo *parent_rel,
+ RelOptInfo *child_rel);
+extern List *find_eclass_clauses_for_index_join(PlannerInfo *root,
+ RelOptInfo *rel,
+ Relids outer_relids);
+extern bool have_relevant_eclass_joinclause(PlannerInfo *root,
+ RelOptInfo *rel1, RelOptInfo *rel2);
+extern bool has_relevant_eclass_joinclause(PlannerInfo *root,
+ RelOptInfo *rel1);
+extern bool eclass_useful_for_merging(EquivalenceClass *eclass,
+ RelOptInfo *rel);
+
+/*
* pathkeys.c
* utilities for matching and building path keys
*/
@@ -101,9 +135,6 @@ typedef enum
PATHKEYS_DIFFERENT /* neither pathkey includes the other */
} PathKeysComparison;
-extern void add_equijoined_keys(PlannerInfo *root, RestrictInfo *restrictinfo);
-extern bool exprs_known_equal(PlannerInfo *root, Node *item1, Node *item2);
-extern void generate_implied_equalities(PlannerInfo *root);
extern List *canonicalize_pathkeys(PlannerInfo *root, List *pathkeys);
extern PathKeysComparison compare_pathkeys(List *keys1, List *keys2);
extern bool pathkeys_contained_in(List *keys1, List *keys2);
@@ -113,23 +144,29 @@ extern Path *get_cheapest_fractional_path_for_pathkeys(List *paths,
List *pathkeys,
double fraction);
extern List *build_index_pathkeys(PlannerInfo *root, IndexOptInfo *index,
- ScanDirection scandir, bool canonical);
+ ScanDirection scandir);
extern List *convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel,
List *subquery_pathkeys);
extern List *build_join_pathkeys(PlannerInfo *root,
RelOptInfo *joinrel,
JoinType jointype,
List *outer_pathkeys);
-extern List *make_pathkeys_for_sortclauses(List *sortclauses,
- List *tlist);
-extern void cache_mergeclause_pathkeys(PlannerInfo *root,
+extern List *make_pathkeys_for_sortclauses(PlannerInfo *root,
+ List *sortclauses,
+ List *tlist,
+ bool canonicalize);
+extern void cache_mergeclause_eclasses(PlannerInfo *root,
RestrictInfo *restrictinfo);
extern List *find_mergeclauses_for_pathkeys(PlannerInfo *root,
List *pathkeys,
+ bool outer_keys,
List *restrictinfos);
-extern List *make_pathkeys_for_mergeclauses(PlannerInfo *root,
- List *mergeclauses,
- RelOptInfo *rel);
+extern List *select_outer_pathkeys_for_merge(PlannerInfo *root,
+ List *mergeclauses,
+ RelOptInfo *joinrel);
+extern List *make_inner_pathkeys_for_merge(PlannerInfo *root,
+ List *mergeclauses,
+ List *outer_pathkeys);
extern int pathkeys_useful_for_merging(PlannerInfo *root,
RelOptInfo *rel,
List *pathkeys);
diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h
index 0f6799338bb..5118061182a 100644
--- a/src/include/optimizer/planmain.h
+++ b/src/include/optimizer/planmain.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/optimizer/planmain.h,v 1.97 2007/01/10 18:06:04 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/optimizer/planmain.h,v 1.98 2007/01/20 20:45:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -38,6 +38,8 @@ extern Plan *create_plan(PlannerInfo *root, Path *best_path);
extern SubqueryScan *make_subqueryscan(List *qptlist, List *qpqual,
Index scanrelid, Plan *subplan);
extern Append *make_append(List *appendplans, bool isTarget, List *tlist);
+extern Sort *make_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree,
+ List *pathkeys);
extern Sort *make_sort_from_sortclauses(PlannerInfo *root, List *sortcls,
Plan *lefttree);
extern Sort *make_sort_from_groupcols(PlannerInfo *root, List *groupcls,
@@ -69,12 +71,22 @@ extern int join_collapse_limit;
extern void add_base_rels_to_query(PlannerInfo *root, Node *jtnode);
extern void build_base_rel_tlists(PlannerInfo *root, List *final_tlist);
+extern void add_vars_to_targetlist(PlannerInfo *root, List *vars,
+ Relids where_needed);
extern List *deconstruct_jointree(PlannerInfo *root);
+extern void distribute_restrictinfo_to_rels(PlannerInfo *root,
+ RestrictInfo *restrictinfo);
extern void process_implied_equality(PlannerInfo *root,
- Node *item1, Node *item2,
- Oid sortop1, Oid sortop2,
- Relids item1_relids, Relids item2_relids,
- bool delete_it);
+ Oid opno,
+ Expr *item1,
+ Expr *item2,
+ Relids qualscope,
+ bool below_outer_join,
+ bool both_const);
+extern RestrictInfo *build_implied_join_equality(Oid opno,
+ Expr *item1,
+ Expr *item2,
+ Relids qualscope);
/*
* prototypes for plan/setrefs.c
diff --git a/src/include/optimizer/restrictinfo.h b/src/include/optimizer/restrictinfo.h
index 619e7cef398..272c5a67037 100644
--- a/src/include/optimizer/restrictinfo.h
+++ b/src/include/optimizer/restrictinfo.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/optimizer/restrictinfo.h,v 1.39 2007/01/05 22:19:56 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/optimizer/restrictinfo.h,v 1.40 2007/01/20 20:45:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -32,12 +32,8 @@ extern List *extract_actual_clauses(List *restrictinfo_list,
extern void extract_actual_join_clauses(List *restrictinfo_list,
List **joinquals,
List **otherquals);
-extern List *remove_redundant_join_clauses(PlannerInfo *root,
- List *restrictinfo_list,
- bool isouterjoin);
extern List *select_nonredundant_join_clauses(PlannerInfo *root,
List *restrictinfo_list,
- List *reference_list,
- bool isouterjoin);
+ List *reference_list);
#endif /* RESTRICTINFO_H */
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index 8d4c0d8e3ef..f0e3f2c20d4 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/lsyscache.h,v 1.112 2007/01/10 18:06:05 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/lsyscache.h,v 1.113 2007/01/20 20:45:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -35,12 +35,11 @@ extern void get_op_opfamily_properties(Oid opno, Oid opfamily,
bool *recheck);
extern Oid get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype,
int16 strategy);
-extern bool get_op_mergejoin_info(Oid eq_op, Oid *left_sortop,
- Oid *right_sortop, Oid *opfamily);
extern bool get_compare_function_for_ordering_op(Oid opno,
Oid *cmpfunc, bool *reverse);
extern Oid get_equality_op_for_ordering_op(Oid opno);
extern Oid get_ordering_op_for_equality_op(Oid opno, bool use_lhs_type);
+extern List *get_mergejoin_opfamilies(Oid opno);
extern Oid get_compatible_hash_operator(Oid opno, bool use_lhs_type);
extern Oid get_op_hash_function(Oid opno);
extern void get_op_btree_interpretation(Oid opno,