aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r--src/backend/optimizer/path/joinpath.c19
-rw-r--r--src/backend/optimizer/plan/createplan.c21
-rw-r--r--src/backend/optimizer/util/pathnode.c10
-rw-r--r--src/backend/optimizer/util/restrictinfo.c30
4 files changed, 32 insertions, 48 deletions
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index 059e605e04e..821d282497b 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -24,7 +24,6 @@
#include "optimizer/pathnode.h"
#include "optimizer/paths.h"
#include "optimizer/planmain.h"
-#include "optimizer/restrictinfo.h"
#include "utils/typcache.h"
/* Hook for plugins to get control in add_paths_to_joinrel() */
@@ -131,7 +130,6 @@ add_paths_to_joinrel(PlannerInfo *root,
{
JoinPathExtraData extra;
bool mergejoin_allowed = true;
- bool consider_join_pushdown = false;
ListCell *lc;
Relids joinrelids;
@@ -324,24 +322,12 @@ add_paths_to_joinrel(PlannerInfo *root,
jointype, &extra);
/*
- * createplan.c does not currently support handling of pseudoconstant
- * clauses assigned to joins pushed down by extensions; check if the
- * restrictlist has such clauses, and if so, disallow pushing down joins.
- */
- if ((joinrel->fdwroutine &&
- joinrel->fdwroutine->GetForeignJoinPaths) ||
- set_join_pathlist_hook)
- consider_join_pushdown = !has_pseudoconstant_clauses(root,
- restrictlist);
-
- /*
* 5. If inner and outer relations are foreign tables (or joins) belonging
* to the same server and assigned to the same user to check access
* permissions as, give the FDW a chance to push down joins.
*/
if (joinrel->fdwroutine &&
- joinrel->fdwroutine->GetForeignJoinPaths &&
- consider_join_pushdown)
+ joinrel->fdwroutine->GetForeignJoinPaths)
joinrel->fdwroutine->GetForeignJoinPaths(root, joinrel,
outerrel, innerrel,
jointype, &extra);
@@ -349,8 +335,7 @@ add_paths_to_joinrel(PlannerInfo *root,
/*
* 6. Finally, give extensions a chance to manipulate the path list.
*/
- if (set_join_pathlist_hook &&
- consider_join_pushdown)
+ if (set_join_pathlist_hook)
set_join_pathlist_hook(root, joinrel, outerrel, innerrel,
jointype, &extra);
}
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index af48109058d..34ca6d4ac21 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -599,8 +599,27 @@ create_scan_plan(PlannerInfo *root, Path *best_path, int flags)
* Detect whether we have any pseudoconstant quals to deal with. Then, if
* we'll need a gating Result node, it will be able to project, so there
* are no requirements on the child's tlist.
+ *
+ * If this replaces a join, it must be a foreign scan or a custom scan,
+ * and the FDW or the custom scan provider would have stored in the best
+ * path the list of RestrictInfo nodes to apply to the join; check against
+ * that list in that case.
*/
- gating_clauses = get_gating_quals(root, scan_clauses);
+ if (IS_JOIN_REL(rel))
+ {
+ List *join_clauses;
+
+ Assert(best_path->pathtype == T_ForeignScan ||
+ best_path->pathtype == T_CustomScan);
+ if (best_path->pathtype == T_ForeignScan)
+ join_clauses = ((ForeignPath *) best_path)->fdw_restrictinfo;
+ else
+ join_clauses = ((CustomPath *) best_path)->custom_restrictinfo;
+
+ gating_clauses = get_gating_quals(root, join_clauses);
+ }
+ else
+ gating_clauses = get_gating_quals(root, scan_clauses);
if (gating_clauses)
flags = 0;
diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index 754f0b9f34c..211ba65389d 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -2229,6 +2229,7 @@ create_foreignscan_path(PlannerInfo *root, RelOptInfo *rel,
List *pathkeys,
Relids required_outer,
Path *fdw_outerpath,
+ List *fdw_restrictinfo,
List *fdw_private)
{
ForeignPath *pathnode = makeNode(ForeignPath);
@@ -2250,6 +2251,7 @@ create_foreignscan_path(PlannerInfo *root, RelOptInfo *rel,
pathnode->path.pathkeys = pathkeys;
pathnode->fdw_outerpath = fdw_outerpath;
+ pathnode->fdw_restrictinfo = fdw_restrictinfo;
pathnode->fdw_private = fdw_private;
return pathnode;
@@ -2273,6 +2275,7 @@ create_foreign_join_path(PlannerInfo *root, RelOptInfo *rel,
List *pathkeys,
Relids required_outer,
Path *fdw_outerpath,
+ List *fdw_restrictinfo,
List *fdw_private)
{
ForeignPath *pathnode = makeNode(ForeignPath);
@@ -2300,6 +2303,7 @@ create_foreign_join_path(PlannerInfo *root, RelOptInfo *rel,
pathnode->path.pathkeys = pathkeys;
pathnode->fdw_outerpath = fdw_outerpath;
+ pathnode->fdw_restrictinfo = fdw_restrictinfo;
pathnode->fdw_private = fdw_private;
return pathnode;
@@ -2322,6 +2326,7 @@ create_foreign_upper_path(PlannerInfo *root, RelOptInfo *rel,
double rows, Cost startup_cost, Cost total_cost,
List *pathkeys,
Path *fdw_outerpath,
+ List *fdw_restrictinfo,
List *fdw_private)
{
ForeignPath *pathnode = makeNode(ForeignPath);
@@ -2345,6 +2350,7 @@ create_foreign_upper_path(PlannerInfo *root, RelOptInfo *rel,
pathnode->path.pathkeys = pathkeys;
pathnode->fdw_outerpath = fdw_outerpath;
+ pathnode->fdw_restrictinfo = fdw_restrictinfo;
pathnode->fdw_private = fdw_private;
return pathnode;
@@ -4149,6 +4155,8 @@ do { \
FLAT_COPY_PATH(fpath, path, ForeignPath);
if (fpath->fdw_outerpath)
REPARAMETERIZE_CHILD_PATH(fpath->fdw_outerpath);
+ if (fpath->fdw_restrictinfo)
+ ADJUST_CHILD_ATTRS(fpath->fdw_restrictinfo);
/* Hand over to FDW if needed. */
rfpc_func =
@@ -4166,6 +4174,8 @@ do { \
FLAT_COPY_PATH(cpath, path, CustomPath);
REPARAMETERIZE_CHILD_PATH_LIST(cpath->custom_paths);
+ if (cpath->custom_restrictinfo)
+ ADJUST_CHILD_ATTRS(cpath->custom_restrictinfo);
if (cpath->methods &&
cpath->methods->ReparameterizeCustomPathByChild)
cpath->custom_private =
diff --git a/src/backend/optimizer/util/restrictinfo.c b/src/backend/optimizer/util/restrictinfo.c
index c1fbbb6bfee..d6d26a2b515 100644
--- a/src/backend/optimizer/util/restrictinfo.c
+++ b/src/backend/optimizer/util/restrictinfo.c
@@ -550,36 +550,6 @@ extract_actual_join_clauses(List *restrictinfo_list,
}
/*
- * has_pseudoconstant_clauses
- *
- * Returns true if 'restrictinfo_list' includes pseudoconstant clauses.
- *
- * This is used when we determine whether to allow extensions to consider
- * pushing down joins in add_paths_to_joinrel().
- */
-bool
-has_pseudoconstant_clauses(PlannerInfo *root,
- List *restrictinfo_list)
-{
- ListCell *l;
-
- /* No need to look if we know there are no pseudoconstants */
- if (!root->hasPseudoConstantQuals)
- return false;
-
- /* See if there are pseudoconstants in the RestrictInfo list */
- foreach(l, restrictinfo_list)
- {
- RestrictInfo *rinfo = lfirst_node(RestrictInfo, l);
-
- if (rinfo->pseudoconstant &&
- !rinfo_is_constant_true(rinfo))
- return true;
- }
- return false;
-}
-
-/*
* join_clause_is_movable_to
* Test whether a join clause is a safe candidate for parameterization
* of a scan on the specified base relation.