[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Uniqueidentifier postgresql
- To: misc_(_at_)_openbsd_(_dot_)_org
- Subject: Uniqueidentifier postgresql
- From: Roy Morris <rmorris_(_at_)_internetsecure_(_dot_)_com>
- Date: Tue, 1 Feb 2005 11:50:12 -0500
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