Datum quantile_numeric(PG_FUNCTION_ARGS) { int idx; struct_numeric * data; CHECK_AGG_CONTEXT("quantile_numeric", fcinfo); if (PG_ARGISNULL(0)) { PG_RETURN_NULL(); } data = (struct_numeric*)PG_GETARG_POINTER(0); qsort(data->elements, data->next, sizeof(Numeric), &numeric_comparator); if (data->quantiles[0] > 0) { idx = (int)ceil(data->next * data->quantiles[0]) - 1; } else { idx = 0; } PG_RETURN_NUMERIC(data->elements[idx]); }
Datum quantile_double(PG_FUNCTION_ARGS) { int idx = 0; double *result; struct_double * data; CHECK_AGG_CONTEXT("quantile_double", fcinfo); if (PG_ARGISNULL(0)) { PG_RETURN_NULL(); } data = (struct_double*)PG_GETARG_POINTER(0); result = palloc(data->nquantiles * sizeof(double)); qsort(data->elements, data->next, sizeof(double), &double_comparator); if ((data->quantiles[0] > 0) && (data->quantiles[0] < 1)) { idx = (int)ceil(data->next * data->quantiles[0]) - 1; } else { idx = 0; } PG_RETURN_FLOAT8(data->elements[idx]); }
Datum count_distinct_deserial(PG_FUNCTION_ARGS) { element_set_t *eset = (element_set_t *)palloc(sizeof(element_set_t)); bytea *state = (bytea *)PG_GETARG_POINTER(0); #ifdef USE_ASSERT_CHECKING Size len = VARSIZE_ANY_EXHDR(state); #endif char *ptr = VARDATA_ANY(state); CHECK_AGG_CONTEXT("count_distinct_deserial", fcinfo); Assert(len > 0); Assert((len - offsetof(element_set_t, data)) > 0); /* copy the header */ memcpy(eset, ptr, offsetof(element_set_t, data)); ptr += offsetof(element_set_t, data); Assert((eset->nall > 0) && (eset->nall == eset->nsorted)); Assert(len == offsetof(element_set_t, data) + eset->nall * eset->item_size); /* we only allocate the necessary space */ eset->data = palloc(eset->nall * eset->item_size); eset->nbytes = eset->nall * eset->item_size; memcpy((void *)eset->data, ptr, eset->nall * eset->item_size); PG_RETURN_POINTER(eset); }
Datum array_agg_distinct_type_by_element(PG_FUNCTION_ARGS) { /* get element type for the dummy second parameter (anynonarray item) */ Oid element_type = get_fn_expr_argtype(fcinfo->flinfo, 1); CHECK_AGG_CONTEXT("count_distinct", fcinfo); /* return empty array if the state was not initialized */ if (PG_ARGISNULL(0)) PG_RETURN_DATUM(PointerGetDatum(construct_empty_array(element_type))); return build_array((element_set_t *)PG_GETARG_POINTER(0), element_type); }
Datum count_distinct(PG_FUNCTION_ARGS) { element_set_t * eset; CHECK_AGG_CONTEXT("count_distinct", fcinfo); if (PG_ARGISNULL(0)) PG_RETURN_NULL(); eset = (element_set_t *)PG_GETARG_POINTER(0); /* do the compaction */ compact_set(eset, false); #if DEBUG_PROFILE print_set_stats(eset); #endif PG_RETURN_INT64(eset->nall); }
Datum quantile_numeric_array(PG_FUNCTION_ARGS) { int i, idx = 0; struct_numeric * data; Numeric * result; CHECK_AGG_CONTEXT("quantile_numeric_array", fcinfo); if (PG_ARGISNULL(0)) { PG_RETURN_NULL(); } data = (struct_numeric*)PG_GETARG_POINTER(0); result = palloc(data->nquantiles * sizeof(Numeric)); qsort(data->elements, data->next, sizeof(Numeric), &numeric_comparator); for (i = 0; i < data->nquantiles; i++) { if ((data->quantiles[i] > 0) && (data->quantiles[i] < 1)) { idx = (int)ceil(data->next * data->quantiles[i]) - 1; } else if (data->quantiles[i] <= 0) { idx = 0; } else if (data->quantiles[i] >= 1) { idx = data->next - 1; } result[i] = data->elements[idx]; } return numeric_to_array(fcinfo, result, data->nquantiles); }
Datum count_distinct_serial(PG_FUNCTION_ARGS) { element_set_t * eset = (element_set_t *)PG_GETARG_POINTER(0); Size hlen = offsetof(element_set_t, data); /* header */ Size dlen; /* elements */ bytea *out; /* output */ char *ptr; Assert(eset != NULL); CHECK_AGG_CONTEXT("count_distinct_serial", fcinfo); /* * force compaction, so that we serialize the smallest amount of data * and also make sure the data is sorted (and the sort happens in the * parallel workers, ot distribute the CPU better) */ compact_set(eset, false); Assert(eset->nall > 0); Assert(eset->nall == eset->nsorted); dlen = eset->nall * eset->item_size; out = (bytea *)palloc(VARHDRSZ + dlen + hlen); SET_VARSIZE(out, VARHDRSZ + dlen + hlen); ptr = VARDATA(out); memcpy(ptr, eset, hlen); ptr += hlen; memcpy(ptr, eset->data, dlen); PG_RETURN_BYTEA_P(out); }