sql/pgq/triggers: magic fields to set event fields directly.
authorMarko Kreen <markokr@gmail.com>
Wed, 14 Oct 2009 13:30:18 +0000 (16:30 +0300)
committerMarko Kreen <markokr@gmail.com>
Wed, 14 Oct 2009 13:30:18 +0000 (16:30 +0300)
pgq.sqltriga() / pgq.logutriga() now consider following fields magic:

  _pgq_ev_type
  _pgq_ev_data
  _pgq_ev_extra1
  _pgq_ev_extra2
  _pgq_ev_extra3
  _pgq_ev_extra4

If any of them is present in table, corresponding event field is set directly
to it's value, overriding value generated by trigger.

sql/pgq/expected/logutriga.out
sql/pgq/expected/sqltriga.out
sql/pgq/sql/logutriga.sql
sql/pgq/sql/sqltriga.sql
sql/pgq/triggers/common.c
sql/pgq/triggers/common.h
sql/pgq/triggers/logtriga.c
sql/pgq/triggers/logutriga.c
sql/pgq/triggers/sqltriga.c
sql/pgq/triggers/stringutil.c

index 782c5965c743f4fdd87b851bca0a2140831120f5..62262718f34e08aadba16f2ef7a22329a2f2afbb 100644 (file)
@@ -16,17 +16,17 @@ create trigger utest AFTER insert or update or delete ON udata
 for each row execute procedure pgq.logutriga('udata_que');
 insert into udata (txt) values ('text1');
 NOTICE:  insert_event(udata_que, I:id, id=1&txt=text1&bin, public.udata)
-CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, null, null)"
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
 insert into udata (bin) values (E'bi\tn\\000bin');
 NOTICE:  insert_event(udata_que, I:id, id=2&txt&bin=bi%5c011n%5c000bin, public.udata)
-CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, null, null)"
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
 -- test missing pkey
 create table nopkey2 (dat text);
 create trigger nopkey_triga2 after insert or update or delete on nopkey2
 for each row execute procedure pgq.logutriga('que3');
 insert into nopkey2 values ('foo');
 NOTICE:  insert_event(que3, I:, dat=foo, public.nopkey2)
-CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, null, null)"
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
 update nopkey2 set dat = 'bat';
 ERROR:  Update/Delete on table without pkey
 delete from nopkey2;
@@ -38,8 +38,31 @@ create trigger ucustom_triga after insert or update or delete on ucustom_pkey
 for each row execute procedure pgq.logutriga('que3');
 insert into ucustom_pkey values ('foo', '2');
 NOTICE:  insert_event(que3, I:, dat1=foo&dat2=2&dat3, public.ucustom_pkey)
-CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, null, null)"
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
 update ucustom_pkey set dat3 = 'bat';
 ERROR:  Update/Delete on table without pkey
 delete from ucustom_pkey;
 ERROR:  Update/Delete on table without pkey
+-- test custom fields
+create table custom_fields2 (
+    dat1 text not null primary key,
+    dat2 int2 not null,
+    dat3 text,
+    _pgq_ev_type text default 'my_type',
+    _pgq_ev_extra1 text default 'e1',
+    _pgq_ev_extra2 text default 'e2',
+    _pgq_ev_extra3 text default 'e3',
+    _pgq_ev_extra4 text default 'e4'
+);
+NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "custom_fields2_pkey" for table "custom_fields2"
+create trigger customf2_triga after insert or update or delete on custom_fields2
+for each row execute procedure pgq.logutriga('que3');
+insert into custom_fields2 values ('foo', '2');
+NOTICE:  insert_event(que3, my_type, dat1=foo&dat2=2&dat3, e1)
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
+update custom_fields2 set dat3 = 'bat';
+NOTICE:  insert_event(que3, my_type, dat1=foo&dat2=2&dat3=bat, e1)
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
+delete from custom_fields2;
+NOTICE:  insert_event(que3, my_type, dat1=foo&dat2=2&dat3=bat, e1)
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
index 3eb91ef309f40c845d448face17c1c6471686f67..6f2258673ae5417cf713b00a13cc19a51f3ad577 100644 (file)
@@ -9,40 +9,40 @@ for each row execute procedure pgq.sqltriga('que');
 -- simple test
 insert into rtest values (1, 'value1');
 NOTICE:  insert_event(que, I, (id,dat) values ('1','value1'), public.rtest)
-CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, null, null)"
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
 update rtest set dat = 'value2';
 NOTICE:  insert_event(que, U, dat='value2' where id='1', public.rtest)
-CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, null, null)"
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
 delete from rtest;
 NOTICE:  insert_event(que, D, id='1', public.rtest)
-CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, null, null)"
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
 -- test new fields
 alter table rtest add column dat2 text;
 insert into rtest values (1, 'value1');
 NOTICE:  insert_event(que, I, (id,dat,dat2) values ('1','value1',null), public.rtest)
-CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, null, null)"
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
 update rtest set dat = 'value2';
 NOTICE:  insert_event(que, U, dat='value2' where id='1', public.rtest)
-CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, null, null)"
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
 delete from rtest;
 NOTICE:  insert_event(que, D, id='1', public.rtest)
-CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, null, null)"
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
 -- test field ignore
 drop trigger rtest_triga on rtest;
 create trigger rtest_triga after insert or update or delete on rtest
 for each row execute procedure pgq.sqltriga('que2', 'ignore=dat2');
 insert into rtest values (1, '666', 'newdat');
 NOTICE:  insert_event(que2, I, (id,dat) values ('1','666'), public.rtest)
-CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, null, null)"
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
 update rtest set dat = 5, dat2 = 'newdat2';
 NOTICE:  insert_event(que2, U, dat='5' where id='1', public.rtest)
-CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, null, null)"
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
 update rtest set dat = 6;
 NOTICE:  insert_event(que2, U, dat='6' where id='1', public.rtest)
-CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, null, null)"
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
 delete from rtest;
 NOTICE:  insert_event(que2, D, id='1', public.rtest)
-CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, null, null)"
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
 -- test hashed pkey
 -- drop trigger rtest_triga on rtest;
 -- create trigger rtest_triga after insert or update or delete on rtest
@@ -57,32 +57,32 @@ create trigger rtest_triga after insert or update or delete on rtest
 for each row execute procedure pgq.sqltriga('que3');
 insert into rtest values (1, 0, 'non-null');
 NOTICE:  insert_event(que3, I, (id,dat,dat2) values ('1','0','non-null'), public.rtest)
-CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, null, null)"
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
 insert into rtest values (2, 0, NULL);
 NOTICE:  insert_event(que3, I, (id,dat,dat2) values ('2','0',null), public.rtest)
-CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, null, null)"
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
 update rtest set dat2 = 'non-null2' where id=1;
 NOTICE:  insert_event(que3, U, dat2='non-null2' where id='1', public.rtest)
-CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, null, null)"
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
 update rtest set dat2 = NULL where id=1;
 NOTICE:  insert_event(que3, U, dat2=NULL where id='1', public.rtest)
-CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, null, null)"
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
 update rtest set dat2 = 'new-nonnull' where id=2;
 NOTICE:  insert_event(que3, U, dat2='new-nonnull' where id='2', public.rtest)
-CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, null, null)"
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
 delete from rtest where id=1;
 NOTICE:  insert_event(que3, D, id='1', public.rtest)
-CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, null, null)"
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
 delete from rtest where id=2;
 NOTICE:  insert_event(que3, D, id='2', public.rtest)
-CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, null, null)"
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
 -- test missing pkey
 create table nopkey (dat text);
 create trigger nopkey_triga after insert or update or delete on nopkey
 for each row execute procedure pgq.sqltriga('que3');
 insert into nopkey values ('foo');
 NOTICE:  insert_event(que3, I, (dat) values ('foo'), public.nopkey)
-CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, null, null)"
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
 update nopkey set dat = 'bat';
 ERROR:  Update/Delete on table without pkey
 delete from nopkey;
@@ -93,10 +93,33 @@ create trigger custom_triga after insert or update or delete on custom_pkey
 for each row execute procedure pgq.sqltriga('que3', 'pkey=dat1,dat2');
 insert into custom_pkey values ('foo', '2');
 NOTICE:  insert_event(que3, I, (dat1,dat2,dat3) values ('foo','2',null), public.custom_pkey)
-CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, null, null)"
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
 update custom_pkey set dat3 = 'bat';
 NOTICE:  insert_event(que3, U, dat3='bat' where dat1='foo' and dat2='2', public.custom_pkey)
-CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, null, null)"
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
 delete from custom_pkey;
 NOTICE:  insert_event(que3, D, dat1='foo' and dat2='2', public.custom_pkey)
-CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, null, null)"
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
+-- test custom fields
+create table custom_fields (
+    dat1 text not null primary key,
+    dat2 int2 not null,
+    dat3 text,
+    _pgq_ev_type text default 'my_type',
+    _pgq_ev_extra1 text default 'e1',
+    _pgq_ev_extra2 text default 'e2',
+    _pgq_ev_extra3 text default 'e3',
+    _pgq_ev_extra4 text default 'e4'
+);
+NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "custom_fields_pkey" for table "custom_fields"
+create trigger customf_triga after insert or update or delete on custom_fields
+for each row execute procedure pgq.sqltriga('que3');
+insert into custom_fields values ('foo', '2');
+NOTICE:  insert_event(que3, my_type, (dat1,dat2,dat3) values ('foo','2',null), e1)
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
+update custom_fields set dat3 = 'bat';
+NOTICE:  insert_event(que3, my_type, dat3='bat' where dat1='foo', e1)
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
+delete from custom_fields;
+NOTICE:  insert_event(que3, my_type, dat1='foo', e1)
+CONTEXT:  SQL statement "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)"
index 8ba3162149844b62ac7afa5bed3258cd4028e531..ce5e42c61d47ec960c4f0d5110b1a380f358dc15 100644 (file)
@@ -38,3 +38,22 @@ insert into ucustom_pkey values ('foo', '2');
 update ucustom_pkey set dat3 = 'bat';
 delete from ucustom_pkey;
 
+-- test custom fields
+create table custom_fields2 (
+    dat1 text not null primary key,
+    dat2 int2 not null,
+    dat3 text,
+    _pgq_ev_type text default 'my_type',
+    _pgq_ev_extra1 text default 'e1',
+    _pgq_ev_extra2 text default 'e2',
+    _pgq_ev_extra3 text default 'e3',
+    _pgq_ev_extra4 text default 'e4'
+);
+create trigger customf2_triga after insert or update or delete on custom_fields2
+for each row execute procedure pgq.logutriga('que3');
+
+insert into custom_fields2 values ('foo', '2');
+update custom_fields2 set dat3 = 'bat';
+delete from custom_fields2;
+
+
index 9ac38a4eff90b8a11c9ba20716d879821d4468df..f23adce489e45bcafb5de9b59131d31cee6a5b1e 100644 (file)
@@ -74,3 +74,22 @@ insert into custom_pkey values ('foo', '2');
 update custom_pkey set dat3 = 'bat';
 delete from custom_pkey;
 
+-- test custom fields
+create table custom_fields (
+    dat1 text not null primary key,
+    dat2 int2 not null,
+    dat3 text,
+    _pgq_ev_type text default 'my_type',
+    _pgq_ev_extra1 text default 'e1',
+    _pgq_ev_extra2 text default 'e2',
+    _pgq_ev_extra3 text default 'e3',
+    _pgq_ev_extra4 text default 'e4'
+);
+create trigger customf_triga after insert or update or delete on custom_fields
+for each row execute procedure pgq.sqltriga('que3');
+
+insert into custom_fields values ('foo', '2');
+update custom_fields set dat3 = 'bat';
+delete from custom_fields;
+
+
index 0cc2bb49f87efef7b2d9673852d94d321606af30..20e47395cd8c387204fe80dc08e82dd797ee054d 100644 (file)
@@ -39,6 +39,9 @@
 PG_MODULE_MAGIC;
 #endif
 
