Buffering multiple results

The am_getnext purpose function can find and store several qualified rows in shared memory before it returns control to the database server.

About this task

To set up and fill in a multiple-row buffer shared memory:

Procedure

  1. Call mi_tab_setniorows() in am_open or am_beginscan to set the number of rows that the access method can return in one scan.
  2. Call mi_tab_niorows() at the start of am_getnext to find out how many rows to return.
  3. Loop through mi_tab_setnextrow() in am_getnext until the number of qualifying rows matches the return value of mi_tab_niorows() or until no more qualifying rows remain.

Example

The following figure shows the preceding steps.
Figure 1: Storing multiple results in a buffer
mi_integer sample_getnext(MI_AM_SCAN_DESC *sd, MI_ROW **retrow,
mi_integer *rowid
)
{
mi_integer nrows, row, fragid;
mi_integer retval;
MI_AM_TABLE_DESC *td =mi_scan_table(sd);

fragid = 0; /* table is not fragmented */

nrows = mi_tab_niorows(td);
if (nrows > 0)
{/*Store qualified results in shared-memory buffer.*/
for (row = 0; row < nrows; ++row)
{ /* Evaluate rows until we get one to return to caller. */
find_good_row(sd, retrow, rowid);
if (*retrow == MI_NULL) break;
mi_tab_setnextrow(td, *retrow, *rowid, fragid);
} /* End of loop for nrows times to fill shared memory.*/
retval = (row>0) ? MI_ROWS : MI_NO_MORE_RESULTS;
}/*End (nrows > 0). */
else
{/*Only one result per call to am_getnext.*/
find_good_row(sd, retrow, rowid);
retval = (retrow!=MI_NULL) ? MI_ROWS : MI_NO_MORE_RESULTS;
}
return retval;
} /* end function sample_getnext() */

The find_good_row() function is not shown here. If there is a row to return from the external data source, find_good_row() retrieves and assembles values and NULLs into arrays of MI_DATUM and mi_boolean, creates a row with mi_row_create(), sets nextrow and nextrowid accordingly, and returns. If there is no row to return, it sets nextrow to NULL.