Question about pull_up_sublinks_qual_recurse - Mailing list pgsql-hackers

From Andy Fan
Subject Question about pull_up_sublinks_qual_recurse
Date
Msg-id CAKU4AWq0d=b+GqpH7fr5C8jT1e6-RndcFPXdxOLuOy1=kHbkTQ@mail.gmail.com
Whole thread Raw
Responses Re: Question about pull_up_sublinks_qual_recurse  (Andy Fan <zhihui.fan1213@gmail.com>)
List 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

pgsql-hackers by date:

Previous
From: Peter Eisentraut
Date:
Subject: libpq support for NegotiateProtocolVersion
Next
From: Dmitry Koval
Date:
Subject: Re: Add SPLIT PARTITION/MERGE PARTITIONS commands