Re: Foreign join pushdown vs EvalPlanQual

From: Etsuro Fujita <fujita(dot)etsuro(at)lab(dot)ntt(dot)co(dot)jp>
To: Kouhei Kaigai <kaigai(at)ak(dot)jp(dot)nec(dot)com>, Robert Haas <robertmhaas(at)gmail(dot)com>
Cc: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Kyotaro HORIGUCHI <horiguchi(dot)kyotaro(at)lab(dot)ntt(dot)co(dot)jp>, "pgsql-hackers(at)postgresql(dot)org" <pgsql-hackers(at)postgresql(dot)org>, Shigeru Hanada <shigeru(dot)hanada(at)gmail(dot)com>
Subject: Re: Foreign join pushdown vs EvalPlanQual
Date: 2015-10-20 10:39:15
Message-ID: 562619D3.7000703@lab.ntt.co.jp
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

>>> On Mon, Oct 19, 2015 at 3:45 AM, Etsuro Fujita
>>> <fujita(dot)etsuro(at)lab(dot)ntt(dot)co(dot)jp> wrote:
>>>> As Tom mentioned, just recomputing the original join tuple is not good
>>>> enough. We would need to rejoin the test tuples for the baserels even if
>>>> ROW_MARK_COPY is in use. Consider:
>>>>
>>>> A=# BEGIN;
>>>> A=# UPDATE t SET a = a + 1 WHERE b = 1;
>>>> B=# SELECT * from t, ft1, ft2
>>>> WHERE t.a = ft1.a AND t.b = ft2.b AND ft1.c = ft2.c FOR UPDATE;
>>>> A=# COMMIT;
>>>>
>>>> where the plan for the SELECT FOR UPDATE is
>>>>
>>>> LockRows
>>>> -> Nested Loop
>>>> -> Seq Scan on t
>>>> -> Foreign Scan on <ft1, ft2>
>>>> Remote SQL: SELECT * FROM ft1 JOIN ft2 WHERE ft1.c = ft2.c AND ft1.a
>>>> = $1 AND ft2.b = $2
>>>>
>>>> If an EPQ recheck is invoked by the A's UPDATE, just recomputing the
>>>> original join tuple from the whole-row image that you proposed would output
>>>> an incorrect result in the EQP recheck since the value a in the updated
>>>> version of a to-be-joined tuple in t would no longer match the value ft1.a
>>>> extracted from the whole-row image if the A's UPDATE has committed
>>>> successfully. So I think we would need to rejoin the tuples populated from
>>>> the whole-row images for the baserels ft1 and ft2, by executing the
>>>> secondary plan with the new parameter values for a and b.

Robert Haas wrote:
>>> No. You just need to populate fdw_recheck_quals correctly, same as
>>> for the scan case.

I wrote:
>> Yeah, I think we can probably do that for the case where a pushed-down
>> join clause is an inner-join one, but I'm not sure that we can do that
>> for the case where that clause is an outer-join one. Maybe I'm missing
>> something, though.

On 2015/10/20 15:42, Kouhei Kaigai wrote:
> Please check my message yesterday. The non-nullable side of outer-join is
> always visible regardless of the join-clause pushed down, as long as it
> satisfies the scan-quals pushed-down.

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 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.

Best regards,
Etsuro Fujita

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Beena Emerson 2015-10-20 11:10:08 Re: Support for N synchronous standby servers - take 2
Previous Message David Rowley 2015-10-20 10:23:18 Re: Parallel Aggregate