Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Meanings of bits in trigger type field (tgtype) of Postgres pg_trigger

Where can I find documentation on bits of POSTGRES tgtype, ex.:

SELECT * FROM pg_trigger;
===>
 tgtype = 23; 

What does this mean?

like image 939
rlib Avatar asked May 13 '14 14:05

rlib


People also ask

What is Tg_op in PostgreSQL?

TG_OP. Data type text ; a string of INSERT , UPDATE , DELETE , or TRUNCATE telling for which operation the trigger was fired. TG_RELID. Data type oid ; the object ID of the table that caused the trigger invocation. TG_RELNAME.

How many types of triggers are present in PostgreSQL?

There are two types of triggers: per-row triggers and per-statement triggers.

What are triggers in PostgreSQL?

A PostgreSQL trigger is a function called automatically whenever an event such as an insert, update, or deletion occurs. A PostgreSQL trigger can be defined to fire in the following cases: Before attempting any operation on a row (before constraints are checked and the INSERT, UPDATE or DELETE is attempted).


2 Answers

tgtype is a (per documentation):

Bit mask identifying trigger firing conditions

But individual bits are not identified there.
The source code says:

41  int16  tgtype;  /* BEFORE/AFTER/INSTEAD, UPDATE/DELETE/INSERT,
42                                   * ROW/STATEMENT; see below */

...

93  /* Bits within tgtype */
94  #define TRIGGER_TYPE_ROW         (1 << 0)
95  #define TRIGGER_TYPE_BEFORE      (1 << 1)
96  #define TRIGGER_TYPE_INSERT      (1 << 2)
97  #define TRIGGER_TYPE_DELETE      (1 << 3)
98  #define TRIGGER_TYPE_UPDATE      (1 << 4)
99  #define TRIGGER_TYPE_TRUNCATE    (1 << 5)
100 #define TRIGGER_TYPE_INSTEAD     (1 << 6)
101
102 #define TRIGGER_TYPE_LEVEL_MASK  (TRIGGER_TYPE_ROW)
103 #define TRIGGER_TYPE_STATEMENT   0

23 translates to 00010111 in the least significant 8 bits, which should stand for:

CREATE TRIGGER trigger_name
BEFORE INSERT OR UPDATE ON table_name
FOR EACH ROW
EXECUTE PROCEDURE func_name();

A couple of quick tests in existing databases of mine seem to confirm it.

like image 54
Erwin Brandstetter Avatar answered Nov 15 '22 02:11

Erwin Brandstetter


Thanks rlib and Erwin. This was exactly what I was looking for.

I put together a query for this. I'll leave it here if anyone else needs it.

SELECT 
  n.nspname as schema_name, 
  c.relname as table_name, 
  t.tgname as trigger_name, 
  proname as function_name,
  tgtype::int::bit(7) as condition_bits,
  CASE WHEN (tgtype::int::bit(7) & b'0000001')::int = 0 THEN 'STATEMENT' ELSE 'EACH ROW' END as cond_row,
  COALESCE(
    CASE WHEN (tgtype::int::bit(7) & b'0000010')::int = 0 THEN NULL ELSE 'BEFORE' END,
    CASE WHEN (tgtype::int::bit(7) & b'0000010')::int = 0 THEN 'AFTER' ELSE NULL END,
    CASE WHEN (tgtype::int::bit(7) & b'1000000')::int = 0 THEN NULL ELSE 'INSTEAD' END,
    ''
  )::text as cond_timing, 
    (CASE WHEN (tgtype::int::bit(7) & b'0000100')::int = 0 THEN '' ELSE ' INSERT' END) ||
    (CASE WHEN (tgtype::int::bit(7) & b'0001000')::int = 0 THEN '' ELSE ' DELETE' END) ||
    (CASE WHEN (tgtype::int::bit(7) & b'0010000')::int = 0 THEN '' ELSE ' UPDATE' END) ||
    (CASE WHEN (tgtype::int::bit(7) & b'0100000')::int = 0 THEN '' ELSE ' TRUNCATE' END)
  as cond_event
FROM pg_trigger t
JOIN pg_proc p ON t.tgfoid = p.oid
JOIN pg_class c ON c.oid = t.tgrelid
JOIN pg_namespace n ON n.oid = c.relnamespace;

Edit:

Hmm, that was overkill. It turns out that the above bit-work is already done in the triggers view in the information_schema schema.

Easier: SELECT * FROM information_schema.triggers

like image 36
Michael Avatar answered Nov 15 '22 04:11

Michael