On Mon, Oct 19, 2015 at 3:45 AM, Etsuro Fujita
<fujita.ets...@lab.ntt.co.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=# 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;

where the plan for the SELECT FOR UPDATE is

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

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

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

Reply via email to