> On Tue, Oct 20, 2015 at 12:39 PM, Etsuro Fujita
> <fujita.ets...@lab.ntt.co.jp> wrote:
> > Sorry, my explanation was not correct.  (Needed to take in caffeine.) What
> > I'm concerned about is the following:
> >
> > SELECT * FROM localtab JOIN (ft1 LEFT JOIN ft2 ON ft1.x = ft2.x) ON
> > localtab.id = ft1.id FOR UPDATE OF ft1
> >
> > LockRows
> > -> Nested Loop
> >      Join Filter: (localtab.id = ft1.id)
> >      -> Seq Scan on localtab
> >      -> Foreign Scan on <ft1, ft2>
> >           Remote SQL: SELECT * FROM ft1 LEFT JOIN ft2 WHERE ft1.x = ft2.x
> > FOR UPDATE OF ft1
> >
> > Assume that ft1 performs late row locking.
> 
> If the SQL includes "FOR UPDATE of ft1", then it clearly performs
> early row locking.  I assume you meant to omit that.
> 
> > If an EPQ recheck was invoked
> > due to a concurrent transaction on the remote server that changed only the
> > value x of the ft1 tuple previously retrieved, then we would have to
> > generate a fake ft1/ft2-join tuple with nulls for ft2. (Assume that the ft2
> > tuple previously retrieved was not a null tuple.) However, I'm not sure how
> > we can do that in ForeignRecheck; we can't know for example, which one is
> > outer and which one is inner, without an alternative local join execution
> > plan.  Maybe I'm missing something, though.
> 
> I would expect it to issue a new query like: SELECT * FROM ft1 LEFT
> JOIN ft2 WHERE ft1.x = ft2.x AND ft1.tid = $0 AND ft2.tid = $1.
> 
> This should be significantly more efficient than fetching the base
> rows from each of two tables with two separate queries.
>
In this case, the EPQ slot to store the joined tuple is still
a challenge to be solved.

Is it possible to use one or any of EPQ slots that are setup for
base relations but represented by ForeignScan/CustomScan?
In case when ForeignScan run a remote join that involves three
base foreign tables (relid=2, 3, 5 for example), for example,
no other code touches this slot. So, it is safe even if we put
a joined tuple on EPQ slots of underlying base relations.

In this case, EPQ slots are initialized as below:

  es_epqTuple[0] ... EPQ tuple of base relation (relid=1)
  es_epqTuple[1] ... EPQ of the joined tuple (for relis=2, 3 5)
  es_epqTuple[2] ... EPQ of the joined tuple (for relis=2, 3 5), copy of above
  es_epqTuple[3] ... EPQ tuple of base relation (relid=4)
  es_epqTuple[4] ... EPQ of the joined tuple (for relis=2, 3 5), copy of above
  es_epqTuple[5] ... EPQ tuple of base relation (relid=6)

Also, FDW/CSP shall be responsible to return a joined tuple
as a result for whole-row reference of underlying base relation.
(One other challenge is how to handle the case when user explicitly
required a whole-row reference...Hmm...)

Then, if FDW/CSP is designed to utilize the preliminary joined
tuples rather than local join, it can just raise the tuple kept
in one of the EPQ slots for underlying base relations.
If FDW/CSP prefers local join, it can perform as like local join
doing; check join condition and construct a joined tuple by itself
or by alternative plan.

Thanks,
--
NEC Business Creation Division / PG-Strom Project
KaiGai Kohei <kai...@ak.jp.nec.com>


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to