4

I am doing an INSERT with ON CONFLICT to postgres using java. Is there any way to find out if the executeUpdate inserted the row or updated it?

Rob Johansen
  • 4,816
  • 8
  • 38
  • 69
safyia
  • 170
  • 1
  • 11
  • 1
    See [Postres upsert: distinguish between new and updated rows](http://stackoverflow.com/a/38614358/1995738). – klin Nov 30 '16 at 01:30
  • Unfortunately I can not edit the existing table, so that would not solve the problem. – safyia Nov 30 '16 at 01:35
  • If you're not updating on conflict (i.e. `DO NOTHING`) you can just check the updated row count. It will be 0 if there was a conflict. – teppic Nov 30 '16 at 04:14

1 Answers1

12

You can look at the system column xmax to tell the difference. It's 0 for inserted rows in this case.

CREATE TABLE tbl(id int PRIMARY KEY, col int);
INSERT INTO tbl VALUES (1, 1);
INSERT INTO tbl(id, col)
VALUES (1,11), (2,22)
ON     CONFLICT (id) DO UPDATE
SET    col = EXCLUDED.col
RETURNING *, (xmax = 0) AS inserted;

This is building on an undocumented implementation detail that might change in future releases (even if unlikely). It works for Postgres 9.5 and 9.6.

The beauty of it: you do not need to introduce additional columns.

Detailed explanation:

Erwin Brandstetter
  • 539,169
  • 125
  • 977
  • 1,137