Subject | Re: External procedures: call for discussion |
---|---|
Author | paulruizendaal |
Post date | 2004-04-01T17:23:01Z |
Re:
M> Not only that - Stored Function need to be parsed in SQL as well.
Currently,
M> they clash with External Functions too. So a bit of syntax and a
bit of
M> parser changes should do it, AFAIU.
It is not that simple, I'm afraid. IMHO, Firebird is a bit confused
about functions and procedures. Firebird functions only exist as
UDF's. Firebird procedures cannot be used as a function in general
expressions: either it returns nothing and hence is a true procedure
or it returns a result set, a cursor if you will, that can only be
used in a FROM list.
This difference is deeply embedded in the implementation of both
UDF's and selectable procedures:
- UDF's are called from within the expression evaluator module, EVL
(see evl.cpp)
- selectable procedures are called from within the cursor handling
module, RSE (see rse.cpp)
The call environment is very different for both circumstances. The
call for UDF's is almost trivial, with arguments being pushed C-style
on a simulated stack and the result retrieved when the function
returns. The call for selectable procedures is much more complicated:
it "saves" the current query state and recursively enters the
execution module, EXE (see exe.cpp). When the procedure returns its
first record (=encounters its first SUSPEND), this state is saved and
the original query is resumed until it needs a next record from the
procedure. The code does quite some fancy footwork to make RSE and
EXE play ping-pong nicely.
Unifying real functions and selectable procedures in a single model
is a non-trivial task: if it were a matter of syntax, it would
already have been done.
Paul
M> Not only that - Stored Function need to be parsed in SQL as well.
Currently,
M> they clash with External Functions too. So a bit of syntax and a
bit of
M> parser changes should do it, AFAIU.
It is not that simple, I'm afraid. IMHO, Firebird is a bit confused
about functions and procedures. Firebird functions only exist as
UDF's. Firebird procedures cannot be used as a function in general
expressions: either it returns nothing and hence is a true procedure
or it returns a result set, a cursor if you will, that can only be
used in a FROM list.
This difference is deeply embedded in the implementation of both
UDF's and selectable procedures:
- UDF's are called from within the expression evaluator module, EVL
(see evl.cpp)
- selectable procedures are called from within the cursor handling
module, RSE (see rse.cpp)
The call environment is very different for both circumstances. The
call for UDF's is almost trivial, with arguments being pushed C-style
on a simulated stack and the result retrieved when the function
returns. The call for selectable procedures is much more complicated:
it "saves" the current query state and recursively enters the
execution module, EXE (see exe.cpp). When the procedure returns its
first record (=encounters its first SUSPEND), this state is saved and
the original query is resumed until it needs a next record from the
procedure. The code does quite some fancy footwork to make RSE and
EXE play ping-pong nicely.
Unifying real functions and selectable procedures in a single model
is a non-trivial task: if it were a matter of syntax, it would
already have been done.
Paul