1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-27 12:41:57 +03:00

Store tuples for EvalPlanQual in slots, rather than as HeapTuples.

For the upcoming pluggable table access methods it's quite
inconvenient to store tuples as HeapTuples, as that'd require
converting tuples from a their native format into HeapTuples. Instead
use slots to manage epq tuples.

To fit into that scheme, change the foreign data wrapper callback
RefetchForeignRow, to store the tuple in a slot. Insist on using the
caller provided slot, so it conveniently can be stored in the
corresponding EPQ slot.  As there is no in core user of
RefetchForeignRow, that change was done blindly, but we plan to test
that soon.

To avoid duplicating that work for row locks, move row locks to just
directly use the EPQ slots - it previously temporarily stored tuples
in LockRowsState.lr_curtuples, but that doesn't seem beneficial, given
we'd possibly end up with a significant number of additional slots.

The behaviour of es_epqTupleSet[rti -1] is now checked by
es_epqTupleSlot[rti -1] != NULL, as that is distinguishable from a
slot containing an empty tuple.

Author: Andres Freund, Haribabu Kommi, Ashutosh Bapat
Discussion: https://postgr.es/m/20180703070645.wchpu5muyto5n647@alap3.anarazel.de
This commit is contained in:
Andres Freund
2019-03-01 10:37:57 -08:00
parent 6cbdbd9e8d
commit ad0bda5d24
13 changed files with 189 additions and 213 deletions

View File

@ -992,29 +992,31 @@ GetForeignRowMarkType(RangeTblEntry *rte,
<para>
<programlisting>
HeapTuple
void
RefetchForeignRow(EState *estate,
ExecRowMark *erm,
Datum rowid,
TupleTableSlot *slot,
bool *updated);
</programlisting>
Re-fetch one tuple from the foreign table, after locking it if required.
Re-fetch one tuple slot from the foreign table, after locking it if required.
<literal>estate</literal> is global execution state for the query.
<literal>erm</literal> is the <structname>ExecRowMark</structname> struct describing
the target foreign table and the row lock type (if any) to acquire.
<literal>rowid</literal> identifies the tuple to be fetched.
<literal>updated</literal> is an output parameter.
<literal>slot</literal> contains nothing useful upon call, but can be used to
hold the returned tuple. <literal>updated</literal> is an output parameter.
</para>
<para>
This function should return a palloc'ed copy of the fetched tuple,
or <literal>NULL</literal> if the row lock couldn't be obtained. The row lock
type to acquire is defined by <literal>erm-&gt;markType</literal>, which is the
value previously returned by <function>GetForeignRowMarkType</function>.
(<literal>ROW_MARK_REFERENCE</literal> means to just re-fetch the tuple without
acquiring any lock, and <literal>ROW_MARK_COPY</literal> will never be seen by
this routine.)
This function should store the tuple into the provided, or clear it if if
the row lock couldn't be obtained. The row lock type to acquire is
defined by <literal>erm-&gt;markType</literal>, which is the value
previously returned by <function>GetForeignRowMarkType</function>.
(<literal>ROW_MARK_REFERENCE</literal> means to just re-fetch the tuple
without acquiring any lock, and <literal>ROW_MARK_COPY</literal> will
never be seen by this routine.)
</para>
<para>
@ -1026,7 +1028,7 @@ RefetchForeignRow(EState *estate,
<para>
Note that by default, failure to acquire a row lock should result in
raising an error; a <literal>NULL</literal> return is only appropriate if
raising an error; returning with an empty slot is only appropriate if
the <literal>SKIP LOCKED</literal> option is specified
by <literal>erm-&gt;waitPolicy</literal>.
</para>