Support parse uuid without separator

This commit is contained in:
zhang2014 2020-06-22 17:26:37 +08:00
parent 5decc73b5d
commit b3ef9a90e9
4 changed files with 48 additions and 14 deletions

View File

@ -40,30 +40,53 @@ void parseHex(IteratorSrc src, IteratorDst dst, const size_t num_bytes)
}
}
template <bool with_separator>
void parseUUID(const UInt8 * src36, UInt8 * dst16)
{
/// If string is not like UUID - implementation specific behaviour.
parseHex(&src36[0], &dst16[0], 4);
parseHex(&src36[9], &dst16[4], 2);
parseHex(&src36[14], &dst16[6], 2);
parseHex(&src36[19], &dst16[8], 2);
parseHex(&src36[24], &dst16[10], 6);
if constexpr (with_separator)
{
parseHex(&src36[0], &dst16[0], 4);
parseHex(&src36[9], &dst16[4], 2);
parseHex(&src36[14], &dst16[6], 2);
parseHex(&src36[19], &dst16[8], 2);
parseHex(&src36[24], &dst16[10], 6);
}
else
{
parseHex(&src36[0], &dst16[0], 4);
parseHex(&src36[8], &dst16[4], 2);
parseHex(&src36[12], &dst16[6], 2);
parseHex(&src36[16], &dst16[8], 2);
parseHex(&src36[20], &dst16[10], 6);
}
}
/** Function used when byte ordering is important when parsing uuid
* ex: When we create an UUID type
*/
template <bool with_separator>
void parseUUID(const UInt8 * src36, std::reverse_iterator<UInt8 *> dst16)
{
/// If string is not like UUID - implementation specific behaviour.
/// FIXME This code looks like trash.
parseHex(&src36[0], dst16 + 8, 4);
parseHex(&src36[9], dst16 + 12, 2);
parseHex(&src36[14], dst16 + 14, 2);
parseHex(&src36[19], dst16, 2);
parseHex(&src36[24], dst16 + 2, 6);
if constexpr (with_separator)
{
parseHex(&src36[0], dst16 + 8, 4);
parseHex(&src36[9], dst16 + 12, 2);
parseHex(&src36[14], dst16 + 14, 2);
parseHex(&src36[19], dst16, 2);
parseHex(&src36[24], dst16 + 2, 6);
}
else
{
parseHex(&src36[0], dst16 + 8, 4);
parseHex(&src36[8], dst16 + 12, 2);
parseHex(&src36[12], dst16 + 14, 2);
parseHex(&src36[16], dst16, 2);
parseHex(&src36[20], dst16 + 2, 6);
}
}
UInt128 stringToUUID(const String & str)

View File

@ -487,7 +487,9 @@ struct NullSink
void push_back(char) {}
};
template <bool with_separator>
void parseUUID(const UInt8 * src36, UInt8 * dst16);
template <bool with_separator>
void parseUUID(const UInt8 * src36, std::reverse_iterator<UInt8 *> dst16);
template <typename IteratorSrc, typename IteratorDst>
@ -577,13 +579,18 @@ inline void readUUIDText(UUID & uuid, ReadBuffer & buf)
char s[36];
size_t size = buf.read(s, 36);
if (size != 36)
if (size >= 32)
{
if (s[8] == '-')
parseUUID<true>(reinterpret_cast<const UInt8 *>(s), std::reverse_iterator<UInt8 *>(reinterpret_cast<UInt8 *>(&uuid) + 16));
else
parseUUID<false>(reinterpret_cast<const UInt8 *>(s), std::reverse_iterator<UInt8 *>(reinterpret_cast<UInt8 *>(&uuid) + 16));
}
else
{
s[size] = 0;
throw Exception(std::string("Cannot parse uuid ") + s, ErrorCodes::CANNOT_PARSE_UUID);
}
parseUUID(reinterpret_cast<const UInt8 *>(s), std::reverse_iterator<UInt8 *>(reinterpret_cast<UInt8 *>(&uuid) + 16));
}

View File

@ -0,0 +1,2 @@
417ddc5d-e556-4d27-95dd-a34d84e46a50
417ddc5d-e556-4d27-95dd-a34d84e46a50

View File

@ -0,0 +1,2 @@
SELECT toUUID('417ddc5de5564d2795dda34d84e46a50');
SELECT toUUID('417ddc5d-e556-4d27-95dd-a34d84e46a50');