Обсуждение: interaction with postgres defined types in custom c functions
I'm experiencing much trouble making use of the V1 custom c function definition framework built into postgres, probably by virtue of my lack of experience with C.
In a nutshell, I've paid close attention to the documentation, have had some success getting useful code out of the version 0 naming convention for simple return types, but need to do some variable-length text processing (to write a crc hash function). My basic question is how to usefully get through the header architecture into some actual data so that I can do an some calculations and return a useful result.
The simplest possible example I could come up with was a slight modification one of the documentation's "variable length, by reference" examples:
PG_FUNCTION_INFO_V1(par);
Datum par(PG_FUNCTION_ARGS) // pete and repeat! takes text struct pointer
{
text *t = PG_GETARG_TEXT_P(0);
text *new_t = (text*) palloc(VARSIZE(t));
VARATT_SIZEP(new_t) = VARSIZE(t);
memcpy((void*) VARDATA(new_t),(void*)VARDATA(t),VARSIZE(t) - VARHDRSZ);
char *ptr = (char*) VARDATA(new_t);
*ptr = 'Q'; // NO EFFECT
PG_RETURN_TEXT(new_t);
}
The "no effect" comment applies to trying to rewrite to the same memory, write from some static type I define, etc, etc. I'm guessing there's a const declaration hiding somewhere that I'm missing. I'd really love to look at some documentation for what a text struct actually IS so that I can use an indirection operator to get its internals. But I'm guessing that's not the appropriate way to do it...
--
========================================================
Jason Nerothin
Programmer/Analyst IV - Database Administration
UCLA-DOE Institute for Genomics & Proteomics
Howard Hughes Medical Institute
========================================================
611 C.E. Young Drive East | Tel: (310) 206-3907
105 Boyer Hall, Box 951570 | Fax: (310) 206-3914
Los Angeles, CA 90095. USA | Mail: jason@mbi.ucla.edu
========================================================
http://www.mbi.ucla.edu/~jason
========================================================
In a nutshell, I've paid close attention to the documentation, have had some success getting useful code out of the version 0 naming convention for simple return types, but need to do some variable-length text processing (to write a crc hash function). My basic question is how to usefully get through the header architecture into some actual data so that I can do an some calculations and return a useful result.
The simplest possible example I could come up with was a slight modification one of the documentation's "variable length, by reference" examples:
PG_FUNCTION_INFO_V1(par);
Datum par(PG_FUNCTION_ARGS) // pete and repeat! takes text struct pointer
{
text *t = PG_GETARG_TEXT_P(0);
text *new_t = (text*) palloc(VARSIZE(t));
VARATT_SIZEP(new_t) = VARSIZE(t);
memcpy((void*) VARDATA(new_t),(void*)VARDATA(t),VARSIZE(t) - VARHDRSZ);
char *ptr = (char*) VARDATA(new_t);
*ptr = 'Q'; // NO EFFECT
PG_RETURN_TEXT(new_t);
}
The "no effect" comment applies to trying to rewrite to the same memory, write from some static type I define, etc, etc. I'm guessing there's a const declaration hiding somewhere that I'm missing. I'd really love to look at some documentation for what a text struct actually IS so that I can use an indirection operator to get its internals. But I'm guessing that's not the appropriate way to do it...
--
========================================================
Jason Nerothin
Programmer/Analyst IV - Database Administration
UCLA-DOE Institute for Genomics & Proteomics
Howard Hughes Medical Institute
========================================================
611 C.E. Young Drive East | Tel: (310) 206-3907
105 Boyer Hall, Box 951570 | Fax: (310) 206-3914
Los Angeles, CA 90095. USA | Mail: jason@mbi.ucla.edu
========================================================
http://www.mbi.ucla.edu/~jason
========================================================
"Jason Nerothin" <jasonnerothin@gmail.com> writes:
> PG_FUNCTION_INFO_V1(par);
> Datum par(PG_FUNCTION_ARGS) // pete and repeat! takes text struct pointer
> {
> text *t = PG_GETARG_TEXT_P(0);
> text *new_t = (text*) palloc(VARSIZE(t));
> VARATT_SIZEP(new_t) = VARSIZE(t);
> memcpy((void*) VARDATA(new_t),(void*)VARDATA(t),VARSIZE(t) - VARHDRSZ);
> char *ptr = (char*) VARDATA(new_t);
> *ptr = 'Q'; // NO EFFECT
> PG_RETURN_TEXT(new_t);
> }
That looks correct to me (well aside from it being an error to define ptr in
the middle of a block in C and replacing the first character with Q will be
wrong if the string is 0-bytes or the first byte is a multibyte character).
> The "no effect" comment applies to trying to rewrite to the same memory,
> write from some static type I define, etc, etc.
I think you've simplified away the mistake in your code. Have you actually
tried the above code? Send an actual example and describe what actually
happens.
The only thing I wonder about is whether you're compiling with optimizations
and without -fno-strict-aliasing which may be necessary for Postgres's code
style to compile correctly. What compiler are you compiling with?
--
Gregory Stark
EnterpriseDB http://www.enterprisedb.com