.During the plan building state, the server builds the query execution plan based on the best plan found during the query optimization state.
The [_enter_state], _describe_extfn, and [_leave_state] methods are called. The _enter_state and _leave_state methods are optional and called if provided by the UDF.
typedef enum a_v4_extfn_state { … EXTFNAPIV4_STATE_PLAN_BUILDING, … } a_v4_extfn_state;
At this point in query processing, the server determines what columns are needed from the UDF, and requests information about the columns needed from the table parameters.
If the UDF supports parallel processing, and if the server agrees that the query is eligible for parallelism, the server creates multiple instances of the UDF for distributed query processing.
In the Plan Building state, UDFs have access to all describe attributes.
As an example, the following code fragment queries the server to determine which columns are used:
a_sql_int32 rc; rg_udf *rgUdf = (rg_udf *)ctx->_user_data; rg_table *rgTable = rgUdf->rgTable; a_sql_uint32 buffer_size = 0; buffer_size = sizeof(a_v4_extfn_column_list) ( rgTable->number_of_columns - 1 ) * sizeof(a_sql_uint32); a_v4_extfn_column_list *ulist = (a_v4_extfn_column_list *)ctx->alloc( ctx, buffer_size ); memset(ulist, 0, buffer_size); rc = ctx->describe_parameter_get( ctx, 0, EXTFNAPIV4_DESCRIBE_PARM_TABLE_UNUSED_COLUMNS, ulist, buffer_size ); if( rc != buffer_size ) { ctx->free( ctx, ulist ); UDF_SQLERROR( PC(ctx), "Describe parameter type get failure.", rc == buffer_size ); } else { rgTable->unused_col_list = ulist; }
Assuming the above code fragment is from a Table UDF that produces 4 result set columns, and assuming the SQL statement was
SELECT c1, c2 FROM my_table_proc();
then the describe API returns only c1 and c2. This lets the UDF optimize the production of the result set values.