Skip to content
Advertisement

Where clause in upsert conflict target

Suppose I have a table created like this:

When attempting to insert a new row, there are three possibilties:

  1. No row for ‘name’ exists. The new row should be inserted.
  2. A row for ‘name’ exists that has a value of NULL. The existing row should be updated with the new value.
  3. A row for ‘name ‘ exists that has a non-NULL value. The insert should fail.

I thought I should be able to use the UPSERT syntax like this:

The first command updates the existing row as expected. But the second command updates the row again, which I did not expect.

What is the where clause in the conflict target supposed to do? In my tests it doesn’t seem to matter if it evaluates to true or false.

Based on PostgreSQL Upsert with a WHERE clause I tried using a unique partial index instead of a primary key, but then I end up with multiple rows with the same name.

Advertisement

Answer

Using the second WHERE will do what you want:


The first WHERE, following the conflict column(s) is meant to select a particular partial index to use for detecting conflicts. An example to give you the feel for it:

Note the last two INSERTs in particular: The first one updates the row with a null value, and the second one generates an error because it doesn’t fully specify a unique index.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement