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 |