Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit05ce7d6

Browse files
author
Neil Conway
committed
Rewrite uuid input and output routines to avoid dependency on the
nonportable "hh" sprintf(3) length modifier. Instead, do the parsingand output by hand. The code to do this isn't ideal, but this isan interim measure anyway: the uuid type should probably use thein-memory struct layout specified by RFC 4122. For now, this patchshould hopefully rectify the buildfarm failures for the uuid test.Along the way, re-add pg_cast entries for uuid <-> varchar, whichI mistakenly removed earlier, and bump the catversion.
1 parent068bf65 commit05ce7d6

File tree

5 files changed

+96
-104
lines changed

5 files changed

+96
-104
lines changed

‎src/backend/utils/adt/uuid.c

Lines changed: 82 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Copyright (c) 2007, PostgreSQL Global Development Group
77
*
88
* IDENTIFICATION
9-
* $PostgreSQL: pgsql/src/backend/utils/adt/uuid.c,v 1.2 2007/01/28 20:25:38 neilc Exp $
9+
* $PostgreSQL: pgsql/src/backend/utils/adt/uuid.c,v 1.3 2007/01/31 19:33:54 neilc Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -18,35 +18,16 @@
1818
#include"utils/builtins.h"
1919
#include"utils/uuid.h"
2020

21-
/* Accepted GUID formats */
22-
23-
/* UUID_FMT1 is the default output format */
24-
#defineUUID_FMT1 "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
25-
#defineUUID_FMT2 "{%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx}"
26-
#defineUUID_FMT3 "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
27-
28-
/* UUIDs are accepted in any of the following textual input formats. */
29-
#defineUUID_CHK_FMT1 "00000000-0000-0000-0000-000000000000"
30-
#defineUUID_CHK_FMT2 "{00000000-0000-0000-0000-000000000000}"
31-
#defineUUID_CHK_FMT3 "00000000000000000000000000000000"
32-
33-
#definePRINT_SIZE 40
34-
3521
/* uuid size in bytes */
3622
#defineUUID_LEN 16
3723

3824
/* pg_uuid_t is declared to be struct pg_uuid_t in uuid.h */
3925
structpg_uuid_t
4026
{
41-
chardata[UUID_LEN];
27+
unsignedchardata[UUID_LEN];
4228
};
4329

4430
staticvoidstring_to_uuid(constchar*source,pg_uuid_t*uuid);
45-
staticvoiduuid_to_string(constchar*fmt,constpg_uuid_t*uuid,
46-
char*uuid_str);
47-
staticboolparse_uuid_string(constchar*fmt,constchar*chk_fmt,
48-
constchar*source,char*data);
49-
staticboolis_valid_format(constchar*source,constchar*fmt);
5031
staticintuuid_internal_cmp(constpg_uuid_t*arg1,constpg_uuid_t*arg2);
5132

5233
Datum
@@ -63,96 +44,105 @@ uuid_in(PG_FUNCTION_ARGS)
6344
Datum
6445
uuid_out(PG_FUNCTION_ARGS)
6546
{
66-
pg_uuid_t*uuid=PG_GETARG_UUID_P(0);
67-
char*uuid_str;
47+
pg_uuid_t*uuid=PG_GETARG_UUID_P(0);
48+
staticconstcharhex_chars[]="0123456789abcdef";
49+
StringInfoDatabuf;
50+
inti;
6851

69-
uuid_str= (char*)palloc(PRINT_SIZE);
70-
uuid_to_string(UUID_FMT1,uuid,uuid_str);
71-
PG_RETURN_CSTRING(uuid_str);
52+
initStringInfo(&buf);
53+
for (i=0;i<UUID_LEN;i++)
54+
{
55+
inthi;
56+
intlo;
57+
58+
/*
59+
* We print uuid values as a string of 8, 4, 4, 4, and then 12
60+
* hexadecimal characters, with each group is separated by a
61+
* hyphen ("-"). Therefore, add the hyphens at the appropriate
62+
* places here.
63+
*/
64+
if (i==4||i==6||i==8||i==10)
65+
appendStringInfoChar(&buf,'-');
66+
67+
hi=uuid->data[i] >>4;
68+
lo=uuid->data[i]&0x0F;
69+
70+
appendStringInfoChar(&buf,hex_chars[hi]);
71+
appendStringInfoChar(&buf,hex_chars[lo]);
72+
}
73+
74+
PG_RETURN_CSTRING(buf.data);
7275
}
7376

