You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This non-standard INSERT clause allows DML statement authors to specify
that in the event of each of any of the tuples being inserted
duplicating an existing tuple in terms of a value or set of values
constrained by a unique index, an alternative path may be taken. The
statement may alternatively IGNORE the tuple being inserted without
raising an error, or go to UPDATE the existing tuple whose value is
duplicated by a value within one single tuple proposed for insertion.
The implementation loops until either an insert or an UPDATE/IGNORE
occurs. No existing tuple may be affected more than once per INSERT.
This is implemented using a new infrastructure called "speculative
insertion". (The approach to "Value locking" presenting here follows
design postgres#2, as described on
https://wiki.postgresql.org/wiki/Value_locking). Alternatively, we may
go to UPDATE, using the EvalPlanQual() mechanism to execute a special
auxiliary plan.
READ COMMITTED isolation level is permitted to UPDATE a tuple even where
no version is visible to the command's MVCC snapshot. Similarly, any
query predicate associated with the UPDATE portion of the new statement
need only satisfy an already locked, conclusively committed and visible
conflict tuple. When the predicate isn't satisfied, the tuple is still
locked, which implies that at READ COMMITTED, a tuple may be locked
without any version being visible to the command's MVCC snapshot.
Users specify a single unique index to take the alternative path on,
which is inferred from a set of user-supplied column names (or
expressions). This is mandatory for the ON CONFLICT UPDATE variant,
which should address concerns about spuriously taking an incorrect
alternative ON CONFLICT path (i.e. the wrong unique index is used for
arbitration of whether or not to take the alternative path) due to there
being more than one would-be unique violation. Previous revisions of
the patch didn't mandate this. However, we may still IGNORE based on
the first would-be unique violation detected, on the assumption that it
doesn't particularly matter where it originated from for that variant
(iff the user didn't make a point of indicated his or her intent).
The auxiliary ModifyTable plan used by the UPDATE portion of the new
statement is not formally a subplan of its parent INSERT ModifyTable
plan. Rather, it's an independently planned subquery, whose execution
is tightly driven by its parent. Special auxiliary state pertaining to
the auxiliary UPDATE is tracked by its parent through all stages of
query execution.
The implementation imposes some restrictions on child auxiliary UPDATE
plans, which make the plans comport with their parent to the extent
required during the executor stage. One user-visible consequences of
this is that the special auxiliary UPDATE query cannot have subselects
within its targetlist or WHERE clause. UPDATEs may not reference any
other table, and UPDATE FROM is disallowed. INSERT's RETURNING clause
projects tuples successfully inserted (in a later commit, it is made to
project tuples inserted and updated, though).
0 commit comments