Enterprise Edition Home | Express Edition Home | Previous Page | Next Page   Database Access > Executing User-Defined Routines > Calling UDRs with the Fastpath Interface >

Obtaining Information from a Function Descriptor

You can use the following DataBlade API functions to obtain additional information about the UDR or cast function that is associated with a function descriptor.

DataBlade API Function Description
mi_fparam_get( ) Returns a pointer to the MI_FPARAM structure that is associated with the function descriptor
mi_routine_id_get( ) Returns the identifier for the UDR or cast function
mi_func_commutator( ) Determines if the UDR has a commutator function
mi_func_handlesnulls( ) Determines whether the UDR or cast function handles NULL arguments
mi_func_isvariant( ) Determines if the UDR or cast function is a variant function
mi_func_negator( ) Determines if the UDR has a negator function

Obtaining the MI_FPARAM Structure

By default, the Fastpath look-up functions allocate an MI_FPARAM structure and assign a pointer to this structure in the function descriptor. To obtain the MI_FPARAM structure that is associated with a function descriptor, use the mi_fparam_get( ) function. After the call to mi_fparam_get( ), you can use the MI_FPARAM accessor functions to retrieve information from the MI_FPARAM structure, such as argument information (Table 61) and return-value information (Table 62). For information about these accessor functions and the information that they can retrieve from an MI_FPARAM structure, see Accessing MI_FPARAM Routine-State Information.

Figure 51 shows the use of the mi_fparam_get( ) function to obtain the MI_FPARAM structure that is associated with the numeric_func( ) user-defined function. This code fragment uses the mi_fp_nrets( ) accessor function to obtain the number of return values for numeric_func( ) from the MI_FPARAM structure.

Tip:
You can allocate your own MI_FPARAM structure for a UDR that you execute with the Fastpath interface. For more information, see Using a User-Allocated MI_FPARAM Structure.

Obtaining a Routine Identifier

To obtain the identifier for a UDR or cast function that a function descriptor describes, use the mi_routine_id_get( ) function. A routine identifier is a unique integer that identifies a UDR within the sysprocedures system catalog. This routine identifier is stored in the procid column of sysprocedures.

The following code fragment obtains the identifier for the numeric_func( ) function that accepts INTEGER arguments:

MI_CONNECTION *conn;
MI_FUNC_DESC *fdesc;
mi_integer rout_id;
...
fdesc = mi_routine_get(conn, 0, 
   "function numeric_func(integer, integer)");
rout_id = mi_routine_id_get(conn, fdesc);
Server Only

If your UDR is executing many other UDRs and it needs to keep several function descriptors for subsequent execution, it can use the routine identifiers to distinguish the different function descriptors.

End of Server Only

Determining If a UDR Handles NULL Arguments

Before you execute a UDR with the Fastpath interface, you can determine whether this routine handles SQL NULL values as arguments. If the current argument values are SQL NULL values and the UDR does not handle NULL values, you do not need to call the actual UDR. By default, a C UDR does not handle NULL values. When the routine manager receives NULL arguments for such a UDR, it does not even invoke the UDR. It just returns a NULL value.

To determine whether the UDR or cast function that a function descriptor describes can handle SQL NULL values as arguments, use the mi_func_handlesnulls( ) function. This function determines whether the UDR was registered with the HANDLESNULLS routine modifier of the CREATE FUNCTION or CREATE PROCEDURE statement (stored in the handlesnulls column of the sysprocedures system catalog table).

The mi_func_handlesnulls( ) function indicates whether a UDR can handle SQL NULL values, as follows.

mi_func_handlesnulls( ) Return Value Meaning
1 The routine that the function descriptor describes has been registered with the HANDLESNULLS routine modifier.
2 The routine that the function descriptor describes has not been registered with the HANDLESNULLS routine modifier.

The code fragment in Figure 53 determines whether to invoke the numeric_func( ) function based on whether it handles NULL arguments.

