8

I have a PostgreSQL database with a table called product. In this table I have an autoincrement column named auxId (not the table's primary key). I want to avoid any update on this column. How can this be done using a PostgreSQL trigger?

I tried:

CREATE OR REPLACE FUNCTION stop_change_on_auxId()
  RETURNS trigger AS
$BODY$
BEGIN
 IF NEW.auxId <> OLD.auxId THEN

 END IF;
 
 RETURN NEW;
END;
$BODY$

-- trigger to avoid updates on auxId
CREATE TRIGGER avoid_auxid_changes
  BEFORE UPDATE
  ON product
  FOR EACH ROW
  EXECUTE PROCEDURE stop_change_on_auxId();

but I believe this will stop the update for the whole row. I just need to avoid the update on the auxId field but allow any other update on its row.

tanius
  • 14,003
  • 3
  • 51
  • 63
Jose Cabrera Zuniga
  • 2,348
  • 3
  • 31
  • 56
  • 1
    Why not just use column level privileges for this? Like; `GRANT UPDATE(col1,col2 /* no "auxId" here*/) ON tbl TO role`. – Steve Chavez Feb 14 '23 at 19:04

2 Answers2

13

Sure, just throw an error when the column is changed:

CREATE FUNCTION noupdate() RETURNS trigger
   LANGUAGE plpgsql AS
$$BEGIN
   IF NEW.auxid <> OLD.auxid THEN
      RAISE EXCEPTION 'not allowed';
   END IF;
   RETURN NEW;
END;$$;

CREATE TRIGGER noupdate
   BEFORE UPDATE ON product FOR EACH ROW
   EXECUTE PROCEDURE noupdate();

This solution allows updates on all other columns, as long as auxid is not modified.

Laurenz Albe
  • 209,280
  • 17
  • 206
  • 263
10

If you basically want to make the auxid column immutable to the outside world, here you go:

CREATE OR REPLACE FUNCTION stop_change_on_auxId()
  RETURNS trigger AS
$BODY$
BEGIN
  -- always reset the auxId to the value already stored
  NEW.auxId := OLD.auxId;
  RETURN NEW;
END;
$BODY$


CREATE TRIGGER avoid_auxid_changes
  BEFORE UPDATE
  ON product
  FOR EACH ROW
  EXECUTE PROCEDURE stop_change_on_auxId();
Ancoron
  • 2,447
  • 1
  • 9
  • 21
  • 1
    I wouldn't recommend this solution as you can not respond in any way, could lead to a lot of debugging. If you're fine with "silent" procedures, this is okayish. – Unkn0wn0x Jan 17 '23 at 01:57