TPF sample tpf_rg_2.cxx builds on the sample in tpf_rg_1.cxx and has similar behavior. It produces rows of data based on an input parameter.
This sample provides an alternate implementation of the _open_extfn method in the a_v4_extfn_func descriptor. The behavior is the same as tpf_rg_1 but the TPF uses fetch_into instead of fetch_block to read rows from the input table.
This code snippet from the _open_extfn method shows fetch_into retrieving rows from the input table:
static short UDF_CALLBACK tpf_rg_open( a_v4_extfn_table_context * tctx ) /***************************************/ { … … … // This block of code will create a statically allocated row block // that can contain at most 1 row of data. a_sql_uint32 c1_data; a_sql_byte c1_null = 0x0; a_sql_uint32 c1_len = 0; a_sql_byte null_mask = 0x1; a_sql_byte null_value = 0x1; a_v4_extfn_column_data cd[1] = { { &c1_null, // is_null null_mask, // null_mask null_value, // null_value &c1_data, // data &c1_len, // piece_len sizeof(c1_data), // max_piece_len NULL // blob } }; a_sql_uint32 r_status; a_v4_extfn_row row = { &r_status, &cd[0] }; a_v4_extfn_row_block rb = { 1, 0, &row }; // We are providing a row block structure that was statically // allocated to have a single row. This means that each call to // fetch_into will return at most 1 row. while( rs->fetch_into( rs, &rb ) ) { // Only consider non-null rows. They way the column data has // been defined allows us to treat c1_null as a boolean. if( !c1_null ) { num_to_generate += c1_data; } } … … }
When using fetch_into to retrieve rows from an input table, the TPF manages the row block structure. In this example, a static row block structure is created that retrieves one row at a time. Alternatively, you can allocate a dynamic structure that simultaneously supports an arbitrary number of rows.
In the code snippet, the row block structure defined to store the value of the column from the input table in the variable c1_data. If a NULL row is encountered, the variable c1_null is set to 1 to indicate this.