CREATE FUNCTION skip_update() RETURNS trigger AS $$ BEGIN RETURN NULL; END; $$ LANGUAGE plpgsql; CREATE FUNCTION fail_update() RETURNS trigger AS $$ BEGIN RAISE EXCEPTION 'can''t modify row values for existing primary key'; END; $$ LANGUAGE plpgsql; CREATE TABLE Dummy_Test ( Timestamp TIMESTAMP WITH TIME ZONE PRIMARY KEY, Foo TEXT, Bar TEXT ); CREATE TRIGGER Dummy_Test_dupe BEFORE UPDATE ON Dummy_Test FOR EACH ROW WHEN ( OLD.Timestamp IS NOT DISTINCT FROM NEW.Timestamp AND OLD.Foo IS NOT DISTINCT FROM NEW.Foo AND OLD.Bar IS NOT DISTINCT FROM NEW.Bar ) EXECUTE FUNCTION skip_update(); CREATE TRIGGER Dummy_Test_modify BEFORE UPDATE ON Dummy_Test FOR EACH ROW WHEN ( OLD.Foo IS DISTINCT FROM NEW.Foo OR OLD.Bar IS DISTINCT FROM NEW.Bar ) EXECUTE FUNCTION fail_update(); INSERT INTO Dummy_Test (Timestamp,Foo,Bar) VALUES ('2020-01-02 12:34','Hello','World') ON CONFLICT ON CONSTRAINT Dummy_Test_pkey DO UPDATE SET Foo=EXCLUDED.Foo, Bar=EXCLUDED.Bar; INSERT INTO Dummy_Test (Timestamp,Foo,Bar) VALUES ('2020-01-02 12:34','Hello','World') ON CONFLICT ON CONSTRAINT Dummy_Test_pkey DO UPDATE SET Foo=EXCLUDED.Foo, Bar=EXCLUDED.Bar; INSERT INTO Dummy_Test (Timestamp,Foo,Bar) VALUES ('2020-01-02 12:34','Hello','abcde') ON CONFLICT ON CONSTRAINT Dummy_Test_pkey DO UPDATE SET Foo=EXCLUDED.Foo, Bar=EXCLUDED.Bar;