7
我正在爲PostgreSQL寫一個C擴展(v 8.4)。我目前堅持如何將PostgreSQL的柱狀數據傳遞給我的C函數。我也有一個內存所有權的問題,因爲PostgreSQL似乎做了很多內存管理。爲PostgreSQL實現C擴展函數 - 我該如何做? (在C/PostgreSQL之間傳遞數據)
如果有人能幫助我「加入點」,我將不勝感激,以獲得一個基本的骨架代碼庫,我可以從中建立庫。
這是我到目前爲止有:
/*******************************************************/
/* C header file */
/*******************************************************/
typedef struct _myarray
{
double *data;
size_t len;
} MyArray;
MyArray * NEW_MyArray(const size_t len);
void Destroy_MyArray(MyArray * arr);
size_t NumElements_MyArray(MyArray * arr); /* trivial function returns number of elements */
MyArray * NotTrivial_MyArray(MyArray * arr); /* non trivial function returns MyArray (a float8[] in PG) */
double HeapFunc_MyArray(MyArray * arr); /* allocs from heap */
/*******************************************************/
/* C Source file */
/*******************************************************/
/* utility conversion funcs */
/* How do I convert from the structure returned by array_agg to float8[] (or int4[] ?) */
MyArray * NEW_MyArray(const size_t len){
/* Do I use palloc0() or calloc() here ? */
}
void Destroy_MyArray(MyArray * arr){
/* Do I use pfree() or free() here ? */
}
size_t NumElements_MyArray(MyArray * arr){
assert(arr != 0);
return arr->len;
}
MyArray * NotTrivial_MyArray(MyArray * arr){
assert(arr != 0);
MyArray * ptr = NEW_MyArray(arr->len);
return ptr;
}
double HeapFunc_MyArray(MyArray * arr){
/* Create temporary variables on heap (use palloc0() or calloc()?) */
/* Cleanup temp variables (use pfree() or free() ? */
return 42/1.0;
}
/*******************************************************/
/* PostgreSQL wrapper funcs implementation source file */
/*******************************************************/
/* Prototypes */
PG_FUNCTION_INFO_V1(test_num_elements);
PG_FUNCTION_INFO_V1(test_not_trivial);
PG_FUNCTION_INFO_V1(test_heapfunc);
Datum test_num_elements(PG_FUNCTION_ARGS);
Datum test_not_trivial(PG_FUNCTION_ARGS);
Datum test_heapfunc(PG_FUNCTION_ARGS);
Datum
test_num_elements(PG_FUNCTION_ARGS)
{
/* Convert data returned by array_agg() into MyArray * (how?) */
/* invoke NumElements_MyArray() */
/* Do I free temporary MyArray * ptr or will PG clean up
- if I have to clean up (like I suspect), do I use pfree() or free() ?*/
PG_RETURN_INT32(result);
}
Datum
test_not_trivial(PG_FUNCTION_ARGS)
{
/* Ditto, as above */
PG_RETURN_POINTER(/* utility function to convert MyArray* to float8[] equiv for PG (how) */);
}
Datum
test_heapfunc(PG_FUNCTION_ARGS)
{
/* Ditto, as above */
PG_RETURN_FLOAT8(result);
}
-- SQL FUNCTIONS
CREATE OR REPLACE FUNCTION test_num_elements(float8[]) RETURNS int4
AS '$libdir/pg_testlib.so' LANGUAGE 'c';
CREATE OR REPLACE FUNCTION test_not_trivial(float8[]) RETURNS float8[]
AS '$libdir/pg_testlib.so' LANGUAGE 'c';
CREATE OR REPLACE FUNCTION test_heapfunc(float8[]) RETURNS float8
AS '$libdir/pg_testlib.so' LANGUAGE 'c';
-- SQL TEST
SELECT test_num_elements(array_agg(salary)) FROM employees;
SELECT test_not_trivial(array_agg(salary)) FROM employees;
SELECT test_heapfunc(array_agg(salary)) FROM employees;
總之,我的問題是:
- 如何轉換的列數據從ARRAY_AGG()到雙打的C數組(或ints)
- 如何將C數組中的整數(或雙精度)轉換回int4 []或float8 []以便在PostgreSQL中使用?
- 內存分配原則 - 我使用PostgreSQL內存管理函數palloc()/ pfree()還是可以使用calloc/free ?.另外,當使用PG mem funcs時,我是否負責釋放分配的內存?