[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Uniqueidentifier postgresql



I have a program that basically adds the ability to generate
the same datatype/function as mssql uniqueidentifier for postgresql. 

We have contacted the author, but he does not know why based
on the error message he was sent.

The instructions basically say, toss it in the contrib directory and run
make and make install etc ... but of course it fails. First it could not fine
uuid.h, which I fixed the path was wrong. Now however it fails with 
another error. I am not a programmer and was hoping someone would
have a clue why this is yaking. The code below the error. 

Thanks in advance for any pointers

# gmake
cc -luuid -O2 -pipe -fno-strict-aliasing -Wall -Wmissing-prototypes 
-Wmissing-declarations -fpic -DPIC -fpic -DPIC -I. -I. -I../../src/include 
-I/usr/include  -c -o uniqueidentifier.o uniqueidentifier.c
uniqueidentifier.c:33: error: field `uid' has incomplete type
uniqueidentifier.c: In function `uniqueidentifier_in':
uniqueidentifier.c:79: warning: implicit declaration of function `uuid_parse'
uniqueidentifier.c: In function `uniqueidentifier_out':
uniqueidentifier.c:107: warning: implicit declaration of function 
`uuid_unparse'
uniqueidentifier.c: In function `newid':
uniqueidentifier.c:296: warning: implicit declaration of function 
`uuid_generate'
gmake: *** [uniqueidentifier.o] Error 1
-- 
Roy Morris
Internetsecure Inc.
905.469.6522 X291
rmorris_(_at_)_internetsecure_(_dot_)_com

---
/*
 * PostgreSQL type definitions for uniqueidentifiers.
 *
 * $Id: uniqueidentifier.c,v 1.7 2003/12/01 20:22:35 dimagog Exp $
 *
 * Copyright (C) 2001-2003 Dmitry G. Mastrukov.
 * Code for _uid_compare is based on libuuid
 *                                      Copyright (C) 1996, 1997 Theodore 
Ts'o.
 *
 * Code for uniqueidentifier_text Copyright (C) 2002 Hussein Patni
 * Code for uniqueidentifier_from_text Copyright (C) 2003 David Bradford
 *
 * %Begin-Header%
 * This file may be redistributed under the terms of the GNU
 * Library General Public License.
 * %End-Header%
 *
 */

#include <string.h>
#include <uuid/uuid.h>
#include "postgres.h"
#include "fmgr.h"
#include "access/hash.h"


/*
 *      Here is the internal storage format for uniqueidentifiers.
 */

typedef struct uniqueidentifier
{
        uuid_t          uid;
}                       uniqueidentifier;


/*
 *      Various forward declarations:
 */

Datum           uniqueidentifier_in(PG_FUNCTION_ARGS);
Datum           uniqueidentifier_out(PG_FUNCTION_ARGS);

Datum           uniqueidentifier_lt(PG_FUNCTION_ARGS);
Datum           uniqueidentifier_le(PG_FUNCTION_ARGS);
Datum           uniqueidentifier_eq(PG_FUNCTION_ARGS);
Datum           uniqueidentifier_ge(PG_FUNCTION_ARGS);
Datum           uniqueidentifier_gt(PG_FUNCTION_ARGS);
Datum           uniqueidentifier_ne(PG_FUNCTION_ARGS);

Datum           uniqueidentifier_cmp(PG_FUNCTION_ARGS);
Datum           uniqueidentifier_hash(PG_FUNCTION_ARGS);

Datum           newid(PG_FUNCTION_ARGS);
Datum           uniqueidentifier_text(PG_FUNCTION_ARGS);
Datum           uniqueidentifier_from_text(PG_FUNCTION_ARGS);

static int32    _uid_compare(uniqueidentifier *u1, uniqueidentifier *u2);

/*
 *      uniqueidentifier input function:
 */

PG_FUNCTION_INFO_V1(uniqueidentifier_in);
Datum
uniqueidentifier_in(PG_FUNCTION_ARGS)
{
        uniqueidentifier *result;
        char *in = PG_GETARG_CSTRING(0);

        if (strlen(in) != 36)
        {
                elog(ERROR, "uniqueidentifier_in: invalid uniqueidentifier 
\"%s\"", in);
                PG_RETURN_POINTER (NULL);
        }

        result = (uniqueidentifier *) palloc(sizeof(uniqueidentifier));

        if (uuid_parse(in, result->uid) != 0)
        {
                elog(ERROR, "uniqueidentifier_in: wrong uniqueidentifier 
\"%s\"", in);
                PG_RETURN_POINTER (NULL);
        }
        PG_RETURN_POINTER (result);
}



/*
 *      uniqueidentifier output function:
 */

PG_FUNCTION_INFO_V1(uniqueidentifier_out);
Datum
uniqueidentifier_out(PG_FUNCTION_ARGS)
{
        char *result;
        uniqueidentifier *in = (uniqueidentifier *) PG_GETARG_POINTER(0);

        if (in == NULL)
                PG_RETURN_CSTRING (NULL);

        result = (char *) palloc(37);

        result[0] = '\0';

        uuid_unparse(in->uid, result);

        PG_RETURN_CSTRING (result);
}

/*
 *      uniqueidentifier to text conversion function:
 */

PG_FUNCTION_INFO_V1(uniqueidentifier_text);
Datum
uniqueidentifier_text(PG_FUNCTION_ARGS)
{
        char *s;
        uniqueidentifier *val = (uniqueidentifier *) PG_GETARG_POINTER(0);
        int len;
        text *result;

        s = (char *) palloc(37);
        s[0] = '\0';
        uuid_unparse(val->uid, s);

        len = strlen(s);

        result = (text *) palloc(VARHDRSZ + len);
        VARATT_SIZEP(result) = len + VARHDRSZ;
        memcpy(VARDATA(result),s,len);
        pfree(s);

        PG_RETURN_TEXT_P(result);
}

/*
 *      text to uniqueidentifier conversion function:
 */

PG_FUNCTION_INFO_V1(uniqueidentifier_from_text);
Datum
uniqueidentifier_from_text(PG_FUNCTION_ARGS)
{
        uniqueidentifier *result;
        char *in  = NULL;
        int len = 0;
        text *data = PG_GETARG_TEXT_P(0);

        len = (VARSIZE(data)-VARHDRSZ);
        if (len != 36)
        {
                elog(ERROR, "uniqueidentifier_from_text: invalid 
uniqueidentifier length: \"%d\"", len);
                PG_RETURN_POINTER (NULL);
        }

        in = (char*)palloc( sizeof(char)*(len+1) );
        if( !in )
        {
            elog(ERROR, "not enough memory in uniqueidentifier_from_text");
            PG_RETURN_POINTER(NULL);
        }
        memset(in, 0, len+1);
        memcpy(in, VARDATA(data), len);
        in[len+1]='\0';

        result = (uniqueidentifier *) palloc(sizeof(uniqueidentifier));
        if (uuid_parse(in, result->uid) != 0)
        {
                elog(ERROR, "uniqueidentifier_from_text: wrong 
uniqueidentifier \"%s\"", in);
                pfree(in);
                PG_RETURN_POINTER (NULL);
        }
        pfree(in);
        PG_RETURN_POINTER (result);
}

/*
 *      Boolean tests:
 */

PG_FUNCTION_INFO_V1(uniqueidentifier_lt);
Datum
uniqueidentifier_lt(PG_FUNCTION_ARGS)
{
        uniqueidentifier *u1 = (uniqueidentifier *) PG_GETARG_POINTER(0);
        uniqueidentifier *u2 = (uniqueidentifier *) PG_GETARG_POINTER(1);
        PG_RETURN_BOOL (_uid_compare(u1, u2) < 0);
};

PG_FUNCTION_INFO_V1(uniqueidentifier_le);
Datum
uniqueidentifier_le(PG_FUNCTION_ARGS)
{
        uniqueidentifier *u1 = (uniqueidentifier *) PG_GETARG_POINTER(0);
        uniqueidentifier *u2 = (uniqueidentifier *) PG_GETARG_POINTER(1);
        PG_RETURN_BOOL (_uid_compare(u1, u2) <= 0);
};

PG_FUNCTION_INFO_V1(uniqueidentifier_eq);
Datum
uniqueidentifier_eq(PG_FUNCTION_ARGS)
{
        uniqueidentifier *u1 = (uniqueidentifier *) PG_GETARG_POINTER(0);
        uniqueidentifier *u2 = (uniqueidentifier *) PG_GETARG_POINTER(1);

        if ((u1 == NULL) || (u2 == NULL)) {
            if ((u1 == NULL) && (u2 == NULL))
                PG_RETURN_BOOL (true);
            else
                PG_RETURN_BOOL (false);
        }

        if (memcmp(u1->uid, u2->uid, 16) == 0)
            PG_RETURN_BOOL (true);
        else
            PG_RETURN_BOOL (false);
};

PG_FUNCTION_INFO_V1(uniqueidentifier_ge);
Datum
uniqueidentifier_ge(PG_FUNCTION_ARGS)
{
        uniqueidentifier *u1 = (uniqueidentifier *) PG_GETARG_POINTER(0);
        uniqueidentifier *u2 = (uniqueidentifier *) PG_GETARG_POINTER(1);
        PG_RETURN_BOOL (_uid_compare(u1, u2) >= 0);
};

PG_FUNCTION_INFO_V1(uniqueidentifier_gt);
Datum
uniqueidentifier_gt(PG_FUNCTION_ARGS)
{
        uniqueidentifier *u1 = (uniqueidentifier *) PG_GETARG_POINTER(0);
        uniqueidentifier *u2 = (uniqueidentifier *) PG_GETARG_POINTER(1);
        PG_RETURN_BOOL (_uid_compare(u1, u2) > 0);
};

PG_FUNCTION_INFO_V1(uniqueidentifier_ne);
Datum
uniqueidentifier_ne(PG_FUNCTION_ARGS)
{
        uniqueidentifier *u1 = (uniqueidentifier *) PG_GETARG_POINTER(0);
        uniqueidentifier *u2 = (uniqueidentifier *) PG_GETARG_POINTER(1);
        if ((u1 == NULL) || (u2 == NULL)) {
            if ((u1 == NULL) && (u2 == NULL))
                PG_RETURN_BOOL (false);
            else
                PG_RETURN_BOOL (true);
        }
        if (memcmp(u1->uid, u2->uid, 16) == 0)
            PG_RETURN_BOOL (false);
        else
            PG_RETURN_BOOL (true);
};


/*
 *      Comparison function for B-tree sorting:
 */

PG_FUNCTION_INFO_V1(uniqueidentifier_cmp);
Datum
uniqueidentifier_cmp(PG_FUNCTION_ARGS)
{
        uniqueidentifier *u1 = (uniqueidentifier *) PG_GETARG_POINTER(0);
        uniqueidentifier *u2 = (uniqueidentifier *) PG_GETARG_POINTER(1);
        PG_RETURN_INT32 (_uid_compare(u1, u2));
};


/*
 *      Hash function for hash sorting:
 */

PG_FUNCTION_INFO_V1(uniqueidentifier_hash);
Datum
uniqueidentifier_hash(PG_FUNCTION_ARGS)
{
        uniqueidentifier *key = (uniqueidentifier *) PG_GETARG_POINTER(0);
        return hash_any ((unsigned char *) key, sizeof(uniqueidentifier));
};


/*
 *      New uniqueidentifier:
 */

PG_FUNCTION_INFO_V1(newid);
Datum
newid(PG_FUNCTION_ARGS)
{
        uniqueidentifier *result = (uniqueidentifier *) 
palloc(sizeof(uniqueidentifier));

        uuid_generate(result->uid);

        PG_RETURN_POINTER(result);
};


/*
 *      Internal compare function:
 */

#define UUCMP(u1,u2) if (u1 != u2) return((u1 < u2) ? -1 : 1);

static int32
_uid_compare(uniqueidentifier *u1, uniqueidentifier *u2)
{
        uint8   *ptr1 = u1->uid;
        uint32 time_low1;
        uint16 time_mid1;
        uint16 time_hi_and_version1;
        uint16 clock_seq1;
        uint8   *ptr2 = u2->uid;
        uint32 time_low2;
        uint16 time_mid2;
        uint16 time_hi_and_version2;
        uint16 clock_seq2;

        if ((u1 == NULL) || (u2 == NULL)) {
            if ((u1 == NULL) && (u2 == NULL))
                return 0;
            if (u1 == NULL)
                return 1;
            else
                return -1;
        }

        if(memcmp(u1->uid, u2->uid, 16) == 0)
            return 0;

        time_low1 = *ptr1++;
        time_low1 = (time_low1 << 8) | *ptr1++;
        time_low1 = (time_low1 << 8) | *ptr1++;
        time_low1 = (time_low1 << 8) | *ptr1++;
        time_low2 = *ptr2++;
        time_low2 = (time_low2 << 8) | *ptr2++;
        time_low2 = (time_low2 << 8) | *ptr2++;
        time_low2 = (time_low2 << 8) | *ptr2++;
        UUCMP(time_low1, time_low2);

        time_mid1 = *ptr1++;
        time_mid1 = (time_mid1 << 8) | *ptr1++;
        time_mid2 = *ptr2++;
        time_mid2 = (time_mid2 << 8) | *ptr2++;
        UUCMP(time_mid1, time_mid2);

        time_hi_and_version1 = *ptr1++;
        time_hi_and_version1 = (time_hi_and_version1 << 8) | *ptr1++;
        time_hi_and_version2 = *ptr2++;
        time_hi_and_version2 = (time_hi_and_version2 << 8) | *ptr2++;
        UUCMP(time_hi_and_version1, time_hi_and_version2);


        clock_seq1 = *ptr1++;
        clock_seq1 = (clock_seq1 << 8) | *ptr1++;
        clock_seq2 = *ptr2++;
        clock_seq2 = (clock_seq2 << 8) | *ptr2++;
        UUCMP(clock_seq1, clock_seq2);


        return memcmp(ptr1, ptr2, 6);
}



Visit your host, monkey.org