Status

Simon Riggs proposed a patch to implement MERGE in 2017, as part of the Postgres v11 release cycle. See the dedicated wiki page for details of that.

Description

MERGE is typically used to merge two tables, and was introduced in the 2003 SQL standard. The REPLACE statement (a MySQL extension) or UPSERT sequence attempts an UPDATE, or on failure, INSERT. This is similar to UPDATE, then for unmatched rows, INSERT. Whether concurrent access allows modifications which could cause row loss is implementation independent.

To implement this cleanly requires that the table have a unique index so duplicate checking can be easily performed. It is possible to do it without a unique index if we require the user to LOCK the table before the MERGE.

Likely Implementation Order

Due to the way this feature needs to be implemented internally, the following is the likely sequence in which this feature will be built:

PostgreSQL doesn't have a good way to lock access to a key value that doesn't exist yet--what other databases call key range locking (SQL Server for example). Improvements to the index implementation are needed to allow this feature.

Add a subset of MERGE support sufficient to implement REPLACE/UPSERT. The full MERGE feature set is a bit broader than this.

Document how to use the new MERGE feature in lieu of REPLACE/UPSERT, to make transitions easier for users of other databases. Actually adding other vendor's non-standard syntax to make other apps work transparently is unlikely to be accepted as a patch.