DROP FUNCTION IF EXISTS func1() CASCADE;
DROP FUNCTION IF EXISTS func2() CASCADE;
DROP FUNCTION IF EXISTS func3() CASCADE;
DROP FUNCTION IF EXISTS func4() CASCADE;
DROP TABLE IF EXISTS test;

CREATE TABLE test (a int);

CREATE FUNCTION func1() RETURNS TRIGGER AS
$$
DECLARE
	foo integer;
BEGIN
	SELECT MAX(a) INTO foo FROM test;
	RAISE NOTICE 'before row-level trigger: a: % ; max a: %', NEW.a, foo;

	RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg1 BEFORE INSERT OR UPDATE OR DELETE ON test FOR EACH ROW EXECUTE PROCEDURE func1();

CREATE FUNCTION func2() RETURNS TRIGGER AS
$$
DECLARE
	foo integer;
BEGIN
	SELECT MAX(a) INTO foo FROM test;
	RAISE NOTICE 'after row-level trigger: a: % ; max a: %', NEW.a, foo;

	RETURN NULL;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg2 AFTER INSERT OR UPDATE OR DELETE ON test FOR EACH ROW EXECUTE PROCEDURE func2();

CREATE FUNCTION func3() RETURNS TRIGGER AS
$$
DECLARE
	foo integer;
BEGIN
	SELECT MAX(a) INTO foo FROM test;
	RAISE NOTICE 'before statement-level trigger: max a: %', foo;

	RETURN NULL;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg3 BEFORE INSERT OR UPDATE OR DELETE ON test FOR EACH STATEMENT EXECUTE PROCEDURE func3();

CREATE FUNCTION func4() RETURNS TRIGGER AS
$$
DECLARE
	foo integer;
BEGIN
	SELECT MAX(a) INTO foo FROM test;
	RAISE NOTICE 'after statement-level trigger: max a: %', foo;

	RETURN NULL;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg4 AFTER INSERT OR UPDATE OR DELETE ON test FOR EACH STATEMENT EXECUTE PROCEDURE func4();

INSERT INTO test (a) VALUES(1),(2),(3);
