C function returns null values

Поиск
Список
Период
Сортировка
От Gregor Trefs
Тема C function returns null values
Дата
Msg-id 5987F6572432A3439988CDF27C6239A60124F7A43D87@winserver.delphit.com
обсуждение исходный текст
Ответы Re: C function returns null values
Список pgsql-general

Hello all,

 

I developed a C function which returns a record. The record contains 3 scalar values and 2 arrays. Randomly some record elements are null and I wonder why. I could trace down the problem to the point where the return record is created. Until this point everything is computed correctly. Below you see an excerpt of the relevant code. I use PostGres 8.4 on Ubuntu 10.10 (x64).

 

typedef struct {

    // Size of the array

    int size;

    // Values of the array

    double *values;

} array_d;

 

// Integer

 

typedef struct {

    // Size of the array

    int size;

    // Values of the array

    int *values;

} array_i;

 

typedef struct {

    interval_orders o;

    array_d *interval_weights;

    array_d *interval_borders;

    array_i *add_weights;

    double b;

} c_param_type;

 

void create_dati_from_result(Datum *values, c_param_type *param) {

    // Array creation

    ArrayType *weights, *borders;

    Datum *weights_elem;

    Datum *borders_elem;

    int16 typlen;

    bool typbyval;

    char typalign;

 

    int i;

 

    // Set values

    values[0] = Float8GetDatum(param->o.interval_weight);

    values[1] = Float8GetDatum(param->o.quantitiy);

    values[2] = Float8GetDatum(param->o.long_sql);

    // Create datum arrays

    weights_elem = palloc(param->interval_weights->size * sizeof (Datum));

    borders_elem = palloc(param->interval_borders->size * sizeof (Datum));

    for (i = 0; i < param->interval_weights->size; i++) {

        weights_elem[i] = Float8GetDatum((float8) param->interval_weights->values[i]);

    }

    for (i = 0; i < param->interval_borders->size; i++) {

        borders_elem[i] = Float8GetDatum((float8) param->interval_borders->values[i]);

    }

    // Create array type

    get_typlenbyvalalign(FLOAT8OID, &typlen, &typbyval, &typalign);

    weights = construct_array(weights_elem, param->interval_weights->size, FLOAT8OID, typlen, typbyval, typalign);

    borders = construct_array(borders_elem, param->interval_borders->size, FLOAT8OID, typlen, typbyval, typalign);

    values[3] = PointerGetDatum(borders);

    values[4] = PointerGetDatum(weights); 

}

 

PG_FUNCTION_INFO_V1(insert_order);

 

Datum insert_order(PG_FUNCTION_ARGS) {

    // Variable declarations go here

    // …

    // vars for result

    TupleDesc tupdesc;

    Datum *values;

    bool *nulls;

    int tuplen,i;

    HeapTuple res_tuple;

    // Look whether everything has been provided

    if (PG_ARGISNULL(0)) {

        ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), errmsg("First argument is NULL")));

        PG_RETURN_NULL();

    }

    // Allocate memory

    param = palloc(sizeof (c_param_type));

    // Get the HeapTupleHeader

    header = PG_GETARG_HEAPTUPLEHEADER_COPY(0);

    // Extract information from parameter

    if (!extract_information(param, header)) {

        PG_RETURN_NULL();

    }

    // Some more code goes here

    // …

 

    // Set values

    param->o.long_sql = total_cost;

    param->o.quantitiy = weight;

    param->o.interval_weight = weight;

  

    // Create result tuple

    values = palloc(sizeof(Datum)*5);

    if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)

        ereport(ERROR, (errcode(ERRCODE_SUCCESSFUL_COMPLETION), errmsg("function returning record called in context that cannot accept type record")));

    // Get Dati

    create_dati_from_result(values, param);

    // Init Tuple Desc

    tupdesc = BlessTupleDesc(tupdesc);

    // Size

    tuplen = tupdesc->natts;

    // Allocate enough memory for nulls

    nulls = palloc(tuplen * sizeof (bool));

    // Create tuple

    res_tuple = heap_form_tuple(tupdesc, values, nulls);

    // Free allocated memory

    pfree(nulls);

    // Return result

    PG_RETURN_DATUM(HeapTupleGetDatum(res_tuple));

}

 

I hope you can help me.

 

Regards,

Gregor

 

В списке pgsql-general по дате отправления:

Предыдущее
От: Radoslaw Smogura
Дата:
Сообщение: Re: Weird problem that enormous locks
Следующее
От: Giuseppe Sacco
Дата:
Сообщение: Re: About permissions on large objects