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
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 |