从Postgres C函数返回数组?

时间:2022-03-09 17:26:46

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

此代码编译时没有错误,但它不返回任何内容。有什么问题吗?

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

    #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 个解决方案

#1


1  

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

实际上,最根本的问题是,PostgreSQL数组与C数组不兼容。

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

好的谷歌关键字是“构造t_md_array”或“构造t_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)

#1


1  

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

实际上,最根本的问题是,PostgreSQL数组与C数组不兼容。

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

好的谷歌关键字是“构造t_md_array”或“构造t_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)