I need a query to update a row in table, but if the id doesn't exist it inserts default values. Also it has to avoid threads race conditions.
I found an answer here that should be fine https://stackoverflow.com/a/7927957/8372336
Using this query:
UPDATE tbl x
SET tbl_id = 24
, name = 'New Gal'
FROM (SELECT tbl_id, name FROM tbl WHERE tbl_id = 4 FOR UPDATE) y
WHERE x.tbl_id = y.tbl_id
RETURNING y.tbl_id AS old_id, y.name AS old_name, x.tbl_id, x.name;
So I think it should return old values after updating and it should prevent threads race conditions.
But I need to add an insert if the row doesn't exist and also return the inserted values this time (old values doesn't make sense because they didn't exist).
So basically I need to do something like
INSERT INTO tbl
(...) VALUES (...)
RETURNING ..., ...
ON CONFLICT DO
UPDATE tbl x
SET tbl_id = 24
, name = 'New Gal'
FROM (SELECT tbl_id, name FROM tbl WHERE tbl_id = 4 FOR UPDATE) y
WHERE x.tbl_id = y.tbl_id
RETURNING y.tbl_id AS old_id, y.name AS old_name, x.tbl_id, x.name;
but i'm not sure if something like this could work. how can i make it work and make it sure of race conditions?