• Andres Freund's avatar
    tableam: Add tuple_{insert, delete, update, lock} and use. · 5db6df0c
    Andres Freund authored
    This adds new, required, table AM callbacks for insert/delete/update
    and lock_tuple. To be able to reasonably use those, the EvalPlanQual
    mechanism had to be adapted, moving more logic into the AM.
    
    Previously both delete/update/lock call-sites and the EPQ mechanism had
    to have awareness of the specific tuple format to be able to fetch the
    latest version of a tuple. Obviously that needs to be abstracted
    away. To do so, move the logic that find the latest row version into
    the AM. lock_tuple has a new flag argument,
    TUPLE_LOCK_FLAG_FIND_LAST_VERSION, that forces it to lock the last
    version, rather than the current one.  It'd have been possible to do
    so via a separate callback as well, but finding the last version
    usually also necessitates locking the newest version, making it
    sensible to combine the two. This replaces the previous use of
    EvalPlanQualFetch().  Additionally HeapTupleUpdated, which previously
    signaled either a concurrent update or delete, is now split into two,
    to avoid callers needing AM specific knowledge to differentiate.
    
    The move of finding the latest row version into tuple_lock means that
    encountering a row concurrently moved into another partition will now
    raise an error about "tuple to be locked" rather than "tuple to be
    updated/deleted" - which is accurate, as that always happens when
    locking rows. While possible slightly less helpful for users, it seems
    like an acceptable trade-off.
    
    As part of this commit HTSU_Result has been renamed to TM_Result, and
    its members been expanded to differentiated between updating and
    deleting. HeapUpdateFailureData has been renamed to TM_FailureData.
    
    The interface to speculative insertion is changed so nodeModifyTable.c
    does not have to set the speculative token itself anymore. Instead
    there's a version of tuple_insert, tuple_insert_speculative, that
    performs the speculative insertion (without requiring a flag to signal
    that fact), and the speculative insertion is either made permanent
    with table_complete_speculative(succeeded = true) or aborted with
    succeeded = false).
    
    Note that multi_insert is not yet routed through tableam, nor is
    COPY. Changing multi_insert requires changes to copy.c that are large
    enough to better be done separately.
    
    Similarly, although simpler, CREATE TABLE AS and CREATE MATERIALIZED
    VIEW are also only going to be adjusted in a later commit.
    
    Author: Andres Freund and Haribabu Kommi
    Discussion:
        https://postgr.es/m/20180703070645.wchpu5muyto5n647@alap3.anarazel.de
        https://postgr.es/m/20190313003903.nwvrxi7rw3ywhdel@alap3.anarazel.de
        https://postgr.es/m/20160812231527.GA690404@alvherre.pgsql
    5db6df0c
nodeModifyTable.c 82.6 KB