Subject RE: [IB-Architect] UDF and null
Author Jim Starkey
At 01:19 PM 12/4/00 -0500, Leyne, Sean wrote:
>While I share some of your cynicism and concerns about the current UDF
>functionality, there does come a point where that developers must take
>responsibility for their work and for their systems/installations.


I chose to implement UDFs because it was neither desirable nor
feasible for Interbase to be the sole arbiter of database functionality.
I knew that the set of reasonable functions was open ended and that
reasonable developers could disagree over the details. I implemented
UDFs with the full knowledge that a badly written or malicious UDF could:

1. Crash the server
2. Corrupt a database
3. Compromise system integrity (server runs as root).
4. Leak memory without bound
5. Compromise database integrity and security
6. Enter an unstoppable infinite loop
7. Lock up a server.

Given the technology available at the time, these were inherent risks
that a DBA could chose to accept or reject. I considered the problem
at length, concluding that given the alternatives, the benefits of
UDFs to conscientious developers outweighed their liabilities.

There were other things about the implementation I was never happy
with. One was an inability to pass a full transaction context to
the UDF. A UDF should be able to do database access under the
same security constraints and transaction control of the invoking
database language. Another was a way to package UDFs with a
database backup. Another was a cross platform UDF strategy. Another
was a mechanism to debug UDF in situ.

The software world today is radically different from when I originally
designed and implemented UDFs. Processors are blindingly fast, memory
is dirt cheap and plentiful, and we have more sophisticated tools
and infrastructures for designing systems. As designers, we need
to remember that all designs are compromises, and if the world changes,
compromises need to be revisited from time to time.

Java is the idea solution to database embedded UDFs. Java code
runs in a controlled sandbox. A Java method cannot see, let along
change, anything that is not within the sandbox. Java cannot leak
memory (a JVM can, but that is a bug). A Java method can be safely
unwound without lose of resource or danger of deadlock. Resources,
memory and processor, can monitored and constrained. Java, as an
object oriented language, provides a mechanism through which arbitrary
context can be made available to a UDF, including connection handling.
Java has a well defined exception mechanism, allowing a UDF to cry
for help. Java code is intrinsically cross platform and can be
readily stored within the database itself, permitting backup of
the UDF itself, not just its name. Java is a stable, widely
respected standard with dozens of independent JVM implementations.
And Java has a debug architecture consistent with remote debugging.

The decision to allow arbitrary untrusted code to run within a
database server was justified by necessity in 1985. It is not
justifiable today. If Firebird is going to thrive in this century,
it must grow with available technology or be supplanted by more
vibrant products.

Firebird UDFs don't need more functional buggy whips, they electronic
ignition, digital fuel management, and automatic transmissions.

Deprecating (while maintaining) the existing UDF mechanism makes
sense for backwards compatibility. Extending them for trivial
gains does not.

Jim Starkey