74-
/* string to uuid convertor by various format types */
77+
/*
78+
* We allow UUIDs in three input formats: 8x-4x-4x-4x-12x,
79+
* {8x-4x-4x-4x-12x}, and 32x, where "nx" means n hexadecimal digits
80+
* (only the first format is used for output). We convert the first
81+
* two formats into the latter format before further processing.
82+
*/
7583
staticvoid
7684
string_to_uuid(constchar*source,pg_uuid_t*uuid)
7785
{
78-
if (!parse_uuid_string(UUID_FMT1,UUID_CHK_FMT1,source,uuid->data)&&
79-
!parse_uuid_string(UUID_FMT2,UUID_CHK_FMT2,source,uuid->data)&&
80-
!parse_uuid_string(UUID_FMT3,UUID_CHK_FMT3,source,uuid->data))
86+
charhex_buf[32];/* not NUL terminated */
87+
inti;
88+
intsrc_len;
89+
90+
src_len=strlen(source);
91+
if (src_len!=32&&src_len!=36&&src_len!=38)
92+
gotosyntax_error;
93+
94+
if (src_len==32)
95+
memcpy(hex_buf,source,src_len);
96+
else
8197
{
82-
ereport(ERROR,
83-
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
84-
errmsg("invalid input syntax for uuid: \"%s\"",
85-
source)));
86-
}
87-
}
98+
constchar*str=source;
8899

89-
/* check the validity of a uuid string by a given format */
90-
staticbool
91-
is_valid_format(constchar*source,constchar*fmt)
92-
{
93-
inti;
94-
intfmtlen=strlen(fmt);
100+
if (src_len==38)
101+
{
102+
if (str[0]!='{'||str[37]!='}')
103+
gotosyntax_error;
95104

96-
/* check length first */
97-
if (fmtlen!=strlen(source))
98-
return false;
105+
str++;/* skip the first character */
106+
}
99107

100-
for (i=0;i<fmtlen;i++)
101-
{
102-
intfc;
103-
intsc;
104-
boolvalid_chr;
105-
106-
fc=fmt[i];
107-
sc=source[i];
108-
109-
/* false if format chr is { or - and source is not */
110-
if (fc!='0'&&fc!=sc)
111-
return false;
112-
113-
/* check for valid char in source */
114-
valid_chr= (sc >='0'&&sc <='9')||
115-
(sc >='a'&&sc <='f' )||
116-
(sc >='A'&&sc <='F' );
117-
118-
if (fc=='0'&& !valid_chr)
119-
return false;
108+
if (str[8]!='-'||str[13]!='-'||
109+
str[18]!='-'||str[23]!='-')
110+
gotosyntax_error;
111+
112+
memcpy(hex_buf,str,8);
113+
memcpy(hex_buf+8,str+9,4);
114+
memcpy(hex_buf+12,str+14,4);
115+
memcpy(hex_buf+16,str+19,4);
116+
memcpy(hex_buf+20,str+24,12);
120117
}
121118

122-
return true;
123-
}
119+
for (i=0;i<UUID_LEN;i++)
120+
{
121+
charstr_buf[3];
124122

125-
/* parse the uuid string to a format and return true if okay */
126-
staticbool
127-
parse_uuid_string(constchar*fmt,constchar*chk_fmt,
128-
constchar*source,char*data)
129-
{
130-
intresult=sscanf(source,fmt,
131-
&data[0],&data[1],&data[2],&data[3],&data[4],
132-
&data[5],&data[6],&data[7],&data[8],&data[9],
133-
&data[10],&data[11],&data[12],&data[13],
134-
&data[14],&data[15]);
123+
memcpy(str_buf,&hex_buf[i*2],2);
124+
if (!isxdigit((unsignedchar)str_buf[0])||
125+
!isxdigit((unsignedchar)str_buf[1]))
126+
gotosyntax_error;
135127

136-
return (result==16)&&is_valid_format(source,chk_fmt);
137-
}
128+
str_buf[2]='\0';
129+
uuid->data[i]= (unsignedchar)strtoul(str_buf,NULL,16);
130+
}
138131

