diff --git a/src/backend/utils/adt/uuid.c b/src/backend/utils/adt/uuid.c
index f0b22c83f5a224f8f5554bc64a5752e3715fcf3e..d01fef4b574eec3e52ccffb89220b2b7d3bc52e9 100644
--- a/src/backend/utils/adt/uuid.c
+++ b/src/backend/utils/adt/uuid.c
@@ -6,7 +6,7 @@
  * Copyright (c) 2007, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/uuid.c,v 1.2 2007/01/28 20:25:38 neilc Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/uuid.c,v 1.3 2007/01/31 19:33:54 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -18,35 +18,16 @@
 #include "utils/builtins.h"
 #include "utils/uuid.h"
 
-/* Accepted GUID formats */
-
-/* UUID_FMT1 is the default output format */
-#define UUID_FMT1 "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
-#define UUID_FMT2 "{%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx}"
-#define UUID_FMT3 "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
-
-/* UUIDs are accepted in any of the following textual input formats. */
-#define UUID_CHK_FMT1 "00000000-0000-0000-0000-000000000000"
-#define UUID_CHK_FMT2 "{00000000-0000-0000-0000-000000000000}"
-#define UUID_CHK_FMT3 "00000000000000000000000000000000"
-
-#define PRINT_SIZE 40
-
 /* uuid size in bytes */
 #define UUID_LEN 16
 
 /* pg_uuid_t is declared to be struct pg_uuid_t in uuid.h */
 struct pg_uuid_t
 {
-    char  data[UUID_LEN];
+    unsigned char  data[UUID_LEN];
 };
 
 static void string_to_uuid(const char *source, pg_uuid_t *uuid);
-static void uuid_to_string(const char *fmt, const pg_uuid_t *uuid,
-						   char *uuid_str);
-static bool parse_uuid_string(const char *fmt, const char *chk_fmt,
-							  const char *source, char *data);
-static bool is_valid_format(const char *source, const char *fmt);
 static int uuid_internal_cmp(const pg_uuid_t *arg1, const pg_uuid_t *arg2);
 
 Datum
@@ -63,96 +44,105 @@ uuid_in(PG_FUNCTION_ARGS)
 Datum
 uuid_out(PG_FUNCTION_ARGS)
 {
-	pg_uuid_t 	*uuid = PG_GETARG_UUID_P(0);
-	char 		*uuid_str;
+	pg_uuid_t 			*uuid = PG_GETARG_UUID_P(0);
+	static const char hex_chars[] = "0123456789abcdef";
+	StringInfoData 		 buf;
+	int 				 i;
 
-	uuid_str = (char *) palloc(PRINT_SIZE);
-	uuid_to_string(UUID_FMT1, uuid, uuid_str);
-	PG_RETURN_CSTRING(uuid_str);
+	initStringInfo(&buf);
+	for (i = 0; i < UUID_LEN; i++)
+	{
+		int hi;
+		int lo;
+
+		/*
+		 * We print uuid values as a string of 8, 4, 4, 4, and then 12
+		 * hexadecimal characters, with each group is separated by a
+		 * hyphen ("-"). Therefore, add the hyphens at the appropriate
+		 * places here.
+		 */
+		if (i == 4 || i == 6 || i == 8 || i == 10)
+			appendStringInfoChar(&buf, '-');
+
+		hi = uuid->data[i] >> 4;
+		lo = uuid->data[i] & 0x0F;
+
+		appendStringInfoChar(&buf, hex_chars[hi]);
+		appendStringInfoChar(&buf, hex_chars[lo]);
+	}
+
+	PG_RETURN_CSTRING(buf.data);
 }
 
