snippetsqlMinor
PostgreSQL How do I convert struct text to plain *char in C functions?
Viewed 0 times
postgresqlstructconvertchartexthowfunctionsplain
Problem
I'm using my internal C function which doesn't know about postgresql's text struct, how do I pass text argument when char * expected?
Here's what xxd sees in log file:
After executing:
Why junk after football?
#include
#include
#include "postgres.h"
#include "fmgr.h"
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
PG_FUNCTION_INFO_V1(fun);
Datum fun(PG_FUNCTION_ARGS)
{
text str1, str2;
str1 = PG_GETARG_TEXT_P(0);
str2 = PG_GETARG_TEXT_P(1);
FILE *fp = fopen("/tmp/fun.log", "w");
fprintf(fp, "%s\n", VARDATA_ANY(str1));
fprintf(fp, "%s\n", VARDATA_ANY(str2));
fclose(fp);
PG_RETURN_INT32(0);
}
Here's what xxd sees in log file:
0000000: 666f 6f74 6261 6c6c c88d 7409 70d3 6b09 football..t.p.k.
0000010: 080a 7a6f 6f6d 0a ..zoom.
After executing:
SELECT * FROM fun('football','zoom');Why junk after football?
Solution
The data pointed to by the
To determine the length of the text, you can use
In your example, you could use
Here's a sample of how either could be done:
Reference documentation for PostgreSQL 9.2.
text structure isn't null-terminated, so you can't use it with C "string" functions directly.To determine the length of the text, you can use
VARSIZE(your_text)-VARHDRSZ.In your example, you could use
fwrite instead of printf to output the string (passing in the length), or copy the text to a char* and terminate it manually if you intend to use C string functions.Here's a sample of how either could be done:
#include
#include
#include "postgres.h"
#include "fmgr.h"
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
PG_FUNCTION_INFO_V1(fun);
size_t log_pgtext(FILE to, text what)
{
return fwrite(VARDATA(what), 1, VARSIZE(what)-VARHDRSZ, to);
}
char dup_pgtext(text what)
{
size_t len = VARSIZE(what)-VARHDRSZ;
char *dup = palloc(len+1);
memcpy(dup, VARDATA(what), len);
dup[len] = 0;
return dup;
}
Datum fun(PG_FUNCTION_ARGS)
{
text str1, str2;
str1 = PG_GETARG_TEXT_P(0);
str2 = PG_GETARG_TEXT_P(1);
FILE *fp = fopen("/tmp/fun.log", "w");
log_pgtext(fp, str1);
fprintf(fp, "\n");
char *str = dup_pgtext(str2);
fprintf(fp, "%s\n", str);
pfree(str);
fclose(fp);
PG_RETURN_INT32(0);
}
Reference documentation for PostgreSQL 9.2.
Context
StackExchange Database Administrators Q#33151, answer score: 3
Revisions (0)
No revisions yet.