One way to write an aggregate UDF to run the proper code required for an aggregation phase is to use the C switch statement.
To help illustrate what is required, the discussion uses code excerpts from a simple aggregate UDF that calculates the standard deviation. For the complete code example, see C Aggregate Function.
Here is an example:
#define SQL_TEXT Latin_Text
#include <sqltypes_td.h>
#include <string.h>
#include <math.h>
void STD_DEV ( FNC_Phase phase,
FNC_Context_t *fctx,
FLOAT *x,
FLOAT *result,
int *x_i,
int *result_i,
char sqlstate[6],
SQL_TEXT fncname[129],
SQL_TEXT sfncname[129],
SQL_TEXT error_message[257])
{
/* switch to determine the aggregation phase */
switch (phase)
{
/* This phase is executed once per group and */
/* allocates and initializes intermediate */
/* aggregate storage */
case AGR_INIT:
/* Get storage for intermediate aggregate values. */
...
/* Initialize the intermediate aggregate values */
...
/**************************************************/
/* Fall through to detail phase, because the */
/* AGR_INIT phase passes in the first set of */
/* values for the group. */
/**************************************************/
/* This phase is executed once for each selected */
/* row to aggregate. One copy will run on each AMP. */
case AGR_DETAIL:
...
break;
/* This phase combines the results of ALL */
/* individual AMPs for each group. */
case AGR_COMBINE:
...
break;
/* This phase returns the final result. */
/* It is called once for each group. */
case AGR_FINAL:
{
...
break;
}
case AGR_NODATA:
/* return null if no data */
*result_i = -1;
break;
default:
/* If it gets here there must be an error because this */
/* function does not accept any other phase options */
strcpy(sqlstate, "U0005");
}
return;
}