mirror of
https://github.com/postgres/postgres.git
synced 2025-09-11 00:12:06 +03:00
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>
This commit is contained in:
@@ -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);
|
||||
|
Reference in New Issue
Block a user