In a previous question about using CStrings to create table data in an SQL extension, it was a problem to use Datums made from CStringGetDatum() for table columns that expect VARCHAR. The solution was to use CStringGetTextDatum(). Now i am curious why.
Here are the function definitions, but i am not sure, in which situation to use CStringGetDatum() over the second, if you can't use the first with CStrings:
#define CStringGetDatum(X) PointerGetDatum(X)
#define CStringGetTextDatum(s) PointerGetDatum(cstring_to_text(s))
#define PointerGetDatum(X) ((Datum) (X))
text *
cstring_to_text(const char *s)
{
return cstring_to_text_with_len(s, strlen(s));
}
text *
cstring_to_text_with_len(const char *s, int len)
{
text *result = (text *) palloc(len VARHDRSZ);
SET_VARSIZE(result, len VARHDRSZ);
memcpy(VARDATA(result), s, len);
return result;
}
CodePudding user response:
The data type text
or varchar
is not stored as a zero-terminated array of characters. It is a varlena
, which has the length (and other stuff) stored in the beginning.
The data type cstring
is for a C string and is an internal data type in PostgreSQL. You can never use it in SQL.
Use CStringGetDatum
whenever you need to pass a Datum
that is a C string and use CStringGetTextDatum
to convert a C string to a text
or varchar
that you need to pass as a Datum
.