From: | Michael Fuhr <mike(at)fuhr(dot)org> |
---|---|
To: | Kjetil Haaland <kjetil(dot)haaland(at)student(dot)uib(dot)no> |
Cc: | pgsql-novice(at)postgresql(dot)org |
Subject: | Re: user defined type |
Date: | 2004-11-09 18:07:25 |
Message-ID: | 20041109180725.GA31357@winnie.fuhr.org |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-novice |
On Tue, Nov 09, 2004 at 01:38:29PM +0100, Kjetil Haaland wrote:
> On Monday 08 November 2004 22:24, Michael Fuhr wrote:
> > On Mon, Nov 08, 2004 at 01:26:55PM +0100, Kjetil Haaland wrote:
> > > typedef struct alignres {
> > > int value;
> > > char *fstring;
> > > }alignres;
> >
> > If you want to store character data, I think the characters must
> > be stored in the structure itself; I don't think using a pointer
> > will work (somebody please correct me if I'm mistaken). So instead
> > of "char *fstring" you'll need "char fstring[x]", where "x" is the
> > maximum size of the character data. You could also use "char fstring[1]"
> > and allocate the alignres structure to be as big as necessary; if
> > you do that then you might want to review the paragraph regarding
> > TOAST-able types near the end of the "User-Defined Types" section
> > of the documentation.
> >
> > http://www.postgresql.org/docs/7.4/static/xtypes.html
> >
> > Make sure your CREATE TYPE statement has "internallength" set
> > correctly: either to the fixed size of the structure (including
> > character data) or to "variable". If you use "variable" then make
> > sure you add the required length field to the beginning of the
> > structure. See the CREATE TYPE documentation for more info.
> I want to use the fstring[1] way, because i don't know how large
> my string will be. You say that i can allocate the hole structure,
> where should i do this? in the in-data-function?
Yes, in alignres_in() you'd allocate enough memory to hold all of
the data: the size of the structure plus the length of the string.
If you don't mind a little waste then here's a simple way to do it:
char *in = PG_GETARG_CSTRING(0);
alignres *result;
result = palloc(sizeof(*result) + strlen(in));
(Note that the compiler evalutes sizeof(*result), so you don't have
to worry that you're dereferencing an unassigned pointer at run
time. This syntax removes the need to specify the type name again,
which eases maintenance.)
I don't think you need to add an extra byte to allow for the string's
terminating NUL because sizeof(*result) already accounts for one
byte of the string (and probably a little extra, due to alignment).
Double-check my thinking, though, and add an extra byte if you think
it's necessary.
> It also says in the documentation that if I use the random for
> internallength when i create my type I have to set the length in
> the structure. Is this set in the declaration of the structure or
> in some of the methods?
The internallength specification is "variable", not "random." The
length is an int32 at the beginning of the data:
typedef struct alignres {
int32 length;
int value;
char fstring[1];
} alignres;
Before returning, set the length field to the total size of the data.
Here's where I think you could eliminate any wasted space that you
allocated -- after you've parsed the data you know exactly how long
fstring is, so you could add only that much to sizeof(*result):
result->length = sizeof(*result) + strlen(fstring);
Again, I don't think you need to add an extra byte to account for
the string's terminating NUL because sizeof(*result) already includes
one byte for the string.
--
Michael Fuhr
http://www.fuhr.org/~mfuhr/
From | Date | Subject | |
---|---|---|---|
Next Message | Kumar S | 2004-11-09 20:34:47 | VACUUM ANALYZE : Is this a time consuming procedure? |
Previous Message | Venkateswaran Udayasankar | 2004-11-09 16:52:58 | Question on stored proecdure parameter |