|
From: <asf...@us...> - 2012-07-11 01:56:44
|
Revision: 54708
http://firebird.svn.sourceforge.net/firebird/?rev=54708&view=rev
Author: asfernandes
Date: 2012-07-11 01:56:37 +0000 (Wed, 11 Jul 2012)
Log Message:
-----------
Frontport UUID fixes (CORE-3238 and CORE-3887).
Modified Paths:
--------------
firebird/trunk/doc/sql.extensions/README.builtin_functions.txt
firebird/trunk/src/common/os/guid.h
firebird/trunk/src/dsql/parse.y
firebird/trunk/src/jrd/SysFunction.cpp
firebird/trunk/src/jrd/trace/TraceService.cpp
firebird/trunk/src/utilities/gstat/ppg.cpp
firebird/trunk/src/utilities/nbackup/nbackup.cpp
firebird/trunk/src/yvalve/keywords.cpp
Modified: firebird/trunk/doc/sql.extensions/README.builtin_functions.txt
===================================================================
--- firebird/trunk/doc/sql.extensions/README.builtin_functions.txt 2012-07-11 01:38:29 UTC (rev 54707)
+++ firebird/trunk/doc/sql.extensions/README.builtin_functions.txt 2012-07-11 01:56:37 UTC (rev 54708)
@@ -246,38 +246,18 @@
Format:
CHAR_TO_UUID( <string> )
-Notes:
- If you have not used this function before, its usage is discouraged. CHAR_TO_UUID2 supersedes it.
+Important (for big-endian servers):
+ It has been discovered that before Firebird 2.5.2, CHAR_TO_UUID and UUID_TO_CHAR works
+ incorrectly in big-endian servers. In these machines, bytes/characters are swapped and goes in
+ wrong positions when converting. This bug was fixed in 2.5.2 and 3.0, but that means these
+ functions now returns different values (for the same input parameter) than before.
Example:
select char_to_uuid('93519227-8D50-4E47-81AA-8F6678C096A1') from rdb$database;
-See also: GEN_UUID, CHAR_TO_UUID2, UUID_TO_CHAR and UUID_TO_CHAR2
+See also: GEN_UUID and UUID_TO_CHAR
--------------
-CHAR_TO_UUID2
--------------
-
-Function:
- Converts the CHAR(32) ASCII representation of an UUID
- (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) to the CHAR(16) OCTETS
- representation (optimized for storage).
-
-Format:
- CHAR_TO_UUID2( <string> )
-
-Notes:
- This function supersedes CHAR_TO_UUID. The difference between them is that CHAR_TO_UUID does a
- byte-by-byte conversion of the ASCII string to the OCTETS one, while CHAR_TO_UUID2 converts
- a RFC-4122 compliant ASCII UUID to a compliant OCTETS string.
-
-Example:
- select char_to_uuid2('93519227-8D50-4E47-81AA-8F6678C096A1') from rdb$database;
-
-See also: GEN_UUID, UUID_TO_CHAR2
-
-
---
COS
---
@@ -431,17 +411,17 @@
Format:
GEN_UUID()
-Notes:
- In Firebird 2.5.0 and 2.5.1, GEN_UUID was returning completely random strings. This is not
- compliant with the RFC-4122 (UUID specification).
- In Firebird 2.5.2 and 3.0 this was fixed. Now GEN_UUID returns a compliant UUID version 4
+Important:
+ Before Firebird 2.5.2, GEN_UUID was returning completely random strings. This is not compliant
+ with the RFC-4122 (UUID specification).
+ This was fixed in Firebird 2.5.2 and 3.0. Now GEN_UUID returns a compliant UUID version 4
string, where some bits are reserved and the others are random. The string format of a compliant
UUID is XXXXXXXX-XXXX-4XXX-YXXX-XXXXXXXXXXXX, where 4 is fixed (version) and Y is 8, 9, A or B.
Example:
insert into records (id) value (gen_uuid());
-See also: CHAR_TO_UUID, UUID_TO_CHAR, CHAR_TO_UUID2, UUID_TO_CHAR2
+See also: CHAR_TO_UUID and UUID_TO_CHAR
----
@@ -873,33 +853,13 @@
Format:
UUID_TO_CHAR( <string> )
-Notes:
- If you have not used this function before, its usage is discouraged. UUID_TO_CHAR2 supersedes it.
+Important (for big-endian servers):
+ It has been discovered that before Firebird 2.5.2, CHAR_TO_UUID and UUID_TO_CHAR works
+ incorrectly in big-endian servers. In these machines, bytes/characters are swapped and goes in
+ wrong positions when converting. This bug was fixed in 2.5.2 and 3.0, but that means these
+ functions now returns different values (for the same input parameter) than before.
Example:
select uuid_to_char(gen_uuid()) from rdb$database;
-See also: GEN_UUID, UUID_TO_CHAR2, CHAR_TO_UUID and CHAR_TO_UUID2
-
-
--------------
-UUID_TO_CHAR2
--------------
-
-Function:
- Converts a CHAR(16) OCTETS UUID (that's returned by GEN_UUID) to the
- CHAR(32) ASCII representation (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).
-
-Format:
- UUID_TO_CHAR2( <string> )
-
-Notes:
- This function supersedes UUID_TO_CHAR. The difference between them is that UUID_TO_CHAR does a
- byte-by-byte conversion of the OCTETS string to the ASCII one, while UUID_TO_CHAR2 converts
- a RFC-4122 compliant OCTETS UUID to a compliant ASCII string. Also, UUID_TO_CHAR returns
- upper-cased string and UUID_TO_CHAR2 returns lower-cased string.
-
-Example:
- select uuid_to_char2(gen_uuid()) from rdb$database;
-
-See also: GEN_UUID, CHAR_TO_UUID2
+See also: GEN_UUID and CHAR_TO_UUID
Modified: firebird/trunk/src/common/os/guid.h
===================================================================
--- firebird/trunk/src/common/os/guid.h 2012-07-11 01:38:29 UTC (rev 54707)
+++ firebird/trunk/src/common/os/guid.h 2012-07-11 01:56:37 UTC (rev 54708)
@@ -40,20 +40,11 @@
const char* const GUID_LEGACY_FORMAT =
"{%04hX%04hX-%04hX-%04hX-%04hX-%04hX%04hX%04hX}";
-const char* const GUID_NEW_FORMAT_UPPER =
+const char* const GUID_NEW_FORMAT =
"{%02hX%02hX%02hX%02hX-%02hX%02hX-%02hX%02hX-%02hX%02hX-%02hX%02hX%02hX%02hX%02hX%02hX}";
-const char* const GUID_NEW_FORMAT_LOWER =
- "{%02hx%02hx%02hx%02hx-%02hx%02hx-%02hx%02hx-%02hx%02hx-%02hx%02hx%02hx%02hx%02hx%02hx}";
struct Guid
{
- enum Style
- {
- STYLE_NBACKUP, // Format introduced with nbackup
- STYLE_BROKEN, // Format introduced in FB 2.5.0
- STYLE_UUID // Format as defined in the RFC-4122.
- };
-
union
{
USHORT data[8];
@@ -71,87 +62,21 @@
void GenerateRandomBytes(void* buffer, size_t size);
void GenerateGuid(Guid* guid);
-// These functions receive buffers of at least GUID_BUFF_SIZE length
+// These functions receive buffers of at least GUID_BUFF_SIZE length.
+// Warning: they are BROKEN in little-endian and should not be used on new code.
-inline void GuidToString(char* buffer, const Guid* guid, Guid::Style style)
+inline void GuidToString(char* buffer, const Guid* guid)
{
- switch (style)
- {
- case Guid::STYLE_NBACKUP:
- sprintf(buffer, GUID_LEGACY_FORMAT,
- guid->data[0], guid->data[1], guid->data[2], guid->data[3],
- guid->data[4], guid->data[5], guid->data[6], guid->data[7]);
- break;
-
- case Guid::STYLE_BROKEN:
- sprintf(buffer, GUID_NEW_FORMAT_UPPER,
- USHORT(guid->data[0] & 0xFF), USHORT(guid->data[0] >> 8),
- USHORT(guid->data[1] & 0xFF), USHORT(guid->data[1] >> 8),
- USHORT(guid->data[2] & 0xFF), USHORT(guid->data[2] >> 8),
- USHORT(guid->data[3] & 0xFF), USHORT(guid->data[3] >> 8),
- USHORT(guid->data[4] & 0xFF), USHORT(guid->data[4] >> 8),
- USHORT(guid->data[5] & 0xFF), USHORT(guid->data[5] >> 8),
- USHORT(guid->data[6] & 0xFF), USHORT(guid->data[6] >> 8),
- USHORT(guid->data[7] & 0xFF), USHORT(guid->data[7] >> 8));
- break;
-
- case Guid::STYLE_UUID:
- sprintf(buffer, GUID_NEW_FORMAT_LOWER,
- USHORT((guid->data1 >> 24) & 0xFF), USHORT((guid->data1 >> 16) & 0xFF),
- USHORT((guid->data1 >> 8) & 0xFF), USHORT(guid->data1 & 0xFF),
- USHORT((guid->data2 >> 8) & 0xFF), USHORT(guid->data2 & 0xFF),
- USHORT((guid->data3 >> 8) & 0xFF), USHORT(guid->data3 & 0xFF),
- USHORT(guid->data4[0]), USHORT(guid->data4[1]),
- USHORT(guid->data4[2]), USHORT(guid->data4[3]),
- USHORT(guid->data4[4]), USHORT(guid->data4[5]),
- USHORT(guid->data4[6]), USHORT(guid->data4[7]));
- break;
- }
+ sprintf(buffer, GUID_LEGACY_FORMAT,
+ guid->data[0], guid->data[1], guid->data[2], guid->data[3],
+ guid->data[4], guid->data[5], guid->data[6], guid->data[7]);
}
-inline void StringToGuid(Guid* guid, const char* buffer, Guid::Style style)
+inline void StringToGuid(Guid* guid, const char* buffer)
{
- if (style == Guid::STYLE_NBACKUP)
- {
- sscanf(buffer, GUID_LEGACY_FORMAT,
- &guid->data[0], &guid->data[1], &guid->data[2], &guid->data[3],
- &guid->data[4], &guid->data[5], &guid->data[6], &guid->data[7]);
- }
- else
- {
- USHORT bytes[16];
- sscanf(buffer, GUID_NEW_FORMAT_LOWER,
- &bytes[0], &bytes[1], &bytes[2], &bytes[3],
- &bytes[4], &bytes[5], &bytes[6], &bytes[7],
- &bytes[8], &bytes[9], &bytes[10], &bytes[11],
- &bytes[12], &bytes[13], &bytes[14], &bytes[15]);
-
- if (style == Guid::STYLE_BROKEN)
- {
- guid->data[0] = bytes[0] | (bytes[1] << 8);
- guid->data[1] = bytes[2] | (bytes[3] << 8);
- guid->data[2] = bytes[4] | (bytes[5] << 8);
- guid->data[3] = bytes[6] | (bytes[7] << 8);
- guid->data[4] = bytes[8] | (bytes[9] << 8);
- guid->data[5] = bytes[10] | (bytes[11] << 8);
- guid->data[6] = bytes[12] | (bytes[13] << 8);
- guid->data[7] = bytes[14] | (bytes[15] << 8);
- }
- else if (style == Guid::STYLE_UUID)
- {
- guid->data1 = (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3];
- guid->data2 = (bytes[4] << 8) | bytes[5];
- guid->data3 = (bytes[6] << 8) | bytes[7];
- guid->data4[0] = bytes[8];
- guid->data4[1] = bytes[9];
- guid->data4[2] = bytes[10];
- guid->data4[3] = bytes[11];
- guid->data4[4] = bytes[12];
- guid->data4[5] = bytes[13];
- guid->data4[6] = bytes[14];
- guid->data4[7] = bytes[15];
- }
- }
+ sscanf(buffer, GUID_LEGACY_FORMAT,
+ &guid->data[0], &guid->data[1], &guid->data[2], &guid->data[3],
+ &guid->data[4], &guid->data[5], &guid->data[6], &guid->data[7]);
}
} // namespace
Modified: firebird/trunk/src/dsql/parse.y
===================================================================
--- firebird/trunk/src/dsql/parse.y 2012-07-11 01:38:29 UTC (rev 54707)
+++ firebird/trunk/src/dsql/parse.y 2012-07-11 01:56:37 UTC (rev 54708)
@@ -523,7 +523,6 @@
%token <legacyStr> AUTONOMOUS
%token <legacyStr> CHAR_TO_UUID
-%token <legacyStr> CHAR_TO_UUID2
%token <legacyStr> FIRSTNAME
%token <legacyStr> GRANTED
%token <legacyStr> LASTNAME
@@ -532,7 +531,6 @@
%token <legacyStr> OS_NAME
%token <legacyStr> SIMILAR
%token <legacyStr> UUID_TO_CHAR
-%token <legacyStr> UUID_TO_CHAR2
// new execute statement
%token <legacyStr> CALLER
%token <legacyStr> COMMON
@@ -6148,7 +6146,6 @@
| BIN_XOR
| CEIL
| CHAR_TO_UUID
- | CHAR_TO_UUID2
| COS
| COSH
| COT
@@ -6182,7 +6179,6 @@
| TANH
| TRUNC
| UUID_TO_CHAR
- | UUID_TO_CHAR2
;
%type <sysFuncCallNode> system_function_special_syntax
@@ -6754,14 +6750,12 @@
| WEEK
| AUTONOMOUS // added in FB 2.5
| CHAR_TO_UUID
- | CHAR_TO_UUID2
| FIRSTNAME
| MIDDLENAME
| LASTNAME
| MAPPING
| OS_NAME
| UUID_TO_CHAR
- | UUID_TO_CHAR2
| GRANTED
| CALLER // new execute statement
| COMMON
Modified: firebird/trunk/src/jrd/SysFunction.cpp
===================================================================
--- firebird/trunk/src/jrd/SysFunction.cpp 2012-07-11 01:38:29 UTC (rev 54707)
+++ firebird/trunk/src/jrd/SysFunction.cpp 2012-07-11 01:56:37 UTC (rev 54708)
@@ -1512,11 +1512,19 @@
buffer[38] = '\0';
memcpy(buffer + 1, data, GUID_BODY_SIZE);
- Guid guid;
- StringToGuid(&guid, buffer, (Guid::Style)(IPTR) function->misc);
+ USHORT bytes[16];
+ sscanf(buffer, GUID_NEW_FORMAT,
+ &bytes[0], &bytes[1], &bytes[2], &bytes[3],
+ &bytes[4], &bytes[5], &bytes[6], &bytes[7],
+ &bytes[8], &bytes[9], &bytes[10], &bytes[11],
+ &bytes[12], &bytes[13], &bytes[14], &bytes[15]);
+ UCHAR resultData[16];
+ for (unsigned i = 0; i < 16; ++i)
+ resultData[i] = (UCHAR) bytes[i];
+
dsc result;
- result.makeText(16, ttype_binary, reinterpret_cast<UCHAR*>(guid.data));
+ result.makeText(16, ttype_binary, resultData);
EVL_make_value(tdbb, &result, impure);
return &impure->vlu_desc;
@@ -2049,8 +2057,26 @@
GenerateGuid(&guid);
+ UCHAR data[16];
+ data[0] = (guid.data1 >> 24) & 0xFF;
+ data[1] = (guid.data1 >> 16) & 0xFF;
+ data[2] = (guid.data1 >> 8) & 0xFF;
+ data[3] = guid.data1 & 0xFF;
+ data[4] = (guid.data2 >> 8) & 0xFF;
+ data[5] = guid.data2 & 0xFF;
+ data[6] = (guid.data3 >> 8) & 0xFF;
+ data[7] = guid.data3 & 0xFF;
+ data[8] = guid.data4[0];
+ data[9] = guid.data4[1];
+ data[10] = guid.data4[2];
+ data[11] = guid.data4[3];
+ data[12] = guid.data4[4];
+ data[13] = guid.data4[5];
+ data[14] = guid.data4[6];
+ data[15] = guid.data4[7];
+
dsc result;
- result.makeText(16, ttype_binary, reinterpret_cast<UCHAR*>(guid.data));
+ result.makeText(16, ttype_binary, data);
EVL_make_value(tdbb, &result, impure);
return &impure->vlu_desc;
@@ -3621,7 +3647,11 @@
}
char buffer[GUID_BUFF_SIZE];
- GuidToString(buffer, reinterpret_cast<const Guid*>(data), (Guid::Style)(IPTR) function->misc);
+ sprintf(buffer, GUID_NEW_FORMAT,
+ USHORT(data[0]), USHORT(data[1]), USHORT(data[2]), USHORT(data[3]), USHORT(data[4]),
+ USHORT(data[5]), USHORT(data[6]), USHORT(data[7]), USHORT(data[8]), USHORT(data[9]),
+ USHORT(data[10]), USHORT(data[11]), USHORT(data[12]), USHORT(data[13]), USHORT(data[14]),
+ USHORT(data[15]));
dsc result;
result.makeText(GUID_BODY_SIZE, ttype_ascii, reinterpret_cast<UCHAR*>(buffer) + 1);
@@ -3656,8 +3686,7 @@
{"BIN_XOR", 2, -1, setParamsInteger, makeBin, evlBin, (void*) funBinXor},
{"CEIL", 1, 1, setParamsDouble, makeCeilFloor, evlCeil, NULL},
{"CEILING", 1, 1, setParamsDouble, makeCeilFloor, evlCeil, NULL},
- {"CHAR_TO_UUID", 1, 1, setParamsCharToUuid, makeUuid, evlCharToUuid, (void*)(IPTR) Guid::STYLE_BROKEN},
- {"CHAR_TO_UUID2", 1, 1, setParamsCharToUuid, makeUuid, evlCharToUuid, (void*)(IPTR) Guid::STYLE_UUID},
+ {"CHAR_TO_UUID", 1, 1, setParamsCharToUuid, makeUuid, evlCharToUuid, NULL},
{"COS", 1, 1, setParamsDouble, makeDoubleResult, evlStdMath, (void*) trfCos},
{"COSH", 1, 1, setParamsDouble, makeDoubleResult, evlStdMath, (void*) trfCosh},
{"COT", 1, 1, setParamsDouble, makeDoubleResult, evlStdMath, (void*) trfCot},
@@ -3694,8 +3723,7 @@
{"TAN", 1, 1, setParamsDouble, makeDoubleResult, evlStdMath, (void*) trfTan},
{"TANH", 1, 1, setParamsDouble, makeDoubleResult, evlStdMath, (void*) trfTanh},
{"TRUNC", 1, 2, setParamsRoundTrunc, makeTrunc, evlTrunc, NULL},
- {"UUID_TO_CHAR", 1, 1, setParamsUuidToChar, makeUuidToChar, evlUuidToChar, (void*)(IPTR) Guid::STYLE_BROKEN},
- {"UUID_TO_CHAR2", 1, 1, setParamsUuidToChar, makeUuidToChar, evlUuidToChar, (void*)(IPTR) Guid::STYLE_UUID},
+ {"UUID_TO_CHAR", 1, 1, setParamsUuidToChar, makeUuidToChar, evlUuidToChar, NULL},
{"", 0, 0, NULL, NULL, NULL, NULL}
};
Modified: firebird/trunk/src/jrd/trace/TraceService.cpp
===================================================================
--- firebird/trunk/src/jrd/trace/TraceService.cpp 2012-07-11 01:38:29 UTC (rev 54707)
+++ firebird/trunk/src/jrd/trace/TraceService.cpp 2012-07-11 01:56:37 UTC (rev 54708)
@@ -107,7 +107,7 @@
GenerateGuid(&guid);
char* buff = session.ses_logfile.getBuffer(GUID_BUFF_SIZE);
- GuidToString(buff, &guid, Guid::STYLE_BROKEN);
+ GuidToString(buff, &guid);
session.ses_logfile.insert(0, "fb_trace.");
}
Modified: firebird/trunk/src/utilities/gstat/ppg.cpp
===================================================================
--- firebird/trunk/src/utilities/gstat/ppg.cpp 2012-07-11 01:38:29 UTC (rev 54707)
+++ firebird/trunk/src/utilities/gstat/ppg.cpp 2012-07-11 01:56:37 UTC (rev 54708)
@@ -277,7 +277,7 @@
case HDR_backup_guid:
{
char buff[Firebird::GUID_BUFF_SIZE];
- Firebird::GuidToString(buff, reinterpret_cast<const Guid*>(p + 2), Guid::STYLE_NBACKUP);
+ Firebird::GuidToString(buff, reinterpret_cast<const Guid*>(p + 2));
uSvc->printf(false, "\tDatabase backup GUID:\t%s\n", buff);
break;
}
Modified: firebird/trunk/src/utilities/nbackup/nbackup.cpp
===================================================================
--- firebird/trunk/src/utilities/nbackup/nbackup.cpp 2012-07-11 01:38:29 UTC (rev 54707)
+++ firebird/trunk/src/utilities/nbackup/nbackup.cpp 2012-07-11 01:56:37 UTC (rev 54708)
@@ -955,7 +955,7 @@
bh.version = 1;
bh.level = level;
bh.backup_guid = backup_guid;
- StringToGuid(&bh.prev_guid, prev_guid, Guid::STYLE_NBACKUP);
+ StringToGuid(&bh.prev_guid, prev_guid);
bh.page_size = header->hdr_page_size;
bh.backup_scn = backup_scn;
bh.prev_scn = prev_scn;
@@ -1113,7 +1113,7 @@
in_sqlda->sqlvar[0].sqldata = (char*) &level;
in_sqlda->sqlvar[0].sqlind = &null_flag;
char temp[GUID_BUFF_SIZE];
- GuidToString(temp, &backup_guid, Guid::STYLE_NBACKUP);
+ GuidToString(temp, &backup_guid);
in_sqlda->sqlvar[1].sqldata = temp;
in_sqlda->sqlvar[1].sqlind = &null_flag;
in_sqlda->sqlvar[2].sqldata = (char*) &backup_scn;
Modified: firebird/trunk/src/yvalve/keywords.cpp
===================================================================
--- firebird/trunk/src/yvalve/keywords.cpp 2012-07-11 01:38:29 UTC (rev 54707)
+++ firebird/trunk/src/yvalve/keywords.cpp 2012-07-11 01:56:37 UTC (rev 54708)
@@ -111,7 +111,6 @@
{KW_CHAR, "CHAR", 1, false},
{CHAR_LENGTH, "CHAR_LENGTH", 2, false},
{CHAR_TO_UUID, "CHAR_TO_UUID", 2, false},
- {CHAR_TO_UUID2, "CHAR_TO_UUID2", 2, false},
{CHARACTER, "CHARACTER", 1, false},
{CHARACTER_LENGTH, "CHARACTER_LENGTH", 2, false},
{CHECK, "CHECK", 1, false},
@@ -415,7 +414,6 @@
{USER, "USER", 1, false},
{USING, "USING", 2, false},
{UUID_TO_CHAR, "UUID_TO_CHAR", 2, false},
- {UUID_TO_CHAR2, "UUID_TO_CHAR2", 2, false},
{KW_VALUE, "VALUE", 1, false},
{VALUES, "VALUES", 1, false},
{VARCHAR, "VARCHAR", 1, false},
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|