I'm writing a user defined type in Postgres called personname:
#define FLXIBLE_ARRAY_MEMBER 0
PG_MODULE_MAGIC;
typedef struct personname{
int familyLen;
int givenLen;
int givenStart;
char pname[FLXIBLE_ARRAY_MEMBER];
}personname;
I write my personname_in and personname_out function roughly like this:
PG_FUNCTION_INFO_V1(pname_in);
Datum
pname_in(PG_FUNCTION_ARGS){
char* str = PG_GETARG_CSTRING(0);
personname *name;
...
name = (personname*) palloc(sizeof(personname) + strlen(str) + 1);
name->familyLen = familyNameLen;
name->givenLen = givenNameLen;
name->givenStart = givenNameStart;
strcpy(name->pname, str);
PG_RETURN_POINTER(name);
}
PG_FUNCTION_INFO_V1(pname_out);
Datum
pname_out(PG_FUNCTION_ARGS){
personname *name = (personname*) PG_GETARG_POINTER(0);
char* family = getFamily(name);
char* given = getGiven(name);
char* nameStr;
nameStr = psprintf("%s,%s", family, given);
pfree(family);
pfree(given);
PG_RETURN_CSTRING(nameStr);
}
And my sql is like this:
CREATE FUNCTION pname_in(cstring)
RETURNS personname
AS '_OBJWD_/pname'
LANGUAGE C IMMUTABLE STRICT;
CREATE FUNCTION pname_out(personname)
RETURNS cstring
AS '_OBJWD_/pname'
LANGUAGE C IMMUTABLE STRICT;
CREATE TYPE personname (
internallength = 12,
input = pname_in,
output = pname_out
);
Now my code can correctly respond with select "NAME" :: personname;
, and when I insert and select, it can correctly access to all arguments in personname except the pname array.
I create a table called users which contains the pname array, when I type select * from users; it shows this:
However, when I copy and paste my personname_in and personname_out code in another c file, replace palloc with malloc and test it with some input string from terminal, it can print correct pname value.
Could someone please tell me where did I do wrong, or what's the correct way to create a new type in PostgreSQL with array?
The CREATE TYPE
statement does not fit the code, and the 4-byte varlena
header is missing.
Qoth the documentation:
While the details of the new type's internal representation are only known to the I/O functions and other functions you create to work with the type, there are several properties of the internal representation that must be declared to PostgreSQL. Foremost of these is
internallength
. Base data types can be fixed-length, in which caseinternallength
is a positive integer, or variable-length, indicated by settinginternallength
toVARIABLE
. (Internally, this is represented by settingtyplen
to -1.) The internal representation of all variable-length types must start with a 4-byte integer giving the total length of this value of the type. (Note that the length field is often encoded, as described in Section 68.2; it's unwise to access it directly.)
You must define the type with
INTERNALLENGTH = VARIABLE
and the struct has to start with a 4-byte integer.
I didn't check for others errors.