diff options
author | Alexander Korotkov <akorotkov@postgresql.org> | 2025-03-25 05:49:47 +0200 |
---|---|---|
committer | Alexander Korotkov <akorotkov@postgresql.org> | 2025-03-25 05:49:47 +0200 |
commit | 023fb512755ffb64949eb6de8464c259ca70f1bd (patch) | |
tree | 4fe850ddc23984be6ddbb090b8b9c8fa49e0dcd2 /contrib/postgres_fdw/postgres_fdw.c | |
parent | adb5f85fa5a00d6d5759df55feb16dc22b0fc8d7 (diff) | |
download | postgresql-023fb512755ffb64949eb6de8464c259ca70f1bd.tar.gz postgresql-023fb512755ffb64949eb6de8464c259ca70f1bd.zip |
postgres_fdw: Avoid pulling up restrict infos from subqueries
Semi-join joins below left/right join are deparsed as
subqueries. Thus, we can't refer to subqueries vars from upper relations.
This commit avoids pulling conditions from them.
Reported-by: Robins Tharakan <tharakan@gmail.com>
Bug: #18852
Discussion: https://postgr.es/m/CAEP4nAzryLd3gwcUpFBAG9MWyDfMRX8ZjuyY2XXjyC_C6k%2B_Zw%40mail.gmail.com
Author: Alexander Pyhalov <a.pyhalov@postgrespro.ru>
Reviewed-by: Alexander Korotkov <aekorotkov@gmail.com>
Backpatch-through: 17
Diffstat (limited to 'contrib/postgres_fdw/postgres_fdw.c')
-rw-r--r-- | contrib/postgres_fdw/postgres_fdw.c | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index 6beae0fa37f..d94c4ce9fd7 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -5963,17 +5963,33 @@ foreign_join_ok(PlannerInfo *root, RelOptInfo *joinrel, JoinType jointype, break; case JOIN_LEFT: - fpinfo->joinclauses = list_concat(fpinfo->joinclauses, - fpinfo_i->remote_conds); - fpinfo->remote_conds = list_concat(fpinfo->remote_conds, - fpinfo_o->remote_conds); + + /* + * When semi-join is involved in the inner or outer part of the + * left join, it's deparsed as a subquery, and we can't refer to + * its vars on the upper level. + */ + if (bms_is_empty(fpinfo_i->hidden_subquery_rels)) + fpinfo->joinclauses = list_concat(fpinfo->joinclauses, + fpinfo_i->remote_conds); + if (bms_is_empty(fpinfo_o->hidden_subquery_rels)) + fpinfo->remote_conds = list_concat(fpinfo->remote_conds, + fpinfo_o->remote_conds); break; case JOIN_RIGHT: - fpinfo->joinclauses = list_concat(fpinfo->joinclauses, - fpinfo_o->remote_conds); - fpinfo->remote_conds = list_concat(fpinfo->remote_conds, - fpinfo_i->remote_conds); + + /* + * When semi-join is involved in the inner or outer part of the + * right join, it's deparsed as a subquery, and we can't refer to + * its vars on the upper level. + */ + if (bms_is_empty(fpinfo_o->hidden_subquery_rels)) + fpinfo->joinclauses = list_concat(fpinfo->joinclauses, + fpinfo_o->remote_conds); + if (bms_is_empty(fpinfo_i->hidden_subquery_rels)) + fpinfo->remote_conds = list_concat(fpinfo->remote_conds, + fpinfo_i->remote_conds); break; case JOIN_SEMI: |