Exemple #1
0
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]);

}
Exemple #2
0
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);
}
Exemple #6
0
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);
}