-/* string to uuid convertor by various format types */
+/*
+ * We allow UUIDs in three input formats: 8x-4x-4x-4x-12x,
+ * {8x-4x-4x-4x-12x}, and 32x, where "nx" means n hexadecimal digits
+ * (only the first format is used for output). We convert the first
+ * two formats into the latter format before further processing.
+ */
 static void
 string_to_uuid(const char *source, pg_uuid_t *uuid)
 {
-	if (!parse_uuid_string(UUID_FMT1, UUID_CHK_FMT1, source, uuid->data) &&
-		!parse_uuid_string(UUID_FMT2, UUID_CHK_FMT2, source, uuid->data) &&
-		!parse_uuid_string(UUID_FMT3, UUID_CHK_FMT3, source, uuid->data))
+	char 		hex_buf[32];	/* not NUL terminated */
+	int 		i;
+	int 		src_len;
+
+	src_len = strlen(source);
+	if (src_len != 32 && src_len != 36 && src_len != 38)
+		goto syntax_error;
+
+	if (src_len == 32)
+		memcpy(hex_buf, source, src_len);
+	else
 	{
-		ereport(ERROR,
-				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
-				 errmsg("invalid input syntax for uuid: \"%s\"",
-						source)));
-	}
-}
+		const char *str = source;
 
-/* check the validity of a uuid string by a given format */
-static bool
-is_valid_format(const char *source, const char *fmt)
-{
-	int i;
-	int fmtlen = strlen(fmt);
+		if (src_len == 38)
+		{
+			if (str[0] != '{' || str[37] != '}')
+				goto syntax_error;
 
-	/* check length first */
-	if (fmtlen != strlen(source))
-		return false;
+			str++;	/* skip the first character */
+		}
 
-	for (i = 0; i < fmtlen; i++)
-	{
-		int 	fc;
-		int 	sc;
-		bool 	valid_chr;
-
-		fc = fmt[i];
-		sc = source[i];
-
-		/* false if format chr is { or - and source is not */
-		if (fc != '0' && fc != sc)
-			return false;
-
-		/* check for valid char in source */
-		valid_chr = (sc >= '0' && sc <= '9') ||
-					(sc >= 'a' && sc <= 'f' ) ||
-					(sc >= 'A' && sc <= 'F' );
-		
-		if (fc == '0' && !valid_chr)
-			return false;
+		if (str[8] != '-' || str[13] != '-' ||
+			str[18] != '-' || str[23] != '-')
+			goto syntax_error;
+
+		memcpy(hex_buf, str, 8);
+		memcpy(hex_buf + 8, str + 9, 4);
+		memcpy(hex_buf + 12, str + 14, 4);
+		memcpy(hex_buf + 16, str + 19, 4);
+		memcpy(hex_buf + 20, str + 24, 12);
 	}
 
-	return true;
-}
+	for (i = 0; i < UUID_LEN; i++)
+	{
+		char str_buf[3];
 
-/* parse the uuid string to a format and return true if okay */
-static bool
-parse_uuid_string(const char *fmt, const char *chk_fmt,
-				  const char *source, char *data)
-{
-	int result = sscanf(source, fmt,
-						&data[0], &data[1], &data[2], &data[3], &data[4],
-						&data[5], &data[6], &data[7], &data[8], &data[9],
-						&data[10], &data[11], &data[12], &data[13],
-						&data[14], &data[15]);
+		memcpy(str_buf, &hex_buf[i * 2], 2);
+		if (!isxdigit((unsigned char) str_buf[0]) ||
+			!isxdigit((unsigned char) str_buf[1]))
+			goto syntax_error;
 
-	return (result == 16) && is_valid_format(source, chk_fmt);
-}
+		str_buf[2] = '\0';
+		uuid->data[i] = (unsigned char) strtoul(str_buf, NULL, 16);
+	}
 
