Subject Re: [IB-Architect] Table Inheritance
Author Joseph Alba
Dear Jim,

Does this mean you're (we're) back in business?
(I have a deadline to meet tomorrow so, just a few notes on OO - I mean
along Design Patterns style of thinking. I'll be a bit straight-forward but
that doesn't mean, I mean to lecture you because everybody knows you are the
dominant male of this IB pack.).

There are two ways that of OO structural reuse:
1. Inheritance
2. Interface.

Inheritance is done through Class definitions
Interface through dynamic binding - usually on object (instantiated) level.

Implications:
- Inheritance, being early binding, means that the semantics is well-defined
at definition point
- Interface, being dynamic, means that semantics may not be known until
run-time.(it may even be attached and detached).

If we want to do the OO thing correctly, I propose two ways of doing
triggers:
one for Inheritance, another for interface.

Inherited trigger is to be implemented like a method of a class. It should
be "contained" in the definition of the table, like:

1. INHERITANCE: (early/static binding: class definition):
---------------------

CREATE TABLE MYTABLE (
....
TRIGGER MYTRIGGER
)

TRIGGER MYTABLE.MYTRIGGER
AS
BEGIN

END;

[On the implementation side, I see that checking / verification of the
correctness of the table definition - along with triggers / along with
inheritance can be done at compile or commit time, and the final code can be
actually flattened out blr]

2. INTERFACE (dynamic binding: object level)
------------------
definition of triggers and assignation to which table(s) is done outside the
table (class) definition.

so the usual

create table mytable (
...
);

create trigger mytrigger for mytable ...

---------------------------------

The important difference between inheritance and interface is WHEN is the
semantics determined? As I pointed out, with inheritance it is determined
early - even at compile (commit/definition) time, but interface being
dynamic is done at run-time.

So, what does this imply (like in the math sense =>)

You only need to verify triggers that are defined within the class
definition. (I mean check whether the variables are there, the correct
referential contraints are in place)..

But with interface - being runtime, everybody (IB, the designer, the user)
knows that interface triggers get semantic meanings at runtime - so
REFERENTIAL CONSTRAINTS and the usual verification checks are postponed
until an actual runtime semantic error is encountered. So, you CAN skip the
referential checking ...

------------------------
In the present IB, I think there is a bit of confusion in this because the
triggers are structurally defined as Interface (thus they can be activated
and deactivated), but their semantics are enforced statically (class/table
definition level). This is the confusion that limits the potential
versatility of triggers.

If the present Interface defined triggers have their semantics correctly
deferred till run-time and semantic correctness is placed at the hands of
the programmer/designer - as runtime semantics are, then we can even assign
the same triggers to multiple tables.

So, the problem with triggers, in my opinion, presently is:
1. the definition for triggers is Interface (being outside of the table)
2. but the semantics is done at definition time instead of runtime. (which
is incompatible to what an interface is)

So, why not two types of triggers that are clearly defined and their
semantics properly assigned to whether it is static - compile time or
dynamic - runtime.

1. Contained triggers: (or you may say method triggers / event handlers)

create table my table (
....
trigger mytrigger on insert position 2;
)

trigger mytable.mytrigger
as
begin

end

The semantics of this trigger is done during compile time, so, the usual
referential checking for NEW/OLD variables, etc... is done.

The designer who wants these referential checks safely done for him
correctly knows that he is quite safe with regards to referential integrity
constraints of his new/old variables.

2. Interface triggers

create trigger mytrigger [for table[, table ...]]
before insert
...
as
begin
end;

This interface trigger can be assigned to multiple tables, it can be created
without being assigned to any table, but later you can say,

set trigger mytrigger for table[, table...]

If you notice the remark that interface is done through objects, you may
note that the table and interface trigger are two separate objects which a
relationship can be established at run-time [ unlike the previous contained
trigger which is intrinsically contained in the table definition and cannot
be detached from the table]

Being two separate objects, these means that the trigger and the table can
be attached or detached from one another at the will of the programmer.

But the most important implication is, that the complicated checks you are
worried about should disappear because it is not understood that the
semantics is relegated to the human programmer.

(I hope its not cryptic / crazy sounding, because I'm typing this as fast as
I can to get back to work... But I just want to THANK YOU, BBW for taking
this up. Nothing beats being in direct contact with the creator himself).

Joseph Alba
jalba@...