返回从Postgres的C函数数组? [英] Return an array from a Postgres C function?

查看:150
本文介绍了返回从Postgres的C函数数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这code编译没有错误,但它不返回任何东西。什么任何想法缺少?

 的#include<&了postgres.h GT;
    #包括LT&;&fmgr.h GT;
    #包括LT&; utils的/ array.h>    #IFDEF PG_MODULE_MAGIC
    PG_MODULE_MAGIC;
    #万一    基准my_c_function(PG_FUNCTION_ARGS);    PG_FUNCTION_INFO_V1(my_c_function);    基准
    my_c_function(PG_FUNCTION_ARGS)
    {
            个float4 VAR1,VAR2,VAR3,VAR4;
            基准*丘壑;
            VAR1 = PG_GETARG_FLOAT8(0);
            VAR2 = PG_GETARG_FLOAT8(1);
            VAR3 = PG_GETARG_FLOAT8(2);
            VAR4 = PG_GETARG_FLOAT8(3);            瓦尔斯=的palloc(的sizeof(基准)* 4);            如果(VAR1< VAR4){
                    瓦尔斯[0] =(int)的1;
                    瓦尔斯[1] =(int)的(0.5+(​​100 *((VAR2-VAR4)/(VAR2-VAR3))));
                    瓦尔斯[2] =(int)的(0.5+(​​100 *((VAR4-VAR1)/(VAR2-VAR3))));
                    瓦尔斯[3] =(int)的(0.5+(​​100 *((VAR1-VAR3)/(VAR2-VAR3))));
            }否则如果(VAR1> VAR4){
                    瓦尔斯[0] =(int)的-1;
                    瓦尔斯[1] =(int)的(0.5+(​​100 *((VAR2-VAR1)/(VAR2-VAR3))));
                    瓦尔斯[2] =(int)的(0.5+(​​100 *((VAR1-VAR4)/(VAR2-VAR3))));
                    瓦尔斯[3] =(int)的(0.5+(​​100 *((VAR4-VAR3)/(VAR2-VAR3))));
            }否则如果(VAR2 == VAR3){
                    PG_RETURN_NULL();
            }其他{
                    瓦尔斯[0] =(int)的0;
                    瓦尔斯[1] =(int)的(0.5+(​​100 *((VAR2-VAR4)/(VAR2-VAR3))));
                    瓦尔斯[2] =(int)的0;
                    瓦尔斯[3] =(int)的(0.5+(​​100 *((VAR4-VAR3)/(VAR2-VAR3))));
            }            PG_RETURN_ARRAYTYPE_P(瓦尔斯);    }

修正版本:

 的#include<&了postgres.h GT;
    #包括LT&;&fmgr.h GT;
    #包括LT&; utils的/ array.h>
    #包括LT&;目录/ pg_type.h文件>    #IFDEF PG_MODULE_MAGIC
    PG_MODULE_MAGIC;
    #万一    基准cget_bar_structure2(PG_FUNCTION_ARGS);    PG_FUNCTION_INFO_V1(cget_bar_structure2);    基准
    cget_bar_structure2(PG_FUNCTION_ARGS)
    {
            个float4 VAR1,VAR2,VAR3,VAR4;
            *基准=瓦尔斯(基准*)的palloc(的sizeof(基准)* 4);
            数组类型*结果;            VAR1 = PG_GETARG_FLOAT8(0);
            VAR2 = PG_GETARG_FLOAT8(1);
            VAR3 = PG_GETARG_FLOAT8(2);
            VAR4 = PG_GETARG_FLOAT8(3);            如果(VAR1< VAR4){
                    瓦尔斯[0] = Int32GetDatum(1);
                    瓦尔斯[1] = Int32GetDatum((0.5+(​​100 *((VAR2-VAR4)/(VAR2-VAR3)))));
                    瓦尔斯[2] = Int32GetDatum((0.5+(​​100 *((VAR4-VAR1)/(VAR2-VAR3)))));
                    瓦尔斯[3] = Int32GetDatum((0.5+(​​100 *((VAR1-VAR3)/(VAR2-VAR3)))));
            }否则如果(VAR1> VAR4){
                    瓦尔斯[0] = Int32GetDatum(-1);
                    瓦尔斯[1] = Int32GetDatum((0.5+(​​100 *((VAR2-VAR1)/(VAR2-VAR3)))));
                    瓦尔斯[2] = Int32GetDatum((0.5+(​​100 *((VAR1-VAR4)/(VAR2-VAR3)))));
                    瓦尔斯[3] = Int32GetDatum((0.5+(​​100 *((VAR4-VAR3)/(VAR2-VAR3)))));
            }否则如果(VAR2 == VAR3){
                    PG_RETURN_NULL();
            }其他{
                    瓦尔斯[0] = Int32GetDatum(0);
                    瓦尔斯[1] = Int32GetDatum((0.5+(​​100 *((VAR2-VAR4)/(VAR2-VAR3)))));
                    瓦尔斯[2] = Int32GetDatum(0);
                    瓦尔斯[3] = Int32GetDatum((0.5+(​​100 *((VAR4-VAR3)/(VAR2-VAR3)))));
            }            结果= construct_array(丘壑,4,INT4OID,和sizeof(int4),真的,'我');            PG_RETURN_ARRAYTYPE_P(结果);    }


解决方案

最根本的问题其实是,让PostgreSQL的数组与C数组兼容。

好谷歌关键字是construct_md_array或construct_array

我发现一个片段应该帮助

  const int的*数据= array.data(); // C数组
基准* D =(基准*)的palloc(的sizeof(基准)*大小);
数组类型*一个;的for(int i = 0; I<大小;我++)
     D [i] = Int32GetDatum(数据由[i]);A = construct_array(D,大小,INT4OID,和sizeof(int4),真的,'我');PG_RETURN_ARRAYTYPE_P(一)

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

    }

解决方案

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)

这篇关于返回从Postgres的C函数数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