Реализация функций расширения C для PostgreSQL - как это сделать? (передача данных между C/PostgreSQL)

Я пишу расширение на C для PostgreSQL (v 8.4). В настоящее время я застрял на том, как передать колоночные данные из PostgreSQL в мои 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;

Вкратце, мои вопросы:

  1. Как преобразовать столбцовые данные из array_agg() в массив двоек (или ints, в зависимости от ситуации)
  2. Как преобразовать массив ints (или двоек) обратно в int4[] или float8[] для использования в PostgreSQL?
  3. Принципы распределения памяти - использовать ли мне функции управления памятью PostgreSQL palloc()/ pfree() или можно использовать calloc/free? Также, при использовании функций PG mem, несу ли я ответственность за освобождение памяти, которую выделил?
7
задан Homunculus Reticulli 5 January 2012 в 09:14
поделиться