Reputation: 1269
I am making a trigger for a user table that to hash password before inserting or updating password.
However, for a reason I ignore, when I insert a new row, NEW.password
is null for the trigger.
CREATE EXTENSION IF NOT EXISTS pgcrypto;
DROP TABLE IF EXISTS public.user;
DROP TRIGGER IF EXISTS encrypt_user_password ON public.user;
DROP DOMAIN IF EXISTS public.email_adress;
DROP TYPE IF EXISTS public.user_role;
DROP FUNCTION IF EXISTS encrypt_password;
CREATE TYPE user_role AS ENUM ('user', 'admin');
CREATE DOMAIN public.email_adress AS TEXT CHECK (value ~* '^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$');
CREATE TABLE public.user (
id SERIAL NOT NULL PRIMARY KEY,
email public.email_adress NOT NULL UNIQUE,
password TEXT NOT NULL,
salt TEXT NOT NULL DEFAULT gen_salt('bf'),
role public.user_role NOT NULL DEFAULT 'user'
);
CREATE OR REPLACE FUNCTION encrypt_password() RETURNS TRIGGER AS
$func$
BEGIN
IF NEW.password IS NULL THEN
RAISE EXCEPTION 'Password cannot be null';
END IF;
NEW.salt := gen_salt('bf');
NEW.password := crypt(NEW.password, NEW.salt);
RETURN NEW;
END
$func$ LANGUAGE plpgsql;
CREATE TRIGGER encrypt_user_password BEFORE INSERT OR UPDATE ON public.user EXECUTE PROCEDURE encrypt_password();
INSERT INTO public.user (email, password) VALUES ('[email protected]', '123456789') ON CONFLICT DO NOTHING;
Can anyone see the problem ?
I am using PostgreSQL 12
Upvotes: 0
Views: 330
Reputation: 12494
If you are going to reference the inserted or updated row from within your function, then you must add the FOR EACH ROW
qualifier.
CREATE TRIGGER encrypt_user_password
BEFORE INSERT OR UPDATE ON public.user
FOR EACH ROW EXECUTE PROCEDURE encrypt_password();
Also, EXECUTE PROCEDURE
is deprecated:
The use of the keyword PROCEDURE here is historical and deprecated
Upvotes: 2