Actually, I thought, I did this using the int32 variable called "dimension" 
which should be exactly this field. Unfortunately, it seems, that something is 
wrong here. I'll look inside the code of cube to determine the things I'm doing 
wrong, currently. Thanks so far for your advice.
My in-method is the following:
Datum pointnd_in(PG_FUNCTION_ARGS)
{
        PointND * in = NULL;
        // access the format string
        char * in_string = PG_GETARG_CSTRING(0);
        char * save = in_string;
        // 1024 bytes should be sufficient for one coordinate
        char curr_buffer[1024];
        bool corrupted = false;
        float8 * coordinates = NULL;
        unsigned int dimensions = 0, i = 0;

        coordinates = (float8 *) palloc(sizeof(float8));

        // allocate the memory
        // read bytewise and count the ',' in order to determine the amount of 
dimensions, after that: parse the point
        in_string = find_char(in_string, '(');
        // next sign after opening bracket
        ++in_string;
        // read as long, as no closing bracket has been found
        for (dimensions = 0; *in_string != ')' && !corrupted; ++dimensions)
        {
                // clear the memory
                memset(curr_buffer, 0, 1024);
                for (i = 0; *in_string != ',' && *in_string != 0 && *in_string 
!= ')'; ++in_string, ++i)
                {
                        if ((*in_string < '0' || *in_string > '9') && 
*in_string != '.')
                        {
                                corrupted = true;
                                break;
                        }
                        // copy current sign
                        curr_buffer[i] = *in_string;
                }

                // something has happened here (no valid number)
                if (corrupted)
                {
                        break;
                }
                coordinates = (float8 *) repalloc(coordinates, (dimensions + 1) 
* sizeof(float8));
                //sscanf(curr_buffer, "%f", &coordinates[dimensions]);
                coordinates[dimensions] = strtod(curr_buffer, NULL);

                // if we have a comma here, skip it
                if (*in_string == ',')
                {
                        ++in_string;
                }
                if (*in_string == ' ')
                {
                        // skip space
                        ++in_string;
                }
        }

        // something lead to a corruption of the point
        if (corrupted)
        {
                ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), 
errmsg("invalid representation of a point: %s, has to look like 
\"(<coord1>,<coord2>,...)\"", save)));
        }
        else
        {
                in = (PointND *) palloc(sizeof(float8) * dimensions + VARHDRSZ);
                SET_VARSIZE(in, dimensions);
                // copy the coordinates to the data area
                memcpy((void *) VARDATA(in), (void *) coordinates, (dimensions) 
* sizeof(float8));
        }

        PG_RETURN_POINTER(in);
}

So, probably in here, I am doing something terribly wrong and you could correct 
me at this point. As I already said, I thought that my int32 dimensions 
variable would represent exactly this vl_len_header field. The remaining stuff 
is OK then? That means the creation script and information about storage 
alignment and layout or do you detect addititonal errors?
I know, that this code might not be the best, but I am still in the testing 
phase of how to achieve sth using Postgres with C.
Thanks so far for your advice
Best regards
        Carsten Kropf
Am 10.02.2010 um 11:39 schrieb Yeb Havinga:

> 
> Carsten Kropf wrote:
>> The usage of static types with fixed length was actually no problem for me, 
>> so I proceeded to variable length types.
>> I created an n-dimensional point structure called "PointND" that contains a 
>> field of float8 values of dynamic length. I also put in a int4/int32 field 
>> for the length specification, as required by the documentation. So the 
>> structure looks like the following:
>> struct PointND
>> {
>> int32 dimensions;
>> float8 coordinates[1];
>> };
> The structure should begin with a int32 vl_len_ header. At creation / palloc 
> time the size must be set with the SET_VARSIZE macro, and the size can be 
> queried with the VARSIZE_ * macros -> doxygen.postgresql.org is your friend 
> here. Take a look at e.g. contrib/cube for examples.
> 
> regards,
> Yeb Havinga
> 

Reply via email to