Allow to parse Date as YYYYMMDD

This commit is contained in:
Alexey Milovidov 2021-10-30 00:23:03 +03:00
parent 6035e0498b
commit aa737b7a11
4 changed files with 62 additions and 38 deletions

View File

@ -768,17 +768,6 @@ ReturnType readDateTextFallback(LocalDate & date, ReadBuffer & buf)
return ReturnType(false); return ReturnType(false);
}; };
auto ignore_delimiter = [&]
{
if (!buf.eof() && !isNumericASCII(*buf.position()))
{
++buf.position();
return true;
}
else
return false;
};
auto append_digit = [&](auto & x) auto append_digit = [&](auto & x)
{ {
if (!buf.eof() && isNumericASCII(*buf.position())) if (!buf.eof() && isNumericASCII(*buf.position()))
@ -792,27 +781,44 @@ ReturnType readDateTextFallback(LocalDate & date, ReadBuffer & buf)
}; };
UInt16 year = 0; UInt16 year = 0;
UInt8 month = 0;
UInt8 day = 0;
if (!append_digit(year) if (!append_digit(year)
|| !append_digit(year) // NOLINT || !append_digit(year) // NOLINT
|| !append_digit(year) // NOLINT || !append_digit(year) // NOLINT
|| !append_digit(year)) // NOLINT || !append_digit(year)) // NOLINT
return error(); return error();
if (!ignore_delimiter()) if (buf.eof())
return error(); return error();
UInt8 month = 0; if (isNumericASCII(*buf.position()))
if (!append_digit(month)) {
return error(); /// YYYYMMDD
append_digit(month); if (!append_digit(month)
|| !append_digit(month) // NOLINT
|| !append_digit(day)
|| !append_digit(day)) // NOLINT
return error();
}
else
{
++buf.position();
if (!ignore_delimiter()) if (!append_digit(month))
return error(); return error();
append_digit(month);
UInt8 day = 0; if (!buf.eof() && !isNumericASCII(*buf.position()))
if (!append_digit(day)) ++buf.position();
return error(); else
append_digit(day); return error();
if (!append_digit(day))
return error();
append_digit(day);
}
date = LocalDate(year, month, day); date = LocalDate(year, month, day);
return ReturnType(true); return ReturnType(true);

View File

@ -597,35 +597,45 @@ inline ReturnType readDateTextImpl(LocalDate & date, ReadBuffer & buf)
/// YYYY-MM-D /// YYYY-MM-D
/// YYYY-M-DD /// YYYY-M-DD
/// YYYY-M-D /// YYYY-M-D
/// YYYYMMDD
/// The delimiters can be arbitrary characters, like YYYY/MM!DD, but obviously not digits. /// The delimiters can be arbitrary characters, like YYYY/MM!DD, but obviously not digits.
UInt16 year = (pos[0] - '0') * 1000 + (pos[1] - '0') * 100 + (pos[2] - '0') * 10 + (pos[3] - '0'); UInt16 year = (pos[0] - '0') * 1000 + (pos[1] - '0') * 100 + (pos[2] - '0') * 10 + (pos[3] - '0');
UInt8 month;
UInt8 day;
pos += 5; pos += 5;
if (isNumericASCII(pos[-1])) if (isNumericASCII(pos[-1]))
return ReturnType(false);
UInt8 month = pos[0] - '0';
if (isNumericASCII(pos[1]))
{ {
month = month * 10 + pos[1] - '0'; /// YYYYMMDD
month = (pos[-1] - '0') * 10 + (pos[0] - '0');
day = (pos[1] - '0') * 10 + (pos[2] - '0');
pos += 3; pos += 3;
} }
else else
pos += 2;
if (isNumericASCII(pos[-1]))
return ReturnType(false);
UInt8 day = pos[0] - '0';
if (isNumericASCII(pos[1]))
{ {
day = day * 10 + pos[1] - '0'; month = pos[0] - '0';
pos += 2; if (isNumericASCII(pos[1]))
{
month = month * 10 + pos[1] - '0';
pos += 3;
}
else
pos += 2;
if (isNumericASCII(pos[-1]))
return ReturnType(false);
day = pos[0] - '0';
if (isNumericASCII(pos[1]))
{
day = day * 10 + pos[1] - '0';
pos += 2;
}
else
pos += 1;
} }
else
pos += 1;
buf.position() = pos; buf.position() = pos;
date = LocalDate(year, month, day); date = LocalDate(year, month, day);

View File

@ -0,0 +1 @@
2021-02-03 2021-03-04 2021-04-05

View File

@ -0,0 +1,7 @@
#!/usr/bin/env bash
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
# shellcheck source=../shell_config.sh
. "$CURDIR"/../shell_config.sh
echo '20210203,2021-03-04,20210405' | $CLICKHOUSE_LOCAL --input-format CSV --structure 'a Date, b Date, c Date' --query 'SELECT * FROM table'