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



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