diff options
author | Alexander Korotkov | 2024-02-15 10:05:52 +0000 |
---|---|---|
committer | Alexander Korotkov | 2024-02-15 10:06:12 +0000 |
commit | 9f133763961e280d8ba692bcad0b061b861e9138 (patch) | |
tree | af76ca54ac251b87aefae347d586e6b300df3c8e /src/backend | |
parent | 995d400ceca3e552f84fe19f150fb03327bdc0c2 (diff) |
Pull up ANY-SUBLINK with the necessary lateral support.
For ANY-SUBLINK, we adopted a two-stage pull-up approach to handle
different types of scenarios. In the first stage, the sublink is pulled up
as a subquery. Because of this, when writing this code, we did not have
the ability to perform lateral joins, and therefore, we were unable to
pull up Var with varlevelsup=1. Now that we have the ability to use
lateral joins, we can eliminate this limitation.
Author: Andy Fan <zhihui.fan1213@gmail.com>
Author: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Richard Guo <guofenglinux@gmail.com>
Reviewed-by: Alena Rybakina <lena.ribackina@yandex.ru>
Reviewed-by: Andrey Lepikhov <a.lepikhov@postgrespro.ru>
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/optimizer/plan/subselect.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c index 3115d79ad98..47e14723d2b 100644 --- a/src/backend/optimizer/plan/subselect.c +++ b/src/backend/optimizer/plan/subselect.c @@ -1278,14 +1278,23 @@ convert_ANY_sublink_to_join(PlannerInfo *root, SubLink *sublink, List *subquery_vars; Node *quals; ParseState *pstate; + Relids sub_ref_outer_relids; + bool use_lateral; Assert(sublink->subLinkType == ANY_SUBLINK); /* - * The sub-select must not refer to any Vars of the parent query. (Vars of - * higher levels should be okay, though.) + * If the sub-select refers to any Vars of the parent query, we so let's + * considering it as LATERAL. (Vars of higher levels don't matter here.) */ - if (contain_vars_of_level((Node *) subselect, 1)) + sub_ref_outer_relids = pull_varnos_of_level(NULL, (Node *) subselect, 1); + use_lateral = !bms_is_empty(sub_ref_outer_relids); + + /* + * Check that sub-select refers nothing outside of available_rels of the + * parent query. + */ + if (!bms_is_subset(sub_ref_outer_relids, available_rels)) return NULL; /* @@ -1323,7 +1332,7 @@ convert_ANY_sublink_to_join(PlannerInfo *root, SubLink *sublink, nsitem = addRangeTableEntryForSubquery(pstate, subselect, makeAlias("ANY_subquery", NIL), - false, + use_lateral, false); rte = nsitem->p_rte; parse->rtable = lappend(parse->rtable, rte); |