+/* memcmp is ok on NameData fields */
+#define is_magic_field(s) (memcmp(s, "_pgq_ev_", 8) == 0)
+
 /*
  * primary key info
  */
@@ -49,7 +52,8 @@ static HTAB *tbl_cache_map;
 static const char pkey_sql[] =
     "SELECT k.attnum, k.attname FROM pg_index i, pg_attribute k"
     " WHERE i.indrelid = $1 AND k.attrelid = i.indexrelid"
-    "   AND i.indisprimary AND k.attnum > 0 AND NOT k.attisdropped" " ORDER BY k.attnum";
+    "   AND i.indisprimary AND k.attnum > 0 AND NOT k.attisdropped"
+    " ORDER BY k.attnum";
 static void *pkey_plan;
 
 static void relcache_reset_cb(Datum arg, Oid relid);
@@ -59,19 +63,20 @@ static void relcache_reset_cb(Datum arg, Oid relid);
  *
  * does not support NULL arguments.
  */
-void pgq_simple_insert(const char *queue_name, Datum ev_type, Datum ev_data, Datum ev_extra1, Datum ev_extra2)
+void pgq_simple_insert(const char *queue_name, Datum ev_type, Datum ev_data,
+                      Datum ev_extra1, Datum ev_extra2, Datum ev_extra3, Datum ev_extra4)
 {
-       Datum values[5];
-       char nulls[5];
+       Datum values[7];
+       char nulls[7];
        static void *plan = NULL;
        int res;
 
        if (!plan) {
                const char *sql;
-               Oid types[5] = { TEXTOID, TEXTOID, TEXTOID, TEXTOID, TEXTOID };
+               Oid   types[7] = { TEXTOID, TEXTOID, TEXTOID, TEXTOID, TEXTOID, TEXTOID, TEXTOID };
 
-               sql = "select pgq.insert_event($1, $2, $3, $4, $5, null, null)";
-               plan = SPI_saveplan(SPI_prepare(sql, 5, types));
+               sql = "select pgq.insert_event($1, $2, $3, $4, $5, $6, $7)";
+               plan = SPI_saveplan(SPI_prepare(sql, 7, types));
                if (plan == NULL)
                        elog(ERROR, "logtriga: SPI_prepare() failed");
        }
@@ -80,23 +85,77 @@ void pgq_simple_insert(const char *queue_name, Datum ev_type, Datum ev_data, Dat
        values[2] = ev_data;
        values[3] = ev_extra1;
        values[4] = ev_extra2;
+       values[5] = ev_extra3;
+       values[6] = ev_extra4;
        nulls[0] = ' ';
-       nulls[1] = ';
-       nulls[2] = ';
-       nulls[3] = ';
+       nulls[1] = ev_type ? ' ' : 'n';
+       nulls[2] = ev_data ? ' ' : 'n';
+       nulls[3] = ev_extra1 ? ' ' : 'n';
        nulls[4] = ev_extra2 ? ' ' : 'n';
+       nulls[5] = ev_extra3 ? ' ' : 'n';
+       nulls[6] = ev_extra4 ? ' ' : 'n';
        res = SPI_execute_plan(plan, values, nulls, false, 0);
        if (res != SPI_OK_SELECT)
                elog(ERROR, "call of pgq.insert_event failed");
 }
 
-void pgq_insert_tg_event(PgqTriggerEvent *ev)
+static void fill_magic_columns(PgqTriggerEvent *ev, TriggerData *tg)
+{
+       int i;
+       char *col_name, *col_value;
+       StringInfo *dst = NULL;
+       TupleDesc tupdesc = tg->tg_relation->rd_att;
+       HeapTuple row;
+
+       if (TRIGGER_FIRED_BY_UPDATE(tg->tg_event))
+               row = tg->tg_newtuple;
+       else
+               row = tg->tg_trigtuple;
+
+       for (i = 0; i < tupdesc->natts; i++) {
+               /* Skip dropped columns */
+               if (tupdesc->attrs[i]->attisdropped)
+                       continue;
+               col_name = NameStr(tupdesc->attrs[i]->attname);
+               if (!is_magic_field(col_name))
+                       continue;
+               if (strcmp(col_name, "_pgq_ev_type") == 0)
+                       dst = &ev->ev_type;
+               else if (strcmp(col_name, "_pgq_ev_data") == 0)
+                       dst = &ev->ev_data;
+               else if (strcmp(col_name, "_pgq_ev_extra1") == 0)
+                       dst = &ev->ev_extra1;
+               else if (strcmp(col_name, "_pgq_ev_extra2") == 0)
+                       dst = &ev->ev_extra2;
+               else if (strcmp(col_name, "_pgq_ev_extra3") == 0)
+                       dst = &ev->ev_extra3;
+               else if (strcmp(col_name, "_pgq_ev_extra4") == 0)
+                       dst = &ev->ev_extra4;
+               else
+                       elog(ERROR, "Unknown magic column: %s", col_name);
+
+               col_value = SPI_getvalue(row, tupdesc, i + 1);
+               if (col_value != NULL) {
+                       *dst = pgq_init_varbuf();
+                       appendStringInfoString(*dst, col_value);
+               } else {
+                       *dst = NULL;
+               }
+       }
+}
+
+void pgq_insert_tg_event(PgqTriggerEvent *ev, TriggerData *tg)
 {
+       if (ev->custom_fields)
+               fill_magic_columns(ev, tg);
+
        pgq_simple_insert(ev->queue_name,
                          pgq_finish_varbuf(ev->ev_type),
                          pgq_finish_varbuf(ev->ev_data),
                          pgq_finish_varbuf(ev->ev_extra1),
-                         ev->ev_extra2 ? pgq_finish_varbuf(ev->ev_extra2) : (Datum)0);
+                         pgq_finish_varbuf(ev->ev_extra2),
+                         pgq_finish_varbuf(ev->ev_extra3),
+                         pgq_finish_varbuf(ev->ev_extra4));
 }
 
 char *pgq_find_table_name(Relation rel)
