1

This code compiles without error but it does not return anything. Any ideas on what's missing? #include #include #include

#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif

Datum my_c_function(PG_FUNCTION_ARGS);

PG_FUNCTION_INFO_V1(my_c_function);

Datum my_c_function(PG_FUNCTION_ARGS) {
    float4 var1, var2, var3, var4;
    Datum* vals;
    var1 = PG_GETARG_FLOAT8(0);
    var2 = PG_GETARG_FLOAT8(1);
    var3 = PG_GETARG_FLOAT8(2);
    var4 = PG_GETARG_FLOAT8(3);

    vals = palloc(sizeof(Datum) * 4);

    if (var1 < var4) {
        vals[0] = (int) 1;
        vals[1] = (int) (0.5 + (100 * ((var2 - var4) / (var2 - var3))));
        vals[2] = (int) (0.5 + (100 * ((var4 - var1) / (var2 - var3))));
        vals[3] = (int) (0.5 + (100 * ((var1 - var3) / (var2 - var3))));
    }
    else if (var1 > var4) {
        vals[0] = (int) -1;
        vals[1] = (int) (0.5 + (100 * ((var2 - var1) / (var2 - var3))));
        vals[2] = (int) (0.5 + (100 * ((var1 - var4) / (var2 - var3))));
        vals[3] = (int) (0.5 + (100 * ((var4 - var3) / (var2 - var3))));
    }
    else if (var2 == var3) {
        PG_RETURN_NULL();
    }
    else {
        vals[0] = (int) 0;
        vals[1] = (int) (0.5 + (100 * ((var2 - var4) / (var2 - var3))));
        vals[2] = (int) 0;
        vals[3] = (int) (0.5 + (100 * ((var4 - var3) / (var2 - var3))));
    }

    PG_RETURN_ARRAYTYPE_P(vals);

}

Corrected version:

#include <postgres.h>
#include <fmgr.h>
#include <utils/array.h>
#include <catalog/pg_type.h>

#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif

Datum cget_bar_structure2(PG_FUNCTION_ARGS);

PG_FUNCTION_INFO_V1(cget_bar_structure2);

Datum
cget_bar_structure2(PG_FUNCTION_ARGS) {
    float4   var1, var2, var3, var4;
    Datum    * vals = (Datum*) palloc(sizeof(Datum) * 4);
    ArrayType* result;

    var1 = PG_GETARG_FLOAT8(0);
    var2 = PG_GETARG_FLOAT8(1);
    var3 = PG_GETARG_FLOAT8(2);
    var4 = PG_GETARG_FLOAT8(3);

    if (var1 < var4) {
        vals[0] = Int32GetDatum(1);
        vals[1] = Int32GetDatum((0.5 + (100 * ((var2 - var4) / (var2 - var3)))));
        vals[2] = Int32GetDatum((0.5 + (100 * ((var4 - var1) / (var2 - var3)))));
        vals[3] = Int32GetDatum((0.5 + (100 * ((var1 - var3) / (var2 - var3)))));
    }
    else if (var1 > var4) {
        vals[0] = Int32GetDatum(-1);
        vals[1] = Int32GetDatum((0.5 + (100 * ((var2 - var1) / (var2 - var3)))));
        vals[2] = Int32GetDatum((0.5 + (100 * ((var1 - var4) / (var2 - var3)))));
        vals[3] = Int32GetDatum((0.5 + (100 * ((var4 - var3) / (var2 - var3)))));
    }
    else if (var2 == var3) {
        PG_RETURN_NULL();
    }
    else {
        vals[0] = Int32GetDatum(0);
        vals[1] = Int32GetDatum((0.5 + (100 * ((var2 - var4) / (var2 - var3)))));
        vals[2] = Int32GetDatum(0);
        vals[3] = Int32GetDatum((0.5 + (100 * ((var4 - var3) / (var2 - var3)))));
    }

    result = construct_array(vals, 4, INT4OID, sizeof(int4), true, 'i');

    PG_RETURN_ARRAYTYPE_P(result);

}
1
  • "Does not return anything". Huh? Can you show the commands you used to CREATE FUNCTION and what happens when you invoke it? If you SELECT pg_backend_pid(), attach gdb to the backend, break my_c_function then c and run the SQL, does gdb actually stop execution at the start of your function? Commented May 9, 2014 at 6:34

1 Answer 1

2

The fundamental problem is in fact, so PostgreSQL arrays are not compatible with C arrays.

Good google keyword is a "construct_md_array" or "construct_array"

I found one fragment that should to help

const int *data = array.data(); // C array
Datum *d = (Datum *) palloc(sizeof(Datum) * size);
ArrayType *a;

for (int i = 0; i < size; i++)
     d[i] = Int32GetDatum(data[i]);

a = construct_array(d, size, INT4OID, sizeof(int4), true, 'i');

PG_RETURN_ARRAYTYPE_P(a)
Sign up to request clarification or add additional context in comments.

2 Comments

error: ‘INT4OID’ undeclared (first use in this function)
I added <catalog/pg_type.h> which removed the undeclared error. Works now. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.