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. |