diff options
author | Etsuro Fujita <efujita@postgresql.org> | 2023-07-28 15:45:08 +0900 |
---|---|---|
committer | Etsuro Fujita <efujita@postgresql.org> | 2023-07-28 15:45:08 +0900 |
commit | 9edf72aa76441716ce62d1f1787988e160da8115 (patch) | |
tree | e7d773d1274cb0d1393d7ea6e37333372b926342 /src/backend/optimizer/path/joinpath.c | |
parent | 0660f74e861d0dc942af3e0b5f88cb2f0c72aee5 (diff) | |
download | postgresql-9edf72aa76441716ce62d1f1787988e160da8115.tar.gz postgresql-9edf72aa76441716ce62d1f1787988e160da8115.zip |
Disallow replacing joins with scans in problematic cases.
Commit e7cb7ee14, which introduced the infrastructure for FDWs and
custom scan providers to replace joins with scans, failed to add support
handling of pseudoconstant quals assigned to replaced joins in
createplan.c, leading to an incorrect plan without a gating Result node
when postgres_fdw replaced a join with such a qual.
To fix, we could add the support by 1) modifying the ForeignPath and
CustomPath structs to store the list of RestrictInfo nodes to apply to
the join, as in JoinPaths, if they represent foreign and custom scans
replacing a join with a scan, and by 2) modifying create_scan_plan() in
createplan.c to use that list in that case, instead of the
baserestrictinfo list, to get pseudoconstant quals assigned to the join;
but #1 would cause an ABI break. So fix by modifying the infrastructure
to just disallow replacing joins with such quals.
Back-patch to all supported branches.
Reported by Nishant Sharma. Patch by me, reviewed by Nishant Sharma and
Richard Guo.
Discussion: https://postgr.es/m/CADrsxdbcN1vejBaf8a%2BQhrZY5PXL-04mCd4GDu6qm6FigDZd6Q%40mail.gmail.com
Diffstat (limited to 'src/backend/optimizer/path/joinpath.c')
-rw-r--r-- | src/backend/optimizer/path/joinpath.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c index c49c58289df..04429770df8 100644 --- a/src/backend/optimizer/path/joinpath.c +++ b/src/backend/optimizer/path/joinpath.c @@ -22,6 +22,7 @@ #include "optimizer/pathnode.h" #include "optimizer/paths.h" #include "optimizer/planmain.h" +#include "optimizer/restrictinfo.h" /* Hook for plugins to get control in add_paths_to_joinrel() */ set_join_pathlist_hook_type set_join_pathlist_hook = NULL; @@ -124,6 +125,7 @@ add_paths_to_joinrel(PlannerInfo *root, { JoinPathExtraData extra; bool mergejoin_allowed = true; + bool consider_join_pushdown = false; ListCell *lc; Relids joinrelids; @@ -308,12 +310,24 @@ 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) + joinrel->fdwroutine->GetForeignJoinPaths && + consider_join_pushdown) joinrel->fdwroutine->GetForeignJoinPaths(root, joinrel, outerrel, innerrel, jointype, &extra); @@ -321,7 +335,8 @@ add_paths_to_joinrel(PlannerInfo *root, /* * 6. Finally, give extensions a chance to manipulate the path list. */ - if (set_join_pathlist_hook) + if (set_join_pathlist_hook && + consider_join_pushdown) set_join_pathlist_hook(root, joinrel, outerrel, innerrel, jointype, &extra); } |