Call UDRs with the Fastpath interface

With the DataBlade® API Fastpath interface, DataBlade® API modules can directly invoke a UDR that was registered in the database. This interface bypasses the overhead associated with invoking a UDR through an SQL statement. This interface bypasses the query optimizer and executor, which are needed for an SQL statement. You can use this interface to execute any SQL routine.

Restriction: You cannot use the Fastpath interface to execute iterator functions or SPL functions with the WITH RESUME keywords in their RETURN statement.
The Fastpath interface is useful for calling a UDR in the following situations:
  • You do not know the location of the UDR you want to call.
  • At compile time, you do not know the name of the UDR you want to call.
  • You need to promote or cast arguments of the UDR you want to call.
  • The UDR you want to call is an overloaded routine and you need to obtain the version for particular argument data types.
  • The UDR you want to call is in a different shared-object file or DataBlade®. (Server only)

The Fastpath interface looks up a UDR or cast function in the system catalog tables to obtain information about the routine and then executes it. It passes any return values from the routine to the caller in internal (binary) format. With the Fastpath interface, a DataBlade® API module can call a foreign UDR.

Server only:

For a C UDR, a foreign UDR is a UDR that is not in the same shared-object file as the UDR that calls it. One UDR can only call another UDR directly when that called UDR is within the same shared-object file or DataBlade® module as the calling UDR. For example, in Calling a UDR directly from another UDR, the func3() user-defined function can directly call func2() because both of these functions are in the source1.so shared-object file.

However, there is no portable way for the C code in one shared-object file to directly call a function in another shared-object file. Different operating systems provide different degrees of support for this type of calling. In addition, if the foreign UDR is part of a DataBlade® module, your UDR has no way of knowing which DataBlade® modules might be installed at a particular customer site.

To call a foreign UDR, a C UDR must use the DataBlade® API Fastpath interface. The following figure shows how a UDR that is one shared-object file, source1.so, can call a foreign UDR, funcB(). Even though the funcB() routine is defined in the source2.so shared-object file, func3() can run the routine through the Fastpath interface.
Figure 1. Using Fastpath to access a routine in another shared-object file
begin figure description - This figure is described in the surrounding text. - end figure description

In preceding figure, the Fastpath interface loads the source2.so shared-object file, which contains the funcB() routine, into memory. For Fastpath to be able to invoke funcB(), the funcB() routine must already have been registered in the database. The call to funcB() within funcC() does not require use of the Fastpath interface because these two functions are in the same shared-object file, source2.so.

The Fastpath interface allows a DataBlade® developer to extend a DataBlade® module that someone else provides. This developer can define new UDRs on data types that some other DataBlade® provides.

For a client LIBMI application, a foreign UDR is any UDR that is registered in the database that is currently open. Client LIBMI programs can use the Fastpath interface to directly invoke registered UDRs.

You can execute foreign UDRs with an SQL statement, such as EXECUTE FUNCTION. However, Fastpath is usually a quicker method for the execution of a UDR because it bypasses query processing.
Important: For the Fastpath interface to execute a UDR, the UDR must be registered in the database with a CREATE FUNCTION or CREATE PROCEDURE statement. When you create a DataBlade®, register internal UDRs that might be of general use. In this way, you can cleanly protect private interfaces and support public ones.

The Fastpath interface provides the following DataBlade® API functions to look up a registered UDR, execute it, and free resources.

Table 1. DataBlade® API functions that look up a UDR and obtain a function descriptor for it
DataBlade® API function Purpose
mi_cast_get() Looks up a cast function that casts between two data types (specified by type identifiers) and returns its function descriptor
mi_func_desc_by_typeid() Looks up a UDR by its routine identifier and returns its function descriptor
mi_routine_get() Looks up a UDR by its routine signature (specified as a character string) and returns its function descriptor
mi_routine_get_by_typeid() Looks up a UDR by its routine signature (specified as separate arguments) and returns its function descriptor
mi_td_cast_get() Looks up a cast function that casts between two data types (specified by type descriptors) and returns its function descriptor
For more information, see Obtain a function descriptor.
Table 2. DataBlade® API functions that obtain information from a function descriptor
DataBlade® API function Purpose
mi_fparam_get() Returns a pointer to the MI_FPARAM structure that is associated with the function descriptor
mi_func_handlesnulls() Determines whether the UDR that is associated with the function descriptor can handle NULL arguments
mi_func_isvariant() Determines whether the user-defined function that is associated with the function descriptor is a variant function
mi_func_negator() Determines whether the user-defined function that is associated with the function descriptor has a negator function
mi_routine_id_get() Returns the identifier for the routine that is associated with the function descriptor
For more information, see Obtain information from a function descriptor.
Table 3. DataBlade® API functions that execute the UDR through its function descriptor
DataBlade® API function Purpose
mi_routine_exec() Executes a UDR that is associated with a specified function descriptor
For more information, see Execute the routine.
Table 4. DataBlade® API functions that use a user-allocated MI_FPARAM structure for the UDR
DataBlade® API function Purpose
mi_fparam_allocate() Allocates an MI_FPARAM structure
mi_fparam_copy() Creates a copy of an existing MI_FPARAM structure
mi_fparam_free() Deallocates a user-allocated MI_FPARAM structure
mi_fp_usr_fparam() Determines whether a specified MI_FPARAM has been allocated by the database server or the user
For more information, see A user-allocated MI_FPARAM structure.
Table 5. DataBlade® API functions that free resources that the function descriptor uses
DataBlade® API function Purpose
mi_routine_end() Releases resources that are associated with the function descriptor
For more information, see Release routine resources.