I am writing a custom Postgres C AGGREGATE extension. I would like to know how to properly map a type defined in PSQL to a struct defined in C. I have tried doing it as best as I know how but I do not get results, I get an empty row when I test.
The C struct has the following form:
typedef struct {
int64_t row_idx; //Row number in the processing order (NOT thread safe)
int64_t data1_size;
int64_t data2_size;
char data2[ 1<<10 ];
char data1[ 1<<10 ];
} search_state;
I am not sure if it is better to get char pointers for the data, or if to allocate statically upfront as above. I have tried both ways to the same effect; I know to allocate with pmalloc to retain data between calls to the rows. I have also tried using the postgres type "text", and I still get no data at the end of the aggregation, just no rows as the result.
On the Psql side I have:
CREATE TYPE search_state AS (
row_idx int8,
data1_size int8,
data2_size int8,
data1 char[1<<10],
data2 char[1<<10]
);
Again, I have tried text type for data1 or data2, but I do not know how to make it work.
The question is, what is the proper way to get a type in psql that will precisely map to a struct in C, as above? It seems my problem arises from postgres being unable to find the data when i modify my struct in C.
The function that uses this struct as intermediary state during the aggregation is something like:
Datum fancy_select(PG_FUNCTION_ARGS){
//Get the Postgres C-Extension Parameters
search_state *state = (search_state * ) PG_GETARG_POINTER(0);
char *inputText = PG_GETARG_CSTRING(1);
uint64_t numeric_id = PG_GETARG_INT64(2);
//Make object to store state from now on.
search_state *new_state = (search_state *) palloc( 2*(1<<10) + 8*3 );
//Small Test updating the state
new_state->row_idx = 1;
new_state->data1[0] = 'T'
new_state->data1[1] = '\0'
new_state->data2[0] = 'H'
new_state->data2[1] = '\0'
new_state->data1_size = strlen( new_state->data1 ) ;
new_state->data2_size = strlen( new_state->data2 ) ;
//Return state
PG_RETURN_POINTER( new_state );
};
}
There is a final function for this aggregation which essentially takes the struct, gets data1, and returns the text that is stored there by the end. I should also mention that this extension is in C++, not plain C, but I am using as much C and as little C++ as possible.
Note 1: Testing with different structures the behaviour ranges from return initcond, no rows at all and the following message:
ERROR: type with OID 0 does not exist
CONTEXT: PL/pgSQL function final_func(search_state) while storing call arguments into local variables