From: | Andy Fan <zhihui(dot)fan1213(at)gmail(dot)com> |
---|---|
To: | pgsql-hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Question about pull_up_sublinks_qual_recurse |
Date: | 2022-10-13 08:45:31 |
Message-ID: | CAKU4AWq0d=b+GqpH7fr5C8jT1e6-RndcFPXdxOLuOy1=kHbkTQ@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
Hi:
When I was working on another task, the following case caught my mind.
create table t1(a int, b int, c int);
create table t2(a int, b int, c int);
create table t3(a int, b int, c int);
explain (costs off) select * from t1
where exists (select 1 from t2
where exists (select 1 from t3
where t3.c = t1.c
and t2.b = t3.b)
and t2.a = t1.a);
I got the plan like this:
QUERY PLAN
-----------------------------------
Hash Semi Join
Hash Cond: (t1.a = t2.a)
Join Filter: (hashed SubPlan 2)
-> Seq Scan on t1
-> Hash
-> Seq Scan on t2
SubPlan 2
-> Seq Scan on t3
(8 rows)
Note we CAN'T pull up the inner sublink which produced the SubPlan 2.
I traced the reason is after we pull up the outer sublink, we got:
select * from t1 semi join t2 on t2.a = t1.a AND
exists (select 1 from t3
where t3.c = t1.c
and t2.b = t3.b);
Later we tried to pull up the EXISTS sublink to t1 OR t2 *separately*, since
this subselect referenced to t1 *AND* t2, so we CAN'T pull up the sublink. I
am thinking why we have to pull up it t1 OR t2 rather than JoinExpr(t1, t2),
I think the latter one is better.
So I changed the code like this, I got the plan I wanted and 'make
installcheck' didn't find any exception.
QUERY PLAN
------------------------------------------------
Hash Semi Join
Hash Cond: ((t2.b = t3.b) AND (t1.c = t3.c))
-> Hash Semi Join
Hash Cond: (t1.a = t2.a)
-> Seq Scan on t1
-> Hash
-> Seq Scan on t2
-> Hash
-> Seq Scan on t3
(9 rows)
@@ -553,10 +553,10 @@ pull_up_sublinks_qual_recurse(PlannerInfo *root, Node
*node,
*/
j->quals = pull_up_sublinks_qual_recurse(root,
j->quals,
- &j->larg,
- available_rels1,
- &j->rarg,
- child_rels);
+ jtlink1,
+ bms_union(available_rels1, child_rels),
+ NULL,
+ NULL);
/* Return NULL representing constant TRUE */
return NULL;
}
Any feedback is welcome.
--
Best Regards
Andy Fan
From | Date | Subject | |
---|---|---|---|
Next Message | Dmitry Koval | 2022-10-13 08:57:33 | Re: Add SPLIT PARTITION/MERGE PARTITIONS commands |
Previous Message | Peter Eisentraut | 2022-10-13 08:33:01 | libpq support for NegotiateProtocolVersion |