UPSERT oznacza "wstaw lub zaktualizuj, jeśli już istnieje". PostgreSQL realizuje to za pomocą INSERT ... ON CONFLICT — wstaw wiersz, ale jeśli naruszałby on ograniczenie unikalności, zamiast tego zaktualizuj istniejący wiersz (albo nie rób nic). Obsługuje to atomowo powszechną potrzebę typu "wstaw lub zaktualizuj".
Problem, który rozwiązuje UPSERT
You want to insert a row, but it might already exist (by a unique key):
❌ a plain INSERT fails with a unique-violation error if it exists
❌ check-then-insert (SELECT, then INSERT or UPDATE) has a RACE CONDITION
(another transaction could insert between your check and insert)
→ ON CONFLICT does it atomically in ONE statement (no race condition)
