aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/planner.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/plan/planner.c')
-rw-r--r--src/backend/optimizer/plan/planner.c60
1 files changed, 58 insertions, 2 deletions
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 4be9b05bb90..7ffbb4666d9 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.88 2000/08/21 20:55:29 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.89 2000/09/12 21:06:54 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -29,6 +29,7 @@
#include "utils/lsyscache.h"
+static void preprocess_join_conditions(Query *parse, Node *jtnode);
static List *make_subplanTargetList(Query *parse, List *tlist,
AttrNumber **groupColIdx);
static Plan *make_groupplan(List *group_tlist, bool tuplePerGroup,
@@ -163,6 +164,7 @@ subquery_planner(Query *parse, double tuple_fraction)
* canonicalize_qual?
*/
parse->qual = (Node *) canonicalize_qual((Expr *) parse->qual, true);
+
#ifdef OPTIMIZER_DEBUG
printf("After canonicalize_qual()\n");
pprint(parse->qual);
@@ -211,6 +213,9 @@ subquery_planner(Query *parse, double tuple_fraction)
parse->havingQual = SS_replace_correlation_vars(parse->havingQual);
}
+ /* Do all the above for each qual condition (ON clause) in the join tree */
+ preprocess_join_conditions(parse, (Node *) parse->jointree);
+
/* Do the main planning (potentially recursive) */
return union_planner(parse, tuple_fraction);
@@ -224,6 +229,58 @@ subquery_planner(Query *parse, double tuple_fraction)
*/
}
+/*
+ * preprocess_join_conditions
+ * Recursively scan the query's jointree and do subquery_planner's
+ * qual preprocessing work on each ON condition found therein.
+ */
+static void
+preprocess_join_conditions(Query *parse, Node *jtnode)
+{
+ if (jtnode == NULL)
+ return;
+ if (IsA(jtnode, List))
+ {
+ List *l;
+
+ foreach(l, (List *) jtnode)
+ preprocess_join_conditions(parse, lfirst(l));
+ }
+ else if (IsA(jtnode, RangeTblRef))
+ {
+ /* nothing to do here */
+ }
+ else if (IsA(jtnode, JoinExpr))
+ {
+ JoinExpr *j = (JoinExpr *) jtnode;
+
+ preprocess_join_conditions(parse, j->larg);
+ preprocess_join_conditions(parse, j->rarg);
+
+ /* Simplify constant expressions */
+ j->quals = eval_const_expressions(j->quals);
+
+ /* Canonicalize the qual, and convert it to implicit-AND format */
+ j->quals = (Node *) canonicalize_qual((Expr *) j->quals, true);
+
+ /* Expand SubLinks to SubPlans */
+ if (parse->hasSubLinks)
+ {
+ j->quals = SS_process_sublinks(j->quals);
+ /*
+ * ON conditions, like WHERE clauses, are evaluated pre-GROUP;
+ * so we allow ungrouped vars in them.
+ */
+ }
+
+ /* Replace uplevel vars with Param nodes */
+ if (PlannerQueryLevel > 1)
+ j->quals = SS_replace_correlation_vars(j->quals);
+ }
+ else
+ elog(ERROR, "preprocess_join_conditions: unexpected node type %d",
+ nodeTag(jtnode));
+}
/*--------------------
* union_planner
@@ -542,7 +599,6 @@ union_planner(Query *parse,
/* Generate the (sub) plan */
result_plan = query_planner(parse,
sub_tlist,
- (List *) parse->qual,
tuple_fraction);
/*