It is a bit of an oddball idea (nothing personal), but how about this:
CREATE FUNCTION not_update_but_insert() RETURNS trigger AS $$
BEGIN
INSERT INTO TG_TABLE_NAME -- Do an INSERT...
SELECT NEW.*; -- ... using the values from the row to be updated
RETURN NULL; -- Fail the UPDATE
END;
$$ LANGUAGE plpgsql;
Obviously this would not work for any table that has a PRIMARY KEY
or other UNIQUE
constraints. You do have to CREATE TRIGGER x BEFORE UPDATE
for every table this would apply to, so analyze your table structure before creating the trigger.
There is obviously a work-around - at least for the PKs based on a sequence
- by examining the information_schema
for "safe" columns in TG_TABLE_NAME
and then assembling their names into strings to splice into the INSERT
statement (column list of main statement and select list). Just leave the columns with sequences or appropriate default values out. This, however, does not address UNIQUE
constraints that have no obvious replacement (like a user name or an email address).