C function returns null values

From: Gregor Trefs <gregor(dot)trefs(at)delphit(dot)com>
To: "pgsql-general(at)postgresql(dot)org" <pgsql-general(at)postgresql(dot)org>
Subject: C function returns null values
Date: 2011-07-15 08:50:49
Message-ID: 5987F6572432A3439988CDF27C6239A60124F7A43D87@winserver.delphit.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: 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

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Giuseppe Sacco 2011-07-15 09:39:45 Re: About permissions on large objects
Previous Message Radoslaw Smogura 2011-07-15 07:33:04 Re: Weird problem that enormous locks