Function descriptors within an SQL command
When you pass a public connection descriptor to one of the Fastpath look-up functions, the look-up function allocates the function descriptor with a PER_COMMAND memory duration. Therefore, the function descriptor remains allocated for the duration of the SQL command that invokes the UDR.
For a list of Fastpath look-up functions, see Table 1.
To cache the function descriptor, save its address in the MI_FPARAM structure of the UDR. The MI_FPARAM structure has a PER_COMMAND duration. Therefore, storing the function-descriptor address in the user state of MI_FPARAM guarantees that all UDR invocations within the SQL command can access it. You can also cache the connection description in MI_FPARAM. When the SQL command completes, the function descriptor, the connection descriptor, and the MI_FPARAM structure are deallocated.
mi_integer non_optimal(arg1, arg2, fparam)
mi_integer arg1, arg2;
MI_FPARAM *fparam;
{
MI_CONNECTION *conn=NULL;
MI_FUNC_DESC *func_desc=NULL;
MI_DATUM func_result;
mi_integer func_error;
mi_string *func_sig="equal(int, int)";
/* Open a connection */
if ( (conn = mi_open(NULL, NULL, NULL))
== (MI_CONNECTION *)NULL )
{
mi_db_error_raise(NULL, MI_EXCEPTION,
"mi_open() call failed");
return MI_ERROR;
}
/* Get the function descriptor for equal() */
if ( (func_desc = mi_routine_get(conn, 0, func_sig))
== (MI_FUNC_DESC *)NULL )
{
mi_db_error_raise(NULL, MI_EXCEPTION,
"mi_routine_get() call failed");
return MI_ERROR;
}
/* Execute the equal() user-defined function */
func_result = mi_routine_exec(conn, func_desc, &func_error,
arg1, arg2);
if ( func_error == MI_ERROR )
{
mi_db_error_raise(NULL, MI_EXCEPTION,
"mi_routine_exec() call failed");
return MI_ERROR;
}
...
typedef struct user_state
{
MI_CONNECTION *conn;
MI_FUNC_DESC *func_desc;
};
mi_integer optimal(arg1, arg2, fparam)
mi_integer arg1, arg2;
MI_FPARAM *fparam;
{
MI_CONNECTION *local_conn = NULL;
MI_FUNC_DESC *local_fdesc = NULL;
mi_string *func_sig="equal(int, int)";
user_state *func_state;
/* Obtain the connection descriptor from MI_FPARAM */
func_state = (user_state *)mi_fp_funcstate(fparam);
if ( func_state == NULL ) /* first time UDR is called */
{
/* Allocate a user_state structure */
func_state =
(user_state *)mi_dalloc(sizeof(user_state),
PER_COMMAND);
/* Obtain the connection descriptor */
if ( (local_conn = mi_open(NULL, NULL, NULL))
== (MI_CONNECTION *)NULL )
{
mi_db_error_raise(NULL, MI_EXCEPTION,
"mi_open() call failed");
return MI_ERROR;
}
/* Obtain the function descriptor for equal() */
if ( (local_fdesc =
mi_routine_get(local_conn, 0, func_sig))
== (MI_FUNC_DESC *)NULL )
{
mi_db_error_raise(NULL, MI_EXCEPTION,
"mi_routine_get() call failed");
return MI_ERROR;
}
/* Cache the connection descriptor and function
* descriptor in MI_FPARAM
*/
func_state->conn = local_conn;
func_state->func_desc = local_fdesc;
/* Save the user state in MI_FPARAM */
mi_fp_setfuncstate(fparam, (void *)func_state);
}
/* Execute the equal() user-defined function */
func_result = mi_routine_exec(func_state->conn,
func_state->func_desc, &func_error, arg1, arg2);
if ( func_error == MI_ERROR )
{
mi_db_error_raise(NULL, MI_EXCEPTION,
"mi_routine_exec() call failed");
return MI_ERROR;
}
...