@@ -415,15 +474,21 @@ bool pgqtriga_skip_col(PgqTriggerEvent *ev, TriggerData *tg, int i, int attkind_
        TupleDesc tupdesc;
        const char *name;
 
+       tupdesc = tg->tg_relation->rd_att;
+       if (tupdesc->attrs[i]->attisdropped)
+               return true;
+       name = NameStr(tupdesc->attrs[i]->attname);
+
+       if (is_magic_field(name)) {
+               ev->custom_fields = 1;
+               return true;
+       }
+
        if (ev->attkind) {
                if (attkind_idx >= ev->attkind_len)
                        return true;
                return ev->attkind[attkind_idx] == 'i';
        } else if (ev->ignore_list) {
-               tupdesc = tg->tg_relation->rd_att;
-               if (tupdesc->attrs[i]->attisdropped)
-                       return true;
-               name = NameStr(tupdesc->attrs[i]->attname);
                return pgq_strlist_contains(ev->ignore_list, name);
        }
        return false;
@@ -446,6 +511,10 @@ bool pgqtriga_is_pkey(PgqTriggerEvent *ev, TriggerData *tg, int i, int attkind_i
                if (tupdesc->attrs[i]->attisdropped)
                        return false;
                name = NameStr(tupdesc->attrs[i]->attname);
+               if (is_magic_field(name)) {
+                       ev->custom_fields = 1;
+                       return false;
+               }
                return pgq_strlist_contains(ev->pkey_list, name);
        }
        return false;
index 957a02df59a61078c3d1650c7bc05a0321bc8a73..0adaa7b1f6e68454f1ebed0704dcd9da6e0fd3bb 100644 (file)
@@ -14,6 +14,7 @@ struct PgqTriggerEvent {
        char op_type;
        bool skip;
        bool backup;
+       bool custom_fields;
 
        struct PgqTableInfo *info;
 
@@ -21,6 +22,8 @@ struct PgqTriggerEvent {
        StringInfo ev_data;
        StringInfo ev_extra1;
        StringInfo ev_extra2;
+       StringInfo ev_extra3;
+       StringInfo ev_extra4;
 };
 typedef struct PgqTriggerEvent PgqTriggerEvent;
 
@@ -42,11 +45,11 @@ struct PgqTableInfo {
 struct PgqTableInfo *pgq_find_table_info(Relation rel);
 void pgq_prepare_event(struct PgqTriggerEvent *ev, TriggerData *tg, bool newstyle);
 char *pgq_find_table_name(Relation rel);
-void pgq_simple_insert(const char *queue_name, Datum ev_type, Datum ev_data, Datum ev_extra1,
-                      Datum ev_extra2);
+void pgq_simple_insert(const char *queue_name, Datum ev_type, Datum ev_data,
+                      Datum ev_extra1, Datum ev_extra2, Datum ev_extra3, Datum ev_extra4);
 bool pgqtriga_skip_col(PgqTriggerEvent *ev, TriggerData *tg, int i, int attkind_idx);
 bool pgqtriga_is_pkey(PgqTriggerEvent *ev, TriggerData *tg, int i, int attkind_idx);
-void pgq_insert_tg_event(PgqTriggerEvent *ev);
+void pgq_insert_tg_event(PgqTriggerEvent *ev, TriggerData *tg);
 
 bool pgq_is_logging_disabled(void);
 
index bc0a40bf7c34b5faa0ae7ea10c9d1a08974240f3..0a474198d9003214612777d3bbc6e63fa71ce948 100644 (file)
@@ -73,7 +73,7 @@ Datum pgq_logtriga(PG_FUNCTION_ARGS)
         * create sql and insert if interesting
         */
        if (pgqtriga_make_sql(&ev, tg, ev.ev_data))
-               pgq_insert_tg_event(&ev);
+               pgq_insert_tg_event(&ev, tg);
 
        if (SPI_finish() < 0)
                elog(ERROR, "SPI_finish failed");
index f6f7ff1763f18606cd03d1f685c311707b17a010..59a0cf0426ee7e75489a6f658cf830cc538d52ca 100644 (file)
@@ -115,7 +115,7 @@ Datum pgq_logutriga(PG_FUNCTION_ARGS)
        /*
         * Construct the parameter array and insert the log row.
         */
-       pgq_insert_tg_event(&ev);
+       pgq_insert_tg_event(&ev, tg);
 
        if (SPI_finish() < 0)
                elog(ERROR, "SPI_finish failed");
index d06917ee649bc3c7849295961a10448237eeeddf..e75bd5110c99a57c7736abce72b91fc898f7a194 100644 (file)
@@ -68,7 +68,7 @@ Datum pgq_sqltriga(PG_FUNCTION_ARGS)
         * create sql and insert if interesting
         */
        if (pgqtriga_make_sql(&ev, tg, ev.ev_data))
-               pgq_insert_tg_event(&ev);
+               pgq_insert_tg_event(&ev, tg);
 
        if (SPI_finish() < 0)
                elog(ERROR, "SPI_finish failed");
index 230567bc7658548e99371fdd1f629c8427ee96e7..b379e7881f0514201f551c389933ff3d604b8271 100644 (file)
@@ -39,6 +39,7 @@ StringInfo pgq_init_varbuf(void)
 
 Datum pgq_finish_varbuf(StringInfo buf)
 {
+       if (!buf) return (Datum)0;
        SET_VARSIZE(buf->data, buf->len);
        return PointerGetDatum(buf->data);
 }