Thread: How do I construct a varlena?
Can you tell me, please, how to construct a varlena (to be returned by a function). I see it is declared as an int and a 1-byte array; I don't know how to assign a longer string in place of that 1-byte array; the compiler complains about incompatible types, whatever I do. Thank you. -- Oliver Elphick Oliver.Elphick@lfix.co.uk Isle of Wight http://www.lfix.co.uk/oliver PGP key from public servers; key ID 32B8FAA1 ======================================== "And not only so, but we glory in tribulations also; knowing that tribulation worketh patience; And patience, experience; and experience, hope." Romans 5:3,4
On Tue, 4 Aug 1998, Oliver Elphick wrote: > Can you tell me, please, how to construct a varlena (to be returned by > a function). > > I see it is declared as an int and a 1-byte array; I don't know how to > assign a longer string in place of that 1-byte array; the compiler > complains about incompatible types, whatever I do. If I'm correct: malloc(sizeof(VARLENA) + l); where 'l' is the length of the string you want to put in (without the trailing '\0'). Maarten _____________________________________________________________________________ | TU Delft, The Netherlands, Faculty of Information Technology and Systems | | Department of Electrical Engineering | | Computer Architecture and Digital Technique section | | M.Boekhold@et.tudelft.nl | -----------------------------------------------------------------------------
Maarten Boekhold wrote: >On Tue, 4 Aug 1998, Oliver Elphick wrote: > >> Can you tell me, please, how to construct a varlena (to be returned by >> a function). >> >> I see it is declared as an int and a 1-byte array; I don't know how to >> assign a longer string in place of that 1-byte array; the compiler >> complains about incompatible types, whatever I do. > >If I'm correct: > > malloc(sizeof(VARLENA) + l); > >where 'l' is the length of the string you want to put in (without the >trailing '\0'). Thanks for your reply; I've been away a few days so I've only just seen it. 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 *result; ... cxname = realloc((void *) cxname, strlen(tmp)+sizeof(struct varlena)); strcpy(cxname+sizeof(int32), tmp); -> result = &((struct varlena) cxname); result->vl_len = strlen(tmp); return *result; } but the compiler gives the error `conversion to non-scalar type requested' at the marked line. 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. -- Oliver Elphick Oliver.Elphick@lfix.co.uk Isle of Wight http://www.lfix.co.uk/oliver PGP key from public servers; key ID 32B8FAA1 ======================================== "...ask, and ye shall receive, that your joy may be full." John 16:24
> 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); }
> 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 *result; > ... > cxname = realloc((void *) cxname, strlen(tmp)+sizeof(struct varlena)); > strcpy(cxname+sizeof(int32), tmp); > -> result = &((struct varlena) cxname); > result->vl_len = strlen(tmp); > > return *result; > } > > but the compiler gives the error `conversion to non-scalar type requested' > at the marked line. I gues something like this should work: struct varlena *cxname cxname = (struct varlena *) realloc(cxname, strlen(tmp) + VARHDRSZ); strcpy(cxname->vl_dat, tmp); /* maybe '&cxname->vl_dat' */ return cxname; I don't think it's possible to 'return *cxname', cos the compiler will only return the part of your data. Most of this is from head, so check on things if they don't work immediately. Maarten _____________________________________________________________________________ | TU Delft, The Netherlands, Faculty of Information Technology and Systems | | Department of Electrical Engineering | | Computer Architecture and Digital Technique section | | M.Boekhold@et.tudelft.nl | -----------------------------------------------------------------------------