mirror of https://github.com/citusdata/citus.git
172 lines
5.7 KiB
Plaintext
172 lines
5.7 KiB
Plaintext
create or replace function trs_before() returns trigger language plpgsql as $$
|
|
BEGIN
|
|
RAISE NOTICE 'BEFORE STATEMENT %', TG_OP;
|
|
RETURN NULL;
|
|
END;
|
|
$$;
|
|
create or replace function trs_after() returns trigger language plpgsql as $$
|
|
DECLARE
|
|
r RECORD;
|
|
BEGIN
|
|
RAISE NOTICE 'AFTER STATEMENT %', TG_OP;
|
|
IF (TG_OP = 'DELETE') THEN
|
|
FOR R IN select * from old_table
|
|
LOOP
|
|
RAISE NOTICE ' (%)', r.i;
|
|
END LOOP;
|
|
ELSE
|
|
FOR R IN select * from new_table
|
|
LOOP
|
|
RAISE NOTICE ' (%)', r.i;
|
|
END LOOP;
|
|
END IF;
|
|
RETURN NULL;
|
|
END;
|
|
$$;
|
|
create or replace function trr_before() returns trigger language plpgsql as $$
|
|
BEGIN
|
|
RAISE NOTICE 'BEFORE ROW %: (%)', TG_OP, NEW.i;
|
|
RETURN NEW;
|
|
END;
|
|
$$;
|
|
create or replace function trr_after() returns trigger language plpgsql as $$
|
|
BEGIN
|
|
RAISE NOTICE 'AFTER ROW %: (%)', TG_OP, NEW.i;
|
|
RETURN NEW;
|
|
END;
|
|
$$;
|
|
create table test_tr(i int) using columnar;
|
|
create trigger tr_before_stmt before insert on test_tr
|
|
for each statement execute procedure trs_before();
|
|
create trigger tr_after_stmt after insert on test_tr
|
|
referencing new table as new_table
|
|
for each statement execute procedure trs_after();
|
|
create trigger tr_before_row before insert on test_tr
|
|
for each row execute procedure trr_before();
|
|
-- after triggers require TIDs, which are not supported yet
|
|
create trigger tr_after_row after insert on test_tr
|
|
for each row execute procedure trr_after();
|
|
ERROR: AFTER ROW triggers are not supported for columnstore access method
|
|
HINT: Consider an AFTER STATEMENT trigger instead.
|
|
insert into test_tr values(1);
|
|
NOTICE: BEFORE STATEMENT INSERT
|
|
CONTEXT: PL/pgSQL function trs_before() line 3 at RAISE
|
|
NOTICE: BEFORE ROW INSERT: (1)
|
|
CONTEXT: PL/pgSQL function trr_before() line 3 at RAISE
|
|
NOTICE: AFTER STATEMENT INSERT
|
|
CONTEXT: PL/pgSQL function trs_after() line 5 at RAISE
|
|
NOTICE: (1)
|
|
CONTEXT: PL/pgSQL function trs_after() line 14 at RAISE
|
|
insert into test_tr values(2),(3),(4);
|
|
NOTICE: BEFORE STATEMENT INSERT
|
|
CONTEXT: PL/pgSQL function trs_before() line 3 at RAISE
|
|
NOTICE: BEFORE ROW INSERT: (2)
|
|
CONTEXT: PL/pgSQL function trr_before() line 3 at RAISE
|
|
NOTICE: BEFORE ROW INSERT: (3)
|
|
CONTEXT: PL/pgSQL function trr_before() line 3 at RAISE
|
|
NOTICE: BEFORE ROW INSERT: (4)
|
|
CONTEXT: PL/pgSQL function trr_before() line 3 at RAISE
|
|
NOTICE: AFTER STATEMENT INSERT
|
|
CONTEXT: PL/pgSQL function trs_after() line 5 at RAISE
|
|
NOTICE: (2)
|
|
CONTEXT: PL/pgSQL function trs_after() line 14 at RAISE
|
|
NOTICE: (3)
|
|
CONTEXT: PL/pgSQL function trs_after() line 14 at RAISE
|
|
NOTICE: (4)
|
|
CONTEXT: PL/pgSQL function trs_after() line 14 at RAISE
|
|
SELECT * FROM test_tr ORDER BY i;
|
|
i
|
|
---------------------------------------------------------------------
|
|
1
|
|
2
|
|
3
|
|
4
|
|
(4 rows)
|
|
|
|
drop table test_tr;
|
|
create table test_tr(i int) using columnar;
|
|
-- we should be able to clean-up and continue gracefully if we
|
|
-- error out in AFTER STATEMENT triggers.
|
|
CREATE SEQUENCE counter START 100;
|
|
create or replace function trs_after_erroring() returns trigger language plpgsql as $$
|
|
BEGIN
|
|
IF nextval('counter') % 2 = 0 THEN
|
|
RAISE EXCEPTION '%', 'error';
|
|
END IF;
|
|
RETURN NULL;
|
|
END;
|
|
$$;
|
|
create trigger tr_after_stmt_erroring after insert on test_tr
|
|
referencing new table as new_table
|
|
for each statement execute procedure trs_after_erroring();
|
|
--
|
|
-- Once upon a time we didn't clean-up properly after erroring out. Here the first
|
|
-- statement errors, but the second succeeds. In old times, because of failure in
|
|
-- clean-up, both rows were visible. But only the 2nd one should be visible.
|
|
--
|
|
insert into test_tr values(5);
|
|
ERROR: error
|
|
CONTEXT: PL/pgSQL function trs_after_erroring() line 4 at RAISE
|
|
insert into test_tr values(6);
|
|
SELECT * FROM test_tr ORDER BY i;
|
|
i
|
|
---------------------------------------------------------------------
|
|
6
|
|
(1 row)
|
|
|
|
drop table test_tr;
|
|
--
|
|
-- https://github.com/citusdata/cstore2/issues/32
|
|
--
|
|
create table events(
|
|
user_id bigint,
|
|
event_id bigint,
|
|
event_time timestamp default now(),
|
|
value float default random())
|
|
PARTITION BY RANGE (event_time);
|
|
create table events_p2020_11_04_102965
|
|
PARTITION OF events FOR VALUES FROM ('2020-11-04 00:00:00+01') TO ('2020-11-05 00:00:00+01')
|
|
USING columnar;
|
|
create table events_trigger_target(
|
|
user_id bigint,
|
|
avg float,
|
|
__count__ bigint
|
|
) USING columnar;
|
|
CREATE OR REPLACE FUNCTION user_value_by_day()
|
|
RETURNS trigger
|
|
LANGUAGE plpgsql
|
|
AS $function$
|
|
BEGIN
|
|
IF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN
|
|
EXECUTE format($exec_format$INSERT INTO %s AS __mat__ SELECT user_id, 0.1 AS avg, pg_catalog.count(*) AS __count__ FROM __ins__ events GROUP BY user_id;
|
|
$exec_format$, TG_ARGV[0]);
|
|
END IF;
|
|
IF (TG_OP = 'DELETE' OR TG_OP = 'UPDATE') THEN
|
|
RAISE EXCEPTION $ex$MATERIALIZED VIEW 'user_value_by_day' on table 'events' does not support UPDATE/DELETE$ex$;
|
|
END IF;
|
|
IF (TG_OP = 'TRUNCATE') THEN
|
|
EXECUTE format($exec_format$TRUNCATE TABLE %s; $exec_format$, TG_ARGV[0]);
|
|
END IF;
|
|
RETURN NULL;
|
|
END;
|
|
$function$;
|
|
create trigger "user_value_by_day_INSERT" AFTER INSERT ON events
|
|
REFERENCING NEW TABLE AS __ins__
|
|
FOR EACH STATEMENT EXECUTE FUNCTION user_value_by_day('events_trigger_target');
|
|
COPY events FROM STDIN WITH (FORMAT 'csv');
|
|
SELECT * FROM events ORDER BY user_id;
|
|
user_id | event_id | event_time | value
|
|
---------------------------------------------------------------------
|
|
1 | 1 | Wed Nov 04 15:54:02.226999 2020 | 1.1
|
|
2 | 3 | Wed Nov 04 16:54:02.226999 2020 | 2.2
|
|
(2 rows)
|
|
|
|
SELECT * FROM events_trigger_target ORDER BY user_id;
|
|
user_id | avg | __count__
|
|
---------------------------------------------------------------------
|
|
1 | 0.1 | 1
|
|
2 | 0.1 | 1
|
|
(2 rows)
|
|
|
|
DROP TABLE events;
|