Subject Re: [firebird-support] Values of RDB$TRIGGERS.RDB$TRIGGER _TYPE
Author Mark Rotteveel
On Fri, 22 Mar 2013 15:54:28 +0100, Josef Kokeš <j.kokes@...>
wrote:
>> > Hi!
>> >
>> > I wonder, is there a documentation of the various
>> > RDB$TRIGGERS.RDB$TRIGGER_TYPE values somewhere? The Interbase 6
>> > documentation (Language Reference, specifically) lists the values
for
>> > the regular BEFORE/AFTER INSERT/UPDATE/DELETE, but I can't find
values
>> > for multi-event triggers, e.g. BEFORE INSERT OR UPDATE. Is there a
>> > better way to find them than to create all possible trigger types
and
>> > see what appears in RDB$TRIGGERS?
>> >
>> > (I am using these values to translate a database structure to a
>> > human-readable form. But even for this limited purpose, I would feel
>> > more comfortable with the documented values than experimentally
>> obtained.)
>>
>> Take a look at the content of RDB$TYPES.
>
> I didn't remember about this table! Thanks!
>
> Unfortunately, it only lists the normal (single-action) triggers and the

> database-level triggers. At least in all my databases (ranging from FB
> 1.5 to FB 2.5).

You are right. Multi action values are encoded into a number of slots. The
Firebird Eclipse data tools project implementation decodes it as this:

/*
* type v s3 s2 s1 t
* BI - 1 - 00 00 00 1
* BU - 3 - 00 00 01 1
* BD - 5 - 00 00 10 1
* BIU - 17 - 00 10 00 1
* BID - 25 - 00 11 00 1
* BUD - 27 - 00 11 01 1
* BIUD - 113 - 11 10 00 1
*
* AI - 2 - 00 00 01 0
* AU - 4 - 00 00 10 0
* AD - 6 - 00 00 11 0
* AIU - 18 - 00 10 01 0
* AID - 26 - 00 11 01 0
* AUD - 28 - 00 11 10 0
* AIUD - 114 - 11 10 01 0
*
* Actual value (v) depends on definition order (eg order BUID = 107,
BDIU = 77)
*/
public void setFirebirdTriggerType(int type) {
// Select time of trigger (t)
final int beforeAfter = type & 0x01;
setActionTime(ACTION_TIME_TYPE[beforeAfter]);

// Transform before triggers to be identical to after triggers for
further processing
type += beforeAfter;
// Select slot1 (s1)
int slot1 = (type & 0x06) >>> 1; // (type & 00000110) >> 1
// Select slot2 (s2)
int slot2 = (type & 0x18) >>> 3; // (type & 00011000) >> 3
// Select slot3 (s3)
int slot3 = (type & 0x60) >>> 5; // (type & 01100000) >> 5

processSlot(slot1);
processSlot(slot2);
processSlot(slot3);
}

/**
* Process the slot value and set the appropriate trigger type (update,
delete or insert).
*
* @param slot Slot value (0 : None, 1: Insert, 2: Update, 3: Delete)
*/
private void processSlot(int slot) {
switch (slot) {
case 0:
// Do nothing
break;
case 1:
setInsertType(true);
break;
case 2:
setUpdateType(true);
break;
case 3:
setDeleteType(true);
break;
default:
throw new IllegalArgumentException("Unexpected value for
slot (expecting 0, 1, 2 or 3): " + slot);
}
}

Mark