Subject | Re: Architectural Cleanliness: CVT_move |
---|---|
Author | paulruizendaal |
Post date | 2003-12-21T17:30:23Z |
This message thread could be more prophetic than Helen imagined: not
only does the UDF interface expose an internal engine structure, it
exposes one that shouldn't be there. In my opinion, runtime
descriptors will go the way of the Dodo, perhaps not in FB2.0, but
certainly before FB3.0
(Forgive the long intro, but I'll get to the point in item 3 :^)
I think the engine execution runtime shows it age. It was designed as
a clever way to do co-routines in the original architecture (classic
+ gpre'd clients).
There are three things that could be better, I think:
1. Change the design paradigm from 'stalling looper' to 'multitasked
VM'. This will make the code flow easier to understand & maintain. It
is mostly a semantic change: if you think about it, impure areas in
requests are like stack frames and the type field of JRD_NODs are
like opcodes, etc.
2. Clearly separate the 'relational' VM and the 'procedural' VM. The
latter can & should be pugable. Perhaps the relational VM should be
plugable too, but it hard to see how more than one per ODS would make
sense. Perhaps it should not be plugable at all.
3. Move type casting decisions from the runtime to the compiler. SQL
is a strongly typed language and I believe so is GDML/blr Where type
casts are necessary is known at compile time. Figuring this out
repeatedly at runtime is inefficient, as is the overhead of
maintaining type information (i.e descriptors). Hence, descriptors
will be superfluous. The runtime will work with 'naked' values (i.e.
value union + null flag)
How the current design is broken shows, for instance, in UDF's that
return their result by descriptor: although you can return any type
you like, if it isn't the compile-time type, you'll create an error
condition further down the processing road.
I guess UDF's by descriptor were added as a quicky, braindead way of
signaling NULL values in parameters or in the return value. This
should have been done by defining a new value struct (value + null
flag) that became part of a published, maintainable, future proof API
(as Jim has already suggested). Would it be a good idea to move FB2.0
to such a UDF system? Or would it cause too much breakage?
BTW, can anybody tell me why there are 3 ways to signal NULL in the
current VM ??
1. return a null DSC pointer
2. set DSC_null flag in the descriptor
3. set req_null flag in the request
Slightly off-topic, I do see the need to provide UDF users with a
tool to cast types, especially from date to string and vice versa.
Would it be an idea to kill the current CVT_move entry point and to
bundle a separate dynamic lib with a type conversion utility like
CVT_move. I was thinking of doing something like that anyway.
If the core team is interested, let me know.
Paul
only does the UDF interface expose an internal engine structure, it
exposes one that shouldn't be there. In my opinion, runtime
descriptors will go the way of the Dodo, perhaps not in FB2.0, but
certainly before FB3.0
(Forgive the long intro, but I'll get to the point in item 3 :^)
I think the engine execution runtime shows it age. It was designed as
a clever way to do co-routines in the original architecture (classic
+ gpre'd clients).
There are three things that could be better, I think:
1. Change the design paradigm from 'stalling looper' to 'multitasked
VM'. This will make the code flow easier to understand & maintain. It
is mostly a semantic change: if you think about it, impure areas in
requests are like stack frames and the type field of JRD_NODs are
like opcodes, etc.
2. Clearly separate the 'relational' VM and the 'procedural' VM. The
latter can & should be pugable. Perhaps the relational VM should be
plugable too, but it hard to see how more than one per ODS would make
sense. Perhaps it should not be plugable at all.
3. Move type casting decisions from the runtime to the compiler. SQL
is a strongly typed language and I believe so is GDML/blr Where type
casts are necessary is known at compile time. Figuring this out
repeatedly at runtime is inefficient, as is the overhead of
maintaining type information (i.e descriptors). Hence, descriptors
will be superfluous. The runtime will work with 'naked' values (i.e.
value union + null flag)
How the current design is broken shows, for instance, in UDF's that
return their result by descriptor: although you can return any type
you like, if it isn't the compile-time type, you'll create an error
condition further down the processing road.
I guess UDF's by descriptor were added as a quicky, braindead way of
signaling NULL values in parameters or in the return value. This
should have been done by defining a new value struct (value + null
flag) that became part of a published, maintainable, future proof API
(as Jim has already suggested). Would it be a good idea to move FB2.0
to such a UDF system? Or would it cause too much breakage?
BTW, can anybody tell me why there are 3 ways to signal NULL in the
current VM ??
1. return a null DSC pointer
2. set DSC_null flag in the descriptor
3. set req_null flag in the request
Slightly off-topic, I do see the need to provide UDF users with a
tool to cast types, especially from date to string and vice versa.
Would it be an idea to kill the current CVT_move entry point and to
bundle a separate dynamic lib with a type conversion utility like
CVT_move. I was thinking of doing something like that anyway.
If the core team is interested, let me know.
Paul