-/* create a string representation of the uuid */
-static void
-uuid_to_string(const char *fmt, const pg_uuid_t *uuid, char *uuid_str)
-{
-	const char *data = uuid->data;
-    snprintf(uuid_str, PRINT_SIZE, fmt,
-			 data[0], data[1], data[2], data[3], data[4],
-			 data[5], data[6], data[7], data[8], data[9],
-			 data[10], data[11], data[12], data[13],
-			 data[14], data[15]);
+	return;
+
+syntax_error:
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+				 errmsg("invalid input syntax for uuid: \"%s\"",
+						source)));
 }
 
 Datum
 uuid_recv(PG_FUNCTION_ARGS)
 {
 	StringInfo 	 buffer = (StringInfo) PG_GETARG_POINTER(0);
-	pg_uuid_t 		*uuid;
+	pg_uuid_t 	*uuid;
 
 	uuid = (pg_uuid_t *) palloc(UUID_LEN);
 	memcpy(uuid->data, pq_getmsgbytes(buffer, UUID_LEN), UUID_LEN);
@@ -166,7 +156,7 @@ uuid_send(PG_FUNCTION_ARGS)
 	StringInfoData 		 buffer;
 
 	pq_begintypsend(&buffer);
-	pq_sendbytes(&buffer, uuid->data, UUID_LEN);
+	pq_sendbytes(&buffer, (char *) uuid->data, UUID_LEN);
 	PG_RETURN_BYTEA_P(pq_endtypsend(&buffer));
 }
 
@@ -246,7 +236,7 @@ Datum
 uuid_hash(PG_FUNCTION_ARGS)
 {
 	pg_uuid_t	*key = PG_GETARG_UUID_P(0);
-	return hash_any((unsigned char *) key, sizeof(pg_uuid_t));
+	return hash_any(key->data, UUID_LEN);
 }
 
 /* cast text to uuid */
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 89dfefe30fb511830fc1e6ef53a9cd2ae85eef7a..8157a3f6a597246c7071e2acea802fbe94f8edaf 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.377 2007/01/28 16:16:52 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.378 2007/01/31 19:33:54 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*							yyyymmddN */
-#define CATALOG_VERSION_NO	200701281
+#define CATALOG_VERSION_NO	200701311
 
 #endif
diff --git a/src/include/catalog/pg_cast.h b/src/include/catalog/pg_cast.h
index a66b8c5b2e61c9ebc9e321ed3e82bda3bfd6c367..4fbf237dad220dffa22e83533ae8bcf20aa372c9 100644
--- a/src/include/catalog/pg_cast.h
+++ b/src/include/catalog/pg_cast.h
@@ -10,7 +10,7 @@
  *
  * Copyright (c) 2002-2007, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_cast.h,v 1.29 2007/01/28 16:16:52 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_cast.h,v 1.30 2007/01/31 19:33:54 neilc Exp $
  *
  * NOTES
  *	  the genbki.sh script reads this file and generates .bki
@@ -400,5 +400,7 @@ DATA(insert ( 1700 1700 1703 i ));
 /* casts to and from uuid */ 
 DATA(insert (   25 2950 2964 a ));
 DATA(insert ( 2950   25 2965 a ));
+DATA(insert ( 1043 2950 2964 a ));
+DATA(insert ( 2950 1043 2965 a ));
 
 #endif   /* PG_CAST_H */
diff --git a/src/test/regress/expected/uuid.out b/src/test/regress/expected/uuid.out
index 9f714ad2e144f07b17aac35e052b073af7e5236f..331a6de5a2ee33bbc68c18a4bbe4f106b8587068 100644
--- a/src/test/regress/expected/uuid.out
+++ b/src/test/regress/expected/uuid.out
@@ -30,14 +30,14 @@ ERROR:  invalid input syntax for uuid: "11+11111-1111-1111-1111-111111111111"
 --inserting three input formats
 INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-1111-111111111111');
 INSERT INTO guid1(guid_field) VALUES('{22222222-2222-2222-2222-222222222222}');
-INSERT INTO guid1(guid_field) VALUES('33333333333333333333333333333333');
+INSERT INTO guid1(guid_field) VALUES('3f3e3c3b3a3039383736353433a2313e');
 -- retrieving the inserted data
 SELECT guid_field FROM guid1;
               guid_field              
 --------------------------------------
  11111111-1111-1111-1111-111111111111
  22222222-2222-2222-2222-222222222222
- 33333333-3333-3333-3333-333333333333
+ 3f3e3c3b-3a30-3938-3736-353433a2313e
 (3 rows)
 
 -- ordering test
@@ -46,19 +46,19 @@ SELECT guid_field FROM guid1 ORDER BY guid_field ASC;
 --------------------------------------
  11111111-1111-1111-1111-111111111111
  22222222-2222-2222-2222-222222222222
