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