#define SQL_TEXT Latin_Text #include <sqltypes_td.h> #include <string.h> typedef struct agr_storage { int cr; // current rank int pv; // previous value } AGR_Storage; void dense_rank( FNC_Phase phase, FNC_Context_t *fctx, INTEGER *x, INTEGER *result, int *x_i, int *result_i, char sqlstate[6], SQL_TEXT fncname[129], SQL_TEXT sfncname[129], SQL_TEXT error_message[257] ) { /* pointer to intermediate storage area */ AGR_Storage *s1 = fctx->interim1; /* switch to determine the aggregation phase */ switch (phase) { case AGR_INIT: /* This UDF currently handles only the cumulative window */ /* type for illustrative purposes. */ if (fctx->window_size != -1) { strcpy(error_message,"Only cumulative window type supported"); strcpy(sqlstate, "U0001"); /* see SQLSTATE table */ return; } if ( (s1=FNC_DefMem(sizeof(AGR_Storage))) == NULL) { strcpy(sqlstate, "U0002"); return; } s1->cr = 1; s1->pv = *x; /***************************************************/ /* Fall through to the detail phase */ /***************************************************/ case AGR_DETAIL: if (*x != s1->pv) { s1->cr++; s1->pv = *x; } break; case AGR_FINAL: *result = s1->cr; break; /* Add this to generate an error for any undefined phases */ case AGR_COMBINE: case AGR_MOVINGTRAIL: default: sprintf(error_message,"phase is %d",phase); strcpy(sqlstate, "U0005"); return; } }