Re: support for MERGE

Alvaro Herrera <alvherre@alvh.no-ip.org>

From: Álvaro Herrera <alvherre@alvh.no-ip.org>
To: Justin Pryzby <pryzby@telsasoft.com>
Cc: Peter Eisentraut <peter.eisentraut@enterprisedb.com>, Amit Langote <amitlangote09@gmail.com>, Japin Li <japinli@hotmail.com>, Zhihong Yu <zyu@yugabyte.com>, Simon Riggs <simon.riggs@enterprisedb.com>, pgsql-hackers@lists.postgresql.org, Tomas Vondra <tomas.vondra@enterprisedb.com>, Daniel Westermann <dwe@dbi-services.com>, Erik Rijkers <er@xs4all.nl>, Jaime Casanova <jcasanov@systemguards.com.ec>, Andres Freund <andres@anarazel.de>
Date: 2022-08-01T15:30:30Z
Lists: pgsql-hackers
On 2022-Aug-01, Justin Pryzby wrote:

> On Tue, Jun 14, 2022 at 11:27:06AM +0200, Álvaro Herrera wrote:
> > @@ -448,9 +448,9 @@ COMMIT;
> >      and execute the first one that succeeds.
> >      If <command>MERGE</command> attempts an <command>INSERT</command>
> >      and a unique index is present and a duplicate row is concurrently
> > -    inserted, then a uniqueness violation is raised.
> > -    <command>MERGE</command> does not attempt to avoid the
> > -    error by executing an <command>UPDATE</command>.
> > +    inserted, then a uniqueness violation error is raised;
> > +    <command>MERGE</command> does not attempt to avoid such
> > +    errors by evaluating <literal>MATCHED</literal> conditions.
> 
> This was a portion of a chang that was committed as ffffeebf2.
> 
> But I don't understand why this changed from "does not attempt to avoid the
> error by executing an <command>UPDATE</command>." to "...by evaluating
> <literal>MATCHED</literal> conditions."
> 
> Maybe it means to say "..by re-starting evaluation of match conditions".

Yeah, my thought there is that it may also be possible that the action
that would run if the conditions are re-run is a DELETE or a WHEN
MATCHED THEN DO NOTHING; so saying "by executing an UPDATE" it leaves
out those possibilities.  IOW if we're evaluating NOT MATCHED INSERT and
we find a duplicate, we do not go back to MATCHED.  We have this comment
in ExecMerge:

     * ExecMergeMatched takes care of following the update chain and
     * re-finding the qualifying WHEN MATCHED action, as long as the updated
     * target tuple still satisfies the join quals, i.e., it remains a WHEN
     * MATCHED case. If the tuple gets deleted or the join quals fail, it
     * returns and we try ExecMergeNotMatched. Given that ExecMergeMatched
     * always make progress by following the update chain and we never switch
     * from ExecMergeNotMatched to ExecMergeMatched, there is no risk of a
     * livelock.

(Another change there is the period to semicolon.  I did that to make it
clear that the last phrase applies to only that part and not phrases
earlier in the same paragraph.)

Your proposed rewording might be a clearer way to express the same idea.

Any other opinions?

> Sorry to re-raise this 6 weeks later..

No worries.  As the Zen of Python says, now is better than never.

-- 
Álvaro Herrera               48°01'N 7°57'E  —  https://www.EnterpriseDB.com/
"All rings of power are equal,
But some rings of power are more equal than others."
                                 (George Orwell's The Lord of the Rings)



Commits

  1. Doc fixes for MERGE statement

  2. MERGE docs adjustments

  3. Link to MVCC docs in MERGE docs

  4. Fix EXPLAIN MERGE output when no tuples are processed

  5. Make EXPLAIN MERGE output format more compact

  6. Add support for MERGE SQL command

  7. Split ExecUpdate and ExecDelete into reusable pieces

  8. Add API of sorts for transition table handling in trigger.c

  9. Represent Lists as expansible arrays, not chains of cons-cells.