Figure 53. Handling Fastpath Execution of a UDR with NULL Arguments
MI_CONNECTION *conn;
MI_FUNC_DESC *fdesc;
MI_FPARAM *fdesc_fparam;
MI_DATUM ret_val;
mi_integer error;
...
fdesc = mi_routine_get(conn, 0, 
   "function numeric_func(integer, integer)");

/* Determine whether to execute the UDR */
if ( mi_func_handlesnulls(fdesc) == 1 )
   {
   fdesc_fparam = mi_fparam_get(conn, fdesc);
   mi_fp_setargisnull(fdesc_fparam, 0, MI_TRUE);
   ret_val = mi_routine_exec(conn, fdesc, &error, 0, 2);
   }
else
   /* have numeric_func( ) return zero if it has NULL args */
   ret_val = 0;

If numeric_func( ) handles NULL arguments, the mi_func_handlesnulls( ) function returns 1 and the code fragment invokes numeric_func( ) with arguments of NULL and 2. The code fragment uses the mi_fparam_get( ) and mi_fp_setargisnull( ) functions to set the first argument to an SQL NULL value.

If numeric_func( ) does not handle NULL arguments, the code fragment does not invoke numeric_func( ); instead, it sets the return value of numeric_func( ) to zero (0).

Checking for a Variant Function

Before you execute a UDR with the Fastpath interface, you might need to determine whether this routine is variant. By default, a UDR is a variant function. A variant function has one of the following characteristics:

A nonvariant function always returns the same value when it receives the same arguments and it has none of the above variant side effects. Therefore, nonvariant functions cannot contain SQL statements or access external files.

To determine whether a UDR is variant, pass its function descriptor to the mi_func_isvariant( ) function. This function determines whether the user-defined function was registered with the VARIANT or NOT VARIAnt routine modifier of the CREATE FUNCTION or CREATE PROCEDURE statement. If the UDR was registered with neither the VARIANT nor NOT VARIANT modifier, the variant column of sysprocedures indicates that the UDR is variant.

The mi_func_isvariant( ) function indicates whether a UDR is variant, as follows.

mi_func_isvariant( ) Return Value Meaning
1 The routine that the function descriptor describes is variant.
2 The routine that the function descriptor describes is not variant.

For more information about variant and nonvariant functions, see the IBM Informix: User-Defined Routines and Data Types Developer's Guide.

Checking for a Negator Function

Before you execute a Boolean user-defined function with the Fastpath interface, you might want to determine whether this function has a negator function. A negator function evaluates the Boolean NOT condition for its associated Boolean user-defined function. In many cases, a negator can be more efficient to execute than the actual Boolean user-defined function.

To determine whether a user-defined function has a negator function, pass its function descriptor to the mi_func_negator( ) function. This function determines whether the user-defined function associated with this function descriptor was registered with the NEGATOR routine modifier of the CREATE FUNCTION statement. If so, mi_func_negator( ) returns the name of the negator function (from the negator column of the sysprocedures system catalog table). If the negator is more efficient, you can use this function name to obtain a function descriptor for the negator function with a Fastpath function such as mi_routine_get( ).

For more information about negator functions, see Creating Negator Functions.

Checking for a Commutator Function

Before you execute a user-defined function with the Fastpath interface, you might want to determine whether this function has a commutator function. If a user-defined function has either of the following characteristics, it is a commutator of another user-defined function:

In many cases, a commutator function can be more efficient to execute than the actual user-defined function.

To determine whether a user-defined function has a commutator function, pass its function descriptor to the mi_func_commutator( ) function. This function determines whether the user-defined function associated with this function descriptor was registered with the COMMUTATOR routine modifier of the CREATE FUNCTION statement. If so, mi_func_commutator( ) returns the name of the commutator function (from the commutator column of the sysprocedures system catalog table). If the commutator is more efficient, you can use this function name to obtain a function descriptor for the commutator function with a Fastpath function such as mi_routine_get( ).

For more information about commutator functions, see Creating Commutator Functions.

Enterprise Edition Home | Express Edition Home | [ Top of Page | Previous Page | Next Page | Contents | Index ]