37
loading...
This website collects cookies to deliver better user experience
GRANT/REVOKE
:GRANT SELECT ON TABLE secret_user_data TO privileged_user;
REVOKE SELECT ON TABLE secret_user_data FROM basic_user;
GRANT ALL PRIVILEGES ON TABLE basic_user_data TO basic_user;
GRANT ALL PRIVILEGES ON TABLE users TO basic_user;
users
has an ID for sure; secret_user_data
and basic_user_data
are 1-to-1 with users via a user_id
foreign key - so do they really need their own primary key?user_id
column fully determines the row; you'd never need to query on a separate id
field. So these side tables should inherit the primary key from users
.user_id
) is overriden (imagine something likedb.secret_user_data.update({user_id: currentUser.id}, data)
data = {user_id: -5}
). Our side table entries would be orphaned from their users, and our data scrambled.CREATE OR REPLACE FUNCTION immutable_id()
RETURNS TRIGGER AS
$BODY$
BEGIN
-- Alternatively, we can just fail silently
-- NEW.id = OLD.id;
IF NEW."id" IS DISTINCT FROM OLD."id"
THEN
RAISE EXCEPTION 'Refusing to update id column';
END IF;
RETURN NEW;
END;
$BODY$
LANGUAGE PLPGSQL;
CREATE TRIGGER secret_user_data_immutable_user_id
BEFORE UPDATE OF "user_id"
ON "secret_user_data"
FOR EACH ROW
EXECUTE PROCEDURE immutable_id();