mirror of
https://github.com/postgres/postgres.git
synced 2025-12-22 17:42:17 +03:00
Add support for INSERT ... ON CONFLICT DO NOTHING/UPDATE.
The newly added ON CONFLICT clause allows to specify an alternative to
raising a unique or exclusion constraint violation error when inserting.
ON CONFLICT refers to constraints that can either be specified using a
inference clause (by specifying the columns of a unique constraint) or
by naming a unique or exclusion constraint. DO NOTHING avoids the
constraint violation, without touching the pre-existing row. DO UPDATE
SET ... [WHERE ...] updates the pre-existing tuple, and has access to
both the tuple proposed for insertion and the existing tuple; the
optional WHERE clause can be used to prevent an update from being
executed. The UPDATE SET and WHERE clauses have access to the tuple
proposed for insertion using the "magic" EXCLUDED alias, and to the
pre-existing tuple using the table name or its alias.
This feature is often referred to as upsert.
This is implemented using a new infrastructure called "speculative
insertion". It is an optimistic variant of regular insertion that first
does a pre-check for existing tuples and then attempts an insert. If a
violating tuple was inserted concurrently, the speculatively inserted
tuple is deleted and a new attempt is made. If the pre-check finds a
matching tuple the alternative DO NOTHING or DO UPDATE action is taken.
If the insertion succeeds without detecting a conflict, the tuple is
deemed inserted.
To handle the possible ambiguity between the excluded alias and a table
named excluded, and for convenience with long relation names, INSERT
INTO now can alias its target table.
Bumps catversion as stored rules change.
Author: Peter Geoghegan, with significant contributions from Heikki
Linnakangas and Andres Freund. Testing infrastructure by Jeff Janes.
Reviewed-By: Heikki Linnakangas, Andres Freund, Robert Haas, Simon Riggs,
Dean Rasheed, Stephen Frost and many others.
This commit is contained in:
@@ -78,11 +78,13 @@ CREATE POLICY <replaceable class="parameter">name</replaceable> ON <replaceable
|
||||
Policies can be applied for specific commands or for specific roles. The
|
||||
default for newly created policies is that they apply for all commands and
|
||||
roles, unless otherwise specified. If multiple policies apply to a given
|
||||
query, they will be combined using OR. Further, for commands which can have
|
||||
both USING and WITH CHECK policies (ALL and UPDATE), if no WITH CHECK policy
|
||||
is defined then the USING policy will be used for both what rows are visible
|
||||
(normal USING case) and which rows will be allowed to be added (WITH CHECK
|
||||
case).
|
||||
query, they will be combined using OR (although <literal>ON CONFLICT DO
|
||||
UPDATE</> and <literal>INSERT</> policies are not combined in this way, but
|
||||
rather enforced as noted at each stage of <literal>ON CONFLICT</> execution).
|
||||
Further, for commands which can have both USING and WITH CHECK policies (ALL
|
||||
and UPDATE), if no WITH CHECK policy is defined then the USING policy will be
|
||||
used for both what rows are visible (normal USING case) and which rows will
|
||||
be allowed to be added (WITH CHECK case).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@@ -263,6 +265,12 @@ CREATE POLICY <replaceable class="parameter">name</replaceable> ON <replaceable
|
||||
as it only ever applies in cases where records are being added to the
|
||||
relation.
|
||||
</para>
|
||||
<para>
|
||||
Note that <literal>INSERT</literal> with <literal>ON CONFLICT DO
|
||||
UPDATE</literal> requires that any <literal>INSERT</literal> policy
|
||||
WITH CHECK expression passes for any rows appended to the relation by
|
||||
the INSERT path only.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
@@ -271,22 +279,39 @@ CREATE POLICY <replaceable class="parameter">name</replaceable> ON <replaceable
|
||||
<listitem>
|
||||
<para>
|
||||
Using <literal>UPDATE</literal> for a policy means that it will apply
|
||||
to <literal>UPDATE</literal> commands. As <literal>UPDATE</literal>
|
||||
involves pulling an existing record and then making changes to some
|
||||
portion (but possibly not all) of the record, the
|
||||
<literal>UPDATE</literal> policy accepts both a USING expression and
|
||||
a WITH CHECK expression. The USING expression will be used to
|
||||
determine which records the <literal>UPDATE</literal> command will
|
||||
see to operate against, while the <literal>WITH CHECK</literal>
|
||||
expression defines what rows are allowed to be added back into the
|
||||
relation (similar to the <literal>INSERT</literal> policy).
|
||||
Any rows whose resulting values do not pass the
|
||||
<literal>WITH CHECK</literal> expression will cause an ERROR and the
|
||||
entire command will be aborted. Note that if only a
|
||||
<literal>USING</literal> clause is specified then that clause will be
|
||||
used for both <literal>USING</literal> and
|
||||
to <literal>UPDATE</literal> commands (or auxiliary <literal>ON
|
||||
CONFLICT DO UPDATE</literal> clauses of <literal>INSERT</literal>
|
||||
commands). As <literal>UPDATE</literal> involves pulling an existing
|
||||
record and then making changes to some portion (but possibly not all)
|
||||
of the record, the <literal>UPDATE</literal> policy accepts both a
|
||||
<literal>USING</literal> expression and a <literal>WITH CHECK</literal>
|
||||
expression. The <literal>USING</literal> expression will be used to
|
||||
determine which records the <literal>UPDATE</literal> command will see
|
||||
to operate against, while the <literal>WITH CHECK</literal> expression
|
||||
defines what rows are allowed to be added back into the relation
|
||||
(similar to the <literal>INSERT</literal> policy). Any rows whose
|
||||
resulting values do not pass the <literal>WITH CHECK</literal>
|
||||
expression will cause an ERROR and the entire command will be aborted.
|
||||
Note that if only a <literal>USING</literal> clause is specified then
|
||||
that clause will be used for both <literal>USING</literal> and
|
||||
<literal>WITH CHECK</literal> cases.
|
||||
</para>
|
||||
<para>
|
||||
Note, however, that <literal>INSERT</literal> with <literal>ON CONFLICT
|
||||
DO UPDATE</literal> requires that an <literal>UPDATE</literal> policy
|
||||
<literal>USING</literal> expression always be enforced as a
|
||||
<literal>WITH CHECK</literal> expression. This
|
||||
<literal>UPDATE</literal> policy must always pass when the
|
||||
<literal>UPDATE</literal> path is taken. Any existing row that
|
||||
necessitates that the <literal>UPDATE</literal> path be taken must pass
|
||||
the (UPDATE or ALL) <literal>USING</literal> qualifications (combined
|
||||
using <literal>OR</literal>), which are always enforced as WTIH CHECK
|
||||
options in this context (the <literal>UPDATE</literal> path will
|
||||
<emphasis>never</> be silently avoided; an error will be thrown
|
||||
instead). Finally, the final row appended to the relation must pass
|
||||
any <literal>WITH CHECK</literal> options that a conventional
|
||||
<literal>UPDATE</literal> is required to pass.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user