Commit 6bf5a3be authored by Alexander Barkov's avatar Alexander Barkov Committed by Sergei Golubchik

MDEV-26785 Hyphens inside the value of uuid datatype

parent 4300f502
......@@ -3120,3 +3120,27 @@ SELECT MIN(a), MAX(a) FROM t1 GROUP BY id;
MIN(a) MAX(a)
00000000-0000-0000-0000-000000000fff 00000000-0000-0000-0000-000000008888
DROP TABLE t1;
#
# MDEV-26785 Hyphens inside the value of uuid datatype
#
CREATE TABLE t1 (a UUID);
INSERT INTO t1 VALUES ('0000000000000000000000000000000'/*31 digits*/);
ERROR 22007: Incorrect uuid value: '0000000000000000000000000000000' for column `test`.`t1`.`a` at row 1
INSERT INTO t1 VALUES ('000000000000000000000000000000000'/*33 digits*/);
ERROR 22007: Incorrect uuid value: '000000000000000000000000000000000' for column `test`.`t1`.`a` at row 1
INSERT INTO t1 VALUES ('-00000000000000000000000000000000'/*leading hyphen*/);
ERROR 22007: Incorrect uuid value: '-00000000000000000000000000000000' for column `test`.`t1`.`a` at row 1
INSERT INTO t1 VALUES ('-00000000000000000000000000000000-'/*trailing hyphen*/);
ERROR 22007: Incorrect uuid value: '-00000000000000000000000000000000-' for column `test`.`t1`.`a` at row 1
INSERT INTO t1 VALUES ('00000000000000000000000000000000');
INSERT INTO t1 VALUES ('0-0000000000000000000000000000011');
INSERT INTO t1 VALUES ('0--0000000000000000000000000000012');
INSERT INTO t1 VALUES ('0---0000000000000000000000000000013');
INSERT INTO t1 VALUES ('0----0000000000000000000000000000014');
INSERT INTO t1 VALUES ('00-000000000000000000000000000021');
INSERT INTO t1 VALUES ('00--000000000000000000000000000022');
INSERT INTO t1 VALUES ('00---000000000000000000000000000023');
INSERT INTO t1 VALUES ('00----000000000000000000000000000024');
INSERT INTO t1 VALUES ('5796dac11a1c11--------------ecab4ef859-713e4be4');
INSERT INTO t1 VALUES ('5796dac11a1c11---------------ecab4ef859-713e4be4');
DROP TABLE t1;
......@@ -1617,3 +1617,32 @@ INSERT INTO t1 VALUES
(1, '00000000-0000-0000-0000-000000008888');
SELECT MIN(a), MAX(a) FROM t1 GROUP BY id;
DROP TABLE t1;
--echo #
--echo # MDEV-26785 Hyphens inside the value of uuid datatype
--echo #
CREATE TABLE t1 (a UUID);
--error ER_TRUNCATED_WRONG_VALUE
INSERT INTO t1 VALUES ('0000000000000000000000000000000'/*31 digits*/);
--error ER_TRUNCATED_WRONG_VALUE
INSERT INTO t1 VALUES ('000000000000000000000000000000000'/*33 digits*/);
--error ER_TRUNCATED_WRONG_VALUE
INSERT INTO t1 VALUES ('-00000000000000000000000000000000'/*leading hyphen*/);
--error ER_TRUNCATED_WRONG_VALUE
INSERT INTO t1 VALUES ('-00000000000000000000000000000000-'/*trailing hyphen*/);
INSERT INTO t1 VALUES ('00000000000000000000000000000000');
INSERT INTO t1 VALUES ('0-0000000000000000000000000000011');
INSERT INTO t1 VALUES ('0--0000000000000000000000000000012');
INSERT INTO t1 VALUES ('0---0000000000000000000000000000013');
INSERT INTO t1 VALUES ('0----0000000000000000000000000000014');
INSERT INTO t1 VALUES ('00-000000000000000000000000000021');
INSERT INTO t1 VALUES ('00--000000000000000000000000000022');
INSERT INTO t1 VALUES ('00---000000000000000000000000000023');
INSERT INTO t1 VALUES ('00----000000000000000000000000000024');
INSERT INTO t1 VALUES ('5796dac11a1c11--------------ecab4ef859-713e4be4');
INSERT INTO t1 VALUES ('5796dac11a1c11---------------ecab4ef859-713e4be4');
DROP TABLE t1;
......@@ -42,28 +42,61 @@ static bool get_digit(char ch, uint *val)
}
bool UUID::ascii_to_fbt(const char *str, size_t str_length)
static bool get_digit(uint *val, const char *str, const char *end)
{
if (str_length < 32 || str_length > 3 * binary_length() - 1)
if (str >= end)
return true;
return get_digit(*str, val);
}
uint oidx= 0;
for (const char *s= str; s < str + str_length; )
static size_t skip_hyphens(const char *str, const char *end)
{
const char *str0= str;
for ( ; str < end; str++)
{
if (oidx >= binary_length())
goto err;
if (*s == '-')
{
if (s == str)
goto err;
s++;
continue;
}
uint hi, lo;
if (get_digit(*s++, &hi) || get_digit(*s++, &lo))
if (str[0] != '-')
break;
}
return str - str0;
}
static const char *get_two_digits(char *val, const char *str, const char *end)
{
uint hi, lo;
if (get_digit(&hi, str++, end))
return NULL;
str+= skip_hyphens(str, end);
if (get_digit(&lo, str++, end))
return NULL;
*val= (char) ((hi << 4) + lo);
return str;
}
bool UUID::ascii_to_fbt(const char *str, size_t str_length)
{
const char *end= str + str_length;
/*
The format understood:
- Hyphen is not allowed on the first and the last position.
- Otherwise, hyphens are allowed on any (odd and even) position,
with any amount.
*/
if (str_length < 32)
goto err;
for (uint oidx= 0; oidx < binary_length(); oidx++)
{
if (!(str= get_two_digits(&m_buffer[oidx], str, end)))
goto err;
m_buffer[oidx++]= (char) ((hi << 4) + lo);
// Allow hypheps after two digits, but not after the last digit
if (oidx + 1 < binary_length())
str+= skip_hyphens(str, end);
}
if (str < end)
goto err; // Some input left
return false;
err:
bzero(m_buffer, sizeof(m_buffer));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment