6

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
  • 5,076
  • 10
  • 40
  • 72
safyia
  • 190
  • 2
  • 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

17

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;

fiddle

This is building on an undocumented implementation detail that might change in future releases (even if highly unlikely). It works for Postgres 9.5 all the way up to Postgres 15.

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

Detailed explanation:

Erwin Brandstetter
  • 605,456
  • 145
  • 1,078
  • 1,228