139-
/* create a string representation of the uuid */
140-
staticvoid
141-
uuid_to_string(constchar*fmt,constpg_uuid_t*uuid,char*uuid_str)
142-
{
143-
constchar*data=uuid->data;
144-
snprintf(uuid_str,PRINT_SIZE,fmt,
145-
data[0],data[1],data[2],data[3],data[4],
146-
data[5],data[6],data[7],data[8],data[9],
147-
data[10],data[11],data[12],data[13],
148-
data[14],data[15]);
132+
return;
133+
134+
syntax_error:
135+
ereport(ERROR,
136+
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
137+
errmsg("invalid input syntax for uuid: \"%s\"",
138+
source)));
149139
}
150140

151141
Datum
152142
uuid_recv(PG_FUNCTION_ARGS)
153143
{
154144
StringInfobuffer= (StringInfo)PG_GETARG_POINTER(0);
155-
pg_uuid_t*uuid;
145+
pg_uuid_t*uuid;
156146

157147
uuid= (pg_uuid_t*)palloc(UUID_LEN);
158148
memcpy(uuid->data,pq_getmsgbytes(buffer,UUID_LEN),UUID_LEN);
@@ -166,7 +156,7 @@ uuid_send(PG_FUNCTION_ARGS)
166156
StringInfoDatabuffer;
167157

168158
pq_begintypsend(&buffer);
169-
pq_sendbytes(&buffer,uuid->data,UUID_LEN);
159+
pq_sendbytes(&buffer,(char*)uuid->data,UUID_LEN);
170160
PG_RETURN_BYTEA_P(pq_endtypsend(&buffer));
171161
}
172162

@@ -246,7 +236,7 @@ Datum
246236
uuid_hash(PG_FUNCTION_ARGS)
247237
{
248238
pg_uuid_t*key=PG_GETARG_UUID_P(0);
249-
returnhash_any((unsignedchar*)key,sizeof(pg_uuid_t));
239+
returnhash_any(key->data,UUID_LEN);
250240
}
251241

252242
/* cast text to uuid */

‎src/include/catalog/catversion.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
3838
* Portions Copyright (c) 1994, Regents of the University of California
3939
*
40-
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.377 2007/01/28 16:16:52 neilc Exp $
40+
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.378 2007/01/31 19:33:54 neilc Exp $
4141
*
4242
*-------------------------------------------------------------------------
4343
*/
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/*yyyymmddN */
56-
#defineCATALOG_VERSION_NO200701281
56+
#defineCATALOG_VERSION_NO200701311
5757

5858
#endif

‎src/include/catalog/pg_cast.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
* Copyright (c) 2002-2007, PostgreSQL Global Development Group
1212
*
13-
* $PostgreSQL: pgsql/src/include/catalog/pg_cast.h,v 1.29 2007/01/28 16:16:52 neilc Exp $
13+
* $PostgreSQL: pgsql/src/include/catalog/pg_cast.h,v 1.30 2007/01/31 19:33:54 neilc Exp $
1414
*
1515
* NOTES
1616
* the genbki.sh script reads this file and generates .bki
@@ -400,5 +400,7 @@ DATA(insert ( 1700 1700 1703 i ));
400400
/* casts to and from uuid */
401401
DATA(insert (2529502964a ));
402402
DATA(insert (2950252965a ));
403+
DATA(insert (104329502964a ));
404+
DATA(insert (295010432965a ));
403405

404406
#endif/* PG_CAST_H */

‎src/test/regress/expected/uuid.out

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ ERROR: invalid input syntax for uuid: "11+11111-1111-1111-1111-111111111111"
3030
--inserting three input formats
3131
INSERT INTO guid1(guid_field) VALUES('11111111-1111-1111-1111-111111111111');
3232
INSERT INTO guid1(guid_field) VALUES('{22222222-2222-2222-2222-222222222222}');
33-
INSERT INTO guid1(guid_field) VALUES('33333333333333333333333333333333');
33+
INSERT INTO guid1(guid_field) VALUES('3f3e3c3b3a3039383736353433a2313e');
3434
-- retrieving the inserted data
3535
SELECT guid_field FROM guid1;
3636
guid_field
3737
--------------------------------------
3838
11111111-1111-1111-1111-111111111111
3939
22222222-2222-2222-2222-222222222222
40-
33333333-3333-3333-3333-333333333333
40+
3f3e3c3b-3a30-3938-3736-353433a2313e
4141
(3 rows)
4242

