2
votes

I'm trying to write a C function in PostgreSQL 9.3 which receive a text and return an array of text. My function make the server crash when I return an array of text or varchar but it works ok when I try to return an array of number or boolean. I think there is a problem with array of pointer variable type or memory allocation. Can anyone help me to solve the problem?

This is my C code:

text*           arg         = PG_GETARG_TEXT_P(0);
char*           content     = VARDATA(arg);
size_t          size        = VARSIZE(arg);
unsigned int    nMax        = 1000;//size / 2 * NGRAM_MAX; //Maximum number of ngrams is 1/2 of content size;
text**          ngrams      = palloc(nMax * sizeof(text*));


ArrayType       *result;
Datum*          elems;
int16           typlen;
bool            typbyval;
char            typalign;

int n = parseNgram(content, size, ngrams, nMax);

elog(NOTICE, "What's sub %d", n);
elems       = (Datum*)palloc(n * sizeof(Datum));

unsigned short i;
for(i = 0; i < n; i++) {
    elems[i] = PointerGetDatum(ngrams[i]);
}

get_typlenbyvalalign(TEXTOID, &typlen, &typbyval, &typalign);
result = construct_array(elems, n, TEXTOID, typlen, typbyval, typalign);

elog(NOTICE, "Test %d", n);

PG_RETURN_ARRAYTYPE_P(result);

As you can see above. My function run well until the last line, I can see it raise notice "Test %d". And this is the SQL code that I use to create the function:

CREATE FUNCTION ngram(text) RETURNS text[] AS '$libdir/libziePGExtension', 'ngram' LANGUAGE C IMMUTABLE STRICT;
1

1 Answers

0
votes

are you sure, so your array contains a text or varchar values? text type is not C string! First N (1,2,4) bytes holds length, other bytes are data. You have to translate C string to text type with function cstring_to_text

elems[i] = PointerGetDatum(cstring_to_text(ngrams[i]))