Re: [HACKERS] How do I construct a varlena?
От | Thomas G. Lockhart |
---|---|
Тема | Re: [HACKERS] How do I construct a varlena? |
Дата | |
Msg-id | 35CE5945.5A3B48D7@alumni.caltech.edu обсуждение исходный текст |
Ответ на | Re: [HACKERS] How do I construct a varlena? ("Oliver Elphick" <olly@lfix.co.uk>) |
Список | pgsql-hackers |
> My problem is in how to get the compiler to treat the malloced space > as a varlena. > I have this (abridged) C code, to be used with > CREATE FUNCTION cname(bpchar, bpchar, bpchar) returns bpchar ...: > > char *cxname; > > text cname (text s, text t, text f) text *cname (text s, text t, text f) > { > text *result; > ... > cxname = realloc((void *) cxname, > strlen(tmp)+sizeof(struct varlena)); strcpy is dangerous because it will copy the trailing null, while text and other varlena types are not guaranteed to be null-terminated. Better to use memmove() or strncpy(). > strcpy(cxname+sizeof(int32), tmp); strcpy(cxname+sizeof(result->vl_len), tmp); or strcpy(cxname+sizeof(VARHDRSZ), tmp); not sure where tmp came from... > -> result = &((struct varlena) cxname); cxname is already a pointer. And why not make it a pointer to text instead of a pointer to char? result = ((text *) cxname); > result->vl_len = strlen(tmp); > > return *result; > } > Once I know how to do this, I will add it to the examples in the > CREATE FUNCTION documentation, since it will no doubt be helpful to > others. There is already documentation on this (though it could stand to be cleaned up and augmented) in doc/src/sgml/xfunc.sgml. This appears in the Programmer's Guide in the chapter titled "Extending SQL: Functions". If you want, it's probably OK to keep the SQL reference docs pretty simple, and if there is an example of C source code it could be shown but then described more completely in the Programmer's Guide. Or we could just mention that there _are_ examples in the Programmer's Guide and leave it at that. There is some code following which gives a (simpler) example... - Tom From the varlena.c file in backend/utils/adt/: /* * textin - converts "..." to internal representation */ text * textin(char *inputText) { text *result; int len; if (inputText == NULL) return (NULL); len = strlen(inputText) + VARHDRSZ; result = (text *) palloc(len); VARSIZE(result) = len; memmove(VARDATA(result), inputText, len - VARHDRSZ); #ifdef CYR_RECODE convertstr(VARDATA(result), len - VARHDRSZ, 0); #endif return (result); }
В списке pgsql-hackers по дате отправления: