diff options
author | Marko Kreen | 2010-09-02 14:56:56 +0000 |
---|---|---|
committer | Marko Kreen | 2010-09-02 14:56:56 +0000 |
commit | 40beabd50f3c6fe639f1e4d315970f786b0147e6 (patch) | |
tree | 9c04af8b9f09d1e97312c0844e7d8fbde0fe48f2 | |
parent | b3c56e9cf5b9e0f9114455fd8b9df81a63154170 (diff) |
pgq/trigger: add when= argument to sqltriga/logutriga.
Similar to WHEN argument for CREATE TRIGGER in 9.0.
-rw-r--r-- | sql/pgq/expected/logutriga.out | 36 | ||||
-rw-r--r-- | sql/pgq/sql/logutriga.sql | 22 | ||||
-rw-r--r-- | sql/pgq/triggers/common.c | 22 | ||||
-rw-r--r-- | sql/pgq/triggers/common.h | 4 | ||||
-rw-r--r-- | sql/pgq/triggers/pgq_triggers.sql.in | 2 |
5 files changed, 86 insertions, 0 deletions
diff --git a/sql/pgq/expected/logutriga.out b/sql/pgq/expected/logutriga.out index 18b81aac..65ebd544 100644 --- a/sql/pgq/expected/logutriga.out +++ b/sql/pgq/expected/logutriga.out @@ -110,3 +110,39 @@ CONTEXT: SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)" delete from custom_expr2; NOTICE: insert_event(que3, bat, dat1=foo&dat2=2&dat3=bat, test=foo) CONTEXT: SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)" +-- test when= +create table when_test ( + dat1 text not null primary key, + dat2 int2 not null, + dat3 text +); +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "when_test_pkey" for table "when_test" +create trigger when_triga after insert or update or delete on when_test +for each row execute procedure pgq.logutriga('que3', 'when=dat1=''foo'''); +insert into when_test values ('foo', '2'); +NOTICE: insert_event(que3, I:dat1, dat1=foo&dat2=2&dat3, public.when_test) +CONTEXT: SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)" +insert into when_test values ('bar', '2'); +select * from when_test; + dat1 | dat2 | dat3 +------+------+------ + foo | 2 | + bar | 2 | +(2 rows) + +update when_test set dat3 = 'bat'; +NOTICE: insert_event(que3, U:dat1, dat1=foo&dat2=2&dat3=bat, public.when_test) +CONTEXT: SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)" +delete from when_test; +NOTICE: insert_event(que3, D:dat1, dat1=foo&dat2=2&dat3=bat, public.when_test) +CONTEXT: SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)" +drop trigger when_triga on when_test; +create trigger when_triga after insert or update or delete on when_test +for each row execute procedure pgq.logutriga('que3', 'when=current_user=''random'''); +insert into when_test values ('foo', '2'); +select * from when_test; + dat1 | dat2 | dat3 +------+------+------ + foo | 2 | +(1 row) + diff --git a/sql/pgq/sql/logutriga.sql b/sql/pgq/sql/logutriga.sql index 11b24427..647d6b80 100644 --- a/sql/pgq/sql/logutriga.sql +++ b/sql/pgq/sql/logutriga.sql @@ -87,4 +87,26 @@ insert into custom_expr2 values ('foo', '2'); update custom_expr2 set dat3 = 'bat'; delete from custom_expr2; +-- test when= +create table when_test ( + dat1 text not null primary key, + dat2 int2 not null, + dat3 text +); +create trigger when_triga after insert or update or delete on when_test +for each row execute procedure pgq.logutriga('que3', 'when=dat1=''foo'''); + +insert into when_test values ('foo', '2'); +insert into when_test values ('bar', '2'); +select * from when_test; +update when_test set dat3 = 'bat'; +delete from when_test; + +drop trigger when_triga on when_test; +create trigger when_triga after insert or update or delete on when_test +for each row execute procedure pgq.logutriga('que3', 'when=current_user=''random'''); + +insert into when_test values ('foo', '2'); +select * from when_test; + diff --git a/sql/pgq/triggers/common.c b/sql/pgq/triggers/common.c index 123706dc..0a1d6c81 100644 --- a/sql/pgq/triggers/common.c +++ b/sql/pgq/triggers/common.c @@ -157,6 +157,9 @@ void pgq_insert_tg_event(PgqTriggerEvent *ev) override_fields(ev); + if (ev->skip_event) + return; + pgq_simple_insert(ev->queue_name, pgq_finish_varbuf(ev->field[EV_TYPE]), pgq_finish_varbuf(ev->field[EV_DATA]), @@ -416,6 +419,8 @@ static void parse_newstyle_args(PgqTriggerEvent *ev, TriggerData *tg) make_query(ev, EV_DATA, arg + 8); else if (strncmp(arg, "ev_type=", 8) == 0) make_query(ev, EV_TYPE, arg + 8); + else if (strncmp(arg, "when=", 5) == 0) + make_query(ev, EV_WHEN, arg + 5); else elog(ERROR, "bad param to pgq trigger"); } @@ -707,6 +712,23 @@ static void override_fields(struct PgqTriggerEvent *ev) elog(ERROR, "Override query failed"); if (SPI_processed != 1) elog(ERROR, "Expect 1 row from override query, got %d", SPI_processed); + + /* special handling for EV_WHEN */ + if (i == EV_WHEN) { + bool isnull; + Oid oid = SPI_gettypeid(SPI_tuptable->tupdesc, 1); + Datum res; + if (oid != BOOLOID) + elog(ERROR, "when= query result must be boolean, got=%u", oid); + res = SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull); + if (isnull) + elog(ERROR, "when= should not be NULL"); + if (DatumGetBool(res) == 0) + ev->skip_event = true; + continue; + } + + /* normal field */ val = SPI_getvalue(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1); if (ev->field[i]) { pfree(ev->field[i]->data); diff --git a/sql/pgq/triggers/common.h b/sql/pgq/triggers/common.h index 89d12187..64ee4d11 100644 --- a/sql/pgq/triggers/common.h +++ b/sql/pgq/triggers/common.h @@ -5,6 +5,7 @@ enum PgqFields { EV_EXTRA2, EV_EXTRA3, EV_EXTRA4, + EV_WHEN, EV_NFIELDS }; @@ -35,6 +36,9 @@ struct PgqTriggerEvent { /* result fields */ StringInfo field[EV_NFIELDS]; + + /* if 'when=' query fails */ + bool skip_event; }; typedef struct PgqTriggerEvent PgqTriggerEvent; diff --git a/sql/pgq/triggers/pgq_triggers.sql.in b/sql/pgq/triggers/pgq_triggers.sql.in index 22509202..6f1f71c8 100644 --- a/sql/pgq/triggers/pgq_triggers.sql.in +++ b/sql/pgq/triggers/pgq_triggers.sql.in @@ -18,6 +18,7 @@ -- backup - Put urlencoded contents of old row to ev_extra2 -- colname=EXPR - Override field value with SQL expression. Can reference table -- columns. colname can be: ev_type, ev_data, ev_extra1 .. ev_extra4 +-- when=EXPR - If EXPR returns false, don't insert event. -- -- Queue event fields: -- ev_type - I/U/D @@ -50,6 +51,7 @@ AS 'MODULE_PATHNAME', 'pgq_sqltriga' LANGUAGE C; -- backup - Put urlencoded contents of old row to ev_extra2 -- colname=EXPR - Override field value with SQL expression. Can reference table -- columns. colname can be: ev_type, ev_data, ev_extra1 .. ev_extra4 +-- when=EXPR - If EXPR returns false, don't insert event. -- -- Queue event fields: -- ev_type - I/U/D ':' pkey_column_list |