4343
-- ordering test
@@ -46,19 +46,19 @@ SELECT guid_field FROM guid1 ORDER BY guid_field ASC;
4646
--------------------------------------
4747
11111111-1111-1111-1111-111111111111
4848
22222222-2222-2222-2222-222222222222
49-
33333333-3333-3333-3333-333333333333
49+
3f3e3c3b-3a30-3938-3736-353433a2313e
5050
(3 rows)
5151

5252
SELECT guid_field FROM guid1 ORDER BY guid_field DESC;
5353
guid_field
5454
--------------------------------------
55-
33333333-3333-3333-3333-333333333333
55+
3f3e3c3b-3a30-3938-3736-353433a2313e
5656
22222222-2222-2222-2222-222222222222
5757
11111111-1111-1111-1111-111111111111
5858
(3 rows)
5959

6060
-- = operator test
61-
SELECT COUNT(*) FROM guid1 WHERE guid_field = '33333333-3333-3333-3333-333333333333';
61+
SELECT COUNT(*) FROM guid1 WHERE guid_field = '3f3e3c3b-3a30-3938-3736-353433a2313e';
6262
count
6363
-------
6464
1
@@ -118,7 +118,7 @@ SELECT count(*) FROM pg_class WHERE relkind='i' AND relname LIKE 'guid%';
118118
INSERT INTO guid1(guid_field) VALUES('44444444-4444-4444-4444-444444444444');
119119
INSERT INTO guid2(guid_field) VALUES('11111111-1111-1111-1111-111111111111');
120120
INSERT INTO guid2(guid_field) VALUES('{22222222-2222-2222-2222-222222222222}');
121-
INSERT INTO guid2(guid_field) VALUES('33333333333333333333333333333333');
121+
INSERT INTO guid2(guid_field) VALUES('3f3e3c3b3a3039383736353433a2313e');
122122
-- join test
123123
SELECT COUNT(*) FROM guid1 g1 INNER JOIN guid2 g2 ON g1.guid_field = g2.guid_field;
124124
count

‎src/test/regress/sql/uuid.sql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ INSERT INTO guid1(guid_field) VALUES('11+11111-1111-1111-1111-111111111111');
2626
--inserting three input formats
2727
INSERT INTO guid1(guid_field)VALUES('11111111-1111-1111-1111-111111111111');
2828
INSERT INTO guid1(guid_field)VALUES('{22222222-2222-2222-2222-222222222222}');
29-
INSERT INTO guid1(guid_field)VALUES('33333333333333333333333333333333');
29+
INSERT INTO guid1(guid_field)VALUES('3f3e3c3b3a3039383736353433a2313e');
3030

3131
-- retrieving the inserted data
3232
SELECT guid_fieldFROM guid1;
@@ -36,7 +36,7 @@ SELECT guid_field FROM guid1 ORDER BY guid_field ASC;
3636
SELECT guid_fieldFROM guid1ORDER BY guid_fieldDESC;
3737

3838
-- = operator test
39-
SELECTCOUNT(*)FROM guid1WHERE guid_field='33333333-3333-3333-3333-333333333333';
39+
SELECTCOUNT(*)FROM guid1WHERE guid_field='3f3e3c3b-3a30-3938-3736-353433a2313e';
4040

4141
-- <> operator test
4242
SELECTCOUNT(*)FROM guid1WHERE guid_field<>'11111111111111111111111111111111';
@@ -69,7 +69,7 @@ SELECT count(*) FROM pg_class WHERE relkind='i' AND relname LIKE 'guid%';
6969
INSERT INTO guid1(guid_field)VALUES('44444444-4444-4444-4444-444444444444');
7070
INSERT INTO guid2(guid_field)VALUES('11111111-1111-1111-1111-111111111111');
7171
INSERT INTO guid2(guid_field)VALUES('{22222222-2222-2222-2222-222222222222}');
72-
INSERT INTO guid2(guid_field)VALUES('33333333333333333333333333333333');
72+
INSERT INTO guid2(guid_field)VALUES('3f3e3c3b3a3039383736353433a2313e');
7373

7474
-- join test
7575
SELECTCOUNT(*)FROM guid1 g1INNER JOIN guid2 g2ONg1.guid_field=g2.guid_field;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp