Commit 19e34b62 authored by Tom Lane's avatar Tom Lane

Improve sublink pullup code to handle ANY/EXISTS sublinks that are at top

level of a JOIN/ON clause, not only at top level of WHERE.  (However, we
can't do this in an outer join's ON clause, unless the ANY/EXISTS refers
only to the nullable side of the outer join, so that it can effectively
be pushed down into the nullable side.)  Per request from Kevin Grittner.

In passing, fix a bug in the initial implementation of EXISTS pullup:
it would Assert if the EXIST's WHERE clause used a join alias variable.
Since we haven't yet flattened join aliases when this transformation
happens, it's necessary to include join relids in the computed set of
RHS relids.
parent 909346ef
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.141 2008/08/14 18:47:59 tgl Exp $ * $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.142 2008/08/17 01:19:59 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -778,7 +778,9 @@ distribute_qual_to_rels(PlannerInfo *root, Node *clause, ...@@ -778,7 +778,9 @@ distribute_qual_to_rels(PlannerInfo *root, Node *clause,
root->hasPseudoConstantQuals = true; root->hasPseudoConstantQuals = true;
/* if not below outer join, push it to top of tree */ /* if not below outer join, push it to top of tree */
if (!below_outer_join) if (!below_outer_join)
relids = get_relids_in_jointree((Node *) root->parse->jointree); relids =
get_relids_in_jointree((Node *) root->parse->jointree,
false);
} }
} }
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.241 2008/08/14 18:47:59 tgl Exp $ * $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.242 2008/08/17 01:19:59 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -268,14 +268,13 @@ subquery_planner(PlannerGlobal *glob, Query *parse, ...@@ -268,14 +268,13 @@ subquery_planner(PlannerGlobal *glob, Query *parse,
root->append_rel_list = NIL; root->append_rel_list = NIL;
/* /*
* Look for ANY and EXISTS SubLinks at the top level of WHERE, and try to * Look for ANY and EXISTS SubLinks in WHERE and JOIN/ON clauses, and try
* transform them into joins. Note that this step only handles SubLinks * to transform them into joins. Note that this step does not descend
* originally at top level of WHERE; if we pull up any subqueries below, * into subqueries; if we pull up any subqueries below, their SubLinks are
* their SubLinks are processed just before pulling them up. * processed just before pulling them up.
*/ */
if (parse->hasSubLinks) if (parse->hasSubLinks)
parse->jointree->quals = pull_up_sublinks(root, pull_up_sublinks(root);
parse->jointree->quals);
/* /*
* Scan the rangetable for set-returning functions, and inline them * Scan the rangetable for set-returning functions, and inline them
......
This diff is collapsed.
This diff is collapsed.
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/optimizer/prep.h,v 1.61 2008/08/14 18:48:00 tgl Exp $ * $PostgreSQL: pgsql/src/include/optimizer/prep.h,v 1.62 2008/08/17 01:20:00 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -21,12 +21,12 @@ ...@@ -21,12 +21,12 @@
/* /*
* prototypes for prepjointree.c * prototypes for prepjointree.c
*/ */
extern Node *pull_up_sublinks(PlannerInfo *root, Node *node); extern void pull_up_sublinks(PlannerInfo *root);
extern void inline_set_returning_functions(PlannerInfo *root); extern void inline_set_returning_functions(PlannerInfo *root);
extern Node *pull_up_subqueries(PlannerInfo *root, Node *jtnode, extern Node *pull_up_subqueries(PlannerInfo *root, Node *jtnode,
bool below_outer_join, bool append_rel_member); bool below_outer_join, bool append_rel_member);
extern void reduce_outer_joins(PlannerInfo *root); extern void reduce_outer_joins(PlannerInfo *root);
extern Relids get_relids_in_jointree(Node *jtnode); extern Relids get_relids_in_jointree(Node *jtnode, bool include_joins);
extern Relids get_relids_for_join(PlannerInfo *root, int joinrelid); extern Relids get_relids_for_join(PlannerInfo *root, int joinrelid);
/* /*
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/optimizer/subselect.h,v 1.32 2008/08/14 18:48:00 tgl Exp $ * $PostgreSQL: pgsql/src/include/optimizer/subselect.h,v 1.33 2008/08/17 01:20:00 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -15,9 +15,13 @@ ...@@ -15,9 +15,13 @@
#include "nodes/plannodes.h" #include "nodes/plannodes.h"
#include "nodes/relation.h" #include "nodes/relation.h"
extern Node *convert_ANY_sublink_to_join(PlannerInfo *root, SubLink *sublink); extern bool convert_ANY_sublink_to_join(PlannerInfo *root, SubLink *sublink,
extern Node *convert_EXISTS_sublink_to_join(PlannerInfo *root, Relids available_rels,
SubLink *sublink, bool under_not); Node **new_qual, List **fromlist);
extern bool convert_EXISTS_sublink_to_join(PlannerInfo *root, SubLink *sublink,
bool under_not,
Relids available_rels,
Node **new_qual, List **fromlist);
extern Node *SS_replace_correlation_vars(PlannerInfo *root, Node *expr); extern Node *SS_replace_correlation_vars(PlannerInfo *root, Node *expr);
extern Node *SS_process_sublinks(PlannerInfo *root, Node *expr, bool isQual); extern Node *SS_process_sublinks(PlannerInfo *root, Node *expr, bool isQual);
extern void SS_finalize_plan(PlannerInfo *root, Plan *plan, extern void SS_finalize_plan(PlannerInfo *root, Plan *plan,
......
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