From: <asf...@us...> - 2011-12-21 14:45:50
|
Revision: 53728 http://firebird.svn.sourceforge.net/firebird/?rev=53728&view=rev Author: asfernandes Date: 2011-12-21 14:45:39 +0000 (Wed, 21 Dec 2011) Log Message: ----------- Backport CORE-3238 - Make GEN_UUID return a compliant RFC-4122 binary UUID and introduce CHAR_TO_UUID2 and UUID_TO_CHAR2 to convert UUIDs from/to string also complying with the RFC. Modified Paths: -------------- firebird/branches/B2_5_Release/builds/make.new/config/install-sh firebird/branches/B2_5_Release/doc/sql.extensions/README.builtin_functions.txt firebird/branches/B2_5_Release/src/dsql/keywords.cpp firebird/branches/B2_5_Release/src/dsql/parse.y firebird/branches/B2_5_Release/src/jrd/SysFunction.cpp firebird/branches/B2_5_Release/src/jrd/os/guid.h firebird/branches/B2_5_Release/src/jrd/os/posix/guid.cpp Property Changed: ---------------- firebird/branches/B2_5_Release/builds/make.new/config/install-sh Property changes on: firebird/branches/B2_5_Release/builds/make.new/config/install-sh ___________________________________________________________________ Added: svn:executable + * Modified: firebird/branches/B2_5_Release/doc/sql.extensions/README.builtin_functions.txt =================================================================== --- firebird/branches/B2_5_Release/doc/sql.extensions/README.builtin_functions.txt 2011-12-21 10:57:15 UTC (rev 53727) +++ firebird/branches/B2_5_Release/doc/sql.extensions/README.builtin_functions.txt 2011-12-21 14:45:39 UTC (rev 53728) @@ -246,12 +246,38 @@ Format: CHAR_TO_UUID( <string> ) +Notes: + If you have not used this function before, its usage is discouraged. CHAR_TO_UUID2 superseds it. + Example: select char_to_uuid('93519227-8D50-4E47-81AA-8F6678C096A1') from rdb$database; -See also: GEN_UUID and UUID_TO_CHAR +See also: GEN_UUID, CHAR_TO_UUID2, UUID_TO_CHAR and UUID_TO_CHAR2 +------------- +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 superseds 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 --- @@ -405,10 +431,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 + 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 and UUID_TO_CHAR +See also: CHAR_TO_UUID, UUID_TO_CHAR, CHAR_TO_UUID2, UUID_TO_CHAR2 ---- @@ -836,7 +869,32 @@ Format: UUID_TO_CHAR( <string> ) +Notes: + If you have not used this function before, its usage is discouraged. UUID_TO_CHAR2 superseds it. + Example: select uuid_to_char(gen_uuid()) from rdb$database; -See also: GEN_UUID and CHAR_TO_UUID +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 superseds 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. + +Example: + select uuid_to_char2(gen_uuid()) from rdb$database; + +See also: GEN_UUID, CHAR_TO_UUID2 Modified: firebird/branches/B2_5_Release/src/dsql/keywords.cpp =================================================================== --- firebird/branches/B2_5_Release/src/dsql/keywords.cpp 2011-12-21 10:57:15 UTC (rev 53727) +++ firebird/branches/B2_5_Release/src/dsql/keywords.cpp 2011-12-21 14:45:39 UTC (rev 53728) @@ -104,6 +104,7 @@ {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}, @@ -383,6 +384,7 @@ {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}, Modified: firebird/branches/B2_5_Release/src/dsql/parse.y =================================================================== --- firebird/branches/B2_5_Release/src/dsql/parse.y 2011-12-21 10:57:15 UTC (rev 53727) +++ firebird/branches/B2_5_Release/src/dsql/parse.y 2011-12-21 14:45:39 UTC (rev 53728) @@ -543,6 +543,7 @@ %token AUTONOMOUS %token CHAR_TO_UUID +%token CHAR_TO_UUID2 %token FIRSTNAME %token GRANTED %token LASTNAME @@ -551,6 +552,7 @@ %token OS_NAME %token SIMILAR %token UUID_TO_CHAR +%token UUID_TO_CHAR2 %token DUMP @@ -4639,6 +4641,7 @@ | BIN_XOR | CEIL | CHAR_TO_UUID + | CHAR_TO_UUID2 | COS | COSH | COT @@ -4671,6 +4674,7 @@ | TANH | TRUNC | UUID_TO_CHAR + | UUID_TO_CHAR2 ; system_function_special_syntax @@ -5073,12 +5077,14 @@ | 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/branches/B2_5_Release/src/jrd/SysFunction.cpp =================================================================== --- firebird/branches/B2_5_Release/src/jrd/SysFunction.cpp 2011-12-21 10:57:15 UTC (rev 53727) +++ firebird/branches/B2_5_Release/src/jrd/SysFunction.cpp 2011-12-21 14:45:39 UTC (rev 53728) @@ -68,7 +68,9 @@ funLPad, funRPad, funLnat, - funLog10 + funLog10, + funUuidBroken, + funUuidRfc }; enum TrigonFunction @@ -1432,8 +1434,37 @@ memcpy(buffer + 1, data, GUID_BODY_SIZE); FB_GUID guid; - StringToGuid(&guid, buffer, false); + switch ((Function)(IPTR) function->misc) + { + case funUuidBroken: + StringToGuid(&guid, buffer, false); + break; + + case funUuidRfc: + { + 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]); + + 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]; + break; + } + } + dsc result; result.makeText(16, ttype_binary, reinterpret_cast<UCHAR*>(guid.data)); EVL_make_value(tdbb, &result, impure); @@ -3288,9 +3319,28 @@ Arg::Str(function->name)); } + const const FB_GUID* guid = reinterpret_cast<const FB_GUID*>(data); char buffer[GUID_BUFF_SIZE]; - GuidToString(buffer, reinterpret_cast<const FB_GUID*>(data), false); + switch ((Function)(IPTR) function->misc) + { + case funUuidBroken: + GuidToString(buffer, guid, false); + break; + + case funUuidRfc: + sprintf(buffer, GUID_NEW_FORMAT, + 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; + } + dsc result; result.makeText(GUID_BODY_SIZE, ttype_ascii, reinterpret_cast<UCHAR*>(buffer) + 1); EVL_make_value(tdbb, &result, impure); @@ -3324,7 +3374,8 @@ {"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, NULL}, + {"CHAR_TO_UUID", 1, 1, setParamsCharToUuid, makeUuid, evlCharToUuid, (void*) funUuidBroken}, + {"CHAR_TO_UUID2", 1, 1, setParamsCharToUuid, makeUuid, evlCharToUuid, (void*) funUuidRfc}, {"COS", 1, 1, setParamsDouble, makeDoubleResult, evlStdMath, (void*) trfCos}, {"COSH", 1, 1, setParamsDouble, makeDoubleResult, evlStdMath, (void*) trfCosh}, {"COT", 1, 1, setParamsDouble, makeDoubleResult, evlStdMath, (void*) trfCot}, @@ -3359,7 +3410,8 @@ {"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, NULL}, + {"UUID_TO_CHAR", 1, 1, setParamsUuidToChar, makeUuidToChar, evlUuidToChar, (void*) funUuidBroken}, + {"UUID_TO_CHAR2", 1, 1, setParamsUuidToChar, makeUuidToChar, evlUuidToChar, (void*) funUuidRfc}, {"", 0, 0, NULL, NULL, NULL, NULL} }; Modified: firebird/branches/B2_5_Release/src/jrd/os/guid.h =================================================================== --- firebird/branches/B2_5_Release/src/jrd/os/guid.h 2011-12-21 10:57:15 UTC (rev 53727) +++ firebird/branches/B2_5_Release/src/jrd/os/guid.h 2011-12-21 14:45:39 UTC (rev 53728) @@ -44,7 +44,18 @@ struct FB_GUID { - USHORT data[8]; + union + { + USHORT data[8]; + + struct // Compatible with Win32 GUID struct layout. + { + ULONG data1; + USHORT data2; + USHORT data3; + UCHAR data4[8]; + }; + }; }; void GenerateRandomBytes(void* buffer, size_t size); @@ -63,14 +74,14 @@ else { sprintf(buffer, GUID_NEW_FORMAT, - guid->data[0] & 0xFF, guid->data[0] >> 8, - guid->data[1] & 0xFF, guid->data[1] >> 8, - guid->data[2] & 0xFF, guid->data[2] >> 8, - guid->data[3] & 0xFF, guid->data[3] >> 8, - guid->data[4] & 0xFF, guid->data[4] >> 8, - guid->data[5] & 0xFF, guid->data[5] >> 8, - guid->data[6] & 0xFF, guid->data[6] >> 8, - guid->data[7] & 0xFF, guid->data[7] >> 8); + 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)); } } Modified: firebird/branches/B2_5_Release/src/jrd/os/posix/guid.cpp =================================================================== --- firebird/branches/B2_5_Release/src/jrd/os/posix/guid.cpp 2011-12-21 10:57:15 UTC (rev 53727) +++ firebird/branches/B2_5_Release/src/jrd/os/posix/guid.cpp 2011-12-21 14:45:39 UTC (rev 53728) @@ -70,4 +70,6 @@ void GenerateGuid(FB_GUID* guid) { GenerateRandomBytes(guid, sizeof(FB_GUID)); + guid->data3 = (4 << 12) | (guid->data3 & 0xFFF); // version 4 + guid->data4[0] = 0x80 | (guid->data4[0] & 0x3F); // variant } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |