\c template1 pgsql DROP DATABASE test; CREATE DATABASE test WITH OWNER nxadba; \c test pgsql CREATE FUNCTION public.plpgsql_call_handler () RETURNS language_handler AS '$libdir/plpgsql', 'plpgsql_call_handler' LANGUAGE c; CREATE TRUSTED PROCEDURAL LANGUAGE plpgsql HANDLER public.plpgsql_call_handler; \c test nxadba BEGIN; CREATE SCHEMA s AUTHORIZATION nxadba; REVOKE ALL ON SCHEMA s FROM PUBLIC; CREATE TABLE s.a ( z BIGINT NOT NULL, x BIGINT NOT NULL ); CREATE UNIQUE INDEX a_udx ON s.a (z,x); CREATE TABLE s.b ( z BIGINT NOT NULL, y BIGINT NOT NULL ); CREATE UNIQUE INDEX b_udx ON s.b (z,y); CREATE TABLE s.c ( x BIGINT NOT NULL, y BIGINT NOT NULL, w INT NOT NULL DEFAULT 1::INT ); CREATE UNIQUE INDEX c_udx ON s.c (x,y); CREATE FUNCTION s.add_y_to_x(BIGINT, BIGINT) RETURNS BOOL EXTERNAL SECURITY DEFINER AS ' DECLARE a_y ALIAS FOR $1; a_x ALIAS FOR $2; r_a s.a%ROWTYPE; -- RECORD; v_w s.c.w%TYPE; BEGIN SELECT d.w INTO v_w FROM s.c d WHERE d.x = a_x AND d.y = a_y; IF FOUND THEN UPDATE s.c SET w = (v_w + 1::INT) WHERE x = a_x AND y = a_y; ELSE INSERT INTO s.c (x,y,w) VALUES (a_x,a_y,1::INT); END IF; FOR r_a IN SELECT d.z, d.x FROM s.a d WHERE d.x = a_x LOOP RAISE INFO ''a_y: %, r_a.z: %'', a_y, r_a.z; END LOOP; RETURN TRUE; END; ' LANGUAGE 'plpgsql'; CREATE FUNCTION s.a_ins() RETURNS TRIGGER EXTERNAL SECURITY DEFINER AS ' DECLARE r_c s.c%ROWTYPE; -- RECORD; BEGIN FOR r_c IN SELECT d.y FROM s.c d WHERE d.x = NEW.x LOOP PERFORM s.add_y_to_x(r_c.y,NEW.z); END LOOP; RETURN NEW; END; ' LANGUAGE 'plpgsql'; CREATE TRIGGER a_ins BEFORE INSERT ON s.a FOR EACH ROW EXECUTE PROCEDURE s.a_ins(); CREATE FUNCTION s.b_ins() RETURNS TRIGGER EXTERNAL SECURITY DEFINER AS ' BEGIN PERFORM s.add_y_to_x(NEW.y, NEW.z); RETURN NEW; END; ' LANGUAGE 'plpgsql'; CREATE TRIGGER b_ins BEFORE INSERT ON s.b FOR EACH ROW EXECUTE PROCEDURE s.b_ins(); COMMIT; \c test pgsql VACUUM FULL FREEZE ANALYZE; \c test nxadba SET search_path = s; BEGIN; INSERT INTO s.b (z,y) VALUES (1,1); INSERT INTO s.b (z,y) VALUES (1,2); INSERT INTO s.b (z,y) VALUES (1,3); INSERT INTO s.b (z,y) VALUES (2,4); INSERT INTO s.b (z,y) VALUES (2,5); INSERT INTO s.b (z,y) VALUES (2,6); INSERT INTO s.b (z,y) VALUES (3,7); COMMIT; INSERT INTO s.a (z,x) VALUES (4,2); INSERT INTO s.a (z,x) VALUES (4,3); INSERT INTO s.a (z,x) VALUES (5,4);