- 33333333-3333-3333-3333-333333333333
+ 3f3e3c3b-3a30-3938-3736-353433a2313e
 (3 rows)
 
 SELECT guid_field FROM guid1 ORDER BY guid_field DESC;
               guid_field              
 --------------------------------------
- 33333333-3333-3333-3333-333333333333
+ 3f3e3c3b-3a30-3938-3736-353433a2313e
  22222222-2222-2222-2222-222222222222
  11111111-1111-1111-1111-111111111111
 (3 rows)
 
 -- = operator test
-SELECT COUNT(*) FROM guid1 WHERE guid_field = '33333333-3333-3333-3333-333333333333';
+SELECT COUNT(*) FROM guid1 WHERE guid_field = '3f3e3c3b-3a30-3938-3736-353433a2313e';
  count 
 -------
      1
@@ -118,7 +118,7 @@ SELECT count(*) FROM pg_class WHERE relkind='i' AND relname LIKE 'guid%';
 INSERT INTO guid1(guid_field) VALUES('44444444-4444-4444-4444-444444444444');
 INSERT INTO guid2(guid_field) VALUES('11111111-1111-1111-1111-111111111111');
 INSERT INTO guid2(guid_field) VALUES('{22222222-2222-2222-2222-222222222222}');
-INSERT INTO guid2(guid_field) VALUES('33333333333333333333333333333333');
+INSERT INTO guid2(guid_field) VALUES('3f3e3c3b3a3039383736353433a2313e');
 -- join test
 SELECT COUNT(*) FROM guid1 g1 INNER JOIN guid2 g2 ON g1.guid_field = g2.guid_field;
  count 
diff --git a/src/test/regress/sql/uuid.sql b/src/test/regress/sql/uuid.sql
index 93153da9d704e6aa1f95b576b1b90b34f0a7bd44..48fe7e71108f82ab55f022ee052574bd3c1a8b0d 100644
--- a/src/test/regress/sql/uuid.sql
+++ b/src/test/regress/sql/uuid.sql
@@ -26,7 +26,7 @@ INSERT INTO guid1(guid_field) VALUES('11+11111-1111-1111-1111-111111111111');
 --inserting three input formats
 INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-1111-111111111111');
 INSERT INTO guid1(guid_field) VALUES('{22222222-2222-2222-2222-222222222222}');
-INSERT INTO guid1(guid_field) VALUES('33333333333333333333333333333333');
+INSERT INTO guid1(guid_field) VALUES('3f3e3c3b3a3039383736353433a2313e');
 
 -- retrieving the inserted data
 SELECT guid_field FROM guid1;
@@ -36,7 +36,7 @@ SELECT guid_field FROM guid1 ORDER BY guid_field ASC;
 SELECT guid_field FROM guid1 ORDER BY guid_field DESC;
 
 -- = operator test
-SELECT COUNT(*) FROM guid1 WHERE guid_field = '33333333-3333-3333-3333-333333333333';
+SELECT COUNT(*) FROM guid1 WHERE guid_field = '3f3e3c3b-3a30-3938-3736-353433a2313e';
 
 -- <> operator test
 SELECT COUNT(*) FROM guid1 WHERE guid_field <> '11111111111111111111111111111111';
@@ -69,7 +69,7 @@ SELECT count(*) FROM pg_class WHERE relkind='i' AND relname LIKE 'guid%';
 INSERT INTO guid1(guid_field) VALUES('44444444-4444-4444-4444-444444444444');
 INSERT INTO guid2(guid_field) VALUES('11111111-1111-1111-1111-111111111111');
 INSERT INTO guid2(guid_field) VALUES('{22222222-2222-2222-2222-222222222222}');
-INSERT INTO guid2(guid_field) VALUES('33333333333333333333333333333333');
+INSERT INTO guid2(guid_field) VALUES('3f3e3c3b3a3039383736353433a2313e');
 
 -- join test
 SELECT COUNT(*) FROM guid1 g1 INNER JOIN guid2 g2 ON g1.guid_field = g2.guid_field;