How to convert UPDATE operation into INSERT using triggers
This is not very complicated to do. If a BEFORE trigger returns a NULL value, this prevents the UPDATE from taking place. 

So in the trigger function you can check the conditions if an UPDATE is allowed. If not, Run an UPDATE statement that marks the row as inactive and do an INSERT.

Something along the lines (not tested!):

create or replace function prevent_update() 
  returns trigger
as
$$
begin
   -- adjust this check to whatever you want to prevent
   -- but make sure to only enter this part if the status is not inactive.
   -- you might want to check pg_trigger_depth() as well to make sure you never create an endless loop
   if old is distinct from new and new.status &lt;&gt; 'inactive' then 

     -- The row was changed, but status column is the same, so we want to mark 
     -- the row as inactive 

     -- Because the new status is 'inactive' the trigger that is now fired for this UPDATE statement
     -- will not do anything because we only do this for status other than 'inactive'
     UPDATE the_table
       SET status = 'inactive'
     WHERE id = new.id; --&lt;&lt; the primary key column

     INSERT INTO the_table (id, some_column, status)
     VALUES (default, new.some_column, 'active');

     -- do NOT proceed with original UPDATE
     return null; 
   end if;

   -- all OK, proceed with the update
   return new;
end;
$$
language plpgsql;


And the trigger definition:

create trigger prevent_update_trigger
   before update on the_table
   for each row execute procedure prevent_update();




I would be very careful to deploy something like this. This kind of "magic" in the background might be the cause of a lot of confusion and trouble, so use with care!