Custom data type in C with one fixed and one variable attribute

Started by Adrian Schreyerover 14 years ago3 messagesgeneral
Jump to latest
#1Adrian Schreyer
ams214@cam.ac.uk

Hi,

I am trying to create a custom data type in C that has a fixed size
and a variable size attribute - is that actually possible? The
documentation mentions only one or the other but a struct in the
pg_trgm extension (TRGM) seems to have that.

The data type I have is

typedef struct {
int4 length;
uint32 foo;
char bar[1];
} oefp;

The external representation of that data type would be (1,
'hexadecimal string here'), for example.

This is my _in function to parse the external cstring.

PG_FUNCTION_INFO_V1(mydatatype_in);
Datum mydatatype_in(PG_FUNCTION_ARGS)
{
char *rawcstring = PG_GETARG_CSTRING(0);

uint32 foo;
char *buffer = (char *) palloc(strlen(rawcstring));

if (sscanf(rawcstring, "(%u,%[^)])", &foo, buffer) != 2)
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("Invalid input syntax: \"%s\"", rawcstring)));
}

mydatatype *dt = (mydatatype*) palloc(VARHDRSZ + sizeof(uint32) +
strlen(buffer));

SET_VARSIZE(dt, VARHDRSZ + sizeof(uint32) + strlen(buffer));
memcpy(dt->bar, buffer, strlen(buffer));
dt->foo = foo;

PG_RETURN_POINTER(dt);
}

The problem is however that dt->bar contains not only the input string
but random characters or other garbage as well, so something must go
wrong at the end of the function. Any thoughts what it could be?

Cheers,

Adrian

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Adrian Schreyer (#1)
Re: Custom data type in C with one fixed and one variable attribute

Adrian Schreyer <ams214@cam.ac.uk> writes:

The data type I have is

typedef struct {
int4 length;
uint32 foo;
char bar[1];
} oefp;

Seems reasonable enough.

mydatatype *dt = (mydatatype*) palloc(VARHDRSZ + sizeof(uint32) +
strlen(buffer));

SET_VARSIZE(dt, VARHDRSZ + sizeof(uint32) + strlen(buffer));
memcpy(dt->bar, buffer, strlen(buffer));
dt->foo = foo;

Fine, but keep in mind that what you are creating here is a
non-null-terminated string.

The problem is however that dt->bar contains not only the input string
but random characters or other garbage as well, so something must go
wrong at the end of the function. Any thoughts what it could be?

It sounds to me like you are inspecting dt->bar with something that
expects to see a null-terminated string. You could either fix your
inspection code, or expend one more byte to make the string be
null-terminated as stored.

regards, tom lane

#3Adrian Schreyer
ams214@cam.ac.uk
In reply to: Tom Lane (#2)
Re: Custom data type in C with one fixed and one variable attribute

I added one more byte to include \0 and its working as expected now.
Thanks for your help!

Cheers,

Adrian

Show quoted text

On Thu, Oct 27, 2011 at 23:23, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Adrian Schreyer <ams214@cam.ac.uk> writes:

The data type I have is

typedef struct {
        int4   length;
        uint32 foo;
        char   bar[1];
    } oefp;

Seems reasonable enough.

    mydatatype *dt = (mydatatype*) palloc(VARHDRSZ + sizeof(uint32) +
strlen(buffer));

    SET_VARSIZE(dt, VARHDRSZ + sizeof(uint32) + strlen(buffer));
    memcpy(dt->bar, buffer, strlen(buffer));
    dt->foo = foo;

Fine, but keep in mind that what you are creating here is a
non-null-terminated string.

The problem is however that dt->bar contains not only the input string
but random characters or other garbage as well, so something must go
wrong at the end of the function. Any thoughts what it could be?

It sounds to me like you are inspecting dt->bar with something that
expects to see a null-terminated string.  You could either fix your
inspection code, or expend one more byte to make the string be
null-terminated as stored.

                       regards, tom lane