char *oph_predicate2(UDF_INIT * initid, UDF_ARGS * args, char *result, unsigned long *length, char *is_null, char *error) { oph_string measure; char *buffer; char **names; int count; oph_predicate2_param *param; int i = 0; if (core_set_type(&(measure), args->args[0], &(args->lengths[0]))) { pmesg(1, __FILE__, __LINE__, "Type not recognized\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } measure.content = args->args[2]; measure.length = &(args->lengths[2]); measure.missingvalue = NULL; core_set_elemsize(&(measure)); if (core_set_numelem(&(measure))) { pmesg(1, __FILE__, __LINE__, "Error on counting elements\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } if (!initid->ptr) { initid->ptr = (char *) malloc(sizeof(oph_predicate2_param)); if (!initid->ptr) { pmesg(1, __FILE__, __LINE__, "Error allocating result string\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } param = (oph_predicate2_param *) initid->ptr; for (i = 0; i < 4; ++i) param->f[i] = NULL; param->occurrence = 0; // ALL buffer = (char *) malloc(1 + args->lengths[3]); strncpy(buffer, args->args[3], args->lengths[3]); buffer[args->lengths[3]] = '\0'; pthread_rwlock_wrlock(&lock); param->f[1] = evaluator_create(buffer); pthread_rwlock_unlock(&lock); free(buffer); if (!param->f[1]) { pmesg(1, __FILE__, __LINE__, "Error allocating evaluator\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } evaluator_get_variables(param->f[1], &names, &count); if (count > 1) { pmesg(1, __FILE__, __LINE__, "Too variables in expression\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } // Comparison operator if (core_set_comp(¶m->op, args->args[4], &(args->lengths[4]))) { pmesg(1, __FILE__, __LINE__, "Comparison operator not recognized\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } if (args->args[5] && args->lengths[5]) { buffer = (char *) malloc(1 + args->lengths[5]); core_strncpy(buffer, args->args[5], &(args->lengths[5])); if (!strcasecmp(buffer, "nan")) sprintf(buffer, "0/0"); } else buffer = strdup("0/0"); pthread_rwlock_wrlock(&lock); param->f[2] = evaluator_create(buffer); pthread_rwlock_unlock(&lock); free(buffer); if (!param->f[2]) { pmesg(1, __FILE__, __LINE__, "Error allocating evaluator\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } evaluator_get_variables(param->f[2], &names, &count); if (count > 1) { pmesg(1, __FILE__, __LINE__, "Too variables in expression\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } if (args->args[6] && args->lengths[6]) { buffer = (char *) malloc(1 + args->lengths[6]); core_strncpy(buffer, args->args[6], &(args->lengths[6])); if (!strcasecmp(buffer, "nan")) sprintf(buffer, "0/0"); } else buffer = strdup("0/0"); pthread_rwlock_wrlock(&lock); param->f[3] = evaluator_create(buffer); pthread_rwlock_unlock(&lock); free(buffer); if (!param->f[3]) { pmesg(1, __FILE__, __LINE__, "Error allocating evaluator\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } evaluator_get_variables(param->f[3], &names, &count); if (count > 1) { pmesg(1, __FILE__, __LINE__, "Too variables in expression\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } oph_string output_array; core_set_type(&output_array, args->args[1], &(args->lengths[1])); if (!output_array.type) { pmesg(1, __FILE__, __LINE__, "Unable to recognize measures type\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } if (core_set_elemsize(&output_array)) { pmesg(1, __FILE__, __LINE__, "Unable to recognize measures type\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } param->result_type = output_array.type; param->result_elemsize = output_array.elemsize; param->length = output_array.elemsize * measure.numelem; param->f[0] = malloc(param->length); if (!param->f[0]) { pmesg(1, __FILE__, __LINE__, "Error allocating result string\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } if (args->arg_count > 7) { buffer = (char *) malloc(1 + args->lengths[7]); core_strncpy(buffer, args->args[7], &(args->lengths[7])); if (strcasecmp(buffer, OPH_PREDICATE2_ALL_OCCURRENCE)) { if (!strcasecmp(buffer, OPH_PREDICATE2_FIRST_OCCURRENCE) || !strcasecmp(buffer, OPH_PREDICATE2_BEGIN_OCCURRENCE)) param->occurrence = 1; else if (!strcasecmp(buffer, OPH_PREDICATE2_LAST_OCCURRENCE) || !strcasecmp(buffer, OPH_PREDICATE2_END_OCCURRENCE)) param->occurrence = -1; else { if (args->arg_type[7] == STRING_RESULT) param->occurrence = (long) strtol(buffer, NULL, 10); else param->occurrence = *((long long *) args->args[7]); if (param->occurrence < 1) { free(buffer); pmesg(1, __FILE__, __LINE__, "Unable to read occurrence\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } } } free(buffer); } } else param = (oph_predicate2_param *) initid->ptr; i = core_oph_predicate2(&measure, initid->ptr); if (i) { pmesg(1, __FILE__, __LINE__, "Unable to compute result\n"); *length = 0; *is_null = 0; *error = 1; return NULL; } *length = param->length; *error = 0; *is_null = 0; return (char *) param->f[0]; }
void oph_aggregate_stats_partial_add(UDF_INIT * initid, UDF_ARGS * args, char *is_null, char *error) { if (*error != 0) return; if (args->args[2]) { oph_agg_stats_partial_data *dat = (oph_agg_stats_partial_data *) initid->ptr; /* Setting of the aggregate result */ if (!dat->result.content) { //It's the first row // default values unsigned long def_mask_len = MASK_LEN; dat->mask.content = (char *) calloc(MASK_LEN + 1, sizeof(char)); if (!dat->mask.content) { pmesg(1, __FILE__, __LINE__, "Error allocating mask content\n"); *error = 1; return; } core_strncpy(dat->mask.content, DEFAULT_MASK, &def_mask_len); dat->mask.length = (unsigned long *) calloc(1, sizeof(unsigned long)); if (!dat->mask.length) { pmesg(1, __FILE__, __LINE__, "Error allocating mask length\n"); *error = 1; return; } *(dat->mask.length) = def_mask_len; core_set_type(&(dat->measure), NULL, 0); dat->measure.length = (unsigned long *) calloc(1, sizeof(unsigned long)); if (!dat->measure.length) { pmesg(1, __FILE__, __LINE__, "Error allocating measure length\n"); *error = 1; return; } *(dat->measure.length) = args->lengths[2]; core_set_type(&(dat->measure), args->args[0], &(args->lengths[0])); if (dat->measure.type != OPH_SHORT && dat->measure.type != OPH_BYTE && dat->measure.type != OPH_INT && dat->measure.type != OPH_LONG && dat->measure.type != OPH_FLOAT && dat->measure.type != OPH_DOUBLE) { pmesg(1, __FILE__, __LINE__, "Invalid type\n"); *error = 1; return; } if (args->arg_count > 3) { core_strncpy(dat->mask.content, args->args[3], &(args->lengths[3])); *(dat->mask.length) = args->lengths[3]; } if (core_set_elemsize(&(dat->measure))) { pmesg(1, __FILE__, __LINE__, "Error on setting measure elements size\n"); *error = 1; return; } if (core_set_numelem(&(dat->measure))) { pmesg(1, __FILE__, __LINE__, "Error on counting measure elements\n"); *error = 1; return; } core_set_type(&dat->result, args->args[1], &(args->lengths[1])); if (!dat->result.type) { pmesg(1, __FILE__, __LINE__, "Unable to recognize measures type\n"); *error = 1; return; } if (core_set_elemsize(&dat->result)) { pmesg(1, __FILE__, __LINE__, "Unable to recognize measures type\n"); *error = 1; return; } // mask processing int i; for (i = 0; i < *(dat->mask.length); i++) { if (dat->mask.content[i] == '1') { (dat->mask.numelem)++; // count 1s switch (i) { case 0: // mean dat->sum1 = 1; // sum{x_i} needed break; case 1: // variance dat->sum1 = 1; dat->sum2 = 1; // sum{(x_i)^2} needed break; case 2: // std dev dat->sum1 = 1; dat->sum2 = 1; break; case 3: // skew dat->sum1 = 1; dat->sum2 = 1; dat->sum3 = 1; // sum{(x_i)^3} needed break; case 4: // kurtosis dat->sum1 = 1; dat->sum2 = 1; dat->sum3 = 1; dat->sum4 = 1; // sum{(x_i)^4} needed break; case 5: // max dat->max = 1; // array with max values needed break; case 6: // min dat->min = 1; // array with min values needed } } } if (dat->mask.numelem == 0) { pmesg(1, __FILE__, __LINE__, "Invalid mask\n"); *error = 1; return; } int size = 1; if (dat->sum1) size++; if (dat->sum2) size++; if (dat->sum3) size++; if (dat->sum4) size++; if (dat->max) size++; if (dat->min) size++; // output array allocation dat->result.numelem = size * dat->measure.numelem; // In future use a structed type of 'size' fields unsigned long outlen = dat->result.numelem * dat->result.elemsize; dat->result.length = (unsigned long *) calloc(1, sizeof(unsigned long)); if (!dat->result.length) { pmesg(1, __FILE__, __LINE__, "Error allocating result length\n"); *error = 1; return; } *(dat->result.length) = outlen; dat->result.content = (char *) calloc(1, *(dat->result.length)); if (!dat->result.content) { pmesg(1, __FILE__, __LINE__, "Error allocating output array\n"); *error = 1; return; } // partial results array allocation dat->partials = (oph_stringPtr) calloc((size - 1), sizeof(oph_string)); if (!dat->partials) { pmesg(1, __FILE__, __LINE__, "Error allocating intermediate arrays\n"); *error = 1; return; } for (i = 0; i < (size - 1); i++) { dat->partials[i].type = dat->measure.type; dat->partials[i].elemsize = dat->measure.elemsize; dat->partials[i].numelem = dat->measure.numelem; dat->partials[i].length = dat->measure.length; dat->partials[i].content = (char *) calloc(1, *(dat->partials[i].length)); if (!dat->partials[i].content) { pmesg(1, __FILE__, __LINE__, "Error allocating intermediate array\n"); *error = 1; return; } } } if (!dat->count) { //It's the first row or the first row in the group of the GROUP BY clause int i = 0; int j; // copy input values if (dat->sum1) { memcpy((void *) (dat->partials[i].content), (void *) (args->args[2]), *(dat->partials[i].length)); i++; } // copy input values squared if (dat->sum2) { switch (dat->measure.type) { case OPH_INT: { int val_i; for (j = 0; j < dat->measure.numelem; j++) { val_i = ((int *) (args->args[2]))[j]; ((int *) (dat->partials[i].content))[j] = val_i * val_i; } break; } case OPH_SHORT: { int val_i; for (j = 0; j < dat->measure.numelem; j++) { val_i = ((short *) (args->args[2]))[j]; ((short *) (dat->partials[i].content))[j] = val_i * val_i; } break; } case OPH_BYTE: { int val_i; for (j = 0; j < dat->measure.numelem; j++) { val_i = ((char *) (args->args[2]))[j]; ((char *) (dat->partials[i].content))[j] = val_i * val_i; } break; } case OPH_LONG: { long long val_l; for (j = 0; j < dat->measure.numelem; j++) { val_l = ((long long *) (args->args[2]))[j]; ((long long *) (dat->partials[i].content))[j] = val_l * val_l; } break; } case OPH_FLOAT: { float val_f; for (j = 0; j < dat->measure.numelem; j++) { val_f = ((float *) (args->args[2]))[j]; ((float *) (dat->partials[i].content))[j] = val_f * val_f; } break; } case OPH_DOUBLE: { double val_d; for (j = 0; j < dat->measure.numelem; j++) { val_d = ((double *) (args->args[2]))[j]; ((double *) (dat->partials[i].content))[j] = val_d * val_d; } } case OPH_COMPLEX_INT: case OPH_COMPLEX_LONG: case OPH_COMPLEX_FLOAT: case OPH_COMPLEX_DOUBLE: case INVALID_TYPE: break; } i++; } // copy input values raised to 3 if (dat->sum3) { switch (dat->measure.type) { case OPH_INT: { int val_i; for (j = 0; j < dat->measure.numelem; j++) { val_i = ((int *) (args->args[2]))[j]; ((int *) (dat->partials[i].content))[j] = val_i * val_i * val_i; } break; } case OPH_SHORT: { short val_i; for (j = 0; j < dat->measure.numelem; j++) { val_i = ((short *) (args->args[2]))[j]; ((short *) (dat->partials[i].content))[j] = val_i * val_i * val_i; } break; } case OPH_BYTE: { char val_i; for (j = 0; j < dat->measure.numelem; j++) { val_i = ((char *) (args->args[2]))[j]; ((char *) (dat->partials[i].content))[j] = val_i * val_i * val_i; } break; } case OPH_LONG: { long long val_l; for (j = 0; j < dat->measure.numelem; j++) { val_l = ((long long *) (args->args[2]))[j]; ((long long *) (dat->partials[i].content))[j] = val_l * val_l * val_l; } break; } case OPH_FLOAT: { float val_f; for (j = 0; j < dat->measure.numelem; j++) { val_f = ((float *) (args->args[2]))[j]; ((float *) (dat->partials[i].content))[j] = val_f * val_f * val_f; } break; } case OPH_DOUBLE: { double val_d; for (j = 0; j < dat->measure.numelem; j++) { val_d = ((double *) (args->args[2]))[j]; ((double *) (dat->partials[i].content))[j] = val_d * val_d * val_d; } } case OPH_COMPLEX_INT: case OPH_COMPLEX_LONG: case OPH_COMPLEX_FLOAT: case OPH_COMPLEX_DOUBLE: case INVALID_TYPE: break; } i++; } // copy input values raised to 4 if (dat->sum4) { switch (dat->measure.type) { case OPH_INT: { int val_i; for (j = 0; j < dat->measure.numelem; j++) { val_i = ((int *) (args->args[2]))[j]; ((int *) (dat->partials[i].content))[j] = val_i * val_i * val_i * val_i; } break; } case OPH_SHORT: { short val_i; for (j = 0; j < dat->measure.numelem; j++) { val_i = ((short *) (args->args[2]))[j]; ((short *) (dat->partials[i].content))[j] = val_i * val_i * val_i * val_i; } break; } case OPH_BYTE: { char val_i; for (j = 0; j < dat->measure.numelem; j++) { val_i = ((char *) (args->args[2]))[j]; ((char *) (dat->partials[i].content))[j] = val_i * val_i * val_i * val_i; } break; } case OPH_LONG: { long long val_l; for (j = 0; j < dat->measure.numelem; j++) { val_l = ((long long *) (args->args[2]))[j]; ((long long *) (dat->partials[i].content))[j] = val_l * val_l * val_l * val_l; } break; } case OPH_FLOAT: { float val_f; for (j = 0; j < dat->measure.numelem; j++) { val_f = ((float *) (args->args[2]))[j]; ((float *) (dat->partials[i].content))[j] = val_f * val_f * val_f * val_f; } break; } case OPH_DOUBLE: { double val_d; for (j = 0; j < dat->measure.numelem; j++) { val_d = ((double *) (args->args[2]))[j]; ((double *) (dat->partials[i].content))[j] = val_d * val_d * val_d * val_d; } } case OPH_COMPLEX_INT: case OPH_COMPLEX_LONG: case OPH_COMPLEX_FLOAT: case OPH_COMPLEX_DOUBLE: case INVALID_TYPE: break; } i++; } // copy input values if (dat->max) { memcpy(dat->partials[i].content, (void *) (args->args[2]), *(dat->partials[i].length)); i++; } // copy input values if (dat->min) { memcpy(dat->partials[i].content, (void *) (args->args[2]), *(dat->partials[i].length)); i++; } } else { // Not the first row in the group => execute next aggregation step dat->measure.content = args->args[2]; int i = 0; if (dat->sum1) { if (core_oph_sum_array(&(dat->measure), &(dat->partials[i]), dat->partials[i].content)) { pmesg(1, __FILE__, __LINE__, "Unable to compute result\n"); *error = 1; return; } i++; } if (dat->sum2) { if (core_oph_sum2_array(&(dat->measure), &(dat->partials[i]), dat->partials[i].content)) { pmesg(1, __FILE__, __LINE__, "Unable to compute result\n"); *error = 1; return; } i++; } if (dat->sum3) { if (core_oph_sum3_array(&(dat->measure), &(dat->partials[i]), dat->partials[i].content)) { pmesg(1, __FILE__, __LINE__, "Unable to compute result\n"); *error = 1; return; } i++; } if (dat->sum4) { if (core_oph_sum4_array(&(dat->measure), &(dat->partials[i]), dat->partials[i].content)) { pmesg(1, __FILE__, __LINE__, "Unable to compute result\n"); *error = 1; return; } i++; } if (dat->max) { if (core_oph_max_array(&(dat->measure), &(dat->partials[i]), dat->partials[i].content)) { pmesg(1, __FILE__, __LINE__, "Unable to compute result\n"); *error = 1; return; } i++; } if (dat->min) { if (core_oph_min_array(&(dat->measure), &(dat->partials[i]), dat->partials[i].content)) { pmesg(1, __FILE__, __LINE__, "Unable to compute result\n"); *error = 1; return; } i++; } } dat->count++; } }