The MI_FPARAM structure for holding private-state information

The MI_FPARAM structure is associated with the routine sequence. Therefore, for a UDR in a query that executes in parallel, each thread has its own routine sequence and therefore its own MI_FPARAM structure. The first invocation of the routine by each thread would have to perform any initialization. Only UDRs that are declared as parallelizable can be executed in parallel queries. The database server always executes an SQL statement that contains a non-parallelizable UDR serially.
Tip: By default, the CREATE FUNCTION statement registers a UDR as non-parallelizable. To declare a user-defined function as parallelizable, specify the PARALLELIZABLE routine modifier in the CREATE FUNCTION or CREATE PROCEDURE statement.

The MI_FPARAM structure has a memory duration of PER_COMMAND. The database server re-initializes the user-state information that mi_fp_funcstate() references to NULL at the end of the SQL command (for example, at the end of the subquery execution for each outer row from an outer query).

The following code example implements the rowcount() function. This function uses the MI_FPARAM structure to hold a count of the number of rows in a query.
/* The rowcount() function maintains the row count with a variable that
 * is stored as user-state information in the MI_FPARAM structure 
 */
mi_integer rowcount (fparam_ptr)
   MI_FPARAM *fparam_ptr;
{
   mi_integer *count = NULL;

   /* obtain the current user-state pointer from the MI_FPARAM structure */
   count = (mi_integer *)mi_fp_funcstate(fparam_ptr);

   /* if the user-state pointer is NULL, this is the first 
    * invocation of the function
    */
   if ( count == NULL )
      {
      /* allocate memory for the user-state information */
      count = (mi_integer *)mi_dalloc(sizeof(mi_integer), PER_COMMAND);

      /* save user-state pointer in the MI_FPARAM structure */
      mi_fp_setfuncstate(fparam_ptr, (void *)count);

      /* initialize the row counter */
      *count = 0;
      }

   /* increment the row counter */
   (*count)++;
   return (*count);
}
The rowcount() function uses the mi_fp_funcstate() function to obtain the user-state pointer from the MI_FPARAM structure. If this pointer is NULL, rowcount() allocates memory for the count variable and uses the mi_fp_setfuncstate() function to store this pointer as the user-state pointer in the MI_FPARAM structure. It uses the mi_dalloc() function to allocate this memory with a duration of PER_COMMAND so that the database server does not deallocate the memory after the first invocation of the function.
Tip: The rowcount() function in the preceding code example shows how to use the MI_FPARAM structure to hold private user-state information. This method removes the need for global or static variables, which can make a C UDR ill-behaved. The code fragment in Avoid modification of global and static variables shows the bad_rowcount() function, which incorrectly implements a row counter with a static variable.
For the rowcount() function to be used in an SQL statement, it must be registered in the database. The following CREATE FUNCTION statement registers the rowcount() function for use in SQL statements:
CREATE FUNCTION rowcount() RETURNS INTEGER
   EXTERNAL NAME '/usr/lib/db_funcs/count.so(rowcount)'
   LANGUAGE C;
The CREATE FUNCTION statement must omit the MI_FPARAM argument; therefore the registered rowcount() function has no arguments. Suppose that the following query uses the rowcount() function:
SELECT rowcount() from employee;
The query calls the rowcount() function for each row in the employee table. Because the rowcount() function uses the MI_FPARAM structure to hold its state information (the count variable), each query has its own private count variable. Separate queries do not interfere with one another as they might with static and global variables.
Tip: You can also implement the rowcount() function as a user-defined aggregate function. User-defined aggregates do not use the MI_FPARAM structure to hold state information.