Re: Foreign join pushdown vs EvalPlanQual - Mailing list pgsql-hackers

From Etsuro Fujita
Subject Re: Foreign join pushdown vs EvalPlanQual
Date
Msg-id 560BA777.7020907@lab.ntt.co.jp
Whole thread Raw
In response to Re: Foreign join pushdown vs EvalPlanQual  (Kouhei Kaigai <kaigai@ak.jp.nec.com>)
List pgsql-hackers
On 2015/09/29 21:38, Kouhei Kaigai wrote:
>>> Also note that EvalPlanQualFetchRowMarks() will raise an error
>>> if RefetchForeignRow callback returned NULL tuple.
>>> Is it right or expected behavior?

>> IIUC, I think that that behavior is reasonable.

>>> It looks to me this callback is designed to pull out a particular
>>> tuple identified by the remote-row-id, regardless of the qualifier
>>> checks based on the latest value.

>> Because erm->markType==ROW_MARK_REFERENCE, I don't think that that
>> behavior would cause any problem.  Maybe I'm missing something, though.

> Really?

Yeah, I think RefetchForeignRow should work differently depending on the 
rowmark type.  When erm->markType==ROW_MARK_REFERENCE, the callback 
should fetch a particular tuple identified by the rowid (ie, the same 
version previously obtained) successfully.  So for that case, I don't 
think the remote quals need to be checked during RefetchForeignRow.

> ExecLockRows() calls EvalPlanQualFetchRowMarks() to fill up EPQ tuple
> slot prior to EvalPlanQualNext(), because these tuples are referenced
> during EPQ rechecks.
> The purpose of EvalPlanQualNext() is evaluate whether the current bunch
> of rows are visible towards the qualifiers of underlying scan/join.
> Then, if not visible, it *ignores* the current tuples, as follows.
>
>          /*
>           * Now fetch any non-locked source rows --- the EPQ logic knows how to
>           * do that.
>           */
>          EvalPlanQualSetSlot(&node->lr_epqstate, slot);
>          EvalPlanQualFetchRowMarks(&node->lr_epqstate);   <--- LOAD REMOTE ROWS
>
>          /*
>           * And finally we can re-evaluate the tuple.
>           */
>          slot = EvalPlanQualNext(&node->lr_epqstate);     <--- EVALUATE QUALIFIERS
>          if (TupIsNull(slot))
>          {
>              /* Updated tuple fails qual, so ignore it and go on */
>              goto lnext;               <-- IGNORE THE ROW, NOT RAISE AN ERROR
>          }
>
> What happen if RefetchForeignRow raise an error in case when the latest
> row exists but violated towards the "remote quals" ?
> This is the case to be ignored, unlike the case when remote row identified
> by row-id didn't exist.

IIUC, I think that that depends on where RefetchForeignRow is called 
(ie, the rowmark type).  When it is called from 
EvalPlanQualFetchRowMarks, the transaction should be aborted as I 
mentioned above, if it couldn't fetch the same version previously 
obtained.  But when RefetchForeignRow is called from ExecLockRows, the 
tuple should be just ignored as the above code, if the latest version on 
the remote side didn't satisfy the remote quals.

Best regards,
Etsuro Fujita




pgsql-hackers by date:

Previous
From:
Date:
Subject: Re: Standby server crashes in master and REL9_5_STABLE branches
Next
From: Etsuro Fujita
Date:
Subject: Re: Foreign join pushdown vs EvalPlanQual