Reputation: 16831
I'm trying to make a list of users who are modified and then at the end of transaction I would like to process the list. Here's how I'm trying to do this:
CREATE TABLE "user"(
user_id bigserial NOT NULL,
username varchar(255) NOT NULL,
CONSTRAINT pk_5 PRIMARY KEY (user_id)
);
CREATE FUNCTION enlist_user ()
RETURNS trigger
LANGUAGE plpgsql
AS $$
DECLARE
rec record;
BEGIN
IF TG_OP = 'INSERT' OR TG_OP = 'UPDATE' THEN
rec := NEW;
ELSE
rec := OLD;
END IF;
CREATE TEMPORARY TABLE IF NOT EXISTS user_list (
user_id bigint NOT NULL,
CONSTRAINT user_queue_pk PRIMARY KEY (user_id)
);
INSERT INTO user_list
VALUES (rec.user_id);
EXCEPTION WHEN OTHERS THEN
RAISE NOTICE 'Unable to add %', rec.user_id;
RETURN rec;
END;
$$;
CREATE TRIGGER user_modified
AFTER INSERT OR DELETE OR UPDATE
ON "user"
FOR EACH ROW
EXECUTE PROCEDURE enlist_user();
INSERT INTO "user" VALUES (default, 'qwe');
But running the above code results in follow error:
ERROR: control reached end of trigger procedure without RETURN
CONTEXT: PL/pgSQL function enlist_user()
What's going on? Why RETURN rec
did not work?
Upvotes: 0
Views: 116
Reputation:
Your indention is misleading. The exception
part belongs logically on the same level as the first begin
:
CREATE FUNCTION enlist_user ()
RETURNS trigger
LANGUAGE plpgsql
AS $$
DECLARE
rec record;
BEGIN
...
EXCEPTION WHEN OTHERS THEN
RAISE NOTICE 'Unable to add %', rec.user_id;
RETURN rec; -- << only reached if an exception is thrown.
END;
$$;
So the RETURN
is part of the exception block and thus only reached if an exception occurs. What you actually want is:
CREATE FUNCTION enlist_user ()
RETURNS trigger
LANGUAGE plpgsql
AS $$
DECLARE
rec record;
BEGIN
...
RETURN rec; -- normal flow of the function
EXCEPTION WHEN OTHERS THEN
RAISE NOTICE 'Unable to add %', rec.user_id;
END;
$$;
You also shouldn't just do a raise notice
which means that the original exception won't be shown to the end user. The caller also will not have any clue that an exception happened. It's better if you re-raise the exception that you handled:
....
RETURN rec; -- normal flow of the function
EXCEPTION WHEN OTHERS THEN
RAISE NOTICE 'Unable to add %', rec.user_id;
RAISE; -- signal this error to the caller
END;
$$;
Upvotes: 1