Initialize the iterations

The first time that the database server calls the iterator function, the database server passes it an MI_FPARAM structure with the iterator status set to SET_INIT and the user-state pointer set to NULL. When the iterator function obtains this iterator-status value, it can perform the following initialization tasks for the iterator function:
  • Allocate memory for the structure in which you save the user-state information with a DataBlade® API memory-management function such as mi_dalloc()

    Make sure that this memory has a memory duration of PER_COMMAND so that the user state remains for the duration of all iterations of the iterator function. If the memory has the default PER_ROUTINE memory duration, the database server automatically deallocates it after only one iteration of the iterator function. For more information, see Choose the memory duration.

  • Save the user-state pointer in the MI_FPARAM structure with the mi_fp_funcstate() function

    Each subsequent call to the iterator function uses the same MI_FPARAM structure, so each iteration can reuse the cached user-state memory. The iterator function must save enough information to return values one at a time on demand. For more information, see Saving a user state.

You can perform these initialization tasks directly in the iterator function or you can declare a separate iterator-initialization function, which the iterator function calls when it receives the SET_INIT iterator-status value. Declare the iterator-initialization function to return the same data type as the main iterator function. However, the database server ignores the return value of this function; it does not put this return value in the active set.

The following code fragment implements an iterator-initialization function, call fibGen_init(), which the fibGen() iterator function (The fibGen() iterator function) calls when it obtains the SET_INIT iterator-status value.
Figure 1: The fibGen_init() initialization function
mi_integer fibGen_init(stop_val, fparam)
   mi_integer stop_val;
   MI_FPARAM *fparam;
{
   fibState   *fibstate;

/* Allocate the user-state structure, fibState. This user-state
 * structure is allocated with PER_COMMAND duration to hold the memory
 * until the end of all iterations of the iterator function.
 */
   fibstate = (fibState *)mi_dalloc(sizeof(fibState), PER_COMMAND);

/* Save a pointer to the user-state structure in the MI_FPARAM structure.
 */
   mi_fp_setfuncstate(fparam, (void *)fibstate);

/* Set return value of function to NULL for either of the following:
 *     - no argument passed into function (MI_FPARAM has a NULL argument)
 *     - stop value is < 0
 */
   if ( mi_fp_argisnull(fparam, 0) || stop_val < 0 ) 
      {
      mi_fp_setreturnisnull(fparam,0,1);
      return;
      }

/* Set the first two numbers of the series: 0 and 1. Set the stop value
 * field in the user-state structure (stop_val) to the stop value passed
 * to the function.
 */
   if ( stop_val < 1 ) 
      {
      fibstate->fib_prec1 = 0;
      fibstate->fib_prec2 = 1;
      fibstate->fib_ncomputed = 1;
      fibstate->fib_endval = stop_val; 
      }
   else 
      {
      fibstate->fib_prec1 = 0;
      fibstate->fib_prec2 = 1;
      fibstate->fib_ncomputed = 0;
      fibstate->fib_endval = stop_val; 
      }
   return (0); /* return value is ignored */
}

The fibGen_init() function returns an mi_integer value (0) because the main iterator function, fibGen(), returns an active set of mi_integer values. However, the database server does not return this value as part of the active set. After fibGen_init() completes, the database server calls the next iteration of fibGen() with an iterator-status value of SET_RETONE to return the first item of the active set.