From: | "Thomas G(dot) Lockhart" <lockhart(at)alumni(dot)caltech(dot)edu> |
---|---|
To: | Oliver Elphick <olly(at)lfix(dot)co(dot)uk> |
Cc: | M(dot)Boekhold(at)et(dot)tudelft(dot)nl, hackers(at)postgreSQL(dot)org |
Subject: | Re: [HACKERS] How do I construct a varlena? |
Date: | 1998-08-10 02:21:57 |
Message-ID: | 35CE5945.5A3B48D7@alumni.caltech.edu |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | 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);
}
From | Date | Subject | |
---|---|---|---|
Next Message | Thomas G. Lockhart | 1998-08-10 02:43:48 | Re: [HACKERS] Re: type coersion (was OR clause status) |
Previous Message | Bruce Momjian | 1998-08-10 01:57:40 | Re: [HACKERS] Re: type coersion (was OR clause status) |